From 05fbc7216e044aa91ebd5c9475f2ce8082152072 Mon Sep 17 00:00:00 2001 From: Vincent Vanwaelscappel Date: Thu, 2 Nov 2023 11:00:30 +0100 Subject: [PATCH] wip #6447 @0.75 --- .htaccess | 2 + CHANGELOG | 250 ++ admin/auth.php | 288 ++ admin/blog.php | 98 + admin/blog_del.php | 71 + admin/blog_pref.php | 528 +++ admin/blog_theme.php | 352 ++ admin/blogs.php | 183 + admin/categories.php | 188 + admin/category.php | 260 ++ admin/comment.php | 232 ++ admin/comments.php | 233 ++ admin/comments_actions.php | 97 + admin/dispatcher.php | 34 + admin/images/attach.png | Bin 0 -> 370 bytes admin/images/check-off.png | Bin 0 -> 450 bytes admin/images/check-on.png | Bin 0 -> 400 bytes admin/images/check-wrn.png | Bin 0 -> 394 bytes admin/images/date-picker.png | Bin 0 -> 1199 bytes admin/images/dotclear_pw.png | Bin 0 -> 1525 bytes admin/images/edit-mini.png | Bin 0 -> 614 bytes admin/images/help.png | Bin 0 -> 1600 bytes admin/images/junk.png | Bin 0 -> 498 bytes admin/images/locker.png | Bin 0 -> 354 bytes admin/images/media/audio.png | Bin 0 -> 1170 bytes admin/images/media/blank.png | Bin 0 -> 1273 bytes admin/images/media/document.png | Bin 0 -> 762 bytes admin/images/media/executable.png | Bin 0 -> 1240 bytes admin/images/media/folder.png | Bin 0 -> 1011 bytes admin/images/media/html.png | Bin 0 -> 1811 bytes admin/images/media/image.png | Bin 0 -> 1467 bytes admin/images/media/package.png | Bin 0 -> 1153 bytes admin/images/media/presentation.png | Bin 0 -> 1141 bytes admin/images/media/spreadsheet.png | Bin 0 -> 1624 bytes admin/images/media/text.png | Bin 0 -> 1095 bytes admin/images/media/video.png | Bin 0 -> 1250 bytes admin/images/menu/blog-pref-b.png | Bin 0 -> 2034 bytes admin/images/menu/blog-theme-b.png | Bin 0 -> 1919 bytes admin/images/menu/blogs.png | Bin 0 -> 762 bytes admin/images/menu/categories.png | Bin 0 -> 410 bytes admin/images/menu/comments-b.png | Bin 0 -> 700 bytes admin/images/menu/comments.png | Bin 0 -> 328 bytes admin/images/menu/dashboard.png | Bin 0 -> 393 bytes admin/images/menu/edit-b.png | Bin 0 -> 2294 bytes admin/images/menu/edit.png | Bin 0 -> 418 bytes admin/images/menu/entries-b.png | Bin 0 -> 1051 bytes admin/images/menu/entries.png | Bin 0 -> 467 bytes admin/images/menu/langs.png | Bin 0 -> 738 bytes admin/images/menu/media.png | Bin 0 -> 564 bytes admin/images/menu/plugins.png | Bin 0 -> 1138 bytes admin/images/menu/search.png | Bin 0 -> 706 bytes admin/images/menu/update.png | Bin 0 -> 1466 bytes admin/images/menu/user-pref-b.png | Bin 0 -> 1388 bytes admin/images/menu/users.png | Bin 0 -> 1082 bytes admin/images/menu_off.png | Bin 0 -> 1346 bytes admin/images/menu_on.png | Bin 0 -> 1334 bytes admin/images/minus.png | Bin 0 -> 284 bytes admin/images/noscreenshot.png | Bin 0 -> 1395 bytes admin/images/picker.png | Bin 0 -> 1520 bytes admin/images/plus.png | Bin 0 -> 297 bytes admin/images/scheduled.png | Bin 0 -> 316 bytes admin/images/selected.png | Bin 0 -> 369 bytes admin/images/trash.png | Bin 0 -> 718 bytes admin/index.php | 257 ++ admin/install/check.php | 83 + admin/install/index.php | 313 ++ admin/install/wizard.php | 182 + admin/js/_blog_theme.js | 6 + admin/js/_categories.js | 2 + admin/js/_category.js | 2 + admin/js/_comment.js | 3 + admin/js/_comments.js | 6 + admin/js/_index.js | 9 + admin/js/_langs.js | 2 + admin/js/_media.js | 7 + admin/js/_media_item.js | 4 + admin/js/_permissions.js | 6 + admin/js/_permissions_blog.js | 2 + admin/js/_plugins.js | 2 + admin/js/_post.js | 16 + admin/js/_posts_list.js | 7 + admin/js/_preferences.js | 5 + admin/js/_trackbacks.js | 2 + admin/js/_users.js | 7 + admin/js/color-picker.js | 6 + admin/js/common.js | 16 + admin/js/confirm-close.js | 12 + admin/js/date-picker.js | 41 + admin/js/dragsort-tablerows.js | 2 + admin/js/filter-controls.js | 2 + admin/js/ie7/IE7.js | 2 + admin/js/ie7/IE8.js | 2 + admin/js/ie7/blank.gif | Bin 0 -> 48 bytes admin/js/ie7/ie7-recalc.js | 2 + admin/js/ie7/ie7-squish.js | 36 + admin/js/jquery/jquery.bgFade.js | 7 + admin/js/jquery/jquery.biscuit.js | 5 + admin/js/jquery/jquery.candyUpload.js | 22 + admin/js/jquery/jquery.farbtastic.js | 22 + admin/js/jquery/jquery.js | 432 +++ admin/js/jquery/jquery.modal.js | 17 + admin/js/jquery/jquery.pageTabs.js | 4 + admin/js/jsToolBar/jsToolBar.dotclear.js | 30 + admin/js/jsToolBar/jsToolBar.js | 28 + admin/js/jsToolBar/jsToolBar.wysiwyg.js | 47 + admin/js/jsToolBar/popup_link.js | 3 + admin/js/jsToolBar/popup_media.js | 13 + admin/js/jsToolBar/popup_posts.js | 2 + admin/js/tool-man/cookies.js | 11 + admin/js/tool-man/coordinates.js | 19 + admin/js/tool-man/core.js | 35 + admin/js/tool-man/css.js | 3 + admin/js/tool-man/drag.js | 84 + admin/js/tool-man/dragsort.js | 35 + admin/js/tool-man/events.js | 8 + admin/langs.php | 289 ++ admin/media.php | 449 +++ admin/media_item.php | 518 +++ admin/permissions.php | 160 + admin/permissions_blog.php | 196 ++ admin/plugin.php | 91 + admin/plugins.php | 364 ++ admin/popup_link.php | 58 + admin/popup_posts.php | 57 + admin/post.php | 657 ++++ admin/post_media.php | 79 + admin/posts.php | 298 ++ admin/posts_actions.php | 250 ++ admin/preferences.php | 202 ++ admin/search.php | 180 + admin/services.php | 236 ++ admin/style/candyUpload/cancel.png | Bin 0 -> 309 bytes admin/style/candyUpload/loader.png | Bin 0 -> 858 bytes admin/style/candyUpload/style.css | 120 + admin/style/cat-bg.png | Bin 0 -> 1270 bytes admin/style/date-picker.css | 35 + admin/style/default-rtl.css | 11 + admin/style/default.css | 1074 ++++++ admin/style/dotclear-logo.png | Bin 0 -> 2900 bytes admin/style/drag.png | Bin 0 -> 415 bytes admin/style/farbtastic/farbtastic.css | 33 + admin/style/farbtastic/marker.png | Bin 0 -> 614 bytes admin/style/farbtastic/mask.png | Bin 0 -> 2020 bytes admin/style/farbtastic/wheel.png | Bin 0 -> 11733 bytes admin/style/footer-bg.png | Bin 0 -> 1490 bytes admin/style/grid.png | Bin 0 -> 202 bytes admin/style/head-bg.png | Bin 0 -> 1325 bytes admin/style/head-logo.png | Bin 0 -> 3877 bytes admin/style/iesucks.css | 42 + admin/style/jsToolBar/bt_bquote.png | Bin 0 -> 261 bytes admin/style/jsToolBar/bt_br.png | Bin 0 -> 243 bytes admin/style/jsToolBar/bt_clean.png | Bin 0 -> 576 bytes admin/style/jsToolBar/bt_code.png | Bin 0 -> 338 bytes admin/style/jsToolBar/bt_del.png | Bin 0 -> 351 bytes admin/style/jsToolBar/bt_em.png | Bin 0 -> 300 bytes admin/style/jsToolBar/bt_img.png | Bin 0 -> 899 bytes admin/style/jsToolBar/bt_img_select.png | Bin 0 -> 518 bytes admin/style/jsToolBar/bt_ins.png | Bin 0 -> 308 bytes admin/style/jsToolBar/bt_link.png | Bin 0 -> 833 bytes admin/style/jsToolBar/bt_ol.png | Bin 0 -> 249 bytes admin/style/jsToolBar/bt_paragraph.png | Bin 0 -> 295 bytes admin/style/jsToolBar/bt_post.png | Bin 0 -> 1507 bytes admin/style/jsToolBar/bt_pre.png | Bin 0 -> 244 bytes admin/style/jsToolBar/bt_quote.png | Bin 0 -> 322 bytes admin/style/jsToolBar/bt_strong.png | Bin 0 -> 336 bytes admin/style/jsToolBar/bt_ul.png | Bin 0 -> 239 bytes admin/style/jsToolBar/jsToolBar.css | 173 + admin/style/jsToolBar/resize.png | Bin 0 -> 1267 bytes admin/style/magnifier.png | Bin 0 -> 499 bytes admin/style/modal/close.png | Bin 0 -> 1179 bytes admin/style/modal/loader.gif | Bin 0 -> 9427 bytes admin/style/modal/modal.css | 52 + admin/style/msg-error.png | Bin 0 -> 617 bytes admin/style/msg-std.png | Bin 0 -> 600 bytes admin/style/package.png | Bin 0 -> 696 bytes admin/style/page-bg.png | Bin 0 -> 1254 bytes admin/style/tab-bg.png | Bin 0 -> 199 bytes admin/style/tab-c-l.png | Bin 0 -> 270 bytes admin/style/tab-c-r.png | Bin 0 -> 377 bytes admin/style/tab-l-l.png | Bin 0 -> 428 bytes admin/style/tab-l-r.png | Bin 0 -> 551 bytes admin/style/tab-n-l.png | Bin 0 -> 411 bytes admin/style/tab-n-r.png | Bin 0 -> 524 bytes admin/trackbacks.php | 150 + admin/update.php | 212 ++ admin/user.php | 301 ++ admin/users.php | 167 + admin/xmlrpc.php | 35 + cache/.htaccess | 1 + .../4f/6a4f55e24111799aaa8e45c1cc4d4583.php | 304 ++ .../16/061624c7d38d3b032e8770d96e17d8da.php | 61 + .../4b/1c4b52bb84ebd38be237c1522ddf181d.php | 212 ++ .../b6/3ab69b6036ca46cabbbc3f6f39ceb835.php | 92 + .../b3/3bb3a29ef197db17fdf8e0d1c82e1f9f.php | 273 ++ .../2a/3d2ab7176958994fb44ae475a0e58648.php | 16 + .../e1/62e139c10241e743060059b9ff916ad8.php | 329 ++ .../28/68289f8a2d83100b6bda1a3cccbbc63f.php | 230 ++ .../ae/8bae1e7eb3f0cd863c169541fdad8d0e.php | 7 + .../06/a706cb39770a563585de2242a3226981.php | 73 + .../5d/b05d35fd541ee9f5da5478faf45bb412.php | 71 + .../f4/b0f4418e5a9e7ab1a68ede430ca901e4.php | 63 + .../d7/b9d701fcfceb205e24dd3c2658797c4e.php | 207 ++ .../cd/c1cd28bd66b4517eec04f3abde1cb6c0.php | 211 ++ .../6a/d66aceb2839fdeb0b5251550574000be.php | 5 + .../53/e153e91980f2acce5c73feac0a840192.php | 173 + .../f4/f7f41a7bdbfd5f0616a3e4b89660a6a8.php | 0 .../cb/68cbfef3c40e3d56b4fb94709e2b9321.ser | Bin 0 -> 27052 bytes .../37/fa37bc9589c9a834517f9ddff94f8683.ser | Bin 0 -> 33321 bytes cache/versions/dotclear-stable | 1 + db/.htaccess | 1 + dotclear-loader.php | 462 +++ inc/.htaccess | 1 + inc/admin/class.dc.menu.php | 86 + inc/admin/lib.dc.page.php | 668 ++++ inc/admin/lib.pager.php | 408 +++ inc/admin/prepend.php | 211 ++ inc/clearbricks/_common.php | 83 + inc/clearbricks/common/_main.php | 58 + inc/clearbricks/common/lib.crypt.php | 77 + inc/clearbricks/common/lib.date.php | 260 ++ inc/clearbricks/common/lib.files.php | 667 ++++ inc/clearbricks/common/lib.form.php | 347 ++ inc/clearbricks/common/lib.html.php | 185 + inc/clearbricks/common/lib.http.php | 418 +++ inc/clearbricks/common/lib.l10n.php | 451 +++ inc/clearbricks/common/lib.text.php | 355 ++ inc/clearbricks/common/tz.dat | 407 +++ inc/clearbricks/dblayer/class.cursor.php | 258 ++ inc/clearbricks/dblayer/class.mysql.php | 253 ++ inc/clearbricks/dblayer/class.pgsql.php | 280 ++ inc/clearbricks/dblayer/class.sqlite.php | 278 ++ inc/clearbricks/dblayer/dblayer.php | 1144 ++++++ inc/clearbricks/dbschema/class.dbschema.php | 310 ++ inc/clearbricks/dbschema/class.dbstruct.php | 639 ++++ .../dbschema/class.mysql.dbschema.php | 470 +++ .../dbschema/class.pgsql.dbschema.php | 400 +++ .../dbschema/class.sqlite.dbschema.php | 515 +++ .../filemanager/class.filemanager.php | 614 ++++ .../html.filter/class.html.filter.php | 676 ++++ .../html.validator/class.html.validator.php | 143 + inc/clearbricks/image/class.image.meta.php | 406 +++ inc/clearbricks/image/class.image.tools.php | 295 ++ inc/clearbricks/mail/class.mail.php | 117 + inc/clearbricks/mail/class.socket.mail.php | 181 + .../net.http.feed/class.feed.parser.php | 288 ++ .../net.http.feed/class.feed.reader.php | 276 ++ inc/clearbricks/net.http/class.net.http.php | 919 +++++ .../net.xmlrpc/class.net.xmlrpc.php | 1353 +++++++ inc/clearbricks/net/class.net.socket.php | 299 ++ inc/clearbricks/pager/class.pager.php | 215 ++ inc/clearbricks/rest/class.rest.php | 292 ++ .../session.db/class.session.db.php | 232 ++ inc/clearbricks/template/class.template.php | 290 ++ .../text.wiki2xhtml/class.wiki2xhtml.php | 1267 +++++++ .../url.handler/class.url.handler.php | 203 ++ inc/clearbricks/zip/class.unzip.php | 522 +++ inc/clearbricks/zip/class.zip.php | 370 ++ inc/config.php | 67 + inc/config.php.in | 67 + inc/core/class.dc.auth.php | 593 ++++ inc/core/class.dc.blog.php | 2006 +++++++++++ inc/core/class.dc.categories.php | 483 +++ inc/core/class.dc.core.php | 1461 ++++++++ inc/core/class.dc.error.php | 129 + inc/core/class.dc.media.php | 1070 ++++++ inc/core/class.dc.modules.php | 519 +++ inc/core/class.dc.rest.php | 52 + inc/core/class.dc.rs.extensions.php | 815 +++++ inc/core/class.dc.settings.php | 330 ++ inc/core/class.dc.themes.php | 84 + inc/core/class.dc.trackback.php | 404 +++ inc/core/class.dc.update.php | 465 +++ inc/core/class.dc.utils.php | 53 + inc/core/class.dc.xmlrpc.php | 1634 +++++++++ inc/core_error.php | 63 + inc/dbschema/db-schema.php | 253 ++ inc/dbschema/upgrade-cli.php | 52 + inc/dbschema/upgrade.php | 142 + inc/digests | 531 +++ inc/load_plugin_file.php | 87 + inc/prepend.php | 260 ++ inc/public/class.dc.template.php | 2916 ++++++++++++++++ .../default-templates/atom-comments.xml | 45 + inc/public/default-templates/atom.xml | 49 + .../default-templates/password-form.html | 43 + .../default-templates/rss2-comments.xml | 48 + inc/public/default-templates/rss2.xml | 49 + inc/public/default-templates/rss2.xsl | 120 + inc/public/lib.tpl.context.php | 435 +++ inc/public/lib.urlhandlers.php | 560 +++ inc/public/prepend.php | 133 + inc/public/rs.extension.php | 93 + inc/swf/player_flv.swf | Bin 0 -> 12975 bytes inc/swf/player_mp3.swf | Bin 0 -> 6379 bytes inc/swf/swfupload.swf | Bin 0 -> 12787 bytes index.php | 23 + locales/README | 1 + locales/en/date.lang.php | 38 + locales/en/date.po | 56 + locales/en/help/blog_pref.html | 148 + locales/en/help/categories.html | 41 + locales/en/help/comments.html | 58 + locales/en/help/media.html | 89 + locales/en/help/post.html | 125 + locales/en/help/posts.html | 65 + locales/en/help/user_pref.html | 61 + locales/en/help/wiki.html | 85 + locales/en/resources.php | 33 + locales/fr/date.lang.php | 58 + locales/fr/date.po | 132 + locales/fr/help/blowupConfig.html | 71 + locales/fr/help/core_blog_pref.html | 190 + locales/fr/help/core_categories.html | 43 + locales/fr/help/core_comments.html | 59 + locales/fr/help/core_media.html | 96 + locales/fr/help/core_post.html | 137 + locales/fr/help/core_posts.html | 65 + locales/fr/help/core_user_pref.html | 64 + locales/fr/help/core_wiki.html | 85 + locales/fr/help/themeEditor.html | 37 + locales/fr/main.lang.php | 816 +++++ locales/fr/main.po | 2485 +++++++++++++ locales/fr/plugins.lang.php | 457 +++ locales/fr/plugins.po | 1358 ++++++++ locales/fr/public.lang.php | 93 + locales/fr/public.po | 237 ++ locales/fr/resources.php | 22 + plugins/.htaccess | 1 + plugins/aboutConfig/_admin.php | 17 + plugins/aboutConfig/_define.php | 21 + plugins/aboutConfig/icon.png | Bin 0 -> 776 bytes plugins/aboutConfig/index.php | 179 + plugins/accessibleCaptcha/LICENSE | 674 ++++ plugins/accessibleCaptcha/_define.php | 12 + plugins/accessibleCaptcha/_install.php | 67 + plugins/accessibleCaptcha/_prepend.php | 34 + .../class.accessible.captcha.php | 303 ++ .../class.dc.filter.accessible.captcha.php | 182 + plugins/accessibleCaptcha/locales/fr/main.po | 87 + plugins/akismet/_define.php | 22 + plugins/akismet/_prepend.php | 17 + plugins/akismet/class.dc.filter.akismet.php | 260 ++ plugins/antispam/_admin.php | 51 + plugins/antispam/_define.php | 22 + plugins/antispam/_install.php | 52 + plugins/antispam/_prepend.php | 30 + plugins/antispam/_public.php | 17 + plugins/antispam/antispam.js | 3 + plugins/antispam/feed.png | Bin 0 -> 404 bytes .../antispam/filters/class.dc.filter.ip.php | 311 ++ .../filters/class.dc.filter.iplookup.php | 120 + .../filters/class.dc.filter.linkslookup.php | 74 + .../filters/class.dc.filter.words.php | 357 ++ plugins/antispam/icon.png | Bin 0 -> 674 bytes plugins/antispam/inc/class.dc.spamfilter.php | 161 + plugins/antispam/inc/class.dc.spamfilters.php | 164 + plugins/antispam/inc/lib.dc.antispam.php | 195 ++ plugins/antispam/inc/lib.dc.antispam.url.php | 99 + plugins/antispam/index.php | 222 ++ plugins/antispam/style.css | 23 + plugins/blogroll/_admin.php | 27 + plugins/blogroll/_define.php | 21 + plugins/blogroll/_install.php | 46 + plugins/blogroll/_prepend.php | 15 + plugins/blogroll/_public.php | 229 ++ plugins/blogroll/_widgets.php | 44 + plugins/blogroll/class.dc.blogroll.php | 198 ++ plugins/blogroll/class.dc.importblogroll.php | 102 + plugins/blogroll/edit.php | 241 ++ plugins/blogroll/icon-small.png | Bin 0 -> 848 bytes plugins/blogroll/icon.png | Bin 0 -> 3485 bytes plugins/blogroll/index.php | 400 +++ plugins/blogroll/locales/en/main.lang.php | 44 + plugins/blogroll/locales/en/main.po | 74 + plugins/blowupConfig/_admin.php | 26 + plugins/blowupConfig/_define.php | 21 + plugins/blowupConfig/_public.php | 193 + plugins/blowupConfig/alpha-img/comment-b.png | Bin 0 -> 1328 bytes plugins/blowupConfig/alpha-img/comment-t.png | Bin 0 -> 1549 bytes plugins/blowupConfig/alpha-img/gradient-d.png | Bin 0 -> 1432 bytes plugins/blowupConfig/alpha-img/gradient-l.png | Bin 0 -> 1443 bytes plugins/blowupConfig/alpha-img/gradient-m.png | Bin 0 -> 1446 bytes plugins/blowupConfig/alpha-img/page-b.png | Bin 0 -> 1340 bytes plugins/blowupConfig/alpha-img/page-bg.png | Bin 0 -> 1263 bytes .../blowupConfig/alpha-img/page-t/animals.png | Bin 0 -> 28044 bytes .../blowupConfig/alpha-img/page-t/blank.png | Bin 0 -> 1892 bytes .../alpha-img/page-t/butterflies.png | Bin 0 -> 6350 bytes .../blowupConfig/alpha-img/page-t/default.png | Bin 0 -> 1926 bytes .../alpha-img/page-t/flamingo.png | Bin 0 -> 12864 bytes .../alpha-img/page-t/flourish-1.png | Bin 0 -> 5045 bytes .../alpha-img/page-t/flourish-2.png | Bin 0 -> 12838 bytes .../alpha-img/page-t/image-mask.png | Bin 0 -> 1982 bytes .../alpha-img/page-t/light-trails-1.png | Bin 0 -> 28612 bytes .../alpha-img/page-t/light-trails-2.png | Bin 0 -> 40999 bytes .../alpha-img/page-t/light-trails-3.png | Bin 0 -> 38308 bytes .../alpha-img/page-t/light-trails-4.png | Bin 0 -> 32171 bytes .../blowupConfig/alpha-img/page-t/rabbit.png | Bin 0 -> 3208 bytes .../alpha-img/page-t/roadrunner-1.png | Bin 0 -> 6337 bytes .../alpha-img/page-t/roadrunner-2.png | Bin 0 -> 8997 bytes .../blowupConfig/alpha-img/page-t/typo.png | Bin 0 -> 15365 bytes plugins/blowupConfig/config.js | 11 + plugins/blowupConfig/help.html | 55 + plugins/blowupConfig/index.php | 449 +++ .../blowupConfig/lib/class.blowup.config.php | 418 +++ plugins/daInstaller/_admin.php | 58 + plugins/daInstaller/_define.php | 19 + plugins/daInstaller/_install.php | 50 + plugins/daInstaller/_prepend.php | 15 + plugins/daInstaller/icon-big-update.png | Bin 0 -> 5190 bytes plugins/daInstaller/icon-big.png | Bin 0 -> 4600 bytes plugins/daInstaller/icon.png | Bin 0 -> 792 bytes plugins/daInstaller/img/help.png | Bin 0 -> 831 bytes plugins/daInstaller/img/support.png | Bin 0 -> 902 bytes .../daInstaller/inc/class.da.installer.php | 317 ++ .../inc/class.da.modules.parser.php | 81 + .../inc/class.da.modules.reader.php | 196 ++ .../daInstaller/inc/lib.da.installer.ui.php | 310 ++ plugins/daInstaller/index.php | 321 ++ plugins/daInstaller/js/_dainstaller.js | 17 + plugins/daInstaller/locales/_pot/main.pot | 98 + .../locales/fr/help/da_installer.html | 30 + plugins/daInstaller/locales/fr/main.lang.php | 120 + plugins/daInstaller/locales/fr/main.po | 163 + plugins/daInstaller/locales/fr/resources.php | 14 + .../l10n-daInstaller-fr-1304423937.bck.zip | Bin 0 -> 1478 bytes .../l10n-daInstaller-fr-1304423968.bck.zip | Bin 0 -> 3032 bytes .../l10n-daInstaller-fr-1304424006.bck.zip | Bin 0 -> 3007 bytes .../l10n-daInstaller-fr-1304424011.bck.zip | Bin 0 -> 3011 bytes .../l10n-daInstaller-fr-1305546468.bck.zip | Bin 0 -> 3008 bytes plugins/daInstaller/style.css | 29 + plugins/externalMedia/_admin.php | 32 + plugins/externalMedia/_define.php | 22 + plugins/externalMedia/bt_video.png | Bin 0 -> 1932 bytes plugins/externalMedia/index.php | 282 ++ plugins/externalMedia/popup.js | 3 + plugins/externalMedia/post.js | 6 + plugins/fairTrackbacks/_define.php | 22 + plugins/fairTrackbacks/_prepend.php | 22 + plugins/fairTrackbacks/_public.php | 18 + .../class.dc.filter.fairtrackbacks.php | 85 + plugins/googleTools/_admin.php | 48 + plugins/googleTools/_define.php | 24 + plugins/googleTools/_install.php | 35 + plugins/googleTools/_public.php | 52 + plugins/googleTools/locales/fr/main.lang.php | 19 + plugins/importExport/_admin.php | 22 + plugins/importExport/_define.php | 22 + plugins/importExport/icon.png | Bin 0 -> 662 bytes .../importExport/inc/class.dc.export.flat.php | 176 + .../importExport/inc/class.dc.ieModule.php | 89 + .../importExport/inc/class.dc.import.dc1.php | 627 ++++ .../importExport/inc/class.dc.import.feed.php | 105 + .../importExport/inc/class.dc.import.flat.php | 238 ++ .../importExport/inc/class.dc.import.wp.php | 786 +++++ .../inc/flat/class.backupFile.php | 132 + .../importExport/inc/flat/class.db.export.php | 106 + .../importExport/inc/flat/class.dc.import.php | 730 ++++ plugins/importExport/index.php | 143 + plugins/importExport/progress.png | Bin 0 -> 858 bytes plugins/importExport/script.js | 3 + plugins/maintenance/_admin.php | 17 + plugins/maintenance/_define.php | 21 + plugins/maintenance/icon.png | Bin 0 -> 411 bytes plugins/maintenance/index.php | 164 + plugins/metadata/_admin.php | 413 +++ plugins/metadata/_define.php | 21 + plugins/metadata/_install.php | 47 + plugins/metadata/_prepend.php | 19 + plugins/metadata/_public.php | 345 ++ plugins/metadata/_widgets.php | 37 + plugins/metadata/_xmlrpc.php | 51 + plugins/metadata/class.dc.meta.php | 422 +++ plugins/metadata/index.php | 22 + plugins/metadata/post.js | 17 + plugins/metadata/style.css | 56 + plugins/metadata/tag-add.png | Bin 0 -> 568 bytes plugins/metadata/tag_posts.php | 156 + plugins/metadata/tags.php | 77 + plugins/metadata/tags.png | Bin 0 -> 477 bytes plugins/pages/_admin.php | 27 + plugins/pages/_define.php | 22 + plugins/pages/_prepend.php | 21 + plugins/pages/_public.php | 265 ++ plugins/pages/_widgets.php | 41 + plugins/pages/default-templates/page.html | 250 ++ plugins/pages/icon-big.png | Bin 0 -> 2032 bytes plugins/pages/icon.png | Bin 0 -> 383 bytes plugins/pages/index.php | 23 + plugins/pages/list.php | 203 ++ plugins/pages/page.php | 638 ++++ plugins/pings/_admin.php | 25 + plugins/pings/_define.php | 21 + plugins/pings/icon.png | Bin 0 -> 878 bytes plugins/pings/index.php | 113 + plugins/pings/lib.pings.php | 92 + plugins/pings/post.js | 2 + plugins/themeEditor/_admin.php | 26 + plugins/themeEditor/_define.php | 21 + plugins/themeEditor/class.themeEditor.php | 252 ++ plugins/themeEditor/help.html | 28 + plugins/themeEditor/index.php | 128 + plugins/themeEditor/script.js | 3 + plugins/themeEditor/style.css | 29 + plugins/widgets/_admin.php | 17 + plugins/widgets/_default_widgets.php | 90 + plugins/widgets/_define.php | 22 + plugins/widgets/_public.php | 115 + plugins/widgets/_widgets_functions.php | 368 ++ plugins/widgets/class.widgets.php | 234 ++ plugins/widgets/dragdrop.js | 29 + plugins/widgets/icon.png | Bin 0 -> 416 bytes plugins/widgets/index.php | 300 ++ plugins/widgets/style.css | 76 + plugins/widgets/widgets.js | 21 + public/.IMG4_m.jpg | Bin 0 -> 27064 bytes public/.IMG4_s.jpg | Bin 0 -> 7121 bytes public/.IMG4_sq.jpg | Bin 0 -> 1143 bytes public/.IMG4_t.jpg | Bin 0 -> 1725 bytes public/.La_fracture_52_m.jpg | Bin 0 -> 29634 bytes public/.La_fracture_52_s.jpg | Bin 0 -> 9353 bytes public/.La_fracture_52_sq.jpg | Bin 0 -> 1240 bytes public/.La_fracture_52_t.jpg | Bin 0 -> 2391 bytes public/.La_fracture_53_m.jpg | Bin 0 -> 42793 bytes public/.La_fracture_53_s.jpg | Bin 0 -> 11803 bytes public/.La_fracture_53_sq.jpg | Bin 0 -> 1282 bytes public/.La_fracture_53_t.jpg | Bin 0 -> 2591 bytes public/.La_fracture_54_m.jpg | Bin 0 -> 42074 bytes public/.La_fracture_54_s.jpg | Bin 0 -> 11744 bytes public/.La_fracture_54_sq.jpg | Bin 0 -> 1303 bytes public/.La_fracture_54_t.jpg | Bin 0 -> 2695 bytes public/.La_fracture_55_m.jpg | Bin 0 -> 43963 bytes public/.La_fracture_55_s.jpg | Bin 0 -> 12353 bytes public/.La_fracture_55_sq.jpg | Bin 0 -> 1306 bytes public/.La_fracture_55_t.jpg | Bin 0 -> 2699 bytes public/.La_fracture_56_m.jpg | Bin 0 -> 40747 bytes public/.La_fracture_56_s.jpg | Bin 0 -> 11553 bytes public/.La_fracture_56_sq.jpg | Bin 0 -> 1298 bytes public/.La_fracture_56_t.jpg | Bin 0 -> 2591 bytes public/.La_fracture_57_m.jpg | Bin 0 -> 38124 bytes public/.La_fracture_57_s.jpg | Bin 0 -> 10944 bytes public/.La_fracture_57_sq.jpg | Bin 0 -> 1304 bytes public/.La_fracture_57_t.jpg | Bin 0 -> 2510 bytes public/020323585666.pdf | Bin 0 -> 299817 bytes public/IMG4.jpg | Bin 0 -> 302521 bytes public/La_fracture_52.jpg | Bin 0 -> 139982 bytes public/La_fracture_53.jpg | Bin 0 -> 193597 bytes public/La_fracture_54.jpg | Bin 0 -> 191124 bytes public/La_fracture_55.jpg | Bin 0 -> 177701 bytes public/La_fracture_56.jpg | Bin 0 -> 184212 bytes public/La_fracture_57.jpg | Bin 0 -> 167252 bytes themes/altowithjquery/Change.txt | 18 + themes/altowithjquery/_define.php | 29 + themes/altowithjquery/custom.css | 15 + themes/altowithjquery/img/attach.png | Bin 0 -> 326 bytes themes/altowithjquery/img/background.gif | Bin 0 -> 483 bytes themes/altowithjquery/img/commentaire.png | Bin 0 -> 27900 bytes themes/altowithjquery/img/footer.png | Bin 0 -> 3891 bytes themes/altowithjquery/img/footer.psd | Bin 0 -> 103690 bytes themes/altowithjquery/img/page.png | Bin 0 -> 183 bytes themes/altowithjquery/img/q.png | Bin 0 -> 161 bytes themes/altowithjquery/img/retrolien.png | Bin 0 -> 28311 bytes themes/altowithjquery/img/rss.png | Bin 0 -> 659 bytes themes/altowithjquery/img/style.css | 671 ++++ themes/altowithjquery/img/tag.png | Bin 0 -> 28051 bytes themes/altowithjquery/img/top.png | Bin 0 -> 24221 bytes themes/altowithjquery/img/top.psd | Bin 0 -> 329229 bytes themes/altowithjquery/screenshot.jpg | Bin 0 -> 8999 bytes themes/altowithjquery/style.css | 679 ++++ themes/altowithjquery/tpl/_footer.html | 5 + themes/altowithjquery/tpl/_head.html | 16 + themes/altowithjquery/tpl/_top.html | 7 + themes/altowithjquery/tpl/archive_day.html | 123 + themes/altowithjquery/tpl/post.html | 297 ++ themes/customCSS/_config.php | 41 + themes/customCSS/_define.php | 20 + themes/customCSS/_public.php | 26 + themes/customCSS/locales/fr/main.lang.php | 22 + themes/customCSS/locales/fr/main.po | 20 + themes/customCSS/style.css | 0 themes/default/_define.php | 20 + themes/default/img/attach.png | Bin 0 -> 1329 bytes themes/default/img/body-bg.png | Bin 0 -> 211 bytes themes/default/img/comment-b.png | Bin 0 -> 175 bytes themes/default/img/comment-t.png | Bin 0 -> 422 bytes themes/default/img/comment.png | Bin 0 -> 1415 bytes themes/default/img/commentmy-b.png | Bin 0 -> 186 bytes themes/default/img/commentmy-t.png | Bin 0 -> 442 bytes themes/default/img/feed.png | Bin 0 -> 2046 bytes themes/default/img/page-b.png | Bin 0 -> 189 bytes themes/default/img/page-bg.png | Bin 0 -> 1263 bytes themes/default/img/page-t.png | Bin 0 -> 25574 bytes themes/default/img/tag.png | Bin 0 -> 381 bytes themes/default/img/trackback.png | Bin 0 -> 1269 bytes themes/default/js/jquery.cookie.js | 6 + themes/default/js/jquery.js | 432 +++ themes/default/js/post.js | 7 + themes/default/print.css | 50 + themes/default/screenshot.jpg | Bin 0 -> 16340 bytes themes/default/smilies/alien.png | Bin 0 -> 558 bytes themes/default/smilies/angry.png | Bin 0 -> 650 bytes themes/default/smilies/arrow.png | Bin 0 -> 600 bytes themes/default/smilies/confused.png | Bin 0 -> 522 bytes themes/default/smilies/cool.png | Bin 0 -> 624 bytes themes/default/smilies/cry.png | Bin 0 -> 700 bytes themes/default/smilies/dizzy.png | Bin 0 -> 634 bytes themes/default/smilies/eek.png | Bin 0 -> 565 bytes themes/default/smilies/evil.png | Bin 0 -> 623 bytes themes/default/smilies/exclam.png | Bin 0 -> 519 bytes themes/default/smilies/idea.png | Bin 0 -> 627 bytes themes/default/smilies/laugh.png | Bin 0 -> 590 bytes themes/default/smilies/lol.png | Bin 0 -> 567 bytes themes/default/smilies/mrgreen.png | Bin 0 -> 568 bytes themes/default/smilies/normal.png | Bin 0 -> 522 bytes themes/default/smilies/question.png | Bin 0 -> 580 bytes themes/default/smilies/razz.png | Bin 0 -> 601 bytes themes/default/smilies/redface.png | Bin 0 -> 492 bytes themes/default/smilies/rolleyes.png | Bin 0 -> 595 bytes themes/default/smilies/sad.png | Bin 0 -> 590 bytes themes/default/smilies/smile.png | Bin 0 -> 555 bytes themes/default/smilies/smilies.txt | 17 + themes/default/smilies/surprised.png | Bin 0 -> 637 bytes themes/default/smilies/wink.png | Bin 0 -> 546 bytes themes/default/style.css | 576 +++ themes/default/tpl/.htaccess | 1 + themes/default/tpl/404.html | 63 + themes/default/tpl/_flv_player.html | 7 + themes/default/tpl/_footer.html | 5 + themes/default/tpl/_head.html | 12 + themes/default/tpl/_mp3_player.html | 5 + themes/default/tpl/_top.html | 10 + themes/default/tpl/archive.html | 80 + themes/default/tpl/archive_month.html | 97 + themes/default/tpl/category.html | 168 + themes/default/tpl/home.html | 145 + themes/default/tpl/post.html | 277 ++ themes/default/tpl/search.html | 153 + themes/default/tpl/tag.html | 154 + themes/default/tpl/tags.html | 70 + themes/default/tpl/user_head.html | 1 + v2/dotclear/CHANGELOG | 385 ++ v2/dotclear/CREDITS | 46 + v2/dotclear/LICENSE | 339 ++ v2/dotclear/README | 22 + v2/dotclear/admin/auth.php | 431 +++ v2/dotclear/admin/blog.php | 96 + v2/dotclear/admin/blog_del.php | 73 + v2/dotclear/admin/blog_pref.php | 553 +++ v2/dotclear/admin/blog_theme.php | 363 ++ v2/dotclear/admin/blogs.php | 185 + v2/dotclear/admin/categories.php | 190 + v2/dotclear/admin/category.php | 260 ++ v2/dotclear/admin/comment.php | 236 ++ v2/dotclear/admin/comments.php | 251 ++ v2/dotclear/admin/comments_actions.php | 136 + v2/dotclear/admin/dispatcher.php | 34 + v2/dotclear/admin/images/add.png | Bin 0 -> 1193 bytes v2/dotclear/admin/images/admin.png | Bin 0 -> 625 bytes v2/dotclear/admin/images/attach.png | Bin 0 -> 370 bytes v2/dotclear/admin/images/check-off.png | Bin 0 -> 450 bytes v2/dotclear/admin/images/check-on.png | Bin 0 -> 1121 bytes v2/dotclear/admin/images/check-wrn.png | Bin 0 -> 394 bytes v2/dotclear/admin/images/date-picker.png | Bin 0 -> 1199 bytes v2/dotclear/admin/images/dotclear_pw.png | Bin 0 -> 1525 bytes v2/dotclear/admin/images/edit-mini.png | Bin 0 -> 614 bytes v2/dotclear/admin/images/favicon.png | Bin 0 -> 858 bytes v2/dotclear/admin/images/help.png | Bin 0 -> 1600 bytes v2/dotclear/admin/images/junk.png | Bin 0 -> 498 bytes v2/dotclear/admin/images/locker.png | Bin 0 -> 354 bytes v2/dotclear/admin/images/logout.png | Bin 0 -> 915 bytes v2/dotclear/admin/images/media/audio.png | Bin 0 -> 1170 bytes v2/dotclear/admin/images/media/blank.png | Bin 0 -> 1273 bytes v2/dotclear/admin/images/media/document.png | Bin 0 -> 762 bytes v2/dotclear/admin/images/media/executable.png | Bin 0 -> 1240 bytes v2/dotclear/admin/images/media/folder.png | Bin 0 -> 1011 bytes v2/dotclear/admin/images/media/html.png | Bin 0 -> 1811 bytes v2/dotclear/admin/images/media/image.png | Bin 0 -> 1467 bytes v2/dotclear/admin/images/media/package.png | Bin 0 -> 1153 bytes .../admin/images/media/presentation.png | Bin 0 -> 1141 bytes .../admin/images/media/spreadsheet.png | Bin 0 -> 1624 bytes v2/dotclear/admin/images/media/text.png | Bin 0 -> 1095 bytes v2/dotclear/admin/images/media/video.png | Bin 0 -> 1250 bytes .../admin/images/menu/add_to_favorites.png | Bin 0 -> 3473 bytes v2/dotclear/admin/images/menu/blog-pref-b.png | Bin 0 -> 5339 bytes v2/dotclear/admin/images/menu/blog-pref.png | Bin 0 -> 1621 bytes .../admin/images/menu/blog-theme-b.png | Bin 0 -> 3925 bytes v2/dotclear/admin/images/menu/blogs-b.png | Bin 0 -> 4371 bytes v2/dotclear/admin/images/menu/blogs.png | Bin 0 -> 1344 bytes .../admin/images/menu/categories-b.png | Bin 0 -> 3859 bytes v2/dotclear/admin/images/menu/categories.png | Bin 0 -> 1472 bytes v2/dotclear/admin/images/menu/comments-b.png | Bin 0 -> 3344 bytes v2/dotclear/admin/images/menu/comments.png | Bin 0 -> 1445 bytes v2/dotclear/admin/images/menu/dashboard.png | Bin 0 -> 256 bytes v2/dotclear/admin/images/menu/edit-b.png | Bin 0 -> 3356 bytes v2/dotclear/admin/images/menu/edit.png | Bin 0 -> 1591 bytes v2/dotclear/admin/images/menu/entries-b.png | Bin 0 -> 3027 bytes v2/dotclear/admin/images/menu/entries.png | Bin 0 -> 1547 bytes v2/dotclear/admin/images/menu/favorite-b.png | Bin 0 -> 6047 bytes v2/dotclear/admin/images/menu/favorite.png | Bin 0 -> 3311 bytes v2/dotclear/admin/images/menu/langs-b.png | Bin 0 -> 8168 bytes v2/dotclear/admin/images/menu/langs.png | Bin 0 -> 1479 bytes v2/dotclear/admin/images/menu/media-b.png | Bin 0 -> 6778 bytes v2/dotclear/admin/images/menu/media.png | Bin 0 -> 1532 bytes v2/dotclear/admin/images/menu/plugins-b.png | Bin 0 -> 8750 bytes v2/dotclear/admin/images/menu/plugins.png | Bin 0 -> 1663 bytes v2/dotclear/admin/images/menu/search-b.png | Bin 0 -> 6716 bytes v2/dotclear/admin/images/menu/search.png | Bin 0 -> 1713 bytes v2/dotclear/admin/images/menu/themes.png | Bin 0 -> 1442 bytes v2/dotclear/admin/images/menu/update.png | Bin 0 -> 3364 bytes v2/dotclear/admin/images/menu/user-pref-b.png | Bin 0 -> 6605 bytes v2/dotclear/admin/images/menu/user-pref.png | Bin 0 -> 1597 bytes v2/dotclear/admin/images/menu/users-b.png | Bin 0 -> 5292 bytes v2/dotclear/admin/images/menu/users.png | Bin 0 -> 1584 bytes v2/dotclear/admin/images/menu_off.png | Bin 0 -> 1346 bytes v2/dotclear/admin/images/menu_on.png | Bin 0 -> 1334 bytes v2/dotclear/admin/images/minus.png | Bin 0 -> 284 bytes v2/dotclear/admin/images/noscreenshot.png | Bin 0 -> 1395 bytes v2/dotclear/admin/images/outgoing-blue.png | Bin 0 -> 972 bytes v2/dotclear/admin/images/outgoing.png | Bin 0 -> 965 bytes v2/dotclear/admin/images/picker.png | Bin 0 -> 1520 bytes v2/dotclear/admin/images/plus.png | Bin 0 -> 297 bytes v2/dotclear/admin/images/scheduled.png | Bin 0 -> 316 bytes v2/dotclear/admin/images/selected.png | Bin 0 -> 259 bytes v2/dotclear/admin/images/superadmin.png | Bin 0 -> 638 bytes v2/dotclear/admin/images/trash.png | Bin 0 -> 718 bytes v2/dotclear/admin/index.php | 360 ++ v2/dotclear/admin/install/check.php | 83 + v2/dotclear/admin/install/index.php | 401 +++ v2/dotclear/admin/install/wizard.php | 190 + v2/dotclear/admin/js/_blog_pref.js | 4 + v2/dotclear/admin/js/_blog_theme.js | 6 + v2/dotclear/admin/js/_categories.js | 2 + v2/dotclear/admin/js/_category.js | 2 + v2/dotclear/admin/js/_comment.js | 3 + v2/dotclear/admin/js/_comments.js | 6 + v2/dotclear/admin/js/_index.js | 10 + v2/dotclear/admin/js/_langs.js | 2 + v2/dotclear/admin/js/_media.js | 7 + v2/dotclear/admin/js/_media_item.js | 4 + v2/dotclear/admin/js/_permissions.js | 6 + v2/dotclear/admin/js/_permissions_blog.js | 2 + v2/dotclear/admin/js/_plugins.js | 2 + v2/dotclear/admin/js/_post.js | 16 + v2/dotclear/admin/js/_posts_list.js | 7 + v2/dotclear/admin/js/_preferences-dragdrop.js | 2 + v2/dotclear/admin/js/_preferences.js | 5 + v2/dotclear/admin/js/_trackbacks.js | 2 + v2/dotclear/admin/js/_users.js | 7 + v2/dotclear/admin/js/color-picker.js | 6 + v2/dotclear/admin/js/common.js | 21 + v2/dotclear/admin/js/confirm-close.js | 12 + v2/dotclear/admin/js/date-picker.js | 41 + v2/dotclear/admin/js/dragsort-tablerows.js | 2 + v2/dotclear/admin/js/filter-controls.js | 2 + v2/dotclear/admin/js/ie7/IE7.js | 74 + v2/dotclear/admin/js/ie7/IE8.js | 86 + v2/dotclear/admin/js/ie7/blank.gif | Bin 0 -> 48 bytes v2/dotclear/admin/js/ie7/ie7-recalc.js | 5 + v2/dotclear/admin/js/ie7/ie7-squish.js | 3 + .../js/jquery/jquery-ui-1.8.12.custom.min.js | 8 + v2/dotclear/admin/js/jquery/jquery.bgFade.js | 7 + v2/dotclear/admin/js/jquery/jquery.biscuit.js | 5 + .../admin/js/jquery/jquery.candyUpload.js | 22 + .../admin/js/jquery/jquery.farbtastic.js | 22 + v2/dotclear/admin/js/jquery/jquery.js | 471 +++ v2/dotclear/admin/js/jquery/jquery.modal.js | 17 + .../admin/js/jquery/jquery.pageTabs.js | 4 + .../admin/js/jsToolBar/jsToolBar.dotclear.js | 35 + v2/dotclear/admin/js/jsToolBar/jsToolBar.js | 29 + .../admin/js/jsToolBar/jsToolBar.wysiwyg.js | 47 + v2/dotclear/admin/js/jsToolBar/popup_link.js | 3 + v2/dotclear/admin/js/jsToolBar/popup_media.js | 13 + v2/dotclear/admin/js/jsToolBar/popup_posts.js | 2 + v2/dotclear/admin/js/meta-editor.js | 14 + v2/dotclear/admin/js/prelude.js | 6 + v2/dotclear/admin/js/tool-man/cookies.js | 11 + v2/dotclear/admin/js/tool-man/coordinates.js | 19 + v2/dotclear/admin/js/tool-man/core.js | 35 + v2/dotclear/admin/js/tool-man/css.js | 3 + v2/dotclear/admin/js/tool-man/drag.js | 84 + v2/dotclear/admin/js/tool-man/dragsort.js | 35 + v2/dotclear/admin/js/tool-man/events.js | 8 + v2/dotclear/admin/langs.php | 289 ++ v2/dotclear/admin/media.php | 472 +++ v2/dotclear/admin/media_item.php | 528 +++ v2/dotclear/admin/permissions.php | 160 + v2/dotclear/admin/permissions_blog.php | 196 ++ v2/dotclear/admin/plugin.php | 91 + v2/dotclear/admin/plugins.php | 364 ++ v2/dotclear/admin/popup_link.php | 62 + v2/dotclear/admin/popup_posts.php | 57 + v2/dotclear/admin/post.php | 624 ++++ v2/dotclear/admin/post_media.php | 79 + v2/dotclear/admin/posts.php | 324 ++ v2/dotclear/admin/posts_actions.php | 259 ++ v2/dotclear/admin/preferences.php | 631 ++++ v2/dotclear/admin/search.php | 180 + v2/dotclear/admin/services.php | 395 +++ v2/dotclear/admin/style/add.png | Bin 0 -> 1113 bytes .../admin/style/candyUpload/cancel.png | Bin 0 -> 309 bytes .../admin/style/candyUpload/loader.png | Bin 0 -> 858 bytes v2/dotclear/admin/style/candyUpload/style.css | 113 + v2/dotclear/admin/style/date-picker.css | 35 + v2/dotclear/admin/style/dc_bg.png | Bin 0 -> 131 bytes v2/dotclear/admin/style/dc_logo.png | Bin 0 -> 825 bytes v2/dotclear/admin/style/dc_logo_small.png | Bin 0 -> 839 bytes v2/dotclear/admin/style/default-rtl.css | 11 + v2/dotclear/admin/style/default.css | 1361 ++++++++ v2/dotclear/admin/style/dotclear-logo.png | Bin 0 -> 2900 bytes v2/dotclear/admin/style/dotclear-logo2.png | Bin 0 -> 1615 bytes v2/dotclear/admin/style/drag.png | Bin 0 -> 611 bytes .../admin/style/farbtastic/farbtastic.css | 33 + v2/dotclear/admin/style/farbtastic/marker.png | Bin 0 -> 614 bytes v2/dotclear/admin/style/farbtastic/mask.png | Bin 0 -> 2020 bytes v2/dotclear/admin/style/farbtastic/wheel.png | Bin 0 -> 11733 bytes v2/dotclear/admin/style/grid.png | Bin 0 -> 202 bytes v2/dotclear/admin/style/head-bg.png | Bin 0 -> 1325 bytes v2/dotclear/admin/style/iesucks.css | 46 + v2/dotclear/admin/style/info.png | Bin 0 -> 724 bytes v2/dotclear/admin/style/install.css | 165 + v2/dotclear/admin/style/install/important.png | Bin 0 -> 1418 bytes v2/dotclear/admin/style/install/note.png | Bin 0 -> 1561 bytes .../admin/style/install/process_warning.png | Bin 0 -> 4937 bytes v2/dotclear/admin/style/install/w-logo.png | Bin 0 -> 1615 bytes .../admin/style/jsToolBar/bt_bquote.png | Bin 0 -> 261 bytes v2/dotclear/admin/style/jsToolBar/bt_br.png | Bin 0 -> 243 bytes .../admin/style/jsToolBar/bt_clean.png | Bin 0 -> 576 bytes v2/dotclear/admin/style/jsToolBar/bt_code.png | Bin 0 -> 338 bytes v2/dotclear/admin/style/jsToolBar/bt_del.png | Bin 0 -> 351 bytes v2/dotclear/admin/style/jsToolBar/bt_em.png | Bin 0 -> 300 bytes v2/dotclear/admin/style/jsToolBar/bt_img.png | Bin 0 -> 899 bytes .../admin/style/jsToolBar/bt_img_select.png | Bin 0 -> 518 bytes v2/dotclear/admin/style/jsToolBar/bt_ins.png | Bin 0 -> 308 bytes v2/dotclear/admin/style/jsToolBar/bt_link.png | Bin 0 -> 833 bytes v2/dotclear/admin/style/jsToolBar/bt_ol.png | Bin 0 -> 249 bytes .../admin/style/jsToolBar/bt_paragraph.png | Bin 0 -> 295 bytes v2/dotclear/admin/style/jsToolBar/bt_post.png | Bin 0 -> 1507 bytes v2/dotclear/admin/style/jsToolBar/bt_pre.png | Bin 0 -> 244 bytes .../admin/style/jsToolBar/bt_quote.png | Bin 0 -> 322 bytes .../admin/style/jsToolBar/bt_strong.png | Bin 0 -> 336 bytes v2/dotclear/admin/style/jsToolBar/bt_ul.png | Bin 0 -> 239 bytes .../admin/style/jsToolBar/jsToolBar.css | 173 + v2/dotclear/admin/style/jsToolBar/resize.png | Bin 0 -> 1267 bytes v2/dotclear/admin/style/magnifier.png | Bin 0 -> 499 bytes v2/dotclear/admin/style/modal/close.png | Bin 0 -> 1179 bytes v2/dotclear/admin/style/modal/loader.gif | Bin 0 -> 9427 bytes v2/dotclear/admin/style/modal/modal.css | 52 + v2/dotclear/admin/style/msg-error.png | Bin 0 -> 4159 bytes v2/dotclear/admin/style/msg-std.png | Bin 0 -> 1135 bytes v2/dotclear/admin/style/package.png | Bin 0 -> 771 bytes v2/dotclear/admin/style/page-bg.png | Bin 0 -> 1254 bytes v2/dotclear/admin/style/warning.png | Bin 0 -> 678 bytes v2/dotclear/admin/trackbacks.php | 150 + v2/dotclear/admin/update.php | 222 ++ v2/dotclear/admin/user.php | 331 ++ v2/dotclear/admin/users.php | 174 + v2/dotclear/admin/xmlrpc.php | 35 + v2/dotclear/cache/.htaccess | 1 + v2/dotclear/db/.htaccess | 1 + v2/dotclear/inc/.htaccess | 1 + v2/dotclear/inc/admin/class.dc.menu.php | 88 + v2/dotclear/inc/admin/lib.dc.page.php | 709 ++++ v2/dotclear/inc/admin/lib.pager.php | 420 +++ v2/dotclear/inc/admin/prepend.php | 376 ++ v2/dotclear/inc/config.php.in | 70 + v2/dotclear/inc/core/class.dc.auth.php | 632 ++++ v2/dotclear/inc/core/class.dc.blog.php | 2089 +++++++++++ v2/dotclear/inc/core/class.dc.categories.php | 483 +++ v2/dotclear/inc/core/class.dc.core.php | 1467 ++++++++ v2/dotclear/inc/core/class.dc.error.php | 133 + v2/dotclear/inc/core/class.dc.log.php | 204 ++ v2/dotclear/inc/core/class.dc.media.php | 1093 ++++++ v2/dotclear/inc/core/class.dc.meta.php | 615 ++++ v2/dotclear/inc/core/class.dc.modules.php | 563 +++ v2/dotclear/inc/core/class.dc.namespace.php | 308 ++ v2/dotclear/inc/core/class.dc.postmedia.php | 172 + v2/dotclear/inc/core/class.dc.prefs.php | 134 + v2/dotclear/inc/core/class.dc.rest.php | 52 + .../inc/core/class.dc.rs.extensions.php | 870 +++++ v2/dotclear/inc/core/class.dc.settings.php | 384 ++ v2/dotclear/inc/core/class.dc.themes.php | 102 + v2/dotclear/inc/core/class.dc.trackback.php | 404 +++ v2/dotclear/inc/core/class.dc.update.php | 478 +++ v2/dotclear/inc/core/class.dc.utils.php | 53 + v2/dotclear/inc/core/class.dc.workspace.php | 368 ++ v2/dotclear/inc/core/class.dc.xmlrpc.php | 1632 +++++++++ v2/dotclear/inc/core_error.php | 62 + v2/dotclear/inc/dbschema/db-schema.php | 282 ++ v2/dotclear/inc/dbschema/upgrade-cli.php | 52 + v2/dotclear/inc/dbschema/upgrade.php | 331 ++ v2/dotclear/inc/digests | 694 ++++ v2/dotclear/inc/libs/clearbricks/Makefile | 44 + v2/dotclear/inc/libs/clearbricks/README | 67 + v2/dotclear/inc/libs/clearbricks/_common.php | 123 + .../inc/libs/clearbricks/common/_main.php | 58 + .../inc/libs/clearbricks/common/lib.crypt.php | 77 + .../inc/libs/clearbricks/common/lib.date.php | 260 ++ .../inc/libs/clearbricks/common/lib.files.php | 667 ++++ .../inc/libs/clearbricks/common/lib.form.php | 347 ++ .../inc/libs/clearbricks/common/lib.html.php | 185 + .../inc/libs/clearbricks/common/lib.http.php | 452 +++ .../inc/libs/clearbricks/common/lib.l10n.php | 453 +++ .../inc/libs/clearbricks/common/lib.text.php | 355 ++ .../inc/libs/clearbricks/common/tz.dat | 407 +++ .../libs/clearbricks/dblayer/class.cursor.php | 258 ++ .../libs/clearbricks/dblayer/class.mysql.php | 253 ++ .../libs/clearbricks/dblayer/class.mysqli.php | 284 ++ .../libs/clearbricks/dblayer/class.pgsql.php | 280 ++ .../libs/clearbricks/dblayer/class.sqlite.php | 278 ++ .../inc/libs/clearbricks/dblayer/dblayer.php | 1208 +++++++ .../clearbricks/dbschema/class.dbschema.php | 310 ++ .../clearbricks/dbschema/class.dbstruct.php | 639 ++++ .../dbschema/class.mysql.dbschema.php | 470 +++ .../dbschema/class.mysqli.dbschema.php | 21 + .../dbschema/class.pgsql.dbschema.php | 400 +++ .../dbschema/class.sqlite.dbschema.php | 514 +++ .../inc/libs/clearbricks/debian/changelog | 466 +++ .../inc/libs/clearbricks/debian/compat | 1 + .../inc/libs/clearbricks/debian/control | 14 + .../inc/libs/clearbricks/debian/copyright | 27 + v2/dotclear/inc/libs/clearbricks/debian/dirs | 1 + v2/dotclear/inc/libs/clearbricks/debian/docs | 1 + .../inc/libs/clearbricks/debian/mkdcl.php | 198 ++ v2/dotclear/inc/libs/clearbricks/debian/rules | 62 + .../inc/libs/clearbricks/diff/lib.diff.php | 366 ++ .../libs/clearbricks/diff/lib.tidy.diff.php | 353 ++ .../clearbricks/ext/incutio.ixr_library.php | 856 +++++ .../filemanager/class.filemanager.php | 618 ++++ .../html.filter/class.html.filter.php | 676 ++++ .../html.validator/class.html.validator.php | 143 + .../clearbricks/image/class.image.meta.php | 406 +++ .../clearbricks/image/class.image.tools.php | 299 ++ .../mail.convert/class.mail.convert.php | 201 ++ .../mail.mime/class.mime.message.php | 467 +++ .../inc/libs/clearbricks/mail/class.mail.php | 117 + .../clearbricks/mail/class.socket.mail.php | 181 + .../net.http.feed/class.feed.parser.php | 288 ++ .../net.http.feed/class.feed.reader.php | 276 ++ .../clearbricks/net.http/class.net.http.php | 918 +++++ .../clearbricks/net.nntp/class.net.nntp.php | 448 +++ .../net.nntp/class.nntp.message.php | 48 + .../net.xmlrpc/class.net.xmlrpc.php | 1349 +++++++ .../libs/clearbricks/net/class.net.socket.php | 315 ++ .../libs/clearbricks/pager/class.pager.php | 215 ++ .../inc/libs/clearbricks/rest/class.rest.php | 292 ++ .../session.db/class.session.db.php | 232 ++ .../clearbricks/template/class.template.php | 324 ++ .../text.wiki2xhtml/class.wiki2xhtml.php | 1305 +++++++ .../url.handler/class.url.handler.php | 229 ++ .../libs/clearbricks/xmlsql/class.xmlsql.php | 180 + .../inc/libs/clearbricks/zip/class.unzip.php | 541 +++ .../inc/libs/clearbricks/zip/class.zip.php | 370 ++ v2/dotclear/inc/load_plugin_file.php | 87 + v2/dotclear/inc/prepend.php | 286 ++ v2/dotclear/inc/public/class.dc.template.php | 3095 +++++++++++++++++ .../inc/public/default-templates/404.html | 62 + .../public/default-templates/_flv_player.html | 8 + .../inc/public/default-templates/_footer.html | 5 + .../inc/public/default-templates/_head.html | 12 + .../public/default-templates/_mp3_player.html | 6 + .../inc/public/default-templates/_top.html | 10 + .../inc/public/default-templates/archive.html | 79 + .../default-templates/archive_month.html | 96 + .../default-templates/atom-comments.xml | 47 + .../inc/public/default-templates/atom.xml | 50 + .../public/default-templates/category.html | 167 + .../inc/public/default-templates/home.html | 144 + .../default-templates/password-form.html | 41 + .../inc/public/default-templates/post.html | 274 ++ .../default-templates/rss2-comments.xml | 48 + .../inc/public/default-templates/rss2.xml | 49 + .../inc/public/default-templates/rss2.xsl | 120 + .../inc/public/default-templates/search.html | 152 + .../public/default-templates/user_head.html | 1 + v2/dotclear/inc/public/lib.tpl.context.php | 443 +++ v2/dotclear/inc/public/lib.urlhandlers.php | 683 ++++ v2/dotclear/inc/public/prepend.php | 156 + v2/dotclear/inc/public/rs.extension.php | 93 + v2/dotclear/inc/swf/player_flv.swf | Bin 0 -> 12975 bytes v2/dotclear/inc/swf/player_mp3.swf | Bin 0 -> 6379 bytes v2/dotclear/inc/swf/swfupload.swf | Bin 0 -> 12787 bytes v2/dotclear/index.php | 23 + v2/dotclear/locales/README | 1 + v2/dotclear/locales/en/date.lang.php | 38 + v2/dotclear/locales/en/date.po | 116 + v2/dotclear/locales/en/help/blog_pref.html | 148 + v2/dotclear/locales/en/help/categories.html | 47 + v2/dotclear/locales/en/help/comments.html | 58 + v2/dotclear/locales/en/help/media.html | 90 + v2/dotclear/locales/en/help/post.html | 125 + v2/dotclear/locales/en/help/posts.html | 65 + v2/dotclear/locales/en/help/user.html | 71 + v2/dotclear/locales/en/help/user_pref.html | 84 + v2/dotclear/locales/en/help/wiki.html | 85 + v2/dotclear/locales/en/main.lang.php | 19 + v2/dotclear/locales/en/main.po | 2785 +++++++++++++++ v2/dotclear/locales/en/plugins.lang.php | 45 + v2/dotclear/locales/en/plugins.po | 1573 +++++++++ v2/dotclear/locales/en/public.lang.php | 19 + v2/dotclear/locales/en/public.po | 243 ++ v2/dotclear/locales/en/resources.php | 35 + v2/dotclear/locales/fr/date.lang.php | 58 + v2/dotclear/locales/fr/date.po | 136 + v2/dotclear/locales/fr/help/blowupConfig.html | 71 + .../locales/fr/help/core_blog_pref.html | 191 + .../locales/fr/help/core_categories.html | 50 + .../locales/fr/help/core_comments.html | 59 + v2/dotclear/locales/fr/help/core_media.html | 97 + v2/dotclear/locales/fr/help/core_post.html | 137 + v2/dotclear/locales/fr/help/core_posts.html | 65 + v2/dotclear/locales/fr/help/core_user.html | 74 + .../locales/fr/help/core_user_pref.html | 91 + v2/dotclear/locales/fr/help/core_wiki.html | 85 + v2/dotclear/locales/fr/help/themeEditor.html | 37 + v2/dotclear/locales/fr/main.lang.php | 923 +++++ v2/dotclear/locales/fr/main.po | 2896 +++++++++++++++ v2/dotclear/locales/fr/plugins.lang.php | 530 +++ v2/dotclear/locales/fr/plugins.po | 1769 ++++++++++ v2/dotclear/locales/fr/public.lang.php | 94 + v2/dotclear/locales/fr/public.po | 241 ++ v2/dotclear/locales/fr/resources.php | 23 + v2/dotclear/plugins/.htaccess | 1 + v2/dotclear/plugins/aboutConfig/_admin.php | 17 + v2/dotclear/plugins/aboutConfig/_define.php | 20 + v2/dotclear/plugins/aboutConfig/icon-big.png | Bin 0 -> 9886 bytes v2/dotclear/plugins/aboutConfig/icon.png | Bin 0 -> 1679 bytes v2/dotclear/plugins/aboutConfig/index.php | 240 ++ v2/dotclear/plugins/akismet/_define.php | 24 + v2/dotclear/plugins/akismet/_prepend.php | 17 + .../akismet/class.dc.filter.akismet.php | 260 ++ v2/dotclear/plugins/antispam/_admin.php | 73 + v2/dotclear/plugins/antispam/_define.php | 24 + v2/dotclear/plugins/antispam/_install.php | 56 + v2/dotclear/plugins/antispam/_prepend.php | 30 + v2/dotclear/plugins/antispam/_public.php | 17 + v2/dotclear/plugins/antispam/antispam.js | 3 + v2/dotclear/plugins/antispam/feed.png | Bin 0 -> 404 bytes .../antispam/filters/class.dc.filter.ip.php | 312 ++ .../filters/class.dc.filter.iplookup.php | 121 + .../filters/class.dc.filter.linkslookup.php | 74 + .../filters/class.dc.filter.words.php | 356 ++ v2/dotclear/plugins/antispam/icon-big.png | Bin 0 -> 5758 bytes v2/dotclear/plugins/antispam/icon.png | Bin 0 -> 1734 bytes .../antispam/inc/class.dc.spamfilter.php | 161 + .../antispam/inc/class.dc.spamfilters.php | 164 + .../plugins/antispam/inc/lib.dc.antispam.php | 211 ++ .../antispam/inc/lib.dc.antispam.url.php | 99 + v2/dotclear/plugins/antispam/index.php | 233 ++ v2/dotclear/plugins/antispam/style.css | 23 + v2/dotclear/plugins/attachments/_admin.php | 75 + v2/dotclear/plugins/attachments/_define.php | 24 + v2/dotclear/plugins/attachments/_public.php | 248 ++ v2/dotclear/plugins/blogroll/_admin.php | 34 + v2/dotclear/plugins/blogroll/_define.php | 23 + v2/dotclear/plugins/blogroll/_install.php | 46 + v2/dotclear/plugins/blogroll/_prepend.php | 15 + v2/dotclear/plugins/blogroll/_public.php | 233 ++ v2/dotclear/plugins/blogroll/_widgets.php | 44 + .../plugins/blogroll/class.dc.blogroll.php | 198 ++ .../blogroll/class.dc.importblogroll.php | 101 + v2/dotclear/plugins/blogroll/edit.php | 241 ++ v2/dotclear/plugins/blogroll/icon-small.png | Bin 0 -> 1810 bytes v2/dotclear/plugins/blogroll/icon.png | Bin 0 -> 7485 bytes v2/dotclear/plugins/blogroll/index.php | 414 +++ .../blogroll/locales/en/help/blogroll.html | 41 + .../plugins/blogroll/locales/en/resources.php | 18 + .../blogroll/locales/fr/help/blogroll.html | 38 + .../plugins/blogroll/locales/fr/resources.php | 18 + v2/dotclear/plugins/blowupConfig/_admin.php | 26 + v2/dotclear/plugins/blowupConfig/_define.php | 23 + v2/dotclear/plugins/blowupConfig/_install.php | 25 + v2/dotclear/plugins/blowupConfig/_public.php | 196 ++ .../blowupConfig/alpha-img/comment-b.png | Bin 0 -> 1328 bytes .../blowupConfig/alpha-img/comment-t.png | Bin 0 -> 1549 bytes .../blowupConfig/alpha-img/gradient-d.png | Bin 0 -> 1432 bytes .../blowupConfig/alpha-img/gradient-l.png | Bin 0 -> 1443 bytes .../blowupConfig/alpha-img/gradient-m.png | Bin 0 -> 1446 bytes .../plugins/blowupConfig/alpha-img/page-b.png | Bin 0 -> 1340 bytes .../blowupConfig/alpha-img/page-bg.png | Bin 0 -> 1263 bytes .../blowupConfig/alpha-img/page-t/animals.png | Bin 0 -> 28044 bytes .../blowupConfig/alpha-img/page-t/blank.png | Bin 0 -> 1892 bytes .../alpha-img/page-t/butterflies.png | Bin 0 -> 6350 bytes .../blowupConfig/alpha-img/page-t/default.png | Bin 0 -> 1926 bytes .../alpha-img/page-t/flamingo.png | Bin 0 -> 12864 bytes .../alpha-img/page-t/flourish-1.png | Bin 0 -> 5045 bytes .../alpha-img/page-t/flourish-2.png | Bin 0 -> 12838 bytes .../alpha-img/page-t/image-mask.png | Bin 0 -> 1982 bytes .../alpha-img/page-t/light-trails-1.png | Bin 0 -> 28612 bytes .../alpha-img/page-t/light-trails-2.png | Bin 0 -> 40999 bytes .../alpha-img/page-t/light-trails-3.png | Bin 0 -> 38308 bytes .../alpha-img/page-t/light-trails-4.png | Bin 0 -> 32171 bytes .../blowupConfig/alpha-img/page-t/rabbit.png | Bin 0 -> 3208 bytes .../alpha-img/page-t/roadrunner-1.png | Bin 0 -> 6337 bytes .../alpha-img/page-t/roadrunner-2.png | Bin 0 -> 8997 bytes .../blowupConfig/alpha-img/page-t/typo.png | Bin 0 -> 15365 bytes v2/dotclear/plugins/blowupConfig/config.js | 11 + v2/dotclear/plugins/blowupConfig/help.html | 55 + v2/dotclear/plugins/blowupConfig/index.php | 464 +++ .../blowupConfig/lib/class.blowup.config.php | 429 +++ .../plugins/fairTrackbacks/_define.php | 24 + .../plugins/fairTrackbacks/_prepend.php | 22 + .../plugins/fairTrackbacks/_public.php | 18 + .../class.dc.filter.fairtrackbacks.php | 85 + v2/dotclear/plugins/importExport/_admin.php | 35 + v2/dotclear/plugins/importExport/_define.php | 21 + v2/dotclear/plugins/importExport/_prepend.php | 42 + v2/dotclear/plugins/importExport/icon-big.png | Bin 0 -> 6024 bytes v2/dotclear/plugins/importExport/icon.png | Bin 0 -> 1666 bytes .../importExport/inc/class.dc.export.flat.php | 241 ++ .../importExport/inc/class.dc.ieModule.php | 80 + .../importExport/inc/class.dc.import.dc1.php | 625 ++++ .../importExport/inc/class.dc.import.feed.php | 99 + .../importExport/inc/class.dc.import.flat.php | 325 ++ .../importExport/inc/class.dc.import.wp.php | 788 +++++ .../inc/flat/class.flat.backup.php | 148 + .../inc/flat/class.flat.export.php | 106 + .../inc/flat/class.flat.import.php | 869 +++++ .../plugins/importExport/inc/img/progress.png | Bin 0 -> 858 bytes v2/dotclear/plugins/importExport/index.php | 95 + v2/dotclear/plugins/importExport/js/script.js | 3 + .../importExport/locales/fr/main.lang.php | 92 + .../plugins/importExport/locales/fr/main.po | 333 ++ v2/dotclear/plugins/importExport/style.css | 25 + v2/dotclear/plugins/maintenance/_admin.php | 26 + v2/dotclear/plugins/maintenance/_define.php | 20 + v2/dotclear/plugins/maintenance/icon-big.png | Bin 0 -> 6729 bytes v2/dotclear/plugins/maintenance/icon.png | Bin 0 -> 1626 bytes v2/dotclear/plugins/maintenance/index.php | 186 + .../locales/en/help/maintenance.html | 41 + .../maintenance/locales/en/resources.php | 18 + .../locales/fr/help/maintenance.html | 39 + .../maintenance/locales/fr/resources.php | 18 + v2/dotclear/plugins/pages/_admin.php | 51 + v2/dotclear/plugins/pages/_define.php | 24 + v2/dotclear/plugins/pages/_prepend.php | 21 + v2/dotclear/plugins/pages/_public.php | 267 ++ v2/dotclear/plugins/pages/_widgets.php | 41 + .../plugins/pages/default-templates/page.html | 247 ++ v2/dotclear/plugins/pages/icon-big.png | Bin 0 -> 2736 bytes v2/dotclear/plugins/pages/icon-np-big.png | Bin 0 -> 2635 bytes v2/dotclear/plugins/pages/icon-np.png | Bin 0 -> 1369 bytes v2/dotclear/plugins/pages/icon.png | Bin 0 -> 1509 bytes v2/dotclear/plugins/pages/index.php | 23 + v2/dotclear/plugins/pages/list.php | 205 ++ .../plugins/pages/locales/en/help/page.html | 165 + .../plugins/pages/locales/en/help/pages.html | 22 + .../plugins/pages/locales/en/resources.php | 21 + .../plugins/pages/locales/fr/help/page.html | 172 + .../plugins/pages/locales/fr/help/pages.html | 22 + .../plugins/pages/locales/fr/resources.php | 21 + v2/dotclear/plugins/pages/page.php | 659 ++++ v2/dotclear/plugins/pings/_admin.php | 47 + v2/dotclear/plugins/pings/_define.php | 23 + v2/dotclear/plugins/pings/icon-big.png | Bin 0 -> 5223 bytes v2/dotclear/plugins/pings/icon.png | Bin 0 -> 1370 bytes v2/dotclear/plugins/pings/index.php | 101 + v2/dotclear/plugins/pings/lib.pings.php | 99 + v2/dotclear/plugins/pings/post.js | 3 + v2/dotclear/plugins/simpleMenu/_admin.php | 32 + v2/dotclear/plugins/simpleMenu/_define.php | 23 + v2/dotclear/plugins/simpleMenu/_install.php | 29 + v2/dotclear/plugins/simpleMenu/_public.php | 116 + v2/dotclear/plugins/simpleMenu/_widgets.php | 25 + v2/dotclear/plugins/simpleMenu/icon-small.png | Bin 0 -> 1328 bytes v2/dotclear/plugins/simpleMenu/icon.png | Bin 0 -> 2188 bytes v2/dotclear/plugins/simpleMenu/index.php | 569 +++ .../simpleMenu/locales/en/help/help.html | 31 + .../simpleMenu/locales/en/resources.php | 18 + .../simpleMenu/locales/fr/help/help.html | 31 + .../simpleMenu/locales/fr/resources.php | 18 + v2/dotclear/plugins/tags/_admin.php | 327 ++ v2/dotclear/plugins/tags/_define.php | 23 + v2/dotclear/plugins/tags/_prepend.php | 17 + v2/dotclear/plugins/tags/_public.php | 374 ++ v2/dotclear/plugins/tags/_widgets.php | 38 + v2/dotclear/plugins/tags/_xmlrpc.php | 50 + .../plugins/tags/default-templates/tag.html | 153 + .../plugins/tags/default-templates/tags.html | 69 + v2/dotclear/plugins/tags/icon-big.png | Bin 0 -> 4765 bytes v2/dotclear/plugins/tags/icon.png | Bin 0 -> 1665 bytes v2/dotclear/plugins/tags/img/loader.gif | Bin 0 -> 1737 bytes v2/dotclear/plugins/tags/img/tag-add.png | Bin 0 -> 568 bytes v2/dotclear/plugins/tags/index.php | 22 + .../plugins/tags/js/jquery.autocomplete.js | 56 + v2/dotclear/plugins/tags/js/post.js | 10 + v2/dotclear/plugins/tags/js/posts_actions.js | 4 + v2/dotclear/plugins/tags/style.css | 100 + v2/dotclear/plugins/tags/tag_posts.php | 167 + v2/dotclear/plugins/tags/tags.php | 77 + v2/dotclear/plugins/themeEditor/_admin.php | 26 + v2/dotclear/plugins/themeEditor/_define.php | 20 + .../plugins/themeEditor/class.themeEditor.php | 252 ++ v2/dotclear/plugins/themeEditor/help.html | 28 + v2/dotclear/plugins/themeEditor/index.php | 128 + v2/dotclear/plugins/themeEditor/script.js | 3 + v2/dotclear/plugins/themeEditor/style.css | 29 + v2/dotclear/plugins/userPref/_admin.php | 17 + v2/dotclear/plugins/userPref/_define.php | 20 + v2/dotclear/plugins/userPref/icon-big.png | Bin 0 -> 6605 bytes v2/dotclear/plugins/userPref/icon.png | Bin 0 -> 1606 bytes v2/dotclear/plugins/userPref/index.php | 236 ++ v2/dotclear/plugins/widgets/_admin.php | 26 + .../plugins/widgets/_default_widgets.php | 91 + v2/dotclear/plugins/widgets/_define.php | 24 + v2/dotclear/plugins/widgets/_install.php | 40 + v2/dotclear/plugins/widgets/_public.php | 131 + .../plugins/widgets/_widgets_functions.php | 369 ++ v2/dotclear/plugins/widgets/class.widgets.php | 263 ++ v2/dotclear/plugins/widgets/dragdrop.js | 29 + v2/dotclear/plugins/widgets/icon-big.png | Bin 0 -> 7965 bytes v2/dotclear/plugins/widgets/icon.png | Bin 0 -> 1568 bytes v2/dotclear/plugins/widgets/index.php | 340 ++ v2/dotclear/plugins/widgets/style.css | 80 + v2/dotclear/plugins/widgets/widgets.js | 22 + v2/dotclear/themes/blueSilence/_define.php | 20 + v2/dotclear/themes/blueSilence/img/attach.png | Bin 0 -> 321 bytes .../themes/blueSilence/img/background.png | Bin 0 -> 588 bytes .../themes/blueSilence/img/commentaire.png | Bin 0 -> 325 bytes .../blueSilence/img/commentaire_bulle.png | Bin 0 -> 312 bytes v2/dotclear/themes/blueSilence/img/footer.png | Bin 0 -> 827 bytes v2/dotclear/themes/blueSilence/img/li.png | Bin 0 -> 154 bytes v2/dotclear/themes/blueSilence/img/report.png | Bin 0 -> 396 bytes .../themes/blueSilence/img/retrolien.png | Bin 0 -> 452 bytes v2/dotclear/themes/blueSilence/img/rss.png | Bin 0 -> 549 bytes .../themes/blueSilence/img/sidebar_li.png | Bin 0 -> 115 bytes v2/dotclear/themes/blueSilence/img/tag.png | Bin 0 -> 308 bytes v2/dotclear/themes/blueSilence/img/tags.png | Bin 0 -> 321 bytes v2/dotclear/themes/blueSilence/img/top.jpg | Bin 0 -> 11038 bytes v2/dotclear/themes/blueSilence/screenshot.jpg | Bin 0 -> 17165 bytes v2/dotclear/themes/blueSilence/style.css | 879 +++++ v2/dotclear/themes/customCSS/_config.php | 41 + v2/dotclear/themes/customCSS/_define.php | 20 + v2/dotclear/themes/customCSS/_public.php | 26 + .../themes/customCSS/locales/fr/main.lang.php | 22 + .../themes/customCSS/locales/fr/main.po | 27 + v2/dotclear/themes/customCSS/style.css | 0 v2/dotclear/themes/default/_define.php | 20 + v2/dotclear/themes/default/img/attach.png | Bin 0 -> 1329 bytes v2/dotclear/themes/default/img/body-bg.png | Bin 0 -> 211 bytes v2/dotclear/themes/default/img/comment-b.png | Bin 0 -> 175 bytes v2/dotclear/themes/default/img/comment-t.png | Bin 0 -> 422 bytes v2/dotclear/themes/default/img/comment.png | Bin 0 -> 1415 bytes .../themes/default/img/commentmy-b.png | Bin 0 -> 186 bytes .../themes/default/img/commentmy-t.png | Bin 0 -> 442 bytes v2/dotclear/themes/default/img/feed.png | Bin 0 -> 2046 bytes v2/dotclear/themes/default/img/page-b.png | Bin 0 -> 189 bytes v2/dotclear/themes/default/img/page-bg.png | Bin 0 -> 1263 bytes v2/dotclear/themes/default/img/page-t.png | Bin 0 -> 25574 bytes v2/dotclear/themes/default/img/tag.png | Bin 0 -> 381 bytes v2/dotclear/themes/default/img/trackback.png | Bin 0 -> 1269 bytes .../themes/default/js/jquery.cookie.js | 6 + v2/dotclear/themes/default/js/jquery.js | 471 +++ v2/dotclear/themes/default/js/post.js | 8 + v2/dotclear/themes/default/print.css | 50 + v2/dotclear/themes/default/screenshot.jpg | Bin 0 -> 16340 bytes v2/dotclear/themes/default/smilies/alien.png | Bin 0 -> 558 bytes v2/dotclear/themes/default/smilies/angry.png | Bin 0 -> 650 bytes v2/dotclear/themes/default/smilies/arrow.png | Bin 0 -> 600 bytes .../themes/default/smilies/confused.png | Bin 0 -> 522 bytes v2/dotclear/themes/default/smilies/cool.png | Bin 0 -> 624 bytes v2/dotclear/themes/default/smilies/cry.png | Bin 0 -> 700 bytes v2/dotclear/themes/default/smilies/dizzy.png | Bin 0 -> 634 bytes v2/dotclear/themes/default/smilies/eek.png | Bin 0 -> 565 bytes v2/dotclear/themes/default/smilies/evil.png | Bin 0 -> 623 bytes v2/dotclear/themes/default/smilies/exclam.png | Bin 0 -> 519 bytes v2/dotclear/themes/default/smilies/idea.png | Bin 0 -> 627 bytes v2/dotclear/themes/default/smilies/laugh.png | Bin 0 -> 590 bytes v2/dotclear/themes/default/smilies/lol.png | Bin 0 -> 567 bytes .../themes/default/smilies/mrgreen.png | Bin 0 -> 568 bytes v2/dotclear/themes/default/smilies/normal.png | Bin 0 -> 522 bytes .../themes/default/smilies/question.png | Bin 0 -> 580 bytes v2/dotclear/themes/default/smilies/razz.png | Bin 0 -> 601 bytes .../themes/default/smilies/redface.png | Bin 0 -> 492 bytes .../themes/default/smilies/rolleyes.png | Bin 0 -> 595 bytes v2/dotclear/themes/default/smilies/sad.png | Bin 0 -> 590 bytes v2/dotclear/themes/default/smilies/smile.png | Bin 0 -> 555 bytes .../themes/default/smilies/smilies.txt | 17 + .../themes/default/smilies/surprised.png | Bin 0 -> 637 bytes v2/dotclear/themes/default/smilies/wink.png | Bin 0 -> 546 bytes v2/dotclear/themes/default/style.css | 564 +++ v2/dotclear/themes/ductile/_config.php | 643 ++++ v2/dotclear/themes/ductile/_define.php | 22 + v2/dotclear/themes/ductile/_prepend.php | 70 + v2/dotclear/themes/ductile/_public.php | 426 +++ v2/dotclear/themes/ductile/ductile.js | 77 + v2/dotclear/themes/ductile/ie.css | 167 + v2/dotclear/themes/ductile/img/404.png | Bin 0 -> 12795 bytes v2/dotclear/themes/ductile/img/download.png | Bin 0 -> 1326 bytes v2/dotclear/themes/ductile/img/feed.png | Bin 0 -> 654 bytes v2/dotclear/themes/ductile/img/filet.png | Bin 0 -> 945 bytes v2/dotclear/themes/ductile/img/hline.png | Bin 0 -> 925 bytes v2/dotclear/themes/ductile/img/info-co.png | Bin 0 -> 2475 bytes v2/dotclear/themes/ductile/img/last-hline.png | Bin 0 -> 947 bytes v2/dotclear/themes/ductile/img/logo.png | Bin 0 -> 2955 bytes v2/dotclear/themes/ductile/img/menu.png | Bin 0 -> 690 bytes v2/dotclear/themes/ductile/img/menumobile.png | Bin 0 -> 449 bytes v2/dotclear/themes/ductile/img/minus-plus.png | Bin 0 -> 1094 bytes v2/dotclear/themes/ductile/img/post-info.png | Bin 0 -> 2111 bytes v2/dotclear/themes/ductile/img/squares.png | Bin 0 -> 1151 bytes .../themes/ductile/img/sticker-about.png | Bin 0 -> 1033 bytes .../themes/ductile/img/sticker-contact.png | Bin 0 -> 1608 bytes .../themes/ductile/img/sticker-feed.png | Bin 0 -> 1447 bytes v2/dotclear/themes/ductile/img/vline.png | Bin 0 -> 928 bytes .../themes/ductile/locales/en/help/help.html | 83 + .../themes/ductile/locales/en/main.lang.php | 21 + v2/dotclear/themes/ductile/locales/en/main.po | 5 + .../themes/ductile/locales/en/resources.php | 18 + .../themes/ductile/locales/es/main.lang.php | 33 + v2/dotclear/themes/ductile/locales/es/main.po | 41 + .../themes/ductile/locales/fr/admin.lang.php | 67 + .../themes/ductile/locales/fr/admin.po | 143 + .../themes/ductile/locales/fr/help/help.html | 96 + .../themes/ductile/locales/fr/main.lang.php | 33 + v2/dotclear/themes/ductile/locales/fr/main.po | 41 + .../themes/ductile/locales/fr/resources.php | 18 + v2/dotclear/themes/ductile/mediaqueries.css | 389 +++ v2/dotclear/themes/ductile/rebase.css | 107 + v2/dotclear/themes/ductile/screenshot.jpg | Bin 0 -> 17218 bytes v2/dotclear/themes/ductile/style.css | 1077 ++++++ v2/dotclear/themes/ductile/tpl/404.html | 59 + .../themes/ductile/tpl/_entry-full.html | 55 + .../themes/ductile/tpl/_entry-short.html | 78 + .../themes/ductile/tpl/_entry-title.html | 41 + v2/dotclear/themes/ductile/tpl/_footer.html | 13 + v2/dotclear/themes/ductile/tpl/_head.html | 17 + .../themes/ductile/tpl/_pagination.html | 13 + v2/dotclear/themes/ductile/tpl/_sidebar.html | 8 + .../themes/ductile/tpl/_simple-entry.html | 179 + v2/dotclear/themes/ductile/tpl/_top.html | 20 + v2/dotclear/themes/ductile/tpl/archive.html | 144 + .../themes/ductile/tpl/archive_month.html | 76 + v2/dotclear/themes/ductile/tpl/category.html | 112 + v2/dotclear/themes/ductile/tpl/home.html | 97 + v2/dotclear/themes/ductile/tpl/page.html | 62 + v2/dotclear/themes/ductile/tpl/post.html | 83 + v2/dotclear/themes/ductile/tpl/search.html | 99 + v2/dotclear/themes/ductile/tpl/tag.html | 88 + v2/dotclear/themes/ductile/tpl/tags.html | 60 + 1337 files changed, 170763 insertions(+) create mode 100644 .htaccess create mode 100644 CHANGELOG create mode 100644 admin/auth.php create mode 100644 admin/blog.php create mode 100644 admin/blog_del.php create mode 100644 admin/blog_pref.php create mode 100644 admin/blog_theme.php create mode 100644 admin/blogs.php create mode 100644 admin/categories.php create mode 100644 admin/category.php create mode 100644 admin/comment.php create mode 100644 admin/comments.php create mode 100644 admin/comments_actions.php create mode 100644 admin/dispatcher.php create mode 100644 admin/images/attach.png create mode 100644 admin/images/check-off.png create mode 100644 admin/images/check-on.png create mode 100644 admin/images/check-wrn.png create mode 100644 admin/images/date-picker.png create mode 100644 admin/images/dotclear_pw.png create mode 100644 admin/images/edit-mini.png create mode 100644 admin/images/help.png create mode 100644 admin/images/junk.png create mode 100644 admin/images/locker.png create mode 100644 admin/images/media/audio.png create mode 100644 admin/images/media/blank.png create mode 100644 admin/images/media/document.png create mode 100644 admin/images/media/executable.png create mode 100644 admin/images/media/folder.png create mode 100644 admin/images/media/html.png create mode 100644 admin/images/media/image.png create mode 100644 admin/images/media/package.png create mode 100644 admin/images/media/presentation.png create mode 100644 admin/images/media/spreadsheet.png create mode 100644 admin/images/media/text.png create mode 100644 admin/images/media/video.png create mode 100644 admin/images/menu/blog-pref-b.png create mode 100644 admin/images/menu/blog-theme-b.png create mode 100644 admin/images/menu/blogs.png create mode 100644 admin/images/menu/categories.png create mode 100644 admin/images/menu/comments-b.png create mode 100644 admin/images/menu/comments.png create mode 100644 admin/images/menu/dashboard.png create mode 100644 admin/images/menu/edit-b.png create mode 100644 admin/images/menu/edit.png create mode 100644 admin/images/menu/entries-b.png create mode 100644 admin/images/menu/entries.png create mode 100644 admin/images/menu/langs.png create mode 100644 admin/images/menu/media.png create mode 100644 admin/images/menu/plugins.png create mode 100644 admin/images/menu/search.png create mode 100644 admin/images/menu/update.png create mode 100644 admin/images/menu/user-pref-b.png create mode 100644 admin/images/menu/users.png create mode 100644 admin/images/menu_off.png create mode 100644 admin/images/menu_on.png create mode 100644 admin/images/minus.png create mode 100644 admin/images/noscreenshot.png create mode 100644 admin/images/picker.png create mode 100644 admin/images/plus.png create mode 100644 admin/images/scheduled.png create mode 100644 admin/images/selected.png create mode 100644 admin/images/trash.png create mode 100644 admin/index.php create mode 100644 admin/install/check.php create mode 100644 admin/install/index.php create mode 100644 admin/install/wizard.php create mode 100644 admin/js/_blog_theme.js create mode 100644 admin/js/_categories.js create mode 100644 admin/js/_category.js create mode 100644 admin/js/_comment.js create mode 100644 admin/js/_comments.js create mode 100644 admin/js/_index.js create mode 100644 admin/js/_langs.js create mode 100644 admin/js/_media.js create mode 100644 admin/js/_media_item.js create mode 100644 admin/js/_permissions.js create mode 100644 admin/js/_permissions_blog.js create mode 100644 admin/js/_plugins.js create mode 100644 admin/js/_post.js create mode 100644 admin/js/_posts_list.js create mode 100644 admin/js/_preferences.js create mode 100644 admin/js/_trackbacks.js create mode 100644 admin/js/_users.js create mode 100644 admin/js/color-picker.js create mode 100644 admin/js/common.js create mode 100644 admin/js/confirm-close.js create mode 100644 admin/js/date-picker.js create mode 100644 admin/js/dragsort-tablerows.js create mode 100644 admin/js/filter-controls.js create mode 100644 admin/js/ie7/IE7.js create mode 100644 admin/js/ie7/IE8.js create mode 100644 admin/js/ie7/blank.gif create mode 100644 admin/js/ie7/ie7-recalc.js create mode 100644 admin/js/ie7/ie7-squish.js create mode 100644 admin/js/jquery/jquery.bgFade.js create mode 100644 admin/js/jquery/jquery.biscuit.js create mode 100644 admin/js/jquery/jquery.candyUpload.js create mode 100644 admin/js/jquery/jquery.farbtastic.js create mode 100644 admin/js/jquery/jquery.js create mode 100644 admin/js/jquery/jquery.modal.js create mode 100644 admin/js/jquery/jquery.pageTabs.js create mode 100644 admin/js/jsToolBar/jsToolBar.dotclear.js create mode 100644 admin/js/jsToolBar/jsToolBar.js create mode 100644 admin/js/jsToolBar/jsToolBar.wysiwyg.js create mode 100644 admin/js/jsToolBar/popup_link.js create mode 100644 admin/js/jsToolBar/popup_media.js create mode 100644 admin/js/jsToolBar/popup_posts.js create mode 100644 admin/js/tool-man/cookies.js create mode 100644 admin/js/tool-man/coordinates.js create mode 100644 admin/js/tool-man/core.js create mode 100644 admin/js/tool-man/css.js create mode 100644 admin/js/tool-man/drag.js create mode 100644 admin/js/tool-man/dragsort.js create mode 100644 admin/js/tool-man/events.js create mode 100644 admin/langs.php create mode 100644 admin/media.php create mode 100644 admin/media_item.php create mode 100644 admin/permissions.php create mode 100644 admin/permissions_blog.php create mode 100644 admin/plugin.php create mode 100644 admin/plugins.php create mode 100644 admin/popup_link.php create mode 100644 admin/popup_posts.php create mode 100644 admin/post.php create mode 100644 admin/post_media.php create mode 100644 admin/posts.php create mode 100644 admin/posts_actions.php create mode 100644 admin/preferences.php create mode 100644 admin/search.php create mode 100644 admin/services.php create mode 100644 admin/style/candyUpload/cancel.png create mode 100644 admin/style/candyUpload/loader.png create mode 100644 admin/style/candyUpload/style.css create mode 100644 admin/style/cat-bg.png create mode 100644 admin/style/date-picker.css create mode 100644 admin/style/default-rtl.css create mode 100644 admin/style/default.css create mode 100644 admin/style/dotclear-logo.png create mode 100644 admin/style/drag.png create mode 100644 admin/style/farbtastic/farbtastic.css create mode 100644 admin/style/farbtastic/marker.png create mode 100644 admin/style/farbtastic/mask.png create mode 100644 admin/style/farbtastic/wheel.png create mode 100644 admin/style/footer-bg.png create mode 100644 admin/style/grid.png create mode 100644 admin/style/head-bg.png create mode 100644 admin/style/head-logo.png create mode 100644 admin/style/iesucks.css create mode 100644 admin/style/jsToolBar/bt_bquote.png create mode 100644 admin/style/jsToolBar/bt_br.png create mode 100644 admin/style/jsToolBar/bt_clean.png create mode 100644 admin/style/jsToolBar/bt_code.png create mode 100644 admin/style/jsToolBar/bt_del.png create mode 100644 admin/style/jsToolBar/bt_em.png create mode 100644 admin/style/jsToolBar/bt_img.png create mode 100644 admin/style/jsToolBar/bt_img_select.png create mode 100644 admin/style/jsToolBar/bt_ins.png create mode 100644 admin/style/jsToolBar/bt_link.png create mode 100644 admin/style/jsToolBar/bt_ol.png create mode 100644 admin/style/jsToolBar/bt_paragraph.png create mode 100644 admin/style/jsToolBar/bt_post.png create mode 100644 admin/style/jsToolBar/bt_pre.png create mode 100644 admin/style/jsToolBar/bt_quote.png create mode 100644 admin/style/jsToolBar/bt_strong.png create mode 100644 admin/style/jsToolBar/bt_ul.png create mode 100644 admin/style/jsToolBar/jsToolBar.css create mode 100644 admin/style/jsToolBar/resize.png create mode 100644 admin/style/magnifier.png create mode 100644 admin/style/modal/close.png create mode 100644 admin/style/modal/loader.gif create mode 100644 admin/style/modal/modal.css create mode 100644 admin/style/msg-error.png create mode 100644 admin/style/msg-std.png create mode 100644 admin/style/package.png create mode 100644 admin/style/page-bg.png create mode 100644 admin/style/tab-bg.png create mode 100644 admin/style/tab-c-l.png create mode 100644 admin/style/tab-c-r.png create mode 100644 admin/style/tab-l-l.png create mode 100644 admin/style/tab-l-r.png create mode 100644 admin/style/tab-n-l.png create mode 100644 admin/style/tab-n-r.png create mode 100644 admin/trackbacks.php create mode 100644 admin/update.php create mode 100644 admin/user.php create mode 100644 admin/users.php create mode 100644 admin/xmlrpc.php create mode 100644 cache/.htaccess create mode 100644 cache/cbfeed/6a/4f/6a4f55e24111799aaa8e45c1cc4d4583.php create mode 100644 cache/cbtpl/06/16/061624c7d38d3b032e8770d96e17d8da.php create mode 100644 cache/cbtpl/1c/4b/1c4b52bb84ebd38be237c1522ddf181d.php create mode 100644 cache/cbtpl/3a/b6/3ab69b6036ca46cabbbc3f6f39ceb835.php create mode 100644 cache/cbtpl/3b/b3/3bb3a29ef197db17fdf8e0d1c82e1f9f.php create mode 100644 cache/cbtpl/3d/2a/3d2ab7176958994fb44ae475a0e58648.php create mode 100644 cache/cbtpl/62/e1/62e139c10241e743060059b9ff916ad8.php create mode 100644 cache/cbtpl/68/28/68289f8a2d83100b6bda1a3cccbbc63f.php create mode 100644 cache/cbtpl/8b/ae/8bae1e7eb3f0cd863c169541fdad8d0e.php create mode 100644 cache/cbtpl/a7/06/a706cb39770a563585de2242a3226981.php create mode 100644 cache/cbtpl/b0/5d/b05d35fd541ee9f5da5478faf45bb412.php create mode 100644 cache/cbtpl/b0/f4/b0f4418e5a9e7ab1a68ede430ca901e4.php create mode 100644 cache/cbtpl/b9/d7/b9d701fcfceb205e24dd3c2658797c4e.php create mode 100644 cache/cbtpl/c1/cd/c1cd28bd66b4517eec04f3abde1cb6c0.php create mode 100644 cache/cbtpl/d6/6a/d66aceb2839fdeb0b5251550574000be.php create mode 100644 cache/cbtpl/e1/53/e153e91980f2acce5c73feac0a840192.php create mode 100644 cache/cbtpl/f7/f4/f7f41a7bdbfd5f0616a3e4b89660a6a8.php create mode 100644 cache/daorg/68/cb/68cbfef3c40e3d56b4fb94709e2b9321.ser create mode 100644 cache/daorg/fa/37/fa37bc9589c9a834517f9ddff94f8683.ser create mode 100644 cache/versions/dotclear-stable create mode 100644 db/.htaccess create mode 100644 dotclear-loader.php create mode 100644 inc/.htaccess create mode 100644 inc/admin/class.dc.menu.php create mode 100644 inc/admin/lib.dc.page.php create mode 100644 inc/admin/lib.pager.php create mode 100644 inc/admin/prepend.php create mode 100644 inc/clearbricks/_common.php create mode 100644 inc/clearbricks/common/_main.php create mode 100644 inc/clearbricks/common/lib.crypt.php create mode 100644 inc/clearbricks/common/lib.date.php create mode 100644 inc/clearbricks/common/lib.files.php create mode 100644 inc/clearbricks/common/lib.form.php create mode 100644 inc/clearbricks/common/lib.html.php create mode 100644 inc/clearbricks/common/lib.http.php create mode 100644 inc/clearbricks/common/lib.l10n.php create mode 100644 inc/clearbricks/common/lib.text.php create mode 100644 inc/clearbricks/common/tz.dat create mode 100644 inc/clearbricks/dblayer/class.cursor.php create mode 100644 inc/clearbricks/dblayer/class.mysql.php create mode 100644 inc/clearbricks/dblayer/class.pgsql.php create mode 100644 inc/clearbricks/dblayer/class.sqlite.php create mode 100644 inc/clearbricks/dblayer/dblayer.php create mode 100644 inc/clearbricks/dbschema/class.dbschema.php create mode 100644 inc/clearbricks/dbschema/class.dbstruct.php create mode 100644 inc/clearbricks/dbschema/class.mysql.dbschema.php create mode 100644 inc/clearbricks/dbschema/class.pgsql.dbschema.php create mode 100644 inc/clearbricks/dbschema/class.sqlite.dbschema.php create mode 100644 inc/clearbricks/filemanager/class.filemanager.php create mode 100644 inc/clearbricks/html.filter/class.html.filter.php create mode 100644 inc/clearbricks/html.validator/class.html.validator.php create mode 100644 inc/clearbricks/image/class.image.meta.php create mode 100644 inc/clearbricks/image/class.image.tools.php create mode 100644 inc/clearbricks/mail/class.mail.php create mode 100644 inc/clearbricks/mail/class.socket.mail.php create mode 100644 inc/clearbricks/net.http.feed/class.feed.parser.php create mode 100644 inc/clearbricks/net.http.feed/class.feed.reader.php create mode 100644 inc/clearbricks/net.http/class.net.http.php create mode 100644 inc/clearbricks/net.xmlrpc/class.net.xmlrpc.php create mode 100644 inc/clearbricks/net/class.net.socket.php create mode 100644 inc/clearbricks/pager/class.pager.php create mode 100644 inc/clearbricks/rest/class.rest.php create mode 100644 inc/clearbricks/session.db/class.session.db.php create mode 100644 inc/clearbricks/template/class.template.php create mode 100644 inc/clearbricks/text.wiki2xhtml/class.wiki2xhtml.php create mode 100644 inc/clearbricks/url.handler/class.url.handler.php create mode 100644 inc/clearbricks/zip/class.unzip.php create mode 100644 inc/clearbricks/zip/class.zip.php create mode 100644 inc/config.php create mode 100644 inc/config.php.in create mode 100644 inc/core/class.dc.auth.php create mode 100644 inc/core/class.dc.blog.php create mode 100644 inc/core/class.dc.categories.php create mode 100644 inc/core/class.dc.core.php create mode 100644 inc/core/class.dc.error.php create mode 100644 inc/core/class.dc.media.php create mode 100644 inc/core/class.dc.modules.php create mode 100644 inc/core/class.dc.rest.php create mode 100644 inc/core/class.dc.rs.extensions.php create mode 100644 inc/core/class.dc.settings.php create mode 100644 inc/core/class.dc.themes.php create mode 100644 inc/core/class.dc.trackback.php create mode 100644 inc/core/class.dc.update.php create mode 100644 inc/core/class.dc.utils.php create mode 100644 inc/core/class.dc.xmlrpc.php create mode 100644 inc/core_error.php create mode 100644 inc/dbschema/db-schema.php create mode 100644 inc/dbschema/upgrade-cli.php create mode 100644 inc/dbschema/upgrade.php create mode 100644 inc/digests create mode 100644 inc/load_plugin_file.php create mode 100644 inc/prepend.php create mode 100644 inc/public/class.dc.template.php create mode 100644 inc/public/default-templates/atom-comments.xml create mode 100644 inc/public/default-templates/atom.xml create mode 100644 inc/public/default-templates/password-form.html create mode 100644 inc/public/default-templates/rss2-comments.xml create mode 100644 inc/public/default-templates/rss2.xml create mode 100644 inc/public/default-templates/rss2.xsl create mode 100644 inc/public/lib.tpl.context.php create mode 100644 inc/public/lib.urlhandlers.php create mode 100644 inc/public/prepend.php create mode 100644 inc/public/rs.extension.php create mode 100644 inc/swf/player_flv.swf create mode 100644 inc/swf/player_mp3.swf create mode 100644 inc/swf/swfupload.swf create mode 100644 index.php create mode 100644 locales/README create mode 100644 locales/en/date.lang.php create mode 100644 locales/en/date.po create mode 100644 locales/en/help/blog_pref.html create mode 100644 locales/en/help/categories.html create mode 100644 locales/en/help/comments.html create mode 100644 locales/en/help/media.html create mode 100644 locales/en/help/post.html create mode 100644 locales/en/help/posts.html create mode 100644 locales/en/help/user_pref.html create mode 100644 locales/en/help/wiki.html create mode 100644 locales/en/resources.php create mode 100644 locales/fr/date.lang.php create mode 100644 locales/fr/date.po create mode 100644 locales/fr/help/blowupConfig.html create mode 100644 locales/fr/help/core_blog_pref.html create mode 100644 locales/fr/help/core_categories.html create mode 100644 locales/fr/help/core_comments.html create mode 100644 locales/fr/help/core_media.html create mode 100644 locales/fr/help/core_post.html create mode 100644 locales/fr/help/core_posts.html create mode 100644 locales/fr/help/core_user_pref.html create mode 100644 locales/fr/help/core_wiki.html create mode 100644 locales/fr/help/themeEditor.html create mode 100644 locales/fr/main.lang.php create mode 100644 locales/fr/main.po create mode 100644 locales/fr/plugins.lang.php create mode 100644 locales/fr/plugins.po create mode 100644 locales/fr/public.lang.php create mode 100644 locales/fr/public.po create mode 100644 locales/fr/resources.php create mode 100644 plugins/.htaccess create mode 100644 plugins/aboutConfig/_admin.php create mode 100644 plugins/aboutConfig/_define.php create mode 100644 plugins/aboutConfig/icon.png create mode 100644 plugins/aboutConfig/index.php create mode 100644 plugins/accessibleCaptcha/LICENSE create mode 100644 plugins/accessibleCaptcha/_define.php create mode 100644 plugins/accessibleCaptcha/_install.php create mode 100644 plugins/accessibleCaptcha/_prepend.php create mode 100644 plugins/accessibleCaptcha/class.accessible.captcha.php create mode 100644 plugins/accessibleCaptcha/class.dc.filter.accessible.captcha.php create mode 100644 plugins/accessibleCaptcha/locales/fr/main.po create mode 100644 plugins/akismet/_define.php create mode 100644 plugins/akismet/_prepend.php create mode 100644 plugins/akismet/class.dc.filter.akismet.php create mode 100644 plugins/antispam/_admin.php create mode 100644 plugins/antispam/_define.php create mode 100644 plugins/antispam/_install.php create mode 100644 plugins/antispam/_prepend.php create mode 100644 plugins/antispam/_public.php create mode 100644 plugins/antispam/antispam.js create mode 100644 plugins/antispam/feed.png create mode 100644 plugins/antispam/filters/class.dc.filter.ip.php create mode 100644 plugins/antispam/filters/class.dc.filter.iplookup.php create mode 100644 plugins/antispam/filters/class.dc.filter.linkslookup.php create mode 100644 plugins/antispam/filters/class.dc.filter.words.php create mode 100644 plugins/antispam/icon.png create mode 100644 plugins/antispam/inc/class.dc.spamfilter.php create mode 100644 plugins/antispam/inc/class.dc.spamfilters.php create mode 100644 plugins/antispam/inc/lib.dc.antispam.php create mode 100644 plugins/antispam/inc/lib.dc.antispam.url.php create mode 100644 plugins/antispam/index.php create mode 100644 plugins/antispam/style.css create mode 100644 plugins/blogroll/_admin.php create mode 100644 plugins/blogroll/_define.php create mode 100644 plugins/blogroll/_install.php create mode 100644 plugins/blogroll/_prepend.php create mode 100644 plugins/blogroll/_public.php create mode 100644 plugins/blogroll/_widgets.php create mode 100644 plugins/blogroll/class.dc.blogroll.php create mode 100644 plugins/blogroll/class.dc.importblogroll.php create mode 100644 plugins/blogroll/edit.php create mode 100644 plugins/blogroll/icon-small.png create mode 100644 plugins/blogroll/icon.png create mode 100644 plugins/blogroll/index.php create mode 100644 plugins/blogroll/locales/en/main.lang.php create mode 100644 plugins/blogroll/locales/en/main.po create mode 100644 plugins/blowupConfig/_admin.php create mode 100644 plugins/blowupConfig/_define.php create mode 100644 plugins/blowupConfig/_public.php create mode 100644 plugins/blowupConfig/alpha-img/comment-b.png create mode 100644 plugins/blowupConfig/alpha-img/comment-t.png create mode 100644 plugins/blowupConfig/alpha-img/gradient-d.png create mode 100644 plugins/blowupConfig/alpha-img/gradient-l.png create mode 100644 plugins/blowupConfig/alpha-img/gradient-m.png create mode 100644 plugins/blowupConfig/alpha-img/page-b.png create mode 100644 plugins/blowupConfig/alpha-img/page-bg.png create mode 100644 plugins/blowupConfig/alpha-img/page-t/animals.png create mode 100644 plugins/blowupConfig/alpha-img/page-t/blank.png create mode 100644 plugins/blowupConfig/alpha-img/page-t/butterflies.png create mode 100644 plugins/blowupConfig/alpha-img/page-t/default.png create mode 100644 plugins/blowupConfig/alpha-img/page-t/flamingo.png create mode 100644 plugins/blowupConfig/alpha-img/page-t/flourish-1.png create mode 100644 plugins/blowupConfig/alpha-img/page-t/flourish-2.png create mode 100644 plugins/blowupConfig/alpha-img/page-t/image-mask.png create mode 100644 plugins/blowupConfig/alpha-img/page-t/light-trails-1.png create mode 100644 plugins/blowupConfig/alpha-img/page-t/light-trails-2.png create mode 100644 plugins/blowupConfig/alpha-img/page-t/light-trails-3.png create mode 100644 plugins/blowupConfig/alpha-img/page-t/light-trails-4.png create mode 100644 plugins/blowupConfig/alpha-img/page-t/rabbit.png create mode 100644 plugins/blowupConfig/alpha-img/page-t/roadrunner-1.png create mode 100644 plugins/blowupConfig/alpha-img/page-t/roadrunner-2.png create mode 100644 plugins/blowupConfig/alpha-img/page-t/typo.png create mode 100644 plugins/blowupConfig/config.js create mode 100644 plugins/blowupConfig/help.html create mode 100644 plugins/blowupConfig/index.php create mode 100644 plugins/blowupConfig/lib/class.blowup.config.php create mode 100644 plugins/daInstaller/_admin.php create mode 100644 plugins/daInstaller/_define.php create mode 100644 plugins/daInstaller/_install.php create mode 100644 plugins/daInstaller/_prepend.php create mode 100644 plugins/daInstaller/icon-big-update.png create mode 100644 plugins/daInstaller/icon-big.png create mode 100644 plugins/daInstaller/icon.png create mode 100644 plugins/daInstaller/img/help.png create mode 100644 plugins/daInstaller/img/support.png create mode 100644 plugins/daInstaller/inc/class.da.installer.php create mode 100644 plugins/daInstaller/inc/class.da.modules.parser.php create mode 100644 plugins/daInstaller/inc/class.da.modules.reader.php create mode 100644 plugins/daInstaller/inc/lib.da.installer.ui.php create mode 100644 plugins/daInstaller/index.php create mode 100644 plugins/daInstaller/js/_dainstaller.js create mode 100644 plugins/daInstaller/locales/_pot/main.pot create mode 100644 plugins/daInstaller/locales/fr/help/da_installer.html create mode 100644 plugins/daInstaller/locales/fr/main.lang.php create mode 100644 plugins/daInstaller/locales/fr/main.po create mode 100644 plugins/daInstaller/locales/fr/resources.php create mode 100644 plugins/daInstaller/locales/l10n-daInstaller-fr-1304423937.bck.zip create mode 100644 plugins/daInstaller/locales/l10n-daInstaller-fr-1304423968.bck.zip create mode 100644 plugins/daInstaller/locales/l10n-daInstaller-fr-1304424006.bck.zip create mode 100644 plugins/daInstaller/locales/l10n-daInstaller-fr-1304424011.bck.zip create mode 100644 plugins/daInstaller/locales/l10n-daInstaller-fr-1305546468.bck.zip create mode 100644 plugins/daInstaller/style.css create mode 100644 plugins/externalMedia/_admin.php create mode 100644 plugins/externalMedia/_define.php create mode 100644 plugins/externalMedia/bt_video.png create mode 100644 plugins/externalMedia/index.php create mode 100644 plugins/externalMedia/popup.js create mode 100644 plugins/externalMedia/post.js create mode 100644 plugins/fairTrackbacks/_define.php create mode 100644 plugins/fairTrackbacks/_prepend.php create mode 100644 plugins/fairTrackbacks/_public.php create mode 100644 plugins/fairTrackbacks/class.dc.filter.fairtrackbacks.php create mode 100644 plugins/googleTools/_admin.php create mode 100644 plugins/googleTools/_define.php create mode 100644 plugins/googleTools/_install.php create mode 100644 plugins/googleTools/_public.php create mode 100644 plugins/googleTools/locales/fr/main.lang.php create mode 100644 plugins/importExport/_admin.php create mode 100644 plugins/importExport/_define.php create mode 100644 plugins/importExport/icon.png create mode 100644 plugins/importExport/inc/class.dc.export.flat.php create mode 100644 plugins/importExport/inc/class.dc.ieModule.php create mode 100644 plugins/importExport/inc/class.dc.import.dc1.php create mode 100644 plugins/importExport/inc/class.dc.import.feed.php create mode 100644 plugins/importExport/inc/class.dc.import.flat.php create mode 100644 plugins/importExport/inc/class.dc.import.wp.php create mode 100644 plugins/importExport/inc/flat/class.backupFile.php create mode 100644 plugins/importExport/inc/flat/class.db.export.php create mode 100644 plugins/importExport/inc/flat/class.dc.import.php create mode 100644 plugins/importExport/index.php create mode 100644 plugins/importExport/progress.png create mode 100644 plugins/importExport/script.js create mode 100644 plugins/maintenance/_admin.php create mode 100644 plugins/maintenance/_define.php create mode 100644 plugins/maintenance/icon.png create mode 100644 plugins/maintenance/index.php create mode 100644 plugins/metadata/_admin.php create mode 100644 plugins/metadata/_define.php create mode 100644 plugins/metadata/_install.php create mode 100644 plugins/metadata/_prepend.php create mode 100644 plugins/metadata/_public.php create mode 100644 plugins/metadata/_widgets.php create mode 100644 plugins/metadata/_xmlrpc.php create mode 100644 plugins/metadata/class.dc.meta.php create mode 100644 plugins/metadata/index.php create mode 100644 plugins/metadata/post.js create mode 100644 plugins/metadata/style.css create mode 100644 plugins/metadata/tag-add.png create mode 100644 plugins/metadata/tag_posts.php create mode 100644 plugins/metadata/tags.php create mode 100644 plugins/metadata/tags.png create mode 100644 plugins/pages/_admin.php create mode 100644 plugins/pages/_define.php create mode 100644 plugins/pages/_prepend.php create mode 100644 plugins/pages/_public.php create mode 100644 plugins/pages/_widgets.php create mode 100644 plugins/pages/default-templates/page.html create mode 100644 plugins/pages/icon-big.png create mode 100644 plugins/pages/icon.png create mode 100644 plugins/pages/index.php create mode 100644 plugins/pages/list.php create mode 100644 plugins/pages/page.php create mode 100644 plugins/pings/_admin.php create mode 100644 plugins/pings/_define.php create mode 100644 plugins/pings/icon.png create mode 100644 plugins/pings/index.php create mode 100644 plugins/pings/lib.pings.php create mode 100644 plugins/pings/post.js create mode 100644 plugins/themeEditor/_admin.php create mode 100644 plugins/themeEditor/_define.php create mode 100644 plugins/themeEditor/class.themeEditor.php create mode 100644 plugins/themeEditor/help.html create mode 100644 plugins/themeEditor/index.php create mode 100644 plugins/themeEditor/script.js create mode 100644 plugins/themeEditor/style.css create mode 100644 plugins/widgets/_admin.php create mode 100644 plugins/widgets/_default_widgets.php create mode 100644 plugins/widgets/_define.php create mode 100644 plugins/widgets/_public.php create mode 100644 plugins/widgets/_widgets_functions.php create mode 100644 plugins/widgets/class.widgets.php create mode 100644 plugins/widgets/dragdrop.js create mode 100644 plugins/widgets/icon.png create mode 100644 plugins/widgets/index.php create mode 100644 plugins/widgets/style.css create mode 100644 plugins/widgets/widgets.js create mode 100644 public/.IMG4_m.jpg create mode 100644 public/.IMG4_s.jpg create mode 100644 public/.IMG4_sq.jpg create mode 100644 public/.IMG4_t.jpg create mode 100644 public/.La_fracture_52_m.jpg create mode 100644 public/.La_fracture_52_s.jpg create mode 100644 public/.La_fracture_52_sq.jpg create mode 100644 public/.La_fracture_52_t.jpg create mode 100644 public/.La_fracture_53_m.jpg create mode 100644 public/.La_fracture_53_s.jpg create mode 100644 public/.La_fracture_53_sq.jpg create mode 100644 public/.La_fracture_53_t.jpg create mode 100644 public/.La_fracture_54_m.jpg create mode 100644 public/.La_fracture_54_s.jpg create mode 100644 public/.La_fracture_54_sq.jpg create mode 100644 public/.La_fracture_54_t.jpg create mode 100644 public/.La_fracture_55_m.jpg create mode 100644 public/.La_fracture_55_s.jpg create mode 100644 public/.La_fracture_55_sq.jpg create mode 100644 public/.La_fracture_55_t.jpg create mode 100644 public/.La_fracture_56_m.jpg create mode 100644 public/.La_fracture_56_s.jpg create mode 100644 public/.La_fracture_56_sq.jpg create mode 100644 public/.La_fracture_56_t.jpg create mode 100644 public/.La_fracture_57_m.jpg create mode 100644 public/.La_fracture_57_s.jpg create mode 100644 public/.La_fracture_57_sq.jpg create mode 100644 public/.La_fracture_57_t.jpg create mode 100644 public/020323585666.pdf create mode 100644 public/IMG4.jpg create mode 100644 public/La_fracture_52.jpg create mode 100644 public/La_fracture_53.jpg create mode 100644 public/La_fracture_54.jpg create mode 100644 public/La_fracture_55.jpg create mode 100644 public/La_fracture_56.jpg create mode 100644 public/La_fracture_57.jpg create mode 100644 themes/altowithjquery/Change.txt create mode 100644 themes/altowithjquery/_define.php create mode 100644 themes/altowithjquery/custom.css create mode 100644 themes/altowithjquery/img/attach.png create mode 100644 themes/altowithjquery/img/background.gif create mode 100644 themes/altowithjquery/img/commentaire.png create mode 100644 themes/altowithjquery/img/footer.png create mode 100644 themes/altowithjquery/img/footer.psd create mode 100644 themes/altowithjquery/img/page.png create mode 100644 themes/altowithjquery/img/q.png create mode 100644 themes/altowithjquery/img/retrolien.png create mode 100644 themes/altowithjquery/img/rss.png create mode 100644 themes/altowithjquery/img/style.css create mode 100644 themes/altowithjquery/img/tag.png create mode 100644 themes/altowithjquery/img/top.png create mode 100644 themes/altowithjquery/img/top.psd create mode 100644 themes/altowithjquery/screenshot.jpg create mode 100644 themes/altowithjquery/style.css create mode 100644 themes/altowithjquery/tpl/_footer.html create mode 100644 themes/altowithjquery/tpl/_head.html create mode 100644 themes/altowithjquery/tpl/_top.html create mode 100644 themes/altowithjquery/tpl/archive_day.html create mode 100644 themes/altowithjquery/tpl/post.html create mode 100644 themes/customCSS/_config.php create mode 100644 themes/customCSS/_define.php create mode 100644 themes/customCSS/_public.php create mode 100644 themes/customCSS/locales/fr/main.lang.php create mode 100644 themes/customCSS/locales/fr/main.po create mode 100644 themes/customCSS/style.css create mode 100644 themes/default/_define.php create mode 100644 themes/default/img/attach.png create mode 100644 themes/default/img/body-bg.png create mode 100644 themes/default/img/comment-b.png create mode 100644 themes/default/img/comment-t.png create mode 100644 themes/default/img/comment.png create mode 100644 themes/default/img/commentmy-b.png create mode 100644 themes/default/img/commentmy-t.png create mode 100644 themes/default/img/feed.png create mode 100644 themes/default/img/page-b.png create mode 100644 themes/default/img/page-bg.png create mode 100644 themes/default/img/page-t.png create mode 100644 themes/default/img/tag.png create mode 100644 themes/default/img/trackback.png create mode 100644 themes/default/js/jquery.cookie.js create mode 100644 themes/default/js/jquery.js create mode 100644 themes/default/js/post.js create mode 100644 themes/default/print.css create mode 100644 themes/default/screenshot.jpg create mode 100644 themes/default/smilies/alien.png create mode 100644 themes/default/smilies/angry.png create mode 100644 themes/default/smilies/arrow.png create mode 100644 themes/default/smilies/confused.png create mode 100644 themes/default/smilies/cool.png create mode 100644 themes/default/smilies/cry.png create mode 100644 themes/default/smilies/dizzy.png create mode 100644 themes/default/smilies/eek.png create mode 100644 themes/default/smilies/evil.png create mode 100644 themes/default/smilies/exclam.png create mode 100644 themes/default/smilies/idea.png create mode 100644 themes/default/smilies/laugh.png create mode 100644 themes/default/smilies/lol.png create mode 100644 themes/default/smilies/mrgreen.png create mode 100644 themes/default/smilies/normal.png create mode 100644 themes/default/smilies/question.png create mode 100644 themes/default/smilies/razz.png create mode 100644 themes/default/smilies/redface.png create mode 100644 themes/default/smilies/rolleyes.png create mode 100644 themes/default/smilies/sad.png create mode 100644 themes/default/smilies/smile.png create mode 100644 themes/default/smilies/smilies.txt create mode 100644 themes/default/smilies/surprised.png create mode 100644 themes/default/smilies/wink.png create mode 100644 themes/default/style.css create mode 100644 themes/default/tpl/.htaccess create mode 100644 themes/default/tpl/404.html create mode 100644 themes/default/tpl/_flv_player.html create mode 100644 themes/default/tpl/_footer.html create mode 100644 themes/default/tpl/_head.html create mode 100644 themes/default/tpl/_mp3_player.html create mode 100644 themes/default/tpl/_top.html create mode 100644 themes/default/tpl/archive.html create mode 100644 themes/default/tpl/archive_month.html create mode 100644 themes/default/tpl/category.html create mode 100644 themes/default/tpl/home.html create mode 100644 themes/default/tpl/post.html create mode 100644 themes/default/tpl/search.html create mode 100644 themes/default/tpl/tag.html create mode 100644 themes/default/tpl/tags.html create mode 100644 themes/default/tpl/user_head.html create mode 100644 v2/dotclear/CHANGELOG create mode 100644 v2/dotclear/CREDITS create mode 100644 v2/dotclear/LICENSE create mode 100644 v2/dotclear/README create mode 100644 v2/dotclear/admin/auth.php create mode 100644 v2/dotclear/admin/blog.php create mode 100644 v2/dotclear/admin/blog_del.php create mode 100644 v2/dotclear/admin/blog_pref.php create mode 100644 v2/dotclear/admin/blog_theme.php create mode 100644 v2/dotclear/admin/blogs.php create mode 100644 v2/dotclear/admin/categories.php create mode 100644 v2/dotclear/admin/category.php create mode 100644 v2/dotclear/admin/comment.php create mode 100644 v2/dotclear/admin/comments.php create mode 100644 v2/dotclear/admin/comments_actions.php create mode 100644 v2/dotclear/admin/dispatcher.php create mode 100644 v2/dotclear/admin/images/add.png create mode 100644 v2/dotclear/admin/images/admin.png create mode 100644 v2/dotclear/admin/images/attach.png create mode 100644 v2/dotclear/admin/images/check-off.png create mode 100644 v2/dotclear/admin/images/check-on.png create mode 100644 v2/dotclear/admin/images/check-wrn.png create mode 100644 v2/dotclear/admin/images/date-picker.png create mode 100644 v2/dotclear/admin/images/dotclear_pw.png create mode 100644 v2/dotclear/admin/images/edit-mini.png create mode 100644 v2/dotclear/admin/images/favicon.png create mode 100644 v2/dotclear/admin/images/help.png create mode 100644 v2/dotclear/admin/images/junk.png create mode 100644 v2/dotclear/admin/images/locker.png create mode 100644 v2/dotclear/admin/images/logout.png create mode 100644 v2/dotclear/admin/images/media/audio.png create mode 100644 v2/dotclear/admin/images/media/blank.png create mode 100644 v2/dotclear/admin/images/media/document.png create mode 100644 v2/dotclear/admin/images/media/executable.png create mode 100644 v2/dotclear/admin/images/media/folder.png create mode 100644 v2/dotclear/admin/images/media/html.png create mode 100644 v2/dotclear/admin/images/media/image.png create mode 100644 v2/dotclear/admin/images/media/package.png create mode 100644 v2/dotclear/admin/images/media/presentation.png create mode 100644 v2/dotclear/admin/images/media/spreadsheet.png create mode 100644 v2/dotclear/admin/images/media/text.png create mode 100644 v2/dotclear/admin/images/media/video.png create mode 100644 v2/dotclear/admin/images/menu/add_to_favorites.png create mode 100644 v2/dotclear/admin/images/menu/blog-pref-b.png create mode 100644 v2/dotclear/admin/images/menu/blog-pref.png create mode 100644 v2/dotclear/admin/images/menu/blog-theme-b.png create mode 100644 v2/dotclear/admin/images/menu/blogs-b.png create mode 100644 v2/dotclear/admin/images/menu/blogs.png create mode 100644 v2/dotclear/admin/images/menu/categories-b.png create mode 100644 v2/dotclear/admin/images/menu/categories.png create mode 100644 v2/dotclear/admin/images/menu/comments-b.png create mode 100644 v2/dotclear/admin/images/menu/comments.png create mode 100644 v2/dotclear/admin/images/menu/dashboard.png create mode 100644 v2/dotclear/admin/images/menu/edit-b.png create mode 100644 v2/dotclear/admin/images/menu/edit.png create mode 100644 v2/dotclear/admin/images/menu/entries-b.png create mode 100644 v2/dotclear/admin/images/menu/entries.png create mode 100644 v2/dotclear/admin/images/menu/favorite-b.png create mode 100644 v2/dotclear/admin/images/menu/favorite.png create mode 100644 v2/dotclear/admin/images/menu/langs-b.png create mode 100644 v2/dotclear/admin/images/menu/langs.png create mode 100644 v2/dotclear/admin/images/menu/media-b.png create mode 100644 v2/dotclear/admin/images/menu/media.png create mode 100644 v2/dotclear/admin/images/menu/plugins-b.png create mode 100644 v2/dotclear/admin/images/menu/plugins.png create mode 100644 v2/dotclear/admin/images/menu/search-b.png create mode 100644 v2/dotclear/admin/images/menu/search.png create mode 100644 v2/dotclear/admin/images/menu/themes.png create mode 100644 v2/dotclear/admin/images/menu/update.png create mode 100644 v2/dotclear/admin/images/menu/user-pref-b.png create mode 100644 v2/dotclear/admin/images/menu/user-pref.png create mode 100644 v2/dotclear/admin/images/menu/users-b.png create mode 100644 v2/dotclear/admin/images/menu/users.png create mode 100644 v2/dotclear/admin/images/menu_off.png create mode 100644 v2/dotclear/admin/images/menu_on.png create mode 100644 v2/dotclear/admin/images/minus.png create mode 100644 v2/dotclear/admin/images/noscreenshot.png create mode 100644 v2/dotclear/admin/images/outgoing-blue.png create mode 100644 v2/dotclear/admin/images/outgoing.png create mode 100644 v2/dotclear/admin/images/picker.png create mode 100644 v2/dotclear/admin/images/plus.png create mode 100644 v2/dotclear/admin/images/scheduled.png create mode 100644 v2/dotclear/admin/images/selected.png create mode 100644 v2/dotclear/admin/images/superadmin.png create mode 100644 v2/dotclear/admin/images/trash.png create mode 100644 v2/dotclear/admin/index.php create mode 100644 v2/dotclear/admin/install/check.php create mode 100644 v2/dotclear/admin/install/index.php create mode 100644 v2/dotclear/admin/install/wizard.php create mode 100644 v2/dotclear/admin/js/_blog_pref.js create mode 100644 v2/dotclear/admin/js/_blog_theme.js create mode 100644 v2/dotclear/admin/js/_categories.js create mode 100644 v2/dotclear/admin/js/_category.js create mode 100644 v2/dotclear/admin/js/_comment.js create mode 100644 v2/dotclear/admin/js/_comments.js create mode 100644 v2/dotclear/admin/js/_index.js create mode 100644 v2/dotclear/admin/js/_langs.js create mode 100644 v2/dotclear/admin/js/_media.js create mode 100644 v2/dotclear/admin/js/_media_item.js create mode 100644 v2/dotclear/admin/js/_permissions.js create mode 100644 v2/dotclear/admin/js/_permissions_blog.js create mode 100644 v2/dotclear/admin/js/_plugins.js create mode 100644 v2/dotclear/admin/js/_post.js create mode 100644 v2/dotclear/admin/js/_posts_list.js create mode 100644 v2/dotclear/admin/js/_preferences-dragdrop.js create mode 100644 v2/dotclear/admin/js/_preferences.js create mode 100644 v2/dotclear/admin/js/_trackbacks.js create mode 100644 v2/dotclear/admin/js/_users.js create mode 100644 v2/dotclear/admin/js/color-picker.js create mode 100644 v2/dotclear/admin/js/common.js create mode 100644 v2/dotclear/admin/js/confirm-close.js create mode 100644 v2/dotclear/admin/js/date-picker.js create mode 100644 v2/dotclear/admin/js/dragsort-tablerows.js create mode 100644 v2/dotclear/admin/js/filter-controls.js create mode 100644 v2/dotclear/admin/js/ie7/IE7.js create mode 100644 v2/dotclear/admin/js/ie7/IE8.js create mode 100644 v2/dotclear/admin/js/ie7/blank.gif create mode 100644 v2/dotclear/admin/js/ie7/ie7-recalc.js create mode 100644 v2/dotclear/admin/js/ie7/ie7-squish.js create mode 100644 v2/dotclear/admin/js/jquery/jquery-ui-1.8.12.custom.min.js create mode 100644 v2/dotclear/admin/js/jquery/jquery.bgFade.js create mode 100644 v2/dotclear/admin/js/jquery/jquery.biscuit.js create mode 100644 v2/dotclear/admin/js/jquery/jquery.candyUpload.js create mode 100644 v2/dotclear/admin/js/jquery/jquery.farbtastic.js create mode 100644 v2/dotclear/admin/js/jquery/jquery.js create mode 100644 v2/dotclear/admin/js/jquery/jquery.modal.js create mode 100644 v2/dotclear/admin/js/jquery/jquery.pageTabs.js create mode 100644 v2/dotclear/admin/js/jsToolBar/jsToolBar.dotclear.js create mode 100644 v2/dotclear/admin/js/jsToolBar/jsToolBar.js create mode 100644 v2/dotclear/admin/js/jsToolBar/jsToolBar.wysiwyg.js create mode 100644 v2/dotclear/admin/js/jsToolBar/popup_link.js create mode 100644 v2/dotclear/admin/js/jsToolBar/popup_media.js create mode 100644 v2/dotclear/admin/js/jsToolBar/popup_posts.js create mode 100644 v2/dotclear/admin/js/meta-editor.js create mode 100644 v2/dotclear/admin/js/prelude.js create mode 100644 v2/dotclear/admin/js/tool-man/cookies.js create mode 100644 v2/dotclear/admin/js/tool-man/coordinates.js create mode 100644 v2/dotclear/admin/js/tool-man/core.js create mode 100644 v2/dotclear/admin/js/tool-man/css.js create mode 100644 v2/dotclear/admin/js/tool-man/drag.js create mode 100644 v2/dotclear/admin/js/tool-man/dragsort.js create mode 100644 v2/dotclear/admin/js/tool-man/events.js create mode 100644 v2/dotclear/admin/langs.php create mode 100644 v2/dotclear/admin/media.php create mode 100644 v2/dotclear/admin/media_item.php create mode 100644 v2/dotclear/admin/permissions.php create mode 100644 v2/dotclear/admin/permissions_blog.php create mode 100644 v2/dotclear/admin/plugin.php create mode 100644 v2/dotclear/admin/plugins.php create mode 100644 v2/dotclear/admin/popup_link.php create mode 100644 v2/dotclear/admin/popup_posts.php create mode 100644 v2/dotclear/admin/post.php create mode 100644 v2/dotclear/admin/post_media.php create mode 100644 v2/dotclear/admin/posts.php create mode 100644 v2/dotclear/admin/posts_actions.php create mode 100644 v2/dotclear/admin/preferences.php create mode 100644 v2/dotclear/admin/search.php create mode 100644 v2/dotclear/admin/services.php create mode 100644 v2/dotclear/admin/style/add.png create mode 100644 v2/dotclear/admin/style/candyUpload/cancel.png create mode 100644 v2/dotclear/admin/style/candyUpload/loader.png create mode 100644 v2/dotclear/admin/style/candyUpload/style.css create mode 100644 v2/dotclear/admin/style/date-picker.css create mode 100644 v2/dotclear/admin/style/dc_bg.png create mode 100644 v2/dotclear/admin/style/dc_logo.png create mode 100644 v2/dotclear/admin/style/dc_logo_small.png create mode 100644 v2/dotclear/admin/style/default-rtl.css create mode 100644 v2/dotclear/admin/style/default.css create mode 100644 v2/dotclear/admin/style/dotclear-logo.png create mode 100644 v2/dotclear/admin/style/dotclear-logo2.png create mode 100644 v2/dotclear/admin/style/drag.png create mode 100644 v2/dotclear/admin/style/farbtastic/farbtastic.css create mode 100644 v2/dotclear/admin/style/farbtastic/marker.png create mode 100644 v2/dotclear/admin/style/farbtastic/mask.png create mode 100644 v2/dotclear/admin/style/farbtastic/wheel.png create mode 100644 v2/dotclear/admin/style/grid.png create mode 100644 v2/dotclear/admin/style/head-bg.png create mode 100644 v2/dotclear/admin/style/iesucks.css create mode 100644 v2/dotclear/admin/style/info.png create mode 100644 v2/dotclear/admin/style/install.css create mode 100644 v2/dotclear/admin/style/install/important.png create mode 100644 v2/dotclear/admin/style/install/note.png create mode 100644 v2/dotclear/admin/style/install/process_warning.png create mode 100644 v2/dotclear/admin/style/install/w-logo.png create mode 100644 v2/dotclear/admin/style/jsToolBar/bt_bquote.png create mode 100644 v2/dotclear/admin/style/jsToolBar/bt_br.png create mode 100644 v2/dotclear/admin/style/jsToolBar/bt_clean.png create mode 100644 v2/dotclear/admin/style/jsToolBar/bt_code.png create mode 100644 v2/dotclear/admin/style/jsToolBar/bt_del.png create mode 100644 v2/dotclear/admin/style/jsToolBar/bt_em.png create mode 100644 v2/dotclear/admin/style/jsToolBar/bt_img.png create mode 100644 v2/dotclear/admin/style/jsToolBar/bt_img_select.png create mode 100644 v2/dotclear/admin/style/jsToolBar/bt_ins.png create mode 100644 v2/dotclear/admin/style/jsToolBar/bt_link.png create mode 100644 v2/dotclear/admin/style/jsToolBar/bt_ol.png create mode 100644 v2/dotclear/admin/style/jsToolBar/bt_paragraph.png create mode 100644 v2/dotclear/admin/style/jsToolBar/bt_post.png create mode 100644 v2/dotclear/admin/style/jsToolBar/bt_pre.png create mode 100644 v2/dotclear/admin/style/jsToolBar/bt_quote.png create mode 100644 v2/dotclear/admin/style/jsToolBar/bt_strong.png create mode 100644 v2/dotclear/admin/style/jsToolBar/bt_ul.png create mode 100644 v2/dotclear/admin/style/jsToolBar/jsToolBar.css create mode 100644 v2/dotclear/admin/style/jsToolBar/resize.png create mode 100644 v2/dotclear/admin/style/magnifier.png create mode 100644 v2/dotclear/admin/style/modal/close.png create mode 100644 v2/dotclear/admin/style/modal/loader.gif create mode 100644 v2/dotclear/admin/style/modal/modal.css create mode 100644 v2/dotclear/admin/style/msg-error.png create mode 100644 v2/dotclear/admin/style/msg-std.png create mode 100644 v2/dotclear/admin/style/package.png create mode 100644 v2/dotclear/admin/style/page-bg.png create mode 100644 v2/dotclear/admin/style/warning.png create mode 100644 v2/dotclear/admin/trackbacks.php create mode 100644 v2/dotclear/admin/update.php create mode 100644 v2/dotclear/admin/user.php create mode 100644 v2/dotclear/admin/users.php create mode 100644 v2/dotclear/admin/xmlrpc.php create mode 100644 v2/dotclear/cache/.htaccess create mode 100644 v2/dotclear/db/.htaccess create mode 100644 v2/dotclear/inc/.htaccess create mode 100644 v2/dotclear/inc/admin/class.dc.menu.php create mode 100644 v2/dotclear/inc/admin/lib.dc.page.php create mode 100644 v2/dotclear/inc/admin/lib.pager.php create mode 100644 v2/dotclear/inc/admin/prepend.php create mode 100644 v2/dotclear/inc/config.php.in create mode 100644 v2/dotclear/inc/core/class.dc.auth.php create mode 100644 v2/dotclear/inc/core/class.dc.blog.php create mode 100644 v2/dotclear/inc/core/class.dc.categories.php create mode 100644 v2/dotclear/inc/core/class.dc.core.php create mode 100644 v2/dotclear/inc/core/class.dc.error.php create mode 100644 v2/dotclear/inc/core/class.dc.log.php create mode 100644 v2/dotclear/inc/core/class.dc.media.php create mode 100644 v2/dotclear/inc/core/class.dc.meta.php create mode 100644 v2/dotclear/inc/core/class.dc.modules.php create mode 100644 v2/dotclear/inc/core/class.dc.namespace.php create mode 100644 v2/dotclear/inc/core/class.dc.postmedia.php create mode 100644 v2/dotclear/inc/core/class.dc.prefs.php create mode 100644 v2/dotclear/inc/core/class.dc.rest.php create mode 100644 v2/dotclear/inc/core/class.dc.rs.extensions.php create mode 100644 v2/dotclear/inc/core/class.dc.settings.php create mode 100644 v2/dotclear/inc/core/class.dc.themes.php create mode 100644 v2/dotclear/inc/core/class.dc.trackback.php create mode 100644 v2/dotclear/inc/core/class.dc.update.php create mode 100644 v2/dotclear/inc/core/class.dc.utils.php create mode 100644 v2/dotclear/inc/core/class.dc.workspace.php create mode 100644 v2/dotclear/inc/core/class.dc.xmlrpc.php create mode 100644 v2/dotclear/inc/core_error.php create mode 100644 v2/dotclear/inc/dbschema/db-schema.php create mode 100644 v2/dotclear/inc/dbschema/upgrade-cli.php create mode 100644 v2/dotclear/inc/dbschema/upgrade.php create mode 100644 v2/dotclear/inc/digests create mode 100644 v2/dotclear/inc/libs/clearbricks/Makefile create mode 100644 v2/dotclear/inc/libs/clearbricks/README create mode 100644 v2/dotclear/inc/libs/clearbricks/_common.php create mode 100644 v2/dotclear/inc/libs/clearbricks/common/_main.php create mode 100644 v2/dotclear/inc/libs/clearbricks/common/lib.crypt.php create mode 100644 v2/dotclear/inc/libs/clearbricks/common/lib.date.php create mode 100644 v2/dotclear/inc/libs/clearbricks/common/lib.files.php create mode 100644 v2/dotclear/inc/libs/clearbricks/common/lib.form.php create mode 100644 v2/dotclear/inc/libs/clearbricks/common/lib.html.php create mode 100644 v2/dotclear/inc/libs/clearbricks/common/lib.http.php create mode 100644 v2/dotclear/inc/libs/clearbricks/common/lib.l10n.php create mode 100644 v2/dotclear/inc/libs/clearbricks/common/lib.text.php create mode 100644 v2/dotclear/inc/libs/clearbricks/common/tz.dat create mode 100644 v2/dotclear/inc/libs/clearbricks/dblayer/class.cursor.php create mode 100644 v2/dotclear/inc/libs/clearbricks/dblayer/class.mysql.php create mode 100644 v2/dotclear/inc/libs/clearbricks/dblayer/class.mysqli.php create mode 100644 v2/dotclear/inc/libs/clearbricks/dblayer/class.pgsql.php create mode 100644 v2/dotclear/inc/libs/clearbricks/dblayer/class.sqlite.php create mode 100644 v2/dotclear/inc/libs/clearbricks/dblayer/dblayer.php create mode 100644 v2/dotclear/inc/libs/clearbricks/dbschema/class.dbschema.php create mode 100644 v2/dotclear/inc/libs/clearbricks/dbschema/class.dbstruct.php create mode 100644 v2/dotclear/inc/libs/clearbricks/dbschema/class.mysql.dbschema.php create mode 100644 v2/dotclear/inc/libs/clearbricks/dbschema/class.mysqli.dbschema.php create mode 100644 v2/dotclear/inc/libs/clearbricks/dbschema/class.pgsql.dbschema.php create mode 100644 v2/dotclear/inc/libs/clearbricks/dbschema/class.sqlite.dbschema.php create mode 100644 v2/dotclear/inc/libs/clearbricks/debian/changelog create mode 100644 v2/dotclear/inc/libs/clearbricks/debian/compat create mode 100644 v2/dotclear/inc/libs/clearbricks/debian/control create mode 100644 v2/dotclear/inc/libs/clearbricks/debian/copyright create mode 100644 v2/dotclear/inc/libs/clearbricks/debian/dirs create mode 100644 v2/dotclear/inc/libs/clearbricks/debian/docs create mode 100644 v2/dotclear/inc/libs/clearbricks/debian/mkdcl.php create mode 100644 v2/dotclear/inc/libs/clearbricks/debian/rules create mode 100644 v2/dotclear/inc/libs/clearbricks/diff/lib.diff.php create mode 100644 v2/dotclear/inc/libs/clearbricks/diff/lib.tidy.diff.php create mode 100644 v2/dotclear/inc/libs/clearbricks/ext/incutio.ixr_library.php create mode 100644 v2/dotclear/inc/libs/clearbricks/filemanager/class.filemanager.php create mode 100644 v2/dotclear/inc/libs/clearbricks/html.filter/class.html.filter.php create mode 100644 v2/dotclear/inc/libs/clearbricks/html.validator/class.html.validator.php create mode 100644 v2/dotclear/inc/libs/clearbricks/image/class.image.meta.php create mode 100644 v2/dotclear/inc/libs/clearbricks/image/class.image.tools.php create mode 100644 v2/dotclear/inc/libs/clearbricks/mail.convert/class.mail.convert.php create mode 100644 v2/dotclear/inc/libs/clearbricks/mail.mime/class.mime.message.php create mode 100644 v2/dotclear/inc/libs/clearbricks/mail/class.mail.php create mode 100644 v2/dotclear/inc/libs/clearbricks/mail/class.socket.mail.php create mode 100644 v2/dotclear/inc/libs/clearbricks/net.http.feed/class.feed.parser.php create mode 100644 v2/dotclear/inc/libs/clearbricks/net.http.feed/class.feed.reader.php create mode 100644 v2/dotclear/inc/libs/clearbricks/net.http/class.net.http.php create mode 100644 v2/dotclear/inc/libs/clearbricks/net.nntp/class.net.nntp.php create mode 100644 v2/dotclear/inc/libs/clearbricks/net.nntp/class.nntp.message.php create mode 100644 v2/dotclear/inc/libs/clearbricks/net.xmlrpc/class.net.xmlrpc.php create mode 100644 v2/dotclear/inc/libs/clearbricks/net/class.net.socket.php create mode 100644 v2/dotclear/inc/libs/clearbricks/pager/class.pager.php create mode 100644 v2/dotclear/inc/libs/clearbricks/rest/class.rest.php create mode 100644 v2/dotclear/inc/libs/clearbricks/session.db/class.session.db.php create mode 100644 v2/dotclear/inc/libs/clearbricks/template/class.template.php create mode 100644 v2/dotclear/inc/libs/clearbricks/text.wiki2xhtml/class.wiki2xhtml.php create mode 100644 v2/dotclear/inc/libs/clearbricks/url.handler/class.url.handler.php create mode 100644 v2/dotclear/inc/libs/clearbricks/xmlsql/class.xmlsql.php create mode 100644 v2/dotclear/inc/libs/clearbricks/zip/class.unzip.php create mode 100644 v2/dotclear/inc/libs/clearbricks/zip/class.zip.php create mode 100644 v2/dotclear/inc/load_plugin_file.php create mode 100644 v2/dotclear/inc/prepend.php create mode 100644 v2/dotclear/inc/public/class.dc.template.php create mode 100644 v2/dotclear/inc/public/default-templates/404.html create mode 100644 v2/dotclear/inc/public/default-templates/_flv_player.html create mode 100644 v2/dotclear/inc/public/default-templates/_footer.html create mode 100644 v2/dotclear/inc/public/default-templates/_head.html create mode 100644 v2/dotclear/inc/public/default-templates/_mp3_player.html create mode 100644 v2/dotclear/inc/public/default-templates/_top.html create mode 100644 v2/dotclear/inc/public/default-templates/archive.html create mode 100644 v2/dotclear/inc/public/default-templates/archive_month.html create mode 100644 v2/dotclear/inc/public/default-templates/atom-comments.xml create mode 100644 v2/dotclear/inc/public/default-templates/atom.xml create mode 100644 v2/dotclear/inc/public/default-templates/category.html create mode 100644 v2/dotclear/inc/public/default-templates/home.html create mode 100644 v2/dotclear/inc/public/default-templates/password-form.html create mode 100644 v2/dotclear/inc/public/default-templates/post.html create mode 100644 v2/dotclear/inc/public/default-templates/rss2-comments.xml create mode 100644 v2/dotclear/inc/public/default-templates/rss2.xml create mode 100644 v2/dotclear/inc/public/default-templates/rss2.xsl create mode 100644 v2/dotclear/inc/public/default-templates/search.html create mode 100644 v2/dotclear/inc/public/default-templates/user_head.html create mode 100644 v2/dotclear/inc/public/lib.tpl.context.php create mode 100644 v2/dotclear/inc/public/lib.urlhandlers.php create mode 100644 v2/dotclear/inc/public/prepend.php create mode 100644 v2/dotclear/inc/public/rs.extension.php create mode 100644 v2/dotclear/inc/swf/player_flv.swf create mode 100644 v2/dotclear/inc/swf/player_mp3.swf create mode 100644 v2/dotclear/inc/swf/swfupload.swf create mode 100644 v2/dotclear/index.php create mode 100644 v2/dotclear/locales/README create mode 100644 v2/dotclear/locales/en/date.lang.php create mode 100644 v2/dotclear/locales/en/date.po create mode 100644 v2/dotclear/locales/en/help/blog_pref.html create mode 100644 v2/dotclear/locales/en/help/categories.html create mode 100644 v2/dotclear/locales/en/help/comments.html create mode 100644 v2/dotclear/locales/en/help/media.html create mode 100644 v2/dotclear/locales/en/help/post.html create mode 100644 v2/dotclear/locales/en/help/posts.html create mode 100644 v2/dotclear/locales/en/help/user.html create mode 100644 v2/dotclear/locales/en/help/user_pref.html create mode 100644 v2/dotclear/locales/en/help/wiki.html create mode 100644 v2/dotclear/locales/en/main.lang.php create mode 100644 v2/dotclear/locales/en/main.po create mode 100644 v2/dotclear/locales/en/plugins.lang.php create mode 100644 v2/dotclear/locales/en/plugins.po create mode 100644 v2/dotclear/locales/en/public.lang.php create mode 100644 v2/dotclear/locales/en/public.po create mode 100644 v2/dotclear/locales/en/resources.php create mode 100644 v2/dotclear/locales/fr/date.lang.php create mode 100644 v2/dotclear/locales/fr/date.po create mode 100644 v2/dotclear/locales/fr/help/blowupConfig.html create mode 100644 v2/dotclear/locales/fr/help/core_blog_pref.html create mode 100644 v2/dotclear/locales/fr/help/core_categories.html create mode 100644 v2/dotclear/locales/fr/help/core_comments.html create mode 100644 v2/dotclear/locales/fr/help/core_media.html create mode 100644 v2/dotclear/locales/fr/help/core_post.html create mode 100644 v2/dotclear/locales/fr/help/core_posts.html create mode 100644 v2/dotclear/locales/fr/help/core_user.html create mode 100644 v2/dotclear/locales/fr/help/core_user_pref.html create mode 100644 v2/dotclear/locales/fr/help/core_wiki.html create mode 100644 v2/dotclear/locales/fr/help/themeEditor.html create mode 100644 v2/dotclear/locales/fr/main.lang.php create mode 100644 v2/dotclear/locales/fr/main.po create mode 100644 v2/dotclear/locales/fr/plugins.lang.php create mode 100644 v2/dotclear/locales/fr/plugins.po create mode 100644 v2/dotclear/locales/fr/public.lang.php create mode 100644 v2/dotclear/locales/fr/public.po create mode 100644 v2/dotclear/locales/fr/resources.php create mode 100644 v2/dotclear/plugins/.htaccess create mode 100644 v2/dotclear/plugins/aboutConfig/_admin.php create mode 100644 v2/dotclear/plugins/aboutConfig/_define.php create mode 100644 v2/dotclear/plugins/aboutConfig/icon-big.png create mode 100644 v2/dotclear/plugins/aboutConfig/icon.png create mode 100644 v2/dotclear/plugins/aboutConfig/index.php create mode 100644 v2/dotclear/plugins/akismet/_define.php create mode 100644 v2/dotclear/plugins/akismet/_prepend.php create mode 100644 v2/dotclear/plugins/akismet/class.dc.filter.akismet.php create mode 100644 v2/dotclear/plugins/antispam/_admin.php create mode 100644 v2/dotclear/plugins/antispam/_define.php create mode 100644 v2/dotclear/plugins/antispam/_install.php create mode 100644 v2/dotclear/plugins/antispam/_prepend.php create mode 100644 v2/dotclear/plugins/antispam/_public.php create mode 100644 v2/dotclear/plugins/antispam/antispam.js create mode 100644 v2/dotclear/plugins/antispam/feed.png create mode 100644 v2/dotclear/plugins/antispam/filters/class.dc.filter.ip.php create mode 100644 v2/dotclear/plugins/antispam/filters/class.dc.filter.iplookup.php create mode 100644 v2/dotclear/plugins/antispam/filters/class.dc.filter.linkslookup.php create mode 100644 v2/dotclear/plugins/antispam/filters/class.dc.filter.words.php create mode 100644 v2/dotclear/plugins/antispam/icon-big.png create mode 100644 v2/dotclear/plugins/antispam/icon.png create mode 100644 v2/dotclear/plugins/antispam/inc/class.dc.spamfilter.php create mode 100644 v2/dotclear/plugins/antispam/inc/class.dc.spamfilters.php create mode 100644 v2/dotclear/plugins/antispam/inc/lib.dc.antispam.php create mode 100644 v2/dotclear/plugins/antispam/inc/lib.dc.antispam.url.php create mode 100644 v2/dotclear/plugins/antispam/index.php create mode 100644 v2/dotclear/plugins/antispam/style.css create mode 100644 v2/dotclear/plugins/attachments/_admin.php create mode 100644 v2/dotclear/plugins/attachments/_define.php create mode 100644 v2/dotclear/plugins/attachments/_public.php create mode 100644 v2/dotclear/plugins/blogroll/_admin.php create mode 100644 v2/dotclear/plugins/blogroll/_define.php create mode 100644 v2/dotclear/plugins/blogroll/_install.php create mode 100644 v2/dotclear/plugins/blogroll/_prepend.php create mode 100644 v2/dotclear/plugins/blogroll/_public.php create mode 100644 v2/dotclear/plugins/blogroll/_widgets.php create mode 100644 v2/dotclear/plugins/blogroll/class.dc.blogroll.php create mode 100644 v2/dotclear/plugins/blogroll/class.dc.importblogroll.php create mode 100644 v2/dotclear/plugins/blogroll/edit.php create mode 100644 v2/dotclear/plugins/blogroll/icon-small.png create mode 100644 v2/dotclear/plugins/blogroll/icon.png create mode 100644 v2/dotclear/plugins/blogroll/index.php create mode 100644 v2/dotclear/plugins/blogroll/locales/en/help/blogroll.html create mode 100644 v2/dotclear/plugins/blogroll/locales/en/resources.php create mode 100644 v2/dotclear/plugins/blogroll/locales/fr/help/blogroll.html create mode 100644 v2/dotclear/plugins/blogroll/locales/fr/resources.php create mode 100644 v2/dotclear/plugins/blowupConfig/_admin.php create mode 100644 v2/dotclear/plugins/blowupConfig/_define.php create mode 100644 v2/dotclear/plugins/blowupConfig/_install.php create mode 100644 v2/dotclear/plugins/blowupConfig/_public.php create mode 100644 v2/dotclear/plugins/blowupConfig/alpha-img/comment-b.png create mode 100644 v2/dotclear/plugins/blowupConfig/alpha-img/comment-t.png create mode 100644 v2/dotclear/plugins/blowupConfig/alpha-img/gradient-d.png create mode 100644 v2/dotclear/plugins/blowupConfig/alpha-img/gradient-l.png create mode 100644 v2/dotclear/plugins/blowupConfig/alpha-img/gradient-m.png create mode 100644 v2/dotclear/plugins/blowupConfig/alpha-img/page-b.png create mode 100644 v2/dotclear/plugins/blowupConfig/alpha-img/page-bg.png create mode 100644 v2/dotclear/plugins/blowupConfig/alpha-img/page-t/animals.png create mode 100644 v2/dotclear/plugins/blowupConfig/alpha-img/page-t/blank.png create mode 100644 v2/dotclear/plugins/blowupConfig/alpha-img/page-t/butterflies.png create mode 100644 v2/dotclear/plugins/blowupConfig/alpha-img/page-t/default.png create mode 100644 v2/dotclear/plugins/blowupConfig/alpha-img/page-t/flamingo.png create mode 100644 v2/dotclear/plugins/blowupConfig/alpha-img/page-t/flourish-1.png create mode 100644 v2/dotclear/plugins/blowupConfig/alpha-img/page-t/flourish-2.png create mode 100644 v2/dotclear/plugins/blowupConfig/alpha-img/page-t/image-mask.png create mode 100644 v2/dotclear/plugins/blowupConfig/alpha-img/page-t/light-trails-1.png create mode 100644 v2/dotclear/plugins/blowupConfig/alpha-img/page-t/light-trails-2.png create mode 100644 v2/dotclear/plugins/blowupConfig/alpha-img/page-t/light-trails-3.png create mode 100644 v2/dotclear/plugins/blowupConfig/alpha-img/page-t/light-trails-4.png create mode 100644 v2/dotclear/plugins/blowupConfig/alpha-img/page-t/rabbit.png create mode 100644 v2/dotclear/plugins/blowupConfig/alpha-img/page-t/roadrunner-1.png create mode 100644 v2/dotclear/plugins/blowupConfig/alpha-img/page-t/roadrunner-2.png create mode 100644 v2/dotclear/plugins/blowupConfig/alpha-img/page-t/typo.png create mode 100644 v2/dotclear/plugins/blowupConfig/config.js create mode 100644 v2/dotclear/plugins/blowupConfig/help.html create mode 100644 v2/dotclear/plugins/blowupConfig/index.php create mode 100644 v2/dotclear/plugins/blowupConfig/lib/class.blowup.config.php create mode 100644 v2/dotclear/plugins/fairTrackbacks/_define.php create mode 100644 v2/dotclear/plugins/fairTrackbacks/_prepend.php create mode 100644 v2/dotclear/plugins/fairTrackbacks/_public.php create mode 100644 v2/dotclear/plugins/fairTrackbacks/class.dc.filter.fairtrackbacks.php create mode 100644 v2/dotclear/plugins/importExport/_admin.php create mode 100644 v2/dotclear/plugins/importExport/_define.php create mode 100644 v2/dotclear/plugins/importExport/_prepend.php create mode 100644 v2/dotclear/plugins/importExport/icon-big.png create mode 100644 v2/dotclear/plugins/importExport/icon.png create mode 100644 v2/dotclear/plugins/importExport/inc/class.dc.export.flat.php create mode 100644 v2/dotclear/plugins/importExport/inc/class.dc.ieModule.php create mode 100644 v2/dotclear/plugins/importExport/inc/class.dc.import.dc1.php create mode 100644 v2/dotclear/plugins/importExport/inc/class.dc.import.feed.php create mode 100644 v2/dotclear/plugins/importExport/inc/class.dc.import.flat.php create mode 100644 v2/dotclear/plugins/importExport/inc/class.dc.import.wp.php create mode 100644 v2/dotclear/plugins/importExport/inc/flat/class.flat.backup.php create mode 100644 v2/dotclear/plugins/importExport/inc/flat/class.flat.export.php create mode 100644 v2/dotclear/plugins/importExport/inc/flat/class.flat.import.php create mode 100644 v2/dotclear/plugins/importExport/inc/img/progress.png create mode 100644 v2/dotclear/plugins/importExport/index.php create mode 100644 v2/dotclear/plugins/importExport/js/script.js create mode 100644 v2/dotclear/plugins/importExport/locales/fr/main.lang.php create mode 100644 v2/dotclear/plugins/importExport/locales/fr/main.po create mode 100644 v2/dotclear/plugins/importExport/style.css create mode 100644 v2/dotclear/plugins/maintenance/_admin.php create mode 100644 v2/dotclear/plugins/maintenance/_define.php create mode 100644 v2/dotclear/plugins/maintenance/icon-big.png create mode 100644 v2/dotclear/plugins/maintenance/icon.png create mode 100644 v2/dotclear/plugins/maintenance/index.php create mode 100644 v2/dotclear/plugins/maintenance/locales/en/help/maintenance.html create mode 100644 v2/dotclear/plugins/maintenance/locales/en/resources.php create mode 100644 v2/dotclear/plugins/maintenance/locales/fr/help/maintenance.html create mode 100644 v2/dotclear/plugins/maintenance/locales/fr/resources.php create mode 100644 v2/dotclear/plugins/pages/_admin.php create mode 100644 v2/dotclear/plugins/pages/_define.php create mode 100644 v2/dotclear/plugins/pages/_prepend.php create mode 100644 v2/dotclear/plugins/pages/_public.php create mode 100644 v2/dotclear/plugins/pages/_widgets.php create mode 100644 v2/dotclear/plugins/pages/default-templates/page.html create mode 100644 v2/dotclear/plugins/pages/icon-big.png create mode 100644 v2/dotclear/plugins/pages/icon-np-big.png create mode 100644 v2/dotclear/plugins/pages/icon-np.png create mode 100644 v2/dotclear/plugins/pages/icon.png create mode 100644 v2/dotclear/plugins/pages/index.php create mode 100644 v2/dotclear/plugins/pages/list.php create mode 100644 v2/dotclear/plugins/pages/locales/en/help/page.html create mode 100644 v2/dotclear/plugins/pages/locales/en/help/pages.html create mode 100644 v2/dotclear/plugins/pages/locales/en/resources.php create mode 100644 v2/dotclear/plugins/pages/locales/fr/help/page.html create mode 100644 v2/dotclear/plugins/pages/locales/fr/help/pages.html create mode 100644 v2/dotclear/plugins/pages/locales/fr/resources.php create mode 100644 v2/dotclear/plugins/pages/page.php create mode 100644 v2/dotclear/plugins/pings/_admin.php create mode 100644 v2/dotclear/plugins/pings/_define.php create mode 100644 v2/dotclear/plugins/pings/icon-big.png create mode 100644 v2/dotclear/plugins/pings/icon.png create mode 100644 v2/dotclear/plugins/pings/index.php create mode 100644 v2/dotclear/plugins/pings/lib.pings.php create mode 100644 v2/dotclear/plugins/pings/post.js create mode 100644 v2/dotclear/plugins/simpleMenu/_admin.php create mode 100644 v2/dotclear/plugins/simpleMenu/_define.php create mode 100644 v2/dotclear/plugins/simpleMenu/_install.php create mode 100644 v2/dotclear/plugins/simpleMenu/_public.php create mode 100644 v2/dotclear/plugins/simpleMenu/_widgets.php create mode 100644 v2/dotclear/plugins/simpleMenu/icon-small.png create mode 100644 v2/dotclear/plugins/simpleMenu/icon.png create mode 100644 v2/dotclear/plugins/simpleMenu/index.php create mode 100644 v2/dotclear/plugins/simpleMenu/locales/en/help/help.html create mode 100644 v2/dotclear/plugins/simpleMenu/locales/en/resources.php create mode 100644 v2/dotclear/plugins/simpleMenu/locales/fr/help/help.html create mode 100644 v2/dotclear/plugins/simpleMenu/locales/fr/resources.php create mode 100644 v2/dotclear/plugins/tags/_admin.php create mode 100644 v2/dotclear/plugins/tags/_define.php create mode 100644 v2/dotclear/plugins/tags/_prepend.php create mode 100644 v2/dotclear/plugins/tags/_public.php create mode 100644 v2/dotclear/plugins/tags/_widgets.php create mode 100644 v2/dotclear/plugins/tags/_xmlrpc.php create mode 100644 v2/dotclear/plugins/tags/default-templates/tag.html create mode 100644 v2/dotclear/plugins/tags/default-templates/tags.html create mode 100644 v2/dotclear/plugins/tags/icon-big.png create mode 100644 v2/dotclear/plugins/tags/icon.png create mode 100644 v2/dotclear/plugins/tags/img/loader.gif create mode 100644 v2/dotclear/plugins/tags/img/tag-add.png create mode 100644 v2/dotclear/plugins/tags/index.php create mode 100644 v2/dotclear/plugins/tags/js/jquery.autocomplete.js create mode 100644 v2/dotclear/plugins/tags/js/post.js create mode 100644 v2/dotclear/plugins/tags/js/posts_actions.js create mode 100644 v2/dotclear/plugins/tags/style.css create mode 100644 v2/dotclear/plugins/tags/tag_posts.php create mode 100644 v2/dotclear/plugins/tags/tags.php create mode 100644 v2/dotclear/plugins/themeEditor/_admin.php create mode 100644 v2/dotclear/plugins/themeEditor/_define.php create mode 100644 v2/dotclear/plugins/themeEditor/class.themeEditor.php create mode 100644 v2/dotclear/plugins/themeEditor/help.html create mode 100644 v2/dotclear/plugins/themeEditor/index.php create mode 100644 v2/dotclear/plugins/themeEditor/script.js create mode 100644 v2/dotclear/plugins/themeEditor/style.css create mode 100644 v2/dotclear/plugins/userPref/_admin.php create mode 100644 v2/dotclear/plugins/userPref/_define.php create mode 100644 v2/dotclear/plugins/userPref/icon-big.png create mode 100644 v2/dotclear/plugins/userPref/icon.png create mode 100644 v2/dotclear/plugins/userPref/index.php create mode 100644 v2/dotclear/plugins/widgets/_admin.php create mode 100644 v2/dotclear/plugins/widgets/_default_widgets.php create mode 100644 v2/dotclear/plugins/widgets/_define.php create mode 100644 v2/dotclear/plugins/widgets/_install.php create mode 100644 v2/dotclear/plugins/widgets/_public.php create mode 100644 v2/dotclear/plugins/widgets/_widgets_functions.php create mode 100644 v2/dotclear/plugins/widgets/class.widgets.php create mode 100644 v2/dotclear/plugins/widgets/dragdrop.js create mode 100644 v2/dotclear/plugins/widgets/icon-big.png create mode 100644 v2/dotclear/plugins/widgets/icon.png create mode 100644 v2/dotclear/plugins/widgets/index.php create mode 100644 v2/dotclear/plugins/widgets/style.css create mode 100644 v2/dotclear/plugins/widgets/widgets.js create mode 100644 v2/dotclear/themes/blueSilence/_define.php create mode 100644 v2/dotclear/themes/blueSilence/img/attach.png create mode 100644 v2/dotclear/themes/blueSilence/img/background.png create mode 100644 v2/dotclear/themes/blueSilence/img/commentaire.png create mode 100644 v2/dotclear/themes/blueSilence/img/commentaire_bulle.png create mode 100644 v2/dotclear/themes/blueSilence/img/footer.png create mode 100644 v2/dotclear/themes/blueSilence/img/li.png create mode 100644 v2/dotclear/themes/blueSilence/img/report.png create mode 100644 v2/dotclear/themes/blueSilence/img/retrolien.png create mode 100644 v2/dotclear/themes/blueSilence/img/rss.png create mode 100644 v2/dotclear/themes/blueSilence/img/sidebar_li.png create mode 100644 v2/dotclear/themes/blueSilence/img/tag.png create mode 100644 v2/dotclear/themes/blueSilence/img/tags.png create mode 100644 v2/dotclear/themes/blueSilence/img/top.jpg create mode 100644 v2/dotclear/themes/blueSilence/screenshot.jpg create mode 100644 v2/dotclear/themes/blueSilence/style.css create mode 100644 v2/dotclear/themes/customCSS/_config.php create mode 100644 v2/dotclear/themes/customCSS/_define.php create mode 100644 v2/dotclear/themes/customCSS/_public.php create mode 100644 v2/dotclear/themes/customCSS/locales/fr/main.lang.php create mode 100644 v2/dotclear/themes/customCSS/locales/fr/main.po create mode 100644 v2/dotclear/themes/customCSS/style.css create mode 100644 v2/dotclear/themes/default/_define.php create mode 100644 v2/dotclear/themes/default/img/attach.png create mode 100644 v2/dotclear/themes/default/img/body-bg.png create mode 100644 v2/dotclear/themes/default/img/comment-b.png create mode 100644 v2/dotclear/themes/default/img/comment-t.png create mode 100644 v2/dotclear/themes/default/img/comment.png create mode 100644 v2/dotclear/themes/default/img/commentmy-b.png create mode 100644 v2/dotclear/themes/default/img/commentmy-t.png create mode 100644 v2/dotclear/themes/default/img/feed.png create mode 100644 v2/dotclear/themes/default/img/page-b.png create mode 100644 v2/dotclear/themes/default/img/page-bg.png create mode 100644 v2/dotclear/themes/default/img/page-t.png create mode 100644 v2/dotclear/themes/default/img/tag.png create mode 100644 v2/dotclear/themes/default/img/trackback.png create mode 100644 v2/dotclear/themes/default/js/jquery.cookie.js create mode 100644 v2/dotclear/themes/default/js/jquery.js create mode 100644 v2/dotclear/themes/default/js/post.js create mode 100644 v2/dotclear/themes/default/print.css create mode 100644 v2/dotclear/themes/default/screenshot.jpg create mode 100644 v2/dotclear/themes/default/smilies/alien.png create mode 100644 v2/dotclear/themes/default/smilies/angry.png create mode 100644 v2/dotclear/themes/default/smilies/arrow.png create mode 100644 v2/dotclear/themes/default/smilies/confused.png create mode 100644 v2/dotclear/themes/default/smilies/cool.png create mode 100644 v2/dotclear/themes/default/smilies/cry.png create mode 100644 v2/dotclear/themes/default/smilies/dizzy.png create mode 100644 v2/dotclear/themes/default/smilies/eek.png create mode 100644 v2/dotclear/themes/default/smilies/evil.png create mode 100644 v2/dotclear/themes/default/smilies/exclam.png create mode 100644 v2/dotclear/themes/default/smilies/idea.png create mode 100644 v2/dotclear/themes/default/smilies/laugh.png create mode 100644 v2/dotclear/themes/default/smilies/lol.png create mode 100644 v2/dotclear/themes/default/smilies/mrgreen.png create mode 100644 v2/dotclear/themes/default/smilies/normal.png create mode 100644 v2/dotclear/themes/default/smilies/question.png create mode 100644 v2/dotclear/themes/default/smilies/razz.png create mode 100644 v2/dotclear/themes/default/smilies/redface.png create mode 100644 v2/dotclear/themes/default/smilies/rolleyes.png create mode 100644 v2/dotclear/themes/default/smilies/sad.png create mode 100644 v2/dotclear/themes/default/smilies/smile.png create mode 100644 v2/dotclear/themes/default/smilies/smilies.txt create mode 100644 v2/dotclear/themes/default/smilies/surprised.png create mode 100644 v2/dotclear/themes/default/smilies/wink.png create mode 100644 v2/dotclear/themes/default/style.css create mode 100644 v2/dotclear/themes/ductile/_config.php create mode 100644 v2/dotclear/themes/ductile/_define.php create mode 100644 v2/dotclear/themes/ductile/_prepend.php create mode 100644 v2/dotclear/themes/ductile/_public.php create mode 100644 v2/dotclear/themes/ductile/ductile.js create mode 100644 v2/dotclear/themes/ductile/ie.css create mode 100644 v2/dotclear/themes/ductile/img/404.png create mode 100644 v2/dotclear/themes/ductile/img/download.png create mode 100644 v2/dotclear/themes/ductile/img/feed.png create mode 100644 v2/dotclear/themes/ductile/img/filet.png create mode 100644 v2/dotclear/themes/ductile/img/hline.png create mode 100644 v2/dotclear/themes/ductile/img/info-co.png create mode 100644 v2/dotclear/themes/ductile/img/last-hline.png create mode 100644 v2/dotclear/themes/ductile/img/logo.png create mode 100644 v2/dotclear/themes/ductile/img/menu.png create mode 100644 v2/dotclear/themes/ductile/img/menumobile.png create mode 100644 v2/dotclear/themes/ductile/img/minus-plus.png create mode 100644 v2/dotclear/themes/ductile/img/post-info.png create mode 100644 v2/dotclear/themes/ductile/img/squares.png create mode 100644 v2/dotclear/themes/ductile/img/sticker-about.png create mode 100644 v2/dotclear/themes/ductile/img/sticker-contact.png create mode 100644 v2/dotclear/themes/ductile/img/sticker-feed.png create mode 100644 v2/dotclear/themes/ductile/img/vline.png create mode 100644 v2/dotclear/themes/ductile/locales/en/help/help.html create mode 100644 v2/dotclear/themes/ductile/locales/en/main.lang.php create mode 100644 v2/dotclear/themes/ductile/locales/en/main.po create mode 100644 v2/dotclear/themes/ductile/locales/en/resources.php create mode 100644 v2/dotclear/themes/ductile/locales/es/main.lang.php create mode 100644 v2/dotclear/themes/ductile/locales/es/main.po create mode 100644 v2/dotclear/themes/ductile/locales/fr/admin.lang.php create mode 100644 v2/dotclear/themes/ductile/locales/fr/admin.po create mode 100644 v2/dotclear/themes/ductile/locales/fr/help/help.html create mode 100644 v2/dotclear/themes/ductile/locales/fr/main.lang.php create mode 100644 v2/dotclear/themes/ductile/locales/fr/main.po create mode 100644 v2/dotclear/themes/ductile/locales/fr/resources.php create mode 100644 v2/dotclear/themes/ductile/mediaqueries.css create mode 100644 v2/dotclear/themes/ductile/rebase.css create mode 100644 v2/dotclear/themes/ductile/screenshot.jpg create mode 100644 v2/dotclear/themes/ductile/style.css create mode 100644 v2/dotclear/themes/ductile/tpl/404.html create mode 100644 v2/dotclear/themes/ductile/tpl/_entry-full.html create mode 100644 v2/dotclear/themes/ductile/tpl/_entry-short.html create mode 100644 v2/dotclear/themes/ductile/tpl/_entry-title.html create mode 100644 v2/dotclear/themes/ductile/tpl/_footer.html create mode 100644 v2/dotclear/themes/ductile/tpl/_head.html create mode 100644 v2/dotclear/themes/ductile/tpl/_pagination.html create mode 100644 v2/dotclear/themes/ductile/tpl/_sidebar.html create mode 100644 v2/dotclear/themes/ductile/tpl/_simple-entry.html create mode 100644 v2/dotclear/themes/ductile/tpl/_top.html create mode 100644 v2/dotclear/themes/ductile/tpl/archive.html create mode 100644 v2/dotclear/themes/ductile/tpl/archive_month.html create mode 100644 v2/dotclear/themes/ductile/tpl/category.html create mode 100644 v2/dotclear/themes/ductile/tpl/home.html create mode 100644 v2/dotclear/themes/ductile/tpl/page.html create mode 100644 v2/dotclear/themes/ductile/tpl/post.html create mode 100644 v2/dotclear/themes/ductile/tpl/search.html create mode 100644 v2/dotclear/themes/ductile/tpl/tag.html create mode 100644 v2/dotclear/themes/ductile/tpl/tags.html diff --git a/.htaccess b/.htaccess new file mode 100644 index 0000000..d25d354 --- /dev/null +++ b/.htaccess @@ -0,0 +1,2 @@ + +AddType x-mapp-php5 .php \ No newline at end of file diff --git a/CHANGELOG b/CHANGELOG new file mode 100644 index 0000000..66fe1a2 --- /dev/null +++ b/CHANGELOG @@ -0,0 +1,250 @@ +Dotclear 2.1.6 - 2009-10-01 +=========================================================== +* Install procedure fixes +* Admin: Page managers can now create pages +* Admin: several typos corrected. +* Admin: Widgets now work in IE8. +* Admin: Password protected posts can now be previewed. +* Templates: tpl:Meta* are now tpl:Tags*. +* Templates: now display all posts. +* new behavior: adminPageHTMLHead +* DB schema: new blog_id field in log table +* Media manager: Pubic folder can now be set on a different host. +* WordPress import fixes +* Dailymotion insertion fix +* Upgrade procedure: CRLF removed in files that were bugging the upgrade. +* JQuery updated to 1.3 +* IE7-js update +* security: Full Path Disclosure protection. Thx to Karim Ayad for pointing it out. +* and way too many bugfixes to be listed. + +Dotclear 2.1.5 - 2009-02-05 +=========================================================== +* Security release +* Youtube insertion update + +Dotclear 2.1.4 - 2008-12-21 +=========================================================== +* Security flaw fix +* WordPress import refining +* XML-RPC improvements + +Dotclear 2.1.3 - 2008-11-19 +=========================================================== +* Admin: New upgrade procedure +* Admin: Fixed video insertion bug +* Template: New attributes + * url on EntryIf + * only_category on Blogroll + * no_context on Pagination +* Template: New tag + * BlogID +* Admin: escaped blog_id on authentication page + +Dotclear 2.1.1 - 2008-11-07 +=========================================================== +* Admin: Automatic Update bug fixes +* Admin: Disable Automatic Update if no digests file +* Admin: Javascript fixes in authentication page +* Admin: Fixed errors with categories select boxes +* Template: Added level attribute in tpl:Categories +* Media: Added H.264/MPEG-4 AVC for mp4 files + +Dotclear 2.1 - 2008-11-01 +=========================================================== +* Subcategories +* Admin: Automatic Update +* Admin: Flash 10 support for uploader +* Admin: mailto link in comment details +* Admin: Embedded video size selection +* Admin: Restrict session cookie path to admin +* Media: H.264/MPEG-4 AVC (HD) support with m4v files +* Inherited themes +* WordPress XML-RPC methods support +* True unicode URLs +* Plugin: Widgets as template tags +* Plugin: Filters in entries widgets and Blogroll +* Plugin: Added vimeo.com in external media +* Template: New tags + * LoopPosition + * CommentAuthorDomain + * CommentAuthorMD5 + * EntryFirstImage + * EntryCategoryShortURL + * CategoryIf + * CategoryFirstChildren + * CategoryParents + * EntryCategoriesBreadcrum + * MediaURL + +Dotclear 2.0.2 - 2008-09-05 +=========================================================== +* New installation procedure +* Plugin: WordPress import fixes +* Plugin: Plain text export as downloadable files +* Plugin: Message about URLs in Dotclear 1.2 import +* Public: Display a message if search returns no result +* Admin: Fixed some CSS bugs +* Admin: Batch select/unselect entries +* Admin: In a media item, find entries containing it + +Dotclear 2.0.1 - 2008-08-16 +=========================================================== +* Plugin: Fixed a bug with Dotclear 1.2 URLs import. +* Plugin: Fixed a l10n bug in Pages +* Admin: Enhanced plugins resources loading and cache + +Dotclear 2.0 - 2008-08-01 +=========================================================== +* Public: Atom becomes the default feed format. RSS 2 is always available. +* Admin: design enhancements and new Dotclear logo +* Admin: entries preview in blog context +* L10N: New language manager with zip files support +* Plugin: Import/Export plugin version 2.0 with import from Dotclear 1.2 and WordPress +* Plugin: Pages enhancements (preview, sorting) +* Plugin: support for jamendo and deezer in External Media +* JSMin on JavaScript files instead of JS packing +* SQLite 3 only support (PDO based) +* Many bug fixes and major performances improvements + +Dotclear 2.0 RC2 - 2008-06-21 +=========================================================== +* FairTrackback spam filter +* Language pack infrastructure +* Bug fix on comment search with author "0" +* Javascript fixes +* dcAuth::sessionExists and dcAuth::checkSession new methods +* Right management in dcAuth::sudo +* Media File sorting options in media manager +* CandyUpload, new uploader tool based on SWFUpload +* New search engine robots options +* New image options +* L10N: Japanese and Portugues (Brazil) language packs +* Many bug fixes and enhancements + +Dotclear 2.0 RC1 - 2008-05-01 +=========================================================== +* New: Pages plugin +* New: Theme editor plugin +* Entries: Text and WYSIWYG enhancements +* Entries: Markup validator +* Entries: Insertion of links to other entries from toolbar +* Entries: External media insertion (dailymotion, youtube, google video) +* Tags: Same list for new and existing entries +* Tags: Tags can be removed on all associated entries +* Tags: Tags can be removed on a post selection +* Admin: Ask password for user management tasks, theme upload and plugin upload +* Admin: New contextual help viewer +* Media manager: Recreate thumbnails option +* Media manager: Custom medium thumbnail size (per blog) +* Media manager: Zip files extract support +* Media manager: Zip file download of directory +* Media manager: File exclusion pattern option +* Themes and plugins: Zip as new package format +* Themes and plugins: Upload +* Themes and plugins: Upgrade within administration interface +* Themes and plugins: Deletion +* Public: New default theme: Blowup (fully customizable) +* Public: Changed the way commenter cookie is handled +* Themes: Template files moved to tpl/ directory +* L10N: Polish, Catalan and Spanish translations +* Misc: jQuery upgraded to 1.2.3 +* Misc: Crushed png files +* Fixed many bugs + +Dotclear 2.0 beta 7 - 2007-07-12 +=========================================================== +* New way to display comments and trackbacks on entries in backend +* Dashboard visual improvements +* Default cache dir created by installation process +* Option to limit posts and comments in feeds +* Introduced UDBS for installation and upgrade +* Changed handling of XML-RPC URLs +* New option to force HTTPS redirect if wanted +* Enforced cookies security (directory and ssl support) +* Added Plugin auto-install and auto-upgrade support +* Added trackbacks ttl and moderation preferences +* Added an Internal search engine +* FLV support in backend with Neolao player +* Added nice messages if database is broken or Dotclear not installed +* upgrade jQuery to 1.1.3 +* Fixed many bugs +* Fixed security issues in backend + +Dotclear 2.0 beta 6 - 2007-02-19 +=========================================================== +* New antispam plugin, with a set of filters (rbl, ipblacklist, spamwords, akismet) +* New admin dashboard page +* Fixed unwanted logout bug +* Added settings to disable template caching and allow PHP code +* Blog preferences panel bug fix +* New XML-RPC Client and Server +* Comment posting permissions bug fix + +Dotclear 2.0 beta 5.4 - 2007-01-19 +=========================================================== +* Minor change on spam display in comments.php +* Command line upgrade script and fix in load_plugin_file.php +* Make akismet configurable only by superadmin with DC_AKISMET_SUPER +* SQL optimisations +* New comments view in post + +Dotclear 2.0 beta 5.2 - 2007-01-11 +=========================================================== +* Fixed a bug with imageMeta::getMeta +* Enhanced dynamic file uploader +* Move clearbricks files to their own repository +* Fixed a bug with auto_br in wikiSimpleComment +* Support for language restriction in feeds +* Default theme structure changes +* Fixed a PHP 5.0 compatibility issue +* Installation Wizard + +Dotclear 2.0 beta 4 - 2006-12-26 +=========================================================== +* Performances enhancements. +* Administration UI enhancements. +* More user-friendly Widgets (version 1.5). +* Switch to jQuery . +* Added jQuery in default theme. +* Major changes in HTTP client and Feed Parser based on a + generic socket handler. +* PHP 5.2 compatibility. +* Code documentation (all core and most of clearbricks). +* Many bug fixes. + +Dotclear 2.0 beta 3 - 2006-11-05 +=========================================================== +* Disallow special wrappers for fopen like functions. +* XML/RPC improvements. +* Read IPTC and EXIF metadata in uploaded pictures. +* MySQL 4.1 support only. +* Metadata import from Dotclear 1.2.x. +* Akismet plugin. +* Pings plugin. +* Added a priority setting for plugins. +* Many bug fixes. + +Dotclear 2.0 beta 2 - 2006-08-09 +=========================================================== +* DC_PLUGIN_ROOT can handle more than one path. +* OPML/XBEL import in blogroll plugin. +* Fixed a security issue in html::absoluteURLs(). +* Fixed issues with timezone on scheduled entries. +* Multiple categories selection in tpl:Entries. +* Improved dbLayer. +* Changed category feed URL. +* Feeds for tags (entries and comments). +* Added attachments count on backend and frontend. +* New settings code design. Can now handle wide system settings. +* Memory usage improvements with autoloader. +* Some code cleanup. +* Feed parser improvements. +* Themes can be configured if needed. +* XMP support on JPEG files. +* Media manager improvements. +* Spamplemousse now uses DNSBL (and the guy who left the bug was fired). +* Javascript editor and toolbar improvements. +* RDS support (XML/RPC API discovery). +* Added a theme with user stylesheet. +* Plugins manager \ No newline at end of file diff --git a/admin/auth.php b/admin/auth.php new file mode 100644 index 0000000..e0cae49 --- /dev/null +++ b/admin/auth.php @@ -0,0 +1,288 @@ +auth->allowPassChange() && !empty($_REQUEST['recover']); +$akey = $core->auth->allowPassChange() && !empty($_GET['akey']) ? $_GET['akey'] : null; +$user_id = $user_pwd = $user_key = $user_email = null; +$err = $msg = null; + +# Auto upgrade +if (empty($_GET) && empty($_POST)) { + require dirname(__FILE__).'/../inc/dbschema/upgrade.php'; + try { + if (($changes = dotclearUpgrade($core)) !== false) { + $msg = __('Dotclear has been upgraded.').''; + } + } catch (Exception $e) { + $err = $e->getMessage(); + } +} + +# If we have POST login informations, go throug auth process +if (!empty($_POST['user_id']) && !empty($_POST['user_pwd'])) +{ + $user_id = !empty($_POST['user_id']) ? $_POST['user_id'] : null; + $user_pwd = !empty($_POST['user_pwd']) ? $_POST['user_pwd'] : null; +} +# If we have POST login informations, go throug auth process +elseif (isset($_COOKIE['dc_admin']) && strlen($_COOKIE['dc_admin']) == 104) +{ + # If we have a remember cookie, go through auth process with user_key + $user_id = substr($_COOKIE['dc_admin'],40); + $user_id = @unpack('a32',@pack('H*',$user_id)); + if (is_array($user_id)) + { + $user_id = $user_id[1]; + $user_key = substr($_COOKIE['dc_admin'],0,40); + $user_pwd = null; + } + else + { + $user_id = null; + } +} + +# Recover password +if ($recover && !empty($_POST['user_id']) && !empty($_POST['user_email'])) +{ + $user_id = !empty($_POST['user_id']) ? $_POST['user_id'] : null; + $user_email = !empty($_POST['user_email']) ? $_POST['user_email'] : ''; + try + { + $recover_key = $core->auth->setRecoverKey($user_id,$user_email); + + $subject = mail::B64Header('DotClear '.__('Password reset')); + $message = + __('Someone has requested to reset the password for the following site and username.')."\n\n". + $page_url."\n".__('Username:').' '.$user_id."\n\n". + __('To reset your password visit the following address, otherwise just ignore this email and nothing will happen.')."\n". + $page_url.'?akey='.$recover_key; + + $headers[] = 'From: dotclear@'.$_SERVER['HTTP_HOST']; + $headers[] = 'Content-Type: text/plain; charset=UTF-8;'; + + mail::sendMail($user_email,$subject,$message,$headers); + $msg = sprintf(__('The e-mail was sent successfully to %s.'),$user_email); + } + catch (Exception $e) + { + $err = $e->getMessage(); + } +} +# Send new password +elseif ($akey) +{ + try + { + $recover_res = $core->auth->recoverUserPassword($akey); + + $subject = mb_encode_mimeheader('DotClear '.__('Your new password'),'UTF-8','B'); + $message = + __('Username:').' '.$recover_res['user_id']."\n". + __('Password:').' '.$recover_res['new_pass']."\n\n". + preg_replace('/\?(.*)$/','',$page_url); + + $headers[] = 'From: dotclear@'.$_SERVER['HTTP_HOST']; + $headers[] = 'Content-Type: text/plain; charset=UTF-8;'; + + mail::sendMail($recover_res['user_email'],$subject,$message,$headers); + $msg = __('Your new password is in your mailbox.'); + } + catch (Exception $e) + { + $err = $e->getMessage(); + } +} +# Try to log +elseif ($user_id !== null && ($user_pwd !== null || $user_key !== null)) +{ + # We check the user + if ($core->auth->checkUser($user_id,$user_pwd,$user_key) === true) + { + $core->session->start(); + $_SESSION['sess_user_id'] = $user_id; + $_SESSION['sess_browser_uid'] = http::browserUID(DC_MASTER_KEY); + + if (!empty($_POST['blog'])) { + $_SESSION['sess_blog_id'] = $_POST['blog']; + } + + if (!empty($_POST['user_remember'])) + { + $cookie_admin = + http::browserUID(DC_MASTER_KEY.$user_id.crypt::hmac(DC_MASTER_KEY,$user_pwd)). + bin2hex(pack('a32',$user_id)); + + setcookie('dc_admin',$cookie_admin,strtotime('+15 days'),'','',DC_ADMIN_SSL); + } + + http::redirect('index.php'); + } + else + { + if (isset($_COOKIE['dc_admin'])) { + unset($_COOKIE['dc_admin']); + setcookie('dc_admin',false,-600,'','',DC_ADMIN_SSL); + } + $err = __('Wrong username or password'); + } +} + +if (isset($_GET['user'])) { + $user_id = $_GET['user']; +} + +header('Content-Type: text/html; charset=UTF-8'); +?> + + + + + + + + + + + <?php echo html::escapeHTML(DC_VENDOR_NAME); ?> + + + + + callBehavior('loginPageHTMLHead'); + ?> + + + + + + +
+

+ +'.$err.''; +} +if ($msg) { + echo '

'.$msg.'

'; +} + +if ($akey) +{ + echo '

'.__('Back to login screen').'

'; +} +elseif ($recover) +{ + echo + '
'.__('Request a new password').''. + '

'. + + '

'. + + '

'. + form::hidden(array('recover'),1).'

'. + '
'. + + '

'.__('Back to login screen').'

'; +} +else +{ + if (is_callable(array($core->auth,'authForm'))) + { + echo $core->auth->authForm($user_id); + } + else + { + echo + '
'. + '

'. + + '

'. + + '

'. + + '

'; + + if (!empty($_REQUEST['blog'])) { + echo form::hidden('blog',html::escapeHTML($_REQUEST['blog'])); + } + + echo + '
'. + + '

'.__('You must accept cookies in order to use the private area.').'

'; + + if ($core->auth->allowPassChange()) { + echo '

'.__('I forgot my password').'

'; + } + } +} +?> +
+ + \ No newline at end of file diff --git a/admin/blog.php b/admin/blog.php new file mode 100644 index 0000000..dab788e --- /dev/null +++ b/admin/blog.php @@ -0,0 +1,98 @@ +con->openCursor($core->prefix.'blog'); + $blog_id = $cur->blog_id = $_POST['blog_id']; + $blog_url = $cur->blog_url = $_POST['blog_url']; + $blog_name = $cur->blog_name = $_POST['blog_name']; + $blog_desc = $cur->blog_desc = $_POST['blog_desc']; + + try + { + # --BEHAVIOR-- adminBeforeBlogCreate + $core->callBehavior('adminBeforeBlogCreate',$cur,$blog_id); + + $core->addBlog($cur); + + # Default settings and override some + $core->blogDefaults($cur->blog_id); + $blog_settings = new dcSettings($core,$cur->blog_id); + $blog_settings->setNameSpace('system'); + $blog_settings->put('lang',$core->auth->getInfo('user_lang')); + $blog_settings->put('blog_timezone',$core->auth->getInfo('user_tz')); + + if (substr($blog_url,-1) == '?') { + $blog_settings->put('url_scan','query_string'); + } else { + $blog_settings->put('url_scan','path_info'); + } + + # --BEHAVIOR-- adminAfterBlogCreate + $core->callBehavior('adminAfterBlogCreate',$cur,$blog_id,$blog_settings); + + http::redirect('blog.php?id='.$cur->blog_id.'&add=1'); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} + +if (!empty($_REQUEST['id'])) +{ + $edit_blog_mode = true; + include dirname(__FILE__).'/blog_pref.php'; +} +else +{ + dcPage::open(__('New blog'),dcPage::jsConfirmClose('blog-form')); + + echo + '

'.__('Blogs').' › '.__('New blog').'

'. + + '
'. + + '
'.__('Blog details').''. + $core->formNonce(). + '

'. + '

'.__('At least 2 characters using letters, numbers or symbols.').' '. + __('Please note that changing your blog ID may require changes in your public index.php file.').'

'. + + '

'. + + '

'. + + '

'. + form::textarea('blog_desc',60,5,html::escapeHTML($blog_desc)).'

'. + '
'. + + '

'. + '
'; + + dcPage::close(); +} +?> \ No newline at end of file diff --git a/admin/blog_del.php b/admin/blog_del.php new file mode 100644 index 0000000..756d32b --- /dev/null +++ b/admin/blog_del.php @@ -0,0 +1,71 @@ +getBlog($_POST['blog_id']); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } + + if ($rs->isEmpty()) { + $core->error->add(__('No such blog ID')); + } else { + $blog_id = $rs->blog_id; + } +} + +# Delete the blog +if (!$core->error->flag() && $blog_id && !empty($_POST['del'])) +{ + if (!$core->auth->checkPassword(crypt::hmac(DC_MASTER_KEY,$_POST['pwd']))) { + $core->error->add(__('Password verification failed')); + } else { + try { + $core->delBlog($blog_id); + http::redirect('blogs.php?del=1'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } + } +} + +dcPage::open('Delete a blog'); + +if (!$core->error->flag()) +{ + echo + '

'.__('Delete a blog').'

'. + '

'.__('Warning').'

'. + '

'.sprintf(__('You are about to delete the blog %s. Every entry, comment and category will be deleted.'), + ''.$blog_id.'').'

'. + '

'.__('Please give your password to confirm the blog deletion.').'

'; + + echo + '
'. + '
'.$core->formNonce().'
'. + '

'. + '

'. + form::hidden('blog_id',$blog_id).'

'. + '
'; +} + +dcPage::close(); +?> \ No newline at end of file diff --git a/admin/blog_pref.php b/admin/blog_pref.php new file mode 100644 index 0000000..e28b107 --- /dev/null +++ b/admin/blog_pref.php @@ -0,0 +1,528 @@ +blog->id; + $blog_url = $core->blog->url; + $blog_status = $core->blog->status; + $blog_name = $core->blog->name; + $blog_desc = $core->blog->desc; + $blog_settings = $core->blog->settings; + + $action = 'blog_pref.php'; + $redir = 'blog_pref.php?upd=1'; +} +else +{ + dcPage::checkSuper(); + try + { + if (empty($_REQUEST['id'])) { + throw new Exception(__('No given blog id.')); + } + $rs = $core->getBlog($_REQUEST['id']); + + if (!$rs) { + throw new Exception(__('No such blog.')); + } + + $blog_id = $rs->blog_id; + $blog_url = $rs->blog_url; + $blog_status = $rs->blog_status; + $blog_name = $rs->blog_name; + $blog_desc = $rs->blog_desc; + $blog_settings = new dcSettings($core,$blog_id); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } + + $action = 'blog.php'; + $redir = 'blog.php?id=%s&upd=1'; +} + +# Language codes +$langs = l10n::getISOcodes(1,1); +foreach ($langs as $k => $v) { + $lang_avail = $v == 'en' || is_dir(DC_L10N_ROOT.'/'.$v); + $lang_combo[] = new formSelectOption($k,$v,$lang_avail ? 'avail10n' : ''); +} + +# Status combo +foreach ($core->getAllBlogStatus() as $k => $v) { + $status_combo[$v] = (string) $k; +} + +# URL scan modes +$url_scan_combo = array( + 'PATH_INFO' => 'path_info', + 'QUERY_STRING' => 'query_string' +); + +# Post URL combo +$post_url_combo = array( + __('year/month/day/title') => '{y}/{m}/{d}/{t}', + __('year/month/title') => '{y}/{m}/{t}', + __('year/title') => '{y}/{t}', + __('title') => '{t}' +); +if (!in_array($blog_settings->post_url_format,$post_url_combo)) { + $post_url_combo[html::escapeHTML($blog_settings->post_url_format)] = html::escapeHTML($blog_settings->post_url_format); +} + +# Image title combo +$img_title_combo = array( + __('Title') => 'Title ;; separator(, )', + __('Title, Date') => 'Title ;; Date(%b %Y) ;; separator(, )', + __('Title, Country, Date') => 'Title ;; Country ;; Date(%b %Y) ;; separator(, )', + __('Title, City, Country, Date') => 'Title ;; City ;; Country ;; Date(%b %Y) ;; separator(, )', +); +if (!in_array($blog_settings->media_img_title_pattern,$img_title_combo)) { + $img_title_combo[html::escapeHTML($blog_settings->media_img_title_pattern)] = html::escapeHTML($blog_settings->media_img_title_pattern); +} + +# Robots policy options +$robots_policy_options = array( + 'INDEX,FOLLOW' => __("I would like search engines and archivers to index and archive my blog's content."), + 'INDEX,FOLLOW,NOARCHIVE' => __("I would like search engines and archivers to index but not archive my blog's content."), + 'NOINDEX,NOFOLLOW,NOARCHIVE' => __("I would like to prevent search engines and archivers from indexing or archiving my blog's content."), +); + +# Update a blog +if ($blog_id && !empty($_POST) && $core->auth->check('admin',$blog_id)) +{ + $cur = $core->con->openCursor($core->prefix.'blog'); + if ($core->auth->isSuperAdmin()) { + $cur->blog_id = $_POST['blog_id']; + $cur->blog_url = $_POST['blog_url']; + if (in_array($_POST['blog_status'],$status_combo)) { + $cur->blog_status = (integer) $_POST['blog_status']; + } + } + $cur->blog_name = $_POST['blog_name']; + $cur->blog_desc = $_POST['blog_desc']; + + $media_img_t_size = abs((integer) $_POST['media_img_t_size']); + if ($media_img_t_size < 0) { $media_img_t_size = 100; } + + $media_img_s_size = abs((integer) $_POST['media_img_s_size']); + if ($media_img_s_size < 0) { $media_img_s_size = 240; } + + $media_img_m_size = abs((integer) $_POST['media_img_m_size']); + if ($media_img_m_size < 0) { $media_img_m_size = 448; } + + $nb_post_per_page = abs((integer) $_POST['nb_post_per_page']); + if ($nb_post_per_page <= 1) { $nb_post_per_page = 1; } + + $nb_post_per_feed = abs((integer) $_POST['nb_post_per_feed']); + if ($nb_post_per_feed <= 1) { $nb_post_per_feed = 1; } + + $nb_comment_per_feed = abs((integer) $_POST['nb_comment_per_feed']); + if ($nb_comment_per_feed <= 1) { $nb_comment_per_feed = 1; } + + try + { + # --BEHAVIOR-- adminBeforeBlogUpdate + $core->callBehavior('adminBeforeBlogUpdate',$cur,$blog_id); + + if (!preg_match('/^[a-z]{2}(-[a-z]{2})?$/',$_POST['lang'])) { + throw new Exception(__('Invalid language code')); + } + + $core->updBlog($blog_id,$cur); + + # --BEHAVIOR-- adminAfterBlogUpdate + $core->callBehavior('adminAfterBlogUpdate',$cur,$blog_id); + + if ($blog_id == $core->blog->id && $cur->blog_id != null && $cur->blog_id != $blog_id) { + $blog_id = $cur->blog_id; + $core->setBlog($cur->blog_id); + $_SESSION['sess_blog_id'] = $cur->blog_id; + $blog_settings = $core->blog->settings; + } + + + $blog_settings->setNameSpace('system'); + + $blog_settings->put('editor',$_POST['editor']); + $blog_settings->put('copyright_notice',$_POST['copyright_notice']); + $blog_settings->put('post_url_format',$_POST['post_url_format']); + $blog_settings->put('lang',$_POST['lang']); + $blog_settings->put('blog_timezone',$_POST['blog_timezone']); + $blog_settings->put('date_format',$_POST['date_format']); + $blog_settings->put('time_format',$_POST['time_format']); + $blog_settings->put('comments_ttl',abs((integer) $_POST['comments_ttl'])); + $blog_settings->put('trackbacks_ttl',abs((integer) $_POST['trackbacks_ttl'])); + $blog_settings->put('allow_comments',!empty($_POST['allow_comments'])); + $blog_settings->put('allow_trackbacks',!empty($_POST['allow_trackbacks'])); + $blog_settings->put('comments_pub',empty($_POST['comments_pub'])); + $blog_settings->put('trackbacks_pub',empty($_POST['trackbacks_pub'])); + $blog_settings->put('comments_nofollow',!empty($_POST['comments_nofollow'])); + $blog_settings->put('wiki_comments',!empty($_POST['wiki_comments'])); + $blog_settings->put('enable_xmlrpc',!empty($_POST['enable_xmlrpc'])); + + $blog_settings->put('nb_post_per_page',$nb_post_per_page); + $blog_settings->put('use_smilies',!empty($_POST['use_smilies'])); + $blog_settings->put('media_img_t_size',$media_img_t_size); + $blog_settings->put('media_img_s_size',$media_img_s_size); + $blog_settings->put('media_img_m_size',$media_img_m_size); + $blog_settings->put('media_img_title_pattern',$_POST['media_img_title_pattern']); + $blog_settings->put('nb_post_per_feed',$nb_post_per_feed); + $blog_settings->put('nb_comment_per_feed',$nb_comment_per_feed); + $blog_settings->put('short_feed_items',!empty($_POST['short_feed_items'])); + + if (isset($_POST['robots_policy'])) { + $blog_settings->put('robots_policy',$_POST['robots_policy']); + } + + # --BEHAVIOR-- adminBeforeBlogSettingsUpdate + $core->callBehavior('adminBeforeBlogSettingsUpdate',$blog_settings); + + if ($core->auth->isSuperAdmin() && in_array($_POST['url_scan'],$url_scan_combo)) { + $blog_settings->put('url_scan',$_POST['url_scan']); + } + + http::redirect(sprintf($redir,$blog_id)); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} + +dcPage::open(__('Blog settings'), + dcPage::jsConfirmClose('blog-form'). + + # --BEHAVIOR-- adminBlogPreferencesHeaders + $core->callBehavior('adminBlogPreferencesHeaders'). + + dcPage::jsPageTabs() +); + +if ($blog_id) +{ + echo '

'.(!$standalone ? ''.__('Blogs').' › ' : ''). + html::escapeHTML($blog_name).' › '. + __('Blog settings').'

'; + + if (!empty($_GET['add'])) { + echo '

'.__('Blog has been successfully created.').'

'; + } + + if (!empty($_GET['upd'])) { + echo '

'.__('Blog has been successfully updated.').'

'; + } + + echo + '
'. + '

'.__('Parameters').'

'. + '
'; + + echo + '
'.__('Blog details').''. + $core->formNonce(); + + if ($core->auth->isSuperAdmin()) + { + echo + '

'. + '

'.__('At least 2 characters using letters, numbers or symbols.').' '. + __('Please note that changing your blog ID may require changes in your public index.php file.').'

'; + } + + echo + '

'; + + if ($core->auth->isSuperAdmin()) + { + echo + '

'. + + '

'. + + '

'; + } + + echo + '

'. + form::textarea('blog_desc',60,5,html::escapeHTML($blog_desc)).'

'. + '
'; + + + echo + '
'.__('Blog configuration').''. + '
'. + '
'. + '

'. + + '

'. + + '

'. + '
'. + + '
'. + '

'. + + '

'. + + '

'. + ' - '.__('more information').'

'. + '
'. + '
'. + '
'. //Opera sucks + '
'; + + echo + '
'.__('Comments and trackbacks').''. + '
'. + '
'. + '

'. + + '

'. + + '

'. + '

'.__('Leave blank to disable this feature.').'

'. + + '

'. + '
'. + + '
'. + '

'. + + '

'. + + '

'. + '

'.__('Leave blank to disable this feature.').'

'. + + '

'. + '
'. + '
'. + '
'. //Opera sucks + '
'; + + echo + '
'.__('Blog presentation').''. + '
'. + '
'. + '

'. + + '

'. + + '

'. + '
'. + + '
'. + '

'. + + '

'. + + '

'. + + '

'. + '
'. + '
'. + '
'. //Opera sucks + '
'; + + echo + '
'.__('Media and images').''. + '
'. + '
'. + '

'.__('Generated image sizes (in pixels)').'

'. + '

'. + + '

'. + + '

'. + '
'. + + '
'. + '

'. + '

'.__('This defines image tag title when you insert it in a post from the media manager. It is retrieved from the picture\'s metadata.').'

'. + '

'.form::combo('media_img_title_pattern',$img_title_combo,html::escapeHTML($blog_settings->media_img_title_pattern)).'

'. + '
'. + '
'. + '
'; + + echo + '
'.__('Search engines robots policy').''; + + foreach ($robots_policy_options as $k => $v) + { + echo '

'; + } + + echo '
'; + + + # --BEHAVIOR-- adminBlogPreferencesForm + $core->callBehavior('adminBlogPreferencesForm',$core,$blog_settings); + + echo + '

'. + (!$standalone ? form::hidden('id',$blog_id) : ''). + '

'. + '
'; + + if ($core->auth->isSuperAdmin() && $blog_id != $core->blog->id) + { + echo + '
'. + '

'. + form::hidden(array('blog_id'),$blog_id). + $core->formNonce().'

'. + '
'; + } + + # XML/RPC information + echo '

'.__('XML/RPC interface').'

'; + + echo '

'.__('XML/RPC interface allows you to edit your blog with an external client.').'

'; + + if (!$blog_settings->enable_xmlrpc) + { + echo '

'.__('XML/RPC interface is not active. Change settings to enable it.').'

'; + } + else + { + echo + '

'.__('XML/RPC interface is active. You should set the following parameters on your XML/RPC client:').'

'. + '
    '. + '
  • '.__('Server URL:').' '. + sprintf(DC_XMLRPC_URL,$core->blog->url,$core->blog->id). + '
  • '. + '
  • '.__('Blogging system:').' Movable Type
  • '. + '
  • '.__('User name:').' '.$core->auth->userID().'
  • '. + '
  • '.__('Password:').' '.__('your password').'
  • '. + '
  • '.__('Blog ID:').' 1
  • '. + '
'; + } + + echo '
'; + + # + # Users on the blog (with permissions) + + $blog_users = $core->getBlogPermissions($blog_id,$core->auth->isSuperAdmin()); + $perm_types = $core->auth->getPermissionsTypes(); + + echo + '
'. + '

'.__('Users on this blog').'

'; + + if (empty($blog_users)) + { + echo '

'.__('No users').'

'; + } + else + { + if ($core->auth->isSuperAdmin()) { + $user_url_p = '%1$s'; + } else { + $user_url_p = '%1$s'; + } + + foreach ($blog_users as $k => $v) + { + if (count($v['p']) > 0) + { + echo + '

'.sprintf($user_url_p,html::escapeHTML($k)). + ' ('.html::escapeHTML(dcUtils::getUserCN( + $k, $v['name'], $v['firstname'], $v['displayname'] + )).')'; + + if (!$v['super'] && $core->auth->isSuperAdmin()) { + echo + ' - ' + .__('change permissions').''; + } + + echo '

'; + + echo '
    '; + if ($v['super']) { + echo '
  • '.__('Super administrator').'
  • '; + } else { + foreach ($v['p'] as $p => $V) { + echo '
  • '.__($perm_types[$p]).'
  • '; + } + } + echo '
'; + } + } + } + + echo '
'; +} + +dcPage::helpBlock('core_blog_pref'); +dcPage::close(); +?> \ No newline at end of file diff --git a/admin/blog_theme.php b/admin/blog_theme.php new file mode 100644 index 0000000..62e821f --- /dev/null +++ b/admin/blog_theme.php @@ -0,0 +1,352 @@ +themes = new dcThemes($core); +$core->themes->loadModules($core->blog->themes_path,null); + +# Theme screenshot +if (!empty($_GET['shot']) && $core->themes->moduleExists($_GET['shot'])) +{ + if (empty($_GET['src'])) { + $f = $core->blog->themes_path.'/'.$_GET['shot'].'/screenshot.jpg'; + } else { + $f = $core->blog->themes_path.'/'.$_GET['shot'].'/'.path::clean($_GET['src']); + } + + $f = path::real($f); + + if (!file_exists($f)) { + $f = dirname(__FILE__).'/images/noscreenshot.png'; + } + + http::cache(array_merge(array($f),get_included_files())); + + header('Content-Type: '.files::getMimeType($f)); + header('Content-Length: '.filesize($f)); + readfile($f); + + exit; +} + +$can_install = $core->auth->isSuperAdmin(); +$is_writable = is_dir($core->blog->themes_path) && is_writable($core->blog->themes_path); +$default_tab = 'themes-list'; + +# Selecting theme +if (!empty($_POST['theme']) && !empty($_POST['select']) && empty($_REQUEST['conf'])) +{ + $core->blog->settings->setNameSpace('system'); + $core->blog->settings->put('theme',$_POST['theme']); + $core->blog->triggerBlog(); + http::redirect('blog_theme.php?upd=1'); +} + +if ($can_install && !empty($_POST['theme']) && !empty($_POST['remove']) && empty($_REQUEST['conf'])) +{ + try + { + if ($_POST['theme'] == 'default') { + throw new Exception(__('You can\'t remove default theme.')); + } + + if (!$core->themes->moduleExists($_POST['theme'])) { + throw new Exception(__('Theme does not exist.')); + } + + $theme = $core->themes->getModules($_POST['theme']); + + # --BEHAVIOR-- themeBeforeDelete + $core->callBehavior('themeBeforeDelete',$theme); + + $core->themes->deleteModule($_POST['theme']); + + # --BEHAVIOR-- themeAfterDelete + $core->callBehavior('themeAfterDelete',$theme); + + http::redirect('blog_theme.php?del=1'); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} + +# Theme upload +if ($can_install && $is_writable && ((!empty($_POST['upload_pkg']) && !empty($_FILES['pkg_file'])) || + (!empty($_POST['fetch_pkg']) && !empty($_POST['pkg_url'])))) +{ + try + { + if (empty($_POST['your_pwd']) || !$core->auth->checkPassword(crypt::hmac(DC_MASTER_KEY,$_POST['your_pwd']))) { + throw new Exception(__('Password verification failed')); + } + + if (!empty($_POST['upload_pkg'])) + { + files::uploadStatus($_FILES['pkg_file']); + + $dest = $core->blog->themes_path.'/'.$_FILES['pkg_file']['name']; + if (!move_uploaded_file($_FILES['pkg_file']['tmp_name'],$dest)) { + throw new Exception(__('Unable to move uploaded file.')); + } + } + else + { + $url = urldecode($_POST['pkg_url']); + $dest = $core->blog->themes_path.'/'.basename($url); + + try + { + $client = netHttp::initClient($url,$path); + $client->setUserAgent('Dotclear - http://www.dotclear.org/'); + $client->useGzip(false); + $client->setPersistReferers(false); + $client->setOutput($dest); + $client->get($path); + } + catch( Exception $e) + { + throw new Exception(__('An error occurred while downloading the file.')); + } + + unset($client); + } + + $ret_code = dcModules::installPackage($dest,$core->themes); + http::redirect('blog_theme.php?added='.$ret_code); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + $default_tab = 'add-theme'; + } +} + +$theme_conf_mode = false; +if (!empty($_REQUEST['conf'])) +{ + $theme_conf_file = path::real($core->blog->themes_path.'/'.$core->blog->settings->theme).'/_config.php'; + if (file_exists($theme_conf_file)) { + $theme_conf_mode = true; + } +} + +function display_theme_details($id,$details,$current) +{ + global $core; + + $screenshot = 'images/noscreenshot.png'; + if (file_exists($core->blog->themes_path.'/'.$id.'/screenshot.jpg')) { + $screenshot = 'blog_theme.php?shot='.rawurlencode($id); + } + + $radio_id = 'theme_'.html::escapeHTML($id); + $theme_url = http::concatURL($core->blog->url,$core->blog->settings->themes_url.'/'.$id); + $has_conf = file_exists(path::real($core->blog->themes_path.'/'.$id).'/_config.php'); + $has_css = file_exists(path::real($core->blog->themes_path.'/'.$id).'/style.css'); + $parent = $core->themes->moduleInfo($id,'parent'); + $has_parent = (boolean)$parent; + if ($has_parent) { + $is_parent_present = $core->themes->moduleExists($parent); + } + + $res = + '
'. + '
'. + '
'. + '

'.form::radio(array('theme',$radio_id),html::escapeHTML($id),$current,'','',($has_parent && !$is_parent_present)).' '. + '

'. + '

'.html::escapeHTML($details['desc']).' '. + ''.sprintf(__('by %s'),html::escapeHTML($details['author'])).' '. + ''.sprintf(__('version %s'),html::escapeHTML($details['version'])).' '; + if ($has_parent) { + if ($is_parent_present) { + $res .= ''.sprintf(__('(built on "%s")'),html::escapeHTML($parent)).' '; + } else { + $res .= ''.sprintf(__('(requires "%s")'),html::escapeHTML($parent)).' '; + } + } + if ($has_css) { + $res .= ''.__('Stylesheet').''; + } + $res .= '

'; + $res .= + '
'. + '
'; + if ($current && $has_conf) { + $res .= '

'.__('Theme configuration').'

'; + } + if ($current) { + # --BEHAVIOR-- adminCurrentThemeDetails + $res .= $core->callBehavior('adminCurrentThemeDetails',$core,$id,$details); + } + $res .= + '
'. + '
'; + + return $res; +} + +dcPage::open(__('Blog themes'), + dcPage::jsLoad('js/_blog_theme.js'). + dcPage::jsPageTabs($default_tab). + dcPage::jsColorPicker() +); + +if (!$theme_conf_mode) +{ + echo + '

'.html::escapeHTML($core->blog->name).' › '.__('Blog aspect').'

'; + + if (!empty($_GET['upd'])) { + echo '

'.__('Theme has been successfully changed.').'

'; + } + + if (!empty($_GET['added'])) { + echo '

'. + ($_GET['added'] == 2 ? __('Theme has been successfully upgraded') : __('Theme has been successfully installed.')). + '

'; + } + + if (!empty($_GET['del'])) { + echo '

'.__('Theme has been successfully deleted.').'

'; + } + + if ($can_install) { + echo + '

'.sprintf(__('You can find additional themes for your blog on %s.'), + 'Dotaddict').' '. + __('To install or upgrade a theme you generally just need to upload it '. + 'in "Install or upgrade a theme" section.').'

'; + } + + # Themes list + echo '
'; + + $themes = $core->themes->getModules(); + if (isset($themes[$core->blog->settings->theme])) { + echo '

'.sprintf(__('You are currently using "%s"'),$themes[$core->blog->settings->theme]['name']).'

'; + } + + echo + '
'. + '
'; + + if (isset($themes[$core->blog->settings->theme])) { + echo display_theme_details($core->blog->settings->theme,$themes[$core->blog->settings->theme],true); + } + + foreach ($themes as $k => $v) + { + if ($core->blog->settings->theme == $k) { // Current theme + continue; + } + echo display_theme_details($k,$v,false); + } + + echo '
'; + + echo + '
'. + $core->formNonce(). + '

'; + + if ($can_install) { + echo '

'; + } + + echo + '
'. + '
'. + '
'; + + # Add a new theme + if ($can_install) + { + echo + '
'; + + if ($is_writable) + { + echo '

'.__('You can install themes by uploading or downloading zip files.').'

'; + + # 'Upload theme' form + echo + '
'. + '
'. + ''.__('Upload a zip file').''. + '

'. + '

'. + ''. + $core->formNonce(). + '
'. + '
'; + + # 'Fetch theme' form + echo + '
'. + '
'. + ''.__('Download a zip file').''. + '

'. + '

'. + ''. + $core->formNonce(). + '
'. + '
'; + } + else + { + echo + '

'. + __('To enable this function, please give write access to your themes directory.'). + '

'; + } + echo '
'; + } +} +else +{ + $theme_name = $core->themes->moduleInfo($core->blog->settings->theme,'name'); + echo + '

'.html::escapeHTML($core->blog->name). + ' › '.__('Blog aspect').' › '.__('Theme configuration').'

'. + '

'.__('back').'

'; + + try + { + echo '
'; + + include $theme_conf_file; + + echo + '

'. + $core->formNonce().'

'. + '
'; + } + catch (Exception $e) + { + echo '

'.$e->getMessage().'

'; + } +} + +dcPage::close(); +?> \ No newline at end of file diff --git a/admin/blogs.php b/admin/blogs.php new file mode 100644 index 0000000..de6440f --- /dev/null +++ b/admin/blogs.php @@ -0,0 +1,183 @@ + 'blog_upddt', +__('Blog name') => 'UPPER(blog_name)', +__('Blog ID') => 'B.blog_id' +); + +$order_combo = array( +__('Descending') => 'desc', +__('Ascending') => 'asc' +); + +$q = !empty($_GET['q']) ? $_GET['q'] : ''; +$sortby = !empty($_GET['sortby']) ? $_GET['sortby'] : 'blog_upddt'; +$order = !empty($_GET['order']) ? $_GET['order'] : 'desc'; + +$page = !empty($_GET['page']) ? $_GET['page'] : 1; +$nb_per_page = 30; + +if (!empty($_GET['nb']) && (integer) $_GET['nb'] > 0) { + $nb_per_page = $_GET['nb']; +} + +$show_filters = false; + +# - Search filter +if ($q) { + $params['q'] = $q; + $show_filters = true; +} + +# - Sortby and order filter +if ($sortby !== '' && in_array($sortby,$sortby_combo)) { + if ($order !== '' && in_array($order,$order_combo)) { + $params['order'] = $sortby.' '.$order; + } + + if ($sortby != 'blog_upddt' || $order != 'desc') { + $show_filters = true; + } +} + +$params['limit'] = array((($page-1)*$nb_per_page),$nb_per_page); + +try { + $counter = $core->getBlogs($params,1); + $rs = $core->getBlogs($params); + $nb_blog = $counter->f(0); +} catch (Exception $e) { + $core->error->add($e->getMessage()); +} + +/* DISPLAY +-------------------------------------------------------- */ +$starting_script = ''; +if (!$show_filters) { + $starting_script .= dcPage::jsLoad('js/filter-controls.js'); +} +dcPage::open(__('List of blogs'),$starting_script); + +if (!empty($_GET['del'])) { + echo '

'.__('Blog has been successfully deleted.').'

'; +} + +echo '

'.__('List of blogs').'

'; + +if (!$core->error->flag()) +{ + if ($core->auth->isSuperAdmin()) { + echo '

'.__('Create a new blog').'

'; + } + + if (!$show_filters) { + echo '

'.__('Filters').'

'; + } + + echo + '
'. + '
'.__('Filters').''. + + '
'. + '

'. + '

'. + '
'. + + '
'. + '

'. + '

'. + '

'. + '
'. + + '
'. //Opera sucks + '
'. + '
'; + + # Show blogs + if ($nb_blog == 0) + { + echo '

'.__('No blog').'

'; + } + else + { + $pager = new pager($page,$nb_blog,$nb_per_page,10); + $pager->var_page = 'page'; + + echo '

'.__('Page(s)').' : '.$pager->getLinks().'

'; + + echo + ''. + ''. + ''. + ''. + ''. + ''. + ''. + ''; + + while ($rs->fetch()) { + echo blogLine($rs); + } + + echo '
'.__('Blog name').''.__('Last update').''.__('Entries').''.__('Blog ID').' '.__('Status').'
'; + + echo '

'.__('Page(s)').' : '.$pager->getLinks().'

'; + } +} + +dcPage::close(); + +function blogLine(&$rs) +{ + global $core; + + $blog_id = html::escapeHTML($rs->blog_id); + $edit_link = ''; + + if ($GLOBALS['core']->auth->isSuperAdmin()) { + $edit_link = + ''. + __('edit').''; + } + + $img_status = $rs->blog_status == 1 ? 'check-on' : 'check-off'; + $txt_status = $GLOBALS['core']->getBlogStatus($rs->blog_status); + $img_status = sprintf('%2$s',$img_status,$txt_status); + + return + ''. + ''. + html::escapeHTML($rs->blog_name).''. + ''.dt::dt2str(__('%Y-%m-%d %H:%M'),$rs->blog_upddt).''. + ''.$core->countBlogPosts($rs->blog_id).''. + ''.$blog_id.''. + ''.$edit_link.''. + ''.$img_status.''. + ''; +} +?> \ No newline at end of file diff --git a/admin/categories.php b/admin/categories.php new file mode 100644 index 0000000..b832269 --- /dev/null +++ b/admin/categories.php @@ -0,0 +1,188 @@ +blog->getCategory((integer) $_POST['del_cat']); + if ($c->isEmpty()) { + throw new Exception(__('This category does not exist.')); + } + unset($c); + $core->blog->delCategory($_POST['del_cat']); + http::redirect('categories.php?del=1'); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} + +# Reset order +if (!empty($_POST['reset'])) +{ + try + { + $core->blog->resetCategoriesOrder(); + http::redirect('categories.php?reord=1'); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} + +/* Display +-------------------------------------------------------- */ +dcPage::open(__('Categories'), + dcPage::jsToolMan()."\n". + dcPage::jsLoad('js/_categories.js') +); + +if (!empty($_GET['add'])) { + echo '

'.__('The category has been successfully created.').'

'; +} +if (!empty($_GET['del'])) { + echo '

'.__('The category has been successfully removed.').'

'; +} +if (!empty($_GET['reord'])) { + echo '

'.__('Categories have been successfully reordered.').'

'; +} +if (!empty($_GET['moved'])) { + echo '

'.__('The category has been successfully moved.').'

'; +} + +echo '

'.html::escapeHTML($core->blog->name).' › '.__('Categories').'

'; + +$rs = $core->blog->getCategories(array('post_type'=>'post')); + +echo +'
'. +'
'; +if ($rs->isEmpty()) +{ + echo '

'.__('No category yet.').'

'; +} +else +{ + echo + '

'.__('Categories list').'

'. + '
'; + + $ref_level = $level = $rs->level-1; + while ($rs->fetch()) + { + $attr = 'id="cat'.$rs->cat_id.'"'; + if ($rs->nb_total == 0) { + $attr .= ' class="deletable"'; + } + + if ($rs->level > $level) { + echo str_repeat('
  • ',$rs->level - $level); + } elseif ($rs->level < $level) { + echo str_repeat('
',-($rs->level - $level)); + } + + if ($rs->level <= $level) { + echo '
  • '; + } + + echo + '

    '.html::escapeHTML($rs->cat_title).''. + ' ('. + sprintf(($rs->nb_post > 1 ? __('%d entries') : __('%d entry') ),$rs->nb_post).''. + ', '.__('total:').' '.$rs->nb_total.')

    '. + '

    '.__('URL:').' '.html::escapeHTML($rs->cat_url).'

    '; + + $level = $rs->level; + } + + if ($ref_level - $level < 0) { + echo str_repeat('
  • ',-($ref_level - $level)); + } + echo '
    '; +} +echo '
    '; + +echo '
    '. + +'
    '. +'
    '.__('Add a new category').''. +'

    '. +'

    '. +'

    '. +$core->formNonce(). +'
    '. +'
    '; + +if (!$rs->isEmpty()) +{ + $deletable = array(); + $l = $rs->level; + $full_name = array($rs->cat_title); + while ($rs->fetch()) + { + if ($rs->level < $l) { + $full_name = array(); + } elseif ($rs->level == $l) { + array_pop($full_name); + } + $full_name[] = html::escapeHTML($rs->cat_title); + if ($rs->nb_post == 0) { + $deletable[implode(' / ',$full_name)] = $rs->cat_id; + } + $l = $rs->level; + } + + if (count($deletable) > 0) + { + echo + '
    '. + '
    '.__('Remove a category').''. + '

    '. + '

    '. + $core->formNonce(). + '
    '. + '
    '; + } + + echo + '
    '. + '
    '.__('Reorder categories').''. + '

    '.__('This will relocate all categories on the top level').'

    '. + '

    '. + form::hidden(array('reset'),1). + $core->formNonce(). + '
    '. + '
    '; +} +echo '
    '; +echo '
    '; + +dcPage::helpBlock('core_categories'); +dcPage::close(); +?> \ No newline at end of file diff --git a/admin/category.php b/admin/category.php new file mode 100644 index 0000000..76a26bf --- /dev/null +++ b/admin/category.php @@ -0,0 +1,260 @@ +blog->getCategory($_REQUEST['id']); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } + + if (!$core->error->flag() && !$rs->isEmpty()) + { + $cat_id = (integer) $rs->cat_id; + $cat_title = $rs->cat_title; + $cat_url = $rs->cat_url; + $cat_desc = $rs->cat_desc; + } + unset($rs); + + # Getting hierarchy information + $parents = $core->blog->getCategoryParents($cat_id); + $rs = $core->blog->getCategoryParent($cat_id); + $cat_parent = $rs->isEmpty() ? 0 : (integer) $rs->cat_id; + unset($rs); + + # Allowed parents list + $children = $core->blog->getCategories(array('post_type'=>'post','start'=>$cat_id)); + $allowed_parents = array(__('Top level')=>0); + + $p = array(); + while ($children->fetch()) { + $p[$children->cat_id] = 1; + } + + $rs = $core->blog->getCategories(array('post_type'=>'post')); + while ($rs->fetch()) { + if (!isset($p[$rs->cat_id])) { + $allowed_parents[] = new formSelectOption( + str_repeat('  ',$rs->level-1).'• '.html::escapeHTML($rs->cat_title), + $rs->cat_id + ); + } + } + unset($rs); + + # Allowed siblings list + $siblings = array(); + $rs = $core->blog->getCategoryFirstChildren($cat_parent); + while ($rs->fetch()) { + if ($rs->cat_id != $cat_id) { + $siblings[html::escapeHTML($rs->cat_title)] = $rs->cat_id; + } + } + unset($rs); +} + +# Changing parent +if ($cat_id && isset($_POST['cat_parent'])) +{ + $new_parent = (integer) $_POST['cat_parent']; + if ($cat_parent != $new_parent) + { + try { + $core->blog->setCategoryParent($cat_id,$new_parent); + http::redirect('categories.php?moved=1'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } + } +} + +# Changing sibling +if ($cat_id && isset($_POST['cat_sibling'])) +{ + try { + $core->blog->setCategoryPosition($cat_id,(integer) $_POST['cat_sibling'],$_POST['cat_move']); + http::redirect('categories.php?moved=1'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} + +# Create or update a category +if (isset($_POST['cat_title'])) +{ + $cur = $core->con->openCursor($core->prefix.'category'); + + $cur->cat_title = $cat_title = $_POST['cat_title']; + + if (isset($_POST['cat_desc'])) { + $cur->cat_desc = $cat_desc = $_POST['cat_desc']; + } + + if (isset($_POST['cat_url'])) { + $cur->cat_url = $cat_url = $_POST['cat_url']; + } else { + $cur->cat_url = $cat_url; + } + + try + { + # Update category + if ($cat_id) + { + # --BEHAVIOR-- adminBeforeCategoryUpdate + $core->callBehavior('adminBeforeCategoryUpdate',$cur,$cat_id); + + $core->blog->updCategory($_POST['id'],$cur); + + # --BEHAVIOR-- adminAfterCategoryUpdate + $core->callBehavior('adminAfterCategoryUpdate',$cur,$cat_id); + + http::redirect('category.php?id='.$_POST['id'].'&upd=1'); + } + # Create category + else + { + # --BEHAVIOR-- adminBeforeCategoryCreate + $core->callBehavior('adminBeforeCategoryCreate',$cur); + + $id = $core->blog->addCategory($cur,(integer) $_POST['new_cat_parent']); + + # --BEHAVIOR-- adminAfterCategoryCreate + $core->callBehavior('adminAfterCategoryCreate',$cur,$id); + + http::redirect('categories.php?add=1'); + } + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} + + +$title = $cat_id ? html::escapeHTML($cat_title) : __('New category'); + +dcPage::open($title, + dcPage::jsConfirmClose('category-form'). + dcPage::jsToolBar(). + dcPage::jsLoad('js/_category.js') +); + +if (!empty($_GET['upd'])) { + echo '

    '.__('Category has been successfully updated.').'

    '; +} + +echo +'

    '.html::escapeHTML($core->blog->name).' › '. +__('Categories').' › '; + +if ($cat_id) +{ + while($parents->fetch()) { + echo ''.html::escapeHTML($parents->cat_title).''; + echo " › "; + } +} + +echo $title.'

    '; + +echo +'
    '. +'
    '.__('Category information').''. +'

    '; +if (!$cat_id) +{ + $rs = $core->blog->getCategories(array('post_type'=>'post')); + echo + '

    '; + unset($rs); +} +echo +'
    '. +'

    '. +'

    '. +__('Warning: If you set the URL manually, it may conflict with another category.').'

    '. +'
    '. + +'

    '. +form::textarea('cat_desc',50,8,html::escapeHTML($cat_desc),'',5). +'

    '. + +'

    '. +($cat_id ? form::hidden('id',$cat_id) : ''). +$core->formNonce(). +'

    '. +'
    '. +'
    '; + +if ($cat_id) +{ + echo + '

    '.__('Move this category').'

    '. + '
    '. + '
    '. + + '
    '. + '
    '.__('Category parent').''. + '

    '. + '

    '. + form::hidden(array('id'),$cat_id).$core->formNonce().'

    '. + '
    '. + '
    '. + '
    '; + + if (count($siblings) > 0) { + echo + '
    '. + '
    '. + '
    '.__('Category sibling').''. + '

    '. + form::combo('cat_move',array(__('before')=>'before',__('after')=>'after')).' '. + form::combo('cat_sibling',$siblings).'

    '. + '

    '. + form::hidden(array('id'),$cat_id).$core->formNonce().'

    '. + '
    '. + '
    '. + '
    '; + } + + echo '
    '; +} + +dcPage::helpBlock('core_categories'); +dcPage::close(); +?> \ No newline at end of file diff --git a/admin/comment.php b/admin/comment.php new file mode 100644 index 0000000..bdb7776 --- /dev/null +++ b/admin/comment.php @@ -0,0 +1,232 @@ +blog->getAllCommentStatus() as $k => $v) { + $status_combo[$v] = (string) $k; +} + +# Adding comment +if (!empty($_POST['add']) && !empty($_POST['post_id'])) +{ + try + { + $rs = $core->blog->getPosts(array('post_id' => $_POST['post_id'], 'post_type' => '')); + + if ($rs->isEmpty()) { + throw new Exception(__('Entry does not exist.')); + } + + $cur = $core->con->openCursor($core->prefix.'comment'); + + $cur->comment_author = $_POST['comment_author']; + $cur->comment_email = html::clean($_POST['comment_email']); + $cur->comment_site = html::clean($_POST['comment_site']); + $cur->comment_content = $core->HTMLfilter($_POST['comment_content']); + $cur->post_id = (integer) $_POST['post_id']; + + # --BEHAVIOR-- adminBeforeCommentCreate + $core->callBehavior('adminBeforeCommentCreate',$cur); + + $comment_id = $core->blog->addComment($cur); + + # --BEHAVIOR-- adminAfterCommentCreate + $core->callBehavior('adminAfterCommentCreate',$cur,$comment_id); + + http::redirect($core->getPostAdminURL($rs->post_type,$rs->post_id,false).'&co=1&creaco=1'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} + +if (!empty($_REQUEST['id'])) +{ + $params['comment_id'] = $_REQUEST['id']; + + try { + $rs = $core->blog->getComments($params); + if (!$rs->isEmpty()) { + $comment_id = $rs->comment_id; + $post_id = $rs->post_id; + $post_type = $rs->post_type; + $post_title = $rs->post_title; + $comment_dt = $rs->comment_dt; + $comment_author = $rs->comment_author; + $comment_email = $rs->comment_email; + $comment_site = $rs->comment_site; + $comment_content = $rs->comment_content; + $comment_ip = $rs->comment_ip; + $comment_status = $rs->comment_status; + $comment_trackback = (boolean) $rs->comment_trackback; + $comment_spam_status = $rs->comment_spam_status; + } + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} + +if (!$comment_id && !$core->error->flag()) { + $core->error->add(__('No comment')); +} + +if (!$core->error->flag() && isset($rs)) +{ + $can_edit = $can_delete = $can_publish = $core->auth->check('contentadmin',$core->blog->id); + + if (!$core->auth->check('contentadmin',$core->blog->id) && $core->auth->userID() == $rs->user_id) { + $can_edit = true; + if ($core->auth->check('delete',$core->blog->id)) { + $can_delete = true; + } + if ($core->auth->check('publish',$core->blog->id)) { + $can_publish = true; + } + } + + # update comment + if (!empty($_POST['update']) && $can_edit) + { + $cur = $core->con->openCursor($core->prefix.'comment'); + + $cur->comment_author = $_POST['comment_author']; + $cur->comment_email = html::clean($_POST['comment_email']); + $cur->comment_site = html::clean($_POST['comment_site']); + $cur->comment_content = $core->HTMLfilter($_POST['comment_content']); + + if (isset($_POST['comment_status'])) { + $cur->comment_status = (integer) $_POST['comment_status']; + } + + try + { + # --BEHAVIOR-- adminBeforeCommentUpdate + $core->callBehavior('adminBeforeCommentUpdate',$cur,$comment_id); + + $core->blog->updComment($comment_id,$cur); + + # --BEHAVIOR-- adminAfterCommentUpdate + $core->callBehavior('adminAfterCommentUpdate',$cur,$comment_id); + + http::redirect('comment.php?id='.$comment_id.'&upd=1'); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } + } + + if (!empty($_POST['delete']) && $can_delete) + { + try { + $core->blog->delComment($comment_id); + http::redirect($core->getPostAdminURL($rs->post_type,$rs->post_id).'&co=1#c'.$comment_id,false); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } + } + + if (!$can_edit) { + $core->error->add(__("You can't edit this comment.")); + } +} + +/* DISPLAY +-------------------------------------------------------- */ +dcPage::open(__('Edit comment'), + dcPage::jsConfirmClose('comment-form'). + dcPage::jsToolBar(). + dcPage::jsLoad('js/_comment.js') +); + +if ($comment_id) +{ + if (!empty($_GET['upd'])) { + echo '

    '.__('Comment has been successfully updated.').'

    '; + } + + $comment_mailto = ''; + if ($comment_email) + { + $comment_mailto = 'getPostURL())) + .'">'.__('Send an e-mail').''; + } + + echo '

    '.html::escapeHTML($core->blog->name).' › '.__('Edit comment').'

    '; + + echo '

    '. + sprintf(__('Back to "%s"'),$post_title).'

    '; + + echo + '
    '. + '

    '. + ''.$comment_ip.'

    '. + + '

    '. + dt::dt2str(__('%Y-%m-%d %H:%M'),$comment_dt).'

    '. + + '

    '. + + '

    '. + + '

    '. + + '

    '. + + # --BEHAVIOR-- adminAfterCommentDesc + $core->callBehavior('adminAfterCommentDesc', $rs). + + '

    '. + form::textarea('comment_content',50,10,html::escapeHTML($comment_content)). + '

    '. + + '

    '.form::hidden('id',$comment_id). + $core->formNonce(). + ' '; + + if ($can_delete) { + echo ''; + } + echo + '

    '. + '
    '; +} + +dcPage::helpBlock('core_comments'); +dcPage::close(); +?> \ No newline at end of file diff --git a/admin/comments.php b/admin/comments.php new file mode 100644 index 0000000..cbcc32f --- /dev/null +++ b/admin/comments.php @@ -0,0 +1,233 @@ + '' +); +foreach ($core->blog->getAllCommentStatus() as $k => $v) { + $status_combo[$v] = (string) $k; +} + +$type_combo = array( +'-' => '', +__('comment') => 'co', +__('trackback') => 'tb' +); + +$sortby_combo = array( +__('Date') => 'comment_dt', +__('Entry title') => 'post_title', +__('Author') => 'comment_author', +__('Status') => 'comment_status' +); + +$order_combo = array( +__('Descending') => 'desc', +__('Ascending') => 'asc' +); + + +/* Get comments +-------------------------------------------------------- */ +$author = isset($_GET['author']) ? $_GET['author'] : ''; +$status = isset($_GET['status']) ? $_GET['status'] : ''; +$type = !empty($_GET['type']) ? $_GET['type'] : ''; +$sortby = !empty($_GET['sortby']) ? $_GET['sortby'] : 'comment_dt'; +$order = !empty($_GET['order']) ? $_GET['order'] : 'desc'; +$ip = !empty($_GET['ip']) ? $_GET['ip'] : ''; + +$with_spam = $author || $status || $type || $sortby != 'comment_dt' || $order != 'desc' || $ip; + +$show_filters = false; + +$page = !empty($_GET['page']) ? (integer) $_GET['page'] : 1; +$nb_per_page = 30; + +if (!empty($_GET['nb']) && (integer) $_GET['nb'] > 0) { + if ($nb_per_page != $_GET['nb']) { + $show_filters = true; + } + $nb_per_page = (integer) $_GET['nb']; +} + +$params['limit'] = array((($page-1)*$nb_per_page),$nb_per_page); +$params['no_content'] = true; + +# Author filter +if ($author !== '') { + $params['q_author'] = $author; + $show_filters = true; +} + +# - Type filter +if ($type == 'tb' || $type == 'co') { + $params['comment_trackback'] = ($type == 'tb'); + $show_filters = true; +} + +# - Status filter +if ($status !== '' && in_array($status,$status_combo)) { + $params['comment_status'] = $status; + $show_filters = true; +} elseif (!$with_spam) { + $params['comment_status_not'] = -2; +} + +# - IP filter +if ($ip) { + $params['comment_ip'] = $ip; + $show_filters = true; +} + +# Sortby and order filter +if ($sortby !== '' && in_array($sortby,$sortby_combo)) { + if ($order !== '' && in_array($order,$order_combo)) { + $params['order'] = $sortby.' '.$order; + } + + if ($sortby != 'comment_dt' || $order != 'desc') { + $show_filters = true; + } +} + +# Actions combo box +$combo_action = array(); +if ($core->auth->check('publish,contentadmin',$core->blog->id)) +{ + $combo_action[__('publish')] = 'publish'; + $combo_action[__('unpublish')] = 'unpublish'; + $combo_action[__('mark as pending')] = 'pending'; + $combo_action[__('mark as junk')] = 'junk'; +} +if ($core->auth->check('delete,contentadmin',$core->blog->id)) +{ + $combo_action[__('delete')] = 'delete'; +} + + +/* Get comments +-------------------------------------------------------- */ +try { + $comments = $core->blog->getComments($params); + $counter = $core->blog->getComments($params,true); + $comment_list = new adminCommentList($core,$comments,$counter->f(0)); +} catch (Exception $e) { + $core->error->add($e->getMessage()); +} + +/* DISPLAY +-------------------------------------------------------- */ +$starting_script = dcPage::jsLoad('js/_comments.js'); +if (!$show_filters) { + $starting_script .= dcPage::jsLoad('js/filter-controls.js'); +} +# --BEHAVIOR-- adminCommentsHeaders +$starting_script .= $core->callBehavior('adminCommentsHeaders'); + +dcPage::open(__('Comments'),$starting_script); + +echo '

    '.html::escapeHTML($core->blog->name).' › '.__('Comments').'

    '; + +if (!$core->error->flag()) +{ + # Filters + if (!$show_filters) { + echo '

    '. + __('Filters').'

    '; + } + + echo + '
    '. + '
    '.__('Filters').''. + '
    '. + '
    '. + ' '. + ''. + '
    '. + + '
    '. + '

    '. + '

    '. + '

    '. + '
    '. + + '
    '. + '

    '. + '

    '. + '

    '. + '
    '. + + '
    '. + '
    '. //Opera sucks + '
    '. + '
    '; + + if (!$with_spam) { + $spam_count = $core->blog->getComments(array('comment_status'=>-2),true)->f(0); + if ($spam_count == 1) { + echo '

    '.sprintf(__('You have one spam comments.'),''.$spam_count.'').' '. + ''.__('Show it.').'

    '; + } elseif ($spam_count > 1) { + echo '

    '.sprintf(__('You have %s spam comments.'),''.$spam_count.'').' '. + ''.__('Show them.').'

    '; + } + } + + # Show comments + $comment_list->display($page,$nb_per_page, + '
    '. + + '%s'. + + '
    '. + '

    '. + + '

    '.__('Selected comments action:').' '. + form::combo('action',$combo_action). + $core->formNonce(). + '

    '. + form::hidden(array('type'),$type). + form::hidden(array('sortby'),$sortby). + form::hidden(array('order'),$order). + form::hidden(array('author'),preg_replace('/%/','%%',$author)). + form::hidden(array('status'),$status). + form::hidden(array('ip'),preg_replace('/%/','%%',$ip)). + form::hidden(array('page'),$page). + form::hidden(array('nb'),$nb_per_page). + '
    '. + + '
    ' + ); +} + +dcPage::helpBlock('core_comments'); +dcPage::close(); +?> \ No newline at end of file diff --git a/admin/comments_actions.php b/admin/comments_actions.php new file mode 100644 index 0000000..650ec15 --- /dev/null +++ b/admin/comments_actions.php @@ -0,0 +1,97 @@ + $v) { + $comments[$k] = (integer) $v; + } + + $params['sql'] = 'AND C.comment_id IN('.implode(',',$comments).') '; + $params['no_content'] = true; + + $co = $core->blog->getComments($params); + + if (preg_match('/^(publish|unpublish|pending|junk)$/',$action)) + { + switch ($action) { + case 'unpublish' : $status = 0; break; + case 'pending' : $status = -1; break; + case 'junk' : $status = -2; break; + default : $status = 1; break; + } + + while ($co->fetch()) + { + try { + $core->blog->updCommentStatus($co->comment_id,$status); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } + } + + if (!$core->error->flag()) { + http::redirect($redir); + } + } + elseif ($action == 'delete') + { + while ($co->fetch()) + { + try { + $core->blog->delComment($co->comment_id); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } + } + + if (!$core->error->flag()) { + http::redirect($redir); + } + } +} + +/* DISPLAY +-------------------------------------------------------- */ +dcPage::open(__('Comments')); + +echo '

    '.__('back').'

    '; + +dcPage::close(); +?> \ No newline at end of file diff --git a/admin/dispatcher.php b/admin/dispatcher.php new file mode 100644 index 0000000..22754e5 --- /dev/null +++ b/admin/dispatcher.php @@ -0,0 +1,34 @@ +What the hell are you doing here?

    '; +exit; +?> \ No newline at end of file diff --git a/admin/images/attach.png b/admin/images/attach.png new file mode 100644 index 0000000000000000000000000000000000000000..f87bc77b50dadd1b8c89de269c7670268c93016a GIT binary patch literal 370 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=$3?vg*uel1On2Vh}LpV4%Za?&Y0OV!{_=LFr z|NsBjuV3H4fB*XR>z6NIK7IQ1@#DvrFJC@?{`}s(dw1^Kxqkin`Sa&bpFVy3`0*V( zc5L6iecQHe>({Sex^(HxnKNr^YpbfN%FD}(ii!#g3-j{wa&mIAva-_B(qdy{Lqb9V z0|PxhJ&lcx@2}d~2eg#2B*-tA!Qt7BG$4nwz$3Dlfq`2Hgc&d0t@{HM6f1F!C~+=I zO)SaG&r=A=%uQu5Fw{4&&^IutDrQgus!#x_2+mI{DNig)W$;Z*F3QhMP037DaLX)8 zEzd8?E>`f3*ga881*q25)5S4_BRV;Ofzi$|GEmN-JFvmEvAs83@J!;=#Hs8-9x|$@ zEV$+v@J%*p?^vR+TV}>#1*L;WPw1-hJT&0$Jni|3S(0Jz6xN6Gyw99~1~PcM`njxg HN@xNAAb^u| literal 0 HcmV?d00001 diff --git a/admin/images/check-off.png b/admin/images/check-off.png new file mode 100644 index 0000000000000000000000000000000000000000..fc5f661d721bce85d63fe782bad90d4e2e5b09a0 GIT binary patch literal 450 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=$3?vg*uel1On2Vh}LpV4%Za?&Y0OU>x@CkAK z|NsBLfB*h|{`~jTr@tRR{(kuI_k#z&?%w@%=gzO&w|`x~{$v0CZyPs$TfhFx;>Dk* zO!?H(^0BJwLrKYpf`SkE`5&^f-e+dMPfdN7knk=({#{($yO@}F(b4ZBBj1IEy$ub0 z8yx&LDCn)P?^{2=H=dqvJUm{zy1sFCe(mJ++Sc}!we>4=^Opt&FSWH_sH(n@le3E2 zoCtIqV@Z%-FoVOh8)-leXMsm#F#`j)5C}6~x?A@LC@5Cq8d2h0l$uzQnV+W+l9`*z zU|^_kV4-hdQdP{L1XQ5_QW2b=R#Ki=l*-_nm|T>fo0^iDsNj}alv^#UfR7-`qJDWr*qo7UN3*B olRo3-qr7R$^o?t(8{*mPEf(|d)VTkI1!yyar>mdKI;Vst0E=S9jlApTE8F;_dAhZ*RSLbMx7oYnSirSh=To`R>AbTaxB%jGetH zcEqW`w90qlN}mZUz4}*p^el7jSZvq2z_N9LMdMtf z+F3f4)78qRC=^YU%;OkH}&M25un`X1sK_?hjB< zti&~<#JMOnu_QA;Paz~THAI6tkVJh3R1!8b9vC_gtf zB{NaMEwd=KJijQrSiv`9_e3ofpxRhZ7sn8eXy3z}d`$)dtQYKq%TnA$mM_&U`fnU` zK_Ko^!#^gQ{15-6olcyeBBFGmYTcnJJ1!dt73&%nCiAR0*Qp$|cB|MqUCD`3u?+A3 oHvf3aAJP12^Slpx8MkqlHGkpx^y+evCD0-UPgg&ebxsLQ0Pek|{r~^~ literal 0 HcmV?d00001 diff --git a/admin/images/check-wrn.png b/admin/images/check-wrn.png new file mode 100644 index 0000000000000000000000000000000000000000..fa327f0e609396c5111896ace7e21a276cd22a8e GIT binary patch literal 394 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=$3?vg*uel1On2Vh}LpV4%Za?&Y0OV!{_=LFr z|NsBrzkh#!eER$2)q{N?{EKlck9Q4y&n%&eLPtGepk->9U1R;q`%vi z^ln??yR8ZDHpjf%9Q|%%#M_PGZ#RU#T_5~*UBKIQfp1oOy;jYXc2>_tDnm{r-UW|w2G|f literal 0 HcmV?d00001 diff --git a/admin/images/date-picker.png b/admin/images/date-picker.png new file mode 100644 index 0000000000000000000000000000000000000000..e35e932ca785f3649eafe142bd98c5895cbe4546 GIT binary patch literal 1199 zcmd^7J&T@I5IsvG#9+XW6d@pt*!uw~(kRE}O|nbEvcv@qSPTj_779wR^AG}lRQU;0 z1k3#mV_~7D2-X&ZjUpD?Dfsbv?*0ugJkQ)a%$+mmocrbB!Ho;&FP{f+VSjIP+woa{ z&zw8s|1bBS`T;nD!&^t!eAMZu(;%Ou_WG&6{{Do43@A{64om<<5G0ZiQA86%AQ1^B zGND8zIxz|N3xPt)jZs1iW2{0HSjd73Rp`PL(1->b*-)bz-IxXjG2kEv8q}Z%GXNNC z9OeRHt*ac+Q$~=%3@TW`4o=XuPJ1OOvdAXK4U&;7n@J@r*~v+oWN4M9D6zyAM>O-O zbw7(LRef^X*SiYW;ds4jbdn|9BNp@9?lR;UAI#%c~pzE2C`}q3p+y!Rj5M~ z!eX-q$~BIW4dQ;XzL9InOes~VPEER{Z@bXBwMuGfBs&o$^GT;lRqE1|Y)`aIGF{iI zR=1{Q&thce>C2-U^=L*|@51!#wu|hc?Xok=#fYUv#_Cwn9X(-l?86c$xnOF^VN>?C<#h|Np`L+uyvpcmC{=dv`9*oH_IT`+M8BuIcG+ zIev8SnKNe|+`IhZ+3kh%r=K}>prgI<_RVv*XMu`0ZCr8r;_<0ddVuUj z3ubQmr+)=#9cO_@WHAE+w-5+3Ub#8IXksPAt^OIGtX8@K|w)DAv48RDcsc8z_-9TH6zobswg$M$}c3jDm&RSMakZd z%cjB#s5v*aBvGLvHz%*ys=`(YY^D{E4HDK@QUEI{$+lH;1X-pK;TxdfoL`ixV4`QJ zn`~fgqF`dCXJl?O*Y5S&<|;FXxCU}UafWMBX!jI0a|txODojsXKDJ1!t?Qv55FG|-pw6wI;H!#vSGSUUA&@HaaD@m--%_~-h z7y>iLCAB!YD6^m>Ge1uOWNufvSUNJQAfWfF=kyxN_sAr%L zHyNnW1}JFdT$Gwvl3x^(pPyp~@xEJTQEGX9QFgI{bFi@uNGFOSgslkusV<2nsdm8d zu+TLy(KRv*F*LO@HL^0bj6%{6QG}-5H$NpatrAJQIas?HSi2!qJCY)(b{lJ#}JM4rIQ}= zH7oG6G-}?+YUuD$J@@AC{30I4)}8+r?tE{dFoomd0e@2`fkM$UGpro-{#{I*{e434 zmW~_g*BLd8j$OzyX}3~&PwK3%$>gW_p?3I z+U0~_gfB4JaXmAB#+~WRa~Kb#Mr^Bb)A_lMzklho>I9BE&GVM`tupFb(!M>IvrKxn z?=*(18&ku!ux$8fS->sIaO~%jwu0=SUZzsDy0s0rKLvkEud!oE6npZ!VZA)iHw>Px KelF{r5}E*DJ>Y-< literal 0 HcmV?d00001 diff --git a/admin/images/edit-mini.png b/admin/images/edit-mini.png new file mode 100644 index 0000000000000000000000000000000000000000..890bae6452b8a54bfa35cd841ee774f8d9498050 GIT binary patch literal 614 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=$3?vg*uel1On2Vh}LpV4%Za?&Y0OWoP@CkAC zx0SwkD!;X>_vixUhmW4tRur7MaD8dL_R7`Ech8JJd+O-XmCpS!TtB~kdVFlg;|p_c z9*$kV{phagF%zqU4=%FUw{PFfnKQ2+2y5?bEeevod-v9-PoK`rWVnC#?EnA&SGG7^ z-(=JmFMjms(F03MP8{BO_w0^~+w3172n{!4*tW6%_OXon&)zPX)!k8-d*kN){)xTs z&gSo3*0iw3>e{K@_wL=hzsvQ~-Yqw7T$`S$a&k@Jlc&$uwCO#&vbwXoZSvF!4b^$S zf4q2lW!a4#9?uTNcQ=2bOZQAqUfJ&T?B27BS8kj+bEYF&_|fC*eQ7F( z7L{K+cU1UNYzQy}rMq>1fPxAot`Q}{ z`DrEPiAAXlzKO|2`MIennTZN+nMJAP`9;~q3ceA$Cu*qx)rx`CIv1rTmSpDVDTHL^ zrZN~9>Kj<-8<RY)8l1R2@EK!~&zCP-Ty147bweCwgw6FT>lEvgEd|;<}v!PC{xWt~$(697~aD-{3$ literal 0 HcmV?d00001 diff --git a/admin/images/help.png b/admin/images/help.png new file mode 100644 index 0000000000000000000000000000000000000000..57c87c2dd2036b6d7fafbf8f036accc4c0e7093b GIT binary patch literal 1600 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dy%*9TgAsieWw;%dH0CE=v_=LE= zd3Eo_i+j(W-+T7#-h;CT<=x9*(2e*46=+efb4K5+5&*3-8(oxHXF#LYFw zZZ0`=W8VH7Gk4#ZwBvg3*6ZC{u6Jy@*0k-LKlZ5Iq0FX%U1&}+D$Q-5Bq`n+oOdF86}(xvCbip~kfMH?3pCQl$&H|6fVg?3oArNM~ zbhqvg0|Sd-iEBhjgs+cPa(=E}VoH8es$NBI0fUWwML}Y6c4~=2Qfhi;o~@FCf`XDl zW{Ry+xT&v!Z-H}aMy5wqQEG6NUr2IQcCuxPlD!?5O@$Rub8c!$qC!P(PF}H9g{>0U zOe-K8B&@Hb09I0xZL8!6vP>buH$cHTzbI9~M9)w+*}&LD!Ng3@$lS=%+)PIyII%>* zD=|;O$Xvn5zyL@XSs5BynHT~c0|rWVTtM2UC?(A*$i)q6Cy-~Wlu=SrV5P5LUS6(O zZmgGIl&)`RX=$l%V5DzkqzhD`TU?n}l31aeSF8*%1ZIv)YH@N=WKgSN@ zeYeb_)bjkI>|zDyU}GDQP83B5TM_zGT@p)D?SSE7p=)5GYh)N=Xli9@WMyg@g`^*% z2u-_heoAIqC6aca31%UNCRT=KRz?<3?MRBC+HLef0f7`S;7|wo2~C_(fTbkE!>gdQ zC+u5Cats;6w|`4k4MjsSE~|`i2(z2Byrv z!;^t3WI!r{^V3So6N^$Au%zi3*W5rQaF3^pV~EA+WCK+OiMGW|vaFh#mAZ4dzO+aj zXb2bH&6I1#rjZbIc$LEhM!p?B8#Dsgy+3|z)C|?(TH+{lXxXwk3Q=O+OqPZU0Y+C7 z7&QZqiSqqgbVi}F%vpx3XU9Rk2O$SV1B?+V;6Mt+Q*I`)ivgR5kWhHS|{2b(Pk1mDRMDR(F%i-WNl$NtKD`le=lt61C+0mo<9+$)?E5FI z?;dhKx3}-c4%-_$bdGJVJ+!Xm@(QJ0OOkdjO4vLrc-IboFyt=akR{05#H)4*&oF literal 0 HcmV?d00001 diff --git a/admin/images/media/audio.png b/admin/images/media/audio.png new file mode 100644 index 0000000000000000000000000000000000000000..fec7e22c8e7392acc5b8297bc09be3a7ba5d89b5 GIT binary patch literal 1170 zcmV;D1a13?P)#2%*=d>Goq<`ov1k>1|kXmcw6|Np(c zy~N0@i)_bi$ajK1mZ4o^aUgMiE6df4yU1&g zn^35^LYt#+#n6P(+nt4xLfqcYsbjgLa3-jUyvRbp`uBp za%CcPQQ16WDn0;aonR=?vbO>?-N%1cz4>h<`0zO^wl*4fDdpw;sKFc1=dXXf`Kg0^Jv!PCA}#u7h+9<3>gnm}=;-L@=jZ0;=H=z(T|N#K6G7yu7@+y1KWwx3#skw6wIdv$L_Wv9PePudlDIt*xxAtgEZ5si~=_r>CT( zq@$ywqN1XopP!zdo}HbYoSdASo12=NnwgoIn3$NCmzS27mX(#2larH?k&%#)kdKd# zj*gCvjg5?qjEjqlii(PfiHV4ah=+%VhK7cOgoJ~GgMxyBfq{X5fPjC0e|>#@dwY9% zd3knrc6D`ib8~ZXadB{PaBgmHYinz1X=!I?XJut&V`F1tVq#%oVPIfjUteEdUS3^Y zU0hsTTU%RNT3T6ISy)(DS65e6RaI0}R8vz^Qc_Y-P*6`#PpDqW{{R3032;bRa{vGe z@Bjb`@Bu=sG?)MY03dWlSaefwW^{L9a%BKbVPkS{ZDnL>VIW3na%FdKa%*!SO<22; zDkJ~^0^UhPK~zY`y_QXG<3EV2r+$Q6=FV0lc5 zKV8*XbdwS#dVp*~fC54Ft9tKMRW~F5@rwT!;Kz@WbIwvPRaH@upjw_q{FmP^0U!VP z`y518A#=H(KCJ+|=O3DRMG#=KZ!(C?zV7@8PtS1QO=w|-=3853?p7O{{Rv|?oC1qWHpi*TN*lfP|@Cs`1bVvZ&_WkB&EOVK?)T^~P z0dVK1Hvl4JIFJKir_=?&`7*beaqAKQ4F+msQ>`@4`|2g2bobJ1;qhfEt3{Sg?}`!v zHs7tsks@EyriLc#0m7IyuZ2W>^7! z{@k7a*Yl&-Aj17mE5NV6wIKUu-!xiJ|LpFb-P1UZeP&o^U@W_fgxJI;gs9?fmeQ1x j_*{If800000NkvXXu0mjf&25Wr literal 0 HcmV?d00001 diff --git a/admin/images/media/document.png b/admin/images/media/document.png new file mode 100644 index 0000000000000000000000000000000000000000..5af28a8658b659a8ba95ce3f83e03648eda008e3 GIT binary patch literal 762 zcmV@Bjb*WO9kR&c2SB zrkAhD=H}+i%*9k_rJTCfnVFe!dya>QijJDHhl-5% z_wJ6Is+z39x6Qwll%<-t*JfsBX>^8@rMP;2g_)U|V!W7QeL?Lp*;u!qxG^0j>`c<9F3L&+O>4~7&!_i1aCn9=gRQ^zCsS(|G_$~`07f9{&3g9z-MAP$ zlGe0O-+#BR*6SQ##o&%5%d+D*%cUdB6bL-fKWahh_lv11D|S=TqLYB@np(J*6uMC` s=d6Jt0=l9oH8#vAY5%aR2}S07*qoM6N<$f-hTh-~a#s literal 0 HcmV?d00001 diff --git a/admin/images/media/executable.png b/admin/images/media/executable.png new file mode 100644 index 0000000000000000000000000000000000000000..bb830b8924b2578fc1ded1bf989aa444216d11ba GIT binary patch literal 1240 zcmV;}1Sk86P)}rvLx{uC~ZYWs-V| zuguKMj+?S(fum$-d@fRgy}iA(x6!7w$%~J%-s9_6Zkc_7pHNkBW_hE;$lLe#_k@bA zLt&1qtg*|@-1b9alc zy3dW2y4~L6=H}*RbCXnEdTV^8w!_qUhOLjAyT!%DRAYruRBm;FppK!tY;1xySchX| zet(U!gp;*&dy>)8*rlz#O=y(J%iVH)qot;+ade57sla@FnPYRMl9i@qXn{&mY*AWu zgpIVFqr{Szyi#kNTXUSPwas&js-3OHij}vtyvvlHzPGoxSYCNQUW{sZn30~fy}!`b z*4C%6%C)}JmX@}{#@Ty(mzAc#aDAIxVtjUksCpgQaYAjA3n!p`@}pTZx2} ztx|KGYn7=SMlMuy8m5*5_g zNt1RGM-E(uu`3B_2M2gqOw^JYnSz$*^!I!3Wn;VBu;ZtmPn_*}wwHT1Koj=_{kNcs z#CrwRn{TRkkDz)pBfRu4&{K@bW`vl)-a6;0D(c7eRUU?Ro)t(H{C z0I}6!foz|*WsT79PYJ}%7)mJg-YSsoJ7u#_h>zz9Kg|L$zG)Jzb&dP|3)7c?uY&?v zzUGh#lBCRI;!764=nm3AJ>s1%1#g}cbTC&ae`@Hr6^QEFG-Df+X^b=A8g1vdy{^IYI=GX-)rsZXI}OE38?<(w+E~+go(ER}dbaO)mY}Fu6X)}7(0L8ydcEGe zoE!Sir&UxpuBc3gP}-Sp*QnRsKJz}1!W;ropN$vy!Xg}^i7PO5F&qv*fMN`I zJ-)qH>c9b-Sj8})KAi1zO2?@9d2Hl~oH`qW6_Ob8{{>5M6J{y@3PeT|00000p+)8Vey}i9tg1K8;Tal5FQD}z3&)_?0rt$Up z;_33Ot*vHpe`cA?jIr2omBXjQ;Y@d}#l^+e*49!|QgU{BbfM6DdwYGR(^YVkwaw+D zxzXKTyKb4 zh`wx*zWR(z?f?J)32;bRa{vGe@Bjb`@Bu=sG?)MY03dWlSaefwW^{L9a%BKbVPkS{ zZDnL>VIW3na%FdKa%*!SO<22;DkJ~^0xU^HK~zY`-Ii-}lRy-PlhAgtw%lr(x=LIp zEx|&JaSdssm9b%@cQ5pOM7{*$%EMR0oFbuaiTA9N` zcoK$Mz0D~Ju<6(q!~(lu1lUs{z`%>&eK#axxjb0^_$jJqa{m-L*Pa-t)B_W2C z+s=2HFnOH|3if|YC4$#EI~4+<7JapIP@VV2YhMZh51;Qx)p>7x@ly!8Z_&qV=T&*b zFwXb43xN%H&zjYFBii{Ogx1jVzjemf=8ZWA(`SXCXh-ilRpq(hJP?AaVc%{}R+BS8 zq`9!!E(Aqek2cC@Vq7JP^RLx?iMQgYBFpi{n|yjckR4N2;{Doh_8x-t?iA4B&+ z2s&~L29#S*6VuH1z?Hho=N6Y>9L<3%m|r~YrfF8bG)4K!k`&$qUJl&VAq(N)y0IGo hZ8M|IZ*JtT!(Ym_)8#kqCS3pk002ovPDHLkV1km??hOC{ literal 0 HcmV?d00001 diff --git a/admin/images/media/html.png b/admin/images/media/html.png new file mode 100644 index 0000000000000000000000000000000000000000..eed6e049e42497a1b4dd4c2588ced234eba860db GIT binary patch literal 1811 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 VLnw+QwaWki002ovPDHLkV1lf+$fN)O literal 0 HcmV?d00001 diff --git a/admin/images/media/package.png b/admin/images/media/package.png new file mode 100644 index 0000000000000000000000000000000000000000..82f5cdff6fcd2f3f7f071d283f58d6cb563e5e54 GIT binary patch literal 1153 zcmV-{1b+L8P)$?e62@9*#D$CS^qgzwLs&x|6sib1t{8|vN3rEnSP)wb8u%)**k$dW$n zzk2S+jPTa1=Co+ln?T{OVE_OB-oll~q;189BH6{J`0LmA=grlgO7!8y)3}b^yo;@U zFWt_z-L`wo%*?8FAgFU7?bx>F$eP2hjNabfw0k13gE`m0ox-PlyNyE3q-6H+=iS%N z;LWe^%8vK<_tw_d?BUL$Y7p#j7IU@z2C*2u6ZHx z>D<<@a>Jcs%C(ZrmPE{%GvvO5!i+b?j48~A9lf7$=(=;t#=zdal)HW$=*yk%)2Gh?^N|Nl~Uu`3V-ky?R!1J|sWOB9zv7Ey5p(>gGL?a*} zQACo2Xz>EC$!+%6CQDqbB}jyKcs^sBB_^)o@%YtcoS2_@8NI*1fA2XwI?{28W{?#s z{LZP>rE>WFdc8ijzP^5ay`7y)eIRz&Qb`B14?#-Edluv^gR4urLAj+^9m}QEpb)+_ z3Pxj~$K*j%VDA{3OhN$%`#CPWSzrQ{9+OMN4B=9ktP{%2zK=R)V!&t28(Kz}mL4aG zI_53sEEXqM^-*M9iG@JA-9xKF`wc|kGe~ioHG4)f$DH$TVs@rQQGi8u=&FQ zV3D`(G@P3u0HF0=0HyX}*1dag>8=>xC_e{f>tve`hXgD0|4sOOY z3>G^AfMn~ShLsFNQcEBqyIfh(u|l0YMn5E5nYvWB1I&`$sP3>@G`m>!Y6FElKs zp-3aOcuIhmMBAZjX0gA6A|pO7NiC+Tj@IXMyj?N)`C-1ft@M;2aD53E__S(2D#;h2 z?P4;S{D@r=fy~Uzx+^PJSyk#~)fUl6L91Jj z)*}-vHsTq@@oYWEBOdjNM?Gqk9byl!f7@LGlrwC&-q~ed3F~b71 z0s-i%%z~=ReZlfD8>SRi5N#I32|1httg--waMFs>l?Z}Gzz89ZOyWE*i1{VpP(U*-zW4PCTb#%lJQbY2EThD3uaJzkAwtlLU zDj;Wt*B9TA@E#5S(rSI2OIAn;GHqy#cGI4%*IRFghMtYY(-X47*|8o?|L^{drAG@3 z_g3N+a)p(BKWR6oZ~u5QzJKZ1i?!r(eud-Ln@!Tq$vguIKTQ?lJvT^f+McPc1K3~wzou9gSV*9Tssoj$!j|%FV_T3W)fTt34$cxbov5e;0Kx&q9s(NIQ?isN*I_NWCbN$LMcrU zo+AuMPEj&~luxlxn47gisZf}^L;!$IC?_HC-E#Q2kfAEhkxo$Tf7d~ z1q=nQ1~I!JPdGJte6R|f;gLCb2FEC<(1Dg9kWpn3fMfEI=0=b=9Z(_wfDFem`u~7= zdWq?-$PwsnAu+BEdC{YX90hqI4{bNtVR0ddc9Ch?)24;35Odl#O{Doh6yHe-64VVt zL^u*K79rH36bOkqP=_2t9On-q{t9p$W2_B&vC)5ZJ;gv?Jd!@_t*00000NkvXX Hu0mjfrtJ+~ literal 0 HcmV?d00001 diff --git a/admin/images/media/spreadsheet.png b/admin/images/media/spreadsheet.png new file mode 100644 index 0000000000000000000000000000000000000000..842750909f3deb0bd7c8529330b7d76b2a6e0309 GIT binary patch literal 1624 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 N002ovPDHLkV1gt+Fk%1z literal 0 HcmV?d00001 diff --git a/admin/images/media/video.png b/admin/images/media/video.png new file mode 100644 index 0000000000000000000000000000000000000000..a0ed12ccbcef5ead8b18f29f752d657bd47d5299 GIT binary patch literal 1250 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 aP7CSfrGiTfdl)O z9eOZl_uVPmZue}w(Y5~i%GE2EEnC*Q=4#EdOJ$2L01YXadp>REnZ&AD5oNQ33#X-} zr8#HMHA!6pv?Ve+9B9!d0likB12{^8{DK)m)5<$$?miF^YE-H%9+Sp7=9y)x9mBT30UkBla|fTWdCh{1MkqUZt|T wpRaoBx!v5{c(p8}u;a;dp6OrZOImv+t_YP)w(EZ*psMAUL&X(s%#>0rg2lK~z}7?bp$gs~`{r(4HpJFaeVP z|JwUtj3$BTmM>d%x8D+rQz$ctu#>?b@LPdUu$vObz=YbuPNs}$2-I?9?x~Idhb+E@ zA2GoPKtQzJ@iZbF26z(SIemJNBjN|;5neTfjoam+5!4I&}O{iH=tX2E1*4q-vKQ^ z>jR_Oe*n@7#11fSo*7ui%ZRB1a0if62 zXj&^-8z7DV=?(Dbz8tr=5L*|}Ys^<5#_dCl6ehE^8wc-&l!I%%x-Mg+N^XxoNm_r4 zpHN(U8@&MGGM_$Wq{ZAnnqHcV-J>ogZz-h$8O>@=y|mz)`g;K)&L=Zm=e i!EwQre;-}{E$|Qbvn(h={3;><0000+ z|9@j+V=XN$pa2kbbhVb1m$bGu0U4E5Wiw~a1S)v{{{73BFOMBN0u-En*XaXL9d}8P zUoeB9prBG{Xj*xBN7kYjXMw_;1s;*bKo_h5VaE4t$J~K}3MH-)CBgY=CFO}lsSLh} z$wm3OsVSL>3T~N2spa`a*~JRJ5xXa9sQ}gHc)B=-aL6VnB>d%PvX_wfQQmx@P9gby ztip}+7x<@D?w{O0TUD1YKc zu~f!^@BBPptG_Y##xQJpHG9$`1?CAK>o;|8-pDv1@Bq&u35Jr8h*p==T$h0MGI+ZB KxvX(@`8KD~SQ?zL;z&YU^3Z{NP{+qW%TxNzponLzbv zX=$mV-mie>u$Bb*1v7N4+I?nq*G_Ao0B3`Ki5R#Fq;O^-gz{RDJtf^pRU|_7^m6%cC>6SY); zYGXZJ9780+Q_r6kYEa;C2&|esY0|&{``Mz}O4||(*~OiHHEby{SrF)aPN(_AohGA) z-&{Lo~_E51cK>kf)9`Ln9=T$>r^?~h7825jj^I1{$bmw&*NeU``S Tit#K5phXOxu6{1-oD!M<&0?Fn literal 0 HcmV?d00001 diff --git a/admin/images/menu/edit-b.png b/admin/images/menu/edit-b.png new file mode 100644 index 0000000000000000000000000000000000000000..d0bfbd50ab0904ff40910c936aff7b86397cec80 GIT binary patch literal 2294 zcmV z3PVFf-M4a>ZCLu}PNtJRmTMV}emKLGm26NM{QUXei*HLyOU1>->+9;NqLT0#8J&d? z#GqS+g@y5#m)*!ZqLg^y+P==jmSsZ_%a9_BV;7^06OMgbM?f)qXhM@V4)a<}(7Q35 zh%#$bCeF;lyrv_UkZZQAevW$~+OcC$ISa0-p5V`xl7&a#78aL=Xp3?K)4qbcxwLzG zd!3z>-rnBMmM?i$6S;#Q|2jIHjYia^Or@D%!nJ(9nQpnWsf=p?|6^mdwY8R5JdJHJ zbaZr>fgW2x3sO>2n2dDE#Rgq|95xe;M=Qt9D{ODb6`2HqH5}BXk$qj zk%n2uzp?zLp|z%A_xJbA%*>XRhRPBWt$QJ(bQ`RSii3Aw?C93hp+w1+Ztw5!l$DFv ztXh3T5|4Nef?O5e$&7?&E4{j=i*pFat(=y2G_J0$kb^?9jYyu0ICN4HuAqjEjg6p* z64%eFv!Z(cs-T};LJo*~W1ym)l$?~!lq$Hdg`+zYx~yy9*}TWGE4!Cc zjeIC%NfU!^N8!?%or`L$noH#0#&T34*t4<8reWR2gqwvWjDk_hi7jzhDCOL(mX2h{ zudDx)lheL4?Ab(pUnQKGf~lZ!#m>e2=})kl8i=v&9p^Y+VN)cmY zW1mGA=H%goV;QK1K#_V8jD}>;oH~qhI;@^#q@j$Rl6=$2pw`jIl#hFSYf1O-@BjDr zx3rwrs8h$ghW}}4|9*axf?&eCtf8Wwu%A=Jy}hfbsNC4n|NsBpvv{nP7~#x3+_h^J zlrmfZ000SaNLh0L01FZT01FZU(%pXi0000SbVXQnQ*UN;cVTj606}DLVr3vkX>w(E zZ*psMAVX6#nAS!E000GLNklKIDFS1n@~ns~W?bh3 zMKrqWB=FOgOArY+eXjgn$yo2!TmRXvQ+fprQFeA z0s)|?Ib3snZ5t9eMJx~lNYFMTtJ$_Z4+%1=kf2N~LxL(QBzF*md1W-JV8Sc70tO41 zVMuU%0;=GfIiUc#gSm2$B1bgR0oXH-=!U!37CZgo0K+$DiPtJ}l-tO7_W zo=`&+F$!f+Y~YUIs06?jM)ENMmKoJ%J&va360w`b+_>|NH4U$C=wqt={ z!qXYJ4`i=m5riZx07*g9wCrOvIZhyg?uw=jAVT)F?)0l$Oah8XGO81-Q!`(D;KGNu zvasBrL z3;{vWofmATbc;Xp)>DWl9$DXi-1{dC0a}dRMKS;6`7>Yd-TU7!Na2G1<5o_4DbEl{ zVk8f{!hXWPePM6Js(S_Dt(DVyp6xF+1a_|syWwcAD-!?x`oW)hJkRyK;x2V+`zRI+Og@7Jx<`2uz=;Q9CJg z85I9XkLMH|_UDd>K7k%4PEZUi(P;j6c$r~SO}$Jcge zx`ww20y%qfimX35H zT6=ayUvNo+SEpU?0(}@AkR^bWDu7^PhpP-(B2`$~5%;GnwTr4O8`u5+0ZMWJJygx> QRsaA107*qoM6N<$g6XYYM*si- literal 0 HcmV?d00001 diff --git a/admin/images/menu/edit.png b/admin/images/menu/edit.png new file mode 100644 index 0000000000000000000000000000000000000000..ca59d5f85aef43aa7100b6e32765d6eea440da17 GIT binary patch literal 418 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJbFq_W2nPqp?T7vkfZXZ;pAgso z|Nr+#G96jK03*H^q9ld?~_O)x*&YU@Om%$YqsJwQX2w1+Ql4Q*>{ThJ1|pgF9x zv@|U(4QNF{v}Ja(77jsGtu1bG4^R&S_q>=e~Aw@1tJ7mgjT% zBG?jlrl~t`a~H@K)|@CSr__~oq;U}d~^5Ws)zQMh#tf|!1();}Tm6?<4>*&tT#k#w=+S}Qoqn@&~ zu#=UL@9*!$#l`pc_l=K>nVFfmy0+HV)~Ktd=H}*}qMXdk%*DmMrKP2bi-wMpjOyy^ zwY9Xav8>+S-o3rOnVpx`-qx*~qM$JW-~^z`zTl$8Yv>J$I~010qN zS#tmY3labT3lag+-G2N40019!MObuGZ)S9NVRB^vO<`klZ*65{X<;BnX>w(EZ*psM zAUL&X(s%#>0{}@xK~z}7?U&t>qaYB4#YAF76V%bclrD*}MohWy|9lGq3L?hJ-fiu< znwg}(Zn_UY<580A)(cQe9!rb6$5+) z09z7(P6Lo;>|x^vQxj!ZOsQd6fZp#$;X*bM_^;cB`Xyjmwl4ugb3SYcF9FiZa}z;# z3tZwAFqwe2R_+ZECIg_XOeQM>^O%}6O~C}M&c&?hJ7CuIPvDJ+bnxwyav0KgG| zh=3z?pbU|1<>#o^1n?DrJ5c&%cA~wRUP1wu>qr{`Fy3OCm9ZtUVY`q=vtI=OIRVS& z1HHHWU`V4)0Cqc>3BLz4o6lCh@7#dVM^QdEe$rWqPhuN@aKS1qYzbd501^PQ0EE?a zxyo_t=ZKmI;hzgYpBnLyRL1Q*$7>!Y;@F3U0)TN`qn$K>6{xZkaciU!0QJobDU$Dl zMb0T4%k=!)9B{x!yabr5pW|iuK*Yl+^JtO0OdY-$z?EJL=hX(R0@#~&A5UfE3TN?y zD3lAdo@c+j!1tXZ^XM?*n~2?_{HG{sz1jg-Nv{@9tGdpz?AIu-bpRaMdGBf4a!cPI zRaIWS$OW+SBh@_GR<~P{JnzTqtB&EjCD^^EWp#Vz`Q;dY)mcwh0T-%|UUv>3T^uLp z^H0U&F?9j7^qOrixAw%^mw9nW zoq&gSGfm0aC;aw6;pr5!^tY6{0cEiMu6prH`jL5__l@TNnQV0|fm1B}dg$jb{{eos VbyydX=&1kz002ovPDHLkV1kY(0#g70 literal 0 HcmV?d00001 diff --git a/admin/images/menu/entries.png b/admin/images/menu/entries.png new file mode 100644 index 0000000000000000000000000000000000000000..304e35f1d00e37320c2b3c54f81f64a455614076 GIT binary patch literal 467 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJbFq_W2nPqp?T7vkfZWCapAgso z|NsB{_xBG7{04$wAn+3izJLGz;|GxV1_ob&;LDdUpFe;8@ZtTtckiA&dHndvqsNaQ zJ$m%;&Yj!0Zr{9e<;wBn$BrI5a^&dYBS#M%K5}^L_AQ&YY+So`)w1PF7A%}QW7f18 zv!?d+b$0i5boI1%cDHqOwE}IQEmq|Xbc}XMkY6y6OC(@WKDqn?P#b4~M`SSr1J?%- zW^`I(G6N{6P~sX<5}cn_Ql40p%HW%rT$G=inv$8Q;FejGTAp8&U98|6v3sJH3Q%pE zr;B5Vge2?1z^p?KA`AyAAG+>R%08$f|A=+Z|HMCfUl>?BXKy)FrZ%0qVL!Lge#Scr znzByJoyocm&!=WwWWq;42L;ejrVp6ixCLdUF=)P54@6^o~m#*KN z)wQ*F#*wRco+nQ|6W+2bzqqVs*){i)l@qq!owNJyuA|rO!^+p}zF0YJuVco%h9xHx z8rC`$uS}bHreoc;oQeCMK7Lp_|6E|({;bL#$HEmU-Fp{oJY76xYt_sH-D}UU+;P5V z>$Qsc$JQKs+`RHaWX~}d|Jdg*-)Brc(!TC$a_0`G%Jq}C-K|=DE@##`%aV=fuRX|~ za&F4nb6zcbqgu9a-hVly>xgIGqA6Rhdu7ilnsa>Z(Ywi$4mB-3*DzzxoSj$m=UtBK z+~r=ewsF?Jd-tC0J$lbEyfnUTNB#62xwDSD)@=U&|NlY%9m2q{iY^KA3kGs&1Q_Q0 z+OY>{4QGKzWHB(x)_^eMd$wclKtY)j*NBqf{Irtt#G+IN$CUh}R0X%pqSW&IqU>S? z=V0R**W5tSdehUzF+^f&a)%Q$j|9`7Gn=@I@-`WLOG`VLqbDQBv*(T2v3ZP*U60N& zO-qcLw}xk-olw%fiDCBy@4Z^*^)IQ2heu1utg5N!)2Cx*Sy^6YMLf&2gv8w5wYAMV z_HNQ71xCFxW=~~XJ4Z43@^adii$Z-J{6>^V2SEY9%0nfy_gVcHebON~KazX3hT;OXk;vd$@?2>`}? BiiZFI literal 0 HcmV?d00001 diff --git a/admin/images/menu/media.png b/admin/images/menu/media.png new file mode 100644 index 0000000000000000000000000000000000000000..a85894cdeb925d22f39616a500bbccaaf636155a GIT binary patch literal 564 zcmV-40?Yl0P)%QFOxzXIQ#nG|E(XY0} zva`asy}rDtxYDP$(Wtl4rnb?tw6UeN(4@GjqO;DSv%{UQ$C|9ln5)U3sk@%3x|XTP zo~XK&sK=bAxs#^GkEXAVqr{A%!HAy0hMd2Hn!bRUy@8szhLNLqlDTz|w{woRfsLYa zjkbu2g@KBiagC>aiJfhUvwDV@X@;?AgsNqOuVaC&VSue+f2&`9s#|-gS9qppb&pha zq)>9BNm+A8S93^Lb46BiK~!`_RBl65a8XfFKvQ%-QExp^aXn9MJx*;nOl~_&Ycxn| zH%DSKM`}1hQ7=MbBQ{xYh2TE`000SaNLh0L01d1F01d1G?*_(40000WbVXQnQ*UN; zcVTj608L?Ia&K*AWNBd_Mrm?ocW-iQb0AGvyOAm+0001&NklvX^*(?|i%-Dbej6OCt7RI)A_KuED!5{%_POG|5rfSV={6BCD)j*gB2 zM8HLbmz9M}RaISG9U|Z=CCSGvAuVm9pa2nY7J>jTZE=WzhYSRGc^N?jg8e}tEZoa0 z6e{5E?i&ykv8#0KXc^?2SMJsd@=;N9I0000E>+bQ$4S{PLB+Fg-ro2B-~UN7a+*4eCQNC3|Nh;gMRQM`I^8&9 z&7VJie8Q8Lub8-G+5CkI7aTmi%vUAuPGEje)D#JRouw(s1vapU^6hYlS+ ze*9!y^ZJ?dn+_bx`1EC)rp{+6}@Z-l%t|6(@XH0CIzomG}`pW9^r1ni+(-$8|Ki2VzkmPL)K~i@SLc=1Y}_&>tHf)=)~nf1WbA`St79f#q|H>w69! zIW}d}sj7z7ih29|;|p%x+LPP2qP)Io(bl60nWfjRUCS#Ct)9E{;e+GLR<-;GgO`Qg ztANStU`dc)FhpeNk_;UtA-zD)NS3%plmzFem6RtIr7}3Cq%m#VIv{8pM-^g+odz2|c;9yi_3 zsU>hjaaT3d?2Q|e0$9Vt% literal 0 HcmV?d00001 diff --git a/admin/images/menu/search.png b/admin/images/menu/search.png new file mode 100644 index 0000000000000000000000000000000000000000..1ba1941b932989b94101e9506b77dd71024300f5 GIT binary patch literal 706 zcmV;z0zLhSP)GJvM^7`uX`uFeT=<)gX@8tCC-1O_> z^y=dB=-Tq<+41Gr@Z{L++`j48q~_DP=+&a<)1T(ixaQEV=FzU@_htmDkPYWXPIg$(mrtnPA10YQvLP!jW3SkX68sS-_1~z>HG9 zich_WRlSBxx`k1?gigGKOS^+myMj)-fJ?Z4N4;`CvT{nWaYUZ7CUD z&u}#eU)EiRjZadHhs88X2`pga#3m*!E+Hwv66OIG@X_K0@x{cr%;LcUK~iE8l0d$& zfLsb#AXG*e%opO5O9Kmp=yQvSi3tgbu-m4B1swfY_<&pyUdD`Auz+HuIWs#SA17m+ zZ=N1lL^CGBLQdW`+0DQzTNEs!?46jFnVw^(uI^9>5dj0kBufpG=pt5xh*6e{OF{t$ oLV&@zI5%IA0U7Z7Gchm#05RDfiMd<0`2YX_07*qoM6N<$f-dxZYybcN literal 0 HcmV?d00001 diff --git a/admin/images/menu/update.png b/admin/images/menu/update.png new file mode 100644 index 0000000000000000000000000000000000000000..dad1429303725957b67ef6b4bdecb4484fd6cda5 GIT binary patch literal 1466 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJbFq_W2nPqp?T7vkfZXr^pAc8$ zG={q`uhr~{iR?32b9|=pOospe{~Nb5%-q-T>F4_?$E%Ls+u<-zz@b$ja*e^}iwlga z8NPn~YTU~(^Gv;Q3B&jA?;WNK0ClZ7H*@BhhRxR(01b5L5$Nc6BoDNLy(Gvl7-%36 zFi3eby8(qb3p^r=85p>QK$!8;-MT*v3@m~rt`Q{>zCKpT`MG+DDfvmMdKI|^3^w)^ z1&PVosU-?Ysp*+{wn_>L3Q7u@DYi=CroINg18?t&$_iGKC1=00rm#qErPFJwx4O z17i~f6Ei&{b0bT0GaZHC#1aLs#5@Hfa|I&<10Z2!WoT$+VhD5$7%16s0co3}lr*a# z7dNP#K%T8qMoCG5mA-y?dAVM>v0i>ry1t>MrKP@sk-m|UE>MMTab;dfVufyAu`tKo-FP)N_diaEtPap@9bsM*WJ!0)0b01AVy3 zK#ev)K`ZB?)WnkfqLBRj96N~j-7Zjo1c=IRteK?p=)TMYh(~&XbRG9VhGiaqzJ0rMjsRq zNC5*5b&#LX#0dphN-{jW3QCJ|z|oSDte={bnwy$eQVa|;L)0)!Nw!MMFUn0UvCGU& zOi$G>$V<1;M+o9|AH>zbWC2W;`tWoKb2>aKX~IB+J57v-7)nb^mj5+Z0hSnIpuz#1 zXhGQ_Br`Xa!N5@8z(U`^q^g)f38+E_q#`&!t)x7$D3t+Anx1jZ4O9*`c)B=-NQB3p zzbMwMz`>TFEg5;XrL1hy=I{0A80YQW_Ww|~zaYo<{Vdj(CNh4SXr~}uVV0?IL7DC3 zJMl$F@2RwM#W$>)uzrH*1Fj1RG3<*HWu+rddd`}B)B8(s+SHB{F?)55lX{ja*iGhN v79b}!#q8HVt$DxiO`pA7VA)Rn?~~1UgmMP7^lY^Px`n~h)z4*}Q$iB}fbgPz literal 0 HcmV?d00001 diff --git a/admin/images/menu/user-pref-b.png b/admin/images/menu/user-pref-b.png new file mode 100644 index 0000000000000000000000000000000000000000..ed66544afdf90dec16fd1ed5c0e9f1768c6569d4 GIT binary patch literal 1388 zcmV-y1(W)TP)<{8goK3A(#PfH-F=2Ng^fIFZ#!*B31Mg>dw){By}hoNbbEVye1kZwtgN_-L{eE7 zjEs!d*4DCuI{d3bc7{_BlgHd0MDIE`vz#0e~Ub-ObxtaQgXxEt)19e+8JleBqpn}q$c;-pI-f(g;Lb14{#jXh`}uVB zPPY6$#R*IXm4kOfk-B4<=#-_ zve=R%I5Bl}_~gmqjbCq{aCu&Vo0AYEY$zrw8k&@qC>RPvJ)SH0>-O=}PoJJXRa^bm z36R#t?l^;yF$%fT?U&*vIf949XV*72PJK};9?97_4K@Y1TkzAw>c~i~R$HA2d&hGG zPcDB`Ely2O6(?RE!nsd=Gixkef^d0#{Nnv;wR-<*>DauBD=M3aO{8hiB{+O+{8oA9 z?t=#xF07T7m#iRck2XNt2uxviZE^AW^K!ZT?$3jt{pgBE8MK{d1*Svr+w%CoGmB-% z{-w3qg2|dTJJ2T3dg*-W?&wUN(O0Fy0lNjd>fcEa79P)zHd$D36&NvyK)?Cn#fx*_ zInI?HFMplA_fR`KwxHGg<=5*Aj`i2)=kuO?3(nRl&}z@#_g^|5{d@`cigyco?7L0E zFhqHRKI6^h^IA}S~~xNB|`$0*tA^01`1qDHyPq5STy+7$73M1i)1s zr6@va6yO*{gfZbJNeE36V1Wr3L?}o&LU9tK1UdvtLEI`}TLSs90%KYQVZc~J5abJ3 z>}Fux33@k?0ci+&G=I2q+)ZgT@ikiW{8?wDD=@ zL82ePH%eQ9cE=rt28E{F&Oy}$$j-?h^putYtqU>(l>$KY4cMDymaiZ4JZ#+Cdw}}g u&29o)Csl3V243G}hqT?(`mW%U5_|ys0wdDqX62v&0000_5&dvOGy6flhhR??u-X2-}{y^#HeT5(Q=D*on@_J9nmV=k~9NhJ0N5-@D zO^-HbZrFDE;il{b+b%v`7xQ{m^o!N8&(?z|m3Va1(JyTcP)_w+d*>a@Ah zV6nZ^;YPjLj#kf|ZN@uV4YIqpwDmh4uhrPrXtKV+ct^EOLi^73wR%TOY~$Ou?$fa%F-@N)y~S) zu1jz*%Uk2JcAb4r5zf`Qz@3K;gM$4dj<$ywkL zSDxO@5rOt{&d4>UjlWI%9!T1k0gQ7VIPVscS_ZfZ(qqJmpy zQEGX9QFgI{Z^Z72S}H)bFFaiwLnOkJXV_MoMF-_C7yqBbk-+e2?N<@goJSH5nEY0` zJv;YrW9CG)KLU+)%+cK6B`VYS46E5T9ANPlZ!ZW8%kwNVcHiL8I5)jOgj;;_jxG-= zkA`x$?d|?b%X=E8Z3@xdYM{uN$A$o;8F)B z%eU{c^e%f+eLdH&3qoHJf+91&-mn4K9c XyHb`O*jBw9=w}8`S3j3^P65^o3*`1O! zVkv@R!B!L$#hZs7Jg6wNJqk+e!INk!h)@qUHw)s=L7~njY0?(aQ-__u$NRqb=6jEw z9f=P#+mG8RifWDyMn=hggiO1wo~%n>hhLGc-t3JEHk<9kr{N89b&U)OecRjHKdtd& zYwJs~__!?<>kuCi>1Y9i;GVe79QNWeRF>9+SMyF)0c8Xzs_GI@H#vi zPf(%F_epYT)CbR+6xGyf&AK-qr+*XU3EVe^6Iv4IL<3PhvNn!Dzha=AW~5CJPPp!_ z^;_v3v;4va60xGGKv1%XVpzy@LB?G$DVm}Vw^$xyu_0d4vQE(=a^|x-YYsfZNGBB*x_iZjY1maz3x;6iA2|oEBBUc>%{TWZ`(0 z<=revrZniFo$P)?PV%FX{z^=83(yl7>pXL#s=)ow5@MGyCDpAr?X!db2qsHaz4S>VQ!0xrL6kvRq+*k3#_rWj zmiVM*WJMfQvSJEBT}}C6&G^s!%2|`PAZ-b&eYul*wUh^PsOf$n^kve64DzkvVF&qr zaM4JQV7n)6h{+IDHy!VopP^t=>p*Dce&cNW^VRv+Vpv~pYiW2wU*8P1&1FtfkG~(f Tb;EshnV_j?Up(@t_rm2rZ)|Yj literal 0 HcmV?d00001 diff --git a/admin/images/menu_on.png b/admin/images/menu_on.png new file mode 100644 index 0000000000000000000000000000000000000000..9b3ccdf0765143a41d08394d4923753189d3b424 GIT binary patch literal 1334 zcmcIkOK1~87@j`R7;QlhQpCfs_9B? z5kJvkKV%00bVP?DNj&ev-QM1YN3C`44W8Qc{wQa&**<+4`HZ*SiD7PFeSN)BsjRK7 zuBgAKi59jCSZrz-{er@K`#p$VY=E&@~QH*aflJOKczWgzVH+$5f(>efq z4_LkB{nFHL96W3cq>Yr4GfZAXpf9Ur5F8XWWGY%ghvAg#_QIf5&p`_p)(~%qiVQhX zLV%)4s)wZ9WgQRzwC}eN>DVwUD3X)6gq$Tw1%cj@$_oW#zzoWZa*%)!5>U(riBp~! z6;s1#TpTKEC{>PgLb)LLvqW#m9w@PxEFpu3C8;RuY$-@oHCep2!XyE!5Tg(zYE`FW z2^dy11l>;BAy6(ibbFnQkMaAw$6$&#;7MMFj1Mvtg$IVEY1U2SVycY@+3_6EvN<*x z8La2TyC5-c7%EGWrfE7&ms8R5B<=V6Ns1vE#(@zIeNr~~l0(*y)I>IPB1jiBQLXxA z>GBz6!Uz(Cm8j9`hvU^oB3ZAShixQFyh_qeifkxjVgLu(>P;vbrzpkHUoI_RF}Hx4 zS(|(m;SChB{BYop@p80_b^BS5Z*&vC2HHlCDOoW$xk2x-=(L}sXx8OrJ#?ME2~?*C zNXv*###CLm&a^EK|6^EIX!xa0XvONaWCaoxk%VMJ$DYw!JKg{az_?T-*-g5Cc2YJe(t*8jej4WXrzy`oe{>Sr@t>f zGnM?!*u@Ok^wx z@(X5gcy=QV$l)yTh%9Dc;1&X5#!GkW{s0BVN?apKoQqNuOEUBG6hbm{QyB~l^$jfa z4NR(v8I*u36hJD1^V3So6N^$Ad=rz4@^e#DG7}ZtGK*5n^NX^J6?`LhPt;NYs@3y! zaSY*zPEHI;NJ#i`Jm~}jlTK5_%6M*x8$uB*^+pB;TuiLi1*=N-FsRrwGpKU0Z%T9v Rcm&kR;OXk;vd$@?2>{JhTfhJS literal 0 HcmV?d00001 diff --git a/admin/images/noscreenshot.png b/admin/images/noscreenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..e9ba66d9ed7e8d7e1ee8fcb7180ecd73ab2ef5f1 GIT binary patch literal 1395 zcmeAS@N?(olHy`uVBq!ia0vp^AAtB02OE$qG4x%}z`$zd>EaktaqI2f=YEef7}_rG z{GYwJZJOeQ3(onBP8o4~Cn~KCTYa}>#tpf-%8^or|9j-_?EAEuLF)DNU z5Ed{{NC07n10dYcz{uDP#LOTC*c3H1IFhYMzyNIB1N&>&uZMs9^eO1hojW3b>-JmN z*yvcz_1n04b8t>hj!1TP_R&+Pyf*IH6QiT6+xvg+{HOnKy)E0ge}DX(dGo}!Z{L3O z_3PEbS_xvBhH7Uv^@Xht{Zh5}(Z7Fne~vRUer`V1^L@ViKZ`kY=7_w1|K4v)gXZny z$B*~3*;p3co;$(b-hOTgWAHSa&3Z}?PHx<{&u-sVw*yliynLCtkkP;I@#Ez4$C=XN zc1nc_7WD1iYrFjlQ<~h*l912?mUaLCz4g*b*!TL;qeYh*ic5CK?&o0qEGyX%SbD%x zPhbD95zCo1eSLjdf(3TQl1Eh&(x%+LZpAW3+1W_Y!1%`9yK8+9SQ@EGGa4`TiC7VQ zV5Uc7!_1&Gk*k^yu3inDKb7Uo7NIjwRD;$XV`pbS`txUHVR^Z^+)`7i-eZrK3Wu`A z?%BJyw|?ICW0h%heGGLzOYpGO88W3wUB7<4*tR@vT3}xFX`UZ%-ki~QJD?NPmhw#N zUGA2K%oUs3QuA_iEoU+<`!|b)7NIQ_^=vvW#4PqyvzisYWD2eYTvnMsCiW^6XBY{R#jK0 zm#UGP=B}6^rV)N-)3O_~yDvbwxvF!hy0t0RvvX8&c<(mK|h_KJ0bC#3CWO5$JjL zJ)1W_KEgR;8QYw{4T1)|ycVlV6%wQ*3hp^XACEk6#pXfFtmvnU7cc(!sJQvy0V4~h zWqF&t+?>w-I&<^6#==>J_hVIf*aHCrQxjk+ zXtrDyS$OGJIMXsWp(i@h<>?#CR{L|!m=#l*-ueB#;BF!A8C|}`xBtX%zdWy#)yGv% zPVQOUnY(MZG_3Ske|@&~gFSQI4umMoZ$EY8vp8dLW6k5a<_X+;xFr~s6Vj$`Kasak zu)sO>#FIUY&s`;eksbLv3mEUticHIt=K4Lq{c+pvT=jqhAur#)U7N8r>i(@8)fO^V zjZDk3I18tB2DaDq!3SSbT3M1Z9X yq@;lrMUdhMrU+gXp(?^rUJ<1TRH$iv7H4kKE}8XSmLFJ{GI+ZBxvXjyn4Q literal 0 HcmV?d00001 diff --git a/admin/images/picker.png b/admin/images/picker.png new file mode 100644 index 0000000000000000000000000000000000000000..d70e6b250a3f76395c9fb7db64153685d0f0d038 GIT binary patch literal 1520 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=$3?vg*uel1On2Vh}LpV4%Za?&Y0OYO?@Ck9{ zZ;;Db_szHWmSg7Dpmmo2|Np;z|5@LWMW4TY-@4~^^``c7Pya31cs93Vi~ID@)n_+H zF3Vc5_NYpqLhPcnzQu>mfBf&zwdl#)mlOBSK7Q`mic?!f8Z;DJjB57(kD2@Gz>Q%z4L@*gYvug@0BKMHEr))v*m_Zo%-J6cf&VX-+uV6epA=d zHP>TTWxn|MI-q?2y>I{Ty??fJ>ov)41(^n2J=?+}ptIRZg8YJk?)?9sVe|ea`+*{y z1s;*b3=G^tAk28_ZrvZCpje4(M2T}zYGO%dex5=|W^O8jfuX*Eg}#AFRWXASP=yRg zMR0yvNqJ&XDuZK6ep0G}TV_#ed45rLv4V53@r-M3z|dn61gVSg^|4CM&(%u=DbuUS zEnu**uP8`N&Q2{+NJ>r5%(GQeP*6}($V{%1*XS zQL?w=vZ=5FYR*k9NmQuF&B-gas<2f8n`s4PgM{^!6u?SKvTcwn? zGt^BsFg8&zG1D_LH?lN0(@_XcEK%@E%u_HjS1>X#01`%4hK5!qhCs)Ffs!2;khUpG zNwW%aaf8|k1^l#~=$>Fbx5m+O@q>*W`v>l<2HTIw4Z=^Gj80#)c1SLT%@R_Nvx zD?xrs^nr6smXN+65i0P4BK0=Pwa#n8Y52BUsOVu8M)o`F8x zWS~YHpr92v#`23o^7C`-utbRsNGFOSgslkusV<2nsdk|7&;=qRvk*gLD-%mAQ}ZY! z{SZZH+I{m=GSe!Nv|H#JnuD~P8dw=wK(!+&f@-(X2L%LDz<@&?(71p)z8 zg3_WKaI~Z(>!;?V=BDPA6a&M|5H-wFlC9G6i*gf7>@sr`(^K^e^3rYe5rTN#2XQqp zSpbuzK0IB*oDPplnlKRIP7~uHhSJg!-FYD;z(OS1)5S4_LzeYms}Lij2*Uw&vE!M` zt4pr){QsX?#{9re|rYMlPg zmfaM%Y1Vbe8#Z=3RR#REMkeyNl>F9XJhXH#`w!+06AqEZp7VWx)-iax`njxgN@xNA DIONiO literal 0 HcmV?d00001 diff --git a/admin/images/plus.png b/admin/images/plus.png new file mode 100644 index 0000000000000000000000000000000000000000..77229ad40b982b5e529f3265e65d9e18d7bdf58e GIT binary patch literal 297 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=%3?!FCJ6-`&%*9TgAsieWw;%dH0CKegd_r9R z|NsB*-@n?qXRGI&DVuSsaLS3C3CGfVk0f;-ifcO<*|a~TZm(a}Zm;s4$1LSsfVvn< zg8YIR9G=}s19CVEJR*x37`TN%nDNrxx<5ccu@cva66d1S#FEVXJcW?V+*AewLwy4a zeFKxKVg@Ck3I&jg;QX|b^2DN42H(WwqWs*{l*~j0x6Go{^8BLgVg=ub-4nG`fNHHh zT^vI=qLY(?n3!1AoE;Se(u7!;6^>R5`fwUFX}sgzZ_cF2$j0WTpnCDZ#f}NWQ=&MQ g9rz{VsKU)Kv4S(}cgeh2Kw}s@UHx3vIVCg!0Ni9>g#Z8m literal 0 HcmV?d00001 diff --git a/admin/images/scheduled.png b/admin/images/scheduled.png new file mode 100644 index 0000000000000000000000000000000000000000..f6e2e9caba31ca0bfaef7b6df7bb5b2efbee4b3b GIT binary patch literal 316 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=%3?!FCJ6-`&%*9TgAsieWw;%dH0CIH$d_r9R z1HtVn|8GzJf2;rhjqd-~+x}mv|9`dV|K+Ox7t8)%DEfas@Bi7XnKNhpXJC-Lvqcc7 zk+CGmFPOpM*^M+HhqJ&VvY3H^TL^?1FWs&C0~8c1ag8W(E=o--$;{7F2+7P%WiT+* zH?Yt*FsUkLPy(t@0I3MhPb(=;EJ|hYO-wGz&rMCqOjK~oEJ`iUFUl@f@Qv6#QA-7= z*4xv?F@z&JIcbk}^~ZG#la-nol$!-6CrCsm%}|)UV8ItRM}e&kf*zWhz6?przQ4Es zQ~zJ?L=eMA7FJe?gI-J#2d~`R?4T7Oz!AatM^jK#r9;vPXe@)LtDnm{r-UW|G=*`O literal 0 HcmV?d00001 diff --git a/admin/images/selected.png b/admin/images/selected.png new file mode 100644 index 0000000000000000000000000000000000000000..b25834b99d168c5c5dc502d05dba0c3f98088b87 GIT binary patch literal 369 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=$3?vg*uel1On2Vh}LpV4%Za?&Y0OW=Q_=LFr z2ZA#U&-RHw+%39hf&cP3J}YP0&6*NEbz*pDdti3`l=RAG-@+Z9x!Zy>tDQ17`)77} zrM6oqZ8VKtrx&qWBY35v?=mIt=~5nxMVuG%+RkIMnEk_TeKF8{#*!evUJSPRm`9SRG|P; z5uBe^Ql40p%HW%rT$G=inv$8Q;FejGTAp8&U98|6v3sJH3Q%pNr;B3FMR?<^Sg9?&jv};o;xm;ojZh z=-uA`;@#`h;p)xeyY)!Ose*zU;R+r{77*Vo|H)zr|?`_a+h)6>$=&)Lk(*vrb? z$;sTw$=S%r;mOI>!^ZNv%HPJt>Y&rK!^7jh#OK1o;lje=!ouUi!p6S7+rPikuEoy4 zz`wn{+@Qt4ySdrAy1KWw*0;CEwYAo@wav7&)wHzJwX@EgyS}rt#5Bq`Ru2%A};YoTS8lubqskuA`!- zqN1dqpT3`;zn`DHprE9noWGo#zMGr2nVGqmm%x{oxtEu-Vy$_Xmz$K7uab|kkdU=d zs&9~wv`ngNj*Xd(jgpIssD_KHiHW9&h^arOS%-(GhlI2*r%+6rWru>8gnyfTeV%%H zn0$GkFqlbnbcbnac@l*olM~U900001bW%=J06^y0W&i*H32;bRa{vGf5&!@T5&_cP ze*6Fc02XvbSad^jWnpw_Z*Cw|X>DZyFflJMI4>|XdUF6G0000WbVXQnQ*UN;cVTj6 z08L?Ia&K*AWNBd_Mrm?ocW-iQb0AGvyOAm+0001)Nkl(liZE794reeEv6PqM=N01M%XDLqQPkpOWbw?6w<(rp z;IdbjV^kCMs0u7%XJEC^wq_C&5LWR|2O6hm?j=}|rXP?M1mq}q`x>Q`7rK<006F5Z zks6Z9j`@|`Kn{abNla>KMTP_e80aJf8}NV_07P>gPHEOsetUserDefaultBlog($core->auth->userID(),$core->blog->id); + http::redirect('index.php'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} + +dcPage::check('usage,contentadmin'); + +# Logout +if (!empty($_GET['logout'])) { + $core->session->destroy(); + if (isset($_COOKIE['dc_admin'])) { + unset($_COOKIE['dc_admin']); + setcookie('dc_admin',false,-600,'','',DC_ADMIN_SSL); + } + http::redirect('auth.php'); + exit; +} + +# Plugin install +$plugins_install = $core->plugins->installModules(); + +# Dashboard icons +$__dashboard_icons = new ArrayObject(); + +$post_count = $core->blog->getPosts(array(),true)->f(0); +$str_entries = ($post_count > 1) ? __('%d entries') : __('%d entry'); + +$comment_count = $core->blog->getComments(array(),true)->f(0); +$str_comments = ($comment_count > 1) ? __('%d comments') : __('%d comment'); + +$__dashboard_icons['new_post'] = new ArrayObject(array(__('New entry'),'post.php','images/menu/edit-b.png')); +$__dashboard_icons['posts'] = new ArrayObject(array(sprintf($str_entries,$post_count),'posts.php','images/menu/entries-b.png')); +$__dashboard_icons['comments'] = new ArrayObject(array(sprintf($str_comments,$comment_count),'comments.php','images/menu/comments-b.png')); +$__dashboard_icons['prefs'] = new ArrayObject(array(__('User preferences'),'preferences.php','images/menu/user-pref-b.png')); + +if ($core->auth->check('admin',$core->blog->id)) +{ + $__dashboard_icons['blog_pref'] = new ArrayObject(array(__('Blog settings'),'blog_pref.php','images/menu/blog-pref-b.png')); + $__dashboard_icons['blog_theme'] = new ArrayObject(array(__('Blog aspect'),'blog_theme.php','images/menu/blog-theme-b.png')); +} + +$core->callBehavior('adminDashboardIcons', $core, $__dashboard_icons); + + +# Latest news for dashboard +$__dashboard_items = new ArrayObject(array(new ArrayObject,new ArrayObject)); + +# Documentation links +if (!empty($__resources['doc'])) +{ + $doc_links = '

    '.__('Documentation').'

      '; + + foreach ($__resources['doc'] as $k => $v) { + $doc_links .= '
    • '.$k.'
    • '; + } + + $doc_links .= '
    '; + $__dashboard_items[0][] = $doc_links; +} + +try +{ + if (empty($__resources['rss_news'])) { + throw new Exception(); + } + + $feed_reader = new feedReader; + $feed_reader->setCacheDir(DC_TPL_CACHE); + $feed_reader->setTimeout(2); + $feed_reader->setUserAgent('Dotclear - http://www.dotclear.org/'); + $feed = $feed_reader->parse($__resources['rss_news']); + if ($feed) + { + $latest_news = '

    '.__('Latest news').'

    '; + $i = 1; + foreach ($feed->items as $item) + { + $dt = isset($item->link) ? ''.$item->title.'' : $item->title; + + if ($i < 3) { + $latest_news .= + '
    '.$dt.'
    '. + '

    '.dt::dt2str('%d %B %Y',$item->pubdate,'Europe/Paris').': '. + ''.text::cutString(html::clean($item->content),120).'...

    '; + } else { + $latest_news .= + '
    '.$dt.'
    '. + '
    '.dt::dt2str('%d %B %Y',$item->pubdate,'Europe/Paris').'
    '; + } + $i++; + if ($i > 7) { break; } + } + $latest_news .= '
    '; + $__dashboard_items[1][] = $latest_news; + } +} +catch (Exception $e) {} + +$core->callBehavior('adminDashboardItems', $core, $__dashboard_items); + +/* DISPLAY +-------------------------------------------------------- */ +dcPage::open(__('Dashboard'), + dcPage::jsToolBar(). + dcPage::jsLoad('js/_index.js'). + # --BEHAVIOR-- adminDashboardHeaders + $core->callBehavior('adminDashboardHeaders') +); + +echo '

    '.html::escapeHTML($core->blog->name).' › '.__('Dashboard'); + +if ($core->auth->getInfo('user_default_blog') != $core->blog->id && $core->auth->blog_count > 1) { + echo + ' - '.__('Make this blog my default blog').''; +} + +echo '

    '; + +if ($core->blog->status == 0) { + echo '

    '.__('This blog is offline').'

    '; +} elseif ($core->blog->status == -1) { + echo '

    '.__('This blog is removed').'

    '; +} + +if (!DC_ADMIN_URL) { + echo + '

    '. + __('DC_ADMIN_URL is not defined, you should edit your configuration file.'). + '

    '; +} + +# Plugins install messages +if (!empty($plugins_install['success'])) +{ + echo '
    '.__('Following plugins have been installed:').'
      '; + foreach ($plugins_install['success'] as $k => $v) { + echo '
    • '.$k.'
    • '; + } + echo '
    '; +} +if (!empty($plugins_install['failure'])) +{ + echo '
    '.__('Following plugins have not been installed:').'
      '; + foreach ($plugins_install['failure'] as $k => $v) { + echo '
    • '.$k.' ('.$v.')
    • '; + } + echo '
    '; +} + +# Dashboard icons +echo '
    '; +foreach ($__dashboard_icons as $i) +{ + echo + '

    '. + ''.$i[0].'

    '; +} +echo '
    '; + +if ($core->auth->check('usage,contentadmin',$core->blog->id)) +{ + $categories_combo = array(' ' => ''); + try { + $categories = $core->blog->getCategories(array('post_type'=>'post')); + while ($categories->fetch()) { + $categories_combo[] = new formSelectOption( + str_repeat('  ',$categories->level-1).'• '.html::escapeHTML($categories->cat_title), + $categories->cat_id + ); + } + } catch (Exception $e) { } + + echo + '
    '. + '

    '.__('Quick entry').'

    '. + '
    '. + '
    '. + '

    '. + '

    '. + form::textarea('post_content',50,7,'','',2). + '

    '. + '

    '. + '

    '. + ($core->auth->check('publish',$core->blog->id) + ? '' + : ''). + $core->formNonce(). + form::hidden('post_status',-2). + form::hidden('post_format',$core->auth->getOption('post_format')). + form::hidden('post_excerpt',''). + form::hidden('post_lang',$core->auth->getInfo('user_lang')). + form::hidden('post_notes',''). + '

    '. + '
    '. + '
    '. + '
    '; +} + +echo '
    '; + +# Dashboard columns +echo '
    '; + +# Dotclear updates notifications +if ($core->auth->isSuperAdmin() && is_readable(DC_DIGESTS)) +{ + $updater = new dcUpdate(DC_UPDATE_URL,'dotclear',DC_UPDATE_VERSION,DC_TPL_CACHE.'/versions'); + $new_v = $updater->check(DC_VERSION); + + if ($updater->getNotify() && $new_v) { + echo + '

    '.sprintf(__('Dotclear %s is available!'),$new_v).'

    '. + '
    '; + } +} + +foreach ($__dashboard_items as $i) +{ + echo '
    '; + foreach ($i as $v) { + echo $v; + } + echo '
    '; +} +echo '
    '; + +dcPage::close(); +?> \ No newline at end of file diff --git a/admin/install/check.php b/admin/install/check.php new file mode 100644 index 0000000..16edaff --- /dev/null +++ b/admin/install/check.php @@ -0,0 +1,83 @@ +driver() == 'mysql') + { + if (version_compare($con->version(),'4.1','<')) + { + $err[] = sprintf(__('MySQL version is %s (4.1 or earlier needed).'),$con->version()); + } + else + { + $rs = $con->select('SHOW ENGINES'); + $innodb = false; + while ($rs->fetch()) { + if (strtolower($rs->f(0)) == 'innodb' && strtolower($rs->f(1)) != 'disabled' && strtolower($rs->f(1)) != 'no') { + $innodb = true; + break; + } + } + + if (!$innodb) { + $err[] = __('MySQL InnoDB engine is not available.'); + } + } + } + elseif ($con->driver() == 'pgsql') + { + if (version_compare($con->version(),'8.0','<')) + { + $err[] = sprintf(__('PostgreSQL version is %s (8.0 or earlier needed).'),$con->version()); + } + } + + return count($err) == 0; +} +?> \ No newline at end of file diff --git a/admin/install/index.php b/admin/install/index.php new file mode 100644 index 0000000..091a21b --- /dev/null +++ b/admin/install/index.php @@ -0,0 +1,313 @@ +wizard.','wizard.php'); + $code = 0; + include dirname(__FILE__).'/../../inc/core_error.php'; + exit; +} + +require dirname(__FILE__).'/../../inc/prepend.php'; +require dirname(__FILE__).'/check.php'; + +$can_install = true; +$err = ''; + +# Loading locales for detected language +$dlang = http::getAcceptLanguage(); +if ($dlang != 'en') +{ + l10n::init(); + l10n::set(dirname(__FILE__).'/../../locales/'.$dlang.'/main'); +} + +if (!defined('DC_MASTER_KEY') || DC_MASTER_KEY == '') { + $can_install = false; + $err = '

    '.__('Please set a master key (DC_MASTER_KEY) in configuration file.').'

    '; +} + +# Check if dotclear is already installed +$schema = dbSchema::init($core->con); +if (in_array($core->prefix.'post',$schema->getTables())) { + $can_install = false; + $err = '

    '.__('Dotclear is already installed.').'

    '; +} + +# Check system capabilites +if (!dcSystemCheck($core->con,$_e)) { + $can_install = false; + $err = '

    '.__('Dotclear cannot be installed.').'

    • '.implode('
    • ',$_e).'
    '; +} + +# Get information and perform install +$u_email = $u_firstname = $u_name = $u_login = $u_pwd = ''; +$mail_sent = false; +if ($can_install && !empty($_POST)) +{ + $u_email = !empty($_POST['u_email']) ? $_POST['u_email'] : null; + $u_firstname = !empty($_POST['u_firstname']) ? $_POST['u_firstname'] : null; + $u_name = !empty($_POST['u_name']) ? $_POST['u_name'] : null; + $u_login = !empty($_POST['u_login']) ? $_POST['u_login'] : null; + $u_pwd = !empty($_POST['u_pwd']) ? $_POST['u_pwd'] : null; + $u_pwd2 = !empty($_POST['u_pwd2']) ? $_POST['u_pwd2'] : null; + + try + { + # Check user information + if (empty($u_login)) { + throw new Exception(__('No user ID given')); + } + if (!preg_match('/^[A-Za-z0-9@._-]{2,}$/',$u_login)) { + throw new Exception(__('User ID must contain at least 2 characters using letters, numbers or symbols.')); + } + if ($u_email && !text::isEmail($u_email)) { + throw new Exception(__('Invalid email address')); + } + + if (empty($u_pwd)) { + throw new Exception(__('No password given')); + } + if ($u_pwd != $u_pwd2) { + throw new Exception(__("Passwords don't match")); + } + if (strlen($u_pwd) < 6) { + throw new Exception(__('Password must contain at least 6 characters.')); + } + + # Try to guess timezone + $default_tz = 'Europe/London'; + if (!empty($_POST['u_date']) && function_exists('timezone_open')) + { + if (preg_match('/\((.+)\)$/',$_POST['u_date'],$_tz)) { + $_tz = $_tz[1]; + $_tz = @timezone_open($_tz); + if ($_tz instanceof DateTimeZone) { + $_tz = @timezone_name_get($_tz); + if ($_tz) { + $default_tz = $_tz; + } + } + unset($_tz); + } + } + + # Create schema + $_s = new dbStruct($core->con,$core->prefix); + require dirname(__FILE__).'/../../inc/dbschema/db-schema.php'; + + $si = new dbStruct($core->con,$core->prefix); + $changes = $si->synchronize($_s); + + # Create user + $cur = $core->con->openCursor($core->prefix.'user'); + $cur->user_id = $u_login; + $cur->user_super = 1; + $cur->user_pwd = crypt::hmac(DC_MASTER_KEY,$u_pwd); + $cur->user_name = (string) $u_name; + $cur->user_firstname = (string) $u_firstname; + $cur->user_email = (string) $u_email; + $cur->user_lang = $dlang; + $cur->user_tz = $default_tz; + $cur->user_creadt = array('NOW()'); + $cur->user_upddt = array('NOW()'); + $cur->user_options = serialize($core->userDefaults()); + $cur->insert(); + + $core->auth->checkUser($u_login); + + $admin_url = preg_replace('%install/index.php$%','',$_SERVER['REQUEST_URI']); + $root_url = preg_replace('%/admin/install/index.php$%','',$_SERVER['REQUEST_URI']); + + # Create blog + $cur = $core->con->openCursor($core->prefix.'blog'); + $cur->blog_id = 'default'; + $cur->blog_url = http::getHost().$root_url.'/index.php?'; + $cur->blog_name = __('My first blog'); + $core->addBlog($cur); + $core->blogDefaults($cur->blog_id); + + $blog_settings = new dcSettings($core,'default'); + $blog_settings->setNameSpace('system'); + $blog_settings->put('blog_timezone',$default_tz); + $blog_settings->put('lang',$dlang); + $blog_settings->put('public_url',$root_url.'/public'); + $blog_settings->put('themes_url',$root_url.'/themes'); + + # Add Dotclear version + $cur = $core->con->openCursor($core->prefix.'version'); + $cur->module = 'core'; + $cur->version = (string) DC_VERSION; + $cur->insert(); + + # Create first post + $core->setBlog('default'); + + $cur = $core->con->openCursor($core->prefix.'post'); + $cur->user_id = $u_login; + $cur->post_format = 'xhtml'; + $cur->post_lang = $dlang; + $cur->post_title = __('Welcome to Dotclear!'); + $cur->post_content = '

    '.__('This is your first entry. When you\'re ready '. + 'to blog, log in to edit or delete it.').'

    '; + $cur->post_content_xhtml = $cur->post_content; + $cur->post_status = 1; + $cur->post_open_comment = 1; + $cur->post_open_tb = 0; + $post_id = $core->blog->addPost($cur); + + # Add a comment to it + $cur = $core->con->openCursor($core->prefix.'comment'); + $cur->post_id = $post_id; + $cur->comment_tz = $default_tz; + $cur->comment_author = __('Dotclear Team'); + $cur->comment_email = 'contact@dotclear.net'; + $cur->comment_site = 'http://www.dotclear.org/'; + $cur->comment_content = __("

    This is a comment.

    \n

    To delete it, log in and ". + "view your blog's comments. Then you might remove or edit it.

    "); + $core->blog->addComment($cur); + + $step = 1; + } + catch (Exception $e) + { + $err = $e->getMessage(); + } +} + +if (!isset($step)) { + $step = 0; +} +header('Content-Type: text/html; charset=UTF-8'); +?> + + + + + + + + + + + Dotclear Install + + + + + + + +
    +'.__('Dotclear installation').''; + +if (!is_writable(DC_TPL_CACHE)) { + echo '

    '.sprintf(__('Cache directory %s is not writable.'),DC_TPL_CACHE).'

    '; +} + +if (!empty($err)) { + echo '

    '.__('Errors:').'

    '.$err.'
    '; +} + +if (!empty($_GET['wiz'])) { + echo '

    '.__('Configuration file has been successfully created.').'

    '; +} + +if ($can_install && $step == 0) +{ + echo + '

    '.__('User information').'

    '. + + '

    '.__('Please provide the following information needed to create the first user.').'

    '. + + '
    '. + '
    '.__('User information').''. + '

    '. + '

    '. + '

    '. + '
    '. + + '
    '.__('Username and password').''. + '

    '. + '

    '. + '

    '. + '
    '. + + '

    '. + '
    '; +} +elseif ($can_install && $step == 1) +{ + echo + '

    '.__('All done!').'

    '. + + '

    '.__('Dotclear has been successfully installed. Here is some useful information you should keep.').'

    '. + + '

    '.__('Your account').'

    '. + '
      '. + '
    • '.__('Username:').' '.html::escapeHTML($u_login).'
    • '. + '
    • '.__('Password:').' '.html::escapeHTML($u_pwd).'
    • '. + '
    '. + + '

    '.__('Your blog').'

    '. + '
      '. + '
    • '.__('Blog address:').' '.html::escapeHTML(http::getHost().$root_url).'/index.php?
    • '. + '
    • '.__('Administration interface:').' '.html::escapeHTML(http::getHost().$admin_url).'
    • '. + '
    '. + + '
    '. + '

    '. + form::hidden(array('user_id'),html::escapeHTML($u_login)). + form::hidden(array('user_pwd'),html::escapeHTML($u_pwd)). + '

    '. + '
    '; +} +?> +
    + + \ No newline at end of file diff --git a/admin/install/wizard.php b/admin/install/wizard.php new file mode 100644 index 0000000..73ab1d5 --- /dev/null +++ b/admin/install/wizard.php @@ -0,0 +1,182 @@ +%s already exists. If you need to reset any of the configuration items in this file, please delete it first or you may continue to install.'), + basename(DC_RC_PATH),'index.php')); +} + +$DBDRIVER = !empty($_POST['DBDRIVER']) ? $_POST['DBDRIVER'] : 'mysql'; +$DBHOST = !empty($_POST['DBHOST']) ? $_POST['DBHOST'] : ''; +$DBNAME = !empty($_POST['DBNAME']) ? $_POST['DBNAME'] : ''; +$DBUSER = !empty($_POST['DBUSER']) ? $_POST['DBUSER'] : ''; +$DBPASSWORD = !empty($_POST['DBPASSWORD']) ? $_POST['DBPASSWORD'] : ''; +$DBPREFIX = !empty($_POST['DBPREFIX']) ? $_POST['DBPREFIX'] : 'dc_'; + +if (!empty($_POST)) +{ + try + { + # Tries to connect to database + try { + $con = dbLayer::init($DBDRIVER,$DBHOST,$DBNAME,$DBUSER,$DBPASSWORD); + } catch (Exception $e) { + throw new Exception('

    ' . __($e->getMessage()) . '

    '); + } + + # Checks system capabilites + require dirname(__FILE__).'/check.php'; + if (!dcSystemCheck($con,$_e)) { + $can_install = false; + throw new Exception('

    '.__('Dotclear cannot be installed.').'

    • '.implode('
    • ',$_e).'
    '); + } + + # Check if dotclear is already installed + $schema = dbSchema::init($con); + if (in_array($DBPREFIX.'version',$schema->getTables())) { + throw new Exception(__('Dotclear is already installed.')); + } + + # Does config.php.in exist? + $config_in = dirname(__FILE__).'/../../inc/config.php.in'; + if (!is_file($config_in)) { + throw new Exception(sprintf(__('File %s does not exist.'),$config_in)); + } + + # Can we write config.php + if (!is_writable(dirname(DC_RC_PATH))) { + throw new Exception(sprintf(__('Cannot write %s file.'),DC_RC_PATH)); + } + + # Creates config.php file + $full_conf = file_get_contents($config_in); + + writeConfigValue('DC_DBDRIVER',$DBDRIVER,$full_conf); + writeConfigValue('DC_DBHOST',$DBHOST,$full_conf); + writeConfigValue('DC_DBUSER',$DBUSER,$full_conf); + writeConfigValue('DC_DBPASSWORD',$DBPASSWORD,$full_conf); + writeConfigValue('DC_DBNAME',$DBNAME,$full_conf); + writeConfigValue('DC_DBPREFIX',$DBPREFIX,$full_conf); + + $admin_url = preg_replace('%install/wizard.php$%','',$_SERVER['REQUEST_URI']); + writeConfigValue('DC_ADMIN_URL',http::getHost().$admin_url,$full_conf); + writeConfigValue('DC_MASTER_KEY',md5(uniqid()),$full_conf); + + $fp = @fopen(DC_RC_PATH,'wb'); + if ($fp === false) { + throw new Exception(sprintf(__('Cannot write %s file.'),DC_RC_PATH)); + } + fwrite($fp,$full_conf); + fclose($fp); + chmod(DC_RC_PATH, 0666); + + $con->close(); + http::redirect('index.php?wiz=1'); + } + catch (Exception $e) + { + $err = $e->getMessage(); + } +} + +function writeConfigValue($name,$val,&$str) +{ + $val = str_replace("'","\'",$val); + $str = preg_replace('/(\''.$name.'\')(.*?)$/ms','$1,\''.$val.'\');',$str); +} + +header('Content-Type: text/html; charset=UTF-8'); +?> + + + + + + + + + + + Dotclear Install Wizard + + + + + +
    +'.__('Dotclear installation wizard').''; + +if (!empty($err)) { + echo '

    '.__('Errors:').'

    '.$err.'
    '; +} + +echo +'

    '.__('System information').'

    '. + +'

    '.__('Please provide the following information needed to create your configuration file.').'

    '. + +'
    '. +'

    '. +'

    '. +'

    '. +'

    '. +'

    '. +'

    '. + +'

    '. +'
    '; +?> +
    + + \ No newline at end of file diff --git a/admin/js/_blog_theme.js b/admin/js/_blog_theme.js new file mode 100644 index 0000000..325a193 --- /dev/null +++ b/admin/js/_blog_theme.js @@ -0,0 +1,6 @@ + +$(function(){$('#themes-actions').hide();var submit_s=$('#themes-actions input[name=select]');var submit_r=$('#themes-actions input[name=remove]');var details=$('#themes div.theme-details');$('div.theme-actions',details).hide();$('input:radio',details).hide();$('div.theme-info span, div.theme-info a',details).hide();details.removeClass('theme-details').addClass('theme-details-js');var themes_wrapper=$('
    ');var theme_box=$('
    ');$('#themes').wrap(themes_wrapper).before(theme_box);details.each(function(){var box=this;var a=$(document.createElement('a'));a.attr('href','#');a.attr('title',$('>div h3>label',this).text());$(box).wrap(a);$(box).parent().click(function(event){update_box(box);event.preventDefault();return false;});});function update_box(e){theme_box.empty();var img=$('div.theme-shot',e).clone();var info=$('div.theme-info',e).clone();if($(e).hasClass('current-theme')){var actions=$('div.theme-actions',e).clone();actions.show();}else{var actions=$('
    ');if(submit_s.length>0&&!$('input:radio',info).attr('disabled')){var select=$(''+dotclear.msg.use_this_theme+'');select.css('font-weight','bold').click(function(){submit_s.click();return false;});actions.append(select).append('  ');} +if(submit_r.length>0&&$('input:radio',info).attr('id')!='theme_default'){var remove=$(''+dotclear.msg.remove_this_theme+'');remove.click(function(){var t_name=$(this).parents('#theme-box').find('div.theme-info h3:first').text();t_name=$.trim(t_name);if(window.confirm(dotclear.msg.confirm_delete_theme.replace('%s',t_name))){submit_r.click();} +return false;});actions.append(remove);}} +$('input:radio',info).remove();$('span, a',info).show();theme_box.append(img).append(info).append(actions);details.removeClass('theme-selected');$(e).addClass('theme-selected');$('input:radio',e).attr('checked','checked');} +update_box(details[0]);}); \ No newline at end of file diff --git a/admin/js/_categories.js b/admin/js/_categories.js new file mode 100644 index 0000000..8e6929e --- /dev/null +++ b/admin/js/_categories.js @@ -0,0 +1,2 @@ + +$(function(){$('form#delete-category').submit(function(){var c_id=$('#del_cat').val();var c_name=$('#del_cat option[value='+c_id+']').text();return window.confirm(dotclear.msg.confirm_delete_category.replace('%s',c_name));});});$(function(){$('form#reset-order').submit(function(){return window.confirm(dotclear.msg.confirm_reorder_categories);});}); \ No newline at end of file diff --git a/admin/js/_category.js b/admin/js/_category.js new file mode 100644 index 0000000..496a4c4 --- /dev/null +++ b/admin/js/_category.js @@ -0,0 +1,2 @@ + +$(function(){dotclear.hideLockable();var tbCategory=new jsToolBar(document.getElementById('cat_desc'));tbCategory.draw('xhtml');}); \ No newline at end of file diff --git a/admin/js/_comment.js b/admin/js/_comment.js new file mode 100644 index 0000000..a46fa52 --- /dev/null +++ b/admin/js/_comment.js @@ -0,0 +1,3 @@ + +$(function(){if(!document.getElementById){return;} +var tbComment=new jsToolBar(document.getElementById('comment_content'));tbComment.draw('xhtml');$('#comment-form input[name="delete"]').click(function(){return window.confirm(dotclear.msg.confirm_delete_comment);});}); \ No newline at end of file diff --git a/admin/js/_comments.js b/admin/js/_comments.js new file mode 100644 index 0000000..01b7483 --- /dev/null +++ b/admin/js/_comments.js @@ -0,0 +1,6 @@ + +dotclear.commentExpander=function(line){var td=line.firstChild;var img=document.createElement('img');img.src=dotclear.img_plus_src;img.alt=dotclear.img_plus_alt;img.className='expand';$(img).css('cursor','pointer');img.line=line;img.onclick=function(){dotclear.viewCommentContent(this,this.line);};td.insertBefore(img,td.firstChild);};dotclear.viewCommentContent=function(img,line){var commentId=line.id.substr(1);var tr=document.getElementById('ce'+commentId);if(!tr){tr=document.createElement('tr');tr.id='ce'+commentId;var td=document.createElement('td');td.colSpan=6;td.className='expand';tr.appendChild(td);img.src=dotclear.img_minus_src;img.alt=dotclear.img_minus_alt;$.get('services.php',{f:'getCommentById',id:commentId},function(data){var rsp=$(data).children('rsp')[0];if(rsp.attributes[0].value=='ok'){var comment=$(rsp).find('comment_display_content').text();if(comment){$(td).append(comment);var comment_email=$(rsp).find('comment_email').text();var comment_site=$(rsp).find('comment_site').text();var comment_ip=$(rsp).find('comment_ip').text();var comment_spam_disp=$(rsp).find('comment_spam_disp').text();$(td).append('

    '+dotclear.msg.website+' '+comment_site+'
    '+''+dotclear.msg.email+' '+comment_email+'
    '+''+dotclear.msg.ip_address+' '+comment_ip+''+'
    '+comment_spam_disp+'

    ');}}else{alert($(rsp).find('message').text());}});$(line).toggleClass('expand');line.parentNode.insertBefore(tr,line.nextSibling);} +else if(tr.style.display=='none') +{$(tr).toggle();$(line).toggleClass('expand');img.src=dotclear.img_minus_src;img.alt=dotclear.img_minus_alt;} +else +{$(tr).toggle();$(line).toggleClass('expand');img.src=dotclear.img_plus_src;img.alt=dotclear.img_plus_alt;}};$(function(){$('#form-comments tr.line').each(function(){dotclear.commentExpander(this);});$('.checkboxes-helpers').each(function(){dotclear.checkboxesHelpers(this);});dotclear.commentsActionsHelper();}); \ No newline at end of file diff --git a/admin/js/_index.js b/admin/js/_index.js new file mode 100644 index 0000000..405c4d1 --- /dev/null +++ b/admin/js/_index.js @@ -0,0 +1,9 @@ + +$(function(){var f=$('#quick-entry');if(f.length>0){var contentTb=new jsToolBar($('#post_content',f)[0]);contentTb.switchMode($('#post_format',f).val());$('input[name=save]',f).click(function(){quickPost(f,-2);return false;});if($('input[name=save-publish]',f).length>0){var btn=$('');$('input[name=save-publish]',f).remove();$('input[name=save]',f).after(btn).after(' ');btn.click(function(){quickPost(f,1);return false;});} +function quickPost(f,status){if(contentTb.getMode()=='wysiwyg'){contentTb.syncContents('iframe');} +var params={f:'quickPost',xd_check:dotclear.nonce,post_title:$('#post_title',f).val(),post_content:$('#post_content',f).val(),cat_id:$('#cat_id',f).val(),post_status:status,post_format:$('#post_format',f).val(),post_lang:$('#post_lang',f).val()} +$('p.qinfo',f).remove();$.post('services.php',params,function(data){if($('rsp[status=failed]',data).length>0){var msg='

    '+dotclear.msg.error+' '+$('rsp',data).text()+'

    ';}else{var msg='

    '+dotclear.msg.entry_created+' - '+ +dotclear.msg.edit_entry+'';if($('rsp>post',data).attr('post_status')==1){msg+=' - '+ +dotclear.msg.view_entry+'';} +msg+='

    ';$('#post_title',f).val('');$('#post_content',f).val('');if(contentTb.getMode()=='wysiwyg'){contentTb.syncContents('textarea');}} +$('fieldset',f).prepend(msg);});}}}); \ No newline at end of file diff --git a/admin/js/_langs.js b/admin/js/_langs.js new file mode 100644 index 0000000..8824cff --- /dev/null +++ b/admin/js/_langs.js @@ -0,0 +1,2 @@ + +$(function(){$('table.plugins form input[type=submit][name=delete]').click(function(){var l_name=$(this).parents('tr.line').find('td:first').text();return window.confirm(dotclear.msg.confirm_delete_lang.replace('%s',l_name));});}); \ No newline at end of file diff --git a/admin/js/_media.js b/admin/js/_media.js new file mode 100644 index 0000000..01e486d --- /dev/null +++ b/admin/js/_media.js @@ -0,0 +1,7 @@ + +$(function(){fileRemoveAct();function fileRemoveAct(){$('a.media-remove').click(function(){var m_name=$(this).parents('ul').find('li:first>a').text();if(window.confirm(dotclear.msg.confirm_delete_media.replace('%s',m_name))){var f=$('#media-remove-hide').get(0);f.elements['remove'].value=this.href.replace(/^(.*)&remove=(.*?)(&|$)/,'$2');this.href='';f.submit();} +return false;});} +if(!$.browser.opera){var upldr=$(''+dotclear.msg.activate_enhanced_uploader+'').click(function(){candyUploadInit();return false;});$('#media-upload>fieldset').append($('
    ').append(upldr));if($.cookie('dc_candy_upl')==1){candyUploadInit();}} +function candyUploadInit() +{var candy_upload_success=false;var candy_upload_form_url=$('#media-upload').attr('action')+'&file_sort=date-desc&d='+$('#media-upload input[name=d]').val();var candy_upload_limit=$('#media-upload input[name=MAX_FILE_SIZE]').val();$('#media-upload').candyUpload({upload_url:dotclear.candyUpload.base_url+'/media.php',flash_movie:dotclear.candyUpload.movie_url,file_size_limit:candy_upload_limit+'b',params:'swfupload=1&'+dotclear.candyUpload.params,callbacks:{createControls:function(){var _this=this;var l=$(''+dotclear.msg.disable_enhanced_uploader+'').click(function(){_this.upldr.destroy();_this.ctrl.block.empty().remove();$('#media-upload').show();delete _this;$.cookie('dc_candy_upl','',{expires:-1});return false;});this.ctrl.disable=$('
    ').append(l).appendTo(this.ctrl.block);},flashReady:function(){this.ctrl.btn_browse.addClass('button');this.ctrl.block.append(this.ctrl.disable);},uploadSuccess:function(o,data){if(data=='ok'){candy_upload_success=true;this.fileMsg(o.id,this.locales.file_uploaded);}else{this.fileErrorMsg(o.id,data);} +if(candy_upload_success&&$('div.cu-file:has(span.cu-filecancel a)',this.ctrl.files).length==0){$.cookie('dc_candy_upl','1',{expires:30});$.get(candy_upload_form_url,function(data){var media=$('div.media-list');media.after($('div.media-list',data)).remove();fileRemoveAct();});}}}});}}); \ No newline at end of file diff --git a/admin/js/_media_item.js b/admin/js/_media_item.js new file mode 100644 index 0000000..c9a2eeb --- /dev/null +++ b/admin/js/_media_item.js @@ -0,0 +1,4 @@ + +$(function(){$('#media-details-tab').onetabload(function(){var media_dt=document.getElementById('media_dt');if(media_dt==undefined){return;} +var post_dtPick=new datePicker(media_dt);post_dtPick.img_top='1.5em';post_dtPick.draw();});$('#file-unzip').each(function(){var a=document.createElement('a');var mediaId=$(this).find('input[name=id]').val();var self=$(this);a.href='#';$(a).text(dotclear.msg.zip_file_content);self.before(a);$(a).wrap('

    ');$(a).click(function(){$.get('services.php',{f:'getZipMediaContent',id:mediaId},function(data){var rsp=$(data).children('rsp')[0];if(rsp.attributes[0].value=='ok'){var div=document.createElement('div');var list=document.createElement('ul');var expanded=false;$(div).css({overflow:'auto',border:'1px solid #ccc',margin:'1em 0',padding:'1px 0.5em'});$(div).append(list);self.before(div);$(a).hide();$(div).before('

    '+dotclear.msg.zip_file_content+'

    ');$(rsp).find('file').each(function(){$(list).append('
  • '+$(this).text()+'
  • ');if($(div).height()>200&&!expanded){$(div).css({height:'200px'});expanded=true;}});}else{alert($(rsp).find('message').text());}});return false;});});$('#file-unzip').submit(function(){if($(this).find('#inflate_mode').val()=='current'){return window.confirm(dotclear.msg.confirm_extract_current);} +return true;});}); \ No newline at end of file diff --git a/admin/js/_permissions.js b/admin/js/_permissions.js new file mode 100644 index 0000000..1547911 --- /dev/null +++ b/admin/js/_permissions.js @@ -0,0 +1,6 @@ + +jQuery.fn.updatePermissionsForm=function(){return this.each(function(){var perms={};var re=/^perm\[(.+?)\]\[(.+?)\]$/;var e,prop;for(var i=0;i'+dotclear.msg.website+' '+comment_site+'
    '+''+dotclear.msg.email+' '+ +comment_email+'
    '+comment_spam_disp+'

    ');}}else{alert($(rsp).find('message').text());}});$(line).toggleClass('expand');line.parentNode.insertBefore(tr,line.nextSibling);} +else if(tr.style.display=='none') +{$(tr).toggle();$(line).toggleClass('expand');img.src=dotclear.img_minus_src;img.alt=dotclear.img_minus_alt;} +else +{$(tr).toggle();$(line).toggleClass('expand');img.src=dotclear.img_plus_src;img.alt=dotclear.img_plus_alt;}};$(function(){if(!document.getElementById){return;} +if(document.getElementById('edit-entry')) +{var formatField=$('#post_format').get(0);$(formatField).change(function(){excerptTb.switchMode(this.value);contentTb.switchMode(this.value);});var excerptTb=new jsToolBar(document.getElementById('post_excerpt'));var contentTb=new jsToolBar(document.getElementById('post_content'));excerptTb.context=contentTb.context='post';} +if(document.getElementById('comment_content')){var commentTb=new jsToolBar(document.getElementById('comment_content'));} +$('#post-preview').modalWeb($(window).width()-40,$(window).height()-40);$('#edit-entry').onetabload(function(){dotclear.hideLockable();var post_dtPick=new datePicker($('#post_dt').get(0));post_dtPick.img_top='1.5em';post_dtPick.draw();$('input[name="delete"]').click(function(){return window.confirm(dotclear.msg.confirm_delete_post);});$('#notes-area label').toggleWithLegend($('#notes-area').children().not('label'),{cookie:'dcx_post_notes',hide:$('#post_notes').val()==''});$('#post_lang').parent().toggleWithLegend($('#post_lang'),{cookie:'dcx_post_lang'});$('#post_password').parent().toggleWithLegend($('#post_password'),{cookie:'dcx_post_password',hide:$('#post_password').val()==''});$('#excerpt-area label').toggleWithLegend($('#excerpt-area').children().not('label'),{fn:function(){excerptTb.switchMode(formatField.value);},cookie:'dcx_post_excerpt',hide:$('#post_excerpt').val()==''});contentTb.switchMode(formatField.value);$('a.attachment-remove').click(function(){this.href='';var m_name=$(this).parents('ul').find('li:first>a').attr('title');if(window.confirm(dotclear.msg.confirm_remove_attachment.replace('%s',m_name))){var f=$('#attachment-remove-hide').get(0);f.elements['media_id'].value=this.id.substring(11);f.submit();} +return false;});var h=document.createElement('h4');var a=document.createElement('a');a.href='#';$(a).click(function(){var params={xd_check:dotclear.nonce,f:'validatePostMarkup',excerpt:$('#post_excerpt').text(),content:$('#post_content').text(),format:$('#post_format').get(0).value,lang:$('#post_lang').get(0).value};$.post('services.php',params,function(data){if($(data).find('rsp').attr('status')!='ok'){alert($(data).find('rsp message').text());return false;} +if($(data).find('valid').text()==1){var p=document.createElement('p');p.id='markup-validator';if($('#markup-validator').length>0){$('#markup-validator').remove();} +$(p).addClass('message');$(p).text(dotclear.msg.xhtml_valid);$(p).insertAfter(h);$(p).backgroundFade({sColor:'#666666',eColor:'#ffcc00',steps:50},function(){$(this).backgroundFade({sColor:'#ffcc00',eColor:'#666666'});});}else{var div=document.createElement('div');div.id='markup-validator';if($('#markup-validator').length>0){$('#markup-validator').remove();} +$(div).addClass('error');$(div).html('

    '+dotclear.msg.xhtml_not_valid+'

    '+$(data).find('errors').text());$(div).insertAfter(h);$(div).backgroundFade({sColor:'#ffffff',eColor:'#ff9999',steps:50},function(){$(this).backgroundFade({sColor:'#ff9999',eColor:'#ffffff'});});} +return false;});return false;});a.appendChild(document.createTextNode(dotclear.msg.xhtml_validator));h.appendChild(a);$(h).appendTo('#entry-content');});$('#comments').onetabload(function(){$('.comments-list tr.line').each(function(){dotclear.commentExpander(this);});$('.checkboxes-helpers').each(function(){dotclear.checkboxesHelpers(this);});dotclear.commentsActionsHelper();});$('#add-comment').onetabload(function(){commentTb.draw('xhtml');});}); \ No newline at end of file diff --git a/admin/js/_posts_list.js b/admin/js/_posts_list.js new file mode 100644 index 0000000..f4ca648 --- /dev/null +++ b/admin/js/_posts_list.js @@ -0,0 +1,7 @@ + +dotclear.postExpander=function(line){var td=line.firstChild;var img=document.createElement('img');img.src=dotclear.img_plus_src;img.alt=dotclear.img_plus_alt;img.className='expand';$(img).css('cursor','pointer');img.line=line;img.onclick=function(){dotclear.viewPostContent(this,this.line);};td.insertBefore(img,td.firstChild);};dotclear.viewPostContent=function(img,line){var postId=line.id.substr(1);var tr=document.getElementById('pe'+postId);if(!tr){tr=document.createElement('tr');tr.id='pe'+postId;var td=document.createElement('td');td.colSpan=8;td.className='expand';tr.appendChild(td);img.src=dotclear.img_minus_src;img.alt=dotclear.img_minus_alt;$.get('services.php',{f:'getPostById',id:postId,post_type:''},function(data){var rsp=$(data).children('rsp')[0];if(rsp.attributes[0].value=='ok'){var post=$(rsp).find('post_display_content').text();var post_excerpt=$(rsp).find('post_display_excerpt').text();var res='';if(post){if(post_excerpt){res+=post_excerpt+'
    ';} +res+=post;$(td).append(res);}}else{alert($(rsp).find('message').text());}});$(line).toggleClass('expand');line.parentNode.insertBefore(tr,line.nextSibling);} +else if(tr.style.display=='none') +{$(tr).toggle();$(line).toggleClass('expand');img.src=dotclear.img_minus_src;img.alt=dotclear.img_minus_alt;} +else +{$(tr).toggle();$(line).toggleClass('expand');img.src=dotclear.img_plus_src;img.alt=dotclear.img_plus_alt;}};$(function(){$('#form-entries tr.line').each(function(){dotclear.postExpander(this);});$('.checkboxes-helpers').each(function(){dotclear.checkboxesHelpers(this);});dotclear.postsActionsHelper();}); \ No newline at end of file diff --git a/admin/js/_preferences.js b/admin/js/_preferences.js new file mode 100644 index 0000000..d47d010 --- /dev/null +++ b/admin/js/_preferences.js @@ -0,0 +1,5 @@ + +$(function(){if($('#new_pwd').length==0){return;} +var user_email=$('#user_email').val();$('#user-form').submit(function(){var e=this.elements['cur_pwd'];if(e.value!=''){return true;} +if($('#user_email').val()!=user_email||$('#new_pwd').val()!=''){e.focus();$(e).backgroundFade({sColor:'#ffffff',eColor:'#ff9999',steps:50},function(){$(this).backgroundFade({sColor:'#ff9999',eColor:'#ffffff'});});return false;} +return true;});}); \ No newline at end of file diff --git a/admin/js/_trackbacks.js b/admin/js/_trackbacks.js new file mode 100644 index 0000000..b3842d7 --- /dev/null +++ b/admin/js/_trackbacks.js @@ -0,0 +1,2 @@ + +$(function(){$('#tb_excerpt').keypress(function(){if(this.value.length>255){this.value=this.value.substring(0,255);}});}); \ No newline at end of file diff --git a/admin/js/_users.js b/admin/js/_users.js new file mode 100644 index 0000000..fec32c1 --- /dev/null +++ b/admin/js/_users.js @@ -0,0 +1,7 @@ + +$(function(){$('.checkboxes-helpers').each(function(){dotclear.checkboxesHelpers(this);});$('#form-users').submit(function(){var action=$(this).find('select[name="dispatch_action"]').val();var user_ids=new Array();var nb_posts=new Array();var i;var msg_cannot_delete=false;$(this).find('input[name="user_id[]"]').each(function(){user_ids.push(this);});$(this).find('input[name="nb_post[]"]').each(function(){nb_posts.push(this.value);});if(action=='deleteuser'){for(i=0;i0){user_ids[i].checked=false;msg_cannot_delete=true;}} +if(msg_cannot_delete==true){alert(dotclear.msg.cannot_delete_users);}} +var selectfields=0;for(i=0;iThis.height()){This.css('height',$('body').height()+'px');}};var textToggler=function(o){var i=$(''+p.img_on_alt+'');o.css('cursor','pointer');var hide=true;o.prepend(' ').prepend(i);o.click(function(){$(this).nextAll().each(function(){if($(this).is('h3')){return false;} +$(this).toggle();sizeBox();return true;});hide=!hide;var img=$(this).find('img');if(!hide){img.attr('src',p.img_off_src);}else{img.attr('src',p.img_on_src);}});};this.addClass('help-box');this.find('>hr').remove();this.find('h3').each(function(){textToggler($(this));});this.find('h3:first').nextAll('*:not(h3)').hide();sizeBox();var img=$(''+dotclear.msg.help+'');var select=$();img.click(function(){return toggle();});$('#content').append(img);return this;};var dotclear={msg:{},hideLockable:function(){$('div.lockable').each(function(){var current_lockable_div=this;$(this).find('p.form-note').hide();$(this).find('input').each(function(){this.disabled=true;$(this).width(($(this).width()-14)+'px');var imgE=document.createElement('img');imgE.src='images/locker.png';imgE.style.position='absolute';imgE.style.top='1.7em';imgE.style.left=($(this).width()+4)+'px';$(imgE).css('cursor','pointer');$(imgE).click(function(){$(this).hide();$(this).prev('input').each(function(){this.disabled=false;$(this).width(($(this).width()+14)+'px');});$(current_lockable_div).find('p.form-note').show();});$(this).parent().css('position','relative');$(this).after(imgE);});});},checkboxesHelpers:function(e){var a=document.createElement('a');a.href='#';$(a).append(document.createTextNode(dotclear.msg.select_all));a.onclick=function(){$(this).parents('form').find('input[type="checkbox"]').check();return false;};$(e).append(a);$(e).append(document.createTextNode(' - '));a=document.createElement('a');a.href='#';$(a).append(document.createTextNode(dotclear.msg.invert_sel));a.onclick=function(){$(this).parents('form').find('input[type="checkbox"]').toggleCheck();return false;};$(e).append(a);},postsActionsHelper:function(){$('#form-entries').submit(function(){var action=$(this).find('select[name="action"]').val();var checked=false;$(this).find('input[name="entries[]"]').each(function(){if(this.checked){checked=true;}});if(!checked){return false;} +if(action=='delete'){return window.confirm(dotclear.msg.confirm_delete_posts);} +return true;});},commentsActionsHelper:function(){$('#form-comments').submit(function(){var action=$(this).find('select[name="action"]').val();var checked=false;$(this).find('input[name="comments[]"]').each(function(){if(this.checked){checked=true;}});if(!checked){return false;} +if(action=='delete'){return window.confirm(dotclear.msg.confirm_delete_comments);} +return true;});}};$(function(){$('#switchblog').change(function(){this.form.submit();});var menu_settings={img_on_src:dotclear.img_menu_off,img_off_src:dotclear.img_menu_on,legend_click:true,speed:100} +$('#blog-menu h3:first').toggleWithLegend($('#blog-menu ul:first'),$.extend({cookie:'dc_blog_menu',hide:false,reverse_cookie:true},menu_settings));$('#system-menu h3:first').toggleWithLegend($('#system-menu ul:first'),$.extend({cookie:'dc_system_menu'},menu_settings));$('#plugins-menu h3:first').toggleWithLegend($('#plugins-menu ul:first'),$.extend({cookie:'dc_plugins_menu'},menu_settings));$('#help').helpViewer();$('.message').backgroundFade({sColor:'#cccccc',eColor:'#666666',steps:20});$('.error').backgroundFade({sColor:'#f5e5e5',eColor:'#e5bfbf',steps:20});$('form:has(input[type=password][name=your_pwd])').submit(function(){var e=this.elements['your_pwd'];if(e.value==''){e.focus();$(e).backgroundFade({sColor:'#ffffff',eColor:'#ff9999',steps:50},function(){$(this).backgroundFade({sColor:'#ff9999',eColor:'#ffffff'});});return false;} +return true;});}); \ No newline at end of file diff --git a/admin/js/confirm-close.js b/admin/js/confirm-close.js new file mode 100644 index 0000000..41489c9 --- /dev/null +++ b/admin/js/confirm-close.js @@ -0,0 +1,12 @@ + +function confirmClose(){if(arguments.length>0){for(var i=0;i0){var res=new Array();var f;for(var i=0;i23){h=0;} +if(h<10){h='0'+h;} +this.hour=h*1;this.oHour.value=h;},setMinute:function(m){if(m<0){m=59;} +if(m>59){m=0;} +if(m<10){m='0'+m;} +this.minute=m*1;this.oMinute.value=m;},changeMonth:function(dir){var y=this.year;var m=this.month;m=m+dir;if(m>12){this.month=1;this.year++;} +else if(m<1){this.month=12;this.year--;} +else{this.month=m;} +this.setDate();},changeYear:function(dir){this.year=this.year+dir;this.setDate();},changeHour:function(dir){this.setHour(this.hour*1+dir);},changeMinute:function(dir){this.setMinute(this.minute*1+dir);},sendDate:function(d){var m=this.month;var hour=this.oHour.value*1;var minute=this.oMinute.value*1;if(hour<0||hour>23||isNaN(hour)){hour=0;} +if(minute<0||minute>59||isNaN(minute)){minute=0;} +if(m<10){m='0'+m;} +if(d<10){d='0'+d;} +if(hour<10){hour='0'+hour;} +if(minute<10){minute='0'+minute;} +this.target.value=this.year+'-'+m+'-'+d+' '+hour+':'+minute;this.close();},sendNow:function(){var dt=new Date();var y=dt.getFullYear();var m=dt.getMonth()+1;var d=dt.getDate();var h=dt.getHours();var i=dt.getMinutes();if(m<10){m='0'+m;} +if(d<10){d='0'+d;} +if(h<10){h='0'+h;} +if(i<10){i='0'+i;} +this.target.value=y+'-'+m+'-'+d+' '+h+':'+i;this.close();},close:function(){document.body.removeChild(this.oTable);},numberOfDays:function(){var res=31;if(this.month==4||this.month==6||this.month==9||this.month==11){res=30;}else if(this.month==2){res=28;if(this.year%4==0&&(this.year%100!=0||this.year%400==0)){res=29;}} +return res;},firstDay:function(){var dt=new Date(this.year,this.month-1,1);var res=dt.getDay();if(res==0){res=7;} +return res;},show:function(){var re=/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2})/;var match=re.exec(this.target.value);if(match){this.year=match[1]*1;this.month=match[2]*1;this.day=match[3]*1;this.hour=match[4]*1;this.minute=match[5]*1;}else{var dt=new Date();this.year=dt.getFullYear();this.month=dt.getMonth()+1;this.day=dt.getDate();this.hour=dt.getHours();this.minute=dt.getMinutes();} +this.oTable.appendChild(this.oBody);this.setDate();this.setPosition();document.body.appendChild(this.oTable);this.oHour.focus();},setPosition:function(){var t_x=this.findPosX(this.target);var t_y=this.findPosY(this.target);var o_h=this.oTable.offsetHeight;var o_w=this.oTable.offsetWidth;this.oTable.style.position='absolute';this.oTable.style.zIndex='100';this.oTable.style.top=t_y+'px';this.oTable.style.left=t_x+'px';},findPosX:function(obj){var curleft=0;if(obj.offsetParent){while(1){curleft+=obj.offsetLeft;if(!obj.offsetParent){break;} +obj=obj.offsetParent;}}else if(obj.x){curleft+=obj.x;} +return curleft;},findPosY:function(obj){var curtop=0;if(obj.offsetParent){while(1){curtop+=obj.offsetTop;if(!obj.offsetParent){break;} +obj=obj.offsetParent;}}else if(obj.y){curtop+=obj.y;} +return curtop;},draw:function(){var imgE=document.createElement('img');imgE.src=this.img_src;imgE.style.position='absolute';imgE.style.top=this.img_top;imgE.style.left=(this.target.clientWidth+4)+'px';imgE.obj=this;imgE.fn=this.show;imgE.onclick=function(){this.fn.apply(this.obj);};this.target.parentNode.style.position='relative';this.target.parentNode.insertBefore(imgE,this.target.nextSibling);}}; \ No newline at end of file diff --git a/admin/js/dragsort-tablerows.js b/admin/js/dragsort-tablerows.js new file mode 100644 index 0000000..164b5ec --- /dev/null +++ b/admin/js/dragsort-tablerows.js @@ -0,0 +1,2 @@ + +ToolMan._dragsortFactory.makeTableSortable=function(table){if(table==null)return;var helpers=ToolMan.helpers();var coordinates=ToolMan.coordinates();var items=table.getElementsByTagName("tr");helpers.map(items,function(item){var dragGroup=dragsort.makeSortable(item);dragGroup.setThreshold(4);var min,max;dragGroup.addTransform(function(coordinate,dragEvent){return coordinate.constrainTo(min,max);});dragGroup.register('dragstart',function(){var items=table.getElementsByTagName("tr");min=max=coordinates.topLeftOffset(items[0]);for(var i=1,n=items.length;i":"","\\/\\*[^*]*\\*+([^\\/][^*]*\\*+)*\\/":"","@(namespace|import)[^;\\n]+[;\\n]":"","'(\\\\.|[^'\\\\])*'":bJ,'"(\\\\.|[^"\\\\])*"':bJ,"\\s+":" "});function cB(a){return cA.exec(a)};function bI(c){return c.replace(cw,function(a,b){return bp[b-1]})};function bJ(c){return"\x01"+bp.push(c.replace(cz,function(a,b){return eval("'\\u"+"0000".slice(b.length)+b+"'")}).slice(1,-1).replace(cx,"\\'"))};function cC(a){return cy.test(a)?bp[a.slice(1)-1]:a};var cD=new D({Width:"Height",width:"height",Left:"Top",left:"top",Right:"Bottom",right:"bottom",onX:"onY"});function A(a){return cD.exec(a)};var bK=[];function bq(a){cF(a);w(window,"onresize",a)};function w(a,b,c){a.attachEvent(b,c);bK.push(arguments)};function cE(a,b,c){try{a.detachEvent(b,c)}catch(ignore){}};w(window,"onunload",function(){var a;while(a=bK.pop()){cE(a[0],a[1],a[2])}});function R(a,b,c){if(!a.elements)a.elements={};if(c)a.elements[b.uniqueID]=b;else delete a.elements[b.uniqueID];return c};w(window,"onbeforeprint",function(){if(!IE7.CSS.print)new bw("print");IE7.CSS.print.recalc()});var bL=/^\d+(px)?$/i;var J=/^\d+%$/;var E=function(a,b){if(bL.test(b))return parseInt(b);var c=a.style.left;var d=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;a.style.left=b||0;b=a.style.pixelLeft;a.style.left=c;a.runtimeStyle.left=d;return b};var br="ie7-";var bM=z.extend({constructor:function(){this.fixes=[];this.recalcs=[]},init:Q});var bs=[];function cF(a){bs.push(a)};IE7.recalc=function(){IE7.HTML.recalc();IE7.CSS.recalc();for(var a=0;a1?2:0;var h=T.exec(f[g])||"if(0){";if(o){h+=i("if(e%1.nodeName!='!'){",m)}var p=S>1?bV:"";h+=i(p+bW,m);h+=Array(I(h,/\{/g).length+1).join("}");d+=h}eval(i(bX,F)+T.unescape(d)+"return s?null:r}");be[a]=_h}return be[a](b||document,c)};var bd=k<6;var bO=/^(href|src)$/;var bu={"class":"className","for":"htmlFor"};IE7._5=1;IE7._e=function(a,b){var c=a.all[b]||null;if(!c||c.id==b)return c;for(var d=0;d+~,]|[^(]\+|^)([#.:\[])/g,cH=/(^|,)([^\s>+~])/g,cI=/\s*([\s>+~(),]|^|$)\s*/g,bQ=/\s\*\s/g;var bR=D.extend({constructor:function(a){this.base(a);this.sorter=new D;this.sorter.add(/:not\([^)]*\)/,D.IGNORE);this.sorter.add(/([ >](\*|[\w-]+))([^: >+~]*)(:\w+-child(\([^)]+\))?)([^: >+~]*)/,"$1$3$6$4")},ignoreCase:true,escape:function(a){return this.optimise(this.format(a))},format:function(a){return a.replace(cI,"$1").replace(cH,"$1 $2").replace(cG,"$1*$2")},optimise:function(a){return this.sorter.exec(a.replace(bQ,">* "))},unescape:function(a){return bI(a)}});var bS={"":"%1!=null","=":"%1=='%2'","~=":/(^| )%1( |$)/,"|=":/^%1(-|$)/,"^=":/^%1/,"$=":/%1$/,"*=":/%1/};var bT={"first-child":"!IE7._b(e%1)","link":"e%1.currentStyle['ie7-link']=='link'","visited":"e%1.currentStyle['ie7-link']=='visited'"};var bv="var p%2=0,i%2,e%2,n%2=e%1.";var bU="e%1.sourceIndex";var bV="var g="+bU+";if(!p[g]){p[g]=1;";var bW="r[r.length]=e%1;if(s)return e%1;";var bX="var _h=function(e0,s){IE7._5++;var r=[],p={},reg=[%1],d=document;";var F;var m;var o;var x;var S;var be={};var T=new bR({" (\\*|[\\w-]+)#([\\w-]+)":function(a,b,c){o=false;var d="var e%2=IE7._e(d,'%4');if(e%2&&";if(b!="*")d+="e%2.nodeName=='%3'&&";d+="(e%1==d||e%1.contains(e%2))){";if(x)d+=i("i%1=n%1.length;",x);return i(d,m++,m,b.toUpperCase(),c)}," (\\*|[\\w-]+)":function(a,b){S++;o=b=="*";var c=bv;c+=(o&&bd)?"all":"getElementsByTagName('%3')";c+=";for(i%2=0;(e%2=n%2[i%2]);i%2++){";return i(c,m++,x=m,b.toUpperCase())},">(\\*|[\\w-]+)":function(a,b){var c=x;o=b=="*";var d=bv;d+=c?"children":"childNodes";if(!o&&c)d+=".tags('%3')";d+=";for(i%2=0;(e%2=n%2[i%2]);i%2++){";if(o){d+="if(e%2.nodeType==1){";o=bd}else{if(!c)d+="if(e%2.nodeName=='%3'){"}return i(d,m++,x=m,b.toUpperCase())},"\\+(\\*|[\\w-]+)":function(a,b){var c="";if(o)c+="if(e%1.nodeName!='!'){";o=false;c+="e%1=IE7._a(e%1);if(e%1";if(b!="*")c+="&&e%1.nodeName=='%2'";c+="){";return i(c,m,b.toUpperCase())},"~(\\*|[\\w-]+)":function(a,b){var c="";if(o)c+="if(e%1.nodeName!='!'){";o=false;S=2;c+="while(e%1=e%1.nextSibling){if(e%1.ie7_adjacent==IE7._5)break;if(";if(b=="*"){c+="e%1.nodeType==1";if(bd)c+="&&e%1.nodeName!='!'"}else c+="e%1.nodeName=='%2'";c+="){e%1.ie7_adjacent=IE7._5;";return i(c,m,b.toUpperCase())},"#([\\w-]+)":function(a,b){o=false;var c="if(e%1.id=='%2'){";if(x)c+=i("i%1=n%1.length;",x);return i(c,m,b)},"\\.([\\w-]+)":function(a,b){o=false;F.push(new RegExp("(^|\\s)"+bb(b)+"(\\s|$)"));return i("if(e%1.className&®[%2].test(e%1.className)){",m,F.length-1)},"\\[([\\w-]+)\\s*([^=]?=)?\\s*([^\\]]*)\\]":function(a,b,c,d){var f=bu[b]||b;if(c){var g="e%1.getAttribute('%2',2)";if(!bO.test(b)){g="e%1.%3||"+g}b=i("("+g+")",m,b,f)}else{b=i("IE7._f(e%1,'%2')",m,b)}var h=bS[c||""]||"0";if(h&&h.source){F.push(new RegExp(i(h.source,bb(T.unescape(d)))));h="reg[%2].test(%1)";d=F.length-1}return"if("+i(h,b,d)+"){"},":+([\\w-]+)(\\(([^)]+)\\))?":function(a,b,c,d){b=bT[b];return"if("+(b?i(b,m,d||""):"0")+"){"}});var bY=/a(#[\w-]+)?(\.[\w-]+)?:(hover|active)/i;var bZ=/\s*\{\s*/,ca=/\s*\}\s*/,cb=/\s*\,\s*/;var cc=/(.*)(:first-(line|letter))/;var y=document.styleSheets;IE7.CSS=new(bM.extend({parser:new bH,screen:"",print:"",styles:[],rules:[],pseudoClasses:k<7?"first\\-child":"",dynamicPseudoClasses:{toString:function(){var a=[];for(var b in this)a.push(b);return a.join("|")}},init:function(){var a="^\x01$";var b="\\[class=?[^\\]]*\\]";var c=[];if(this.pseudoClasses)c.push(this.pseudoClasses);var d=this.dynamicPseudoClasses.toString();if(d)c.push(d);c=c.join("|");var f=k<7?["[>+~[(]|([:.])\\w+\\1"]:[b];if(c)f.push(":("+c+")");this.UNKNOWN=new RegExp(f.join("|")||a,"i");var g=k<7?["\\[[^\\]]+\\]|[^\\s(\\[]+\\s*[+~]"]:[b];var h=g.concat();if(c)h.push(":("+c+")");n.COMPLEX=new RegExp(h.join("|")||a,"ig");if(this.pseudoClasses)g.push(":("+this.pseudoClasses+")");L.COMPLEX=new RegExp(g.join("|")||a,"i");L.MATCH=new RegExp(d?"(.*):("+d+")(.*)":a,"i");this.createStyleSheet();this.refresh()},addEventHandler:function(){w.apply(null,arguments)},addFix:function(a,b){this.parser.add(a,b)},addRecalc:function(c,d,f,g){d=new RegExp("([{;\\s])"+c+"\\s*:\\s*"+d+"[^;}]*");var h=this.recalcs.length;if(g)g=c+":"+g;this.addFix(d,function(a,b){return(g?b+g:a)+";ie7-"+a.slice(1)+";ie7_recalc"+h+":1"});this.recalcs.push(arguments);return h},apply:function(){this.getInlineStyles();new bw("screen");this.trash()},createStyleSheet:function(){this.styleSheet=document.createStyleSheet();this.styleSheet.ie7=true;this.styleSheet.owningElement.ie7=true;this.styleSheet.cssText=G},getInlineStyles:function(){var a=document.getElementsByTagName("style"),b;for(var c=a.length-1;(b=a[c]);c--){if(!b.disabled&&!b.ie7){this.styles.push(b.innerHTML)}}},getText:function(a,b){try{var c=a.cssText}catch(e){c=""}if(H)c=cl(a.href,b)||c;return c},recalc:function(){this.screen.recalc();var a=/ie7_recalc\d+/g;var b=G.match(/[{,]/g).length;var c=b+(this.screen.cssText.match(/\{/g)||"").length;var d=this.styleSheet.rules,f;var g,h,p,t,q,j,u,l;for(q=b;q0&&n.CLASS.test(b)){b=b.replace(n.CLASS,"");d--}while(c>0&&n.TAG.test(b)){b=b.replace(n.TAG,"$1*");c--}b+="."+this.className;d=Math.min(d,2);c=Math.min(c,2);var f=-10*d-c;if(f>0){b=b+","+n.MAP[f]+" "+b}return b},remove:function(a){a.className=a.className.replace(this.MATCH,"$1")},toString:function(){return i("%1 {%2}",this.selectorText,this.cssText)}},{CHILD:/>/g,CLASS:/\.[\w-]+/,CLASSES:/[.:\[]/g,MULTI:/(\.[\w-]+)+/g,PREFIX:"ie7_class",TAG:/^\w+|([\s>+~])\w+/,TAGS:/^\w|[\s>+~]\w/g,MAP:{1:"html",2:"html body",10:".ie7_html",11:"html.ie7_html",12:"html.ie7_html body",20:".ie7_html .ie7_body",21:"html.ie7_html .ie7_body",22:"html.ie7_html body.ie7_body"}});var L=n.extend({constructor:function(a,b,c,d,f){this.attach=b||"*";this.dynamicPseudoClass=IE7.CSS.dynamicPseudoClasses[c];this.target=d;this.base(a,f)},recalc:function(){var a=B(this.attach),b;for(var c=0;b=a[c];c++){var d=this.target?B(this.target,b):[b];if(d.length)this.dynamicPseudoClass.apply(b,d,this)}}});var cd=z.extend({constructor:function(a,b){this.name=a;this.apply=b;this.instances={};IE7.CSS.dynamicPseudoClasses[a]=this},register:function(a){var b=a[2];a.id=b.id+a[0].uniqueID;if(!this.instances[a.id]){var c=a[1],d;for(d=0;d*:"+(b=="marginTop"?"first":"last")+"-child",a,true);if(d&&d.currentStyle.styleFloat=="none"&&IE7.hasLayout(d)){collapseMargin(d,b);margin=_9(a,a.currentStyle[b]);childMargin=_9(d,d.currentStyle[b]);if(margin<0||childMargin<0){a.runtimeStyle[b]=margin+childMargin}else{a.runtimeStyle[b]=Math.max(childMargin,margin)}d.runtimeStyle[b]="0px"}}};function _9(a,b){return b=="auto"?0:E(a,b)};var UNIT=/^[.\d][\w%]*$/,AUTO=/^(auto|0cm)$/;var applyWidth,applyHeight;IE7.Layout.borderBox=function(a){applyWidth(a);applyHeight(a)};var fixWidth=function(g){applyWidth=function(a){if(!J.test(a.currentStyle.width))h(a);collapseMargins(a)};function h(a,b){if(!a.runtimeStyle.fixedWidth){if(!b)b=a.currentStyle.width;a.runtimeStyle.fixedWidth=(UNIT.test(b))?Math.max(0,q(a,b)):b;K(a,"width",a.runtimeStyle.fixedWidth)}};function p(a){if(!bc(a)){var b=a.offsetParent;while(b&&!IE7.hasLayout(b))b=b.offsetParent}return(b||s).clientWidth};function t(a,b){if(J.test(b))return parseInt(parseFloat(b)/100*p(a));return E(a,b)};var q=function(a,b){var c=a.currentStyle["box-sizing"]=="border-box";var d=0;if(C&&!c)d+=j(a)+u(a,"padding");else if(!C&&c)d-=j(a)+u(a,"padding");return t(a,b)+d};function j(a){return a.offsetWidth-a.clientWidth};function u(a,b){return t(a,a.currentStyle[b+"Left"])+t(a,a.currentStyle[b+"Right"])};G+="*{minWidth:none;maxWidth:none;min-width:none;max-width:none}";layout.minWidth=function(a){if(a.currentStyle["min-width"]!=null){a.style.minWidth=a.currentStyle["min-width"]}if(R(arguments.callee,a,a.currentStyle.minWidth!="none")){layout.boxSizing(a);h(a);l(a)}};eval("IE7.Layout.maxWidth="+String(layout.minWidth).replace(/min/g,"max"));function l(a){var b=a.getBoundingClientRect();var c=b.right-b.left;if(a.currentStyle.minWidth!="none"&&c<=q(a,a.currentStyle.minWidth)){a.runtimeStyle.width=a.currentStyle.minWidth}else if(a.currentStyle.maxWidth!="none"&&c>=q(a,a.currentStyle.maxWidth)){a.runtimeStyle.width=a.currentStyle.maxWidth}else{a.runtimeStyle.width=a.runtimeStyle.fixedWidth}};function r(a){if(R(r,a,/^(fixed|absolute)$/.test(a.currentStyle.position)&&bt(a,"left")!="auto"&&bt(a,"right")!="auto"&&AUTO.test(bt(a,"width")))){N(a);IE7.Layout.boxSizing(a)}};IE7.Layout.fixRight=r;function N(a){var b=t(a,a.runtimeStyle._c||a.currentStyle.left);var c=p(a)-t(a,a.currentStyle.right)-b-u(a,"margin");if(parseInt(a.runtimeStyle.width)==c)return;a.runtimeStyle.width="";if(bc(a)||g||a.offsetWidth=5.5&&k<7){IE7.CSS.addFix(/background(-image)?\s*:\s*([^};]*)?url\(([^\)]+)\)([^;}]*)?/,function(a,b,c,d,f){d=cC(d);return bi.test(d)?"filter:"+i(bx,d,"crop")+";zoom:1;background"+(b||"")+":"+(c||"")+"none"+(f||""):a});IE7.HTML.addRecalc("img,input",function(a){if(a.tagName=="INPUT"&&a.type!="image")return;by(a);w(a,"onpropertychange",function(){if(!bj&&event.propertyName=="src"&&a.src.indexOf(bg)==-1)by(a)})});var bj=false;w(window,"onbeforeprint",function(){bj=true;for(var a=0;a=7)return;IE7.CSS.addRecalc("position","fixed",_6,"absolute");IE7.CSS.addRecalc("background(-attachment)?","[^};]*fixed",_2);var $viewport=C?"body":"documentElement";function _3(){if(v.currentStyle.backgroundAttachment!="fixed"){if(v.currentStyle.backgroundImage=="none"){v.runtimeStyle.backgroundRepeat="no-repeat";v.runtimeStyle.backgroundImage="url("+bg+")"}v.runtimeStyle.backgroundAttachment="fixed"}_3=Q};var _0=bN("img");function _1(a){return a?bc(a)||_1(a.parentElement):false};function _d(a,b,c){setTimeout("document.all."+a.uniqueID+".runtimeStyle.setExpression('"+b+"','"+c+"')",0)};function _2(a){if(R(_2,a,a.currentStyle.backgroundAttachment=="fixed"&&!a.contains(v))){_3();bgLeft(a);bgTop(a);_8(a)}};function _8(a){_0.src=a.currentStyle.backgroundImage.slice(5,-2);var b=a.canHaveChildren?a:a.parentElement;b.appendChild(_0);setOffsetLeft(a);setOffsetTop(a);b.removeChild(_0)};function bgLeft(a){a.style.backgroundPositionX=a.currentStyle.backgroundPositionX;if(!_1(a)){_d(a,"backgroundPositionX","(parseInt(runtimeStyle.offsetLeft)+document."+$viewport+".scrollLeft)||0")}};eval(A(bgLeft));function setOffsetLeft(a){var b=_1(a)?"backgroundPositionX":"offsetLeft";a.runtimeStyle[b]=getOffsetLeft(a,a.style.backgroundPositionX)-a.getBoundingClientRect().left-a.clientLeft+2};eval(A(setOffsetLeft));function getOffsetLeft(a,b){switch(b){case"left":case"top":return 0;case"right":case"bottom":return s.clientWidth-_0.offsetWidth;case"center":return(s.clientWidth-_0.offsetWidth)/2;default:if(J.test(b)){return parseInt((s.clientWidth-_0.offsetWidth)*parseFloat(b)/100)}_0.style.left=b;return _0.offsetLeft}};eval(A(getOffsetLeft));function _6(a){if(R(_6,a,bc(a))){K(a,"position","absolute");K(a,"left",a.currentStyle.left);K(a,"top",a.currentStyle.top);_3();IE7.Layout.fixRight(a);_4(a)}};function _4(a,b){positionTop(a,b);positionLeft(a,b,true);if(!a.runtimeStyle.autoLeft&&a.currentStyle.marginLeft=="auto"&&a.currentStyle.right!="auto"){var c=s.clientWidth-getPixelWidth(a,a.currentStyle.right)-getPixelWidth(a,a.runtimeStyle._c)-a.clientWidth;if(a.currentStyle.marginRight=="auto")c=parseInt(c/2);if(_1(a.offsetParent))a.runtimeStyle.pixelLeft+=c;else a.runtimeStyle.shiftLeft=c}clipWidth(a);clipHeight(a)};function clipWidth(a){var b=a.runtimeStyle.fixWidth;a.runtimeStyle.borderRightWidth="";a.runtimeStyle.width=b?getPixelWidth(a,b):"";if(a.currentStyle.width!="auto"){var c=a.getBoundingClientRect();var d=a.offsetWidth-s.clientWidth+c.left-2;if(d>=0){a.runtimeStyle.borderRightWidth="0px";d=Math.max(E(a,a.currentStyle.width)-d,0);K(a,"width",d);return d}}};eval(A(clipWidth));function positionLeft(a,b){if(!b&&J.test(a.currentStyle.width)){a.runtimeStyle.fixWidth=a.currentStyle.width}if(a.runtimeStyle.fixWidth){a.runtimeStyle.width=getPixelWidth(a,a.runtimeStyle.fixWidth)}a.runtimeStyle.shiftLeft=0;a.runtimeStyle._c=a.currentStyle.left;a.runtimeStyle.autoLeft=a.currentStyle.right!="auto"&&a.currentStyle.left=="auto";a.runtimeStyle.left="";a.runtimeStyle.screenLeft=getScreenLeft(a);a.runtimeStyle.pixelLeft=a.runtimeStyle.screenLeft;if(!b&&!_1(a.offsetParent)){_d(a,"pixelLeft","runtimeStyle.screenLeft+runtimeStyle.shiftLeft+document."+$viewport+".scrollLeft")}};eval(A(positionLeft));function getScreenLeft(a){var b=a.offsetLeft,c=1;if(a.runtimeStyle.autoLeft){b=s.clientWidth-a.offsetWidth-getPixelWidth(a,a.currentStyle.right)}if(a.currentStyle.marginLeft!="auto"){b-=getPixelWidth(a,a.currentStyle.marginLeft)}while(a=a.offsetParent){if(a.currentStyle.position!="static")c=-1;b+=a.offsetLeft*c}return b};eval(A(getScreenLeft));function getPixelWidth(a,b){return J.test(b)?parseInt(parseFloat(b)/100*s.clientWidth):E(a,b)};eval(A(getPixelWidth));function _g(){var a=_2.elements;for(var b in a)_8(a[b]);a=_6.elements;for(b in a){_4(a[b],true);_4(a[b],true)}_7=0};var _7;bq(function(){if(!_7)_7=setTimeout(_g,0)})};var bk={backgroundColor:"transparent",backgroundImage:"none",backgroundPositionX:null,backgroundPositionY:null,backgroundRepeat:null,borderTopWidth:0,borderRightWidth:0,borderBottomWidth:0,borderLeftStyle:"none",borderTopStyle:"none",borderRightStyle:"none",borderBottomStyle:"none",borderLeftWidth:0,height:null,marginTop:0,marginBottom:0,marginRight:0,marginLeft:0,width:"100%"};IE7.CSS.addRecalc("overflow","visible",function(a){if(a.parentNode.ie7_wrapped)return;if(IE7.Layout&&a.currentStyle["max-height"]!="auto"){IE7.Layout.maxHeight(a)}if(a.currentStyle.marginLeft=="auto")a.style.marginLeft=0;if(a.currentStyle.marginRight=="auto")a.style.marginRight=0;var b=document.createElement(bA);b.ie7_wrapped=a;for(var c in bk){b.style[c]=a.currentStyle[c];if(bk[c]!=null){a.runtimeStyle[c]=bk[c]}}b.style.display="block";b.style.position="relative";a.runtimeStyle.position="absolute";a.parentNode.insertBefore(b,a);b.appendChild(a)});function cf(){var f="xx-small,x-small,small,medium,large,x-large,xx-large".split(",");for(var g=0;g":"","\\/\\*[^*]*\\*+([^\\/][^*]*\\*+)*\\/":"","@(namespace|import)[^;\\n]+[;\\n]":"","'(\\\\.|[^'\\\\])*'":bW,'"(\\\\.|[^"\\\\])*"':bW,"\\s+":" "});function cS(a){return bV.exec(a)};function bg(c){return c.replace(cO,function(a,b){return bA[b-1]})};function bW(c){return"\x01"+bA.push(c.replace(cR,function(a,b){return eval("'\\u"+"0000".slice(b.length)+b+"'")}).slice(1,-1).replace(cP,"\\'"))};function bB(a){return cQ.test(a)?bA[a.slice(1)-1]:a};var cT=new H({Width:"Height",width:"height",Left:"Top",left:"top",Right:"Bottom",right:"bottom",onX:"onY"});function C(a){return cT.exec(a)};var bX=[];function bC(a){cV(a);v(window,"onresize",a)};function v(a,b,c){a.attachEvent(b,c);bX.push(arguments)};function cU(a,b,c){try{a.detachEvent(b,c)}catch(ignore){}};v(window,"onunload",function(){var a;while(a=bX.pop()){cU(a[0],a[1],a[2])}});function X(a,b,c){if(!a.elements)a.elements={};if(c)a.elements[b.uniqueID]=b;else delete a.elements[b.uniqueID];return c};v(window,"onbeforeprint",function(){if(!IE7.CSS.print)new bJ("print");IE7.CSS.print.recalc()});var bY=/^\d+(px)?$/i;var M=/^\d+%$/;var D=function(a,b){if(bY.test(b))return parseInt(b);var c=a.style.left;var d=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;a.style.left=b||0;b=a.style.pixelLeft;a.style.left=c;a.runtimeStyle.left=d;return b};var bD="ie7-";var bZ=B.extend({constructor:function(){this.fixes=[];this.recalcs=[]},init:U});var bE=[];function cV(a){bE.push(a)};IE7.recalc=function(){IE7.HTML.recalc();IE7.CSS.recalc();for(var a=0;a1?2:0;var h=E.exec(f[g])||"if(0){";if(p){h+=i("if(e%1.nodeName!='!'){",l)}var j=Y>1?ch:"";h+=i(j+ci,l);h+=Array(L(h,/\{/g).length+1).join("}");d+=h}eval(i(cj,I)+E.unescape(d)+"return s?null:r}");bj[a]=_k}return bj[a](b||document,c)};var bi=m<6;var cb=/^(href|src)$/;var bG={"class":"className","for":"htmlFor"};IE7._1=1;IE7._e=function(a,b){var c=a.all[b]||null;if(!c||c.id==b)return c;for(var d=0;d+~,]|[^(]\+|^)([#.:\[])/g,cX=/(^|,)([^\s>+~])/g,cY=/\s*([\s>+~(),]|^|$)\s*/g,cd=/\s\*\s/g;var ce=H.extend({constructor:function(a){this.base(a);this.sorter=new H;this.sorter.add(/:not\([^)]*\)/,H.IGNORE);this.sorter.add(/([ >](\*|[\w-]+))([^: >+~]*)(:\w+-child(\([^)]+\))?)([^: >+~]*)/,"$1$3$6$4")},ignoreCase:true,escape:function(a){return this.optimise(this.format(a))},format:function(a){return a.replace(cY,"$1").replace(cX,"$1 $2").replace(cW,"$1*$2")},optimise:function(a){return this.sorter.exec(a.replace(cd,">* "))},unescape:function(a){return bg(a)}});var cf={"":"%1!=null","=":"%1=='%2'","~=":/(^| )%1( |$)/,"|=":/^%1(-|$)/,"^=":/^%1/,"$=":/%1$/,"*=":/%1/};var bH={"first-child":"!IE7._4(e%1)","link":"e%1.currentStyle['ie7-link']=='link'","visited":"e%1.currentStyle['ie7-link']=='visited'"};var bI="var p%2=0,i%2,e%2,n%2=e%1.";var cg="e%1.sourceIndex";var ch="var g="+cg+";if(!p[g]){p[g]=1;";var ci="r[r.length]=e%1;if(s)return e%1;";var cj="var _k=function(e0,s){IE7._1++;var r=[],p={},reg=[%1],d=document;";var I;var l;var p;var y;var Y;var bj={};var E=new ce({" (\\*|[\\w-]+)#([\\w-]+)":function(a,b,c){p=false;var d="var e%2=IE7._e(d,'%4');if(e%2&&";if(b!="*")d+="e%2.nodeName=='%3'&&";d+="(e%1==d||e%1.contains(e%2))){";if(y)d+=i("i%1=n%1.length;",y);return i(d,l++,l,b.toUpperCase(),c)}," (\\*|[\\w-]+)":function(a,b){Y++;p=b=="*";var c=bI;c+=(p&&bi)?"all":"getElementsByTagName('%3')";c+=";for(i%2=0;(e%2=n%2[i%2]);i%2++){";return i(c,l++,y=l,b.toUpperCase())},">(\\*|[\\w-]+)":function(a,b){var c=y;p=b=="*";var d=bI;d+=c?"children":"childNodes";if(!p&&c)d+=".tags('%3')";d+=";for(i%2=0;(e%2=n%2[i%2]);i%2++){";if(p){d+="if(e%2.nodeType==1){";p=bi}else{if(!c)d+="if(e%2.nodeName=='%3'){"}return i(d,l++,y=l,b.toUpperCase())},"\\+(\\*|[\\w-]+)":function(a,b){var c="";if(p)c+="if(e%1.nodeName!='!'){";p=false;c+="e%1=IE7._3(e%1);if(e%1";if(b!="*")c+="&&e%1.nodeName=='%2'";c+="){";return i(c,l,b.toUpperCase())},"~(\\*|[\\w-]+)":function(a,b){var c="";if(p)c+="if(e%1.nodeName!='!'){";p=false;Y=2;c+="while(e%1=e%1.nextSibling){if(e%1.ie7_adjacent==IE7._1)break;if(";if(b=="*"){c+="e%1.nodeType==1";if(bi)c+="&&e%1.nodeName!='!'"}else c+="e%1.nodeName=='%2'";c+="){e%1.ie7_adjacent=IE7._1;";return i(c,l,b.toUpperCase())},"#([\\w-]+)":function(a,b){p=false;var c="if(e%1.id=='%2'){";if(y)c+=i("i%1=n%1.length;",y);return i(c,l,b)},"\\.([\\w-]+)":function(a,b){p=false;I.push(new RegExp("(^|\\s)"+W(b)+"(\\s|$)"));return i("if(e%1.className&®[%2].test(e%1.className)){",l,I.length-1)},"\\[([\\w-]+)\\s*([^=]?=)?\\s*([^\\]]*)\\]":function(a,b,c,d){var f=bG[b]||b;if(c){var g="e%1.getAttribute('%2',2)";if(!cb.test(b)){g="e%1.%3||"+g}b=i("("+g+")",l,b,f)}else{b=i("IE7._f(e%1,'%2')",l,b)}var h=cf[c||""]||"0";if(h&&h.source){I.push(new RegExp(i(h.source,W(E.unescape(d)))));h="reg[%2].test(%1)";d=I.length-1}return"if("+i(h,b,d)+"){"},":+([\\w-]+)(\\(([^)]+)\\))?":function(a,b,c,d){b=bH[b];return"if("+(b?i(b,l,d||""):"0")+"){"}});var ck=/a(#[\w-]+)?(\.[\w-]+)?:(hover|active)/i;var cl=/\s*\{\s*/,cm=/\s*\}\s*/,cn=/\s*\,\s*/;var co=/(.*)(:first-(line|letter))/;var z=document.styleSheets;IE7.CSS=new(bZ.extend({parser:new bU,screen:"",print:"",styles:[],rules:[],pseudoClasses:m<7?"first\\-child":"",dynamicPseudoClasses:{toString:function(){var a=[];for(var b in this)a.push(b);return a.join("|")}},init:function(){var a="^\x01$";var b="\\[class=?[^\\]]*\\]";var c=[];if(this.pseudoClasses)c.push(this.pseudoClasses);var d=this.dynamicPseudoClasses.toString();if(d)c.push(d);c=c.join("|");var f=m<7?["[>+~[(]|([:.])\\w+\\1"]:[b];if(c)f.push(":("+c+")");this.UNKNOWN=new RegExp(f.join("|")||a,"i");var g=m<7?["\\[[^\\]]+\\]|[^\\s(\\[]+\\s*[+~]"]:[b];var h=g.concat();if(c)h.push(":("+c+")");o.COMPLEX=new RegExp(h.join("|")||a,"ig");if(this.pseudoClasses)g.push(":("+this.pseudoClasses+")");O.COMPLEX=new RegExp(g.join("|")||a,"i");O.MATCH=new RegExp(d?"(.*):("+d+")(.*)":a,"i");this.createStyleSheet();this.refresh()},addEventHandler:function(){v.apply(null,arguments)},addFix:function(a,b){this.parser.add(a,b)},addRecalc:function(c,d,f,g){d=new RegExp("([{;\\s])"+c+"\\s*:\\s*"+d+"[^;}]*");var h=this.recalcs.length;if(g)g=c+":"+g;this.addFix(d,function(a,b){return(g?b+g:a)+";ie7-"+a.slice(1)+";ie7_recalc"+h+":1"});this.recalcs.push(arguments);return h},apply:function(){this.getInlineStyles();new bJ("screen");this.trash()},createStyleSheet:function(){this.styleSheet=document.createStyleSheet();this.styleSheet.ie7=true;this.styleSheet.owningElement.ie7=true;this.styleSheet.cssText=J},getInlineStyles:function(){var a=document.getElementsByTagName("style"),b;for(var c=a.length-1;(b=a[c]);c--){if(!b.disabled&&!b.ie7){this.styles.push(b.innerHTML)}}},getText:function(a,b){try{var c=a.cssText}catch(e){c=""}if(K)c=cD(a.href,b)||c;return c},recalc:function(){this.screen.recalc();var a=/ie7_recalc\d+/g;var b=J.match(/[{,]/g).length;var c=b+(this.screen.cssText.match(/\{/g)||"").length;var d=this.styleSheet.rules,f;var g,h,j,q,r,k,u,n;for(r=b;r0&&o.CLASS.test(b)){b=b.replace(o.CLASS,"");d--}while(c>0&&o.TAG.test(b)){b=b.replace(o.TAG,"$1*");c--}b+="."+this.className;d=Math.min(d,2);c=Math.min(c,2);var f=-10*d-c;if(f>0){b=b+","+o.MAP[f]+" "+b}return b},remove:function(a){a.className=a.className.replace(this.MATCH,"$1")},toString:function(){return i("%1 {%2}",this.selectorText,this.cssText)}},{CHILD:/>/g,CLASS:/\.[\w-]+/,CLASSES:/[.:\[]/g,MULTI:/(\.[\w-]+)+/g,PREFIX:"ie7_class",TAG:/^\w+|([\s>+~])\w+/,TAGS:/^\w|[\s>+~]\w/g,MAP:{1:"html",2:"html body",10:".ie7_html",11:"html.ie7_html",12:"html.ie7_html body",20:".ie7_html .ie7_body",21:"html.ie7_html .ie7_body",22:"html.ie7_html body.ie7_body"}});var O=o.extend({constructor:function(a,b,c,d,f){this.attach=b||"*";this.dynamicPseudoClass=IE7.CSS.dynamicPseudoClasses[c];this.target=d;this.base(a,f)},recalc:function(){var a=x(this.attach),b;for(var c=0;b=a[c];c++){var d=this.target?x(this.target,b):[b];if(d.length)this.dynamicPseudoClass.apply(b,d,this)}}});var A=B.extend({constructor:function(a,b){this.name=a;this.apply=b;this.instances={};IE7.CSS.dynamicPseudoClasses[a]=this},register:function(a){var b=a[2];a.id=b.id+a[0].uniqueID;if(!this.instances[a.id]){var c=a[1],d;for(d=0;d*:"+(b=="marginTop"?"first":"last")+"-child",a,true);if(d&&d.currentStyle.styleFloat=="none"&&IE7.hasLayout(d)){collapseMargin(d,b);margin=_b(a,a.currentStyle[b]);childMargin=_b(d,d.currentStyle[b]);if(margin<0||childMargin<0){a.runtimeStyle[b]=margin+childMargin}else{a.runtimeStyle[b]=Math.max(childMargin,margin)}d.runtimeStyle[b]="0px"}}};function _b(a,b){return b=="auto"?0:D(a,b)};var UNIT=/^[.\d][\w%]*$/,AUTO=/^(auto|0cm)$/;var applyWidth,applyHeight;IE7.Layout.borderBox=function(a){applyWidth(a);applyHeight(a)};var fixWidth=function(g){applyWidth=function(a){if(!M.test(a.currentStyle.width))h(a);collapseMargins(a)};function h(a,b){if(!a.runtimeStyle.fixedWidth){if(!b)b=a.currentStyle.width;a.runtimeStyle.fixedWidth=(UNIT.test(b))?Math.max(0,r(a,b)):b;N(a,"width",a.runtimeStyle.fixedWidth)}};function j(a){if(!bh(a)){var b=a.offsetParent;while(b&&!IE7.hasLayout(b))b=b.offsetParent}return(b||t).clientWidth};function q(a,b){if(M.test(b))return parseInt(parseFloat(b)/100*j(a));return D(a,b)};var r=function(a,b){var c=a.currentStyle["box-sizing"]=="border-box";var d=0;if(G&&!c)d+=k(a)+u(a,"padding");else if(!G&&c)d-=k(a)+u(a,"padding");return q(a,b)+d};function k(a){return a.offsetWidth-a.clientWidth};function u(a,b){return q(a,a.currentStyle[b+"Left"])+q(a,a.currentStyle[b+"Right"])};J+="*{minWidth:none;maxWidth:none;min-width:none;max-width:none}";layout.minWidth=function(a){if(a.currentStyle["min-width"]!=null){a.style.minWidth=a.currentStyle["min-width"]}if(X(arguments.callee,a,a.currentStyle.minWidth!="none")){layout.boxSizing(a);h(a);n(a)}};eval("IE7.Layout.maxWidth="+String(layout.minWidth).replace(/min/g,"max"));function n(a){var b=a.getBoundingClientRect();var c=b.right-b.left;if(a.currentStyle.minWidth!="none"&&c<=r(a,a.currentStyle.minWidth)){a.runtimeStyle.width=a.currentStyle.minWidth}else if(a.currentStyle.maxWidth!="none"&&c>=r(a,a.currentStyle.maxWidth)){a.runtimeStyle.width=a.currentStyle.maxWidth}else{a.runtimeStyle.width=a.runtimeStyle.fixedWidth}};function s(a){if(X(s,a,/^(fixed|absolute)$/.test(a.currentStyle.position)&&bF(a,"left")!="auto"&&bF(a,"right")!="auto"&&AUTO.test(bF(a,"width")))){R(a);IE7.Layout.boxSizing(a)}};IE7.Layout.fixRight=s;function R(a){var b=q(a,a.runtimeStyle._c||a.currentStyle.left);var c=j(a)-q(a,a.currentStyle.right)-b-u(a,"margin");if(parseInt(a.runtimeStyle.width)==c)return;a.runtimeStyle.width="";if(bh(a)||g||a.offsetWidth=5.5&&m<7){IE7.CSS.addFix(/background(-image)?\s*:\s*([^};]*)?url\(([^\)]+)\)([^;}]*)?/,function(a,b,c,d,f){d=bB(d);return bm.test(d)?"filter:"+i(bK,d,"crop")+";zoom:1;background"+(b||"")+":"+(c||"")+"none"+(f||""):a});IE7.HTML.addRecalc("img,input",function(a){if(a.tagName=="INPUT"&&a.type!="image")return;bL(a);v(a,"onpropertychange",function(){if(!bn&&event.propertyName=="src"&&a.src.indexOf(bk)==-1)bL(a)})});var bn=false;v(window,"onbeforeprint",function(){bn=true;for(var a=0;a=7)return;IE7.CSS.addRecalc("position","fixed",_8,"absolute");IE7.CSS.addRecalc("background(-attachment)?","[^};]*fixed",_5);var $viewport=G?"body":"documentElement";function _6(){if(w.currentStyle.backgroundAttachment!="fixed"){if(w.currentStyle.backgroundImage=="none"){w.runtimeStyle.backgroundRepeat="no-repeat";w.runtimeStyle.backgroundImage="url("+bk+")"}w.runtimeStyle.backgroundAttachment="fixed"}_6=U};var _0=ca("img");function _2(a){return a?bh(a)||_2(a.parentElement):false};function _d(a,b,c){setTimeout("document.all."+a.uniqueID+".runtimeStyle.setExpression('"+b+"','"+c+"')",0)};function _5(a){if(X(_5,a,a.currentStyle.backgroundAttachment=="fixed"&&!a.contains(w))){_6();bgLeft(a);bgTop(a);_a(a)}};function _a(a){_0.src=a.currentStyle.backgroundImage.slice(5,-2);var b=a.canHaveChildren?a:a.parentElement;b.appendChild(_0);setOffsetLeft(a);setOffsetTop(a);b.removeChild(_0)};function bgLeft(a){a.style.backgroundPositionX=a.currentStyle.backgroundPositionX;if(!_2(a)){_d(a,"backgroundPositionX","(parseInt(runtimeStyle.offsetLeft)+document."+$viewport+".scrollLeft)||0")}};eval(C(bgLeft));function setOffsetLeft(a){var b=_2(a)?"backgroundPositionX":"offsetLeft";a.runtimeStyle[b]=getOffsetLeft(a,a.style.backgroundPositionX)-a.getBoundingClientRect().left-a.clientLeft+2};eval(C(setOffsetLeft));function getOffsetLeft(a,b){switch(b){case"left":case"top":return 0;case"right":case"bottom":return t.clientWidth-_0.offsetWidth;case"center":return(t.clientWidth-_0.offsetWidth)/2;default:if(M.test(b)){return parseInt((t.clientWidth-_0.offsetWidth)*parseFloat(b)/100)}_0.style.left=b;return _0.offsetLeft}};eval(C(getOffsetLeft));function _8(a){if(X(_8,a,bh(a))){N(a,"position","absolute");N(a,"left",a.currentStyle.left);N(a,"top",a.currentStyle.top);_6();IE7.Layout.fixRight(a);_7(a)}};function _7(a,b){positionTop(a,b);positionLeft(a,b,true);if(!a.runtimeStyle.autoLeft&&a.currentStyle.marginLeft=="auto"&&a.currentStyle.right!="auto"){var c=t.clientWidth-getPixelWidth(a,a.currentStyle.right)-getPixelWidth(a,a.runtimeStyle._c)-a.clientWidth;if(a.currentStyle.marginRight=="auto")c=parseInt(c/2);if(_2(a.offsetParent))a.runtimeStyle.pixelLeft+=c;else a.runtimeStyle.shiftLeft=c}clipWidth(a);clipHeight(a)};function clipWidth(a){var b=a.runtimeStyle.fixWidth;a.runtimeStyle.borderRightWidth="";a.runtimeStyle.width=b?getPixelWidth(a,b):"";if(a.currentStyle.width!="auto"){var c=a.getBoundingClientRect();var d=a.offsetWidth-t.clientWidth+c.left-2;if(d>=0){a.runtimeStyle.borderRightWidth="0px";d=Math.max(D(a,a.currentStyle.width)-d,0);N(a,"width",d);return d}}};eval(C(clipWidth));function positionLeft(a,b){if(!b&&M.test(a.currentStyle.width)){a.runtimeStyle.fixWidth=a.currentStyle.width}if(a.runtimeStyle.fixWidth){a.runtimeStyle.width=getPixelWidth(a,a.runtimeStyle.fixWidth)}a.runtimeStyle.shiftLeft=0;a.runtimeStyle._c=a.currentStyle.left;a.runtimeStyle.autoLeft=a.currentStyle.right!="auto"&&a.currentStyle.left=="auto";a.runtimeStyle.left="";a.runtimeStyle.screenLeft=getScreenLeft(a);a.runtimeStyle.pixelLeft=a.runtimeStyle.screenLeft;if(!b&&!_2(a.offsetParent)){_d(a,"pixelLeft","runtimeStyle.screenLeft+runtimeStyle.shiftLeft+document."+$viewport+".scrollLeft")}};eval(C(positionLeft));function getScreenLeft(a){var b=a.offsetLeft,c=1;if(a.runtimeStyle.autoLeft){b=t.clientWidth-a.offsetWidth-getPixelWidth(a,a.currentStyle.right)}if(a.currentStyle.marginLeft!="auto"){b-=getPixelWidth(a,a.currentStyle.marginLeft)}while(a=a.offsetParent){if(a.currentStyle.position!="static")c=-1;b+=a.offsetLeft*c}return b};eval(C(getScreenLeft));function getPixelWidth(a,b){return M.test(b)?parseInt(parseFloat(b)/100*t.clientWidth):D(a,b)};eval(C(getPixelWidth));function _j(){var a=_5.elements;for(var b in a)_a(a[b]);a=_8.elements;for(b in a){_7(a[b],true);_7(a[b],true)}_9=0};var _9;bC(function(){if(!_9)_9=setTimeout(_j,0)})};var bp={backgroundColor:"transparent",backgroundImage:"none",backgroundPositionX:null,backgroundPositionY:null,backgroundRepeat:null,borderTopWidth:0,borderRightWidth:0,borderBottomWidth:0,borderLeftStyle:"none",borderTopStyle:"none",borderRightStyle:"none",borderBottomStyle:"none",borderLeftWidth:0,height:null,marginTop:0,marginBottom:0,marginRight:0,marginLeft:0,width:"100%"};IE7.CSS.addRecalc("overflow","visible",function(a){if(a.parentNode.ie7_wrapped)return;if(IE7.Layout&&a.currentStyle["max-height"]!="auto"){IE7.Layout.maxHeight(a)}if(a.currentStyle.marginLeft=="auto")a.style.marginLeft=0;if(a.currentStyle.marginRight=="auto")a.style.marginRight=0;var b=document.createElement(bN);b.ie7_wrapped=a;for(var c in bp){b.style[c]=a.currentStyle[c];if(bp[c]!=null){a.runtimeStyle[c]=bp[c]}}b.style.display="block";b.style.position="relative";a.runtimeStyle.position="absolute";a.parentNode.insertBefore(b,a);b.appendChild(a)});function cq(){var f="xx-small,x-small,small,medium,large,x-large,xx-large".split(",");for(var g=0;g=%2",f,g,c,d,"&&","%","==");if(h)j="!("+j+")";return j};bH={"link":"e%1.currentStyle['ie7-link']=='link'","visited":"e%1.currentStyle['ie7-link']=='visited'","checked":"e%1.checked","contains":"e%1.innerText.indexOf('%2')!=-1","disabled":"e%1.isDisabled","empty":"IE7._g(e%1)","enabled":"e%1.disabled===false","first-child":"!IE7._4(e%1)","lang":"IE7._h(e%1,'%2')","last-child":"!IE7._3(e%1)","only-child":"!IE7._4(e%1)&&!IE7._3(e%1)","target":"e%1.id==location.hash.slice(1)","indeterminate":"e%1.indeterminate"};IE7._i=function(a){if(a.rows){a.ie7_length=a.rows.length;a.ie7_lookup="rowIndex"}else if(a.cells){a.ie7_length=a.cells.length;a.ie7_lookup="cellIndex"}else if(a.ie7_indexed!=IE7._1){var b=0;var c=a.firstChild;while(c){if(c.nodeType==1&&c.nodeName!="!"){c.ie7_index=++b}c=c.nextSibling}a.ie7_length=b;a.ie7_lookup="ie7_index"}a.ie7_indexed=IE7._1;return a};var ba=E[V];var cs=ba[ba.length-1];ba.length--;E.merge({":not\\((\\*|[\\w-]+)?([^)]*)\\)":function(a,b,c){var d=(b&&b!="*")?i("if(e%1.nodeName=='%2'){",l,b.toUpperCase()):"";d+=E.exec(c);return"if(!"+d.slice(2,-1).replace(/\)\{if\(/g,"&&")+"){"},":nth(-last)?-child\\(([^)]+)\\)":function(a,b,c){p=false;b=i("e%1.parentNode.ie7_length",l);var d="if(p%1!==e%1.parentNode)p%1=IE7._i(e%1.parentNode);";d+="var i=e%1[p%1.ie7_lookup];if(p%1.ie7_lookup!='ie7_index')i++;if(";return i(d,l)+cr(a,c,"i",b)+"){"}});ba.push(cs);var bM="\\([^)]*\\)";if(IE7.CSS.pseudoClasses)IE7.CSS.pseudoClasses+="|";IE7.CSS.pseudoClasses+="before|after|last\\-child|only\\-child|empty|root|"+"not|nth\\-child|nth\\-last\\-child|contains|lang".split("|").join(bM+"|")+bM;bV.add(/::/,":");var bb=new A("focus",function(a){var b=arguments;IE7.CSS.addEventHandler(a,"onfocus",function(){bb.unregister(b);bb.register(b)});IE7.CSS.addEventHandler(a,"onblur",function(){bb.unregister(b)});if(a==document.activeElement){bb.register(b)}});var bq=new A("active",function(a){var b=arguments;IE7.CSS.addEventHandler(a,"onmousedown",function(){bq.register(b)})});v(document,"onmouseup",function(){var a=bq.instances;for(var b in a)bq.unregister(a[b])});var br=new A("checked",function(a){if(typeof a.checked!="boolean")return;var b=arguments;IE7.CSS.addEventHandler(a,"onpropertychange",function(){if(event.propertyName=="checked"){if(a.checked)br.register(b);else br.unregister(b)}});if(a.checked)br.register(b)});var bs=new A("enabled",function(a){if(typeof a.disabled!="boolean")return;var b=arguments;IE7.CSS.addEventHandler(a,"onpropertychange",function(){if(event.propertyName=="disabled"){if(!a.isDisabled)bs.register(b);else bs.unregister(b)}});if(!a.isDisabled)bs.register(b)});var bt=new A("disabled",function(a){if(typeof a.disabled!="boolean")return;var b=arguments;IE7.CSS.addEventHandler(a,"onpropertychange",function(){if(event.propertyName=="disabled"){if(a.isDisabled)bt.register(b);else bt.unregister(b)}});if(a.isDisabled)bt.register(b)});var bu=new A("indeterminate",function(a){if(typeof a.indeterminate!="boolean")return;var b=arguments;IE7.CSS.addEventHandler(a,"onpropertychange",function(){if(event.propertyName=="indeterminate"){if(a.indeterminate)bu.register(b);else bu.unregister(b)}});IE7.CSS.addEventHandler(a,"onclick",function(){bu.unregister(b)})});var bv=new A("target",function(a){var b=arguments;if(!a.tabIndex)a.tabIndex=0;IE7.CSS.addEventHandler(document,"onpropertychange",function(){if(event.propertyName=="activeElement"){if(a.id&&a.id==location.hash.slice(1))bv.register(b);else bv.unregister(b)}});if(a.id&&a.id==location.hash.slice(1))bv.register(b)});var ct=/^attr/;var cu=/^url\s*\(\s*([^)]*)\)$/;var cv={before0:"beforeBegin",before1:"afterBegin",after0:"afterEnd",after1:"beforeEnd"};var F=IE7.PseudoElement=o.extend({constructor:function(a,b,c){this.position=b;var d=c.match(F.CONTENT),f,g;if(d){d=d[1];f=d.split(/\s+/);for(var h=0;(g=f[h]);h++){f[h]=ct.test(g)?{attr:g.slice(5,-1)}:(g.charAt(0)=="'")?bB(g):bg(g)}d=f}this.content=d;this.base(a,bg(c))},init:function(){this.match=x(this.selector);for(var a=0;a%4",MATCH:/(.*):(before|after).*/,count:0});var cw=/^(submit|reset|button)$/;IE7.HTML.addRecalc("button,input",function(a){if(a.tagName=="BUTTON"){var b=a.outerHTML.match(/ value="([^"]*)"/i);a.runtimeStyle.value=(b)?b[1]:""}if(a.type=="submit"){v(a,"onclick",function(){a.runtimeStyle.clicked=true;setTimeout("document.all."+a.uniqueID+".runtimeStyle.clicked=false",1)})}});IE7.HTML.addRecalc("form",function(c){v(c,"onsubmit",function(){for(var a,b=0;a=c[b];b++){if(cw.test(a.type)&&!a.disabled&&!a.runtimeStyle.clicked){a.disabled=true;setTimeout("document.all."+a.uniqueID+".disabled=false",1)}else if(a.tagName=="BUTTON"&&a.type=="submit"){setTimeout("document.all."+a.uniqueID+".value='"+a.value+"'",1);a.value=a.runtimeStyle.value}}})});IE7.HTML.addRecalc("img",function(a){if(a.alt&&!a.title)a.title=""});IE7.CSS.addRecalc("border-spacing",P,function(a){if(a.currentStyle.borderCollapse!="collapse"){a.cellSpacing=D(a,a.currentStyle["border-spacing"])}});IE7.CSS.addRecalc("box-sizing","content-box",IE7.Layout.boxSizing);IE7.CSS.addRecalc("box-sizing","border-box",IE7.Layout.borderBox);IE7.CSS.addFix(/opacity\s*:\s*([\d.]+)/,function(a,b){return"zoom:1;filter:Alpha(opacity="+((b*100)||1)+")"});var cx=/^image/i;IE7.HTML.addRecalc("object",function(a){if(cx.test(a.type)){a.body.style.cssText="margin:0;padding:0;border:none;overflow:hidden";return a}});IE7.loaded=true;(function(){try{bx.doScroll("left")}catch(e){setTimeout(arguments.callee,1);return}try{eval(bO.innerHTML)}catch(e){}bm=new RegExp(W(typeof IE7_PNG_SUFFIX=="string"?IE7_PNG_SUFFIX:"-trans.png")+"$","i");w=document.body;t=G?w:bx;w.className+=" ie7_body";bx.className+=" ie7_html";if(G)cq();IE7.CSS.init();IE7.HTML.init();IE7.HTML.apply();IE7.CSS.apply();IE7.recalc()})()})(); \ No newline at end of file diff --git a/admin/js/ie7/blank.gif b/admin/js/ie7/blank.gif new file mode 100644 index 0000000000000000000000000000000000000000..a4fe2e6297c7a013637b0e15f842dca1ef3128c4 GIT binary patch literal 48 wcmZ?wbhEHbWMp7un83&Y1poj4SNzEWWHK`7fcPL81|}vSMh3-y@(c{t0P2MZQ2+n{ literal 0 HcmV?d00001 diff --git a/admin/js/ie7/ie7-recalc.js b/admin/js/ie7/ie7-recalc.js new file mode 100644 index 0000000..f07c5a6 --- /dev/null +++ b/admin/js/ie7/ie7-recalc.js @@ -0,0 +1,2 @@ +/* IE7/IE8.js - copyright 2004-2008, Dean Edwards */ +(function(){if(!IE7.loaded)return;CLASSES=/\sie7_class\d+/g;IE7.CSS.extend({elements:{},handlers:[],reset:function(){this.removeEventHandlers();var a=this.elements;for(var b in a)a[b].runtimeStyle.cssText="";this.elements={};var a=IE7.Rule.elements;for(var b in a){with(a[b])className=className.replace(CLASSES,"")}IE7.Rule.elements={}},reload:function(){this.rules=[];this.getInlineStyles();this.screen.load();if(this.print)this.print.load();this.refresh();this.trash()},addRecalc:function(b,c,d,e){this.base(b,c,function(a){d(a);IE7.CSS.elements[a.uniqueID]=a},e)},recalc:function(){this.reset();this.base()},addEventHandler:function(a,b,c){a.attachEvent(b,c);this.handlers.push(arguments)},removeEventHandlers:function(){var a;while(a=this.handlers.pop()){a[0].detachEvent(a[1],a[2])}},getInlineStyles:function(){var a=document.getElementsByTagName("style"),b;for(var c=a.length-1;(b=a[c]);c--){if(!b.disabled&&!b.ie7){var d=b.cssText||b.innerHTML;this.styles.push(d);b.cssText=d}}},trash:function(){var a=document.styleSheets,b,c;for(c=0;c= 6) IE7.CSS.addRecalc("float", "(left|right)", function(element) { + IE7.Layout.boxSizing(element.parentElement); // assing "hasLayout" to parent element + // "doubled margin" bug + element.style.display = "inline"; + }); + + // "unscrollable content" bug + // http://www.positioniseverything.net/explorer/unscrollable.html + IE7.CSS.addRecalc("position", "absolute|fixed", function(element) { + if (element.offsetParent && element.offsetParent.currentStyle.position == "relative") + IE7.Layout.boxSizing(element.offsetParent); // assing "hasLayout" + }); +} + +//# // get rid of Microsoft's pesky image toolbar +//# document.write(''); diff --git a/admin/js/jquery/jquery.bgFade.js b/admin/js/jquery/jquery.bgFade.js new file mode 100644 index 0000000..cdf201a --- /dev/null +++ b/admin/js/jquery/jquery.bgFade.js @@ -0,0 +1,7 @@ + +jQuery.fn.backgroundFade=function(s,callback){var defaults={sColor:[255,0,0],eColor:[255,255,255],fColor:null,steps:200,intervals:5,powr:4},params=jQuery.extend(defaults,s);return this.each(function(){this.bgFade_sColor=jQuery.backgroundFade.parseHexColor(params.sColor);this.bgFade_eColor=jQuery.backgroundFade.parseHexColor(params.eColor);this.bgFade_fColor=params.fColor?params.fColor:jQuery(this).css('backgroundColor');this.bgFade_steps=params.steps;this.bgFade_intervals=params.intervals;this.bgFade_powr=params.powr;this.bgFade_fn=callback;jQuery.backgroundFade.doFade(this);});};jQuery.backgroundFade={parseHexColor:function(c){if(c.constructor==String&&c.substr(0,1)=='#'){return[parseInt(c.substr(1,2),16),parseInt(c.substr(3,2),16),parseInt(c.substr(5,2),16)];} +return c;},easeInOut:function(minValue,maxValue,totalSteps,actualStep,powr){var delta=maxValue-minValue;var stepp=minValue+(Math.pow(((1/totalSteps)*actualStep),powr)*delta);return Math.ceil(stepp);},doFade:function(e){if(e.bgFadeInt)window.clearInterval(e.bgFadeInt);var act_step=0;e.bgFadeInt=window.setInterval(function(){e.style.backgroundColor="rgb("+ +jQuery.backgroundFade.easeInOut(e.bgFade_sColor[0],e.bgFade_eColor[0],e.bgFade_steps,act_step,e.bgFade_powr)+","+ +jQuery.backgroundFade.easeInOut(e.bgFade_sColor[1],e.bgFade_eColor[1],e.bgFade_steps,act_step,e.bgFade_powr)+","+ +jQuery.backgroundFade.easeInOut(e.bgFade_sColor[2],e.bgFade_eColor[2],e.bgFade_steps,act_step,e.bgFade_powr)+")";act_step++;if(act_step>e.bgFade_steps){window.clearInterval(e.bgFadeInt);e.bgFade_sColor=undefined;e.bgFade_eColor=undefined;e.bgFade_fColor=undefined;e.bgFade_steps=undefined;e.bgFade_intervals=undefined;e.bgFade_powr=undefined;if(typeof(e.bgFade_fn)=='function'){e.bgFade_fn.call(e);} +e.style.backgroundColor=e.bgFade_fColor;}},e.bgFade_intervals);}}; \ No newline at end of file diff --git a/admin/js/jquery/jquery.biscuit.js b/admin/js/jquery/jquery.biscuit.js new file mode 100644 index 0000000..8b74194 --- /dev/null +++ b/admin/js/jquery/jquery.biscuit.js @@ -0,0 +1,5 @@ + +jQuery.cookie=function(name,value,options){if(typeof value!='undefined'){options=options||{};var expires='';if(options.expires&&(typeof options.expires=='number'||options.expires.toGMTString)){var date;if(typeof options.expires=='number'){date=new Date();date.setTime(date.getTime()+(options.expires*24*60*60*1000));}else{date=options.expires;} +expires='; expires='+date.toGMTString();} +var path=options.path?'; path='+options.path:'';var domain=options.domain?'; domain='+options.domain:'';var secure=options.secure?'; secure':'';document.cookie=[name,'=',encodeURIComponent(value),expires,path,domain,secure].join('');return null;}else{var cookieValue=null;if(document.cookie&&document.cookie!=''){var cookies=document.cookie.split(';');for(var i=0;i'+''+''+''+''+''+'';this.container=$('');if(this.params.target_element==null){this.container.css({display:'block',position:'absolute',left:$(document).scrollLeft()+'px',top:$(document).scrollTop()+'px',width:'30px',height:'30px',background:'#f00'});$('body').append(this.container);}else{$(this.params.target_element).append(this.container);this.container.css({display:'block',position:'absolute',top:0,left:0,zIndex:1});} +this.container[0].innerHTML=flash;this.movie=document.getElementById(this.params.movie_name);return this;},addFlashVar:function(fv,n,v){if(v!=null){fv.push(n+'='+encodeURIComponent(v));}},flashBind:function(){_this=this;var events={flashReady:function(){if(window[_this.params.movie_name]==undefined){window[_this.params.movie_name]=_this.movie;} +_this.flashBindEvent('flashReady',arguments);},fileDialogComplete:function(){_this.flashBindEvent('fileDialogComplete',arguments);},fileDialogStart:function(){_this.flashBindEvent('fileDialogStart',arguments);},fileQueued:function(file_object){_this.flashBindEvent('fileQueued',arguments);},fileQueueError:function(file_object,error_code,error_msg){_this.flashBindEvent('fileQueueError',arguments);},uploadStart:function(){_this.flashBindEvent('uploadStart',arguments);},uploadProgress:function(){_this.flashBindEvent('uploadProgress',arguments);},uploadError:function(){_this.flashBindEvent('uploadError',arguments);},uploadSuccess:function(){_this.flashBindEvent('uploadSuccess',arguments);},uploadComplete:function(){_this.flashBindEvent('uploadComplete',arguments);},debug:function(){_this.flashBindEvent('debug',arguments);}};window.SWFUpload.instances[this.params.movie_name]=events;window.SWFUpload.movieCount++;},flashEventQueue:[],flashBindEvent:function(evt,a){a=a||new Array();var _this=this;if($.isFunction(this.callbacks[evt])){this.flashEventQueue.push(function(){this.callbacks[evt].apply(this,a);});setTimeout(function(){_this.flashExecuteNextEvent();},0);}else if(this.callbacks[evt]!==null){throw'Event handler '+evt+' is unknown or is not a function';}},flashExecuteNextEvent:function(){var f=this.flashEventQueue?this.flashEventQueue.shift():null;if($.isFunction(f)){f.apply(this);}},destroy:function(){try{this.StopUpload();$(this.movie).remove();SWFUpload.instances[this.params.movie_name]=null;SWFUpload.movieCount--;delete SWFUpload.instances[this.movieName];delete window[this.movieName];return true;}catch(e){return false;}},StartUpload:function(file_id){return this.movie.StartUpload(file_id);},ReturnUploadStart:function(value){return this.movie.ReturnUploadStart(value);},StopUpload:function(){return this.movie.StopUpload();},CancelUpload:function(file_id){return this.movie.CancelUpload(file_id);},GetStats:function(){return this.movie.GetStats();},SetStats:function(stats){return this.movie.SetStats(stats);},GetFile:function(file_id){return this.movie.GetFile(file_id);},GetFileByIndex:function(file_index){return this.movie.GetFileByIndex(file_index);},getFileSizeLimit:function(size){var value=0;var unit='kb';size=$.trim(size.toLowerCase());var values=size.match(/^\d+/);if(values!=null&&values.length>0){value=parseInt(values[0]);} +var units=size.match(/(b|kb|mb|gb)/);if(units!=null&&units.length>0){unit=units[0];} +var multiplier=1024;if(unit==="b"){multiplier=1;}else if(unit==="mb"){multiplier=1048576;}else if(unit==="gb"){multiplier=1073741824;} +return value*multiplier;}};})(jQuery);(function($){$.fn.candyUpload=function(settings,callbacks){new $._candyUpload(this,settings,callbacks);return this;};$._candyUpload=function(target,settings,callbacks){var defaults={debug:false,upload_url:'',params:null,flash_movie:'',file_types:'*.*',file_types_description:'All files',file_size_limit:0,file_upload_limit:0,file_queue_limit:-1,callbacks:{}};this.params=$.extend(defaults,settings);this.params.movie_name='SWFU-'+(window.SWFUpload.instances.length+1);this.target=target;this.createControls();this.target.hide().after(this.ctrl.block).hide();this.params.target_element=this.ctrl.btn_browse.parent().get(0);var _this=this;this.upldr=$.uploader(this.params,{debug:function(msg){$('body').append('
    '+msg+'
    ');_this.bindEvent('debug',arguments);},flashReady:function(){_this.initControls(this);_this.bindEvent('flashReady',arguments);this.movie.style.width=_this.ctrl.btn_browse.width()+'px';this.movie.style.height=_this.ctrl.btn_browse.height()+'px';},fileDialogComplete:function(num_ref_files,num_queue_files){_this.bindEvent('fileDialogComplete',arguments);},fileDialogStart:function(){_this.bindEvent('fileQueued',arguments);},fileQueued:function(o){_this.appendFile(this,o);_this.refreshControls(this);_this.bindEvent('fileQueued',arguments);},fileQueueError:function(o,code,msg){var codes=window.SWFUpload.QUEUE_ERROR;switch(code){case codes.QUEUE_LIMIT_EXCEEDED:_this.queueErrorMsg(_this.locales.limit_exceeded);break;case codes.FILE_EXCEEDS_SIZE_LIMIT:_this.queueErrorMsg(_this.locales.size_limit_exceeded);break;case codes.ZERO_BYTE_FILE:case codes.INVALID_FILETYPE:_this.queueErrorMsg(msg);break;} +_this.bindEvent('fileQueueError',arguments);},uploadStart:function(){this.ReturnUploadStart(true);_this.bindEvent('uploadStart',arguments);},uploadProgress:function(o,bytes,total){_this.fileProgressBar(o.id,bytes,total);_this.bindEvent('uploadProgress',arguments);},uploadError:function(o,code,msg){var codes=window.SWFUpload.UPLOAD_ERROR;switch(code){case codes.FILE_CANCELLED:_this.fileErrorMsg(o.id,_this.locales.canceled);break;case codes.HTTP_ERROR:_this.fileErrorMsg(o.id,_this.locales.http_error+' '+msg);break;case codes.MISSING_UPLOAD_URL:case codes.IO_ERROR:case codes.SECURITY_ERROR:case codes.UPLOAD_LIMIT_EXCEEDED:case codes.UPLOAD_FAILED:case codes.SPECIFIED_FILE_ID_NOT_FOUND:case codes.FILE_VALIDATION_FAILED:case codes.FILE_CANCELLED:case codes.UPLOAD_STOPPED:_this.fileErrorMsg(o.id,_this.locales.error+' '+msg);break;} +_this.refreshControls(this);_this.removeFileCancel(o);_this.bindEvent('uploadError',arguments);},uploadSuccess:function(o,data){_this.fileProgressBar(o.id,1,1);_this.refreshControls(this);_this.removeFileCancel(o);_this.bindEvent('uploadSuccess',arguments);},uploadComplete:function(o){this.StartUpload();_this.refreshControls(this);_this.bindEvent('uploadComplete',arguments);}});};$._candyUpload.prototype={locales:{max_file_size:'Maximum file size allowed:',limit_exceeded:'Limit exceeded.',size_limit_exceeded:'File size exceeds allowed limit.',canceled:'Canceled.',http_error:'HTTP Error:',error:'Error:',choose_file:'Choose file',choose_files:'Choose files',cancel:'Cancel',clean:'Clean',upload:'Upload',no_file_in_queue:'No file in queue.',file_in_queue:'1 file in queue.',files_in_queue:'%d files in queue.',queue_error:'Queue error:'},ctrl:{block:$('
    '),files:null},createControls:function(){this.ctrl.btn_browse=$(' ').click(function(){return false;});this.ctrl.btn_cancel=$(''+this.locales.cancel+'').click(function(){return false;});this.ctrl.btn_clean=$(''+this.locales.clean+'').click(function(){return false;});this.ctrl.btn_upload=$(''+this.locales.upload+'').click(function(){return false;});this.ctrl.msg=$('
    '+this.locales.no_file_in_queue+'
    ').appendTo(this.ctrl.block);var btn=$('
    ').appendTo(this.ctrl.block);var brw=$('').append(this.ctrl.btn_browse).appendTo(btn);$('').append(this.ctrl.btn_upload).appendTo(btn).hide();$('').append(this.ctrl.btn_cancel).appendTo(btn).hide();$('').append(this.ctrl.btn_clean).appendTo(btn).hide();this.bindEvent('createControls');},initControls:function(upldr){if(this.params.file_queue_limit==1){this.ctrl.btn_browse.text(this.locales.choose_file);}else{this.ctrl.btn_browse.text(this.locales.choose_files);} +var _this=this;this.ctrl.btn_cancel.click(function(){_this.cancelQueue(upldr);return false;});this.ctrl.btn_clean.click(function(){_this.cleanQueue(upldr);return false;});this.ctrl.btn_upload.click(function(){_this.uploadQueue(upldr);return false;});var size=this.formatSize(upldr.params.file_size_limit);$('
    '+this.locales.max_file_size+' '+size+'
    ').appendTo(this.ctrl.block);},refreshControls:function(upldr){if(!this.ctrl.files||this.ctrl.files.length==0){return;} +var stats=upldr.GetStats();if(stats.files_queued>0){this.ctrl.btn_cancel.parent().show();this.ctrl.btn_upload.parent().show();if(this.params.file_queue_limit>0&&this.params.file_queue_limit==stats.files_queued){this.ctrl.btn_browse.hide();}else{this.ctrl.btn_browse.show();} +if(stats.files_queued>1){var msg=this.locales.files_in_queue.replace(/%d/,stats.files_queued);}else{var msg=this.locales.file_in_queue;}}else{this.ctrl.btn_browse.show();this.ctrl.btn_cancel.parent().hide();this.ctrl.btn_upload.parent().hide();var msg=this.locales.no_file_in_queue;} +this.ctrl.msg.removeClass('cu-error').text(msg);if(stats.successful_uploads>0||stats.upload_errors>0||stats.upload_cancelled>0){this.ctrl.btn_clean.parent().show();}else{this.ctrl.btn_clean.parent().hide();}},removeFileCancel:function(o){$('#'+o.id+' span.cu-filecancel',this.ctrl.files).remove();},appendFile:function(upldr,o){if(!this.ctrl.files){this.ctrl.files=$('
    ');this.ctrl.msg.after(this.ctrl.files);} +var fileblock=$('
    '+'
    '+o.name+' '+'('+this.formatSize(o.size)+') '+'cancel '+''+'
    ');$('span.cu-filecancel a',fileblock).click(function(){upldr.CancelUpload(o.id);return false;});this.ctrl.files.append(fileblock);},fileProgressBar:function(file_id,bytes,total){var bar=$('#'+file_id+' div.cu-progress>div',this.ctrl.files);if(bar.length==0){$('#'+file_id,this.ctrl.files).append('
     
    ');bar=$('#'+file_id+' div.cu-progress>div',this.ctrl.files);} +var percent=Math.round((bytes*100)/total);bar.css('width',percent+'%').text(percent+'%');},fileMsg:function(file_id,msg,error){error=error||false;var span=$('#'+file_id+' span.cu-filemsg',this.ctrl.files).attr('class','cu-filemsg');if(error){span.addClass('cu-error');} +span.text(msg);},fileErrorMsg:function(file_id,msg){this.fileMsg(file_id,msg,true);},cancelQueue:function(upldr){if(!this.ctrl.files||this.ctrl.files.length==0){return;} +this.ctrl.files.children('div').each(function(){upldr.CancelUpload(this.id);});},uploadQueue:function(upldr){if(!this.ctrl.files||this.ctrl.files.length==0){return;} +upldr.StartUpload();},cleanQueue:function(upldr){var _this=this;var e=$('div.cu-file',this.ctrl.files).not(':has(span.cu-filecancel a)');e.filter(':last').slideUp(200,function(){$(this).remove();if(e.length==1){upldr.SetStats({successful_uploads:0,upload_errors:0,upload_cancelled:0});_this.refreshControls(upldr);}else if(e.length>1){_this.cleanQueue(upldr);}});},queueErrorMsg:function(msg){this.ctrl.msg.addClass('cu-error').text(this.locales.queue_error+' '+msg);},formatSize:function(s){var a_size=Array('B','KB','MB','GB','TB');var i_index=0;while(s>1024){i_index++;s/=1024;} +return(Math.round(s*100)/100)+' '+a_size[i_index];},bindEvent:function(evt,a){if(this.params.callbacks[evt]!=undefined&&$.isFunction(this.params.callbacks[evt])){a=a||new Array();this.params.callbacks[evt].apply(this,a);}}};})(jQuery); \ No newline at end of file diff --git a/admin/js/jquery/jquery.farbtastic.js b/admin/js/jquery/jquery.farbtastic.js new file mode 100644 index 0000000..a758344 --- /dev/null +++ b/admin/js/jquery/jquery.farbtastic.js @@ -0,0 +1,22 @@ + +jQuery.fn.farbtastic=function(callback){$.farbtastic(this,callback);return this;};jQuery.farbtastic=function(container,callback){var container=$(container).get(0);return container.farbtastic||(container.farbtastic=new jQuery._farbtastic(container,callback));};jQuery._farbtastic=function(container,callback){var fb=this;$(container).html('
    ');var e=$('.farbtastic',container);fb.wheel=$('.wheel',container).get(0);fb.radius=84;fb.square=100;fb.width=194;if(navigator.appVersion.match(/MSIE [0-6]\./)){$('*',e).each(function(){if(this.currentStyle.backgroundImage!='none'){var image=this.currentStyle.backgroundImage;image=this.currentStyle.backgroundImage.substring(5,image.length-2);$(this).css({'backgroundImage':'none','filter':"progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='"+image+"')"});}});} +fb.linkTo=function(callback){if(typeof fb.callback=='object'){$(fb.callback).unbind('keyup',fb.updateValue);} +fb.color=null;if(typeof callback=='function'){fb.callback=callback;} +else if(typeof callback=='object'||typeof callback=='string'){fb.callback=$(callback);fb.callback.bind('keyup',fb.updateValue);if(fb.callback.get(0).value){fb.setColor(fb.callback.get(0).value);}} +return this;};fb.updateValue=function(event){if(this.value&&this.value!=fb.color){fb.setColor(this.value);}};fb.setColor=function(color){var unpack=fb.unpack(color);if(fb.color!=color&&unpack){fb.color=color;fb.rgb=unpack;fb.hsl=fb.RGBToHSL(fb.rgb);fb.updateDisplay();} +return this;};fb.setHSL=function(hsl){fb.hsl=hsl;fb.rgb=fb.HSLToRGB(hsl);fb.color=fb.pack(fb.rgb);fb.updateDisplay();return this;};fb.widgetCoords=function(event){var x,y;var el=event.target||event.srcElement;var reference=fb.wheel;if(typeof event.offsetX!='undefined'){var pos={x:event.offsetX,y:event.offsetY};var e=el;while(e){e.mouseX=pos.x;e.mouseY=pos.y;pos.x+=e.offsetLeft;pos.y+=e.offsetTop;e=e.offsetParent;} +var e=reference;var offset={x:0,y:0};while(e){if(typeof e.mouseX!='undefined'){x=e.mouseX-offset.x;y=e.mouseY-offset.y;break;} +offset.x+=e.offsetLeft;offset.y+=e.offsetTop;e=e.offsetParent;} +e=el;while(e){e.mouseX=undefined;e.mouseY=undefined;e=e.offsetParent;}} +else{var pos=fb.absolutePosition(reference);x=(event.pageX||0*(event.clientX+$('html').get(0).scrollLeft))-pos.x;y=(event.pageY||0*(event.clientY+$('html').get(0).scrollTop))-pos.y;} +return{x:x-fb.width/2,y:y-fb.width/2};};fb.mousedown=function(event){if(!document.dragging){$(document).bind('mousemove',fb.mousemove).bind('mouseup',fb.mouseup);document.dragging=true;} +var pos=fb.widgetCoords(event);fb.circleDrag=Math.max(Math.abs(pos.x),Math.abs(pos.y))*2>fb.square;fb.mousemove(event);return false;};fb.mousemove=function(event){var pos=fb.widgetCoords(event);if(fb.circleDrag){var hue=Math.atan2(pos.x,-pos.y)/6.28;if(hue<0)hue+=1;fb.setHSL([hue,fb.hsl[1],fb.hsl[2]]);} +else{var sat=Math.max(0,Math.min(1,-(pos.x/fb.square)+.5));var lum=Math.max(0,Math.min(1,-(pos.y/fb.square)+.5));fb.setHSL([fb.hsl[0],sat,lum]);} +return false;};fb.mouseup=function(){$(document).unbind('mousemove',fb.mousemove);$(document).unbind('mouseup',fb.mouseup);document.dragging=false;};fb.updateDisplay=function(){var angle=fb.hsl[0]*6.28;$('.h-marker',e).css({left:Math.round(Math.sin(angle)*fb.radius+fb.width/2)+'px',top:Math.round(-Math.cos(angle)*fb.radius+fb.width/2)+'px'});$('.sl-marker',e).css({left:Math.round(fb.square*(.5-fb.hsl[1])+fb.width/2)+'px',top:Math.round(fb.square*(.5-fb.hsl[2])+fb.width/2)+'px'});$('.color',e).css('backgroundColor',fb.pack(fb.HSLToRGB([fb.hsl[0],1,0.5])));if(typeof fb.callback=='object'){$(fb.callback).css({backgroundColor:fb.color,color:fb.hsl[2]>0.5?'#000':'#fff'});$(fb.callback).each(function(){if(this.value!=fb.color){this.value=fb.color;}});} +else if(typeof fb.callback=='function'){fb.callback.call(fb,fb.color);}};fb.absolutePosition=function(el){var r={x:el.offsetLeft,y:el.offsetTop};if(el.offsetParent){var tmp=fb.absolutePosition(el.offsetParent);r.x+=tmp.x;r.y+=tmp.y;} +return r;};fb.pack=function(rgb){var r=Math.round(rgb[0]*255);var g=Math.round(rgb[1]*255);var b=Math.round(rgb[2]*255);return'#'+(r<16?'0':'')+r.toString(16)+ +(g<16?'0':'')+g.toString(16)+ +(b<16?'0':'')+b.toString(16);};fb.unpack=function(color){if(color.length==7){return[parseInt('0x'+color.substring(1,3))/255,parseInt('0x'+color.substring(3,5))/255,parseInt('0x'+color.substring(5,7))/255];} +else if(color.length==4){return[parseInt('0x'+color.substring(1,2))/15,parseInt('0x'+color.substring(2,3))/15,parseInt('0x'+color.substring(3,4))/15];}};fb.HSLToRGB=function(hsl){var m1,m2,r,g,b;var h=hsl[0],s=hsl[1],l=hsl[2];m2=(l<=0.5)?l*(s+1):l+s-l*s;m1=l*2-m2;return[this.hueToRGB(m1,m2,h+0.33333),this.hueToRGB(m1,m2,h),this.hueToRGB(m1,m2,h-0.33333)];};fb.hueToRGB=function(m1,m2,h){h=(h<0)?h+1:((h>1)?h-1:h);if(h*6<1)return m1+(m2-m1)*h*6;if(h*2<1)return m2;if(h*3<2)return m1+(m2-m1)*(0.66666-h)*6;return m1;};fb.RGBToHSL=function(rgb){var min,max,delta,h,s,l;var r=rgb[0],g=rgb[1],b=rgb[2];min=Math.min(r,Math.min(g,b));max=Math.max(r,Math.max(g,b));delta=max-min;l=(min+max)/2;s=0;if(l>0&&l<1){s=delta/(l<0.5?(2*l):(2-2*l));} +h=0;if(delta>0){if(max==r&&max!=g)h+=(g-b)/delta;if(max==g&&max!=b)h+=(2+(b-r)/delta);if(max==b&&max!=r)h+=(4+(r-g)/delta);h/=6;} +return[h,s,l];};$('*',e).mousedown(fb.mousedown);fb.setColor('#000000');if(callback){fb.linkTo(callback);}}; \ No newline at end of file diff --git a/admin/js/jquery/jquery.js b/admin/js/jquery/jquery.js new file mode 100644 index 0000000..4071503 --- /dev/null +++ b/admin/js/jquery/jquery.js @@ -0,0 +1,432 @@ + +(function(){var +window=this,undefined,_jQuery=window.jQuery,_$=window.$,jQuery=window.jQuery=window.$=function(selector,context){return new jQuery.fn.init(selector,context);},quickExpr=/^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,isSimple=/^.[^:#\[\.,]*$/;jQuery.fn=jQuery.prototype={init:function(selector,context){selector=selector||document;if(selector.nodeType){this[0]=selector;this.length=1;this.context=selector;return this;} +if(typeof selector==="string"){var match=quickExpr.exec(selector);if(match&&(match[1]||!context)){if(match[1]) +selector=jQuery.clean([match[1]],context);else{var elem=document.getElementById(match[3]);if(elem&&elem.id!=match[3]) +return jQuery().find(selector);var ret=jQuery(elem||[]);ret.context=document;ret.selector=selector;return ret;}}else +return jQuery(context).find(selector);}else if(jQuery.isFunction(selector)) +return jQuery(document).ready(selector);if(selector.selector&&selector.context){this.selector=selector.selector;this.context=selector.context;} +return this.setArray(jQuery.isArray(selector)?selector:jQuery.makeArray(selector));},selector:"",jquery:"1.3.2",size:function(){return this.length;},get:function(num){return num===undefined?Array.prototype.slice.call(this):this[num];},pushStack:function(elems,name,selector){var ret=jQuery(elems);ret.prevObject=this;ret.context=this.context;if(name==="find") +ret.selector=this.selector+(this.selector?" ":"")+selector;else if(name) +ret.selector=this.selector+"."+name+"("+selector+")";return ret;},setArray:function(elems){this.length=0;Array.prototype.push.apply(this,elems);return this;},each:function(callback,args){return jQuery.each(this,callback,args);},index:function(elem){return jQuery.inArray(elem&&elem.jquery?elem[0]:elem,this);},attr:function(name,value,type){var options=name;if(typeof name==="string") +if(value===undefined) +return this[0]&&jQuery[type||"attr"](this[0],name);else{options={};options[name]=value;} +return this.each(function(i){for(name in options) +jQuery.attr(type?this.style:this,name,jQuery.prop(this,options[name],type,i,name));});},css:function(key,value){if((key=='width'||key=='height')&&parseFloat(value)<0) +value=undefined;return this.attr(key,value,"curCSS");},text:function(text){if(typeof text!=="object"&&text!=null) +return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(text));var ret="";jQuery.each(text||this,function(){jQuery.each(this.childNodes,function(){if(this.nodeType!=8) +ret+=this.nodeType!=1?this.nodeValue:jQuery.fn.text([this]);});});return ret;},wrapAll:function(html){if(this[0]){var wrap=jQuery(html,this[0].ownerDocument).clone();if(this[0].parentNode) +wrap.insertBefore(this[0]);wrap.map(function(){var elem=this;while(elem.firstChild) +elem=elem.firstChild;return elem;}).append(this);} +return this;},wrapInner:function(html){return this.each(function(){jQuery(this).contents().wrapAll(html);});},wrap:function(html){return this.each(function(){jQuery(this).wrapAll(html);});},append:function(){return this.domManip(arguments,true,function(elem){if(this.nodeType==1) +this.appendChild(elem);});},prepend:function(){return this.domManip(arguments,true,function(elem){if(this.nodeType==1) +this.insertBefore(elem,this.firstChild);});},before:function(){return this.domManip(arguments,false,function(elem){this.parentNode.insertBefore(elem,this);});},after:function(){return this.domManip(arguments,false,function(elem){this.parentNode.insertBefore(elem,this.nextSibling);});},end:function(){return this.prevObject||jQuery([]);},push:[].push,sort:[].sort,splice:[].splice,find:function(selector){if(this.length===1){var ret=this.pushStack([],"find",selector);ret.length=0;jQuery.find(selector,this[0],ret);return ret;}else{return this.pushStack(jQuery.unique(jQuery.map(this,function(elem){return jQuery.find(selector,elem);})),"find",selector);}},clone:function(events){var ret=this.map(function(){if(!jQuery.support.noCloneEvent&&!jQuery.isXMLDoc(this)){var html=this.outerHTML;if(!html){var div=this.ownerDocument.createElement("div");div.appendChild(this.cloneNode(true));html=div.innerHTML;} +return jQuery.clean([html.replace(/ jQuery\d+="(?:\d+|null)"/g,"").replace(/^\s*/,"")])[0];}else +return this.cloneNode(true);});if(events===true){var orig=this.find("*").andSelf(),i=0;ret.find("*").andSelf().each(function(){if(this.nodeName!==orig[i].nodeName) +return;var events=jQuery.data(orig[i],"events");for(var type in events){for(var handler in events[type]){jQuery.event.add(this,type,events[type][handler],events[type][handler].data);}} +i++;});} +return ret;},filter:function(selector){return this.pushStack(jQuery.isFunction(selector)&&jQuery.grep(this,function(elem,i){return selector.call(elem,i);})||jQuery.multiFilter(selector,jQuery.grep(this,function(elem){return elem.nodeType===1;})),"filter",selector);},closest:function(selector){var pos=jQuery.expr.match.POS.test(selector)?jQuery(selector):null,closer=0;return this.map(function(){var cur=this;while(cur&&cur.ownerDocument){if(pos?pos.index(cur)>-1:jQuery(cur).is(selector)){jQuery.data(cur,"closest",closer);return cur;} +cur=cur.parentNode;closer++;}});},not:function(selector){if(typeof selector==="string") +if(isSimple.test(selector)) +return this.pushStack(jQuery.multiFilter(selector,this,true),"not",selector);else +selector=jQuery.multiFilter(selector,this);var isArrayLike=selector.length&&selector[selector.length-1]!==undefined&&!selector.nodeType;return this.filter(function(){return isArrayLike?jQuery.inArray(this,selector)<0:this!=selector;});},add:function(selector){return this.pushStack(jQuery.unique(jQuery.merge(this.get(),typeof selector==="string"?jQuery(selector):jQuery.makeArray(selector))));},is:function(selector){return!!selector&&jQuery.multiFilter(selector,this).length>0;},hasClass:function(selector){return!!selector&&this.is("."+selector);},val:function(value){if(value===undefined){var elem=this[0];if(elem){if(jQuery.nodeName(elem,'option')) +return(elem.attributes.value||{}).specified?elem.value:elem.text;if(jQuery.nodeName(elem,"select")){var index=elem.selectedIndex,values=[],options=elem.options,one=elem.type=="select-one";if(index<0) +return null;for(var i=one?index:0,max=one?index+1:options.length;i=0||jQuery.inArray(this.name,value)>=0);else if(jQuery.nodeName(this,"select")){var values=jQuery.makeArray(value);jQuery("option",this).each(function(){this.selected=(jQuery.inArray(this.value,values)>=0||jQuery.inArray(this.text,values)>=0);});if(!values.length) +this.selectedIndex=-1;}else +this.value=value;});},html:function(value){return value===undefined?(this[0]?this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g,""):null):this.empty().append(value);},replaceWith:function(value){return this.after(value).remove();},eq:function(i){return this.slice(i,+i+1);},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments),"slice",Array.prototype.slice.call(arguments).join(","));},map:function(callback){return this.pushStack(jQuery.map(this,function(elem,i){return callback.call(elem,i,elem);}));},andSelf:function(){return this.add(this.prevObject);},domManip:function(args,table,callback){if(this[0]){var fragment=(this[0].ownerDocument||this[0]).createDocumentFragment(),scripts=jQuery.clean(args,(this[0].ownerDocument||this[0]),fragment),first=fragment.firstChild;if(first) +for(var i=0,l=this.length;i1||i>0?fragment.cloneNode(true):fragment);if(scripts) +jQuery.each(scripts,evalScript);} +return this;function root(elem,cur){return table&&jQuery.nodeName(elem,"table")&&jQuery.nodeName(cur,"tr")?(elem.getElementsByTagName("tbody")[0]||elem.appendChild(elem.ownerDocument.createElement("tbody"))):elem;}}};jQuery.fn.init.prototype=jQuery.fn;function evalScript(i,elem){if(elem.src) +jQuery.ajax({url:elem.src,async:false,dataType:"script"});else +jQuery.globalEval(elem.text||elem.textContent||elem.innerHTML||"");if(elem.parentNode) +elem.parentNode.removeChild(elem);} +function now(){return+new Date;} +jQuery.extend=jQuery.fn.extend=function(){var target=arguments[0]||{},i=1,length=arguments.length,deep=false,options;if(typeof target==="boolean"){deep=target;target=arguments[1]||{};i=2;} +if(typeof target!=="object"&&!jQuery.isFunction(target)) +target={};if(length==i){target=this;--i;} +for(;i-1;}},swap:function(elem,options,callback){var old={};for(var name in options){old[name]=elem.style[name];elem.style[name]=options[name];} +callback.call(elem);for(var name in options) +elem.style[name]=old[name];},css:function(elem,name,force,extra){if(name=="width"||name=="height"){var val,props={position:"absolute",visibility:"hidden",display:"block"},which=name=="width"?["Left","Right"]:["Top","Bottom"];function getWH(){val=name=="width"?elem.offsetWidth:elem.offsetHeight;if(extra==="border") +return;jQuery.each(which,function(){if(!extra) +val-=parseFloat(jQuery.curCSS(elem,"padding"+this,true))||0;if(extra==="margin") +val+=parseFloat(jQuery.curCSS(elem,"margin"+this,true))||0;else +val-=parseFloat(jQuery.curCSS(elem,"border"+this+"Width",true))||0;});} +if(elem.offsetWidth!==0) +getWH();else +jQuery.swap(elem,props,getWH);return Math.max(0,Math.round(val));} +return jQuery.curCSS(elem,name,force);},curCSS:function(elem,name,force){var ret,style=elem.style;if(name=="opacity"&&!jQuery.support.opacity){ret=jQuery.attr(style,"opacity");return ret==""?"1":ret;} +if(name.match(/float/i)) +name=styleFloat;if(!force&&style&&style[name]) +ret=style[name];else if(defaultView.getComputedStyle){if(name.match(/float/i)) +name="float";name=name.replace(/([A-Z])/g,"-$1").toLowerCase();var computedStyle=defaultView.getComputedStyle(elem,null);if(computedStyle) +ret=computedStyle.getPropertyValue(name);if(name=="opacity"&&ret=="") +ret="1";}else if(elem.currentStyle){var camelCase=name.replace(/\-(\w)/g,function(all,letter){return letter.toUpperCase();});ret=elem.currentStyle[name]||elem.currentStyle[camelCase];if(!/^\d+(px)?$/i.test(ret)&&/^\d/.test(ret)){var left=style.left,rsLeft=elem.runtimeStyle.left;elem.runtimeStyle.left=elem.currentStyle.left;style.left=ret||0;ret=style.pixelLeft+"px";style.left=left;elem.runtimeStyle.left=rsLeft;}} +return ret;},clean:function(elems,context,fragment){context=context||document;if(typeof context.createElement==="undefined") +context=context.ownerDocument||context[0]&&context[0].ownerDocument||document;if(!fragment&&elems.length===1&&typeof elems[0]==="string"){var match=/^<(\w+)\s*\/?>$/.exec(elems[0]);if(match) +return[context.createElement(match[1])];} +var ret=[],scripts=[],div=context.createElement("div");jQuery.each(elems,function(i,elem){if(typeof elem==="number") +elem+='';if(!elem) +return;if(typeof elem==="string"){elem=elem.replace(/(<(\w+)[^>]*?)\/>/g,function(all,front,tag){return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?all:front+">";});var tags=elem.replace(/^\s+/,"").substring(0,10).toLowerCase();var wrap=!tags.indexOf("",""]||!tags.indexOf("",""]||tags.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"","
    "]||!tags.indexOf("",""]||(!tags.indexOf("",""]||!tags.indexOf("",""]||!jQuery.support.htmlSerialize&&[1,"div
    ","
    "]||[0,"",""];div.innerHTML=wrap[1]+elem+wrap[2];while(wrap[0]--) +div=div.lastChild;if(!jQuery.support.tbody){var hasBody=/"&&!hasBody?div.childNodes:[];for(var j=tbody.length-1;j>=0;--j) +if(jQuery.nodeName(tbody[j],"tbody")&&!tbody[j].childNodes.length) +tbody[j].parentNode.removeChild(tbody[j]);} +if(!jQuery.support.leadingWhitespace&&/^\s/.test(elem)) +div.insertBefore(context.createTextNode(elem.match(/^\s*/)[0]),div.firstChild);elem=jQuery.makeArray(div.childNodes);} +if(elem.nodeType) +ret.push(elem);else +ret=jQuery.merge(ret,elem);});if(fragment){for(var i=0;ret[i];i++){if(jQuery.nodeName(ret[i],"script")&&(!ret[i].type||ret[i].type.toLowerCase()==="text/javascript")){scripts.push(ret[i].parentNode?ret[i].parentNode.removeChild(ret[i]):ret[i]);}else{if(ret[i].nodeType===1) +ret.splice.apply(ret,[i+1,0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))));fragment.appendChild(ret[i]);}} +return scripts;} +return ret;},attr:function(elem,name,value){if(!elem||elem.nodeType==3||elem.nodeType==8) +return undefined;var notxml=!jQuery.isXMLDoc(elem),set=value!==undefined;name=notxml&&jQuery.props[name]||name;if(elem.tagName){var special=/href|src|style/.test(name);if(name=="selected"&&elem.parentNode) +elem.parentNode.selectedIndex;if(name in elem&¬xml&&!special){if(set){if(name=="type"&&jQuery.nodeName(elem,"input")&&elem.parentNode) +throw"type property can't be changed";elem[name]=value;} +if(jQuery.nodeName(elem,"form")&&elem.getAttributeNode(name)) +return elem.getAttributeNode(name).nodeValue;if(name=="tabIndex"){var attributeNode=elem.getAttributeNode("tabIndex");return attributeNode&&attributeNode.specified?attributeNode.value:elem.nodeName.match(/(button|input|object|select|textarea)/i)?0:elem.nodeName.match(/^(a|area)$/i)&&elem.href?0:undefined;} +return elem[name];} +if(!jQuery.support.style&¬xml&&name=="style") +return jQuery.attr(elem.style,"cssText",value);if(set) +elem.setAttribute(name,""+value);var attr=!jQuery.support.hrefNormalized&¬xml&&special?elem.getAttribute(name,2):elem.getAttribute(name);return attr===null?undefined:attr;} +if(!jQuery.support.opacity&&name=="opacity"){if(set){elem.zoom=1;elem.filter=(elem.filter||"").replace(/alpha\([^)]*\)/,"")+ +(parseInt(value)+''=="NaN"?"":"alpha(opacity="+value*100+")");} +return elem.filter&&elem.filter.indexOf("opacity=")>=0?(parseFloat(elem.filter.match(/opacity=([^)]*)/)[1])/100)+'':"";} +name=name.replace(/-([a-z])/ig,function(all,letter){return letter.toUpperCase();});if(set) +elem[name]=value;return elem[name];},trim:function(text){return(text||"").replace(/^\s+|\s+$/g,"");},makeArray:function(array){var ret=[];if(array!=null){var i=array.length;if(i==null||typeof array==="string"||jQuery.isFunction(array)||array.setInterval) +ret[0]=array;else +while(i) +ret[--i]=array[i];} +return ret;},inArray:function(elem,array){for(var i=0,length=array.length;i0?this.clone(true):this).get();jQuery.fn[original].apply(jQuery(insert[i]),elems);ret=ret.concat(elems);} +return this.pushStack(ret,name,selector);};});jQuery.each({removeAttr:function(name){jQuery.attr(this,name,"");if(this.nodeType==1) +this.removeAttribute(name);},addClass:function(classNames){jQuery.className.add(this,classNames);},removeClass:function(classNames){jQuery.className.remove(this,classNames);},toggleClass:function(classNames,state){if(typeof state!=="boolean") +state=!jQuery.className.has(this,classNames);jQuery.className[state?"add":"remove"](this,classNames);},remove:function(selector){if(!selector||jQuery.filter(selector,[this]).length){jQuery("*",this).add([this]).each(function(){jQuery.event.remove(this);jQuery.removeData(this);});if(this.parentNode) +this.parentNode.removeChild(this);}},empty:function(){jQuery(this).children().remove();while(this.firstChild) +this.removeChild(this.firstChild);}},function(name,fn){jQuery.fn[name]=function(){return this.each(fn,arguments);};});function num(elem,prop){return elem[0]&&parseInt(jQuery.curCSS(elem[0],prop,true),10)||0;} +var expando="jQuery"+now(),uuid=0,windowData={};jQuery.extend({cache:{},data:function(elem,name,data){elem=elem==window?windowData:elem;var id=elem[expando];if(!id) +id=elem[expando]=++uuid;if(name&&!jQuery.cache[id]) +jQuery.cache[id]={};if(data!==undefined) +jQuery.cache[id][name]=data;return name?jQuery.cache[id][name]:id;},removeData:function(elem,name){elem=elem==window?windowData:elem;var id=elem[expando];if(name){if(jQuery.cache[id]){delete jQuery.cache[id][name];name="";for(name in jQuery.cache[id]) +break;if(!name) +jQuery.removeData(elem);}}else{try{delete elem[expando];}catch(e){if(elem.removeAttribute) +elem.removeAttribute(expando);} +delete jQuery.cache[id];}},queue:function(elem,type,data){if(elem){type=(type||"fx")+"queue";var q=jQuery.data(elem,type);if(!q||jQuery.isArray(data)) +q=jQuery.data(elem,type,jQuery.makeArray(data));else if(data) +q.push(data);} +return q;},dequeue:function(elem,type){var queue=jQuery.queue(elem,type),fn=queue.shift();if(!type||type==="fx") +fn=queue[0];if(fn!==undefined) +fn.call(elem);}});jQuery.fn.extend({data:function(key,value){var parts=key.split(".");parts[1]=parts[1]?"."+parts[1]:"";if(value===undefined){var data=this.triggerHandler("getData"+parts[1]+"!",[parts[0]]);if(data===undefined&&this.length) +data=jQuery.data(this[0],key);return data===undefined&&parts[1]?this.data(parts[0]):data;}else +return this.trigger("setData"+parts[1]+"!",[parts[0],value]).each(function(){jQuery.data(this,key,value);});},removeData:function(key){return this.each(function(){jQuery.removeData(this,key);});},queue:function(type,data){if(typeof type!=="string"){data=type;type="fx";} +if(data===undefined) +return jQuery.queue(this[0],type);return this.each(function(){var queue=jQuery.queue(this,type,data);if(type=="fx"&&queue.length==1) +queue[0].call(this);});},dequeue:function(type){return this.each(function(){jQuery.dequeue(this,type);});}});(function(){var chunker=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,done=0,toString=Object.prototype.toString;var Sizzle=function(selector,context,results,seed){results=results||[];context=context||document;if(context.nodeType!==1&&context.nodeType!==9) +return[];if(!selector||typeof selector!=="string"){return results;} +var parts=[],m,set,checkSet,check,mode,extra,prune=true;chunker.lastIndex=0;while((m=chunker.exec(selector))!==null){parts.push(m[1]);if(m[2]){extra=RegExp.rightContext;break;}} +if(parts.length>1&&origPOS.exec(selector)){if(parts.length===2&&Expr.relative[parts[0]]){set=posProcess(parts[0]+parts[1],context);}else{set=Expr.relative[parts[0]]?[context]:Sizzle(parts.shift(),context);while(parts.length){selector=parts.shift();if(Expr.relative[selector]) +selector+=parts.shift();set=posProcess(selector,set);}}}else{var ret=seed?{expr:parts.pop(),set:makeArray(seed)}:Sizzle.find(parts.pop(),parts.length===1&&context.parentNode?context.parentNode:context,isXML(context));set=Sizzle.filter(ret.expr,ret.set);if(parts.length>0){checkSet=makeArray(set);}else{prune=false;} +while(parts.length){var cur=parts.pop(),pop=cur;if(!Expr.relative[cur]){cur="";}else{pop=parts.pop();} +if(pop==null){pop=context;} +Expr.relative[cur](checkSet,pop,isXML(context));}} +if(!checkSet){checkSet=set;} +if(!checkSet){throw"Syntax error, unrecognized expression: "+(cur||selector);} +if(toString.call(checkSet)==="[object Array]"){if(!prune){results.push.apply(results,checkSet);}else if(context.nodeType===1){for(var i=0;checkSet[i]!=null;i++){if(checkSet[i]&&(checkSet[i]===true||checkSet[i].nodeType===1&&contains(context,checkSet[i]))){results.push(set[i]);}}}else{for(var i=0;checkSet[i]!=null;i++){if(checkSet[i]&&checkSet[i].nodeType===1){results.push(set[i]);}}}}else{makeArray(checkSet,results);} +if(extra){Sizzle(extra,context,results,seed);if(sortOrder){hasDuplicate=false;results.sort(sortOrder);if(hasDuplicate){for(var i=1;i":function(checkSet,part,isXML){var isPartStr=typeof part==="string";if(isPartStr&&!/\W/.test(part)){part=isXML?part:part.toUpperCase();for(var i=0,l=checkSet.length;i=0)){if(!inplace) +result.push(elem);}else if(inplace){curLoop[i]=false;}}} +return false;},ID:function(match){return match[1].replace(/\\/g,"");},TAG:function(match,curLoop){for(var i=0;curLoop[i]===false;i++){} +return curLoop[i]&&isXML(curLoop[i])?match[1]:match[1].toUpperCase();},CHILD:function(match){if(match[1]=="nth"){var test=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(match[2]=="even"&&"2n"||match[2]=="odd"&&"2n+1"||!/\D/.test(match[2])&&"0n+"+match[2]||match[2]);match[2]=(test[1]+(test[2]||1))-0;match[3]=test[3]-0;} +match[0]=done++;return match;},ATTR:function(match,curLoop,inplace,result,not,isXML){var name=match[1].replace(/\\/g,"");if(!isXML&&Expr.attrMap[name]){match[1]=Expr.attrMap[name];} +if(match[2]==="~="){match[4]=" "+match[4]+" ";} +return match;},PSEUDO:function(match,curLoop,inplace,result,not){if(match[1]==="not"){if(match[3].match(chunker).length>1||/^\w/.test(match[3])){match[3]=Sizzle(match[3],null,null,curLoop);}else{var ret=Sizzle.filter(match[3],curLoop,inplace,true^not);if(!inplace){result.push.apply(result,ret);} +return false;}}else if(Expr.match.POS.test(match[0])||Expr.match.CHILD.test(match[0])){return true;} +return match;},POS:function(match){match.unshift(true);return match;}},filters:{enabled:function(elem){return elem.disabled===false&&elem.type!=="hidden";},disabled:function(elem){return elem.disabled===true;},checked:function(elem){return elem.checked===true;},selected:function(elem){elem.parentNode.selectedIndex;return elem.selected===true;},parent:function(elem){return!!elem.firstChild;},empty:function(elem){return!elem.firstChild;},has:function(elem,i,match){return!!Sizzle(match[3],elem).length;},header:function(elem){return/h\d/i.test(elem.nodeName);},text:function(elem){return"text"===elem.type;},radio:function(elem){return"radio"===elem.type;},checkbox:function(elem){return"checkbox"===elem.type;},file:function(elem){return"file"===elem.type;},password:function(elem){return"password"===elem.type;},submit:function(elem){return"submit"===elem.type;},image:function(elem){return"image"===elem.type;},reset:function(elem){return"reset"===elem.type;},button:function(elem){return"button"===elem.type||elem.nodeName.toUpperCase()==="BUTTON";},input:function(elem){return/input|select|textarea|button/i.test(elem.nodeName);}},setFilters:{first:function(elem,i){return i===0;},last:function(elem,i,match,array){return i===array.length-1;},even:function(elem,i){return i%2===0;},odd:function(elem,i){return i%2===1;},lt:function(elem,i,match){return imatch[3]-0;},nth:function(elem,i,match){return match[3]-0==i;},eq:function(elem,i,match){return match[3]-0==i;}},filter:{PSEUDO:function(elem,match,i,array){var name=match[1],filter=Expr.filters[name];if(filter){return filter(elem,i,match,array);}else if(name==="contains"){return(elem.textContent||elem.innerText||"").indexOf(match[3])>=0;}else if(name==="not"){var not=match[3];for(var i=0,l=not.length;i=0);}}},ID:function(elem,match){return elem.nodeType===1&&elem.getAttribute("id")===match;},TAG:function(elem,match){return(match==="*"&&elem.nodeType===1)||elem.nodeName===match;},CLASS:function(elem,match){return(" "+(elem.className||elem.getAttribute("class"))+" ").indexOf(match)>-1;},ATTR:function(elem,match){var name=match[1],result=Expr.attrHandle[name]?Expr.attrHandle[name](elem):elem[name]!=null?elem[name]:elem.getAttribute(name),value=result+"",type=match[2],check=match[4];return result==null?type==="!=":type==="="?value===check:type==="*="?value.indexOf(check)>=0:type==="~="?(" "+value+" ").indexOf(check)>=0:!check?value&&result!==false:type==="!="?value!=check:type==="^="?value.indexOf(check)===0:type==="$="?value.substr(value.length-check.length)===check:type==="|="?value===check||value.substr(0,check.length+1)===check+"-":false;},POS:function(elem,match,i,array){var name=match[2],filter=Expr.setFilters[name];if(filter){return filter(elem,i,match,array);}}}};var origPOS=Expr.match.POS;for(var type in Expr.match){Expr.match[type]=RegExp(Expr.match[type].source+/(?![^\[]*\])(?![^\(]*\))/.source);} +var makeArray=function(array,results){array=Array.prototype.slice.call(array);if(results){results.push.apply(results,array);return results;} +return array;};try{Array.prototype.slice.call(document.documentElement.childNodes);}catch(e){makeArray=function(array,results){var ret=results||[];if(toString.call(array)==="[object Array]"){Array.prototype.push.apply(ret,array);}else{if(typeof array.length==="number"){for(var i=0,l=array.length;i";var root=document.documentElement;root.insertBefore(form,root.firstChild);if(!!document.getElementById(id)){Expr.find.ID=function(match,context,isXML){if(typeof context.getElementById!=="undefined"&&!isXML){var m=context.getElementById(match[1]);return m?m.id===match[1]||typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id").nodeValue===match[1]?[m]:undefined:[];}};Expr.filter.ID=function(elem,match){var node=typeof elem.getAttributeNode!=="undefined"&&elem.getAttributeNode("id");return elem.nodeType===1&&node&&node.nodeValue===match;};} +root.removeChild(form);})();(function(){var div=document.createElement("div");div.appendChild(document.createComment(""));if(div.getElementsByTagName("*").length>0){Expr.find.TAG=function(match,context){var results=context.getElementsByTagName(match[1]);if(match[1]==="*"){var tmp=[];for(var i=0;results[i];i++){if(results[i].nodeType===1){tmp.push(results[i]);}} +results=tmp;} +return results;};} +div.innerHTML="";if(div.firstChild&&typeof div.firstChild.getAttribute!=="undefined"&&div.firstChild.getAttribute("href")!=="#"){Expr.attrHandle.href=function(elem){return elem.getAttribute("href",2);};}})();if(document.querySelectorAll)(function(){var oldSizzle=Sizzle,div=document.createElement("div");div.innerHTML="

    ";if(div.querySelectorAll&&div.querySelectorAll(".TEST").length===0){return;} +Sizzle=function(query,context,extra,seed){context=context||document;if(!seed&&context.nodeType===9&&!isXML(context)){try{return makeArray(context.querySelectorAll(query),extra);}catch(e){}} +return oldSizzle(query,context,extra,seed);};Sizzle.find=oldSizzle.find;Sizzle.filter=oldSizzle.filter;Sizzle.selectors=oldSizzle.selectors;Sizzle.matches=oldSizzle.matches;})();if(document.getElementsByClassName&&document.documentElement.getElementsByClassName)(function(){var div=document.createElement("div");div.innerHTML="
    ";if(div.getElementsByClassName("e").length===0) +return;div.lastChild.className="e";if(div.getElementsByClassName("e").length===1) +return;Expr.order.splice(1,0,"CLASS");Expr.find.CLASS=function(match,context,isXML){if(typeof context.getElementsByClassName!=="undefined"&&!isXML){return context.getElementsByClassName(match[1]);}};})();function dirNodeCheck(dir,cur,doneName,checkSet,nodeCheck,isXML){var sibDir=dir=="previousSibling"&&!isXML;for(var i=0,l=checkSet.length;i0){match=elem;break;}} +elem=elem[dir];} +checkSet[i]=match;}}} +var contains=document.compareDocumentPosition?function(a,b){return a.compareDocumentPosition(b)&16;}:function(a,b){return a!==b&&(a.contains?a.contains(b):true);};var isXML=function(elem){return elem.nodeType===9&&elem.documentElement.nodeName!=="HTML"||!!elem.ownerDocument&&isXML(elem.ownerDocument);};var posProcess=function(selector,context){var tmpSet=[],later="",match,root=context.nodeType?[context]:context;while((match=Expr.match.PSEUDO.exec(selector))){later+=match[0];selector=selector.replace(Expr.match.PSEUDO,"");} +selector=Expr.relative[selector]?selector+"*":selector;for(var i=0,l=root.length;i0||elem.offsetHeight>0;};Sizzle.selectors.filters.animated=function(elem){return jQuery.grep(jQuery.timers,function(fn){return elem===fn.elem;}).length;};jQuery.multiFilter=function(expr,elems,not){if(not){expr=":not("+expr+")";} +return Sizzle.matches(expr,elems);};jQuery.dir=function(elem,dir){var matched=[],cur=elem[dir];while(cur&&cur!=document){if(cur.nodeType==1) +matched.push(cur);cur=cur[dir];} +return matched;};jQuery.nth=function(cur,result,dir,elem){result=result||1;var num=0;for(;cur;cur=cur[dir]) +if(cur.nodeType==1&&++num==result) +break;return cur;};jQuery.sibling=function(n,elem){var r=[];for(;n;n=n.nextSibling){if(n.nodeType==1&&n!=elem) +r.push(n);} +return r;};return;window.Sizzle=Sizzle;})();jQuery.event={add:function(elem,types,handler,data){if(elem.nodeType==3||elem.nodeType==8) +return;if(elem.setInterval&&elem!=window) +elem=window;if(!handler.guid) +handler.guid=this.guid++;if(data!==undefined){var fn=handler;handler=this.proxy(fn);handler.data=data;} +var events=jQuery.data(elem,"events")||jQuery.data(elem,"events",{}),handle=jQuery.data(elem,"handle")||jQuery.data(elem,"handle",function(){return typeof jQuery!=="undefined"&&!jQuery.event.triggered?jQuery.event.handle.apply(arguments.callee.elem,arguments):undefined;});handle.elem=elem;jQuery.each(types.split(/\s+/),function(index,type){var namespaces=type.split(".");type=namespaces.shift();handler.type=namespaces.slice().sort().join(".");var handlers=events[type];if(jQuery.event.specialAll[type]) +jQuery.event.specialAll[type].setup.call(elem,data,namespaces);if(!handlers){handlers=events[type]={};if(!jQuery.event.special[type]||jQuery.event.special[type].setup.call(elem,data,namespaces)===false){if(elem.addEventListener) +elem.addEventListener(type,handle,false);else if(elem.attachEvent) +elem.attachEvent("on"+type,handle);}} +handlers[handler.guid]=handler;jQuery.event.global[type]=true;});elem=null;},guid:1,global:{},remove:function(elem,types,handler){if(elem.nodeType==3||elem.nodeType==8) +return;var events=jQuery.data(elem,"events"),ret,index;if(events){if(types===undefined||(typeof types==="string"&&types.charAt(0)==".")) +for(var type in events) +this.remove(elem,type+(types||""));else{if(types.type){handler=types.handler;types=types.type;} +jQuery.each(types.split(/\s+/),function(index,type){var namespaces=type.split(".");type=namespaces.shift();var namespace=RegExp("(^|\\.)"+namespaces.slice().sort().join(".*\\.")+"(\\.|$)");if(events[type]){if(handler) +delete events[type][handler.guid];else +for(var handle in events[type]) +if(namespace.test(events[type][handle].type)) +delete events[type][handle];if(jQuery.event.specialAll[type]) +jQuery.event.specialAll[type].teardown.call(elem,namespaces);for(ret in events[type])break;if(!ret){if(!jQuery.event.special[type]||jQuery.event.special[type].teardown.call(elem,namespaces)===false){if(elem.removeEventListener) +elem.removeEventListener(type,jQuery.data(elem,"handle"),false);else if(elem.detachEvent) +elem.detachEvent("on"+type,jQuery.data(elem,"handle"));} +ret=null;delete events[type];}}});} +for(ret in events)break;if(!ret){var handle=jQuery.data(elem,"handle");if(handle)handle.elem=null;jQuery.removeData(elem,"events");jQuery.removeData(elem,"handle");}}},trigger:function(event,data,elem,bubbling){var type=event.type||event;if(!bubbling){event=typeof event==="object"?event[expando]?event:jQuery.extend(jQuery.Event(type),event):jQuery.Event(type);if(type.indexOf("!")>=0){event.type=type=type.slice(0,-1);event.exclusive=true;} +if(!elem){event.stopPropagation();if(this.global[type]) +jQuery.each(jQuery.cache,function(){if(this.events&&this.events[type]) +jQuery.event.trigger(event,data,this.handle.elem);});} +if(!elem||elem.nodeType==3||elem.nodeType==8) +return undefined;event.result=undefined;event.target=elem;data=jQuery.makeArray(data);data.unshift(event);} +event.currentTarget=elem;var handle=jQuery.data(elem,"handle");if(handle) +handle.apply(elem,data);if((!elem[type]||(jQuery.nodeName(elem,'a')&&type=="click"))&&elem["on"+type]&&elem["on"+type].apply(elem,data)===false) +event.result=false;if(!bubbling&&elem[type]&&!event.isDefaultPrevented()&&!(jQuery.nodeName(elem,'a')&&type=="click")){this.triggered=true;try{elem[type]();}catch(e){}} +this.triggered=false;if(!event.isPropagationStopped()){var parent=elem.parentNode||elem.ownerDocument;if(parent) +jQuery.event.trigger(event,data,parent,true);}},handle:function(event){var all,handlers;event=arguments[0]=jQuery.event.fix(event||window.event);event.currentTarget=this;var namespaces=event.type.split(".");event.type=namespaces.shift();all=!namespaces.length&&!event.exclusive;var namespace=RegExp("(^|\\.)"+namespaces.slice().sort().join(".*\\.")+"(\\.|$)");handlers=(jQuery.data(this,"events")||{})[event.type];for(var j in handlers){var handler=handlers[j];if(all||namespace.test(handler.type)){event.handler=handler;event.data=handler.data;var ret=handler.apply(this,arguments);if(ret!==undefined){event.result=ret;if(ret===false){event.preventDefault();event.stopPropagation();}} +if(event.isImmediatePropagationStopped()) +break;}}},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(event){if(event[expando]) +return event;var originalEvent=event;event=jQuery.Event(originalEvent);for(var i=this.props.length,prop;i;){prop=this.props[--i];event[prop]=originalEvent[prop];} +if(!event.target) +event.target=event.srcElement||document;if(event.target.nodeType==3) +event.target=event.target.parentNode;if(!event.relatedTarget&&event.fromElement) +event.relatedTarget=event.fromElement==event.target?event.toElement:event.fromElement;if(event.pageX==null&&event.clientX!=null){var doc=document.documentElement,body=document.body;event.pageX=event.clientX+(doc&&doc.scrollLeft||body&&body.scrollLeft||0)-(doc.clientLeft||0);event.pageY=event.clientY+(doc&&doc.scrollTop||body&&body.scrollTop||0)-(doc.clientTop||0);} +if(!event.which&&((event.charCode||event.charCode===0)?event.charCode:event.keyCode)) +event.which=event.charCode||event.keyCode;if(!event.metaKey&&event.ctrlKey) +event.metaKey=event.ctrlKey;if(!event.which&&event.button) +event.which=(event.button&1?1:(event.button&2?3:(event.button&4?2:0)));return event;},proxy:function(fn,proxy){proxy=proxy||function(){return fn.apply(this,arguments);};proxy.guid=fn.guid=fn.guid||proxy.guid||this.guid++;return proxy;},special:{ready:{setup:bindReady,teardown:function(){}}},specialAll:{live:{setup:function(selector,namespaces){jQuery.event.add(this,namespaces[0],liveHandler);},teardown:function(namespaces){if(namespaces.length){var remove=0,name=RegExp("(^|\\.)"+namespaces[0]+"(\\.|$)");jQuery.each((jQuery.data(this,"events").live||{}),function(){if(name.test(this.type)) +remove++;});if(remove<1) +jQuery.event.remove(this,namespaces[0],liveHandler);}}}}};jQuery.Event=function(src){if(!this.preventDefault) +return new jQuery.Event(src);if(src&&src.type){this.originalEvent=src;this.type=src.type;}else +this.type=src;this.timeStamp=now();this[expando]=true;};function returnFalse(){return false;} +function returnTrue(){return true;} +jQuery.Event.prototype={preventDefault:function(){this.isDefaultPrevented=returnTrue;var e=this.originalEvent;if(!e) +return;if(e.preventDefault) +e.preventDefault();e.returnValue=false;},stopPropagation:function(){this.isPropagationStopped=returnTrue;var e=this.originalEvent;if(!e) +return;if(e.stopPropagation) +e.stopPropagation();e.cancelBubble=true;},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=returnTrue;this.stopPropagation();},isDefaultPrevented:returnFalse,isPropagationStopped:returnFalse,isImmediatePropagationStopped:returnFalse};var withinElement=function(event){var parent=event.relatedTarget;while(parent&&parent!=this) +try{parent=parent.parentNode;} +catch(e){parent=this;} +if(parent!=this){event.type=event.data;jQuery.event.handle.apply(this,arguments);}};jQuery.each({mouseover:'mouseenter',mouseout:'mouseleave'},function(orig,fix){jQuery.event.special[fix]={setup:function(){jQuery.event.add(this,orig,withinElement,fix);},teardown:function(){jQuery.event.remove(this,orig,withinElement);}};});jQuery.fn.extend({bind:function(type,data,fn){return type=="unload"?this.one(type,data,fn):this.each(function(){jQuery.event.add(this,type,fn||data,fn&&data);});},one:function(type,data,fn){var one=jQuery.event.proxy(fn||data,function(event){jQuery(this).unbind(event,one);return(fn||data).apply(this,arguments);});return this.each(function(){jQuery.event.add(this,type,one,fn&&data);});},unbind:function(type,fn){return this.each(function(){jQuery.event.remove(this,type,fn);});},trigger:function(type,data){return this.each(function(){jQuery.event.trigger(type,data,this);});},triggerHandler:function(type,data){if(this[0]){var event=jQuery.Event(type);event.preventDefault();event.stopPropagation();jQuery.event.trigger(event,data,this[0]);return event.result;}},toggle:function(fn){var args=arguments,i=1;while(i=0){var selector=url.slice(off,url.length);url=url.slice(0,off);} +var type="GET";if(params) +if(jQuery.isFunction(params)){callback=params;params=null;}else if(typeof params==="object"){params=jQuery.param(params);type="POST";} +var self=this;jQuery.ajax({url:url,type:type,dataType:"html",data:params,complete:function(res,status){if(status=="success"||status=="notmodified") +self.html(selector?jQuery("
    ").append(res.responseText.replace(//g,"")).find(selector):res.responseText);if(callback) +self.each(callback,[res.responseText,status,res]);}});return this;},serialize:function(){return jQuery.param(this.serializeArray());},serializeArray:function(){return this.map(function(){return this.elements?jQuery.makeArray(this.elements):this;}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password|search/i.test(this.type));}).map(function(i,elem){var val=jQuery(this).val();return val==null?null:jQuery.isArray(val)?jQuery.map(val,function(val,i){return{name:elem.name,value:val};}):{name:elem.name,value:val};}).get();}});jQuery.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(i,o){jQuery.fn[o]=function(f){return this.bind(o,f);};});var jsc=now();jQuery.extend({get:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data=null;} +return jQuery.ajax({type:"GET",url:url,data:data,success:callback,dataType:type});},getScript:function(url,callback){return jQuery.get(url,null,callback,"script");},getJSON:function(url,data,callback){return jQuery.get(url,data,callback,"json");},post:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data={};} +return jQuery.ajax({type:"POST",url:url,data:data,success:callback,dataType:type});},ajaxSetup:function(settings){jQuery.extend(jQuery.ajaxSettings,settings);},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:function(){return window.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest();},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(s){s=jQuery.extend(true,s,jQuery.extend(true,{},jQuery.ajaxSettings,s));var jsonp,jsre=/=\?(&|$)/g,status,data,type=s.type.toUpperCase();if(s.data&&s.processData&&typeof s.data!=="string") +s.data=jQuery.param(s.data);if(s.dataType=="jsonp"){if(type=="GET"){if(!s.url.match(jsre)) +s.url+=(s.url.match(/\?/)?"&":"?")+(s.jsonp||"callback")+"=?";}else if(!s.data||!s.data.match(jsre)) +s.data=(s.data?s.data+"&":"")+(s.jsonp||"callback")+"=?";s.dataType="json";} +if(s.dataType=="json"&&(s.data&&s.data.match(jsre)||s.url.match(jsre))){jsonp="jsonp"+jsc++;if(s.data) +s.data=(s.data+"").replace(jsre,"="+jsonp+"$1");s.url=s.url.replace(jsre,"="+jsonp+"$1");s.dataType="script";window[jsonp]=function(tmp){data=tmp;success();complete();window[jsonp]=undefined;try{delete window[jsonp];}catch(e){} +if(head) +head.removeChild(script);};} +if(s.dataType=="script"&&s.cache==null) +s.cache=false;if(s.cache===false&&type=="GET"){var ts=now();var ret=s.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+ts+"$2");s.url=ret+((ret==s.url)?(s.url.match(/\?/)?"&":"?")+"_="+ts:"");} +if(s.data&&type=="GET"){s.url+=(s.url.match(/\?/)?"&":"?")+s.data;s.data=null;} +if(s.global&&!jQuery.active++) +jQuery.event.trigger("ajaxStart");var parts=/^(\w+:)?\/\/([^\/?#]+)/.exec(s.url);if(s.dataType=="script"&&type=="GET"&&parts&&(parts[1]&&parts[1]!=location.protocol||parts[2]!=location.host)){var head=document.getElementsByTagName("head")[0];var script=document.createElement("script");script.src=s.url;if(s.scriptCharset) +script.charset=s.scriptCharset;if(!jsonp){var done=false;script.onload=script.onreadystatechange=function(){if(!done&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){done=true;success();complete();script.onload=script.onreadystatechange=null;head.removeChild(script);}};} +head.appendChild(script);return undefined;} +var requestDone=false;var xhr=s.xhr();if(s.username) +xhr.open(type,s.url,s.async,s.username,s.password);else +xhr.open(type,s.url,s.async);try{if(s.data) +xhr.setRequestHeader("Content-Type",s.contentType);if(s.ifModified) +xhr.setRequestHeader("If-Modified-Since",jQuery.lastModified[s.url]||"Thu, 01 Jan 1970 00:00:00 GMT");xhr.setRequestHeader("X-Requested-With","XMLHttpRequest");xhr.setRequestHeader("Accept",s.dataType&&s.accepts[s.dataType]?s.accepts[s.dataType]+", */*":s.accepts._default);}catch(e){} +if(s.beforeSend&&s.beforeSend(xhr,s)===false){if(s.global&&!--jQuery.active) +jQuery.event.trigger("ajaxStop");xhr.abort();return false;} +if(s.global) +jQuery.event.trigger("ajaxSend",[xhr,s]);var onreadystatechange=function(isTimeout){if(xhr.readyState==0){if(ival){clearInterval(ival);ival=null;if(s.global&&!--jQuery.active) +jQuery.event.trigger("ajaxStop");}}else if(!requestDone&&xhr&&(xhr.readyState==4||isTimeout=="timeout")){requestDone=true;if(ival){clearInterval(ival);ival=null;} +status=isTimeout=="timeout"?"timeout":!jQuery.httpSuccess(xhr)?"error":s.ifModified&&jQuery.httpNotModified(xhr,s.url)?"notmodified":"success";if(status=="success"){try{data=jQuery.httpData(xhr,s.dataType,s);}catch(e){status="parsererror";}} +if(status=="success"){var modRes;try{modRes=xhr.getResponseHeader("Last-Modified");}catch(e){} +if(s.ifModified&&modRes) +jQuery.lastModified[s.url]=modRes;if(!jsonp) +success();}else +jQuery.handleError(s,xhr,status);complete();if(isTimeout) +xhr.abort();if(s.async) +xhr=null;}};if(s.async){var ival=setInterval(onreadystatechange,13);if(s.timeout>0) +setTimeout(function(){if(xhr&&!requestDone) +onreadystatechange("timeout");},s.timeout);} +try{xhr.send(s.data);}catch(e){jQuery.handleError(s,xhr,null,e);} +if(!s.async) +onreadystatechange();function success(){if(s.success) +s.success(data,status);if(s.global) +jQuery.event.trigger("ajaxSuccess",[xhr,s]);} +function complete(){if(s.complete) +s.complete(xhr,status);if(s.global) +jQuery.event.trigger("ajaxComplete",[xhr,s]);if(s.global&&!--jQuery.active) +jQuery.event.trigger("ajaxStop");} +return xhr;},handleError:function(s,xhr,status,e){if(s.error)s.error(xhr,status,e);if(s.global) +jQuery.event.trigger("ajaxError",[xhr,s,e]);},active:0,httpSuccess:function(xhr){try{return!xhr.status&&location.protocol=="file:"||(xhr.status>=200&&xhr.status<300)||xhr.status==304||xhr.status==1223;}catch(e){} +return false;},httpNotModified:function(xhr,url){try{var xhrRes=xhr.getResponseHeader("Last-Modified");return xhr.status==304||xhrRes==jQuery.lastModified[url];}catch(e){} +return false;},httpData:function(xhr,type,s){var ct=xhr.getResponseHeader("content-type"),xml=type=="xml"||!type&&ct&&ct.indexOf("xml")>=0,data=xml?xhr.responseXML:xhr.responseText;if(xml&&data.documentElement.tagName=="parsererror") +throw"parsererror";if(s&&s.dataFilter) +data=s.dataFilter(data,type);if(typeof data==="string"){if(type=="script") +jQuery.globalEval(data);if(type=="json") +data=window["eval"]("("+data+")");} +return data;},param:function(a){var s=[];function add(key,value){s[s.length]=encodeURIComponent(key)+'='+encodeURIComponent(value);};if(jQuery.isArray(a)||a.jquery) +jQuery.each(a,function(){add(this.name,this.value);});else +for(var j in a) +if(jQuery.isArray(a[j])) +jQuery.each(a[j],function(){add(j,this);});else +add(j,jQuery.isFunction(a[j])?a[j]():a[j]);return s.join("&").replace(/%20/g,"+");}});var elemdisplay={},timerId,fxAttrs=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];function genFx(type,num){var obj={};jQuery.each(fxAttrs.concat.apply([],fxAttrs.slice(0,num)),function(){obj[this]=type;});return obj;} +jQuery.fn.extend({show:function(speed,callback){if(speed){return this.animate(genFx("show",3),speed,callback);}else{for(var i=0,l=this.length;i").appendTo("body");display=elem.css("display");if(display==="none") +display="block";elem.remove();elemdisplay[tagName]=display;} +jQuery.data(this[i],"olddisplay",display);}} +for(var i=0,l=this.length;i=0;i--) +if(timers[i].elem==this){if(gotoEnd) +timers[i](true);timers.splice(i,1);}});if(!gotoEnd) +this.dequeue();return this;}});jQuery.each({slideDown:genFx("show",1),slideUp:genFx("hide",1),slideToggle:genFx("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(name,props){jQuery.fn[name]=function(speed,callback){return this.animate(props,speed,callback);};});jQuery.extend({speed:function(speed,easing,fn){var opt=typeof speed==="object"?speed:{complete:fn||!fn&&easing||jQuery.isFunction(speed)&&speed,duration:speed,easing:fn&&easing||easing&&!jQuery.isFunction(easing)&&easing};opt.duration=jQuery.fx.off?0:typeof opt.duration==="number"?opt.duration:jQuery.fx.speeds[opt.duration]||jQuery.fx.speeds._default;opt.old=opt.complete;opt.complete=function(){if(opt.queue!==false) +jQuery(this).dequeue();if(jQuery.isFunction(opt.old)) +opt.old.call(this);};return opt;},easing:{linear:function(p,n,firstNum,diff){return firstNum+diff*p;},swing:function(p,n,firstNum,diff){return((-Math.cos(p*Math.PI)/2)+0.5)*diff+firstNum;}},timers:[],fx:function(elem,options,prop){this.options=options;this.elem=elem;this.prop=prop;if(!options.orig) +options.orig={};}});jQuery.fx.prototype={update:function(){if(this.options.step) +this.options.step.call(this.elem,this.now,this);(jQuery.fx.step[this.prop]||jQuery.fx.step._default)(this);if((this.prop=="height"||this.prop=="width")&&this.elem.style) +this.elem.style.display="block";},cur:function(force){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null)) +return this.elem[this.prop];var r=parseFloat(jQuery.css(this.elem,this.prop,force));return r&&r>-10000?r:parseFloat(jQuery.curCSS(this.elem,this.prop))||0;},custom:function(from,to,unit){this.startTime=now();this.start=from;this.end=to;this.unit=unit||this.unit||"px";this.now=this.start;this.pos=this.state=0;var self=this;function t(gotoEnd){return self.step(gotoEnd);} +t.elem=this.elem;if(t()&&jQuery.timers.push(t)&&!timerId){timerId=setInterval(function(){var timers=jQuery.timers;for(var i=0;i=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var done=true;for(var i in this.options.curAnim) +if(this.options.curAnim[i]!==true) +done=false;if(done){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(jQuery.css(this.elem,"display")=="none") +this.elem.style.display="block";} +if(this.options.hide) +jQuery(this.elem).hide();if(this.options.hide||this.options.show) +for(var p in this.options.curAnim) +jQuery.attr(this.elem.style,p,this.options.orig[p]);this.options.complete.call(this.elem);} +return false;}else{var n=t-this.startTime;this.state=n/this.options.duration;this.pos=jQuery.easing[this.options.easing||(jQuery.easing.swing?"swing":"linear")](this.state,n,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update();} +return true;}};jQuery.extend(jQuery.fx,{speeds:{slow:600,fast:200,_default:400},step:{opacity:function(fx){jQuery.attr(fx.elem.style,"opacity",fx.now);},_default:function(fx){if(fx.elem.style&&fx.elem.style[fx.prop]!=null) +fx.elem.style[fx.prop]=fx.now+fx.unit;else +fx.elem[fx.prop]=fx.now;}}});if(document.documentElement["getBoundingClientRect"]) +jQuery.fn.offset=function(){if(!this[0])return{top:0,left:0};if(this[0]===this[0].ownerDocument.body)return jQuery.offset.bodyOffset(this[0]);var box=this[0].getBoundingClientRect(),doc=this[0].ownerDocument,body=doc.body,docElem=doc.documentElement,clientTop=docElem.clientTop||body.clientTop||0,clientLeft=docElem.clientLeft||body.clientLeft||0,top=box.top+(self.pageYOffset||jQuery.boxModel&&docElem.scrollTop||body.scrollTop)-clientTop,left=box.left+(self.pageXOffset||jQuery.boxModel&&docElem.scrollLeft||body.scrollLeft)-clientLeft;return{top:top,left:left};};else +jQuery.fn.offset=function(){if(!this[0])return{top:0,left:0};if(this[0]===this[0].ownerDocument.body)return jQuery.offset.bodyOffset(this[0]);jQuery.offset.initialized||jQuery.offset.initialize();var elem=this[0],offsetParent=elem.offsetParent,prevOffsetParent=elem,doc=elem.ownerDocument,computedStyle,docElem=doc.documentElement,body=doc.body,defaultView=doc.defaultView,prevComputedStyle=defaultView.getComputedStyle(elem,null),top=elem.offsetTop,left=elem.offsetLeft;while((elem=elem.parentNode)&&elem!==body&&elem!==docElem){computedStyle=defaultView.getComputedStyle(elem,null);top-=elem.scrollTop,left-=elem.scrollLeft;if(elem===offsetParent){top+=elem.offsetTop,left+=elem.offsetLeft;if(jQuery.offset.doesNotAddBorder&&!(jQuery.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(elem.tagName))) +top+=parseInt(computedStyle.borderTopWidth,10)||0,left+=parseInt(computedStyle.borderLeftWidth,10)||0;prevOffsetParent=offsetParent,offsetParent=elem.offsetParent;} +if(jQuery.offset.subtractsBorderForOverflowNotVisible&&computedStyle.overflow!=="visible") +top+=parseInt(computedStyle.borderTopWidth,10)||0,left+=parseInt(computedStyle.borderLeftWidth,10)||0;prevComputedStyle=computedStyle;} +if(prevComputedStyle.position==="relative"||prevComputedStyle.position==="static") +top+=body.offsetTop,left+=body.offsetLeft;if(prevComputedStyle.position==="fixed") +top+=Math.max(docElem.scrollTop,body.scrollTop),left+=Math.max(docElem.scrollLeft,body.scrollLeft);return{top:top,left:left};};jQuery.offset={initialize:function(){if(this.initialized)return;var body=document.body,container=document.createElement('div'),innerDiv,checkDiv,table,td,rules,prop,bodyMarginTop=body.style.marginTop,html='
    ';rules={position:'absolute',top:0,left:0,margin:0,border:0,width:'1px',height:'1px',visibility:'hidden'};for(prop in rules)container.style[prop]=rules[prop];container.innerHTML=html;body.insertBefore(container,body.firstChild);innerDiv=container.firstChild,checkDiv=innerDiv.firstChild,td=innerDiv.nextSibling.firstChild.firstChild;this.doesNotAddBorder=(checkDiv.offsetTop!==5);this.doesAddBorderForTableAndCells=(td.offsetTop===5);innerDiv.style.overflow='hidden',innerDiv.style.position='relative';this.subtractsBorderForOverflowNotVisible=(checkDiv.offsetTop===-5);body.style.marginTop='1px';this.doesNotIncludeMarginInBodyOffset=(body.offsetTop===0);body.style.marginTop=bodyMarginTop;body.removeChild(container);this.initialized=true;},bodyOffset:function(body){jQuery.offset.initialized||jQuery.offset.initialize();var top=body.offsetTop,left=body.offsetLeft;if(jQuery.offset.doesNotIncludeMarginInBodyOffset) +top+=parseInt(jQuery.curCSS(body,'marginTop',true),10)||0,left+=parseInt(jQuery.curCSS(body,'marginLeft',true),10)||0;return{top:top,left:left};}};jQuery.fn.extend({position:function(){var left=0,top=0,results;if(this[0]){var offsetParent=this.offsetParent(),offset=this.offset(),parentOffset=/^body|html$/i.test(offsetParent[0].tagName)?{top:0,left:0}:offsetParent.offset();offset.top-=num(this,'marginTop');offset.left-=num(this,'marginLeft');parentOffset.top+=num(offsetParent,'borderTopWidth');parentOffset.left+=num(offsetParent,'borderLeftWidth');results={top:offset.top-parentOffset.top,left:offset.left-parentOffset.left};} +return results;},offsetParent:function(){var offsetParent=this[0].offsetParent||document.body;while(offsetParent&&(!/^body|html$/i.test(offsetParent.tagName)&&jQuery.css(offsetParent,'position')=='static')) +offsetParent=offsetParent.offsetParent;return jQuery(offsetParent);}});jQuery.each(['Left','Top'],function(i,name){var method='scroll'+name;jQuery.fn[method]=function(val){if(!this[0])return null;return val!==undefined?this.each(function(){this==window||this==document?window.scrollTo(!i?val:jQuery(window).scrollLeft(),i?val:jQuery(window).scrollTop()):this[method]=val;}):this[0]==window||this[0]==document?self[i?'pageYOffset':'pageXOffset']||jQuery.boxModel&&document.documentElement[method]||document.body[method]:this[0][method];};});jQuery.each(["Height","Width"],function(i,name){var tl=i?"Left":"Top",br=i?"Right":"Bottom",lower=name.toLowerCase();jQuery.fn["inner"+name]=function(){return this[0]?jQuery.css(this[0],lower,false,"padding"):null;};jQuery.fn["outer"+name]=function(margin){return this[0]?jQuery.css(this[0],lower,false,margin?"margin":"border"):null;};var type=name.toLowerCase();jQuery.fn[type]=function(size){return this[0]==window?document.compatMode=="CSS1Compat"&&document.documentElement["client"+name]||document.body["client"+name]:this[0]==document?Math.max(document.documentElement["client"+name],document.body["scroll"+name],document.documentElement["scroll"+name],document.body["offset"+name],document.documentElement["offset"+name]):size===undefined?(this.length?jQuery.css(this[0],type):null):this.css(type,typeof size==="string"?size:size+"px");};});})(); \ No newline at end of file diff --git a/admin/js/jquery/jquery.modal.js b/admin/js/jquery/jquery.modal.js new file mode 100644 index 0000000..03703e9 --- /dev/null +++ b/admin/js/jquery/jquery.modal.js @@ -0,0 +1,17 @@ + +(function($){if(/^1\.(0|1)\./.test($.fn.jquery)||/^1\.2\.(0|1|2|3|4|5)/.test($.fn.jquery)){throw('Modal requieres jQuery v1.2.6 or later. You are using v'+$.fn.jquery);return;} +$.modal=function(data,params){this.params=$.extend(this.params,params);return this.build(data);};$.modal.version='1.0';$.modal.prototype={params:{width:null,height:null,speed:300,opacity:0.9,loader_img:'loader.gif',loader_txt:'loading...',close_img:'close.png',close_txt:'close',on_close:function(){}},ctrl:{box:$(),loader:$(),overlay:$('
    '),hidden:$()},build:function(data){this.ctrl.loader=$('
    '+this.params.loader_txt+'
    ');this.addOverlay();var size=this.getBoxSize(this.ctrl.loading);this.ctrl.box=this.getBox(this.ctrl.loading,{top:Math.round($(window).height()/2+$(window).scrollTop()-size.h/2),left:Math.round($(window).width()/2+$(window).scrollLeft()-size.w/2),visibility:'hidden'});this.ctrl.overlay.after(this.ctrl.box);if(data!=undefined){this.updateBox(data);this.data=data;} +return this;},updateBox:function(data,fn){var This=this;this.hideCloser();fn=$.isFunction(fn)?fn:function(){};var content=$('div.jq-modal-content',this.ctrl.box);content.empty().append(this.ctrl.loader);var size=this.getBoxSize(data,this.params.width,this.params.height);var top=Math.round($(window).height()/2+$(window).scrollTop()-size.h/2);var left=Math.round($(window).width()/2+$(window).scrollLeft()-size.w/2);this.ctrl.box.css('visibility','visible').animate({top:top<0?0:top,left:left<0?0:left,width:size.w,height:size.h},this.params.speed,function(){This.setContentSize(content,This.params.width,This.params.height);content.empty().append(data).css('opacity',0).fadeTo(This.params.speed,1,function(){fn.call(This,content);});This.showCloser();});},getBox:function(data,css,content_w,content_h){var box=$('
    '+'
    '+'
    ').css($.extend({position:'absolute',top:0,left:0,zIndex:100},css));if(data!=undefined){$('div.jq-modal-content',box).append(data);} +this.setContentSize($('div.jq-modal-content',box),content_w,content_h);return box;},getBoxSize:function(data,content_w,content_h){var box=this.getBox(data,{visibility:'hidden'},content_w,content_h);this.ctrl.overlay.after(box);var size={w:box.width(),h:box.height()};box.remove();box=null;return size;},setContentSize:function(content,w,h){content.css({width:w>0?w:'auto',height:h>0?h:'auto'});},showCloser:function(){if($('div.jq-modal-closer',this.ctrl.box).length>0){$('div.jq-modal-closer',this.ctrl.box).show();return;} +$('div.jq-modal-container',this.ctrl.box).append('');var This=this;var close=$('div.jq-modal-closer a',this.ctrl.box) +close.css({background:'transparent url('+this.params.close_img+') no-repeat'}).click(function(){This.removeOverlay();return false;});if(document.all){close[0].runtimeStyle.filter='progid:DXImageTransform.Microsoft.AlphaImageLoader(src="'+this.params.close_img+'", sizingMethod="crop")';close[0].runtimeStyle.backgroundImage="none"}},hideCloser:function(){$('div.jq-modal-closer',this.ctrl.box).hide();},addOverlay:function(){var This=this;if(document.all){this.ctrl.hidden=$('select:visible, object:visible, embed:visible').css('visibility','hidden');} +this.ctrl.overlay.css({backgroundColor:'#000',position:'absolute',top:0,left:0,zIndex:90,opacity:this.params.opacity}).appendTo('body').dblclick(function(){This.removeOverlay();});this.resizeOverlay({data:this.ctrl});$(window).bind('resize.modal',this.ctrl,this.resizeOverlay);$(document).bind('keypress.modal',this,this.keyRemove);},resizeOverlay:function(e){e.data.overlay.css({width:$(window).width(),height:$(document).height()});if(e.data.box.parents('body').length>0){var top=Math.round($(window).height()/2+$(window).scrollTop()-e.data.box.height()/2);var left=Math.round($(window).width()/2+$(window).scrollLeft()-e.data.box.width()/2);e.data.box.css({top:top<0?0:top,left:left<0?0:left});}},keyRemove:function(e){if(e.keyCode==27){e.data.removeOverlay();} +return true;},removeOverlay:function(){$(window).unbind('resize.modal');$(document).unbind('keypress');this.params.on_close.apply(this);this.ctrl.overlay.remove();this.ctrl.hidden.css('visibility','visible');this.ctrl.box.remove();this.ctrl.box=$();}};})(jQuery);(function($){$.fn.modalImages=function(params){params=$.extend(this.params,params);var links=new Array();this.each(function(){if($(this).attr('href')==''||$(this).attr('href')==undefined||$(this).attr('href')=='#'){return false;} +var index=links.length;links.push($(this));$(this).click(function(){new $.modalImages(index,links,params);return false;});return true;});return this;};$.modalImages=function(index,links,params){this.links=links;this.modal=new $.modal(null,params);this.showImage(index);};$.modalImages.prototype={params:{prev_txt:'previous',next_txt:'next',prev_img:'prev.png',next_img:'next.png',blank_img:'blank.gif'},showImage:function(index){var This=this;$(document).unbind('keypress.modalImage');if(this.links[index]==undefined){this.modal.removeOverlay();} +var link=this.links[index];var modal=this.modal;var res=$('
    ');res.append('');var thumb=$('img:first',link);if(thumb.length>0&&thumb.attr('title')){res.append(''+thumb.attr('title')+'');}else if(link.attr('title')){res.append(''+link.attr('title')+'');} +if(index!=0){$('prev').appendTo(res);} +if(index+1next').appendTo(res);} +var img=new Image();if(this.modal.ctrl.box.css('visibility')=='visible'){$('div.jq-modal-content',this.modal.ctrl.box).empty().append(this.modal.ctrl.loader);}else{this.modal.updateBox(this.modal.ctrl.loader);} +img.onload=function(){modal.updateBox(res,function(){var Img=$('div.jq-modal-content img',this.ctrl.box);This.navBtnStyle($('a.jq-modal-next',this.ctrl.box),true).css('height',Img.height()).bind('click',index+1,navClick);This.navBtnStyle($('a.jq-modal-prev',this.ctrl.box),false).css('height',Img.height()).bind('click',index-1,navClick);Img.click(function(){This.modal.removeOverlay();});$(document).bind('keypress.modalImage',navKey);});this.onload=function(){};};img.src=link.attr('href');var navClick=function(e){This.showImage(e.data);return false;};var navKey=function(e){var key=String.fromCharCode(e.which).toLowerCase();if((key=='n'||e.keyCode==39)&&index+1').css({border:'none',width:w,height:h});return new $.modal(iframe);};$.fn.modalWeb=function(w,h){this.click(function(){if(this.href!=undefined){$.modalWeb(this.href,w,h);} +return false;});};})(jQuery); \ No newline at end of file diff --git a/admin/js/jquery/jquery.pageTabs.js b/admin/js/jquery/jquery.pageTabs.js new file mode 100644 index 0000000..7c79756 --- /dev/null +++ b/admin/js/jquery/jquery.pageTabs.js @@ -0,0 +1,4 @@ + +jQuery.pageTabs=function(start_tab,settings){return new jQuery._pageTabs(start_tab,settings);};jQuery._pageTabs=function(start_tab,settings){var defaults={className:'multi-part',listClassName:'part-tabs',breakerClassName:'clear'};var index=start_tab?start_tab:0;this.params=jQuery.extend(defaults,settings);this.divs=jQuery('div.'+this.params.className);this.createList();this.showDiv(index);};jQuery._pageTabs.prototype={items:new Array(),createList:function(){if(this.divs.length<=0){return;} +this.block=document.createElement('div');this.block.className=this.params.listClassName;this.list=document.createElement('ul');this.block.appendChild(this.list);var li,a;var This=this;var i=0;jQuery('.'+this.params.className).each(function(){if(this.tagName=="DIV"){li=document.createElement('li');a=document.createElement('a');a.appendChild(document.createTextNode(this.title));this.title='';a.href='#';a.fn=This.showDiv;a.index=this.id||i;a.obj=This;jQuery(a).click(function(){this.fn.call(this.obj,this.index);return false;});li.appendChild(a);This.list.appendChild(li);This.items[i]=li;i++;}else{li=document.createElement('li');li.className=This.params.listClassName+'-link';li.appendChild(this);This.list.appendChild(li);}});this.breaker=document.createElement('br');this.breaker.className=this.params.breakerClassName;jQuery(this.divs.get(0)).before(this.block);jQuery(this.block).after(this.breaker);},showDiv:function(index){var This=this;var i=0;var to_trigger=null;this.divs.each(function(){if((this.id!=''&&this.id==index)||i==index){jQuery(this).show();This.items[i].className=This.params.listClassName+'-active';to_trigger=i;}else{jQuery(this).hide();This.items[i].className='';} +i++;});if(to_trigger!=null){jQuery(this.divs[to_trigger]).onetabload();jQuery(this.divs[to_trigger]).tabload();}}};jQuery.fn.tabload=function(f){this.each(function(){if(f){chainHandler(this,'tabload',f)}else{var h=this.tabload;if(h){h.apply(this);}}});return this;};jQuery.fn.onetabload=function(f){this.each(function(){if(f){chainHandler(this,'onetabload',f);}else{var h=this.onetabload;if(h!=null){h.apply(this);this.onetabload=null;}}});return this;}; \ No newline at end of file diff --git a/admin/js/jsToolBar/jsToolBar.dotclear.js b/admin/js/jsToolBar/jsToolBar.dotclear.js new file mode 100644 index 0000000..86ee951 --- /dev/null +++ b/admin/js/jsToolBar/jsToolBar.dotclear.js @@ -0,0 +1,30 @@ + +jsToolBar.prototype.elements.link.data={};jsToolBar.prototype.elements.link.fncall={};jsToolBar.prototype.elements.link.open_url='popup_link.php';jsToolBar.prototype.elements.link.popup=function(args){window.the_toolbar=this;args=args||'';this.elements.link.data={};var url=this.elements.link.open_url+args;var p_win=window.open(url,'dc_popup','alwaysRaised=yes,dependent=yes,toolbar=yes,height=420,width=380,'+'menubar=no,resizable=yes,scrollbars=yes,status=no');};jsToolBar.prototype.elements.link.fn.wiki=function(){this.elements.link.popup.call(this,'?hreflang='+this.elements.link.default_hreflang);};jsToolBar.prototype.elements.link.fncall.wiki=function(){var data=this.elements.link.data;if(data.href==''){return;} +var etag='|'+data.href;if(data.hreflang){etag+='|'+data.hreflang;} +if(data.content){this.encloseSelection('['+data.content,etag+']');}else{this.encloseSelection('[',etag+']');}};jsToolBar.prototype.elements.link.fn.xhtml=function(){this.elements.link.popup.call(this,'?hreflang='+this.elements.link.default_hreflang);};jsToolBar.prototype.elements.link.fncall.xhtml=function(){var data=this.elements.link.data;if(data.href==''){return;} +var stag='','>').replace('<','<').replace('"','"')+'"';} +res+=' />';if(d.link){res=''+res+'';} +return res;});};jsToolBar.prototype.elements.img.fn.wysiwyg=function(){var src=this.elements.img.prompt.call(this);if(!src){return;} +var img=this.iwin.document.createElement('img');img.src=src;img.setAttribute('alt',this.getSelectedText());this.insertNode(img);};jsToolBar.prototype.elements.img_select.fn.wysiwyg=function(){this.elements.img_select.popup.call(this);};jsToolBar.prototype.elements.img_select.fncall.wysiwyg=function(){var d=this.elements.img_select.data;if(d.src==undefined){return;} +var img=this.iwin.document.createElement('img');img.src=d.src;img.setAttribute('alt',this.getSelectedText());if(d.alignment=='left'){if(img.style.styleFloat!=undefined){img.style.styleFloat='left';}else{img.style.cssFloat='left';} +img.style.marginTop=0;img.style.marginRight='1em';img.style.marginBottom='1em';img.style.marginLeft=0;}else if(d.alignment=='right'){if(img.style.styleFloat!=undefined){img.style.styleFloat='right';}else{img.style.cssFloat='right';} +img.style.marginTop=0;img.style.marginRight=0;img.style.marginBottom='1em';img.style.marginLeft='1em';}else if(d.alignment=='center'){img.style.marginTop=0;img.style.marginRight='auto';img.style.marginBottom=0;img.style.marginLeft='auto';img.style.display='block';} +if(d.description){img.setAttribute('title',d.description);} +if(d.link){var a=this.iwin.document.createElement('a');a.href=d.url;a.appendChild(img);this.insertNode(a);}else{this.insertNode(img);}};jsToolBar.prototype.elements.mp3_insert={fncall:{},data:{}};jsToolBar.prototype.elements.mp3_insert.fncall.wiki=function(){var d=this.elements.mp3_insert.data;if(d.player==undefined){return;} +this.encloseSelection('','',function(str){return'\n///html\n'+d.player+'///\n';});};jsToolBar.prototype.elements.mp3_insert.fncall.xhtml=function(){var d=this.elements.mp3_insert.data;if(d.player==undefined){return;} +this.encloseSelection('','',function(str){return'\n'+d.player+'\n';});};jsToolBar.prototype.elements.mp3_insert.fncall.wysiwyg=function(){return;};jsToolBar.prototype.elements.flv_insert={fncall:{},data:{}};jsToolBar.prototype.elements.flv_insert.fncall.wiki=function(){var d=this.elements.flv_insert.data;if(d.player==undefined){return;} +this.encloseSelection('','',function(str){return'\n///html\n'+d.player+'///\n';});};jsToolBar.prototype.elements.flv_insert.fncall.xhtml=function(){var d=this.elements.flv_insert.data;if(d.player==undefined){return;} +this.encloseSelection('','',function(str){return'\n'+d.player+'\n';});};jsToolBar.prototype.elements.flv_insert.fncall.wysiwyg=function(){return;};jsToolBar.prototype.elements.post_link={type:'button',title:'Link to an entry',fn:{},open_url:'popup_posts.php',data:{},popup:function(){window.the_toolbar=this;this.elements.img_select.data={};var p_win=window.open(this.elements.post_link.open_url,'dc_popup','alwaysRaised=yes,dependent=yes,toolbar=yes,height=500,width=760,'+'menubar=no,resizable=yes,scrollbars=yes,status=no');}};jsToolBar.prototype.elements.post_link.fn.wiki=function(){this.elements.post_link.popup.call(this);};jsToolBar.prototype.elements.post_link.fn.xhtml=function(){this.elements.post_link.popup.call(this);};jsToolBar.prototype.elements.post_link.fn.wysiwyg=function(){this.elements.post_link.popup.call(this);};jsToolBar.prototype.elements.space3={type:'space'}; \ No newline at end of file diff --git a/admin/js/jsToolBar/jsToolBar.js b/admin/js/jsToolBar/jsToolBar.js new file mode 100644 index 0000000..9121528 --- /dev/null +++ b/admin/js/jsToolBar/jsToolBar.js @@ -0,0 +1,28 @@ + +function jsToolBar(textarea){if(!document.createElement){return;} +if(!textarea){return;} +if((typeof(document["selection"])=="undefined")&&(typeof(textarea["setSelectionRange"])=="undefined")){return;} +this.textarea=textarea;this.editor=document.createElement('div');this.editor.className='jstEditor';this.textarea.parentNode.insertBefore(this.editor,this.textarea);this.editor.appendChild(this.textarea);this.toolbar=document.createElement("div");this.toolbar.className='jstElements';this.editor.parentNode.insertBefore(this.toolbar,this.editor);if(this.editor.addEventListener) +{this.handle=document.createElement('div');this.handle.className='jstHandle';var dragStart=this.resizeDragStart;var This=this;this.handle.addEventListener('mousedown',function(event){dragStart.call(This,event);},false);window.addEventListener('unload',function(){var del=This.handle.parentNode.removeChild(This.handle);delete(This.handle);},false);this.editor.parentNode.insertBefore(this.handle,this.editor.nextSibling);} +this.context=null;this.toolNodes={};};function jsButton(title,fn,scope,className){this.title=title||null;this.fn=fn||function(){};this.scope=scope||null;this.className=className||null;};jsButton.prototype.draw=function(){if(!this.scope)return null;var button=document.createElement('button');button.setAttribute('type','button');if(this.className)button.className=this.className;button.title=this.title;var span=document.createElement('span');span.appendChild(document.createTextNode(this.title));button.appendChild(span);if(this.icon!=undefined){button.style.backgroundImage='url('+this.icon+')';} +if(typeof(this.fn)=='function'){var This=this;button.onclick=function(){try{This.fn.apply(This.scope,arguments)}catch(e){}return false;};} +return button;};function jsSpace(id){this.id=id||null;this.width=null;};jsSpace.prototype.draw=function(){var span=document.createElement('span');if(this.id)span.id=this.id;span.appendChild(document.createTextNode(String.fromCharCode(160)));span.className='jstSpacer';if(this.width)span.style.marginRight=this.width+'px';return span;};function jsCombo(title,options,scope,fn,className){this.title=title||null;this.options=options||null;this.scope=scope||null;this.fn=fn||function(){};this.className=className||null;};jsCombo.prototype.draw=function(){if(!this.scope||!this.options)return null;var select=document.createElement('select');if(this.className)select.className=className;select.title=this.title;for(var o in this.options){var option=document.createElement('option');option.value=o;option.appendChild(document.createTextNode(this.options[o]));select.appendChild(option);} +var This=this;select.onchange=function(){try{This.fn.call(This.scope,this.value);}catch(e){alert(e);} +return false;};return select;};jsToolBar.prototype={base_url:'',mode:'xhtml',elements:{},getMode:function(){return this.mode;},setMode:function(mode){this.mode=mode||'xhtml';},switchMode:function(mode){mode=mode||'xhtml';this.draw(mode);},button:function(toolName){var tool=this.elements[toolName];if(typeof tool.fn[this.mode]!='function')return null;var b=new jsButton(tool.title,tool.fn[this.mode],this,'jstb_'+toolName);if(tool.icon!=undefined){b.icon=tool.icon;} +return b;},space:function(toolName){var tool=new jsSpace(toolName);if(this.elements[toolName].width!==undefined){tool.width=this.elements[toolName].width;} +return tool;},combo:function(toolName){var tool=this.elements[toolName];var length=tool[this.mode].list.length;if(typeof tool[this.mode].fn!='function'||length==0){return null;}else{var options={};for(var i=0;i','');}catch(e){};this.toolNodes.blocks.value='nonebis';}},wiki:{list:['nonebis','h2','h3','h4','h5'],fn:function(opt){switch(opt){case'nonebis':this.textarea.focus();break;case'h2':this.encloseSelection('!!!!');break;case'h3':this.encloseSelection('!!!');break;case'h4':this.encloseSelection('!!');break;case'h5':this.encloseSelection('!');break;} +this.toolNodes.blocks.value='nonebis';}}};jsToolBar.prototype.elements.space0={type:'space'};jsToolBar.prototype.elements.strong={type:'button',title:'Strong emphasis',fn:{wiki:function(){this.singleTag('__')},xhtml:function(){this.singleTag('','')}}};jsToolBar.prototype.elements.em={type:'button',title:'Emphasis',fn:{wiki:function(){this.singleTag("''")},xhtml:function(){this.singleTag('','')}}};jsToolBar.prototype.elements.ins={type:'button',title:'Inserted',fn:{wiki:function(){this.singleTag('++')},xhtml:function(){this.singleTag('','')}}};jsToolBar.prototype.elements.del={type:'button',title:'Deleted',fn:{wiki:function(){this.singleTag('--')},xhtml:function(){this.singleTag('','')}}};jsToolBar.prototype.elements.quote={type:'button',title:'Inline quote',fn:{wiki:function(){this.singleTag('{{','}}')},xhtml:function(){this.singleTag('','')}}};jsToolBar.prototype.elements.code={type:'button',title:'Code',fn:{wiki:function(){this.singleTag('@@')},xhtml:function(){this.singleTag('','')}}};jsToolBar.prototype.elements.space1={type:'space'};jsToolBar.prototype.elements.br={type:'button',title:'Line break',fn:{wiki:function(){this.encloseSelection("%%%\n",'')},xhtml:function(){this.encloseSelection("
    \n",'')}}};jsToolBar.prototype.elements.space2={type:'space'};jsToolBar.prototype.elements.blockquote={type:'button',title:'Blockquote',fn:{xhtml:function(){this.singleTag('
    ','
    ')},wiki:function(){this.encloseSelection("\n",'',function(str){str=str.replace(/\r/g,'');return'> '+str.replace(/\n/g,"\n> ");});}}};jsToolBar.prototype.elements.pre={type:'button',title:'Preformated text',fn:{wiki:function(){this.singleTag("///\n","\n///")},xhtml:function(){this.singleTag('
    ','
    ')}}};jsToolBar.prototype.elements.ul={type:'button',title:'Unordered list',fn:{wiki:function(){this.encloseSelection('','',function(str){str=str.replace(/\r/g,'');return'* '+str.replace(/\n/g,"\n* ");});},xhtml:function(){this.encloseSelection('','',function(str){str=str.replace(/\r/g,'');str=str.replace(/\n/g,"\n
  • ");return"
      \n
    • "+str+"
    • \n
    ";});}}};jsToolBar.prototype.elements.ol={type:'button',title:'Ordered list',fn:{wiki:function(){this.encloseSelection('','',function(str){str=str.replace(/\r/g,'');return'# '+str.replace(/\n/g,"\n# ");});},xhtml:function(){this.encloseSelection('','',function(str){str=str.replace(/\r/g,'');str=str.replace(/\n/g,"
  • \n
  • ");return"
      \n
    1. "+str+"
    2. \n
    ";});}}};jsToolBar.prototype.elements.space3={type:'space'};jsToolBar.prototype.elements.link={type:'button',title:'Link',fn:{},href_prompt:'Please give page URL:',hreflang_prompt:'Language of this page:',default_hreflang:'',prompt:function(href,hreflang){href=href||'';hreflang=hreflang||this.elements.link.default_hreflang;href=window.prompt(this.elements.link.href_prompt,href);if(!href){return false;} +hreflang=window.prompt(this.elements.link.hreflang_prompt,hreflang);return{href:this.stripBaseURL(href),hreflang:hreflang};}};jsToolBar.prototype.elements.link.fn.xhtml=function(){var link=this.elements.link.prompt.call(this);if(link){var stag='';var etag='';this.encloseSelection(stag,etag);}};jsToolBar.prototype.elements.link.fn.wiki=function(){var link=this.elements.link.prompt.call(this);if(link){var stag='[';var etag='|'+link.href;if(link.hreflang){etag=etag+'|'+link.hreflang;} +etag=etag+']';this.encloseSelection(stag,etag);}};jsToolBar.prototype.elements.img={type:'button',title:'External image',src_prompt:'Please give image URL:',fn:{},prompt:function(src){src=src||'';return this.stripBaseURL(window.prompt(this.elements.img.src_prompt,src));}};jsToolBar.prototype.elements.img.fn.xhtml=function(){var src=this.elements.img.prompt.call(this);if(src){this.encloseSelection('','',function(str){if(str){return''+str+'';}else{return'';}});}};jsToolBar.prototype.elements.img.fn.wiki=function(){var src=this.elements.img.prompt.call(this);if(src){this.encloseSelection('','',function(str){if(str){return'(('+src+'|'+str+'))';}else{return'(('+src+'))';}});}}; \ No newline at end of file diff --git a/admin/js/jsToolBar/jsToolBar.wysiwyg.js b/admin/js/jsToolBar/jsToolBar.wysiwyg.js new file mode 100644 index 0000000..cb33ad0 --- /dev/null +++ b/admin/js/jsToolBar/jsToolBar.wysiwyg.js @@ -0,0 +1,47 @@ + +jsToolBar.prototype.can_wwg=(document.designMode!=undefined);jsToolBar.prototype.iframe=null;jsToolBar.prototype.iwin=null;jsToolBar.prototype.ibody=null;jsToolBar.prototype.iframe_css=null;jsToolBar.prototype.drawToolBar=jsToolBar.prototype.draw;jsToolBar.prototype.draw=function(mode){mode=mode||'xhtml';if(this.can_wwg){this.mode='wysiwyg';this.drawToolBar('wysiwyg');this.initWindow();}else{this.drawToolBar(mode);}};jsToolBar.prototype.switchMode=function(mode){mode=mode||'xhtml';if(mode=='xhtml'){this.draw(mode);}else{if(this.wwg_mode){this.syncContents('iframe');} +this.removeEditor();this.textarea.style.display='';this.drawToolBar(mode);}};jsToolBar.prototype.syncContents=function(from){from=from||'textarea';var This=this;if(from=='textarea'){initContent();}else{this.validBlockquote();var html=this.applyHtmlFilters(this.ibody.innerHTML);if(html=='
    '){html='

    ';} +this.textarea.value=html;} +function initContent(){if(!This.iframe.contentWindow.document||!This.iframe.contentWindow.document.body){setTimeout(initContent,1);return;} +This.ibody=This.iframe.contentWindow.document.body;if(This.textarea.value!=''&&This.textarea.value!='

    '){This.ibody.innerHTML=This.applyWysiwygFilters(This.textarea.value);if(This.ibody.createTextRange){var IErange=This.ibody.createTextRange();IErange.execCommand("SelectAll");IErange.collapse();IErange.select();}}else if(window.navigator.product!=undefined&&window.navigator.product=='Gecko'){This.ibody.innerHTML='


    ';}else{var idoc=This.iwin.document;var para=idoc.createElement('p');para.appendChild(idoc.createTextNode(''));while(idoc.body.hasChildNodes()){idoc.body.removeChild(idoc.body.lastChild);} +idoc.body.appendChild(para);}}};jsToolBar.prototype.htmlFilters={tagsoup:function(str){return this.tagsoup2xhtml(str);}};jsToolBar.prototype.applyHtmlFilters=function(str){for(var fn in this.htmlFilters){str=this.htmlFilters[fn].call(this,str);} +return str;};jsToolBar.prototype.wysiwygFilters={};jsToolBar.prototype.applyWysiwygFilters=function(str){for(var fn in this.wysiwygFilters){str=this.wysiwygFilters[fn].call(this,str);} +return str;};jsToolBar.prototype.switchEdit=function(){if(this.wwg_mode){this.textarea.style.display='';this.iframe.style.display='none';this.syncContents('iframe');this.drawToolBar('xhtml');this.wwg_mode=false;this.focusEditor();}else{this.iframe.style.display='';this.textarea.style.display='none';this.syncContents('textarea');this.drawToolBar('wysiwyg');this.wwg_mode=true;this.focusEditor();} +this.setSwitcher();};jsToolBar.prototype.initWindow=function(){var This=this;this.iframe=document.createElement('iframe');this.textarea.parentNode.insertBefore(this.iframe,this.textarea.nextSibling);this.switcher=document.createElement('ul');this.switcher.className='jstSwitcher';this.editor.appendChild(this.switcher);this.iframe.height=this.textarea.offsetHeight+0;this.iframe.width=this.textarea.offsetWidth+0;if(this.textarea.tabIndex!=undefined){this.iframe.tabIndex=this.textarea.tabIndex;} +function initIframe(){var doc=This.iframe.contentWindow.document;if(!doc){setTimeout(initIframe,1);return false;} +doc.open();var html='\n'+'\n'+'\n'+ +(This.base_url!=''?'':'')+'\n'+'\n'+'\n'+'';doc.write(html);doc.close();if(document.all){doc.designMode='on';} +This.iwin=This.iframe.contentWindow;This.syncContents('textarea');if(This.wwg_mode==undefined){This.wwg_mode=true;} +if(This.wwg_mode){This.textarea.style.display='none';}else{This.iframe.style.display='none';} +if(This.textarea.form){chainHandler(This.textarea.form,'onsubmit',function(){if(This.wwg_mode){This.syncContents('iframe');}});} +for(var evt in This.iwinEvents){var event=This.iwinEvents[evt];This.addIwinEvent(This.iframe.contentWindow.document,event.type,event.fn,This);} +This.setSwitcher();setTimeout(function(){This.focusEditor();},1);return true;} +initIframe();};jsToolBar.prototype.addIwinEvent=function(target,type,fn,scope){var myFn=function(e){fn.call(scope,e)};addEvent(target,type,myFn,true);addEvent(scope.iwin,'unload',function(){removeEvent(target,type,myFn,true);},true);};jsToolBar.prototype.iwinEvents={block1:{type:'mouseup',fn:function(){this.adjustBlockLevelCombo()}},block2:{type:'keyup',fn:function(){this.adjustBlockLevelCombo()}}};jsToolBar.prototype.switcher_visual_title='visual';jsToolBar.prototype.switcher_source_title='source';jsToolBar.prototype.setSwitcher=function(){while(this.switcher.hasChildNodes()){this.switcher.removeChild(this.switcher.firstChild);} +var This=this;function setLink(title,link){var li=document.createElement('li');if(link){var a=document.createElement('a');a.href='#';a.editor=This;a.onclick=function(){this.editor.switchEdit();return false;};a.appendChild(document.createTextNode(title));}else{li.className='jstSwitcherCurrent';a=document.createTextNode(title);} +li.appendChild(a);This.switcher.appendChild(li);} +setLink(this.switcher_visual_title,!this.wwg_mode);setLink(this.switcher_source_title,this.wwg_mode);};jsToolBar.prototype.removeEditor=function(){if(this.iframe!=null){this.iframe.parentNode.removeChild(this.iframe);this.iframe=null;} +if(this.switcher!=undefined&&this.switcher.parentNode!=undefined){this.switcher.parentNode.removeChild(this.switcher);}};jsToolBar.prototype.focusEditor=function(){if(this.wwg_mode){try{this.iwin.document.designMode='on';}catch(e){};var This=this;setTimeout(function(){This.iframe.contentWindow.focus()},1);}else{this.textarea.focus();}};jsToolBar.prototype.resizeSetStartH=function(){if(this.wwg_mode&&this.iframe!=undefined){this.dragStartH=this.iframe.offsetHeight;return;} +this.dragStartH=this.textarea.offsetHeight+0;};jsToolBar.prototype.resizeDragMove=function(event){var new_height=(this.dragStartH+event.clientY-this.dragStartY)+'px';if(this.iframe!=undefined){this.iframe.style.height=new_height;} +this.textarea.style.height=new_height;};jsToolBar.prototype.insertNode=function(node){var range;if(this.iwin.getSelection){var sel=this.iwin.getSelection();range=sel.getRangeAt(0);sel.removeAllRanges();range.deleteContents();range.insertNode(node);range.selectNodeContents(node);range.setEndAfter(node);if(range.endContainer.childNodes.length>range.endOffset&&range.endContainer.nodeType!=Node.TEXT_NODE){range.setEnd(range.endContainer.childNodes[range.endOffset],0);}else{range.setEnd(range.endContainer.childNodes[0]);} +sel.addRange(range);sel.collapseToEnd();}else{var p=this.iwin.document.createElement('div');p.appendChild(node);range=this.iwin.document.selection.createRange();range.execCommand('delete');range.pasteHTML(p.innerHTML);range.collapse(false);range.select();} +this.iwin.focus();};jsToolBar.prototype.getSelectedNode=function(){if(this.iwin.getSelection){var sel=this.iwin.getSelection();var range=sel.getRangeAt(0);var content=range.cloneContents();}else{var sel=this.iwin.document.selection;var d=this.iwin.document.createElement('div');d.innerHTML=sel.createRange().htmlText;var content=this.iwin.document.createDocumentFragment();for(var i=0;i/gim,''],[/[\w\W]*?<\/style>/gim,''],[/<\/?font[\w\W]*?>/gim,''],[/<(\/?)(B|b|STRONG)([\s>\/])/g,"<$1strong$3"],[/<(\/?)(I|i|EM)([\s>\/])/g,"<$1em$3"],[/]*?[^\/])>/gi,""],[/]*?[^\/])>/gi,""],[/]*?[^\/])>/gi,""],[/]*?[^\/])>/gi,""],[/]*?[^\/])>/gi,""],[/<(\/?)U([\s>\/])/gi,"<$1ins$2"],[/<(\/?)STRIKE([\s>\/])/gi,"<$1del$2"],[/([\w\W]*?)<\/span>/gm,"$1"],[/([\w\W]*?)<\/span>/gm,"$1"],[/([\w\W]*?)<\/span>/gm,"$1"],[/([\w\W]*?)<\/span>/gm,"$1"],[/([\w\W]*?)<\/span>/gm,"$1"],[/([\w\W]*?)<\/span>/gm,"$1"],[/([\w\W]*?)<\/span>/gm,"$2"],[/([\w\W]*?)<\/span>/gm,"$2"],[/([\w\W]*?)<\/span>/gm,"$2"],[/([\w\W]*?)<\/span>/gm,"$2"],[/([\w\W]*?)<\/span>/gm,"$2"],[/([\w\W]*?)<\/span>/gm,"$2"],[/([\w\W]*?)<\/span>/gm,"$2"],[/([\w\W]*?)<\/span>/gm,"$2"],[/([\w\W]*?)<\/strong>/gm,"$1"],[/<([a-z]+) style="font-weight: normal;">([\w\W]*?)<\/\1>/gm,"<$1>$2"],[/<([a-z]+) style="font-weight: bold;">([\w\W]*?)<\/\1>/gm,"<$1>$2"],[/<([a-z]+) style="font-style: italic;">([\w\W]*?)<\/\1>/gm,"<$1>$2"],[/<([a-z]+) style="text-decoration: underline;">([\w\W]*?)<\/\1>/gm,"<$1>$2"],[/<([a-z]+) style="text-decoration: line-through;">([\w\W]*?)<\/\1>/gm,"<$1>$2"],[/<([a-z]+) style="text-decoration: underline line-through;">([\w\W]*?)<\/\1>/gm,"<$1>$2"],[/<([a-z]+) style="(font-weight: bold; ?|font-style: italic; ?){2}">([\w\W]*?)<\/\1>/gm,"<$1>$3"],[/<([a-z]+) style="(font-weight: bold; ?|text-decoration: underline; ?){2}">([\w\W]*?)<\/\1>/gm,"<$1>$3"],[/<([a-z]+) style="(font-weight: italic; ?|text-decoration: underline; ?){2}">([\w\W]*?)<\/\1>/gm,"<$1>$3"],[/<([a-z]+) style="(font-weight: bold; ?|text-decoration: line-through; ?){2}">([\w\W]*?)<\/\1>/gm,"<$1>$3"],[/<([a-z]+) style="(font-weight: italic; ?|text-decoration: line-through; ?){2}">([\w\W]*?)<\/\1>/gm,"<$1>$3"],[/<([a-z]+) style="(font-weight: bold; ?|font-style: italic; ?|text-decoration: underline; ?){3}">([\w\W]*?)<\/\1>/gm,"<$1>$3"],[/<([a-z]+) style="(font-weight: bold; ?|font-style: italic; ?|text-decoration: line-through; ?){3}">([\w\W]*?)<\/\1>/gm,"<$1>$3"],[/<([a-z]+) style="(font-weight: bold; ?|font-style: italic; ?|text-decoration: underline line-through; ?){3}">([\w\W]*?)<\/\1>/gm,"<$1>$3"],[/<\/(strong|em|ins|del|q|code)>(\s*?)<\1>/gim,"$2"],[/<(br|BR)>/g,"
    "],[/([^\s])\/>/g,"$1 />"],[/
    \s*<\/(h1|h2|h3|h4|h5|h6|ul|ol|li|p|blockquote|div)/gi,"([^\n\u000B\r\f])/gi,"\n$2"],[/<(hr|HR)( style="width: 100%; height: 2px;")?>/g,"
    "]);jsToolBar.prototype.tagsoup2xhtml=function(html){for(var reg in this.simpleCleanRegex){html=html.replace(this.simpleCleanRegex[reg][0],this.simpleCleanRegex[reg][1]);} +while(/(<[^\/!]>|<[^\/!][^>]*[^\/]>)\s*<\/[^>]*[^-]>/.test(html)){html=html.replace(/(<[^\/!]>|<[^\/!][^>]*[^\/]>)\s*<\/[^>]*[^-]>/g,"");} +html=html.replace(/<(\/?)([A-Z0-9]+)/g,function(match0,match1,match2){return"<"+match1+match2.toLowerCase();});var myRegexp=/<[^>]+((\s+\w+\s*=\s*)([^"'][\w~@+$,%\/:.#?=&;!*()-]*))[^>]*?>/;while(myRegexp.test(html)){html=html.replace(myRegexp,function(str,val1,val2,val3){var tamponRegex=new RegExp(regexpEscape(val1));return str.replace(tamponRegex,val2+'"'+val3+'"');})} +while(/(<[^>]+style=(["'])[^>]+[\s:]+)0(pt|px)(\2|\s|;)/.test(html)){html=html.replace(/(<[^>]+style=(["'])[^>]+[\s:]+)0(pt|px)(\2|\s|;)/gi,"$1"+"0$4");} +html=html.replace(/\r\n/g,"\n");html=html.replace(/^\s+/gm,'');html=html.replace(/\s+$/gm,'');return html;};jsToolBar.prototype.validBlockquote=function(){var blockElts=['address','blockquote','dl','div','fieldset','form','h1','h2','h3','h4','h5','h6','hr','ol','p','pre','table','ul'];var BQs=this.iwin.document.getElementsByTagName('blockquote');var bqChilds;for(var bq=0;bq=0;i--){if(bqChilds[i].nodeType==1&&arrayIndexOf(blockElts,bqChilds[i].tagName.toLowerCase())>=0) +{if(frag.childNodes.length>0){var p=this.iwin.document.createElement('p');p.appendChild(frag);BQs[bq].replaceChild(p,bqChilds[i+1]);frag=this.iwin.document.createDocumentFragment();}}else{if(frag.childNodes.length>0)BQs[bq].removeChild(bqChilds[i+1]);frag.insertBefore(bqChilds[i].cloneNode(true),frag.firstChild);}} +if(frag.childNodes.length>0){var p=this.iwin.document.createElement('p');p.appendChild(frag);BQs[bq].replaceChild(p,bqChilds[0]);}}};jsToolBar.prototype.removeFormatRegexp=new Array([/(<[a-z][^>]*)margin\s*:[^;]*;/mg,"$1"],[/(<[a-z][^>]*)margin-bottom\s*:[^;]*;/mg,"$1"],[/(<[a-z][^>]*)margin-left\s*:[^;]*;/mg,"$1"],[/(<[a-z][^>]*)margin-right\s*:[^;]*;/mg,"$1"],[/(<[a-z][^>]*)margin-top\s*:[^;]*;/mg,"$1"],[/(<[a-z][^>]*)padding\s*:[^;]*;/mg,"$1"],[/(<[a-z][^>]*)padding-bottom\s*:[^;]*;/mg,"$1"],[/(<[a-z][^>]*)padding-left\s*:[^;]*;/mg,"$1"],[/(<[a-z][^>]*)padding-right\s*:[^;]*;/mg,"$1"],[/(<[a-z][^>]*)padding-top\s*:[^;]*;/mg,"$1"],[/(<[a-z][^>]*)font\s*:[^;]*;/mg,"$1"],[/(<[a-z][^>]*)font-family\s*:[^;]*;/mg,"$1"],[/(<[a-z][^>]*)font-size\s*:[^;]*;/mg,"$1"],[/(<[a-z][^>]*)font-style\s*:[^;]*;/mg,"$1"],[/(<[a-z][^>]*)font-variant\s*:[^;]*;/mg,"$1"],[/(<[a-z][^>]*)font-weight\s*:[^;]*;/mg,"$1"],[/(<[a-z][^>]*)color\s*:[^;]*;/mg,"$1"]);jsToolBar.prototype.removeTextFormating=function(html){for(var reg in this.removeFormatRegexp){html=html.replace(this.removeFormatRegexp[reg][0],this.removeFormatRegexp[reg][1]);} +html=this.tagsoup2xhtml(html);html=html.replace(/style="\s*?"/mgi,'');return html;};jsToolBar.prototype.elements.blocks.wysiwyg={list:['none','p','h1','h2','h3','h4','h5','h6'],fn:function(opt){if(opt=='none'){var blockLevel=this.getBlockLevel();if(blockLevel!==null){this.replaceNodeByContent(blockLevel);} +this.iwin.focus();}else{try{this.iwin.document.execCommand('formatblock',false,'<'+opt+'>');}catch(e){};this.iwin.focus();}}};jsToolBar.prototype.elements.strong.fn.wysiwyg=function(){this.iwin.document.execCommand('bold',false,null);this.iwin.focus();};jsToolBar.prototype.elements.em.fn.wysiwyg=function(){this.iwin.document.execCommand('italic',false,null);this.iwin.focus();};jsToolBar.prototype.elements.ins.fn.wysiwyg=function(){this.iwin.document.execCommand('underline',false,null);this.iwin.focus();};jsToolBar.prototype.elements.del.fn.wysiwyg=function(){this.iwin.document.execCommand('strikethrough',false,null);this.iwin.focus();};jsToolBar.prototype.elements.quote.fn.wysiwyg=function(){var n=this.getSelectedNode();var q=this.iwin.document.createElement('q');q.appendChild(n);this.insertNode(q);};jsToolBar.prototype.elements.code.fn.wysiwyg=function(){var n=this.getSelectedNode();var code=this.iwin.document.createElement('code');code.appendChild(n);this.insertNode(code);};jsToolBar.prototype.elements.br.fn.wysiwyg=function(){var n=this.iwin.document.createElement('br');this.insertNode(n);};jsToolBar.prototype.elements.blockquote.fn.wysiwyg=function(){var n=this.getSelectedNode();var q=this.iwin.document.createElement('blockquote');q.appendChild(n);this.insertNode(q);};jsToolBar.prototype.elements.pre.fn.wysiwyg=function(){this.iwin.document.execCommand('formatblock',false,'
    ');this.iwin.focus();};jsToolBar.prototype.elements.ul.fn.wysiwyg=function(){this.iwin.document.execCommand('insertunorderedlist',false,null);this.iwin.focus();};jsToolBar.prototype.elements.ol.fn.wysiwyg=function(){this.iwin.document.execCommand('insertorderedlist',false,null);this.iwin.focus();};jsToolBar.prototype.elements.link.fn.wysiwyg=function(){var href,hreflang;var range,commonAncestorContainer;if(this.iwin.getSelection){var selection=this.iwin.getSelection();range=selection.getRangeAt(0);commonAncestorContainer=range.commonAncestorContainer;while(commonAncestorContainer.nodeType!=1){commonAncestorContainer=commonAncestorContainer.parentNode;}}else{range=this.iwin.document.selection.createRange();commonAncestorContainer=range.parentElement();}
    +var ancestorTagName=commonAncestorContainer.tagName.toLowerCase();while(ancestorTagName!='a'&&ancestorTagName!='body'){commonAncestorContainer=commonAncestorContainer.parentNode;ancestorTagName=commonAncestorContainer.tagName.toLowerCase();}
    +if(ancestorTagName=='a'){href=commonAncestorContainer.href||'';hreflang=commonAncestorContainer.hreflang||'';}
    +href=window.prompt(this.elements.link.href_prompt,href);if(ancestorTagName=='a'&&href==''){this.replaceNodeByContent(commonAncestorContainer);}
    +if(!href)return;hreflang=window.prompt(this.elements.link.hreflang_prompt,hreflang);if(ancestorTagName=='a'&&href){commonAncestorContainer.setAttribute('href',href);if(hreflang){commonAncestorContainer.setAttribute('hreflang',hreflang);}else{commonAncestorContainer.removeAttribute('hreflang');}
    +return;}
    +var n=this.getSelectedNode();var a=this.iwin.document.createElement('a');a.href=href;if(hreflang)a.setAttribute('hreflang',hreflang);a.appendChild(n);this.insertNode(a);};jsToolBar.prototype.elements.removeFormat={type:'button',title:'Remove text formating',fn:{}};jsToolBar.prototype.elements.removeFormat.disabled=!jsToolBar.prototype.can_wwg;jsToolBar.prototype.elements.removeFormat.fn.xhtml=function(){var html=this.textarea.value;html=this.removeTextFormating(html);this.textarea.value=html;};jsToolBar.prototype.elements.removeFormat.fn.wysiwyg=function(){var html=this.iwin.document.body.innerHTML;html=this.removeTextFormating(html);this.iwin.document.body.innerHTML=html;};function arrayIndexOf(aArray,aValue){if(typeof Array.indexOf=='function'){return aArray.indexOf(aValue);}else{var index=-1;var l=aArray.length;for(var i=0;i'+player+'
  • ';} +tb.elements.mp3_insert.data.player=player.replace(/>/g,'>\n');tb.elements.mp3_insert.fncall[tb.mode].call(tb);} +else if(type=='flv') +{var oplayer=$('
    '+$('#public_player').val()+'
    ');var flashvars=$("[name=FlashVars]",oplayer).val();var align=$('input[name="alignment"]:checked',insert_form).val();var title=insert_form.elements.title.value;if(title){flashvars='title='+encodeURI(title)+'&'+flashvars;} +$('object',oplayer).attr('width',$('#video_w').val());$('object',oplayer).attr('height',$('#video_h').val());flashvars=flashvars.replace(/(width=\d*)/,'width='+$('#video_w').val());flashvars=flashvars.replace(/(height=\d*)/,'height='+$('#video_h').val());$("[name=FlashVars]",oplayer).val(flashvars);var player=oplayer.html();if(align!=undefined&&align!='none'){player='
    '+player+'
    ';} +tb.elements.flv_insert.data.player=player.replace(/>/g,'>\n');tb.elements.flv_insert.fncall[tb.mode].call(tb);} +else +{tb.elements.link.data.href=tb.stripBaseURL(insert_form.elements.url.value);tb.elements.link.data.content=insert_form.elements.title.value;tb.elements.link.fncall[tb.mode].call(tb);}};function playerFormat(s){s=s.replace(/</g,'<');s=s.replace(/>/g,'>\n');s=s.replace(/&/g,'&');return s;};}); \ No newline at end of file diff --git a/admin/js/jsToolBar/popup_posts.js b/admin/js/jsToolBar/popup_posts.js new file mode 100644 index 0000000..0fbb77d --- /dev/null +++ b/admin/js/jsToolBar/popup_posts.js @@ -0,0 +1,2 @@ + +$(function(){$('#link-insert-cancel').click(function(){window.close();});$('#form-entries tr>td.maximal>a').click(function(){var tb=window.opener.the_toolbar;var data=tb.elements.link.data;data.href=tb.stripBaseURL($(this).attr('title'));tb.elements.link.fncall[tb.mode].call(tb);window.close();});}); \ No newline at end of file diff --git a/admin/js/tool-man/cookies.js b/admin/js/tool-man/cookies.js new file mode 100644 index 0000000..4e4f03d --- /dev/null +++ b/admin/js/tool-man/cookies.js @@ -0,0 +1,11 @@ + +ToolMan._cookieOven={set:function(name,value,expirationInDays){if(expirationInDays){var date=new Date() +date.setTime(date.getTime()+(expirationInDays*24*60*60*1000)) +var expires="; expires="+date.toGMTString()}else{var expires=""} +document.cookie=name+"="+value+expires+"; path=/"},get:function(name){var namePattern=name+"=" +var cookies=document.cookie.split(';') +for(var i=0,n=cookies.length;i=0){return this.create(document.body.scrollLeft,document.body.scrollTop)}else{return this.create(0,0)}},clientSize:function(){if(window.innerHeight>=0){return this.create(window.innerWidth,window.innerHeight)}else if(document.documentElement){return this.create(document.documentElement.clientWidth,document.documentElement.clientHeight)}else if(document.body.clientHeight>=0){return this.create(document.body.clientWidth,document.body.clientHeight)}else{return this.create(0,0)}},mousePosition:function(event){event=ToolMan.events().fix(event) +return this.create(event.clientX,event.clientY)},mouseOffset:function(event){event=ToolMan.events().fix(event) +if(event.pageX>=0||event.pageX<0){return this.create(event.pageX,event.pageY)}else if(event.clientX>=0||event.clientX<0){return this.mousePosition(event).plus(this.scrollOffset())}},_size:function(element){return this.create(element.offsetWidth,element.offsetHeight)},_offset:function(element){return this.create(element.offsetLeft,element.offsetTop)}} +function _ToolManCoordinate(factory,x,y){this.factory=factory +this.x=isNaN(x)?0:x +this.y=isNaN(y)?0:y} +_ToolManCoordinate.prototype={toString:function(){return"("+this.x+","+this.y+")"},plus:function(that){return this.factory.create(this.x+that.x,this.y+that.y)},minus:function(that){return this.factory.create(this.x-that.x,this.y-that.y)},min:function(that){return this.factory.create(Math.min(this.x,that.x),Math.min(this.y,that.y))},max:function(that){return this.factory.create(Math.max(this.x,that.x),Math.max(this.y,that.y))},constrainTo:function(one,two){var min=one.min(two) +var max=one.max(two) +return this.max(min).min(max)},distance:function(that){return Math.sqrt(Math.pow(this.x-that.x,2)+Math.pow(this.y-that.y,2))},reposition:function(element){element.style["top"]=this.y+"px" +element.style["left"]=this.x+"px"}} \ No newline at end of file diff --git a/admin/js/tool-man/core.js b/admin/js/tool-man/core.js new file mode 100644 index 0000000..7a46341 --- /dev/null +++ b/admin/js/tool-man/core.js @@ -0,0 +1,35 @@ + +var ToolMan={events:function(){if(!ToolMan._eventsFactory)throw"ToolMan Events module isn't loaded";return ToolMan._eventsFactory},css:function(){if(!ToolMan._cssFactory)throw"ToolMan CSS module isn't loaded";return ToolMan._cssFactory},coordinates:function(){if(!ToolMan._coordinatesFactory)throw"ToolMan Coordinates module isn't loaded";return ToolMan._coordinatesFactory},drag:function(){if(!ToolMan._dragFactory)throw"ToolMan Drag module isn't loaded";return ToolMan._dragFactory},dragsort:function(){if(!ToolMan._dragsortFactory)throw"ToolMan DragSort module isn't loaded";return ToolMan._dragsortFactory},helpers:function(){return ToolMan._helpers},cookies:function(){if(!ToolMan._cookieOven)throw"ToolMan Cookie module isn't loaded";return ToolMan._cookieOven},junkdrawer:function(){return ToolMan._junkdrawer}} +ToolMan._helpers={map:function(array,func){for(var i=0,n=array.length;i0)return identifier;identifier=trim(item.getAttribute("itemID")) +if(identifier!=null&&identifier.length>0)return identifier;return trim(item.innerHTML)},_itemsByID:function(list){var array=new Array() +var items=list.getElementsByTagName('li') +for(var i=0,n=items.length;isetCacheDir(DC_TPL_CACHE); +$feed_reader->setTimeout(5); +$feed_reader->setUserAgent('Dotclear - http://www.dotclear.org/'); +try { + $dc_langs = $feed_reader->parse(sprintf(DC_L10N_UPDATE_URL,DC_VERSION)); + if ($dc_langs !== false) { + $dc_langs = $dc_langs->items; + } +} catch (Exception $e) {} + +# Delete a language pack +if ($is_writable && !empty($_POST['delete']) && !empty($_POST['locale_id'])) +{ + try + { + $locale_id = $_POST['locale_id']; + if (!isset($iso_codes[$locale_id]) || !is_dir(DC_L10N_ROOT.'/'.$locale_id)) { + throw new Exception(__('No such installed language')); + } + + if ($locale_id == 'en') { + throw new Exception(__("You can't remove English language.")); + } + + if (!files::deltree(DC_L10N_ROOT.'/'.$locale_id)) { + throw new Exception(__('Permissions to delete language denied.')); + } + + http::redirect('langs.php?removed=1'); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} + +# Download a language pack +if ($is_writable && !empty($_POST['pkg_url'])) +{ + try + { + if (empty($_POST['your_pwd']) || !$core->auth->checkPassword(crypt::hmac(DC_MASTER_KEY,$_POST['your_pwd']))) { + throw new Exception(__('Password verification failed')); + } + + $url = html::escapeHTML($_POST['pkg_url']); + $dest = DC_L10N_ROOT.'/'.basename($url); + if (!preg_match('#^http://[^.]+\.dotclear\.net/.*\.zip$#',$url)) { + throw new Exception(__('Invalid language file URL.')); + } + + $client = netHttp::initClient($url,$path); + $client->setUserAgent('Dotclear - http://www.dotclear.org/'); + $client->useGzip(false); + $client->setPersistReferers(false); + $client->setOutput($dest); + $client->get($path); + + try { + $ret_code = dc_lang_install($dest); + } catch (Exception $e) { + @unlink($dest); + throw $e; + } + + @unlink($dest); + http::redirect('langs.php?added='.$ret_code); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} + +# Upload a language pack +if ($is_writable && !empty($_POST['upload_pkg'])) +{ + try + { + if (empty($_POST['your_pwd']) || !$core->auth->checkPassword(crypt::hmac(DC_MASTER_KEY,$_POST['your_pwd']))) { + throw new Exception(__('Password verification failed')); + } + + files::uploadStatus($_FILES['pkg_file']); + $dest = DC_L10N_ROOT.'/'.$_FILES['pkg_file']['name']; + if (!move_uploaded_file($_FILES['pkg_file']['tmp_name'],$dest)) { + throw new Exception(__('Unable to move uploaded file.')); + } + + try { + $ret_code = dc_lang_install($dest); + } catch (Exception $e) { + @unlink($dest); + throw $e; + } + + @unlink($dest); + http::redirect('langs.php?added='.$ret_code); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} + +/* DISPLAY Main page +-------------------------------------------------------- */ +dcPage::open(__('Languages management'), + dcPage::jsLoad('js/_langs.js') +); + +echo +'

    '.__('Languages management').'

    '; + +if (!empty($_GET['removed'])) { + echo '

    '.__('Language has been successfully deleted.').'

    '; +} + +if (!empty($_GET['added'])) { + echo '

    '. + ($_GET['added'] == 2 ? __('Language has been successfully upgraded') : __('Language has been successfully installed.')). + '

    '; +} + +echo +'

    '.__('Here you can install, upgrade or remove languages for your Dotclear '. +'installation.').'

    '. +'

    '.sprintf(__('You can change your user language in your preferences or '. +'change your blog\'s main language in your blog settings.'), +'preferences.php','blog_pref.php').'

    '; + +echo +'

    '.__('Installed languages').'

    '; + +$locales_content = scandir(DC_L10N_ROOT); +$tmp = array(); +foreach ($locales_content as $v) { + $c = ($v == '.' || $v == '..' || $v == 'en' || !is_dir(DC_L10N_ROOT.'/'.$v) || !isset($iso_codes[$v])); + + if (!$c) { + $tmp[$v] = DC_L10N_ROOT.'/'.$v; + } +} +$locales_content = $tmp; + +if (empty($locales_content)) +{ + echo '

    '.__('No additional language is installed.').'

    '; +} +else +{ + echo + ''. + ''. + ''. + ''; + + foreach ($locales_content as $k => $v) + { + $is_deletable = $is_writable && is_writable($v); + + echo + ''. + ''. + ''; + } + echo '
    '.__('Language').''.__('Action').'
    ('.$k.') '. + ''.html::escapeHTML($iso_codes[$k]).''; + + if ($is_deletable) + { + echo + '
    '. + '
    '. + $core->formNonce(). + form::hidden(array('locale_id'),html::escapeHTML($k)). + ' '. + '
    '. + '
    '; + } + + echo '
    '; +} + +echo '

    '.__('Install or upgrade languages').'

    '; + +if (!$is_writable) { + echo '

    '.sprintf(__('You can install or remove a language by adding or '. + 'removing the relevant directory in your %s folder.'),'locales').'

    '; +} + +if (!empty($dc_langs) && $is_writable) +{ + $dc_langs_combo = array(); + foreach ($dc_langs as $k => $v) { + if ($v->link && isset($iso_codes[$v->title])) { + $dc_langs_combo[html::escapeHTML('('.$v->title.') '.$iso_codes[$v->title])] = html::escapeHTML($v->link); + } + } + + echo + '
    '. + '
    '. + ''.__('Available languages').''. + '

    '.sprintf(__('You can download and install a additional language directly from Dotclear.net. '. + 'Proposed languages are based on your version: %s.'),''.DC_VERSION.'').'

    '. + '

    '. + '

    '. + ''. + $core->formNonce(). + '
    '. + '
    '; +} + +if ($is_writable) +{ + # 'Upload language pack' form + echo + '
    '. + '
    '. + ''.__('Upload a zip file').''. + '

    '.__('You can install languages by uploading zip files.').'

    '. + '

    '. + '

    '. + ''. + $core->formNonce(). + '
    '. + '
    '; +} + +dcPage::close(); + + +# Language installation function +function dc_lang_install($file) +{ + $zip = new fileUnzip($file); + $zip->getList(false,'#(^|/)(__MACOSX|\.svn|\.DS_Store|Thumbs\.db)(/|$)#'); + + if (!preg_match('/^[a-z]{2,3}(-[a-z]{2})?$/',$zip->getRootDir())) { + throw new Exception(__('Invalid language zip file.')); + } + + if ($zip->isEmpty() || !$zip->hasFile($zip->getRootDir().'/main.po')) { + throw new Exception(__('The zip file does not appear to be a valid Dotclear language pack.')); + } + + + $target = dirname($file); + $destination = $target.'/'.$zip->getRootDir(); + $res = 1; + + if (is_dir($destination)) { + if (!files::deltree($destination)) { + throw new Exception(__('An error occurred during language upgrade.')); + } + $res = 2; + } + + $zip->unzipAll($target); + return $res; +} +?> \ No newline at end of file diff --git a/admin/media.php b/admin/media.php new file mode 100644 index 0000000..906a172 --- /dev/null +++ b/admin/media.php @@ -0,0 +1,449 @@ +auth->check('media,media_admin',$core->blog->id)) { + throw new Exception('Permission denied.'); + } + + $d = isset($_POST['d']) ? $_POST['d'] : null; + $core->media = new dcMedia($core); + $core->media->chdir($d); + $core->media->getDir(); + $dir =& $core->media->dir; + + if (empty($_FILES['Filedata'])) { + throw new Exception('No file to upload.'); + } + + files::uploadStatus($_FILES['Filedata']); + $core->media->uploadFile($_FILES['Filedata']['tmp_name'],$_FILES['Filedata']['name']); + + echo 'ok'; + } + catch (Exception $e) { + echo __('Error:').' '.__($e->getMessage()); + } + exit; +} + + +/* HTML page +-------------------------------------------------------- */ +require dirname(__FILE__).'/../inc/admin/prepend.php'; + +dcPage::check('media,media_admin'); + +$post_id = !empty($_GET['post_id']) ? (integer) $_GET['post_id'] : null; +if ($post_id) { + $post = $core->blog->getPosts(array('post_id'=>$post_id,'post_type'=>'')); + if ($post->isEmpty()) { + $post_id = null; + } + $post_title = $post->post_title; + $post_type = $post->post_type; + unset($post); +} + +$d = isset($_REQUEST['d']) ? $_REQUEST['d'] : null; +$dir = null; + +$page = !empty($_GET['page']) ? $_GET['page'] : 1; +$nb_per_page = 30; + +# We are on home not comming from media manager +if ($d === null && isset($_SESSION['media_manager_dir'])) { + # We get session information + $d = $_SESSION['media_manager_dir']; +} + +if (!isset($_GET['page']) && isset($_SESSION['media_manager_page'])) { + $page = $_SESSION['media_manager_page']; +} + +# We set session information about directory and page +if ($d) { + $_SESSION['media_manager_dir'] = $d; +} else { + unset($_SESSION['media_manager_dir']); +} +if ($page != 1) { + $_SESSION['media_manager_page'] = $page; +} else { + unset($_SESSION['media_manager_page']); +} + +# Sort combo +$sort_combo = array( + __('By names, ascendant') => 'name-asc', + __('By names, descendant') => 'name-desc', + __('By dates, ascendant') => 'date-asc', + __('By dates, descendant') => 'date-desc' +); + +if (!empty($_GET['file_sort']) && in_array($_GET['file_sort'],$sort_combo)) { + $_SESSION['media_file_sort'] = $_GET['file_sort']; +} +$file_sort = !empty($_SESSION['media_file_sort']) ? $_SESSION['media_file_sort'] : null; + +$popup = (integer) !empty($_GET['popup']); + +$page_url = 'media.php?popup='.$popup.'&post_id='.$post_id; + +if ($popup) { + $open_f = array('dcPage','openPopup'); + $close_f = array('dcPage','closePopup'); +} else { + $open_f = array('dcPage','open'); + $close_f = create_function('',"dcPage::helpBlock('core_media'); dcPage::close();"); +} + +$core_media_writable = false; +try { + $core->media = new dcMedia($core); + if ($file_sort) { + $core->media->setFileSort($file_sort); + } + $core->media->chdir($d); + $core->media->getDir(); + $core_media_writable = $core->media->writable(); + $dir =& $core->media->dir; + if (!$core_media_writable) { + throw new Exception('you do not have sufficient permissions to write to this folder: '); + } +} catch (Exception $e) { + $core->error->add($e->getMessage()); +} + +# Zip download +if (!empty($_GET['zipdl']) && $core->auth->check('media_admin',$core->blog->id)) +{ + try + { + @set_time_limit(300); + $fp = fopen('php://output','wb'); + $zip = new fileZip($fp); + $zip->addExclusion('#(^|/).(.*?)_(m|s|sq|t).jpg$#'); + $zip->addDirectory($core->media->root.'/'.$d,'',true); + + header('Content-Disposition: attachment;filename='.($d ? $d : 'media').'.zip'); + header('Content-Type: application/x-zip'); + $zip->write(); + unset($zip); + exit; + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} + +# New directory +if ($dir && !empty($_POST['newdir'])) +{ + try { + $core->media->makeDir($_POST['newdir']); + http::redirect($page_url.'&d='.rawurlencode($d).'&mkdok=1'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} + +# Adding a file +if ($dir && !empty($_FILES['upfile'])) +{ + try + { + files::uploadStatus($_FILES['upfile']); + + $f_title = (isset($_POST['upfiletitle']) ? $_POST['upfiletitle'] : ''); + $f_private = (isset($_POST['upfilepriv']) ? $_POST['upfilepriv'] : false); + + $core->media->uploadFile($_FILES['upfile']['tmp_name'],$_FILES['upfile']['name'],$f_title,$f_private); + http::redirect($page_url.'&d='.rawurlencode($d).'&upok=1'); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} + + +# Removing item +if ($dir && !empty($_POST['rmyes']) && !empty($_POST['remove'])) +{ + $_POST['remove'] = rawurldecode($_POST['remove']); + + try { + $core->media->removeItem($_POST['remove']); + http::redirect($page_url.'&d='.rawurlencode($d).'&rmfok=1'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} + +# Rebuild directory +if ($dir && $core->auth->isSuperAdmin() && !empty($_POST['rebuild'])) +{ + try { + $core->media->rebuild($d); + http::redirect($page_url.'&d='.rawurlencode($d).'&rebuildok=1'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} + + +# DISPLAY confirm page for rmdir & rmfile +if ($dir && !empty($_GET['remove'])) +{ + call_user_func($open_f,__('Media manager')); + + echo '

    '.html::escapeHTML($core->blog->name).' › '.__('Media manager').' › '.__('confirm removal').'

    '; + + echo + '
    '. + '

    '.sprintf(__('Are you sure you want to remove %s?'), + html::escapeHTML($_GET['remove'])).'

    '. + '

    '. + '   '. + form::hidden('d',$d). + $core->formNonce(). + form::hidden('remove',html::escapeHTML($_GET['remove'])).'

    '. + '
    '; + + call_user_func($close_f); + exit; +} + +/* DISPLAY Main page +-------------------------------------------------------- */ +call_user_func($open_f,__('Media manager'), + dcPage::jsLoad('js/_media.js'). + ($core_media_writable ? dcPage::jsCandyUpload(array('d='.$d)) : '')); + +if (!empty($_GET['mkdok'])) { + echo '

    '.__('Directory has been successfully created.').'

    '; +} + +if (!empty($_GET['upok'])) { + echo '

    '.__('Files have been successfully uploaded.').'

    '; +} + +if (!empty($_GET['rmfok'])) { + echo '

    '.__('File has been successfully removed.').'

    '; +} + +if (!empty($_GET['rmdok'])) { + echo '

    '.__('Directory has been successfully removed.').'

    '; +} + +if (!empty($_GET['rebuildok'])) { + echo '

    '.__('Directory has been successfully rebuilt.').'

    '; +} + +if (!empty($_GET['unzipok'])) { + echo '

    '.__('Zip file has been successfully extracted.').'

    '; +} + +echo '

    '.html::escapeHTML($core->blog->name).' › '.__('Media manager').''. +' / '.$core->media->breadCrumb(html::escapeURL($page_url).'&d=%s').'

    '; + +if (!$dir) { + call_user_func($close_f); + exit; +} + +if ($post_id) { + echo '

    '.sprintf(__('Choose a file to attach to entry %s by clicking on %s.'), + ''.html::escapeHTML($post_title).'', + ''.__('Attach this file to entry').'').'

    '; +} +if ($popup) { + echo '

    '.sprintf(__('Choose a file to insert into entry by clicking on %s.'), + ''.__('Attach this file to entry').'').'

    '; +} + + +$items = array_values(array_merge($dir['dirs'],$dir['files'])); +if (count($items) == 0) +{ + echo '

    '.__('No file.').'

    '; +} +else +{ + $pager = new pager($page,count($items),$nb_per_page,10); + + echo + '
    '. + '

    '. + form::hidden(array('popup'),$popup). + form::hidden(array('post_id'),$post_id). + '

    '. + '
    '. + + '
    '. + '

    '.__('Page(s)').' : '.$pager->getLinks().'

    '; + + for ($i=$pager->index_start, $j=0; $i<=$pager->index_end; $i++, $j++) + { + echo mediaItemLine($items[$i],$j); + } + + echo + '

    '.__('Page(s)').' : '.$pager->getLinks().'

    '. + '
    '; +} + +if ($core_media_writable) +{ + echo '
    '; + + echo + '

    '.__('Add files').'

    '. + '
    '. + '
    '.form::hidden(array('MAX_FILE_SIZE'),DC_MAX_UPLOAD_SIZE). + $core->formNonce().'
    '. + '
    '. + '

    '. + '

    '. + '

    '. + '

    '. + form::hidden(array('d'),$d).'

    '. + '
    '. + '
    '. + '

    '.__('Please take care to publish media that you own and that are not protected by copyright.').'

    '. + '
    '; + + echo + '

    '.__('New directory').'

    '. + '
    '. + '
    '. + $core->formNonce(). + '

    '. + '

    '. + form::hidden(array('d'),html::escapeHTML($d)).'

    '. + '
    '. + '
    '; + + echo '
    '; +} + +# Empty remove form (for javascript actions) +echo +'
    '. +form::hidden('rmyes',1).form::hidden('d',html::escapeHTML($d)). +form::hidden('remove',''). +$core->formNonce(). +'
    '; + +# Get zip directory +if ($core->auth->check('media_admin',$core->blog->id)) +{ + echo + '

    '. + __('Download this directory as a zip file').'

    '; +} + +call_user_func($close_f); + +/* ----------------------------------------------------- */ +function mediaItemLine($f,$i) +{ + global $core, $page_url, $popup, $post_id; + + $fname = $f->basename; + + if ($f->d) { + $link = html::escapeURL($page_url).'&d='.html::sanitizeURL($f->relname); + if ($f->parent) { + $fname = '..'; + } + } else { + $link = + 'media_item.php?id='.$f->media_id.'&popup='.$popup.'&post_id='.$post_id; + } + + $class = 'media-item media-col-'.($i%2); + + $res = + '
    '. + ''. + '
      '. + '
    • '.$fname.'
    • '; + + if (!$f->d) { + $res .= + '
    • '.$f->media_title.'
    • '. + '
    • '. + $f->media_dtstr.' - '. + files::size($f->size).' - '. + ''.__('open').''. + '
    • '; + } + + $res .= '
    •  '; + + if ($post_id && !$f->d) { + $res .= '
      '. + ' '. + form::hidden('media_id',$f->media_id). + form::hidden('post_id',$post_id). + form::hidden('attach',1). + $core->formNonce(). + '
      '; + } + + if ($popup && !$f->d) { + $res .= ''.__('Insert this file into entry').' '; + } + + if ($f->del) { + $res .= ''. + ''.__('delete').''; + } + + $res .= '
    • '; + + if ($f->type == 'audio/mpeg3') { + $res .= '
    • '.dcMedia::mp3player($f->file_url,'index.php?pf=player_mp3.swf').'
    • '; + } + + $res .= '
    '; + + return $res; +} +?> \ No newline at end of file diff --git a/admin/media_item.php b/admin/media_item.php new file mode 100644 index 0000000..1ddbaba --- /dev/null +++ b/admin/media_item.php @@ -0,0 +1,518 @@ +blog->getPosts(array('post_id'=>$post_id)); + if ($post->isEmpty()) { + $post_id = null; + } + $post_title = $post->post_title; + unset($post); +} + +$file = null; +$popup = (integer) !empty($_GET['popup']); +$page_url = 'media_item.php?popup='.$popup.'&post_id='.$post_id; +$media_page_url = 'media.php?popup='.$popup.'&post_id='.$post_id; + +$id = !empty($_REQUEST['id']) ? (integer) $_REQUEST['id'] : ''; + +if ($popup) { + $open_f = array('dcPage','openPopup'); + $close_f = array('dcPage','closePopup'); +} else { + $open_f = array('dcPage','open'); + $close_f = create_function('',"dcPage::helpBlock('core_media'); dcPage::close();"); +} + +$core_media_writable = false; +try +{ + $core->media = new dcMedia($core); + + if ($id) { + $file = $core->media->getFile($id); + } + + if ($file === null) { + throw new Exception(__('Not a valid file')); + } + + $core->media->chdir(dirname($file->relname)); + $core_media_writable = $core->media->writable(); + + # Prepare directories combo box + $dirs_combo = array(); + foreach ($core->media->getRootDirs() as $v) { + if ($v->w) { + $dirs_combo['/'.$v->relname] = $v->relname; + } + } +} +catch (Exception $e) +{ + $core->error->add($e->getMessage()); +} + +# Upload a new file +if ($file && !empty($_FILES['upfile']) && $file->editable && $core_media_writable) +{ + try { + files::uploadStatus($_FILES['upfile']); + $core->media->uploadFile($_FILES['upfile']['tmp_name'],$file->basename,null,false,true); + http::redirect($page_url.'&id='.$id.'&fupl=1'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} + +# Update file +if ($file && !empty($_POST['media_file']) && $file->editable && $core_media_writable) +{ + $newFile = clone $file; + + $newFile->basename = $_POST['media_file']; + + if ($_POST['media_path']) { + $newFile->dir = $_POST['media_path']; + $newFile->relname = $_POST['media_path'].'/'.$newFile->basename; + } else { + $newFile->dir = ''; + $newFile->relname = $newFile->basename; + } + $newFile->media_title = $_POST['media_title']; + $newFile->media_dt = strtotime($_POST['media_dt']); + $newFile->media_dtstr = $_POST['media_dt']; + $newFile->media_priv = !empty($_POST['media_private']); + + try { + $core->media->updateFile($file,$newFile); + http::redirect($page_url.'&id='.$id.'&fupd=1'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} + +# Update thumbnails +if (!empty($_POST['thumbs']) && $file->media_type == 'image' && $file->editable && $core_media_writable) +{ + try { + $foo = null; + $core->media->imageThumbCreate($foo,$file->basename); + http::redirect($page_url.'&id='.$id.'&thumbupd=1'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} + +# Unzip file +if (!empty($_POST['unzip']) && $file->type == 'application/zip' && $file->editable && $core_media_writable) +{ + try { + $unzip_dir = $core->media->inflateZipFile($file,$_POST['inflate_mode'] == 'new'); + http::redirect($media_page_url.'&d='.$unzip_dir.'&unzipok=1'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} + +# Function to get image title based on meta +function dcGetImageTitle($file,$pattern) +{ + $res = array(); + $pattern = preg_split('/\s*;;\s*/',$pattern); + $sep = ', '; + + foreach ($pattern as $v) { + if ($v == 'Title') { + $res[] = $file->media_title; + } elseif ($file->media_meta->{$v}) { + $res[] = (string) $file->media_meta->{$v}; + } elseif (preg_match('/^Date\((.+?)\)$/u',$v,$m)) { + $res[] = dt::str($m[1],$file->media_dt); + } elseif (preg_match('/^DateTimeOriginal\((.+?)\)$/u',$v,$m) && $file->media_meta->DateTimeOriginal) { + $res[] = dt::dt2str($m[1],(string) $file->media_meta->DateTimeOriginal); + } elseif (preg_match('/^separator\((.*?)\)$/u',$v,$m)) { + $sep = $m[1]; + } + } + return implode($sep,$res); +} + +/* DISPLAY Main page +-------------------------------------------------------- */ +$starting_scripts = dcPage::jsLoad('js/_media_item.js'); +if ($popup) { + $starting_scripts .= + dcPage::jsLoad('js/jsToolBar/popup_media.js'); +} +call_user_func($open_f,__('Media manager'), + $starting_scripts. + dcPage::jsDatePicker(). + dcPage::jsPageTabs() +); + +if ($file === null) { + call_user_func($close_f); + exit; +} + +if (!empty($_GET['fupd']) || !empty($_GET['fupl'])) { + echo '

    '.__('File has been successfully updated.').'

    '; +} +if (!empty($_GET['thumbupd'])) { + echo '

    '.__('Thumbnails have been successfully updated.').'

    '; +} + +echo '

    '.__('Media manager').''. +' / '.$core->media->breadCrumb(html::escapeURL($media_page_url).'&d=%s'). +$file->basename.'

    '; + +# Insertion popup +if ($popup) +{ + $media_desc = $file->media_title; + + echo + '
    '. + '
    '; + + if ($file->media_type == 'image') + { + $media_type = 'image'; + $media_desc = dcGetImageTitle($file,$core->blog->settings->media_img_title_pattern); + if ($media_desc == $file->basename) { + $media_desc = ''; + } + + echo + '

    '.__('Image size:').'

    '; + + $s_checked = false; + echo '

    '; + foreach (array_reverse($file->media_thumb) as $s => $v) { + $s_checked = ($s == 'm'); + echo '
    '; + } + $s_checked = (!isset($file->media_thumb['m'])); + echo '
    '; + echo '

    '; + + + echo '

    '.__('Image alignment').'

    '; + $i_align = array( + 'none' => array(__('None'),1), + 'left' => array(__('Left'),0), + 'right' => array(__('Right'),0), + 'center' => array(__('Center'),0) + ); + + echo '

    '; + foreach ($i_align as $k => $v) { + echo '
    '; + } + echo '

    '; + + echo + '

    '.__('Image insertion').'

    '. + '

    '. + '
    '. + ''. + '

    '; + } + elseif ($file->type == 'audio/mpeg3') + { + $media_type = 'mp3'; + + echo '

    '.__('MP3 disposition').'

    '. + '

    '.__("Please note that you cannot insert mp3 files with visual editor.").'

    '; + + $i_align = array( + 'none' => array(__('None'),0), + 'left' => array(__('Left'),0), + 'right' => array(__('Right'),0), + 'center' => array(__('Center'),1) + ); + + echo '

    '; + foreach ($i_align as $k => $v) { + echo '
    '; + } + + $public_player = dcMedia::mp3player($file->file_url,$core->blog->getQmarkURL().'pf=player_mp3.swf'); + echo form::hidden('public_player',html::escapeHTML($public_player)); + echo '

    '; + } + elseif ($file->type == 'video/x-flv' || $file->type == 'video/mp4' || $file->type == 'video/x-m4v') + { + $media_type = 'flv'; + + echo + '

    '.__("Please note that you cannot insert video files with visual editor.").'

    '; + + echo + '

    '.__('Video size').'

    '. + '

    '; + + echo '

    '.__('Video disposition').'

    '; + + $i_align = array( + 'none' => array(__('None'),0), + 'left' => array(__('Left'),0), + 'right' => array(__('Right'),0), + 'center' => array(__('Center'),1) + ); + + echo '

    '; + foreach ($i_align as $k => $v) { + echo '
    '; + } + + $public_player = dcMedia::flvplayer($file->file_url,$core->blog->getQmarkURL().'pf=player_flv.swf'); + echo form::hidden('public_player',html::escapeHTML($public_player)); + echo '

    '; + } + else + { + $media_type = 'default'; + echo '

    '.__('Media item will be inserted as a link.').'

    '; + } + + echo + '

    '.__('Cancel').' - '. + ''.__('Insert').''. + form::hidden(array('type'),html::escapeHTML($media_type)). + form::hidden(array('title'),html::escapeHTML($file->media_title)). + form::hidden(array('description'),html::escapeHTML($media_desc)). + form::hidden(array('url'),$file->file_url). + '

    '; + + echo '
    '; +} + +echo +'
    '. +'

    '; + +echo +'
    '; + +if ($file->media_image) +{ + $thumb_size = !empty($_GET['size']) ? $_GET['size'] : 's'; + + if (!isset($core->media->thumb_sizes[$thumb_size]) && $thumb_size != 'o') { + $thumb_size = 's'; + } + + echo '

    '.__('Available sizes:').' '; + foreach (array_reverse($file->media_thumb) as $s => $v) + { + $strong_link = ($s == $thumb_size) ? '%s' : '%s'; + printf($strong_link,''.$core->media->thumb_sizes[$s][2].' | '); + } + echo ''.__('original').''; + echo '

    '; + + if (isset($file->media_thumb[$thumb_size])) { + echo '

    '; + } elseif ($thumb_size == 'o') { + $S = getimagesize($file->file); + $class = ($S[1] > 500) ? ' class="overheight"' : ''; + unset($S); + echo '

    '; + } +} + +if ($file->type == 'audio/mpeg3') +{ + echo dcMedia::mp3player($file->file_url,'index.php?pf=player_mp3.swf'); +} + +if ($file->type == 'video/x-flv' || $file->type == 'video/mp4' || $file->type == 'video/x-m4v') +{ + echo dcMedia::flvplayer($file->file_url,'index.php?pf=player_flv.swf'); +} + +echo +'

    '.__('Media details').'

    '. +'
      '. + '
    • '.__('File owner:').' '.$file->media_user.'
    • '. + '
    • '.__('File type:').' '.$file->type.'
    • '. + '
    • '.__('File size:').' '.files::size($file->size).'
    • '. + '
    • '.__('File URL:').' '.$file->file_url.'
    • '. +'
    '; + +if (empty($_GET['find_posts'])) +{ + echo + '

    '. + __('Show entries containing this media').'

    '; +} +else +{ + echo '

    '.__('Entries containing this media').'

    '; + $params = array( + 'post_type' => '', + 'from' => 'LEFT OUTER JOIN '.$core->prefix.'post_media PM ON P.post_id = PM.post_id ', + 'sql' => 'AND ('. + 'PM.media_id = '.(integer) $id.' '. + "OR post_content_xhtml LIKE '%".$core->con->escape($file->relname)."%' ". + "OR post_excerpt_xhtml LIKE '%".$core->con->escape($file->relname)."%' " + ); + + if ($file->media_image) + { # We look for thumbnails too + $media_root = $core->blog->host.path::clean($core->blog->settings->public_url).'/'; + foreach ($file->media_thumb as $v) { + $v = preg_replace('/^'.preg_quote($media_root,'/').'/','',$v); + $params['sql'] .= "OR post_content_xhtml LIKE '%".$core->con->escape($v)."%' "; + $params['sql'] .= "OR post_excerpt_xhtml LIKE '%".$core->con->escape($v)."%' "; + } + } + + $params['sql'] .= ') '; + + $rs = $core->blog->getPosts($params); + + if ($rs->isEmpty()) + { + echo '

    '.__('No entry seems contain this media.').'

    '; + } + else + { + echo '
      '; + while ($rs->fetch()) { + echo '
    • '. + $rs->post_title.''. + ($rs->post_type != 'post' ? ' ('.html::escapeHTML($rs->post_type).')' : ''). + ' - '.dt::dt2str(__('%Y-%m-%d %H:%M'),$rs->post_dt).'
    • '; + } + echo '
    '; + } +} + +if ($file->type == 'image/jpeg') +{ + echo '

    '.__('Image details').'

    '; + + if (count($file->media_meta) == 0) + { + echo '

    '.__('No detail').'

    '; + } + else + { + echo '
      '; + foreach ($file->media_meta as $k => $v) + { + if ((string) $v) { + echo '
    • '.$k.': '.html::escapeHTML($v).'
    • '; + } + } + echo '
    '; + } +} + +if ($file->editable && $core_media_writable) +{ + if ($file->media_type == 'image') + { + echo + '
    '. + '
    '.__('Update thumbnails').''. + '

    '.__('This will create or update thumbnails for this image.').'

    '. + '

    '. + form::hidden(array('id'),$id). + $core->formNonce().'

    '. + '
    '; + } + + if ($file->type == 'application/zip') + { + $inflate_combo = array( + __('Extract in a new directory') => 'new', + __('Extract in current directory') => 'current' + ); + + echo + '
    '. + '
    '.__('Extract archive').''. + '
      '. + '
    • '.__('Extract in a new directory').' : '. + __('This will extract archive in a new directory that should not exists yet.').'
    • '. + '
    • '.__('Extract in current directory').' : '. + __('This will extract archive in current directory and will overwrite existing files or directory.').'
    • '. + '
    '. + '

    '. + ''. + form::hidden(array('id'),$id). + $core->formNonce().'

    '. + '
    '; + } + + echo + '
    '. + '
    '.__('Change media properties').''. + '

    '. + '

    '. + '

    '. + '

    '. + '

    '. + '

    '. + form::hidden(array('id'),$id). + $core->formNonce().'

    '. + '
    '; + + echo + '
    '. + '
    '.__('Change file').''. + '
    '.form::hidden(array('MAX_FILE_SIZE'),DC_MAX_UPLOAD_SIZE).'
    '. + '

    '. + '

    '. + form::hidden(array('id'),$id). + $core->formNonce().'

    '. + '
    '; +} + +echo +'
    '. +'
    '; + +call_user_func($close_f); +?> \ No newline at end of file diff --git a/admin/permissions.php b/admin/permissions.php new file mode 100644 index 0000000..f9094a7 --- /dev/null +++ b/admin/permissions.php @@ -0,0 +1,160 @@ +userExists($u)) { + $users[] = $u; + } + } +} + +# Check blogs +if (!empty($_REQUEST['blog_id']) && is_array($_REQUEST['blog_id'])) +{ + foreach ($_REQUEST['blog_id'] as $b) + { + if ($core->blogExists($b)) { + $blogs[] = $b; + } + } +} + +# Update permissions +if (!empty($_POST['upd_perm']) && !empty($users) && !empty($blogs)) +{ + $redir = 'permissions.php?upd=1'; + + try + { + if (empty($_POST['your_pwd']) || !$core->auth->checkPassword(crypt::hmac(DC_MASTER_KEY,$_POST['your_pwd']))) { + throw new Exception(__('Password verification failed')); + } + + foreach ($users as $u) + { + foreach ($blogs as $b) + { + $set_perms = array(); + + if (!empty($_POST['perm'][$b])) + { + foreach ($_POST['perm'][$b] as $perm_id => $v) + { + if ($v) { + $set_perms[$perm_id] = true; + } + } + } + + $core->setUserBlogPermissions($u, $b, $set_perms, true); + } + + $redir .= '&user_id[]='.$u; + } + + foreach ($blogs as $b) { + $redir .= '&blog_id[]='.$b; + } + http::redirect($redir); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} + + + +if (empty($blogs) || empty($users)) { + $core->error->add(__('No blog or user given.')); +} + + +/* DISPLAY +-------------------------------------------------------- */ +dcPage::open(__('permissions'), + dcPage::jsLoad('js/_permissions.js') +); + +echo '

    '.__('Users').' › '.__('Permissions').'

    '; + +if (!empty($_GET['upd'])) { + echo '

    '.__('The permissions have been successfully updated.').'

    '; +} + +if (!empty($blogs) && !empty($users)) +{ + $perm_form = ''; + + if (count($users) == 1) { + $user_perm = $core->getUserPermissions($users[0]); + } + + foreach ($users as $u) { + $user_list[] = ''.$u.''; + } + + echo '

    '.sprintf(__('You are about to change permissions on the following blogs for users %s.'), + implode(', ',$user_list)); + + echo '

    '; + + foreach ($blogs as $b) + { + echo '

    '.html::escapeHTML($b).''. + form::hidden(array('blog_id[]'),$b).'

    '; + + foreach ($core->auth->getPermissionsTypes() as $perm_id => $perm) + { + $checked = false; + + if (count($users) == 1) { + $checked = isset($user_perm[$b]['p'][$perm_id]) && $user_perm[$b]['p'][$perm_id]; + } + + echo + '

    '; + } + } + + echo + '
    '. + '

    '. + '
    '. + '

    '. + $core->formNonce(); + + foreach ($users as $u) { + echo form::hidden(array('user_id[]'),$u); + } + + echo form::hidden('upd_perm',1).'

    '; +} + +dcPage::close(); +?> \ No newline at end of file diff --git a/admin/permissions_blog.php b/admin/permissions_blog.php new file mode 100644 index 0000000..9720b7c --- /dev/null +++ b/admin/permissions_blog.php @@ -0,0 +1,196 @@ + 'B.blog_id', +__('Blog name') => 'blog_name' +); + +$order_combo = array( +__('Descending') => 'desc', +__('Ascending') => 'asc' +); + +$q = !empty($_GET['q']) ? $_GET['q'] : ''; +$sortby = !empty($_GET['sortby']) ? $_GET['sortby'] : 'blog_id'; +$order = !empty($_GET['order']) ? $_GET['order'] : 'asc'; + + +# Check users +if (!empty($_REQUEST['user_id']) && is_array($_REQUEST['user_id'])) +{ + foreach ($_REQUEST['user_id'] as $u) + { + if ($core->userExists($u)) { + $users[] = $u; + } + } +} + +if (empty($users)) +{ + $core->error->add(__('No blog or user given.')); +} +else +{ + $page = !empty($_GET['page']) ? $_GET['page'] : 1; + $nb_per_page = 30; + + if (!empty($_GET['nb']) && (integer) $_GET['nb'] > 0) { + $nb_per_page = $_GET['nb']; + } + + $show_filters = false; + + # - Search filter + if ($q) { + $params['q'] = $q; + $show_filters = true; + } + + # - Sortby and order filter + if ($sortby !== '' && in_array($sortby,$sortby_combo)) { + if ($order !== '' && in_array($order,$order_combo)) { + $params['order'] = $sortby.' '.$order; + $show_filters = true; + } + } + + $params['limit'] = array((($page-1)*$nb_per_page),$nb_per_page); + + try { + $rs = $core->getBlogs($params); + $counter = $core->getBlogs($params,1); + $nb_blog = $counter->f(0); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} + +/* DISPLAY +-------------------------------------------------------- */ +$starting_script = dcPage::jsLoad('js/_permissions_blog.js'); +if (!$show_filters) { + $starting_script .= dcPage::jsLoad('js/filter-controls.js'); +} +dcPage::open(__('choose a blog'),$starting_script); + +echo '

    '.__('Users').' › '.__('Choose a blog').'

    '; + +if (!$core->error->flag()) +{ + $hidden_fields = ''; + foreach ($users as $u) { + $hidden_fields .= form::hidden(array('user_id[]'),$u); + } + + if (!$show_filters) { + echo '

    '.__('Filters').'

    '; + } + + echo + '
    '. + '
    '.__('Filters').''. + + '
    '. + '

    '. + '

    '. + '
    '. + + '
    '. + '

    '. + '

    '. + ''. + $hidden_fields.'

    '. + '
    '. + + '
    '. //Opera sucks + '
    '. + '
    '; + + echo + '

    '. + sprintf(__('Choose one or more blogs to which you want to give permissions to users %s.'), + ''.implode(', ',$users).'').'

    '; + + # Show blogs + if ($nb_blog == 0) + { + echo '

    '.__('No blog').'

    '; + } + else + { + $pager = new pager($page,$nb_blog,$nb_per_page,10); + $pager->var_page = 'page'; + + echo '

    '.__('Page(s)').' : '.$pager->getLinks().'

    '; + + echo + '
    '. + ''. + ''. + ''. + ''. + ''. + ''; + + while ($rs->fetch()) { + echo blogLine($rs); + } + + echo + '
    '.__('Blog ID').''.__('Blog name').''.__('Entries').''.__('Status').'
    '. + + '

    '. + + '

    '. + $hidden_fields. + $core->formNonce().'

    '. + '
    '; + + echo '

    '.__('Page(s)').' : '.$pager->getLinks().'

    '; + } +} + +dcPage::close(); + +function blogLine(&$rs) +{ + global $core; + + $img_status = $rs->blog_status == 1 ? 'check-on' : 'check-off'; + $txt_status = $GLOBALS['core']->getBlogStatus($rs->blog_status); + $img_status = sprintf('%2$s',$img_status,$txt_status); + + return + ''. + ''. + form::checkbox(array('blog_id[]'),$rs->blog_id).''. + ''.$rs->blog_id.''. + ''.html::escapeHTML($rs->blog_name).''. + ''.$core->countBlogPosts($rs->blog_id).''. + ''.$img_status.''. + ''; +} +?> \ No newline at end of file diff --git a/admin/plugin.php b/admin/plugin.php new file mode 100644 index 0000000..0e633a9 --- /dev/null +++ b/admin/plugin.php @@ -0,0 +1,91 @@ +plugins->moduleExists($p)) { + $p_file = $core->plugins->moduleRoot($p).'/index.php'; +} + +if (file_exists($p_file)) +{ + # Loading plugin + $p_info = $core->plugins->getModules($p); + + $p_url = 'plugin.php?p='.$p; + + $p_title = 'no content - plugin'; + $p_head = ''; + $p_content = '

    '.__('No content found on this plugin.').'

    '; + + ob_start(); + include $p_file; + $res = ob_get_contents(); + ob_end_clean(); + + if (preg_match('|(.*?)(.*?)|ms',$m[1],$mt)) { + $p_title = $mt[1]; + } + + if (preg_match_all('|(.*?)|ms',$m[1],$ms)) { + foreach ($ms[1] as $v) { + $p_head .= $v."\n"; + } + } + + if (preg_match_all('|(.*?)|ms',$m[1],$ms)) { + foreach ($ms[1] as $v) { + $p_head .= $v."\n"; + } + } + + if (preg_match_all('|()|ms',$m[1],$ms)) { + foreach ($ms[1] as $v) { + $p_head .= $v."\n"; + } + } + } + + if (preg_match('|(.+)|ms',$res,$m)) { + $p_content = $m[1]; + } + + call_user_func($open_f,$p_title,$p_head); + echo $p_content; + call_user_func($close_f); +} +else +{ + call_user_func($open_f,__('Plugin not found')); + + echo '

    '.__('Plugin not found').'

    '; + + echo '

    '.__('The plugin you reached does not exist or does not have an admin page.').'

    '; + + call_user_func($close_f); +} +?> \ No newline at end of file diff --git a/admin/plugins.php b/admin/plugins.php new file mode 100644 index 0000000..f93a378 --- /dev/null +++ b/admin/plugins.php @@ -0,0 +1,364 @@ +plugins->moduleExists($plugin_id)) { + throw new Exception(__('No such plugin.')); + } + + $plugin = $core->plugins->getModules($plugin_id); + $plugin['id'] = $plugin_id; + + if (!preg_match('!^'.$p_path_pat.'!', $plugin['root'])) { + throw new Exception(__('You don\'t have permissions to delete this plugin.')); + } + + # --BEHAVIOR-- pluginBeforeDelete + $core->callBehavior('pluginsBeforeDelete', $plugin); + + $core->plugins->deleteModule($plugin_id); + + # --BEHAVIOR-- pluginAfterDelete + $core->callBehavior('pluginsAfterDelete', $plugin); + } + else + { + $core->plugins->deleteModule($plugin_id,true); + } + + http::redirect('plugins.php?removed=1'); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } + } + # Deactivate plugin + elseif ($plugin_id && !empty($_POST['deactivate'])) + { + try + { + if (!$core->plugins->moduleExists($plugin_id)) { + throw new Exception(__('No such plugin.')); + } + + $plugin = $core->plugins->getModules($plugin_id); + $plugin['id'] = $plugin_id; + + if (!$plugin['root_writable']) { + throw new Exception(__('You don\'t have permissions to deactivate this plugin.')); + } + + $core->plugins->deactivateModule($plugin_id); + http::redirect('plugins.php'); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } + } + # Activate plugin + elseif ($plugin_id && !empty($_POST['activate'])) + { + try + { + $p = $core->plugins->getDisabledModules(); + if (!isset($p[$plugin_id])) { + throw new Exception(__('No such plugin.')); + } + $core->plugins->activateModule($plugin_id); + http::redirect('plugins.php'); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } + } + # Plugin upload + elseif ((!empty($_POST['upload_pkg']) && !empty($_FILES['pkg_file'])) || + (!empty($_POST['fetch_pkg']) && !empty($_POST['pkg_url']))) + { + try + { + if (empty($_POST['your_pwd']) || !$core->auth->checkPassword(crypt::hmac(DC_MASTER_KEY,$_POST['your_pwd']))) { + throw new Exception(__('Password verification failed')); + } + + if (!empty($_POST['upload_pkg'])) + { + files::uploadStatus($_FILES['pkg_file']); + + $dest = $p_path.'/'.$_FILES['pkg_file']['name']; + if (!move_uploaded_file($_FILES['pkg_file']['tmp_name'],$dest)) { + throw new Exception(__('Unable to move uploaded file.')); + } + } + else + { + $url = urldecode($_POST['pkg_url']); + $dest = $p_path.'/'.basename($url); + + try + { + $client = netHttp::initClient($url,$path); + $client->setUserAgent('Dotclear - http://www.dotclear.org/'); + $client->useGzip(false); + $client->setPersistReferers(false); + $client->setOutput($dest); + $client->get($path); + } + catch( Exception $e) + { + throw new Exception(__('An error occurred while downloading the file.')); + } + + unset($client); + } + + $ret_code = $core->plugins->installPackage($dest,$core->plugins); + http::redirect('plugins.php?added='.$ret_code); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + $default_tab = 'addplugin'; + } + } +} + +# Plugin install +$plugins_install = $core->plugins->installModules(); + +/* DISPLAY Main page +-------------------------------------------------------- */ +dcPage::open(__('Plugins management'), + dcPage::jsLoad('js/_plugins.js'). + dcPage::jsPageTabs($default_tab) +); + +echo +'

    '.__('Plugins management').'

    '; + +if (!empty($_GET['removed'])) { + echo + '

    '.__('Plugin has been successfully deleted.').'

    '; +} +if (!empty($_GET['added'])) { + echo '

    '. + ($_GET['added'] == 2 ? __('Plugin has been successfully upgraded') : __('Plugin has been successfully installed.')). + '

    '; +} + +# Plugins install messages +if (!empty($plugins_install['success'])) +{ + echo '
    '.__('Following plugins have been installed:').'
      '; + foreach ($plugins_install['success'] as $k => $v) { + echo '
    • '.$k.'
    • '; + } + echo '
    '; +} +if (!empty($plugins_install['failure'])) +{ + echo '
    '.__('Following plugins have not been installed:').'
      '; + foreach ($plugins_install['failure'] as $k => $v) { + echo '
    • '.$k.' ('.$v.')
    • '; + } + echo '
    '; +} + +# List all active plugins +echo '

    '.__('Plugins add new functionalities to Dotclear. '. +'Here you can activate or deactivate installed plugins.').'

    '; + +echo '

    '.sprintf(__('You can find additional plugins for your blog on %s.'), +'Dotaddict').' '; + +if ($is_writable) { + echo __('To install or upgrade a plugin you generally just need to upload it '. + 'in "Install or upgrade a plugin" section.'); +} else { + echo __('To install or upgrade a plugin you just need to extract it in your plugins directory.'); +} +echo '

    '; + +echo +'
    '; + +$p_available = $core->plugins->getModules(); +uasort($p_available,create_function('$a,$b','return strcasecmp($a["name"],$b["name"]);')); +if (!empty($p_available)) +{ + echo + '

    '.__('Activated plugins').'

    '. + ''. + ''. + ''. + ''. + ''. + ''; + + foreach ($p_available as $k => $v) + { + $is_deletable = $is_writable && preg_match('!^'.$p_path_pat.'!',$v['root']); + $is_deactivable = $v['root_writable']; + + echo + ''. + ''. + ''. + ''. + ''. + ''; + } + echo + '
    '.__('Plugin').''.__('Version').''.__('Details').''.__('Action').'
    '.html::escapeHTML($k).''.html::escapeHTML($v['version']).''.html::escapeHTML($v['name']).' '. + '
    '.html::escapeHTML($v['desc']).'
    '; + + if ($is_deletable || $is_deactivable) + { + echo + '
    '. + '
    '. + $core->formNonce(). + form::hidden(array('plugin_id'),html::escapeHTML($k)). + ($is_deactivable ? ' ' : ''). + ($is_deletable ? ' ' : ''). + '
    '. + '
    '; + } + + echo + '
    '; +} + +$p_disabled = $core->plugins->getDisabledModules(); +uksort($p_disabled,create_function('$a,$b','return strcasecmp($a,$b);')); +if (!empty($p_disabled)) +{ + echo + '

    '.__('Deactivated plugins').'

    '. + ''. + ''. + ''. + ''; + + foreach ($p_disabled as $k => $v) + { + $is_deletable = $is_writable && preg_match('!^'.$p_path_pat.'!',$v['root']); + $is_activable = $v['root_writable']; + + echo + ''. + ''. + ''. + ''; + } + echo + '
    '.__('Plugin').''.__('Action').'
    '.html::escapeHTML($k).''; + + if ($is_deletable || $is_activable) + { + echo + '
    '. + '
    '. + $core->formNonce(). + form::hidden(array('plugin_id'),html::escapeHTML($k)). + form::hidden(array('deactivated'),1). + ($is_activable ? ' ' : ''). + ($is_deletable ? ' ' : ''). + '
    '. + '
    '; + } + + echo + '
    '; +} + +echo '
    '; + +# Add a new plugin +echo +'
    '; + +if ($is_writable) +{ + echo '

    '.__('You can install plugins by uploading or downloading zip files.').'

    '; + + # 'Upload plugin' form + echo + '
    '. + '
    '. + ''.__('Upload a zip file').''. + '

    '. + '

    '. + ''. + $core->formNonce(). + '
    '. + '
    '; + + # 'Fetch plugin' form + echo + '
    '. + '
    '. + ''.__('Download a zip file').''. + '

    '. + '

    '. + ''. + $core->formNonce(). + '
    '. + '
    '; +} +else +{ + echo + '

    '. + __('To enable this function, please give write access to your plugins directory.'). + '

    '; +} +echo '
    '; + +# --BEHAVIOR-- pluginsToolsTabs +$core->callBehavior('pluginsToolsTabs',$core); + +dcPage::close(); +?> \ No newline at end of file diff --git a/admin/popup_link.php b/admin/popup_link.php new file mode 100644 index 0000000..a75d496 --- /dev/null +++ b/admin/popup_link.php @@ -0,0 +1,58 @@ +'.__('Add a link').''; + +# Languages combo +$rs = $core->blog->getLangs(array('order'=>'asc')); +$all_langs = l10n::getISOcodes(0,1); +$lang_combo = array('' => '', __('Most used') => array(), __('Available') => l10n::getISOcodes(1,1)); +while ($rs->fetch()) { + if (isset($all_langs[$rs->post_lang])) { + $lang_combo[__('Most used')][$all_langs[$rs->post_lang]] = $rs->post_lang; + unset($lang_combo[__('Available')][$all_langs[$rs->post_lang]]); + } else { + $lang_combo[__('Most used')][$rs->post_lang] = $rs->post_lang; + } +} +unset($all_langs); +unset($rs); + +echo +''. + +'

    '.__('cancel').' - '. +''.__('insert').'

    '."\n". + +''."\n"; + +dcPage::closePopup(); +?> \ No newline at end of file diff --git a/admin/popup_posts.php b/admin/popup_posts.php new file mode 100644 index 0000000..9b771a6 --- /dev/null +++ b/admin/popup_posts.php @@ -0,0 +1,57 @@ +'.__('Add a link to an entry').''; + +echo '
    '. +'

    '. +'

    '. +'
    '; + +try { + $posts = $core->blog->getPosts($params); + $counter = $core->blog->getPosts($params,true); + $post_list = new adminPostMiniList($core,$posts,$counter->f(0)); +} catch (Exception $e) { + $core->error->add($e->getMessage()); +} + +echo '
    '; # I know it's not a form but we just need the ID +$post_list->display($page,$nb_per_page); +echo '
    '; + +echo '

    '.__('cancel').'

    '; + +dcPage::closePopup(); +?> \ No newline at end of file diff --git a/admin/post.php b/admin/post.php new file mode 100644 index 0000000..796ddc6 --- /dev/null +++ b/admin/post.php @@ -0,0 +1,657 @@ +auth->getOption('post_format'); +$post_password = ''; +$post_url = ''; +$post_lang = $core->auth->getInfo('user_lang'); +$post_title = ''; +$post_excerpt = ''; +$post_excerpt_xhtml = ''; +$post_content = ''; +$post_content_xhtml = ''; +$post_notes = ''; +$post_status = $core->auth->getInfo('user_post_status'); +$post_selected = false; +$post_open_comment = $core->blog->settings->allow_comments; +$post_open_tb = $core->blog->settings->allow_trackbacks; + +$post_media = array(); + +$page_title = __('New entry'); + +$can_view_page = true; +$can_edit_post = $core->auth->check('usage,contentadmin',$core->blog->id); +$can_publish = $core->auth->check('publish,contentadmin',$core->blog->id); +$can_delete = false; + +$post_headlink = ''; +$post_link = '%s'; + +$next_link = $prev_link = $next_headlink = $prev_headlink = null; + +# If user can't publish +if (!$can_publish) { + $post_status = -2; +} + +# Getting categories +$categories_combo = array(' ' => ''); +try { + $categories = $core->blog->getCategories(array('post_type'=>'post')); + while ($categories->fetch()) { + $categories_combo[] = new formSelectOption( + str_repeat('  ',$categories->level-1).'• '.html::escapeHTML($categories->cat_title), + $categories->cat_id + ); + } +} catch (Exception $e) { } + +# Status combo +foreach ($core->blog->getAllPostStatus() as $k => $v) { + $status_combo[$v] = (string) $k; +} + +# Formaters combo +foreach ($core->getFormaters() as $v) { + $formaters_combo[$v] = $v; +} + +# Languages combo +$rs = $core->blog->getLangs(array('order'=>'asc')); +$all_langs = l10n::getISOcodes(0,1); +$lang_combo = array('' => '', __('Most used') => array(), __('Available') => l10n::getISOcodes(1,1)); +while ($rs->fetch()) { + if (isset($all_langs[$rs->post_lang])) { + $lang_combo[__('Most used')][$all_langs[$rs->post_lang]] = $rs->post_lang; + unset($lang_combo[__('Available')][$all_langs[$rs->post_lang]]); + } else { + $lang_combo[__('Most used')][$rs->post_lang] = $rs->post_lang; + } +} +unset($all_langs); +unset($rs); + + +# Get entry informations +if (!empty($_REQUEST['id'])) +{ + $params['post_id'] = $_REQUEST['id']; + + $post = $core->blog->getPosts($params); + + if ($post->isEmpty()) + { + $core->error->add(__('This entry does not exist.')); + $can_view_page = false; + } + else + { + $post_id = $post->post_id; + $cat_id = $post->cat_id; + $post_dt = date('Y-m-d H:i',strtotime($post->post_dt)); + $post_format = $post->post_format; + $post_password = $post->post_password; + $post_url = $post->post_url; + $post_lang = $post->post_lang; + $post_title = $post->post_title; + $post_excerpt = $post->post_excerpt; + $post_excerpt_xhtml = $post->post_excerpt_xhtml; + $post_content = $post->post_content; + $post_content_xhtml = $post->post_content_xhtml; + $post_notes = $post->post_notes; + $post_status = $post->post_status; + $post_selected = (boolean) $post->post_selected; + $post_open_comment = (boolean) $post->post_open_comment; + $post_open_tb = (boolean) $post->post_open_tb; + + $page_title = __('Edit entry'); + + $can_edit_post = $post->isEditable(); + $can_delete= $post->isDeletable(); + + $next_rs = $core->blog->getNextPost($post,1); + $prev_rs = $core->blog->getNextPost($post,-1); + + if ($next_rs !== null) { + $next_link = sprintf($post_link,$next_rs->post_id, + html::escapeHTML($next_rs->post_title),__('next entry').' »'); + $next_headlink = sprintf($post_headlink,'next', + html::escapeHTML($next_rs->post_title),$next_rs->post_id); + } + + if ($prev_rs !== null) { + $prev_link = sprintf($post_link,$prev_rs->post_id, + html::escapeHTML($prev_rs->post_title),'« '.__('previous entry')); + $prev_headlink = sprintf($post_headlink,'previous', + html::escapeHTML($prev_rs->post_title),$prev_rs->post_id); + } + + try { + $core->media = new dcMedia($core); + $post_media = $core->media->getPostMedia($post_id); + } catch (Exception $e) {} + } +} + +# Format excerpt and content +if (!empty($_POST) && $can_edit_post) +{ + $post_format = $_POST['post_format']; + $post_excerpt = $_POST['post_excerpt']; + $post_content = $_POST['post_content']; + + $post_title = $_POST['post_title']; + + $cat_id = (integer) $_POST['cat_id']; + + if (isset($_POST['post_status'])) { + $post_status = (integer) $_POST['post_status']; + } + + if (empty($_POST['post_dt'])) { + $post_dt = ''; + } else { + $post_dt = strtotime($_POST['post_dt']); + $post_dt = date('Y-m-d H:i',$post_dt); + } + + $post_open_comment = !empty($_POST['post_open_comment']); + $post_open_tb = !empty($_POST['post_open_tb']); + $post_selected = !empty($_POST['post_selected']); + $post_lang = $_POST['post_lang']; + $post_password = !empty($_POST['post_password']) ? $_POST['post_password'] : null; + + $post_notes = $_POST['post_notes']; + + if (isset($_POST['post_url'])) { + $post_url = $_POST['post_url']; + } + + $core->blog->setPostContent( + $post_id,$post_format,$post_lang, + $post_excerpt,$post_excerpt_xhtml,$post_content,$post_content_xhtml + ); +} + +# Create or update post +if (!empty($_POST) && !empty($_POST['save']) && $can_edit_post) +{ + $cur = $core->con->openCursor($core->prefix.'post'); + + $cur->post_title = $post_title; + $cur->cat_id = ($cat_id ? $cat_id : null); + $cur->post_dt = $post_dt ? date('Y-m-d H:i:00',strtotime($post_dt)) : ''; + $cur->post_format = $post_format; + $cur->post_password = $post_password; + $cur->post_lang = $post_lang; + $cur->post_title = $post_title; + $cur->post_excerpt = $post_excerpt; + $cur->post_excerpt_xhtml = $post_excerpt_xhtml; + $cur->post_content = $post_content; + $cur->post_content_xhtml = $post_content_xhtml; + $cur->post_notes = $post_notes; + $cur->post_status = $post_status; + $cur->post_selected = (integer) $post_selected; + $cur->post_open_comment = (integer) $post_open_comment; + $cur->post_open_tb = (integer) $post_open_tb; + + if (isset($_POST['post_url'])) { + $cur->post_url = $post_url; + } + + # Update post + if ($post_id) + { + try + { + # --BEHAVIOR-- adminBeforePostUpdate + $core->callBehavior('adminBeforePostUpdate',$cur,$post_id); + + $core->blog->updPost($post_id,$cur); + + # --BEHAVIOR-- adminAfterPostUpdate + $core->callBehavior('adminAfterPostUpdate',$cur,$post_id); + + http::redirect('post.php?id='.$post_id.'&upd=1'); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } + } + else + { + $cur->user_id = $core->auth->userID(); + + try + { + # --BEHAVIOR-- adminBeforePostCreate + $core->callBehavior('adminBeforePostCreate',$cur); + + $return_id = $core->blog->addPost($cur); + + # --BEHAVIOR-- adminAfterPostCreate + $core->callBehavior('adminAfterPostCreate',$cur,$return_id); + + http::redirect('post.php?id='.$return_id.'&crea=1'); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } + } +} + +if (!empty($_POST['delete']) && $can_delete) +{ + try { + # --BEHAVIOR-- adminBeforePostDelete + $core->callBehavior('adminBeforePostDelete',$post_id); + $core->blog->delPost($post_id); + http::redirect('posts.php'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} + +/* DISPLAY +-------------------------------------------------------- */ +$default_tab = 'edit-entry'; +if (!$can_edit_post) { + $default_tab = ''; +} +if (!empty($_GET['co'])) { + $default_tab = 'comments'; +} + +dcPage::open($page_title, + dcPage::jsDatePicker(). + dcPage::jsToolBar(). + dcPage::jsModal(). + dcPage::jsLoad('js/_post.js'). + dcPage::jsConfirmClose('entry-form','comment-form'). + # --BEHAVIOR-- adminPostHeaders + $core->callBehavior('adminPostHeaders'). + dcPage::jsPageTabs($default_tab). + $next_headlink."\n".$prev_headlink +); + +if (!empty($_GET['upd'])) { + echo '

    '.__('Entry has been successfully updated.').'

    '; +} +elseif (!empty($_GET['crea'])) { + echo '

    '.__('Entry has been successfully created.').'

    '; +} +elseif (!empty($_GET['attached'])) { + echo '

    '.__('File has been successfully attached.').'

    '; +} +elseif (!empty($_GET['rmattach'])) { + echo '

    '.__('Attachment has been successfully removed.').'

    '; +} + +if (!empty($_GET['creaco'])) { + echo '

    '.__('Comment has been successfully created.').'

    '; + } + +# XHTML conversion +if (!empty($_GET['xconv'])) +{ + $post_excerpt = $post_excerpt_xhtml; + $post_content = $post_content_xhtml; + $post_format = 'xhtml'; + + echo '

    '.__('Don\'t forget to validate your XHTML conversion by saving your post.').'

    '; +} + +echo '

    '.html::escapeHTML($core->blog->name).' › '.$page_title; + +if ($post_id && $post->post_status == 1) { + echo ' - '.__('View entry').''; +} elseif ($post_id) { + $preview_url = + $core->blog->url.$core->url->getBase('preview').'/'. + $core->auth->userID().'/'. + http::browserUID(DC_MASTER_KEY.$core->auth->userID().$core->auth->getInfo('user_pwd')). + '/'.$post->post_url; + echo ' - '.__('Preview entry').''; +} + +echo '

    '; + +if ($post_id) +{ + echo '

    '; + if ($prev_link) { echo $prev_link; } + if ($next_link && $prev_link) { echo ' - '; } + if ($next_link) { echo $next_link; } + + # --BEHAVIOR-- adminPostNavLinks + $core->callBehavior('adminPostNavLinks',isset($post) ? $post : null); + + echo '

    '; +} + +# Exit if we cannot view page +if (!$can_view_page) { + dcPage::helpBlock('core_post'); + dcPage::close(); + exit; +} + +/* Post form if we can edit post +-------------------------------------------------------- */ +if ($can_edit_post) +{ + echo '
    '; + echo '
    '; + echo '
    '; + + echo + '

    '. + + '

    '. + + '

    '. + + '

    '. + + '

    '. + '

    '. + '

    '. + + '

    '. + + '

    '. + + '
    '. + '

    '. + '

    '. + __('Warning: If you set the URL manually, it may conflict with another entry.'). + '

    '. + '
    '; + + if ($post_id) + { + echo + '

    '.__('Attachments').'

    '; + foreach ($post_media as $f) + { + $ftitle = $f->media_title; + if (strlen($ftitle) > 18) { + $ftitle = substr($ftitle,0,16).'...'; + } + echo + '
    '. + ''. + ''. + ''. + '
    '; + } + unset($f); + + if (empty($post_media)) { + echo '

    '.__('No attachment.').'

    '; + } + echo '

    '.__('Add files to this entry').'

    '; + } + + # --BEHAVIOR-- adminPostFormSidebar + $core->callBehavior('adminPostFormSidebar',isset($post) ? $post : null); + + echo '
    '; // End #entry-sidebar + + echo '
    '; + + echo + '

    '. + + '

    '. + form::textarea('post_excerpt',50,5,html::escapeHTML($post_excerpt),'',2). + '

    '. + + '

    '. + form::textarea('post_content',50,$core->auth->getOption('edit_size'),html::escapeHTML($post_content),'',2). + '

    '. + + '

    '. + form::textarea('post_notes',50,5,html::escapeHTML($post_notes),'',2). + '

    '; + + # --BEHAVIOR-- adminPostForm + $core->callBehavior('adminPostForm',isset($post) ? $post : null); + + echo + '

    '. + ($post_id ? form::hidden('id',$post_id) : ''). + ' '. + ($can_delete ? '' : ''). + $core->formNonce(). + '

    '; + + echo '
    '; // End #entry-content + echo '
    '; + echo '
    '; + + if ($post_id && $post->post_status == 1) { + echo '

    '. + __('Ping blogs').'

    '; + } + + if ($post_id && !empty($post_media)) + { + echo + '
    '. + '
    '.form::hidden(array('post_id'),$post_id). + form::hidden(array('media_id'),''). + form::hidden(array('remove'),1). + $core->formNonce().'
    '; + } +} + + +/* Comments and trackbacks +-------------------------------------------------------- */ +if ($post_id) +{ + $params = array('post_id' => $post_id, 'order' => 'comment_dt ASC'); + + $comments = $core->blog->getComments(array_merge($params,array('comment_trackback'=>0))); + $trackbacks = $core->blog->getComments(array_merge($params,array('comment_trackback'=>1))); + + # Actions combo box + $combo_action = array(); + if ($can_edit_post && $core->auth->check('publish,contentadmin',$core->blog->id)) + { + $combo_action[__('publish')] = 'publish'; + $combo_action[__('unpublish')] = 'unpublish'; + $combo_action[__('mark as pending')] = 'pending'; + $combo_action[__('mark as junk')] = 'junk'; + } + + if ($can_edit_post && $core->auth->check('delete,contentadmin',$core->blog->id)) + { + $combo_action[__('delete')] = 'delete'; + } + + $has_action = !empty($combo_action) && (!$trackbacks->isEmpty() || !$comments->isEmpty()); + + echo + '
    '; + + if ($has_action) { + echo '
    '; + } + + echo '

    '.__('Trackbacks').'

    '; + + if (!$trackbacks->isEmpty()) { + showComments($trackbacks,$has_action); + } else { + echo '

    '.__('No trackback').'

    '; + } + + echo '

    '.__('Comments').'

    '; + if (!$comments->isEmpty()) { + showComments($comments,$has_action); + } else { + echo '

    '.__('No comment').'

    '; + } + + if ($has_action) { + echo + '
    '. + '

    '. + + '

    '.__('Selected comments action:').' '. + form::combo('action',$combo_action). + form::hidden('redir','post.php?id='.$post_id.'&co=1'). + $core->formNonce(). + '

    '. + '
    '. + '
    '; + } + + echo '
    '; +} + +/* Add a comment +-------------------------------------------------------- */ +if ($post_id) +{ + echo + '
    '. + '

    '.__('Add a comment').'

    '. + + '
    '. + '
    '. + '

    '. + + '

    '. + + '

    '. + + '

    '. + form::textarea('comment_content',50,8,html::escapeHTML('')). + '

    '. + + '

    '.form::hidden('post_id',$post_id). + $core->formNonce(). + '

    '. + '
    '. + '
    '. + '
    '; +} + + +# Show comments or trackbacks +function showComments(&$rs,$has_action) +{ + echo + ''. + ''. + ''. + ''. + ''. + ''. + ''; + + while($rs->fetch()) + { + $comment_url = 'comment.php?id='.$rs->comment_id; + + $img = '%1$s'; + switch ($rs->comment_status) { + case 1: + $img_status = sprintf($img,__('published'),'check-on.png'); + break; + case 0: + $img_status = sprintf($img,__('unpublished'),'check-off.png'); + break; + case -1: + $img_status = sprintf($img,__('pending'),'check-wrn.png'); + break; + case -2: + $img_status = sprintf($img,__('junk'),'junk.png'); + break; + } + + echo + ''. + + ''. + ''. + ''. + ''. + ''. + ''. + + ''; + } + + echo '
    '.__('Author').''.__('Date').''.__('IP address').''.__('Status').' 
    '. + ($has_action ? form::checkbox(array('comments[]'),$rs->comment_id,'','','',0) : '').''.html::escapeHTML($rs->comment_author).''.dt::dt2str(__('%Y-%m-%d %H:%M'),$rs->comment_dt).''.$rs->comment_ip.''.$img_status.''. + '
    '; +} + +dcPage::helpBlock('core_post','core_wiki'); +dcPage::close(); +?> diff --git a/admin/post_media.php b/admin/post_media.php new file mode 100644 index 0000000..1360dd4 --- /dev/null +++ b/admin/post_media.php @@ -0,0 +1,79 @@ +blog->getPosts(array('post_id' => $post_id,'post_type'=>'')); +if ($rs->isEmpty()) { + exit; +} + +if ($post_id && $media_id && !empty($_POST['attach'])) +{ + $core->media = new dcMedia($core); + $core->media->addPostMedia($post_id,$media_id); + http::redirect($core->getPostAdminURL($rs->post_type,$post_id,false)); +} + +try { + $core->media = new dcMedia($core); + $f = $core->media->getPostMedia($post_id,$media_id); + if (empty($f)) { + $post_id = $media_id = null; + throw new Exception(__('This attachment does not exist')); + } + $f = $f[0]; +} catch (Exception $e) { + $core->error->add($e->getMessage()); +} + +# Remove a media from en +if (($post_id && $media_id) || $core->error->flag()) +{ + if (!empty($_POST['remove'])) + { + $core->media->removePostMedia($post_id,$media_id); + http::redirect($core->getPostAdminURL($rs->post_type,$post_id,false).'&rmattach=1'); + } + elseif (isset($_POST['post_id'])) { + http::redirect($core->getPostAdminURL($rs->post_type,$post_id,false)); + } + + if (!empty($_GET['remove'])) + { + dcPage::open(__('Remove attachment')); + + echo '

    '.__('Attachment').' › '.__('confirm removal').'

    '; + + echo + '
    '. + '

    '.__('Are you sure you want to remove this attachment?').'

    '. + '

    '. + '   '. + form::hidden('post_id',$post_id). + form::hidden('media_id',$media_id). + $core->formNonce().'

    '. + '
    '; + + dcPage::close(); + exit; + } +} +?> \ No newline at end of file diff --git a/admin/posts.php b/admin/posts.php new file mode 100644 index 0000000..c575a9c --- /dev/null +++ b/admin/posts.php @@ -0,0 +1,298 @@ +blog->getCategories(array('post_type'=>'post')); +} catch (Exception $e) { + $core->error->add($e->getMessage()); +} + +# Getting authors +try { + $users = $core->blog->getPostsUsers(); +} catch (Exception $e) { + $core->error->add($e->getMessage()); +} + +# Getting dates +try { + $dates = $core->blog->getDates(array('type'=>'month')); +} catch (Exception $e) { + $core->error->add($e->getMessage()); +} + +# Getting langs +try { + $langs = $core->blog->getLangs(); +} catch (Exception $e) { + $core->error->add($e->getMessage()); +} + +# Creating filter combo boxes +if (!$core->error->flag()) +{ + # Filter form we'll put in html_block + $users_combo = $categories_combo = array(); + $users_combo['-'] = $categories_combo['-'] = ''; + while ($users->fetch()) + { + $user_cn = dcUtils::getUserCN($users->user_id,$users->user_name, + $users->user_firstname,$users->user_displayname); + + if ($user_cn != $users->user_id) { + $user_cn .= ' ('.$users->user_id.')'; + } + + $users_combo[$user_cn] = $users->user_id; + } + + while ($categories->fetch()) { + $categories_combo[str_repeat('  ',$categories->level-1).'• '. + html::escapeHTML($categories->cat_title). + ' ('.$categories->nb_post.')'] = $categories->cat_id; + } + + $status_combo = array( + '-' => '' + ); + foreach ($core->blog->getAllPostStatus() as $k => $v) { + $status_combo[$v] = (string) $k; + } + + $selected_combo = array( + '-' => '', + __('selected') => '1', + __('not selected') => '0' + ); + + # Months array + $dt_m_combo['-'] = ''; + while ($dates->fetch()) { + $dt_m_combo[dt::str('%B %Y',$dates->ts())] = $dates->year().$dates->month(); + } + + $lang_combo['-'] = ''; + while ($langs->fetch()) { + $lang_combo[$langs->post_lang] = $langs->post_lang; + } + + $sortby_combo = array( + __('Date') => 'post_dt', + __('Title') => 'post_title', + __('Category') => 'cat_title', + __('Author') => 'user_id', + __('Status') => 'post_status', + __('Selected') => 'post_selected' + ); + + $order_combo = array( + __('Descending') => 'desc', + __('Ascending') => 'asc' + ); +} + +# Actions combo box +$combo_action = array(); +if ($core->auth->check('publish,contentadmin',$core->blog->id)) +{ + $combo_action[__('publish')] = 'publish'; + $combo_action[__('unpublish')] = 'unpublish'; + $combo_action[__('schedule')] = 'schedule'; + $combo_action[__('mark as pending')] = 'pending'; +} +$combo_action[__('mark as selected')] = 'selected'; +$combo_action[__('mark as unselected')] = 'unselected'; +$combo_action[__('change category')] = 'category'; +if ($core->auth->check('admin',$core->blog->id)) { + $combo_action[__('change author')] = 'author'; +} +if ($core->auth->check('delete,contentadmin',$core->blog->id)) +{ + $combo_action[__('delete')] = 'delete'; +} + +# --BEHAVIOR-- adminPostsActionsCombo +$core->callBehavior('adminPostsActionsCombo',array(&$combo_action)); + +/* Get posts +-------------------------------------------------------- */ +$user_id = !empty($_GET['user_id']) ? $_GET['user_id'] : ''; +$cat_id = !empty($_GET['cat_id']) ? $_GET['cat_id'] : ''; +$status = isset($_GET['status']) ? $_GET['status'] : ''; +$selected = isset($_GET['selected']) ? $_GET['selected'] : ''; +$month = !empty($_GET['month']) ? $_GET['month'] : ''; +$lang = !empty($_GET['lang']) ? $_GET['lang'] : ''; +$sortby = !empty($_GET['sortby']) ? $_GET['sortby'] : 'post_dt'; +$order = !empty($_GET['order']) ? $_GET['order'] : 'desc'; + +$show_filters = false; + +$page = !empty($_GET['page']) ? (integer) $_GET['page'] : 1; +$nb_per_page = 30; + +if (!empty($_GET['nb']) && (integer) $_GET['nb'] > 0) { + if ($nb_per_page != $_GET['nb']) { + $show_filters = true; + } + $nb_per_page = (integer) $_GET['nb']; +} + +$params['limit'] = array((($page-1)*$nb_per_page),$nb_per_page); +$params['no_content'] = true; + +# - User filter +if ($user_id !== '' && in_array($user_id,$users_combo)) { + $params['user_id'] = $user_id; + $show_filters = true; +} + +# - Categories filter +if ($cat_id !== '' && in_array($cat_id,$categories_combo)) { + $params['cat_id'] = $cat_id; + $show_filters = true; +} + +# - Status filter +if ($status !== '' && in_array($status,$status_combo)) { + $params['post_status'] = $status; + $show_filters = true; +} + +# - Selected filter +if ($selected !== '' && in_array($selected,$selected_combo)) { + $params['post_selected'] = $selected; + $show_filters = true; +} + +# - Month filter +if ($month !== '' && in_array($month,$dt_m_combo)) { + $params['post_month'] = substr($month,4,2); + $params['post_year'] = substr($month,0,4); + $show_filters = true; +} + +# - Lang filter +if ($lang !== '' && in_array($lang,$lang_combo)) { + $params['post_lang'] = $lang; + $show_filters = true; +} + +# - Sortby and order filter +if ($sortby !== '' && in_array($sortby,$sortby_combo)) { + if ($order !== '' && in_array($order,$order_combo)) { + $params['order'] = $sortby.' '.$order; + } + + if ($sortby != 'post_dt' || $order != 'desc') { + $show_filters = true; + } +} + +# Get posts +try { + $posts = $core->blog->getPosts($params); + $counter = $core->blog->getPosts($params,true); + $post_list = new adminPostList($core,$posts,$counter->f(0)); +} catch (Exception $e) { + $core->error->add($e->getMessage()); +} + +/* DISPLAY +-------------------------------------------------------- */ +$starting_script = dcPage::jsLoad('js/_posts_list.js'); +if (!$show_filters) { + $starting_script .= dcPage::jsLoad('js/filter-controls.js'); +} + +dcPage::open(__('Entries'),$starting_script); + +if (!$core->error->flag()) +{ + echo '

    '.html::escapeHTML($core->blog->name).' › '.__('Entries').'

    '; + + if (!$show_filters) { + echo '

    '. + __('Filters').'

    '; + } + + echo + '
    '. + '
    '.__('Filters').''. + '
    '. + '
    '. + ' '. + ' '. + ' '. + '
    '. + + '
    '. + ' '. + ' '. + ' '. + '
    '. + + '
    '. + '

    '. + '

    '. + '

    '. + '

    '. + '
    '. + '
    '. + '
    '. //Opera sucks + '
    '. + '
    '; + + # Show posts + $post_list->display($page,$nb_per_page, + '
    '. + + '%s'. + + '
    '. + '

    '. + + '

    '.__('Selected entries action:').' '. + form::combo('action',$combo_action). + '

    '. + form::hidden(array('user_id'),$user_id). + form::hidden(array('cat_id'),$cat_id). + form::hidden(array('status'),$status). + form::hidden(array('selected'),$selected). + form::hidden(array('month'),$month). + form::hidden(array('lang'),$lang). + form::hidden(array('sortby'),$sortby). + form::hidden(array('order'),$order). + form::hidden(array('page'),$page). + form::hidden(array('nb'),$nb_per_page). + $core->formNonce(). + '
    '. + '
    ' + ); +} + +dcPage::helpBlock('core_posts','core_wiki'); +dcPage::close(); +?> \ No newline at end of file diff --git a/admin/posts_actions.php b/admin/posts_actions.php new file mode 100644 index 0000000..21594b0 --- /dev/null +++ b/admin/posts_actions.php @@ -0,0 +1,250 @@ + $v) { + $entries[$k] = (integer) $v; + } + + $params['sql'] = 'AND P.post_id IN('.implode(',',$entries).') '; + $params['no_content'] = true; + + if (isset($_POST['post_type'])) { + $params['post_type'] = $_POST['post_type']; + } + + $posts = $core->blog->getPosts($params); + + # --BEHAVIOR-- adminPostsActions + $core->callBehavior('adminPostsActions',$core,$posts,$action,$redir); + + if (preg_match('/^(publish|unpublish|schedule|pending)$/',$action)) + { + switch ($action) { + case 'unpublish' : $status = 0; break; + case 'schedule' : $status = -1; break; + case 'pending' : $status = -2; break; + default : $status = 1; break; + } + + try + { + while ($posts->fetch()) { + $core->blog->updPostStatus($posts->post_id,$status); + } + + http::redirect($redir); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } + } + elseif ($action == 'selected' || $action == 'unselected') + { + try + { + while ($posts->fetch()) { + $core->blog->updPostSelected($posts->post_id,$action == 'selected'); + } + + http::redirect($redir); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } + } + elseif ($action == 'delete') + { + try + { + while ($posts->fetch()) { + # --BEHAVIOR-- adminBeforePostDelete + $core->callBehavior('adminBeforePostDelete',$posts->post_id); + $core->blog->delPost($posts->post_id); + } + + http::redirect($redir); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } + + } + elseif ($action == 'category' && isset($_POST['new_cat_id'])) + { + try + { + while ($posts->fetch()) + { + $new_cat_id = (integer) $_POST['new_cat_id']; + $core->blog->updPostCategory($posts->post_id,$new_cat_id); + } + http::redirect($redir); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } + } + elseif ($action == 'author' && isset($_POST['new_auth_id']) + && $core->auth->check('admin',$core->blog->id)) + { + $new_user_id = $_POST['new_auth_id']; + + try + { + if ($core->getUser($new_user_id)->isEmpty()) { + throw new Exception(__('This user does not exist')); + } + + while ($posts->fetch()) + { + $cur = $core->con->openCursor($core->prefix.'post'); + $cur->user_id = $new_user_id; + $cur->update('WHERE post_id = '.(integer) $posts->post_id); + } + + http::redirect($redir); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } + } +} + +/* DISPLAY +-------------------------------------------------------- */ +dcPage::open(__('Entries')); + +if (!isset($action)) { + dcPage::close(); + exit; +} + +$hidden_fields = ''; +while ($posts->fetch()) { + $hidden_fields .= form::hidden(array('entries[]'),$posts->post_id); +} + +if (isset($_POST['redir']) && strpos($_POST['redir'],'://') === false) +{ + $hidden_fields .= form::hidden(array('redir'),html::escapeURL($_POST['redir'])); +} +else +{ + $hidden_fields .= + form::hidden(array('user_id'),$_POST['user_id']). + form::hidden(array('cat_id'),$_POST['cat_id']). + form::hidden(array('status'),$_POST['status']). + form::hidden(array('selected'),$_POST['selected']). + form::hidden(array('month'),$_POST['month']). + form::hidden(array('lang'),$_POST['lang']). + form::hidden(array('sortby'),$_POST['sortby']). + form::hidden(array('order'),$_POST['order']). + form::hidden(array('page'),$_POST['page']). + form::hidden(array('nb'),$_POST['nb']); +} + +if (isset($_POST['post_type'])) { + $hidden_fields .= form::hidden(array('post_type'),$_POST['post_type']); +} + +# --BEHAVIOR-- adminPostsActionsContent +$core->callBehavior('adminPostsActionsContent',$core,$action,$hidden_fields); + +if ($action == 'category') +{ + echo '

    '.__('Change category for entries').'

    '; + + # categories list + # Getting categories + $categories_combo = array(' ' => ''); + try { + $categories = $core->blog->getCategories(array('post_type'=>'post')); + while ($categories->fetch()) { + $categories_combo[] = new formSelectOption( + str_repeat('  ',$categories->level-1).'• '.html::escapeHTML($categories->cat_title), + $categories->cat_id + ); + } + } catch (Exception $e) { } + + echo + '
    '. + '

    '; + + echo + $hidden_fields. + $core->formNonce(). + form::hidden(array('action'),'category'). + '

    '. + '
    '; +} +elseif ($action == 'author' && $core->auth->check('admin',$core->blog->id)) +{ + echo '

    '.__('Change author for entries').'

    '; + + echo + '
    '. + '

    '; + + echo + $hidden_fields. + $core->formNonce(). + form::hidden(array('action'),'author'). + '

    '. + '
    '; +} + +echo '

    '.__('back').'

    '; + +dcPage::close(); +?> \ No newline at end of file diff --git a/admin/preferences.php b/admin/preferences.php new file mode 100644 index 0000000..13e018a --- /dev/null +++ b/admin/preferences.php @@ -0,0 +1,202 @@ +auth->getInfo('user_name'); +$user_firstname = $core->auth->getInfo('user_firstname'); +$user_displayname = $core->auth->getInfo('user_displayname'); +$user_email = $core->auth->getInfo('user_email'); +$user_url = $core->auth->getInfo('user_url'); +$user_lang = $core->auth->getInfo('user_lang'); +$user_tz = $core->auth->getInfo('user_tz'); +$user_post_status = $core->auth->getInfo('user_post_status'); + +$user_options = $core->auth->getOptions(); + +foreach ($core->getFormaters() as $v) { + $formaters_combo[$v] = $v; +} + +foreach ($core->blog->getAllPostStatus() as $k => $v) { + $status_combo[$v] = $k; +} + +# Language codes +$langs = l10n::getISOcodes(1,1); +foreach ($langs as $k => $v) { + $lang_avail = $v == 'en' || is_dir(DC_L10N_ROOT.'/'.$v); + $lang_combo[] = new formSelectOption($k,$v,$lang_avail ? 'avail10n' : ''); +} + +# Add or update user +if (isset($_POST['user_name'])) +{ + try + { + $pwd_check = !empty($_POST['cur_pwd']) && $core->auth->checkPassword(crypt::hmac(DC_MASTER_KEY,$_POST['cur_pwd'])); + + if ($core->auth->allowPassChange() && !$pwd_check && $user_email != $_POST['user_email']) { + throw new Exception(__('If you want to change your email or password you must provide your current password.')); + } + + $cur = $core->con->openCursor($core->prefix.'user'); + + $cur->user_name = $user_name = $_POST['user_name']; + $cur->user_firstname = $user_firstname = $_POST['user_firstname']; + $cur->user_displayname = $user_displayname = $_POST['user_displayname']; + $cur->user_email = $user_email = $_POST['user_email']; + $cur->user_url = $user_url = $_POST['user_url']; + $cur->user_lang = $user_lang = $_POST['user_lang']; + $cur->user_tz = $user_tz = $_POST['user_tz']; + $cur->user_post_status = $user_post_status = $_POST['user_post_status']; + + $user_options['edit_size'] = (integer) $_POST['user_edit_size']; + if ($user_options['edit_size'] < 1) { + $user_options['edit_size'] = 10; + } + $user_options['post_format'] = $_POST['user_post_format']; + $user_options['enable_wysiwyg'] = !empty($_POST['user_wysiwyg']); + + $cur->user_options = new ArrayObject($user_options); + + if ($core->auth->allowPassChange() && !empty($_POST['new_pwd'])) + { + if (!$pwd_check) { + throw new Exception(__('If you want to change your email or password you must provide your current password.')); + } + + if ($_POST['new_pwd'] != $_POST['new_pwd_c']) { + throw new Exception(__("Passwords don't match")); + } + + $cur->user_pwd = $_POST['new_pwd']; + } + + # --BEHAVIOR-- adminBeforeUserUpdate + $core->callBehavior('adminBeforeUserUpdate',$cur,$core->auth->userID()); + + # Udate user + $core->updUser($core->auth->userID(),$cur); + + # --BEHAVIOR-- adminAfterUserUpdate + $core->callBehavior('adminAfterUserUpdate',$cur,$core->auth->userID()); + + http::redirect('preferences.php?upd=1'); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} + + +/* DISPLAY +-------------------------------------------------------- */ +dcPage::open($page_title, + dcPage::jsLoad('js/_preferences.js'). + dcPage::jsConfirmClose('user-form'). + + # --BEHAVIOR-- adminPreferencesHeaders + $core->callBehavior('adminPreferencesHeaders') +); + +if (!empty($_GET['upd'])) { + echo '

    '.__('Personal information has been successfully updated.').'

    '; +} + +echo '

    '.$page_title.'

    '; + + +echo +'
    '. +'
    '.__('User preferences').''. +'
    '. +'
    '. +'

    '. + +'

    '. + +'

    '. + +'

    '. + +'

    '. + +'
    '. + +'
    '. + +'

    '. + +'

    '. + +'

    '. + +'

    '. + +'

    '. + +'

    '. +'
    '. +'
    '. +'
    '. //Opera sucks +'
    '; + +# --BEHAVIOR-- adminPreferencesForm +$core->callBehavior('adminPreferencesForm',$core); + +if ($core->auth->allowPassChange()) +{ + echo + '
    '. + ''.__('Change your password').''. + + '

    '. + + '

    '. + '
    '. + + '
    '. + '

    '.__('If you want to change your email or password you must provide your current password.').'

    '. + '

    '. + '
    '; +} + +echo +'

    '. +$core->formNonce(). +'

    '. +'
    '; + +dcPage::helpBlock('core_user_pref'); +dcPage::close(); +?> \ No newline at end of file diff --git a/admin/search.php b/admin/search.php new file mode 100644 index 0000000..fd7d899 --- /dev/null +++ b/admin/search.php @@ -0,0 +1,180 @@ +blog->getPosts($params); + $counter = $core->blog->getPosts($params,true); + $post_list = new adminPostList($core,$posts,$counter->f(0)); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } + } + # Get comments + elseif ($qtype == 'c') + { + $starting_scripts .= dcPage::jsLoad('js/_comments.js'); + + $params['search'] = $q; + $params['limit'] = array((($page-1)*$nb_per_page),$nb_per_page); + $params['no_content'] = true; + $params['order'] = 'comment_dt DESC'; + + try { + $comments = $core->blog->getComments($params); + $counter = $core->blog->getComments($params,true); + $comment_list = new adminCommentList($core,$comments,$counter->f(0)); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } + } +} + + +dcPage::open(__('Search'),$starting_scripts); + +echo +'

    '.html::escapeHTML($core->blog->name).' › '.__('Search').'

    '. +'
    '. +'
    '.__('Search options').''. +'

    '. +' '. +' '. +'

    '. +'
    '. +'
    '; + +if ($q && !$core->error->flag()) +{ + $redir = html::escapeHTML($_SERVER['REQUEST_URI']); + + # Show posts + if ($qtype == 'p') + { + # Actions combo box + $combo_action = array(); + if ($core->auth->check('publish,contentadmin',$core->blog->id)) + { + $combo_action[__('publish')] = 'publish'; + $combo_action[__('unpublish')] = 'unpublish'; + $combo_action[__('schedule')] = 'schedule'; + $combo_action[__('mark as pending')] = 'pending'; + } + $combo_action[__('change category')] = 'category'; + if ($core->auth->check('admin',$core->blog->id)) { + $combo_action[__('change author')] = 'author'; + } + if ($core->auth->check('delete,contentadmin',$core->blog->id)) + { + $combo_action[__('delete')] = 'delete'; + } + + # --BEHAVIOR-- adminPostsActionsCombo + $core->callBehavior('adminPostsActionsCombo',array(&$combo_action)); + + if ($counter->f(0) > 0) { + printf('

    '. + ($counter->f(0) == 1 ? __('%d entry found') : __('%d entries found')). + '

    ',$counter->f(0)); + } + + $post_list->display($page,$nb_per_page, + '
    '. + + '%s'. + + '
    '. + '

    '. + + '

    '.__('Selected entries action:'). + form::combo('action',$combo_action). + '

    '. + form::hidden('redir',preg_replace('/%/','%%',$redir)). + $core->formNonce(). + '
    '. + '
    ' + ); + } + # Show posts + elseif ($qtype == 'c') + { + # Actions combo box + $combo_action = array(); + if ($core->auth->check('publish,contentadmin',$core->blog->id)) + { + $combo_action[__('publish')] = 'publish'; + $combo_action[__('unpublish')] = 'unpublish'; + $combo_action[__('mark as pending')] = 'pending'; + $combo_action[__('mark as junk')] = 'junk'; + } + if ($core->auth->check('delete,contentadmin',$core->blog->id)) + { + $combo_action[__('delete')] = 'delete'; + } + + if ($counter->f(0) > 0) { + printf('

    '. + ($counter->f(0) == 1 ? __('%d comment found') : __('%d comments found')). + '

    ',$counter->f(0)); + } + + $comment_list->display($page,$nb_per_page, + '
    '. + + '%s'. + + '
    '. + '

    '. + + '

    '.__('Selected comments action:').' '. + form::combo('action',$combo_action). + '

    '. + form::hidden('redir',preg_replace('/%/','%%',$redir)). + $core->formNonce(). + '
    '. + '
    ' + ); + } +} + + +dcPage::close(); +?> \ No newline at end of file diff --git a/admin/services.php b/admin/services.php new file mode 100644 index 0000000..f19146c --- /dev/null +++ b/admin/services.php @@ -0,0 +1,236 @@ +rest->addFunction('getPostById',array('dcRestMethods','getPostById')); +$core->rest->addFunction('getCommentById',array('dcRestMethods','getCommentById')); +$core->rest->addFunction('quickPost',array('dcRestMethods','quickPost')); +$core->rest->addFunction('validatePostMarkup',array('dcRestMethods','validatePostMarkup')); +$core->rest->addFunction('getZipMediaContent',array('dcRestMethods','getZipMediaContent')); + +$core->rest->serve(); + +/* Common REST methods */ +class dcRestMethods +{ + public static function getPostById(&$core,$get) + { + if (empty($get['id'])) { + throw new Exception('No post ID'); + } + + $params = array('post_id' => (integer) $get['id']); + + if (isset($get['post_type'])) { + $params['post_type'] = $get['post_type']; + } + + $rs = $core->blog->getPosts($params); + + if ($rs->isEmpty()) { + throw new Exception('No post for this ID'); + } + + $rsp = new xmlTag('post'); + $rsp->id = $rs->post_id; + + $rsp->blog_id($rs->blog_id); + $rsp->user_id($rs->user_id); + $rsp->cat_id($rs->cat_id); + $rsp->post_dt($rs->post_dt); + $rsp->post_creadt($rs->post_creadt); + $rsp->post_upddt($rs->post_upddt); + $rsp->post_format($rs->post_format); + $rsp->post_url($rs->post_url); + $rsp->post_lang($rs->post_lang); + $rsp->post_title($rs->post_title); + $rsp->post_excerpt($rs->post_excerpt); + $rsp->post_excerpt_xhtml($rs->post_excerpt_xhtml); + $rsp->post_content($rs->post_content); + $rsp->post_content_xhtml($rs->post_content_xhtml); + $rsp->post_notes($rs->post_notes); + $rsp->post_status($rs->post_status); + $rsp->post_selected($rs->post_selected); + $rsp->post_open_comment($rs->post_open_comment); + $rsp->post_open_tb($rs->post_open_tb); + $rsp->nb_comment($rs->nb_comment); + $rsp->nb_trackback($rs->nb_trackback); + $rsp->user_name($rs->user_name); + $rsp->user_firstname($rs->user_firstname); + $rsp->user_displayname($rs->user_displayname); + $rsp->user_email($rs->user_email); + $rsp->user_url($rs->user_url); + $rsp->cat_title($rs->cat_title); + $rsp->cat_url($rs->cat_url); + + $rsp->post_display_content($rs->getContent(true)); + $rsp->post_display_excerpt($rs->getExcerpt(true)); + + $metaTag = new xmlTag('meta'); + if (($meta = @unserialize($rs->post_meta)) !== false) + { + foreach ($meta as $K => $V) + { + foreach ($V as $v) { + $metaTag->$K($v); + } + } + } + $rsp->post_meta($metaTag); + + return $rsp; + } + + public static function getCommentById(&$core,$get) + { + if (empty($get['id'])) { + throw new Exception('No comment ID'); + } + + $rs = $core->blog->getComments(array('comment_id' => (integer) $get['id'])); + + if ($rs->isEmpty()) { + throw new Exception('No comment for this ID'); + } + + $rsp = new xmlTag('post'); + $rsp->id = $rs->comment_id; + + $rsp->comment_dt($rs->comment_dt); + $rsp->comment_upddt($rs->comment_upddt); + $rsp->comment_author($rs->comment_author); + $rsp->comment_site($rs->comment_site); + $rsp->comment_content($rs->comment_content); + $rsp->comment_trackback($rs->comment_trackback); + $rsp->comment_status($rs->comment_status); + $rsp->post_title($rs->post_title); + $rsp->post_url($rs->post_url); + $rsp->post_id($rs->post_id); + $rsp->post_dt($rs->post_dt); + $rsp->user_id($rs->user_id); + + $rsp->comment_display_content($rs->getContent(true)); + + if ($core->auth->userID()) { + $rsp->comment_ip($rs->comment_ip); + $rsp->comment_email($rs->comment_email); + # --BEHAVIOR-- adminAfterCommentDesc + $rsp->comment_spam_disp($core->callBehavior('adminAfterCommentDesc', $rs)); + } + + return $rsp; + } + + public static function quickPost(&$core,$get,$post) + { + $cur = $core->con->openCursor($core->prefix.'post'); + + $cur->post_title = !empty($post['post_title']) ? $post['post_title'] : ''; + $cur->user_id = $core->auth->userID(); + $cur->post_content = !empty($post['post_content']) ? $post['post_content'] : ''; + $cur->cat_id = !empty($post['cat_id']) ? (integer) $post['cat_id'] : null; + $cur->post_format = !empty($post['post_format']) ? $post['post_format'] : 'xhtml'; + $cur->post_lang = !empty($post['post_lang']) ? $post['post_lang'] : ''; + $cur->post_status = !empty($post['post_status']) ? (integer) $post['post_status'] : 0; + $cur->post_open_comment = (integer) $core->blog->settings->allow_comments; + $cur->post_open_tb = (integer) $core->blog->settings->allow_trackbacks; + + # --BEHAVIOR-- adminBeforePostCreate + $core->callBehavior('adminBeforePostCreate',$cur); + + $return_id = $core->blog->addPost($cur); + + # --BEHAVIOR-- adminAfterPostCreate + $core->callBehavior('adminAfterPostCreate',$cur,$return_id); + + $rsp = new xmlTag('post'); + $rsp->id = $return_id; + + $post = $core->blog->getPosts(array('post_id' => $return_id)); + + $rsp->post_status = $post->post_status; + $rsp->post_url = $post->getURL(); + return $rsp; + } + + public static function validatePostMarkup(&$core,$get,$post) + { + if (!isset($post['excerpt'])) { + throw new Exception('No entry excerpt'); + } + + if (!isset($post['content'])) { + throw new Exception('No entry content'); + } + + if (empty($post['format'])) { + throw new Exception('No entry format'); + } + + if (!isset($post['lang'])) { + throw new Exception('No entry lang'); + } + + $excerpt = $post['excerpt']; + $excerpt_xhtml = ''; + $content = $post['content']; + $content_xhtml = ''; + $format = $post['format']; + $lang = $post['lang']; + + $core->blog->setPostContent(0,$format,$lang,$excerpt,$excerpt_xhtml,$content,$content_xhtml); + + $rsp = new xmlTag('result'); + + $v = htmlValidator::validate($excerpt_xhtml.$content_xhtml); + + $rsp->valid($v['valid']); + $rsp->errors($v['errors']); + + return $rsp; + } + + public static function getZipMediaContent(&$core,$get,$post) + { + if (empty($get['id'])) { + throw new Exception('No media ID'); + } + + $id = (integer) $get['id']; + + if (!$core->auth->check('media,media_admin',$core->blog)) { + throw new Exception('Permission denied'); + } + + $core->media = new dcMedia($core); + $file = $core->media->getFile($id); + + if ($file === null || $file->type != 'application/zip' || !$file->editable) { + throw new Exception('Not a valid file'); + } + + $rsp = new xmlTag('result'); + $content = $core->media->getZipContent($file); + + foreach ($content as $k => $v) { + $rsp->file($k); + } + + return $rsp; + } +} +?> \ No newline at end of file diff --git a/admin/style/candyUpload/cancel.png b/admin/style/candyUpload/cancel.png new file mode 100644 index 0000000000000000000000000000000000000000..b1a59471c3f21f2329931fe4a589a861c2b36d19 GIT binary patch literal 309 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=%3?!FCJ6-`&%*9TgAsieWw;%dH0CE)rd_r9R z|NsB*-@o7Q-~WF1?)CinZ|2W`J#XIqgoOL?@mCED&M+{D@#={J6*H9t`33)Hc)H!d z3&`Uv@Q5sCVBi)4Va7{$>;3=*#Y$WwN}P*Q6H7Al^Atidb5j|N4fG96^$jdmhR^R+>#4|r8huuglz u;=QMdC4aJ7^QN50^v`E@TsZvrqI~=ssfn9+&+G&m&*16m=d#Wzp$P!Nf^V<@ literal 0 HcmV?d00001 diff --git a/admin/style/candyUpload/loader.png b/admin/style/candyUpload/loader.png new file mode 100644 index 0000000000000000000000000000000000000000..267f54111eae4c93e3629b643bb5a61609e2769c GIT binary patch literal 858 zcmV-g1Eu_lP)RGReGUQd7@Bypi^|BM|q!9a-l6z7Pj;M8 zbDc_Yo<($OmUh?a+pkTnMiS$N^6@taF|GMmPl!uH*S?kZ|hkTqqGJ7$bPWsE*!jXGVBDq@Q|UXCtYk11Y@Fj|c#Uy3wgi8@(}CRmFl zU57MQi6d5sB~^$bRE8o|h9y&mAXJ4URD&f^gdS6YB~*bZQh_2?fGksgCr^SLPJbLt zfErAH8B2W`N_`hidLT=C8%TQMgsr<02XvbSad^jWnpw_ zZ*Cw|X>DZyGC40WH7_tY@MYc30003kNklUHWeNNLtF5Z;u+0Us$1 zKHu0jRryJ6@K@~7Vm4_S^0yA9ow6KB*D!TPJ$a;SxS-uas?#-GQbRHA>l&`5S#SH?9 z4i%kP;Xh!aBMYi3(Z7I!1tI8&geV(GFmRWoNn0V9dh-2x`o8zxefNAj)yl$n@XahcE8L?0RDoO~3Ks80 zl63j1=p*kwKK?C97q76nRkm7QLN@gj?9er$#9kno({X_9CShQWG+aL?0{~>;Iyre| zqO6vK0$Fz#J0YocDwf@8+J+-f=aXiPIN2i%gV<~N5sGti*C*m@VTLm3LRd2=&xl}P zwOj=S8WNCEw3Mx;Gaxgm=vm#!PTmGJ%)lM&13e3LRpo<@G!11mo=msN`6Qps(5a*4 z;(R|Q-{s_W#sUOkyWLjWX@!Ojs2PR^pNt=ev z2o!2*Q!r0~hEa!nQpAkpg&ryX>64b0Mi~Q5WbdEg_dsXpW$L)~&13qMplgPusYuHr zeWFi40qWCDD1RlsAe|NKD}OPri^ri`wBmQL zT#rbq2GuF3W;&51bHq)7sL?uWform>div { + line-height: 18px; +} +#info-box select { + width : 160px; +} +#info-box a.logout { + font-weight : bold; + color: #fff; +} + +#wrapper { + background: transparent url(page-bg.png) repeat-y top left; + width: 100%; +} +#main { + width : 100%; + float : right; + margin-left : -155px; + margin-top : 0; +} + +#content { + margin-left : 155px; + margin-bottom : 10px; + padding-top : 1px; + margin-right : 15px; +} + +#main-menu { + width : 135px; + float : left; + margin-top : 0; + margin-bottom : 10px; +} +#main-menu h3 { + margin : 0 0 0.5em 0; + padding : 0 0 0 5px; + text-transform: uppercase; + color: #7e7d77; +} +#main-menu ul { + margin : 0 0 1em 4px; + padding : 0; + list-style : none; +} +#main-menu li { + display : block; + margin : 0.5em 0 0 5px; + padding : 2px 0 1px 20px; + background-repeat: no-repeat; + background-position: 0 0; +} +#main-menu a { + font-weight : bold; +} +#main-menu .active a { + border-bottom-style: solid; +} +#main-menu #dashboard-menu li { + margin-left: 0; +} +#main-menu #menu-new-post a { + padding : 2px; + background: #7e7d77; + color: #fff; + border: 1px solid #7e7d77; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; +} +#main-menu #menu-new-post a:hover, #main-menu #menu-new-post a:focus { + background: #666; +} + +#footer { + clear : both; + margin: 0; + padding: 40px 0 0 0; + background: #fff url(footer-bg.png) no-repeat top left; +} +#footer p * { + vertical-align: bottom; +} +#footer p { + margin: 0 15px 0 155px;; + padding: 3px 0 20px 0; + border-top: 1px solid #dedcd1; + color: #93928a; + text-align: right; + font-size: 1.1em; +} + +#debug { + position: absolute; + top: 0; + width: 100%; + height: 4px; + background: #d99; +} +#debug div { + display: none; + padding: 3px 0.5em 2px; +} +#debug p { + margin : 0.5em 0; +} +#debug:hover { + height: auto; +} +#debug:hover div { + display: block; +} + +/* DASHBOARD */ +#dashboard-main { + float: left; + overflow: hidden; + padding-bottom: 1em; + width: 66%; +} +#dashboard-main #icons { + overflow: hidden; + padding-bottom: 1em; +} +#dashboard-main #icons p { + float: left; + width: 32%; + text-align: center; + margin: 2em 0 0 0; +} +#dashboard-main #icons span { + display: block; +} +#dashboard-main #icons a { + border-bottom-width: 0; +} +#dashboard-main #icons span a { + border-bottom-width: 1px; +} + +#dashboard-main #quick { + clear: left; + margin-top: 2em; +} +#dashboard-main #quick h3 { + margin-bottom: 0.2em; + font-size: 1.4em; +} +#dashboard-main #quick p.qinfo { + margin: -1em -1em 1em; + padding: 1em; + background: #ebeadd; +} + +#dashboard-items { + float: left; + width: 31%; + overflow: hidden; + margin-left: 2%; + padding-bottom: 1em; + font-size: 1.2em; +} +#dashboard-items p img { + vertical-align: middle; +} +#dashboard-items ul { + display: block; + padding-left: 1.5em; + list-style: square; +} +#dashboard-items li { + margin: 0.25em 0 0 0; + color: #666; +} +#dashboard-items #news dt { + font-weight: bold; + margin: 0 0 0.4em 0; +} +#dashboard-items #news dd { + font-size: 0.9em; + margin: 0 0 1em 0; +} +#dashboard-items #news dd p { + margin: 0.2em 0 0 0; +} +#upg-notify { + font-size: 0.9em; +} +#upg-notify ul { + padding-left: 15px; +} +#upg-notify li { + color: #fff; +} + +/* POST */ +#entry-sidebar { + width : 200px; + float : right; +} +#entry-content { + margin-right : 220px; +} +#comments { + clear : both; +} + +/* CATEGORIES */ +#categories { + margin: 1em 0 2em; +} +#categories ul { + list-style: none; + margin: 0 0 0 0; + padding: 0 0 0 0; +} +#categories ul li { + margin: 1em 0 0 0; + padding: 5px 10px 1em 30px; + border: 1px solid #ccc; + background: transparent url(cat-bg.png) repeat-y top left; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; +} +#categories ul li h4 { + margin: 0; +} +#categories ul li h4 span { + font-weight: normal; +} +#categories ul li p { + margin: 0; +} +select#del_cat { + width: 100%; +} + +/* MEDIA */ +#media-icon { + float: left; +} +#media-details { + margin-left: 70px; +} +#media-details ul { + display: block; + margin-left: 0; + padding: 0; +} +#media-details li { + list-style: square inside; + margin: 0; + padding: 0; +} +#media-original-image { + overflow: auto; +} +#media-original-image.overheight { + height: 500px; +} + +#add-file-f { + position: relative; +} +#add-file-f .more-file { + position:absolute; + right: 0.5em; + background: #999; + color: #fff; + border: none; +} + +/* Help */ +#help { + margin-top: 2em; + background: #d6dde5; +} +#help-button { + position: absolute; + top: 50px; + right: 0px; + cursor: pointer; + background: #06c; + -moz-border-radius: 8px 0 0 8px; + -webkit-border-top-left-radius: 8px; + -webkit-border-bottom-left-radius: 8px; +} +.help-box { + display: none; +} +.help-box ul { + padding-left: 20px; + margin-left: 0; +} +#content.with-help #help-button { + right: 280px; +} +#content.with-help #help { + display: block; + position: absolute; + top: 40px; + right: 0; + width: 280px; + border-left: 1px solid #ccc; + margin-top: 0; + padding: 10px 0 0 0; + overflow: auto; +} +#content.with-help .help-content { + padding: 0 5px 1em 5px; +} + +/* POPUP */ +body.popup #wrapper { + background-position : -130px 0; +} +body.popup #top h1 { + background-position : -130px 0; +} +body.popup #main { + margin-left : -35px; +} +body.popup #content { + margin-left : 35px; +} +body.popup #footer { + background-position: -130px 0; +} +body.popup #footer p { + margin-left: 35px; + border: none; +} + +/* CLASSES +-------------------------------------------------------- */ +a.button, a.back { + padding : 2px; + background: #e2dfca; + border: 1px solid #e2dfca; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + cursor: pointer; + outline: none; +} +a.button:hover, a.button:focus, a.back:hover, a.back:focus { + border-color: #ccc; +} +h2 a.button { + color: #333; + font-weight: normal; +} +a.back:before { + content: "\ab\a0"; +} + +.help-content dt { + font-weight: bold; + color: #666; + margin: 0; +} +.help-content dd { + margin: 0.3em 0 1.5em 0; +} + +.clear { + clear : both; +} +.lclear { + clear : left; +} +div.clearer { + height : 1px; + font-size : 1px; +} + +.hide { + display : none; +} + +.right { + text-align : right; +} + +.frame-shrink { + border: 1px solid #666; + padding: 0.5em; + margin-bottom: 1em; + height: 120px; + overflow: auto; +} + +.grid { + background: transparent repeat url('grid.png') 0 0; +} + +.line p { + margin : 0; +} + +div.error, p.error, div.message, p.message, div.static-msg, p.static-msg { + padding: 0.5em 0.5em 0.5em 40px; + margin-bottom: 1em; + -moz-border-radius: 8px; + -webkit-border-radius: 8px; +} +p.error, p.message, p.static-msg { + padding-top: 1em; + padding-bottom: 1em; +} +div.error, p.error { + background: #e5bfbf url(msg-error.png) no-repeat 5px 5px; + color: #600; +} +div.message, p.message, div.static-msg, p.static-msg { + background: #666 url(msg-std.png) no-repeat 5px 5px; + color: #fff; +} +div.message a, p.message a, div.static-msg a, p.static-msg a { + color: #fff; +} + +.offline { + color : #666; +} + +ul.nice { + margin: 1em 0; + padding: 0 0 0 2em; + list-style: square; +} +ul.nice li { + margin:0; + padding: 0; +} + +.three-cols { +} +.three-cols .col { + width : 32.3%; + float : left; + margin-left : 1%; +} +.three-cols .col:first-child { + width : 33.3%; + margin-left : 0; +} + +.two-cols { + position : static; +} +.two-cols .col { + width : 49%; + margin-left : 1%; + float : left; +} +.two-cols .col:first-child { + width : 50%; + margin-left : 0; +} + +.comment { + border-top : 2px solid #ccc; + margin-bottom : 1em; + padding : 2em 0 1em 0; + position : relative; +} +.comment form p { + margin : 0; + position : absolute; + top : 2px; + right : 0; +} + + +.part-tabs { + float: left; + width: 100%; + background: transparent url(tab-bg.png) repeat-x bottom; + margin-bottom: 2em; +} +.part-tabs ul { + margin: 0; + padding: 10px 10px 0; + list-style: none; +} +.part-tabs li { + float: left; + background: transparent url(tab-n-l.png) no-repeat top left; + margin: 0 3px 0 0; + padding: 0 0 0 5px; +} +.part-tabs a { + display: block; + background: transparent url(tab-n-r.png) no-repeat top right; + padding: 1px 10px 1px 5px; + border: none; + outline: none; +} +.part-tabs li.part-tabs-active { + background-image: url(tab-c-l.png); +} +.part-tabs li.part-tabs-active a { + background-image: url(tab-c-r.png); + padding-bottom: 2px; + font-weight : bold; +} +.part-tabs li.part-tabs-link { + background-image: url(tab-l-l.png); +} +.part-tabs li.part-tabs-link a { + background-image: url(tab-l-r.png); +} + +/* Themes list */ +#themes { + border-bottom: 1px solid #ccc; + margin: 1em 0; +} +#themes div.theme-details { + clear: left; + border-top: 1px solid #ccc; + padding: 1em 0; +} +#themes div.theme-details:hover { + background: #eee; +} +#themes div.theme-details div.theme-shot { + float: left; +} +#themes div.theme-details div.theme-shot img { + display: block; + width: 57px; + height: 50px; + border: 1px solid #ccc; +} +#themes div.theme-details div.theme-info { + margin-left: 67px; +} +#themes div.theme-details div.theme-info span.theme-desc { + display: block; +} +#themes div.theme-details div.theme-info span.theme-version { + color: #666; +} +#themes div.theme-details div.theme-actions { + margin-left: 67px; +} +/* Themes list, JS version */ +#themes-wrapper { +} +#theme-box { + border: 1px solid #999; + border-left: none; + padding: 5px; + float: right; + height: 400px; + width: 300px; + overflow: auto; +} +#theme-box div.theme-shot img { + display: block; + margin: 0 0 0 10px; + width: 280px; + height: 245px; + border: 1px solid #ccc; +} +#theme-box div.theme-info { + margin: 1em 0 0 10px; +} +#theme-box h3 { + margin: 0; +} +#theme-box div.theme-info span { + display: block; +} +#theme-box span.theme-version { + color: #666; +} +#theme-box span.theme-parent-ok { + color: #666; +} +#theme-box span.theme-parent-missing { + color: #c00; + font-weight:bold; +} +#theme-box div.theme-actions { + margin-left: 10px; +} +#themes-wrapper #themes { + border: 1px solid #999; + overflow: auto; + height: 400px; + padding: 5px; + margin: 0; +} +#themes div.theme-details-js { + float: left; + width: 120px; + height: 150px; + margin: 0 10px 20px; + padding: 10px 10px 0; + text-align: center; + background: #f3f3f3; + border: 1px solid #f3f3f3; + cursor: pointer; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; +} +#themes div.theme-details-js label { + cursor: pointer; +} +#themes div.theme-details-js.theme-selected { + background: #ebe9dd; + border: 1px solid #999; +} +#themes div.theme-details-js div.theme-shot img { + width: 120px; + height: 105px; + border: 1px solid #fff; +} +#themes div.theme-details-js h3 { + font-size: 90%; + font-family: inherit; + font-weight: normal; + margin: 0; + padding: 0; +} + +/* Plugins list */ +#plugins td.action { + vertical-align: middle; +} +#plugins td form input.activate, table.plugins form input.delete { + padding: 1px; + background: none; + font-weight: normal; + border-color: #f90; +} +#plugins td form input.delete { + font-weight: bold; + color: #c00; +} + +.media-list { + position : static; +} +.media-col-0 { + clear: left; +} +.media-item { + position: relative; + border-top: 1px solid #ccc; + margin-bottom: 1em; + padding: 5px 0; +} +div.media-list .media-item { + width: 49%; + float: left; + margin-right: 1%; +} +a.media-icon { + display: block; + border-bottom: none; + float: left; +} +.media-icon img { + display: block; +} +.media-item ul { + display: block; + list-style: none; + margin: 0 0 0 60px; + padding: 0; +} +li.media-action { + display: block; + position: absolute; + top: 5px; + right: 5px; + height: 16px; +} +li.media-action a { + border: none; +} +li.media-action form { + display: inline; +} +li.media-action input { + border: none; +} + +.zip-dl { + background: transparent url(package.png) no-repeat 0 50%; + padding: 5px 0 5px 20px; +} + +select.l10n option { + padding-left: 16px; +} +option.avail10n { + background: transparent url(../images/check-on.png) no-repeat 0 50%; +} + +/* TABLES +-------------------------------------------------------- */ +table { + font-size : 1em; + border-collapse : collapse; + margin : 0 0 1em 0; +} +tr.line:hover { + background : #ddd; +} +th, td { + border-width : 0 0 1px 0; + border-style : solid; + border-color : #ccc; + padding : 3px 5px; + vertical-align : top; +} +th { + text-align : left; + border-bottom-color : #666; +} + +.noborder td, td.noborder, .noborder th, th.noborder { + border-width : 0; +} + +table .maximal, table.maximal { + width : 100%; +} +table .minimal { + width : 1px; +} + +table .nowrap { + white-space : nowrap; +} + +td.status { + vertical-align: middle; +} +td.status img { + margin-bottom: -2px; +} +td.status a { + border: none; +} + +tr.line img.expand { + margin-right: 10px; + margin-bottom: -2px; +} +tr.line input { + vertical-align: top; +} +tr.expand td { + border-bottom: none; +} +td.expand { + padding: 1em; +} + +.dragable { + border-collapse: separate; +} +.dragable tbody td { + +} +.handle { + padding : 0; +} +.handler { + cursor : move; + background : transparent url(drag.png) no-repeat 0 50%; + padding-left : 15px; +} + +/* FORMS +-------------------------------------------------------- */ +form { + display : block; + margin : 0; + padding : 0; +} + +fieldset { + display : block; + margin : 0 0 1em 0; + padding : 1em 0.5em; + border-width : 1px 0; + border-style: solid; + border-color: #ccc; + background: #fbfbfb; +} +legend { + font-weight : bold; + padding: 0.2em 0.6em; + border-width: 1px; + border-style: solid; + border-color: #ccc; + background: #fbfbfb; + margin-bottom: 0.5em; +} +optgroup { + font-weight : bold; + font-style : normal; +} +option { + font-weight : normal; +} + +input, textarea, select { + background : #f9f9f9; + border-width : 1px; + border-style : solid; + border-color : #000 #ccc #ccc #000; +} +input, textarea, select, option { + font: 1em "DejaVu Sans","Lucida Grande","Lucida Sans Unicode",Arial,sans-serif; +} +input[type=text], input[type=password], textarea { + padding : 2px 0; +} +input[type=checkbox], input[type=radio] { + border: none; +} +textarea { + padding : 2px 0; +} +/*input[type=text]:focus, input[type=password]:focus, textarea:focus, option { + background : #dfdcc7; +} can't select text with opera */ +input[type=submit], input[type=reset], input[type=button], input.submit { + padding : 2px 2px; + background: #e2dfca; + border: 1px solid #e2dfca; + color: #333; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + cursor: pointer; +} +input[type=submit]:hover, input[type=reset]:hover, input[type=button]:hover, input.submit:hover { + border-color: #ccc; + color: #06c; +} + +input[type=submit], input.submit { + font-weight : bold; +} + +input[type=checkbox], input[type=radio] { + margin : 0; + padding : 0; + background : transparent; +} + +label { + display : block; +} +label input, label select, label span { + display : block; +} +p.form-note { + margin-top : -1em; + color : #f60; +} + +label.classic { + display : inline; +} +label.classic input, label span input, label.classic select, label span select { + display : inline; +} + +label.area, p.area { + width: inherit !important; +} +.area textarea { + display : block; + width : 100%; +} + +label.required { + font-weight : bold; +} +label.required:before { + content : '* '; + color : #c00; +} + +p.field { + position: relative; + +} +p.field label { + display: block; + width: 14em; +} +p.field input, p.field select { + display: inline; + position: absolute; + left: 15em; + top: 0; +} + +label .maximal, textarea.maximal, input.maximal { + width : 100%; +} + +a.form-control { + display : none; + font-weight: bold; + background: url(magnifier.png) no-repeat 0 0; + color: green; + padding-left: 20px; +} + +fieldset.constrained { + margin: 0; + padding: 0; + border: none; + background: transparent; +} + +#login-screen { + display: block; + width : 180px; + margin : 30px auto 0; + font-size: 1.1em; +} +#login-screen h1 { + text-indent: -2000px; + background: transparent url(dotclear-logo.png) no-repeat top left; + height: 46px; +} +#login-screen fieldset { + border: 1px solid #999; + padding: 1em 10px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; +} +#login-screen input[type=text], #login-screen input[type=password] { + width: 100%; +} \ No newline at end of file diff --git a/admin/style/dotclear-logo.png b/admin/style/dotclear-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..e39a3eaa56fa83741510fba9198ad500b04c478e GIT binary patch literal 2900 zcmcIkcUV)|5)ZH{b+J$^DA_2uAf!o=(7Qn?0xpVc3E=_}NU}+U5Tyt<(1!>j(&ep! zih_kIp|>CBhIKxwLOZmeosmr!R`16c*+c7CbL1$SKT!oS&DS|NLRzvxm94 z*||B{Igjt=Ji42e`FmDoT2^LiMtVYeT5@_?QsV8Hq}w+VZpFsMMqQ5vCGy(U3zsjQ zzjz@yG$be_I4};fNCe53BJV#+g+OFBil*4BzL1X)$PXK6)<HcJhktv;w!}|g>s0ZLpAR5DDnXh$(Dc*VLyWcxG)@C@eE(QfhWw= zMB0ds0m1$N4F{$B`w^)ax-o1uCI;M#%m^5C)rID33^NxcgC4PWf?AR&08|H#(#9kA z>Ogh$;Anlcfxey=)CEU_+Tn;$v_2G#M1l&9L7^}@DDW_=17;!(u0|A3FO0L5&F7rp zmodzTMk8Yoh`_)=c;H?*iQ!99^48-T5iVUvaDeDxN|h z(+DIYR1_EIK{`V-hQUOMzKqY8!;!xvB2qt-2hxb3MR)p#{r?f>iT}bE`3%Kx z^;tae2*3~U2Z%H($QkPIoO$9gUL=Y?j%Gse$9V$?GSS-z@zwZ0&-dxnU|E1=iTF~N ze;xhHQ+}7tSKhx%_)kHg(Tw0#UML7qm>0)k94WWfivR4 zwy>-99lvC^(z_RmZo9b6M5UcPy1U|W*kWhheBztlmr^?Xp?@jmhZPsc%AH$`_@f{m zxl+*MqsLc=Fw|`N`$ML}k-3U9@})6$!)mQI&kfiT>1o$w`b^JFa<)B94qWMd{hE+( zWj$P3#2F|f39O?&&hSc(9jjq)tCb2nA%CNg$NY&kGVDm*1Tj{PTm^Ofn2(zECm{_d>J>1Ai(=W|qM#bR9A4DLI4+VpzlE$vtz zXTHsU-Fcqr!z)&do~ixy84cE%?(aJNY~z%#%BP*v1p1At={lQbQ9Fpz9L4aVVz~G_ zLs^=iTGX35xuZVIS9ErE%Bi2GvbLL!K|_zn@$NlScFbYcr=9x9K7HioSn6Q;J^?&z zJHsXSY}iI`%R+^t?anim&kq(GX`0+&EaZoeMRjm{7&F0_T zPil8IZn6jzQxoTu47_!=?}TW@XBM0EVU=^9@A-Mr=|DXflKAWZWRJIzJCIOerurnU zRcBj_>-RrLWKp#oWE;)TIvui+ zubC8UEmPed!LV>Vd{Y+d7`63-_QV5=G#QJ?j3rm77HzuC!=!%=>n8P%3 zppKQneitj=y*_2bg`L8EO5Gb&*=B~1+QjvbZK+p(7X3!Nw+@?_Fy$2gtCr7I3PMGox$&z$rJOg}KVG(~*!+ z#n_PS@BnklVxw7tr$(xUTWlHBJvk+OFWyg6tzW8B-oMSHrP=GKsxre=rc|XSZjYHE zpHRw%kVZIp;MYbI^a!=-Q(-RFJ`v78I(iV9hyoz3s!^It*G( zq`mMLrLE_GBfd8qh%bU%u(0rz6%4H>Mcp{7uw3OD7Frv5-RG`HhIZurwtdIBn(HuZ zuZ!8X!)B9f>Z3`5*7VvJ9(VMHiW-Ht?_w?29Dn(w7OMzQRu136+V%3I2YvFaGGxk} zq%!uYkvH`mY}VxN$SIQh%~C^q%ZmJa&ARfvvu#NCYOTko59TCIsz+7~yb?z%a4;@Z zn>UY>xo2hb2^x0}=SI$vofg{+n__I@j?uizs}#l?@OHhMu$$)$FEP{9b+h8m%ES8-o7nRqRkzWh|>CU=soQjkSR9JMrMZok!V??H0-j<8Tx?}modADAJW z*c*=LZ(=WtrJmTSp?=(KvvjrZ?}ui>0}S4`2P@7x%e!oIy_lXQ)3-3kzg6@>`Dvh) zePN6+`hG_#UAjiK%&vFv@XaKyS9`9Z@?7+~i2e}gdk%Y(PnweZa^kUT84TOINmAEB zM#}x&r!{oi0)Fj`zU6!;P6`i97OD@#k2fthLV2m&X+YmJrLS^wB~HXqT@~T4^_@O zT04DjVgKID{=LynoBeCIhE{Iytk~>cvEDsrscG~iNZp zC;$Kd--3&`8)&0aNswPKkc%HM@Lo7v2vp5k;1O92^v)U(W_-_f%pEAGP~sX<5}cn_ zQl40p%HW%rT$G=inv$8Q;FejGTAp8&U98|6v3sJH3Q%pCr;B5VM0n_#(?U%SJT4a% zG`jlMzYwvS;Q8;rx^EC$*Y4MwGXy41<4|F`eY{R|!{4fR;*HbJMOwEo@M=DtbE%Ih z!|aE^)u_MDGS9YeW1OSLvm;abgUk$GlXrsNj(gZmYP4=O@3x=ObARtDnm{r-UW|ELys& literal 0 HcmV?d00001 diff --git a/admin/style/farbtastic/farbtastic.css b/admin/style/farbtastic/farbtastic.css new file mode 100644 index 0000000..07d953f --- /dev/null +++ b/admin/style/farbtastic/farbtastic.css @@ -0,0 +1,33 @@ +.farbtastic { + position: relative; +} +.farbtastic * { + position: absolute; + cursor: crosshair; +} +.farbtastic, .farbtastic .wheel { + width: 195px; + height: 195px; +} +.farbtastic .color, .farbtastic .overlay { + top: 47px; + left: 47px; + width: 101px; + height: 101px; +} +.farbtastic .wheel { + background: url(wheel.png) no-repeat; + width: 195px; + height: 195px; +} +.farbtastic .overlay { + background: url(mask.png) no-repeat; +} +.farbtastic .marker { + width: 17px; + height: 17px; + margin: -8px 0 0 -8px; + overflow: hidden; + background: url(marker.png) no-repeat; +} + diff --git a/admin/style/farbtastic/marker.png b/admin/style/farbtastic/marker.png new file mode 100644 index 0000000000000000000000000000000000000000..db7da5560eb0ee83f8192aebfdbdd391f94c9dcf GIT binary patch literal 614 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 literal 0 HcmV?d00001 diff --git a/admin/style/footer-bg.png b/admin/style/footer-bg.png new file mode 100644 index 0000000000000000000000000000000000000000..45019be2a61071aa71d145ff9811d1cb11b74a1a GIT binary patch literal 1490 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 r_3{R8_7YjMk9EybP0l+XkKU!zYW literal 0 HcmV?d00001 diff --git a/admin/style/jsToolBar/bt_br.png b/admin/style/jsToolBar/bt_br.png new file mode 100644 index 0000000000000000000000000000000000000000..717ff6cfd854e477355cd699005f991bbc86dac6 GIT binary patch literal 243 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAf3?x51|2hvyF&8^|hH!9j+QJYD@<);T3K0RT6!MF0Q* literal 0 HcmV?d00001 diff --git a/admin/style/jsToolBar/bt_clean.png b/admin/style/jsToolBar/bt_clean.png new file mode 100644 index 0000000000000000000000000000000000000000..3973a2c3066464f889896da9b4c11b74fa5fa70e GIT binary patch literal 576 zcmV-G0>AxxN#00003b3#c}2nYz< z;ZNWI008h%OjJcJAPM^8Xy(XFq>oKnUtH|!-iV2ny1KHddjwE60lc3t|Nq3$!kk`Q zRFi&Kd~#YvI4RVsc(Sjd;Lv}SOa%Y=sg{U&(ZjJLD>ncC|8HPIGcz;X)QZJ{K8A#Z zxTt*k+-z1oAK1*W(YQskV;QQVm9dX$@1)VFg*RKEn*2clH%*>hN&VC^&Lfg)o|M_qn>vRMF000Jb zQchF<|NsC00JFcOzW@LL32;bRa{vGf5&!@T5&_cPe*6Fc02XvbSad^jWnpw_Z*Cw| zX>DZyFflJMI4>|XdUF6G0000WbVXQnQ*UN;cVTj608L?Ia&K*AWNBd_Mrm?ocW-iQ zb0AGvyOAm+0001oNkl#(k<>Gga7Gc7ck)nW)7Fwk7UXgAmD*1?- zn`QK$!8;-MT+OL9r6oh!W?b)Wnj^{5*w_%-mE414DfS z3w;BVs$vEupb7<$is1aTlJdl&R0iL~|zDqh}{#lRDf#3 zJzX3_IA$jA;AZD>F$`_?KIb%pm4}CCPr@@%w!6~O3TIa9l)t~%V!-gTe~DWM4fqSJW3 literal 0 HcmV?d00001 diff --git a/admin/style/jsToolBar/bt_del.png b/admin/style/jsToolBar/bt_del.png new file mode 100644 index 0000000000000000000000000000000000000000..87c3c6604b2e97dc6b8025b08527e592f04a26b1 GIT binary patch literal 351 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc3?z4jzqJQa%*9TgAsieWw;%dH0CJ53d_r7- z^qW`rCQs^$2oKiQ);xFiP+4g{A0O|=^~*dxT+`Ch?%ux8(p+<3-xgUJX)7!9MGI#L z`5w^%YGW!1@(cdY@N~O@7m&wU;1OBOz`!j8!i<;h*8Kqrij}xVlsFfqCYEI8=P86_ z=B6?j80s5X=o^?+6*DLSRVaW|1m~xflqVLYGWaGY7v<-srer26xMdclmgg5`7c2Ni z?4GEl0#uvs>Eak7ae3*5(|m^vcw7SS&r%DP=KBACtB!yubB@4fo341yeJXXwL$$Xg z<~w^&<1ucuvvgy;BlBG3z|jJika{0^!Ow3b-0w}lE|>X~>4h!N>x&gqapDbY|D;a) jvgL8vgkSytYtG76Ph#dy`?zy2&`JhRS3j3^P6%y{W;-5;Q!Scz*yiE~kEVo7Fxo?nB7grmi9 hy1$0%y@>)04F6{cv!Bj>_7rFqgQu&X%Q~loCII%_U2OmW literal 0 HcmV?d00001 diff --git a/admin/style/jsToolBar/bt_img.png b/admin/style/jsToolBar/bt_img.png new file mode 100644 index 0000000000000000000000000000000000000000..b991a527aa2d7cb8274152b4f7db01846e564112 GIT binary patch literal 899 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc3?z4jzqJQa%*9TgAsieWw;%dHU|?Wu2=EDU z1qvVdSX#6mQ1j)k}Go|ts9zhGJJ|NsA&>^Xht?1Ps6`GNHpw_TXp zyXtsMOJLf}w2*{+X$3X=yeFB{c1hUT&pGm6D|&bJ{DYZm_pCkjBz5kl7r#$-uRa%$ zq#ID=;!=GnZRX6`mzEy5xcPcC~X=mR4yb{qDu9vV%G*EQs zgE>yc*NlygHy^xGJ9X36llPk!A9XG}ZRTfm`1Zp$ukK08%1>EycHi-R6BZuHo3K?- zOiD>j!@d1TWMZ*j{hhR#XYzVtHXl3Nz5aUcjKdtf>{^<7ItknF+_|Q5G3E*|4suI^ z{DOf&K{vplyX}fM&|=O4kH}&M25un`X1sK_?hjBAI6tkVJh3R1!8b9vC_gtfB{NaMEwd=KJijQrSiv`9_e3of zpxVoxE{-7*my=H%WRm#6k<}sk;>u#KuHDirZqMAkLy_WZ|FG8TIy}`cuQ)o#aSVtn-7{Uotv|6-n4sKzs|@w798B;v#_XAes@A`Aa~-9 zgjGF0kyGcd(&P|%ZsfqS)8g>zLJiMhPGMBm*Z2R106fG(}YjZTW+eYz2EX7}# zBD!;Vy)SRlo@(s#@ZOhDA5Z?k$CJChnH#!tO}G`{uB*)H{#b`i#qr;a9|nTT6SGvy0fr%dE3Oro{`1hzI|J=V`WI`l8&xc*O0ubwi%nYY@EMxcY0}mU|`^zSNHz^ z|8MS|bmZdtwmJI~>sRM?ZeFzc+`G@GO+2zHCheTM;<&z3(zc_U7H&S=v+!VQ^ZJW- zHa2$6n!EnEZ9rlFvh{!dzWe^`zJ+68boGk8`}SnCtg`UQYn-*iF{I?t>wUGIbEm95 zTGYF(Z}E|%=e9QXE}FIGl&^HdX`pKbN`m}?fwm(9h6l>Al0Z4m0*}aI1_o{+5N5n| zx9$&6P^`o?qQtoGlds7@p!MOd1szt~a)Mk|J!)%W zOTPdAs!OC*%dhx4@yTZtwSAxPFH2kgrCsf9%C(G*W~Va@3h&;&u-ET&MEB-L77_k7 z{v3@4n>A}w=6rT~_(OEA|89#i8TN%XF5kjVrAsJ%S)K4?@$7D`hP_VHYHkZOa38Yq vf9J@M%5nd+TI(%y-VoapG3Im2p47?9Jdji@HB(pubRdJLtDnm{r-UW|&l>1o literal 0 HcmV?d00001 diff --git a/admin/style/jsToolBar/bt_ins.png b/admin/style/jsToolBar/bt_ins.png new file mode 100644 index 0000000000000000000000000000000000000000..f690b90d4f94b31315c4a6f7c8a011d3af305c3d GIT binary patch literal 308 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAd3?%E9GuQzs=3*z$5DpHG+YkL80J#PMJ|V6^ z`pv6*EzLC%;lWl`<_Gp|*|>h$-fqJ=X&JzUe$(qv_%CyJ@g z2I^rd3Gxg6&+v4+ffta+S>O>_%)r1c1j3A$?$-SQ3W}AuMwB=gr6!hS=I1GdWag$a z7#QjsSm+y=R24HQ0aYk~R0QXzm6RtIr84*?CKu)Brlw>jD!649rIzOxWfv>>M(m!b zr2z0KOr60h&AL?HX@;=~>rx>_pNsL9 p&kW2vmL*!bH!!kD6z&#hV`x;9cy(l#s{qg_22WQ%mvv4FO#uJIUXK6( literal 0 HcmV?d00001 diff --git a/admin/style/jsToolBar/bt_link.png b/admin/style/jsToolBar/bt_link.png new file mode 100644 index 0000000000000000000000000000000000000000..07a2b0e5bddac5c7f5cf627f891e50fe64a32fce GIT binary patch literal 833 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc3?z4jzqJQa%*9TgAsieWw;%dHU|?V@4DbnY z6_QbT`uKX$-iYezYH61xN3QR7s5$cO+qcMwkj%AvrcUXxceFk5v2^vSg%{pD=TR&1 znyFmBcJ=n{+tX)kiC)xUS9rjpyh74bw`FeOl{dR)ZoHhoX=2#aHEC&SItkmiU6^WY zY<&CXxj9Gv14Tp>9Rgd=7c4n!8eA~@(o!I>5A|;8pRXIadF`&##%X7!tT{XXO6sAr z51#zEXP@_E(#d`aJNs2T=e~J$uY3LVJ9n~w5wM8l3n?(Ii9 z7M3jAa!M~@)#ig&-u}GeSAXaK|Nr;yT)cPho}sbzi)XjBqId5*zOT8t+0Dma#&;pm z@B<&})~;Q-L1;G39Sl%JcLl9{OBmRXcqo?nz*tl%55d!m*KQ0-Mu7sn8Z@MMGIOcEbB zc1^#f9=(VwZPTgUoYPyQl(~0Rdx-ruT-nL-M3Iv#Y-iPH5BHT_md1xzd4+v18U3(G z?Fm*o`=BXkn~{{8*Q-81t4E#%j(;u8#8B#=bM8pU+L^JdwXvR!d4IZU%!G@M ze)?u7><=5-M2Ai57R=h6x6p5$Sb1BTn}eHA9Z$%GnA_f}4VKNa9L7$Ij1%wigq`5n ze42}gXUpe}fi1sd6`8qOHgIhE?V`+*`q@;`VH&gI3`xQBjBFqGa5ye75Yc${fTNP( Y-@aIjLe{0hKo2r_y85}Sb4q9e04Ly+QK$!8;-MT+OL9r6oh!W?b)Wnj^ z{5*w_%-mE414DfS3w;BVs$vEupb7<$is1aTlJdl&R0iL~|zDqh}{#lRDf#rJY5_^IHHq({Qu9)%u~<)=()nKg$!rd9v*iv^Z92e@Sp8dz4Oz1 g%s2TbeqlCbsGMc`zR~Z`I-pJlPgg&ebxsLQ0DVDCO#lD@ literal 0 HcmV?d00001 diff --git a/admin/style/jsToolBar/bt_paragraph.png b/admin/style/jsToolBar/bt_paragraph.png new file mode 100644 index 0000000000000000000000000000000000000000..5de086ecf20245f05569becf2def4153790d6828 GIT binary patch literal 295 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAd3?%E9GuQzs=3*z$5DpHG+YkL80J$mwJ|V6^ z`sw5AWu^I>H?A-?Hdawl3JmnUee;}v0RQo$yAuKD>8!cHX*u%e{N|{{R1f=FFMZ zs}`1)mfpK_ap}^fFP`1@^Yx632Dzu^B2Pq!O*0ePGS9+AZi4BSE>%y{W;-5&-97QqtN zh>{3jAFJg2T)o7U{G?R9irfMQ8~cia#N_PM5{0DH^vpb4B?ScqC56lsTcvPQUjyF) z=hTc$kE){7;3~h6MhJ1(0FE1>4w)RIJnirk#MVyg;UC9s)RKsHENUr7P1 zq$Jx`$q{6kLWFOCf^&XRs)C80p>DE)v5A6-nVylkk)^qrjzVx^iGo*Ro`R9Nf{}p% zkT9|`G_*1?1Ud!`l`9GBGM0zyk)Oennz|zM-ChKHOxWMjN1@m2**QVo82cNPd2f9mM-?nMJAP`9;~q z3eLgCHXxlSiV(IU^ryNcmZaK&!b2B`jLbp|jjc>9txV0Mkn}?op=tNcPsvQHglV_X zH89aNG7T{_wK6cbGPQ(iM^XgUZlezh2&8}khdRhlXySwdEF~EpUInE^IpAnXN!Cxz zNzF~oD=7wsnIUSJr6gOW!ks3@Lky**B{}~E>VYMO7^rXnCt6T;2+7P%WiT+*H?Yt*FsUkLPy(uu0jUVi zPb(=;EJ|g-lBQ=|a|4x&Gd*1#LnOj;&%YLGQV?iMoYtxtxb2FKidyg8|F+8(am(JD zf4*ij57R%D177EhydI@AWxW^v%e}K{x`e-i{=_qJM^ZBn{pQR&9m%u*wDD6T*WG&2 zQcJf#tJa)z`JAnJh;*9e)hmIWPd}Ec+)Z6_LLhcl-9gh3<+*#ldLK^qDp;SO^TEN? ugq`WdPQI6BNu}kvFQfz)tarN1d+%Kx@2c3)+24SUWbkzLb6Mw<&;$U$sl*Zh literal 0 HcmV?d00001 diff --git a/admin/style/jsToolBar/bt_pre.png b/admin/style/jsToolBar/bt_pre.png new file mode 100644 index 0000000000000000000000000000000000000000..b765759a6b9d242d0013d9e4a6579961300a42bd GIT binary patch literal 244 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAj3?#R^_xk}U=3*z$5DpHG+YkL80J&@dJ|V6^ z`pv6*2U1J+0a;8XL4Lvi8J=!8@B;EU3p^r=85p>QK$!8;-MT+OL9r6oh!W?b)Wnj^ z{5*w_%-mE414DfS3w;BVs$vEupb7<$is1aTlJdl&R0iL~|zDqh}{#lRDfzVJzX3_IHHq({Qu9)tXEUv%Xs+iO=*dD?+g-l?3O-pKlwm`yhfe; bb~%Pb3Da%wR@r?7YGUwo^>bP0l+XkK?Hx*6 literal 0 HcmV?d00001 diff --git a/admin/style/jsToolBar/bt_quote.png b/admin/style/jsToolBar/bt_quote.png new file mode 100644 index 0000000000000000000000000000000000000000..6cd98e118f5a14a707a636ec105a843149ba8aa3 GIT binary patch literal 322 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAd3?%E9GuQzs=3*z$5DpHG+YkL80J-V`J|V6^ z`sw5AGiS~W4D>yIbhnC%QdehFS!w>}jVo^7JZEfdoR|>(=G8p`@BNuTrMx9Ue!>5d z0E6udr8b}hXMsm#F#`j)5C}6~x?A@LC@5Cq8d2h0l$uzQnV+W+l9`*zU|^_kV4-hd zQdP{L1XQ5_QW2b=R#Ki=l*-_nm|T>fo0^iDsNj}alvbz##9pI7yO^$>2?DzAdj=aBeIx*fm;ZK886+f`vVjdD{+k|aV|5mEPyne2&QB{TPb^Ah@J&oE%Fj(r$xKvm%PdMQ&o9a@R`8A3 zJyA;qs5ZjW#W6(U^4bZz#TpcNobxlEDk}W@f8AQK$!8;-MT+OL9r6oh!W?b)Wnj^ z{5*w_%-mE414DfS3w;BVs$vEupb7<$is1aTlJdl&R0iL~|zDqh}{#lRDfz#JY5_^IHHq({Qu9)Z1j)k2){I!gq+jO|BX2!l`CW- p:first-child { + margin-top: 0; +} \ No newline at end of file diff --git a/admin/style/jsToolBar/resize.png b/admin/style/jsToolBar/resize.png new file mode 100644 index 0000000000000000000000000000000000000000..1b212709db2a3bf3158b90a32a15aed916f10d27 GIT binary patch literal 1267 zcmcIk&ubGw6y6w-7%8X+527%v2QTiOqC=I%|WFH3tpT8g#9qEiRU`Moa+gGEPzK_PmJ1C2_<_V4S$Ih(;m2 zTN0O&WN5p-fhvB;kS?o|rQ~#^&&ygtD;DN&p(f?%F7=RBK$@aJrx8^px(bUKHL;up zYlL>2Y*tq%Ibl{3cR3FT#{GU@?&oAb>|nK6EMi5&nkGSn6zzMQ#*!D^7?T|GR9R$& zPQV@CLkTZ!`Fp%1ib_({4%oz#tSkNr%49}{RvvQ(`1dldvsyU(;Nxtyl2!0%N0$%rRr@em&Uyu}C z((_eGmyEL|jWEntq%2X~=}X)b!I&tI36Ru~uC&GuN%3!$+wz azZZe}S^Djp7tdeAH=(xDsJ>i&`1lV+B|r@T literal 0 HcmV?d00001 diff --git a/admin/style/magnifier.png b/admin/style/magnifier.png new file mode 100644 index 0000000000000000000000000000000000000000..1578a8d114883a5e0fc8a9f47636f9f4a9c2eaa0 GIT binary patch literal 499 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 OhM#~I&wK(i`}3bHw&zm- literal 0 HcmV?d00001 diff --git a/admin/style/modal/modal.css b/admin/style/modal/modal.css new file mode 100644 index 0000000..8524e7c --- /dev/null +++ b/admin/style/modal/modal.css @@ -0,0 +1,52 @@ +div.jq-modal { + line-height: 1; + background: #fff; +} +div.jq-modal-container { + padding: 1px; + position: relative; +} +div.jq-modal-content { + position: relative; + overflow: auto; +} +div.jq-modal-closer { + position: absolute; + top: -12px; + right: -12px; + width: 25px; + height: 25px; +} +div.jq-modal-closer a { + display: block; + text-indent: -5000px; + width: 25px; + height: 25px; + outline: none; + border: none; +} + +/* modalImage */ +div.jq-modal-content img { + display: block; +} +span.jq-modal-legend { + display: block; + padding: 3px 0; +} +a.jq-modal-next, a.jq-modal-prev { + display: block; + position: absolute; + top: 0; + width: 50%; + bottom: 0; + outline: none; + border: none; + text-indent: -5000px; +} +a.jq-modal-next { + right: 0; +} +a.jq-modal-prev { + left: 0; +} \ No newline at end of file diff --git a/admin/style/msg-error.png b/admin/style/msg-error.png new file mode 100644 index 0000000000000000000000000000000000000000..eb6cedb529482d44de8b192e1b0867003e8aa7a4 GIT binary patch literal 617 zcmeAS@N?(olHy`uVBq!ia0vp^5M1+QhdU$v^IXN9Xc<{`bGe?geg)sjA{`UR* zcc5M%Hp7<{C~Rl|D&z{@2>iPd&&Rnv;SY6{{K?{ z{|jCJ&$awNUGx7~!T%%K{|}}9-=FY*Z`A+YA^*3!|KIHRf4#;3wTAy!Y5iZO@PD!7 z{{=$-=W_p_$>968hZE=^k&+<4Ugjjc zYhQd{#P(9S(*C-fli4X|Q)Mn2dhXj-HtD0uu&17hLF}kB tLxZoBukPQ!nV z+W$&b{}qe>OO*TI{`$F}vQ|9kemGyQM#`u^42$xo&|=C1$$c5z>2 z+9HE*RuQ+9?6Y<+Jn>G0X~khVubLEBM?ZWH-OOM6;`HLxLHF&$cgU?<_F>*<>y>k^FREYv^B7y+^Pd}^ z{@Am#ZtttDyINQLjksNV$M)RwRmZn(Q8;O4)|vNt&fT+YyVA4H$bGI_dkyLtfu?1Q d3?2+0b3v#)ykAR>AgeBlQsSJ;@P%U?Z!y{;FbUL&Hv=3|L(y5>$~Q) zJ><7-<+4TX+`jS8h~2$)>$W@X#e@07Naf6w;;J~-tyb&4Pu8Yi^W?n$=&J15r1#c} z;>LOR?%dk4WBTH%`}XbX!$t4PiR{aS{_n>B;+_55jsE!J(xO<`uul5qu=VTD_0WIW zwNL%}=jY6b;KqK`sz(0Sc=PAg?Afu`t!v1RGsuoW{Q2JNw*()uvJ2pEB~@ulDWI_vEtr?9S`WkKw>_|J8Tz-^KpfeC5ia z>)5UP+miLrc+Q+Z`10ZK;lkFqaNM_e^}Rsn(vj!TnC;S%;io|A)tuhHW!<@H`SRz` zms8oUQ2+k$&@iKga7Zy>9kDSu~zlTY2d(p_}iW5xhG!C^gSA-hojv03%5WT%Ca^kKq|3SXMJUbNPsT>jJ1O&~Ju9FhvcEd>wJK+L(|_#gMMsm=nTV#y|9{5j zq2Y3cNnI-_8Ph-ZbNyEa)g5@ts}beHo*lj5)+PX?eOu#d{?-|y2hU+i?9q$1zMd|$ etc1!AtNsBz!zPZaM$`BJ0000jR6MEPMV|@f~hCny}Rf4eed1(PJX(vzA}@&mIVOJ z)K;sT!XAj3otPBs!!I{q2{Rcj)~rk>^X}8#kK#DJv1ToO`}*O<^JlLYets983&HBW z2!M-Mk~#6_{o~)ld7Uq9^9F129tkN}a9ESVWjCZf7Iq?7Y2**zE+qeSmKctQQb<5uG*oGs`m$PP!1=ypUz}V~h5sphz%8A83aU%()A-q$P`c-e& zH(-T@6c%JPXDj&vEX>MUQ8S9Ow_t;Cc!&5UOgUgX%n8=R?;t3g1Oai3J3K}vCpedXX6i}J92>V-=n-CaJ<_Hq@Y^ODIsaK-ziRO; z#Ir=hcX?d;u$5=B8R>o|^nKE^OfvQ3a8CR_F4d|FR_1~2+&+Kqpt6zy_%nE^A9bh2 OH&9zzuO2Nvdh!Q!$2|=I literal 0 HcmV?d00001 diff --git a/admin/style/tab-bg.png b/admin/style/tab-bg.png new file mode 100644 index 0000000000000000000000000000000000000000..4c466bee93bae53d93b44993236183168ad9dfac GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^Aa(#FGmw;eS(Xo^n2Vh}LpV4%Za?&Y0OYa-_=LFr z|NlQNEv@fe&H|taXMsm#F#`j)5C}6~x?A@LC@5Cq8d2h0l$uzQnV+W+l9`*zU}T_g zV5VSNwKgH_^2xL>4nJa0`JjnbOkI($LUQ zUtgb*k&&LB?w6#u4QK*eNswPK(1id088+`O>_%)r1c1j3A$?$-SQ3W}Au zMwB=gr6!hS=I1GdWag$a7#ZjrnCTmsKmV?k1XLjdQW2b=R#Ki=l*-_klAn~S;FejG zTAp8&U98|7Y&_$d8^|Mdo-U3d6}R4AI4;;=z{9XXCSjN6Z~fEu>1Gq$0;*p=6%*`@ zdlRmgq;+{_lGo$CUK+A57ns=dc{R_FPdd^esO;7wVF+S0LnsJe04}WT#)GWP5vm#@ czarW0b-38>Il9vp0$sx3>FVdQ&MBb@0B@?1iU0rr literal 0 HcmV?d00001 diff --git a/admin/style/tab-l-l.png b/admin/style/tab-l-l.png new file mode 100644 index 0000000000000000000000000000000000000000..376052043c73679426999bec4dcc3d123dc047d6 GIT binary patch literal 428 zcmaKo+be@{7{`BFYM7FXg_ccR30oAGj16yT*ml8<-m#Z0F>P;Aa@e?_TsRafQtsSv zqg>GzMMF8|e4N9aw+l*2zpvl^0pI#Q-=3#WPfyQqjiDkjJ}sUQlE_u+j4WfBwNeSI zd0n#$EF`W{&McKmFM`##tnIC-GV4LZpb^kF;0m|~Zh%`L2zm#45BdQ52pR%?0(}O3 z0euC12mJt!ffL{qI0Mds3*Zts`ucqQ`g{n7!=X@UE8yGQSoQl?e7+U0cVckRJuu+* zc=~#Jx@}RlMDj1E*d^(r(O|-VBJU}R21dqpRMxu)Nl1=5=HROLmks5jzD_K23Kr4s zXjhr-Z34;Hs5OOZP0`bLb|WJcQNrYC7CS9YfoQFcMnP3>cM6>jXRAw9W-9O=mq#B} z%jvY{l*6Vmf#-#03vX?rfi*vkY!}Go8{INl&Q38T+@w-gG9H{x8nW^wqZm6?rtS$p s9rM4t{kw{+!p!~bRNI_!ByV|X{fuPHqzi>18h4-VAh*#H0l literal 0 HcmV?d00001 diff --git a/admin/style/tab-l-r.png b/admin/style/tab-l-r.png new file mode 100644 index 0000000000000000000000000000000000000000..ef538e6e59f0c30677feaa0b09842c98aac64aa8 GIT binary patch literal 551 zcmeAS@N?(olHy`uVBq!ia0y~yV3Yu|9XXhRr0p_qQy|4$?Bp53!NGC+q5lIQw>Q8i z#P$EbcmMx=`2X+y|9@})|G)YF|E>T3Z~y;)=l}n^|Nr0n|Ns8~{}2BEfB663qyPUN z|Nr;o|G%gI|2_Nv@A?0KFaG~~`TyUm|Nmb9|M%wq|7-vMU;qFA#{d6U|NeRR``4?l zU!HyZ@c11NynXQU#jR)0o*g)_XaD{^d-iPEv19#|Dg7-ijSUTT^>sBF85!y6=|JL3 z@Y*>*hbfi>`33(c02t;Uyr2kF%vs}5F15y#3pH@nD!553ci}NSBH-L(;MXak+$NEUU;4w`>=N>_49>YTx zs!3q67DKp>`Z6zf-j0tygh29terf)k;CIHonpu0Nl9jd1VNIYf7(8A5T-G@yGywov CuOPVq literal 0 HcmV?d00001 diff --git a/admin/style/tab-n-l.png b/admin/style/tab-n-l.png new file mode 100644 index 0000000000000000000000000000000000000000..2d9a8bff7d306117cbad6766c4ed248e2f358f8b GIT binary patch literal 411 zcmeAS@N?(olHy`uVBq!ia0vp^tU&C@!3-qzD(0;PQq09po*^6@9Je3(KLB#81AIbU z-@SYH>iL6L&+or_@$l8NJFlMKd-V*6?!J0@`_cQCucdtLVcVqYNoqKj~ z+qHAY&K+AOPV8@JsBfsRtE;Q6s;bP$NY6-5|HA!z8_*eyB|(0{3=Yq3qyagc1s;*b z3=G^tAk28_ZrvZCpje4(M2T}zYGO%dex5=|W^O8jk%7K}nZAMf^Y2sPQuNX%e=c0yB>8&fqqp_3?$4(4&sZ;D`FuOeC7@jlp00i_>zopr0A@?W A8~^|S literal 0 HcmV?d00001 diff --git a/admin/style/tab-n-r.png b/admin/style/tab-n-r.png new file mode 100644 index 0000000000000000000000000000000000000000..420bf7fcf53877b1ad840b11195f95036eb628c2 GIT binary patch literal 524 zcmeAS@N?(olHy`uVBq!ia0y~yV3Yu|9XXhRr0p_qQy|4$?Bp53!NGC+q5lIQw=2LW z#P!{~cdwp5c=h7ZtLOJ$y?FTQ`Mp=q?!J0<=hd@&ub$p{_4L-$r%zuzd+_S%?N?83 zJb!Zc)svgAo?L(R`0A_2*Iqro{_4?{SC1~gdUWa4Lm;~F>fyy#56-=MaN*U1^RFJ9 zeR%)oy*t-#-@J1D%DLUUckbG?bL09oYuBvk>+No6sIRT5uCA`iNC$z8jP%*<(`Nx) z#aI&L7tG-B>_!@p!&%@FS}5F15y#3pH@HJ6Og3>>?b*fC*Eih%^x*y1 zPoE?|zc~JV`)_d-`9FW2Z+@~k{=N8m$$R>f9-2>j$e-q9}|9f6#F zof$9HX4af)N}1#nw^?DP%H;W*K;(8E54Dp|fC_>5edGk6NhhntR3@i7+6@ p0{ehe+5!cPx#hqrqai8})gQm~blog->getPosts($params); + + if ($post->isEmpty()) { + $core->error->add(__('This entry does not exist or is not published')); + $can_view_page = false; + } else { + $TB = new dcTrackback($core); + $tb_excerpt = $post->post_excerpt_xhtml.' '.$post->post_content_xhtml; + $post_title = $post->post_title; + $post_url = $post->getURL(); + } +} +else +{ + $core->error->add(__('This entry does not exist.')); + $can_view_page = false; +} + +# Change excerpt +if (!empty($_POST['tb_excerpt'])) { + $tb_excerpt = $_POST['tb_excerpt']; +} + +# Sanitize excerpt +$tb_excerpt = html::clean($tb_excerpt); +$tb_excerpt = html::decodeEntities($tb_excerpt); +$tb_excerpt = text::cutString(html::escapeHTML($tb_excerpt),255); +$tb_excerpt = preg_replace('/\s+/ms',' ',$tb_excerpt); + +# Send pings +if ($post && !$post->isEmpty() && !empty($_POST['tb_urls'])) +{ + $tb_urls = $_POST['tb_urls']; + $tb_urls = str_replace("\r",'',$tb_urls); + + $post_title = html::escapeHTML(trim(html::clean($post_title))); + + foreach (explode("\n",$tb_urls) as $tb_url) + { + try { + $TB->ping($tb_url,$id,$post_title,$tb_excerpt,$post_url); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } + } + + if (!$core->error->flag()) { + http::redirect('trackbacks.php?id='.$id.'&sent=1'); + } +} + +$page_title = __('Ping blogs'); + +/* DISPLAY +-------------------------------------------------------- */ +dcPage::open($page_title,dcPage::jsLoad('js/_trackbacks.js')); + +# Exit if we cannot view page +if (!$can_view_page) { + dcPage::close(); + exit; +} + +if (!empty($_GET['sent'])) { + echo '

    '.__('All pings sent.').'

    '; +} + +echo '

    '.html::escapeHTML($core->blog->name).' › '.$page_title.'

    '; + +echo '

    « '. + sprintf(__('Back to "%s"'),html::escapeHTML($post->post_title)).'

    '; + +echo +'

    '. +html::escapeHTML($post->post_title).'

    '. +'
    '. +($post->post_excerpt_xhtml ? $post->post_excerpt_xhtml.'
    ' : ''). +$post->post_content_xhtml. +'
    '; + +if (!empty($_GET['auto'])) { + flush(); + $tb_urls = implode("\n",$TB->discover($post->post_excerpt_xhtml.' '.$post->post_content_xhtml)); +} else { + $auto_link = ''. + __('Auto discover ping URLs').''; +} + +echo +'

    '.__('Ping blogs').'

    '. +'
    '. +'

    '. + +'

    '. + +'

    '.form::hidden('id',$id). +$core->formNonce(). +'  '. +$auto_link.'

    '. +'
    '; + +$pings = $TB->getPostPings($id); + +if (!$pings->isEmpty()) +{ + echo '

    '.__('Previously sent pings').'

    '; + + echo '
      '; + while ($pings->fetch()) { + echo + '
    • '.dt::dt2str(__('%Y-%m-%d %H:%M'),$pings->ping_dt).' - '. + $pings->ping_url.'
    • '; + } + echo '
    '; +} + +dcPage::close(); +?> \ No newline at end of file diff --git a/admin/update.php b/admin/update.php new file mode 100644 index 0000000..1495fc3 --- /dev/null +++ b/admin/update.php @@ -0,0 +1,212 @@ +Access denied'; + dcPage::close(); + exit; +} + +$updater = new dcUpdate(DC_UPDATE_URL,'dotclear',DC_UPDATE_VERSION,DC_TPL_CACHE.'/versions'); +$new_v = $updater->check(DC_VERSION); +$zip_file = $new_v ? DC_ROOT.'/'.basename($updater->getFileURL()) : ''; + +# Hide "update me" message +if (!empty($_GET['hide_msg'])) { + $updater->setNotify(false); + http::redirect('index.php'); +} + +$p_url = 'update.php'; + +$step = isset($_GET['step']) ? $_GET['step'] : ''; +$step = in_array($step,array('check','download','backup','unzip')) ? $step : ''; + +$archives = array(); +foreach (files::scanDir(DC_ROOT) as $v) { + if (preg_match('/backup-([0-9A-Za-z\.-]+).zip/',$v)) { + $archives[] = $v; + } +} + +# Revert or delete backup file +if (!empty($_POST['backup_file']) && in_array($_POST['backup_file'],$archives)) +{ + $b_file = $_POST['backup_file']; + + try + { + if (!empty($_POST['b_del'])) + { + if (!@unlink(DC_ROOT.'/'.$b_file)) { + throw new Exception(sprintf(__('Unable to delete file %s'),html::escapeHTML($b_file))); + } + http::redirect($p_url); + } + + if (!empty($_POST['b_revert'])) + { + $zip = new fileUnzip(DC_ROOT.'/'.$b_file); + $zip->unzipAll(DC_ROOT.'/'); + @unlink(DC_ROOT.'/'.$b_file); + http::redirect($p_url); + } + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} + +# Upgrade process +if ($new_v && $step) +{ + try + { + $updater->setForcedFiles('inc/digests'); + + switch ($step) + { + case 'check': + $updater->checkIntegrity(DC_ROOT.'/inc/digests',DC_ROOT); + http::redirect($p_url.'?step=download'); + break; + case 'download': + $updater->download($zip_file); + if (!$updater->checkDownload($zip_file)) { + throw new Exception( + sprintf(__('Downloaded Dotclear archive seems to be corrupted. '. + 'Try download it again.'),'href="'.$p_url.'?step=download"') + ); + } + http::redirect($p_url.'?step=backup'); + break; + case 'backup': + $updater->backup( + $zip_file, 'dotclear/inc/digests', + DC_ROOT, DC_ROOT.'/inc/digests', + DC_ROOT.'/backup-'.DC_VERSION.'.zip' + ); + http::redirect($p_url.'?step=unzip'); + break; + case 'unzip': + $updater->performUpgrade( + $zip_file, 'dotclear/inc/digests', 'dotclear', + DC_ROOT, DC_ROOT.'/inc/digests' + ); + break; + } + } + catch (Exception $e) + { + $msg = $e->getMessage(); + if ($e->getCode() == dcUpdate::ERR_FILES_CHANGED) + { + $msg = + __('The following files of your Dotclear installation '. + 'have been modified so we won\'t try to update your installation. '. + 'Please try to update manually.'); + } + elseif ($e->getCode() == dcUpdate::ERR_FILES_UNREADABLE) + { + $msg = + sprintf(__('The following files of your Dotclear installation are not readable. '. + 'Please fix this or try to make a backup file named %s manually.'), + 'backup-'.DC_VERSION.'.zip'); + } + elseif ($e->getCode() == dcUpdate::ERR_FILES_UNWRITALBE) + { + $msg = + __('The following files of your Dotclear installation cannot be written. '. + 'Please fix this or try to update manually.'); + } + + if (isset($e->bad_files)) { + $msg .= + '
    • '. + implode('
    • ',$e->bad_files). + '
    '; + } + + $core->error->add($msg); + } +} + +/* DISPLAY Main page +-------------------------------------------------------- */ +dcPage::open(__('Dotclear update')); + +if (!$core->error->flag()) { + echo '

    '.__('Dotclear update').'

    '; +} + +if (!$step) +{ + if (empty($new_v)) + { + echo '

    '.__('No newer Dotclear version available.').'

    '; + } + else + { + echo + '

    '.sprintf(__('Dotclear %s is available.'),$new_v).'

    '. + + '

    '.__('To upgrade your Dotclear installation simply click on the following button. '. + 'A backup file of your current installation will be created in your root directory.').'

    '. + '
    '. + '

    '. + '

    '. + '
    '; + } + + if (!empty($archives)) + { + echo + '

    '.__('Update backup files').'

    '. + '

    '.__('The following files are backups of previously updates. '. + 'You can revert your previous installation or delete theses files.').'

    '; + + echo '
    '; + + foreach ($archives as $v) { + echo + '

    '; + } + + echo + '

    '.__('Please note that reverting your Dotclear version may have some '. + 'unwanted side-effects. Consider reverting only if you experience strong issues with this new version.').' '. + sprintf(__('You should not revert to version prior to last one (%s).'),end($archives)). + '

    '. + '

    '. + ''. + $core->formNonce().'

    '. + '
    '; + } +} +elseif ($step == 'unzip' && !$core->error->flag()) +{ + echo + '

    '. + __("Congratulations, you're one click away from the end of the update."). + ' '.__('Finish the update.').''. + '

    '; +} + +dcPage::close(); +?> \ No newline at end of file diff --git a/admin/user.php b/admin/user.php new file mode 100644 index 0000000..5e38136 --- /dev/null +++ b/admin/user.php @@ -0,0 +1,301 @@ +auth->getInfo('user_lang'); +$user_tz = $core->auth->getInfo('user_tz'); +$user_post_status = ''; + +$user_options = $core->userDefaults(); + +foreach ($core->getFormaters() as $v) { + $formaters_combo[$v] = $v; +} + +foreach ($core->blog->getAllPostStatus() as $k => $v) { + $status_combo[$v] = $k; +} + +# Language codes +$langs = l10n::getISOcodes(1,1); +foreach ($langs as $k => $v) { + $lang_avail = $v == 'en' || is_dir(DC_L10N_ROOT.'/'.$v); + $lang_combo[] = new formSelectOption($k,$v,$lang_avail ? 'avail10n' : ''); +} + +# Get user if we have an ID +if (!empty($_REQUEST['id'])) +{ + try { + $rs = $core->getUser($_REQUEST['id']); + + $user_id = $rs->user_id; + $user_super = $rs->user_super; + $user_pwd = $rs->user_pwd; + $user_name = $rs->user_name; + $user_firstname = $rs->user_firstname; + $user_displayname = $rs->user_displayname; + $user_email = $rs->user_email; + $user_url = $rs->user_url; + $user_lang = $rs->user_lang; + $user_tz = $rs->user_tz; + $user_post_status = $rs->user_post_status; + + $user_options = array_merge($user_options,$rs->options()); + + $page_title = $user_id; + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} + +# Add or update user +if (isset($_POST['user_name'])) +{ + try + { + if (empty($_POST['your_pwd']) || !$core->auth->checkPassword(crypt::hmac(DC_MASTER_KEY,$_POST['your_pwd']))) { + throw new Exception(__('Password verification failed')); + } + + $cur = $core->con->openCursor($core->prefix.'user'); + + $cur->user_id = $_POST['user_id']; + $cur->user_super = $user_super = !empty($_POST['user_super']) ? 1 : 0; + $cur->user_name = $user_name = $_POST['user_name']; + $cur->user_firstname = $user_firstname = $_POST['user_firstname']; + $cur->user_displayname = $user_displayname = $_POST['user_displayname']; + $cur->user_email = $user_email = $_POST['user_email']; + $cur->user_url = $user_url = $_POST['user_url']; + $cur->user_lang = $user_lang = $_POST['user_lang']; + $cur->user_tz = $user_tz = $_POST['user_tz']; + $cur->user_post_status = $user_post_status = $_POST['user_post_status']; + + if (!empty($_POST['new_pwd'])) { + if ($_POST['new_pwd'] != $_POST['new_pwd_c']) { + throw new Exception(__("Passwords don't match")); + } else { + $cur->user_pwd = $_POST['new_pwd']; + } + } + + $user_options['post_format'] = $_POST['user_post_format']; + $user_options['edit_size'] = (integer) $_POST['user_edit_size']; + + if ($user_options['edit_size'] < 1) { + $user_options['edit_size'] = 10; + } + + $cur->user_options = new ArrayObject($user_options); + + # Udate user + if ($user_id) + { + # --BEHAVIOR-- adminBeforeUserUpdate + $core->callBehavior('adminBeforeUserUpdate',$cur,$user_id); + + $new_id = $core->updUser($user_id,$cur); + + # --BEHAVIOR-- adminAfterUserUpdate + $core->callBehavior('adminAfterUserUpdate',$cur,$new_id); + + if ($user_id == $core->auth->userID() && + $user_id != $new_id) { + $core->session->destroy(); + } + + http::redirect('user.php?id='.$new_id.'&upd=1'); + } + # Add user + else + { + if ($core->getUsers(array('user_id' => $cur->user_id),true)->f(0) > 0) { + throw new Exception(sprintf(__('User "%s" already exists.'),html::escapeHTML($cur->user_id))); + } + + # --BEHAVIOR-- adminBeforeUserCreate + $core->callBehavior('adminBeforeUserCreate',$cur); + + $new_id = $core->addUser($cur); + + # --BEHAVIOR-- adminAfterUserCreate + $core->callBehavior('adminAfterUserCreate',$cur,$new_id); + + http::redirect('user.php?id='.$new_id.'&add=1'); + } + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} + + +/* DISPLAY +-------------------------------------------------------- */ +dcPage::open($page_title, + dcPage::jsConfirmClose('user-form'). + + # --BEHAVIOR-- adminUserHeaders + $core->callBehavior('adminUserHeaders') +); + +if (!empty($_GET['upd'])) { + echo '

    '.__('User has been successfully updated.').'

    '; +} + +if (!empty($_GET['add'])) { + echo '

    '.__('User has been successfully created.').'

    '; +} + +echo '

    '.__('Users').' › '.$page_title.'

    '; + +if ($user_id == $core->auth->userID()) { + echo + '

    '.__('Warning:').' '. + __('If you change your username, you will have to log in again.').'

    '; +} + +echo +'
    '. +'
    '.__('User information').''. +'
    '. +'
    '. +'

    '. +'

    '.__('At least 2 characters using letters, numbers or symbols.').'

    '. + +'

    '. + +'

    '. + +'

    '. + +'

    '. + +'

    '. + +'

    '. +'
    '. + +'
    '. +'

    '. +'

    '. + +'

    '. + +'

    '. + +'

    '. + +'

    '. + +'

    '. +'
    '. +'
    '. +'
    '; + +# --BEHAVIOR-- adminUserForm +$core->callBehavior('adminUserForm',isset($rs) ? $rs : null); + +echo +'
    '. +'

    '. +'
    '. +'

    '. +($user_id != '' ? form::hidden('id',$user_id) : ''). +$core->formNonce(). +'

    '. + +'
    '; + +if ($user_id) +{ + echo '
    '.__('Permissions').''; + + $permissions = $core->getUserPermissions($user_id); + $perm_types = $core->auth->getPermissionsTypes(); + + if (count($permissions) == 0) + { + echo '

    '.__('No permissions.').'

    '; + } + else + { + foreach ($permissions as $k => $v) + { + if (count($v['p']) > 0) + { + echo '

    '. + html::escapeHTML($v['name']).' ('.html::escapeHTML($k).') - '. + '' + .__('change permissions').'

    '; + + echo '
      '; + foreach ($v['p'] as $p => $V) { + if (isset($perm_types[$p])) { + echo '
    • '.__($perm_types[$p]).'
    • '; + } + } + echo '
    '; + } + } + } + + echo + '

    '. + __('Add new permissions').'

    '. + '
    '; +} + +dcPage::close(); +?> \ No newline at end of file diff --git a/admin/users.php b/admin/users.php new file mode 100644 index 0000000..195cabd --- /dev/null +++ b/admin/users.php @@ -0,0 +1,167 @@ +callBehavior('adminBeforeUserDelete',$u); + + $core->delUser($u); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } + } + + if (!$core->error->flag()) { + http::redirect('users.php?del=1'); + } +} + + +# Creating filter combo boxes +$sortby_combo = array( +__('Username') => 'U.user_id', +__('Last Name') => 'user_name', +__('First Name') => 'user_firstname', +__('Display name') => 'user_displayname', +__('Number of entries') => 'nb_post' +); + +$order_combo = array( +__('Descending') => 'desc', +__('Ascending') => 'asc' +); + + +# Get users +$page = !empty($_GET['page']) ? $_GET['page'] : 1; +$nb_per_page = 30; + +if (!empty($_GET['nb']) && (integer) $_GET['nb'] > 0) { + $nb_per_page = $_GET['nb']; +} + +$q = !empty($_GET['q']) ? $_GET['q'] : ''; +$sortby = !empty($_GET['sortby']) ? $_GET['sortby'] : 'user_id'; +$order = !empty($_GET['order']) ? $_GET['order'] : 'asc'; + +$params['limit'] = array((($page-1)*$nb_per_page),$nb_per_page); + +$show_filters = false; + +# - Search filter +if ($q) { + $params['q'] = $q; + $show_filters = true; +} + +# - Sortby and order filter +if ($sortby !== '' && in_array($sortby,$sortby_combo)) { + if ($order !== '' && in_array($order,$order_combo)) { + $params['order'] = $sortby.' '.$order; + $show_filters = true; + } +} + +try { + $rs = $core->getUsers($params); + $counter = $core->getUsers($params,1); + $user_list = new adminUserList($core,$rs,$counter->f(0)); +} catch (Exception $e) { + $core->error->add($e->getMessage()); +} + + +/* DISPLAY +-------------------------------------------------------- */ +$starting_script = dcPage::jsLoad('js/_users.js'); +if (!$show_filters) { + $starting_script .= dcPage::jsLoad('js/filter-controls.js'); +} + +dcPage::open(__('users'),$starting_script); + +if (!$core->error->flag()) +{ + if (!empty($_GET['del'])) { + echo '

    '.__('User has been successfully removed.').'

    '; + } + + echo '

    '.__('Users').'

    '; + + echo '

    '.__('Create a new user').'

    '; + + if (!$show_filters) { + echo '

    '.__('Filters').'

    '; + } + + echo + '
    '. + '
    '.__('Filters').''. + + '
    '. + '

    '. + '

    '. + '
    '. + + '
    '. + '

    '. + '

    '. + '

    '. + '
    '. + + '
    '. //Opera sucks + '
    '. + '
    '; + + # Show users + $user_list->display($page,$nb_per_page, + '
    '. + + '%s'. + + '
    '. + '

    '. + + '

    '. + ''. + '

    '. + '
    '. + '
    ' + ); +} + +dcPage::close(); +?> \ No newline at end of file diff --git a/admin/xmlrpc.php b/admin/xmlrpc.php new file mode 100644 index 0000000..39b3e0c --- /dev/null +++ b/admin/xmlrpc.php @@ -0,0 +1,35 @@ +plugins->loadModules(DC_PLUGINS_ROOT); + +# Start XML-RPC server +$server = new dcXmlRpc($core,$blog_id); +$server->serve(); +?> \ No newline at end of file diff --git a/cache/.htaccess b/cache/.htaccess new file mode 100644 index 0000000..14249c5 --- /dev/null +++ b/cache/.htaccess @@ -0,0 +1 @@ +Deny from all \ No newline at end of file diff --git a/cache/cbfeed/6a/4f/6a4f55e24111799aaa8e45c1cc4d4583.php b/cache/cbfeed/6a/4f/6a4f55e24111799aaa8e45c1cc4d4583.php new file mode 100644 index 0000000..2830353 --- /dev/null +++ b/cache/cbfeed/6a/4f/6a4f55e24111799aaa8e45c1cc4d4583.php @@ -0,0 +1,304 @@ +O:10:"feedParser":7:{s:9:"feed_type";s:8:"atom 1.0";s:5:"title";s:13:"Blog Dotclear";s:4:"link";s:29:"https://fr.dotclear.org/blog/";s:11:"description";s:33:"Prenez le contrôle de votre blog";s:7:"pubdate";s:25:"2023-10-16T10:50:34+02:00";s:9:"generator";s:8:"Dotclear";s:5:"items";a:20:{i:0;O:8:"stdClass":8:{s:4:"link";s:60:"https://fr.dotclear.org/blog/post/2023/08/31/Dotclear-2.27.3";s:5:"title";s:15:"Dotclear 2.27.3";s:7:"creator";s:6:"Franck";s:11:"description";s:0:"";s:7:"content";s:276:"

    Une nouvelle version qui corrige quelques problèmes rencontrés avec l'installation, la gestion des dépendances des plugins et thèmes, la procédure de récupération de mot de passe, l'export à plat et lorsque certains réglages de widget étaient incorrects.

    +";s:7:"subject";a:1:{i:0;s:4:"News";}s:7:"pubdate";s:25:"2023-08-31T16:34:00+02:00";s:2:"TS";i:1693492440;}i:1;O:8:"stdClass":8:{s:4:"link";s:60:"https://fr.dotclear.org/blog/post/2023/08/22/Dotclear-2.27.2";s:5:"title";s:15:"Dotclear 2.27.2";s:7:"creator";s:6:"Franck";s:11:"description";s:0:"";s:7:"content";s:300:"

    Une nouvelle version de maintenance qui comporte quelques corrections d'erreurs rencontrées avec les versions 2.27 et 2.27.1 précédentes.

    +";s:7:"subject";a:1:{i:0;s:4:"News";}s:7:"pubdate";s:25:"2023-08-22T11:05:00+02:00";s:2:"TS";i:1692695100;}i:2;O:8:"stdClass":8:{s:4:"link";s:60:"https://fr.dotclear.org/blog/post/2023/08/14/Dotclear-2.27.1";s:5:"title";s:15:"Dotclear 2.27.1";s:7:"creator";s:6:"Franck";s:11:"description";s:0:"";s:7:"content";s:217:"

    Forcément, on regarde partout, on teste mille fois, et puis la petite erreur de frappe vient s'insinuer dans les rouages bien huilés et donc ce matin une petite version de maintenance sans effet visible.

    +";s:7:"subject";a:1:{i:0;s:4:"News";}s:7:"pubdate";s:25:"2023-08-14T09:47:00+02:00";s:2:"TS";i:1691999220;}i:3;O:8:"stdClass":8:{s:4:"link";s:58:"https://fr.dotclear.org/blog/post/2023/08/13/Dotclear-2.27";s:5:"title";s:13:"Dotclear 2.27";s:7:"creator";s:6:"Franck";s:11:"description";s:0:"";s:7:"content";s:1223:"

    Comme souvent on avait prévu des monts et des merveilles et puis chemin faisant on est redevenu raisonnable compte-tenu de nos disponibilités respectives avec toutefois quelques améliorations visibles et surtout beaucoup de travail invisible pour moderniser le code et supprimer les vieilleries.

    + +

    Ce trimestre la version 2.27 apporte la prévisualisation des thèmes avec le contenu actuel du blog, ça peut être utile pour se rendre compte visuellement avant d'activer un thème, et puis on a ajouté et complété (à l'aide de moteurs de traduction) quelques langues ; mais surtout cette version est la dernière à supporter PHP 7.4 et PHP 8.0.

    + +

    Nous vous conseillons donc, si vous souhaitez poursuivre les mises à jour futures, de basculer sur PHP 8.1 ou PHP 8.2. Notez que ne pas le faire ne vous empêchera pas d'utiliser encore longtemps la 2.27, à vous de voir.

    + +

    Pour finir, nous souhaitons un joyeux anniversaire pour les vingt ans de DotClear avec un C majuscule, comme Olivier l'écrivait dans son billet d'annonce !

    +";s:7:"subject";a:1:{i:0;s:4:"News";}s:7:"pubdate";s:25:"2023-08-13T08:43:00+02:00";s:2:"TS";i:1691908980;}i:4;O:8:"stdClass":8:{s:4:"link";s:60:"https://fr.dotclear.org/blog/post/2023/06/04/Dotclear-2.26.1";s:5:"title";s:15:"Dotclear 2.26.1";s:7:"creator";s:6:"Franck";s:11:"description";s:0:"";s:7:"content";s:708:"

    Une petite version de maintenance, habituelle après une version majeure et qui règle quelques problèmes rencontrés depuis.

    + +

    La prochaine version majeure (2.27) est prévue pour mi-août, ça sera d'ailleurs l'occasion de fêter les 20 ans de Dotclear et sachez que cette version sera la dernière à supporter encore PHP 7.4.

    + +

    À partir de la 2.28 qui sera publiée à la fin de l'année (mi-novembre a priori) il faudra avoir a minima PHP 8.1 pour fonctionner.

    + +

    Vous pouvez d'ores et déjà vous y préparer en basculant sur cette version, voire encore mieux sur la 8.2 puisque ça fait quelques versions que Dotclear la supporte bien !

    +";s:7:"subject";a:1:{i:0;s:4:"News";}s:7:"pubdate";s:25:"2023-06-04T09:15:00+02:00";s:2:"TS";i:1685862900;}i:5;O:8:"stdClass":8:{s:4:"link";s:58:"https://fr.dotclear.org/blog/post/2023/05/13/Dotclear-2.26";s:5:"title";s:13:"Dotclear 2.26";s:7:"creator";s:6:"Franck";s:11:"description";s:0:"";s:7:"content";s:1228:"

    Une nouvelle version dont la mise à jour devrait passer sans problème majeur chez la plupart d'entre vous.

    + +

    Rien d'extraordinaire cette fois, surtout des petites améliorations ici et là, et c'est surtout du côté du code que l'essentiel à été fait car pour la première fois depuis la première version de Dotclear 2, la librairie Clearbricks n'en fait plus partie, ou plutôt a été intégrée directement dans le code de Dotclear.

    + +

    C'était également l'occasion de renforcer les tests unitaires et l'analyse statique du code (avec PHPStan, PSalm et Rector) qui continuera d'être progressivement modernisé (il en reste pas mal).

    + +

    Un nouveau thème est en cours de développement et il devrait, si possible, faire partie de la prochaine version majeure — qui sonnera aussi les 20 ans de Dotclear —, mais comme on a dit souvent ici : « Ça sera le cas quand il sera prêt ! ».

    + +

    Par ailleurs, la reprise de l'architecture de l'administration est à l'étude, en particulier pour bénéficier des dernières possibilités de HTML et CSS. Il y aura possiblement un peu de casse, mais on essaiera de limiter les dégâts, comme à notre habitude.

    + +

    Bonne mise à jour !

    +";s:7:"subject";a:1:{i:0;s:4:"News";}s:7:"pubdate";s:25:"2023-05-13T06:08:00+02:00";s:2:"TS";i:1683950880;}i:6;O:8:"stdClass":8:{s:4:"link";s:60:"https://fr.dotclear.org/blog/post/2023/02/25/Dotclear-2.25.3";s:5:"title";s:15:"Dotclear 2.25.3";s:7:"creator";s:6:"Franck";s:11:"description";s:0:"";s:7:"content";s:82:"

    Une mise à jour qui corrige quelques bugs rencontrés avec la 2.25.2.

    +";s:7:"subject";a:1:{i:0;s:4:"News";}s:7:"pubdate";s:25:"2023-02-25T09:16:00+01:00";s:2:"TS";i:1677312960;}i:7;O:8:"stdClass":8:{s:4:"link";s:60:"https://fr.dotclear.org/blog/post/2023/02/19/Dotclear-2.25.2";s:5:"title";s:15:"Dotclear 2.25.2";s:7:"creator";s:6:"Franck";s:11:"description";s:0:"";s:7:"content";s:82:"

    Une mise à jour qui corrige quelques bugs rencontrés avec la 2.25.1.

    +";s:7:"subject";a:1:{i:0;s:4:"News";}s:7:"pubdate";s:25:"2023-02-19T09:13:00+01:00";s:2:"TS";i:1676794380;}i:8;O:8:"stdClass":8:{s:4:"link";s:60:"https://fr.dotclear.org/blog/post/2023/02/18/Dotclear-2.25.1";s:5:"title";s:15:"Dotclear 2.25.1";s:7:"creator";s:6:"Franck";s:11:"description";s:0:"";s:7:"content";s:80:"

    Une mise à jour qui corrige quelques bugs rencontrés avec la 2.25.

    +";s:7:"subject";a:1:{i:0;s:4:"News";}s:7:"pubdate";s:25:"2023-02-18T13:08:00+01:00";s:2:"TS";i:1676722080;}i:9;O:8:"stdClass":8:{s:4:"link";s:58:"https://fr.dotclear.org/blog/post/2023/02/13/Dotclear-2.25";s:5:"title";s:13:"Dotclear 2.25";s:7:"creator";s:6:"Franck";s:11:"description";s:0:"";s:7:"content";s:3009:"

    Une nouvelle version de Dotclear pour laquelle vous devriez rencontrer moins de soucis, si c'était le cas, qu'au moment de la mise à jour en 2.24.

    + +

    Cette version intègre essentiellement une modernisation du code — modernisation qui devrait encore se poursuivre pendant quelques trimestres.

    + +

    Il est possible que dans un futur proche la version de PHP requise évolue, en particulier pour nous permettre d'accentuer nos efforts sur la modernisation du code. Pour l'instant c'est encore PHP 7.4, mais l'interface d'administration de la 2.25 vous signalera, si vous utilisez encore cette version, qu'il est temps de songer à basculer sur PHP 8.0 ou encore PHP 8.1, voire PHP 8.2 pour laquelle nous nous sommes efforcés d'assurer la compatibilité.

    + +

    Une petite note à l'attention des développeurs de plugins : Il était jusqu'à maintenant optionnel de définir le type de module dans le fichier _define.php ; il est fort probable que la future 2.26 l'impose, alors ajoutez cette ligne dans les propriétés :

    + +
    +'type' => 'plugin',
    +
    + +

    Prenez exemple sur un des plugins distribués avec Dotclear si nécessaire.

    + +

    Le CHANGELOG de la 2.25 :

    + +
      +
    • 🐘 PHP 7.4+ is required, PHP 8.0/8.1 compliance (and as far as we know PHP 8.2)
    • +
    • Core: New plugin/theme code structure (using a brand new autoloader), old plugins/themes remain compatibles
    • +
    • Core: Clearbricks is now included in Dotclear code, not more as a git sub-module
    • +
    • Core: Update last step will not redirect to the safe-mode login page
    • +
    • Core: No more need to add namespace (blog-settings) / workspace (user-preferences) before using them
    • +
    • Core: Add possible using of external db driver (Experimental)
    • +
    • Core: Add support of .mjs ECMAScript module files
    • +
    • Core: Remove unnecessary and weak protection code
    • +
    • Core: Move some legacy and proxy code in dcProxyV2 plugin
    • +
    • a11y: Some aria attributes have been set in backend
    • +
    • Theme: Merge default smilies and blog's smilies (the blog's smilies have a higher priority)
    • +
    • Theme: Merge plugin blowupConfig into theme Blowup
    • +
    • Admin: Some jQuery javascript scripts have been rewritten in pure ECMAScript
    • +
    • Admin: Add Atkinson Hyperlegible font (used by default in admin, may be disabled in user pref)
    • +
    • Admin: Add some shortcuts (CTRL+letter) to dcLegacyEditor toolbar
    • +
    • Admin: Add a specific warning message on update page if necessary (breaking changes)
    • +
    • Admin: Cope with no user TZ defined (use UTC in this case)
    • +
    • Admin: Fix admin permission management for blogroll and pages plugins
    • +
    • Admin: Cope with float/double values in about:config and user:pref
    • +
    • 🐛 → Various bugs, a11y concerns and typos fixed
    • +
    • 🌼 → Some locales and cosmetic adjustments
    • +
    • 📣 Warning: Next major release (2.26) may require PHP 8.0 (announced in backend) or PHP 8.1
    • +
    +";s:7:"subject";a:1:{i:0;s:4:"News";}s:7:"pubdate";s:25:"2023-02-13T09:25:00+01:00";s:2:"TS";i:1676276700;}i:10;O:8:"stdClass":8:{s:4:"link";s:60:"https://fr.dotclear.org/blog/post/2023/01/18/Dotclear-2.24.1";s:5:"title";s:15:"Dotclear 2.24.1";s:7:"creator";s:6:"Franck";s:11:"description";s:0:"";s:7:"content";s:97:"

    Une mise à jour qui corrige quelques bugs rencontrés avec la 2.24 de Noël dernier.

    +";s:7:"subject";a:1:{i:0;s:4:"News";}s:7:"pubdate";s:25:"2023-01-18T12:13:00+01:00";s:2:"TS";i:1674040380;}i:11;O:8:"stdClass":8:{s:4:"link";s:58:"https://fr.dotclear.org/blog/post/2022/12/24/Dotclear-2.24";s:5:"title";s:13:"Dotclear 2.24";s:7:"creator";s:6:"Franck";s:11:"description";s:0:"";s:7:"content";s:1827:"

    La nouvelle version pour les fêtes de fin d'année. Il est fortement recommandé de faire la mise à jour en mode de secours, ce qui vous permettra ensuite de mettre à jour les plugins qui doivent l'être.

    + +

    Si vous avez un souci pour vous connecter après la mise à jour, supprimez les cookies associés avant de rafraichir la page de connexion.

    + +

    Le CHANGELOG de la 2.24 :

    + +
      +
    • 🐘 PHP 7.4+ is required, PHP 8.0/8.1 compliance
    • +
    • 🗑 Remove XML/RPC system (keep only minimum for Pingbacks)
    • +
    • New blog parameter to close comments/trackbacks after a period of inactivity on the blog
    • +
    • Core: Large code review has been done, may break old code (3rd party plugins and themes)
    • +
    • Admin UI: New default icons for media items
    • +
    • Admin UI: Message look reviewed
    • +
    • Admin UX: Preserve current dir and current view of media manager
    • +
    • Admin UX: Password strength use an entropy indicator
    • +
    • Admin UX: Improve navigation in about:config and user:preferences list
    • +
    • Admin UX: Allow activation and de-activation of plugins in safe mode
    • +
    • Admin UX: Allow update of disabled/activated plugins in safe mode/normal mode
    • +
    • Admin UX: Add folding capability to widgets group
    • +
    • Theme: Cope with theme defined widget container format
    • +
    • Theme: Smilies are available for every theme (Blowup theme not more mandatory)
    • +
    • Lib: Update CKEditor to 4.20.1
    • +
    • Lib: Update Codemirror to 5.65.10
    • +
    • 🐛 → Various bugs, a11y concerns and typos fixed
    • +
    • 🌼 → Some locales and cosmetic adjustments
    • +
    +";s:7:"subject";a:1:{i:0;s:4:"News";}s:7:"pubdate";s:25:"2022-12-24T10:00:00+01:00";s:2:"TS";i:1671872400;}i:12;O:8:"stdClass":8:{s:4:"link";s:78:"https://fr.dotclear.org/blog/post/2022/12/13/Faire-la-mise-%C3%A0-jour-en-2.24";s:5:"title";s:29:"Faire la mise à jour en 2.24";s:7:"creator";s:6:"Franck";s:11:"description";s:0:"";s:7:"content";s:5541:"

    + +

    On va pas se mentir, la prochaine mise à jour pourra être … sportive1 :-)

    + +

    Je viens de tester plusieurs fois, à partir d'une installation qui tourne en production (mon blog) avec Dotclear 2.23.1 et j'ai noté les choses suivantes :

    + +
      +
    1. Si jamais vous utilisez le plugin de cache statique2, désactivez-le temporairement (il suffit de commenter la constante d'activation DC_SC_CACHE_ENABLE dans le fichier inc/config.php, ou de la mettre à false).

    2. +
    3. Faire la mise à jour vers Dotclear 2.24 en mode de secours est la meilleure façon de faire, une fois que vous savez3 que les plugins que vous utilisez sont disponibles pour la 2.244.

    4. +
    5. Si jamais vous aviez besoin du plugin FakeMeUp, alors reconnectez-vous en mode normal, installez-le, lancez-le, puis reconnectez-vous en mode de secours.

    6. +
    7. Place aux mises à jour :

      + +
        +
      1. Faites la mise à jour de Dotclear en 2.24 (toujours en mode de secours),
      2. +
      3. Reconnectez-vous en mode de secours car l'étape précédente vous ramènera sur la page d'authentification5,
      4. +
      5. Faites la mise à jour des plugins6,
      6. +
      7. Réactivez le cache statique si nécessaire,
      8. +
      9. Reconnectez-vous en mode normal.
      10. +
    8. +
    + +

    Ça devrait être tout bon !

    + +

    Profitez-en pour vider le cache des templates et le cache statique (plugin Entretien).

    + +

    Petit supplément : il peut être utile d'installer le plugin growUp pour faire un peu de ménage7 une fois la mise à jour effectuée8.

    + +

    Quoi qu'il en soit on sera dans les parages si jamais il y avait un problème ; sur le forum en particulier.

    + +
    +
    +
      + +
    1. +

      Pour être honnête ma première tentative s'est heurté à un problème avec le cache statique (voir le point 1 de la liste), sinon j'ai pu faire la mise à jour en mode normal sans souci. 

      +
    2. + +
    3. +

      Surtout si vous l'utilisez, comme moi, de façon agressive. 

      +
    4. + +
    5. +

      Installez le plugin Check store version, il vous dira tout ça. 

      +
    6. + +
    7. +

      Dans le cas contraire, attendez qu'ils le soient, c'est préférable ! 

      +
    8. + +
    9. +

      Il se peut que la page d'authentification ne s'affiche pas, dans ce cas supprimez les cookies associés au site et rafraichissez la page. 

      +
    10. + +
    11. +

      Forcez la vérification de mise à jour pour être sûr·e de ne rien louper. 

      +
    12. + +
    13. +

      C'est normalement effectué pendant la mise à jour, mais parfois il peut se passer des bricoles ;-) 

      +
    14. + +
    15. +

      Il peut être désactivé ou désinstallé ensuite. 

      +
    16. + +
    +
    +";s:7:"subject";a:1:{i:0;s:4:"News";}s:7:"pubdate";s:25:"2022-12-13T15:13:00+01:00";s:2:"TS";i:1670940780;}i:13;O:8:"stdClass":8:{s:4:"link";s:77:"https://fr.dotclear.org/blog/post/2022/12/03/Mode-de-secours-de-Dotclear-2.24";s:5:"title";s:32:"Mode de secours de Dotclear 2.24";s:7:"creator";s:6:"Franck";s:11:"description";s:0:"";s:7:"content";s:7114:"

    + +

    La version 2.24 de Dotclear — qui devrait être publiée dans quelques semaines — a été l'objet d'une reprise du code assez profonde, pour assurer une meilleure robustesse et pour évacuer quelques vieilleries qu'elle transportait depuis longtemps. Cependant cette refonte a généré quelques incompatibilités avec les versions précédentes des plugins et parfois des thèmes.

    + +

    En conséquence, une fois mis à jour avec la version 2.24 de Dotclear il se pourrait bien que vous ayez du mal à retrouver votre tableau de bord ou autre chose qu'une page blanche du côté public de votre blog préféré.

    + +

    Message d'erreur d'un plugin

    + +

    La raison ?

    + +

    Un ou plusieurs plugins qui nécessitent des mises à jour — celles-ci sont déjà disponibles pour un nombre conséquent de plugins tiers —, ou des désactivations.

    + +

    Or comment faire cette ou ces mises à jour, voire cette ou ces désactivations si vous n'avez pas accès à l'administration de votre installation ?

    + +

    C'est très exactement pour cette raison qu'il y a, depuis plusieurs années, un mode de secours — aussi appelé « mode sans échec » — qui permet de se connecter à l'interface d'administration sans activer aucun plugin. Et quand je dis aucun, c'est vraiment aucun ; même les plugins livrés avec Dotclear sont désactivés dans ce mode particulier.

    + +
    +

    Attention

    +

    Il vous est fortement conseillé, avant de mettre à jour votre installation vers la version 2.24, de lister les plugins tiers installés et actifs (et de mettre cette liste de côté), ils sont les plus susceptibles de poser des problèmes une fois la mise à jour effectuée, pour évaluer ensuite la liste des mises à jour requises, voire les désactivations à prévoir si elles n'étaient pas disponibles

    +

    Il existe d'ailleurs un plugin (pour les versions 2.19 à 2.23.1), nommé CheckStoreVersion, développé par Jean-Christian Denis, et qui permet d'ajouter un onglet supplémentaire sur la page de gestion des plugins (et des thèmes), et qui indique la liste des mises à jours disponibles pour les plugins (et thèmes) actuellement installés. Ce plugin est disponible sur DotAddict.

    +
    + +

    La nouveauté avec la version 2.24 de Dotclear est que vous pouvez, avec ce mode de secours, désactiver, mettre à jour, supprimer ou installer des plugins, ceux-ci restant bien évidemment inactifs tant que vous êtes connecté dans ce mode.

    + +

    En pratique, comment ça se passe ?

    + +

    Premièrement il faut vous connecter en mode de secours. Pour cela, sur la page de connexion vous avez un lien situé en bas et intitulé « Problème de connexion ? » :

    + +

    Page de connexion normale

    + +

    Si vous cliquez sur ce lien vous démasquez alors deux liens. Le premier permet d'engager la procédure à utiliser en cas d'oubli de son mot de passe — mais ce n'est pas l'objet de ce billet —, et le second vous permet de basculer en mode de secours :

    + +

    Page de connexion normale avec les liens de secours

    + +
    +

    Astuce

    +

    Il se peut que même l'accès à la page de connexion soit impossible. Dans ce cas il vous suffira d'ajouter à la fin de l'URL de connexion que vous utilisez habituellement ceci : +

    ?safe_mode=1
    +Safe mode étant l'équivalent anglais de Mode de secours (ou mode sans échec).

    + +

    Si par exemple votre URL de connexion est :

    +
    https://example.com/admin/auth.php
    +

    alors l'URL de connexion en mode de secours sera :

    +
    https://example.com/admin/auth.php?safe_mode=1
    +
    + +

    Il faut donc cliquer sur ce deuxième lien qui vous amènera alors sur une autre page de connexion :

    + +

    Page de connexion en mode de secours

    + +

    Remplissez les champs comme à l'accoutumée et validez. Vous devriez maintenant avoir le tableau de bord affiché avec un beau message vous avertissant que vous êtes en mode de secours :

    + +

    Tableau de bord avec le message concernant le mode de secours

    + +

    Vous remarquerez alors, que comme précisé plus haut, aucun plugin n'est actif ; par contre vous avez la possibilité de basculer sur la page de gestion des plugins qui fonctionne de la même manière qu'en mode normal.

    + +

    Vous retrouverez donc les onglets classiques qui listent les plugins en attente de mise à jour, les plugins installés, activés ou pas, ainsi que les onglets qui permettent l'installation automatique ou manuelle de plugins :

    + +

    Page de gestion des plugins en mode de secours

    + +

    Chaque action dans cette page ne vous sortira pas du mode de secours où aucun plugin n'est actif, donc aucun danger de « casser » votre installation ici.

    + +

    Une fois tous les plugins mis à jour ou désactivés en attendant une prochaine mise à jour — comparez avec la liste que vous avez mis de côté avant de mettre à jour pour vérifier que vous n'avez rien oublié —, vous pouvez revenir à la connexion habituelle.

    + +

    Il suffit pour cela de vous déconnecter et de vous reconnecter comme à l'ordinaire.

    + +
    + +

    Gardez ce billet sous le coude pour le jour où vous ferez la mise à jour vers la 2.24, il se pourrait qu'il vous serve.

    +";s:7:"subject";a:1:{i:0;s:4:"News";}s:7:"pubdate";s:25:"2022-12-03T15:38:00+01:00";s:2:"TS";i:1670078280;}i:14;O:8:"stdClass":8:{s:4:"link";s:74:"https://fr.dotclear.org/blog/post/2022/10/27/Adapter-son-code-pour-la-2.24";s:5:"title";s:29:"Adapter son code pour la 2.24";s:7:"creator";s:6:"Franck";s:11:"description";s:0:"";s:7:"content";s:1756:"

    + +

    Bonjour,

    + +

    J'ai entrepris, depuis quelques jours, de publier sur mon blog une série de billets expliquant, pas à pas, comment mettre à niveau le code de vos plugins et thèmes pour assurer la compatibilité avec la future version 2.24 de Dotclear, qui devrait être publiée dans quelques semaines.

    + +

    Un flux Atom est également disponible pour cette série avec ce lien.

    + +

    En effet, cette future version de Dotclear rompt avec le passé récent et la rétro-compatibilité habituelle assurée de version en version depuis quelques années ; c'est le coût de la modernisation et du renforcement de la robustesse du cœur de Dotclear.

    + +

    En conséquence il est possible que certains plugins (et peut-être thèmes) « bloquent » l'accès à votre blog et/ou à l'administration de votre installation après la mise à jour en 2.24. Il faudra alors vérifier si une mise à jour de ceux-ci est disponible ou dans le cas contraire les désactiver.

    + +

    À ce sujet je reviendrai dans un futur billet sur le mode de secours, dont les fonctionnalités ont été améliorées, au moment de la sortie de la version 2.24.

    + +

    Notez par ailleurs qu'il est d'ores et déjà possible de publier ses plugins et thèmes dépendants de la version 2.24 sur DotAddict (via la console).

    +";s:7:"subject";a:1:{i:0;s:14:"Développement";}s:7:"pubdate";s:25:"2022-10-27T08:14:00+02:00";s:2:"TS";i:1666851240;}i:15;O:8:"stdClass":8:{s:4:"link";s:60:"https://fr.dotclear.org/blog/post/2022/08/13/Dotclear-2.23.1";s:5:"title";s:15:"Dotclear 2.23.1";s:7:"creator";s:6:"Franck";s:11:"description";s:0:"";s:7:"content";s:108:"

    Et dans la foulée, une version de maintenance pour corriger un bug avec l'ajout de commentaires.

    ";s:7:"subject";a:1:{i:0;s:4:"News";}s:7:"pubdate";s:25:"2022-08-13T10:01:00+02:00";s:2:"TS";i:1660377660;}i:16;O:8:"stdClass":8:{s:4:"link";s:58:"https://fr.dotclear.org/blog/post/2022/08/13/Dotclear-2.23";s:5:"title";s:13:"Dotclear 2.23";s:7:"creator";s:6:"Franck";s:11:"description";s:0:"";s:7:"content";s:2437:"

    La nouvelle version pour ce trimestre avec quelques améliorations au programme essentiellement dans le cœur du code, mais pas que.

    + + +

    Notez la disparition de la gestion des jeux d'icônes, peu utilisée et potentiellement complexifiée avec l'usage des icônes au format SVG en deux versions (thème clair et sombre).

    + + +

    Le CHANGELOG de la 2.23 :

    + +
      +
    • 🐘 PHP 7.4+ is required, PHP 8.0/8.1 compliance
    • +
    • 🗑 Remove Iconset management
    • +
    • Admin UI: Harmonize font size on different support (laptop, tablet, mobile)
    • +
    • Admin UX: Group more logically buttons on CKEditor toolbar
    • +
    • Core: New constant DC_DEFAULT_THEME, set to 'berlin'
    • +
    • Core: Use predefined constants for post statuses (dcBlog::POST_*)
    • +
    • Core: Use predefined constants for comment statuses (dcBlog::COMMENT_*)
    • +
    • Core: Deprecated global $core (or $GLOBALS'core'), use dcCore::app() instead
    • +
    • Core: Deprecated global $_ctx, use dcCore::app()->ctx instead
    • +
    • Core: Deprecated global $_lang, use dcCore::app()->lang instead
    • +
    • Core: Deprecated global $mod_files, use dcCore::app()->cache'mod_files' instead
    • +
    • Core: Deprecated global $mod_ts, use dcCore::app()->cache'mod_ts' instead
    • +
    • Core: Deprecated global $_menu, use dcCore::app()->menu instead
    • +
    • Core: Deprecated global $__resources, use dcCore::app()->resources instead
    • +
    • Core: REST server now accepts JSON format (experimental)
    • +
    • Fix: Use relative URL for attachments as far as possible
    • +
    • Fix: Remove select hiding mechanism when help is displayed
    • +
    • Fix: Loading of modules (plugins/themes) in safe mode
    • +
    • Fix: Message position on Quick entry submit (dashboard)
    • +
    • Fix: Select appearance on Safari (webkit engine)
    • +
    • Lib: Update CKEditor to 4.19.1
    • +
    • Lib: Update Codemirror to 5.65.7
    • +
    • 🐛 → Various bugs, a11y concerns and typos fixed
    • +
    • 🌼 → Some locales and cosmetic adjustments
    • +
    • 📣 Warning: Internet Explorer is not more officially supported (may still work weirdly)
    • +
    ";s:7:"subject";a:1:{i:0;s:4:"News";}s:7:"pubdate";s:25:"2022-08-13T09:30:00+02:00";s:2:"TS";i:1660375800;}i:17;O:8:"stdClass":8:{s:4:"link";s:58:"https://fr.dotclear.org/blog/post/2022/05/13/Dotclear-2.22";s:5:"title";s:13:"Dotclear 2.22";s:7:"creator";s:6:"Franck";s:11:"description";s:0:"";s:7:"content";s:1381:"

    La nouvelle version pour ce trimestre — on tient le rythme, c'est une bonne chose — avec quelques améliorations au programme :

    + +
      +
    • PHP 7.4 minimum et c'est compatible — sauf bug de dernière minute — jusqu'à PHP 8.1 inclus
    • +
    • On a retiré le système de traçage FLoC de Google qui a jeté l'éponge entretemps
    • +
    • Ajout d'un bouton de prévisualisation dans l'éditeur standard de Dotclear ; pratique pour vérifier les modifications d'un billet déjà publié, avant de les sauvegarder
    • +
    • Les thèmes Berlin et Ductile ne requièrent plus jQuery pour fonctionner ; vérifiez toutefois les plugins tiers que vous avez installé, ils peuvent toujours en avoir besoin côté public
    • +
    • Amélioration de la récupération des métadonnées de la source d'un Webmention ou d'un Pingback
    • +
    • Ajout d'un bouton « Réinitialiser à maintenant Â» pour la date de publication d'un billet ; permet de pallier l'absence de cette fonctionnalité sur certains navigateurs
    • +
    • Réduction des seuils de bascule de l'affichage de l'administration (mobile, tablette et laptop)
    • +
    • Le menu d'accès rapide aux sections de about:Config et user:Pref est maintenant en position fixe en haut de l'écran
    • +
    • Léger redesign des icônes de la barre d'outils de l'éditeur standard de Dotclear
    • +
    ";s:7:"subject";a:1:{i:0;s:4:"News";}s:7:"pubdate";s:25:"2022-05-13T08:17:00+02:00";s:2:"TS";i:1652422620;}i:18;O:8:"stdClass":8:{s:4:"link";s:60:"https://fr.dotclear.org/blog/post/2022/03/07/Dotclear-2.21.3";s:5:"title";s:15:"Dotclear 2.21.3";s:7:"creator";s:6:"Franck";s:11:"description";s:0:"";s:7:"content";s:146:"

    Une nouvelle version qui corrige deux bugs concernant la gestion des utilisateurs autres qu'administrateurs (ou super-administrateurs).

    ";s:7:"subject";a:1:{i:0;s:4:"News";}s:7:"pubdate";s:25:"2022-03-07T10:17:00+01:00";s:2:"TS";i:1646644620;}i:19;O:8:"stdClass":8:{s:4:"link";s:60:"https://fr.dotclear.org/blog/post/2022/02/26/Dotclear-2.21.2";s:5:"title";s:15:"Dotclear 2.21.2";s:7:"creator";s:6:"Franck";s:11:"description";s:0:"";s:7:"content";s:391:"

    Une nouvelle version de maintenance qui résout, entre autres, les problèmes de date et de cache rencontrés par certains utilisateurs.

    + + +

    Changements :

    + +
      +
    • Retour en arrière sur certaines modifications faites pour la conformité à PHP 8.1 (strftime)
    • +
    • Nettoyage des dossiers currywurst restants (template currywurst supprimé depuis la 2.20)
    • +
    ";s:7:"subject";a:1:{i:0;s:4:"News";}s:7:"pubdate";s:25:"2022-02-26T09:32:00+01:00";s:2:"TS";i:1645864320;}}} \ No newline at end of file diff --git a/cache/cbtpl/06/16/061624c7d38d3b032e8770d96e17d8da.php b/cache/cbtpl/06/16/061624c7d38d3b032e8770d96e17d8da.php new file mode 100644 index 0000000..73490f4 --- /dev/null +++ b/cache/cbtpl/06/16/061624c7d38d3b032e8770d96e17d8da.php @@ -0,0 +1,61 @@ +xml version="1.0" encoding="utf-8""; ?> + + + <?php echo context::global_filter($core->blog->name,1,0,0,0,0,'BlogName'); ?><?php if ($_ctx->feed_subtitle !== null) { echo context::global_filter($_ctx->feed_subtitle,1,0,0,0,0,'SysFeedSubtitle');} ?> + - <?php echo __('Comments'); ?> + blog->desc,1,0,0,0,0,'BlogDescription'); ?> + + + blog->upddt,$core->blog->settings->blog_timezone),0,0,0,0,0,'BlogUpdateDate'); ?> + + blog->settings->editor,1,0,0,0,0,'BlogEditor'); ?> + + blog->uid,0,0,0,0,0,'BlogFeedID'); ?> + Dotclear + + exists("meta")) { @$params['from'] .= ', '.$core->prefix.'meta META '; +@$params['sql'] .= 'AND META.post_id = P.post_id '; +$params['sql'] .= "AND META.meta_type = 'tag' "; +$params['sql'] .= "AND META.meta_id = '".$core->con->escape($_ctx->meta->meta_id)."' "; +} ?> +posts !== null) { $params['post_id'] = $_ctx->posts->post_id; $core->blog->withoutPassword(false); +} +if ($_ctx->nb_comment_per_page !== null) { $params['limit'] = $_ctx->nb_comment_per_page; } +if ($_ctx->exists("categories")) { $params['cat_id'] = $_ctx->categories->cat_id; } +if ($_ctx->exists("langs")) { $params['sql'] = "AND P.post_lang = '".$core->blog->con->escape($_ctx->langs->post_lang)."' "; } +$params['order'] = 'comment_dt desc'; +$_ctx->comments = $core->blog->getComments($params); unset($params); +if ($_ctx->posts !== null) { $core->blog->withoutPassword(true);} +$_ctx->pings = $_ctx->comments; +?> +comments->fetch()) : ?> + + comments->comment_trackback) : ?> + + [ping] <?php echo context::global_filter($_ctx->pings->post_title,1,0,0,0,0,'PingEntryTitle'); ?> - <?php echo context::global_filter($_ctx->pings->comment_author,1,0,0,0,0,'PingBlogName'); ?> + + pings->getFeedID(),0,0,0,0,0,'PingFeedID'); ?> + pings->getISO8601Date(),0,0,0,0,0,'PingDate'); ?> + pings->comment_author,1,0,0,0,0,'PingBlogName'); ?> + <p><a href="pings->getAuthorURL(),1,0,0,0,0,'PingAuthorURL'); ?>">pings->getTrackbackTitle(),1,0,0,0,0,'PingTitle'); ?></a></p> pings->getTrackbackContent(),1,0,0,0,0,'PingContent'); ?> + + + + + comments->comment_trackback) : ?> + + <?php echo context::global_filter($_ctx->comments->post_title,1,0,0,0,0,'CommentEntryTitle'); ?> - <?php echo context::global_filter($_ctx->comments->comment_author,1,0,0,0,0,'CommentAuthor'); ?> + + comments->getFeedID(),0,0,0,0,0,'CommentFeedID'); ?> + comments->getISO8601Date(),0,0,0,0,0,'CommentDate'); ?> + comments->comment_author,1,0,0,0,0,'CommentAuthor'); ?> + comments->getContent(1),1,0,0,0,0,'CommentContent'); ?> + + + comments = null; ?> + + \ No newline at end of file diff --git a/cache/cbtpl/1c/4b/1c4b52bb84ebd38be237c1522ddf181d.php b/cache/cbtpl/1c/4b/1c4b52bb84ebd38be237c1522ddf181d.php new file mode 100644 index 0000000..f8871ba --- /dev/null +++ b/cache/cbtpl/1c/4b/1c4b52bb84ebd38be237c1522ddf181d.php @@ -0,0 +1,212 @@ + + + + + + + + <?php echo __('Tag'); ?> - <?php echo context::global_filter($_ctx->meta->meta_id,0,0,0,0,0,'TagID'); ?> - <?php echo context::global_filter($core->blog->name,1,0,0,0,0,'BlogName'); ?><?php if(!context::PaginationStart()) : ?> - <?php echo __('page'); ?> <?php echo context::global_filter(context::PaginationPosition(0),0,0,0,0,0,'PaginationCurrent'); ?><?php endif; ?> + + + + + + + + + + + + + + + " title="" /> + + exists("meta")) { @$params['from'] .= ', '.$core->prefix.'meta META '; +@$params['sql'] .= 'AND META.post_id = P.post_id '; +$params['sql'] .= "AND META.meta_type = 'tag' "; +$params['sql'] .= "AND META.meta_id = '".$core->con->escape($_ctx->meta->meta_id)."' "; +} ?> +nb_entry_per_page; +$params['limit'] = array((($_page_number-1)*$params['limit']),$params['limit']); +if ($_ctx->exists("users")) { $params['user_id'] = $_ctx->users->user_id; } +if ($_ctx->exists("categories")) { $params['cat_id'] = $_ctx->categories->cat_id; } +if ($_ctx->exists("archives")) { $params['post_year'] = $_ctx->archives->year(); $params['post_month'] = $_ctx->archives->month(); unset($params['limit']); } +if ($_ctx->exists("langs")) { $params['post_lang'] = $_ctx->langs->post_lang; } +if (isset($_search)) { $params['search'] = $_search; } +$params['order'] = 'post_dt desc'; +$params['no_content'] = true; +$_ctx->post_params = $params; +$_ctx->posts = $core->blog->getPosts($params); unset($params); +?> +posts->fetch()) : ?> + posts->isStart()) : ?> + post_params; +$_ctx->pagination = $core->blog->getPosts($params,true); unset($params); +?> +pagination->f(0) > $_ctx->posts->count()) : ?> + + + + + + + + + + + + posts = null; $_ctx->post_params = null; ?> + + meta->meta_id)."/atom",0,0,0,0,0,'TagFeedURL'); ?>" /> + " /> + + tpl->getData('_head.html'); } catch (Exception $e) {} ?> + + + +
    +tpl->getData('_top.html'); } catch (Exception $e) {} ?> + +
    + +
    +
    + +
    +

    - meta->meta_id,0,0,0,0,0,'TagID'); ?>

    + +

    meta->meta_id)."/atom",0,0,0,0,0,'TagFeedURL'); ?>" + title="" class="feed"> + + blog->settings->allow_comments || $core->blog->settings->allow_trackbacks) : ?> + - meta->meta_id)."/atom",0,0,0,0,0,'TagFeedURL'); ?>/comments" + title="" class="feed"> + +

    +
    + + exists("meta")) { @$params['from'] .= ', '.$core->prefix.'meta META '; +@$params['sql'] .= 'AND META.post_id = P.post_id '; +$params['sql'] .= "AND META.meta_type = 'tag' "; +$params['sql'] .= "AND META.meta_id = '".$core->con->escape($_ctx->meta->meta_id)."' "; +} ?> +nb_entry_per_page; +$params['limit'] = array((($_page_number-1)*$params['limit']),$params['limit']); +if ($_ctx->exists("users")) { $params['user_id'] = $_ctx->users->user_id; } +if ($_ctx->exists("categories")) { $params['cat_id'] = $_ctx->categories->cat_id; } +if ($_ctx->exists("archives")) { $params['post_year'] = $_ctx->archives->year(); $params['post_month'] = $_ctx->archives->month(); unset($params['limit']); } +if ($_ctx->exists("langs")) { $params['post_lang'] = $_ctx->langs->post_lang; } +if (isset($_search)) { $params['search'] = $_search; } +$params['order'] = 'post_dt desc'; +$_ctx->post_params = $params; +$_ctx->posts = $core->blog->getPosts($params); unset($params); +?> +posts->fetch()) : ?> +
    + + posts->firstPostOfDay()) : ?>

    posts->getDate(''),0,0,0,0,0,'EntryDate'); ?>

    + +

    posts->post_title,1,0,0,0,0,'EntryTitle'); ?>

    + + + + meta = $objMeta->getMetaRecordset($_ctx->posts->post_meta,'tag'); $_ctx->meta->sort('meta_id_lower','asc'); ?>meta->fetch()) : ?> + meta->isStart()) : ?> + meta = null; unset($objMeta); ?> + + hasBehavior('publicEntryBeforeContent')) { $core->callBehavior('publicEntryBeforeContent',$core,$_ctx);} ?> + + posts->isExtended()) : ?> +
    posts->getExcerpt(0),0,0,0,0,0,'EntryExcerpt'); ?>
    +

    ...

    + + + posts->isExtended()) : ?> +
    posts->getContent(0),0,0,0,0,0,'EntryContent'); ?>
    + + + hasBehavior('publicEntryAfterContent')) { $core->callBehavior('publicEntryAfterContent',$core,$_ctx);} ?> + + posts->countMedia() || ($_ctx->posts->hasComments() || $_ctx->posts->commentsActive()) || ($_ctx->posts->hasTrackbacks() || $_ctx->posts->trackbacksActive())) : ?> + + +
    + + posts->isEnd()) : ?> + post_params; +$_ctx->pagination = $core->blog->getPosts($params,true); unset($params); +?> +pagination->f(0) > $_ctx->posts->count()) : ?> +

    - + + -

    + + + posts = null; $_ctx->post_params = null; ?> +
    +
    + + + +
    + +tpl->getData('_footer.html'); } catch (Exception $e) {} ?> +
    + + \ No newline at end of file diff --git a/cache/cbtpl/3a/b6/3ab69b6036ca46cabbbc3f6f39ceb835.php b/cache/cbtpl/3a/b6/3ab69b6036ca46cabbbc3f6f39ceb835.php new file mode 100644 index 0000000..86c976a --- /dev/null +++ b/cache/cbtpl/3a/b6/3ab69b6036ca46cabbbc3f6f39ceb835.php @@ -0,0 +1,92 @@ + + + + + + + + <?php echo __('Archives'); ?> - <?php echo context::global_filter($core->blog->name,1,0,0,0,0,'BlogName'); ?> + + + + + + + + + + + + + + + + exists("categories")) { $params['cat_id'] = $_ctx->categories->cat_id; } +$_ctx->archives = $core->blog->getDates($params); unset($params); +?> +archives->fetch()) : ?> + + archives = null; ?> + + " /> + + tpl->getData('_head.html'); } catch (Exception $e) {} ?> + + + +
    +tpl->getData('_top.html'); } catch (Exception $e) {} ?> + +
    + +
    +
    + +
    +

    +
    + +
    + exists("categories")) { $params['cat_id'] = $_ctx->categories->cat_id; } +$_ctx->archives = $core->blog->getDates($params); unset($params); +?> +archives->fetch()) : ?> + archives->yearHeader()) : ?> +

    archives->dt),0,0,0,0,0,'ArchiveDate'); ?>

    + + + archives = null; ?> +
    + +
    +
    + + + +
    + +tpl->getData('_footer.html'); } catch (Exception $e) {} ?> +
    + + \ No newline at end of file diff --git a/cache/cbtpl/3b/b3/3bb3a29ef197db17fdf8e0d1c82e1f9f.php b/cache/cbtpl/3b/b3/3bb3a29ef197db17fdf8e0d1c82e1f9f.php new file mode 100644 index 0000000..d41216b --- /dev/null +++ b/cache/cbtpl/3b/b3/3bb3a29ef197db17fdf8e0d1c82e1f9f.php @@ -0,0 +1,273 @@ + + + + + + + + <?php echo context::global_filter($_ctx->posts->post_title,1,0,0,0,0,'EntryTitle'); ?> - <?php echo context::global_filter($core->blog->name,1,0,0,0,0,'BlogName'); ?> + posts->getContent(0),1,1,180,0,0,'EntryContent'); ?>" /> + + + + + + + posts->getContent(0),1,1,180,0,0,'EntryContent'); ?>" /> + + + + + + + + + + " title="" /> + + " /> + + tpl->getData('_head.html'); } catch (Exception $e) {} ?> + + + + + + +
    +posts->trackbacksActive()) { echo $_ctx->posts->getTrackbackData(); } ?> + + +tpl->getData('_top.html'); } catch (Exception $e) {} ?> + +
    + +
    +
    + +
    +

    posts->post_title,1,0,0,0,0,'EntryTitle'); ?>

    + + hasBehavior('publicEntryBeforeContent')) { $core->callBehavior('publicEntryBeforeContent',$core,$_ctx);} ?> + + posts->isExtended()) : ?> +
    posts->getExcerpt(0),0,0,0,0,0,'EntryExcerpt'); ?>
    + +
    posts->getContent(0),0,0,0,0,0,'EntryContent'); ?>
    + +

    posts->getDate(''),0,0,0,0,0,'EntryDate'); ?> + posts->getAuthorLink(),0,0,0,0,0,'EntryAuthorLink'); ?>

    + + hasBehavior('publicEntryAfterContent')) { $core->callBehavior('publicEntryAfterContent',$core,$_ctx);} ?> +
    + + posts !== null && $core->media) { +$_ctx->attachments = new ArrayObject($core->media->getPostMedia($_ctx->posts->post_id)); +?> +attachments as $attach_i => $attach_f) : $GLOBALS['attach_i'] = $attach_i; $GLOBALS['attach_f'] = $attach_f;$_ctx->file_url = $attach_f->file_url; ?> + +
    +

    +
      + +
    • + type == "audio/mpeg3") : ?> + tpl->getData('_mp3_player.html'); } catch (Exception $e) {} ?> - + + type == "video/x-flv" || $attach_f->type == "video/mp4" || $attach_f->type == "video/x-m4v")) : ?> + tpl->getData('_flv_player.html'); } catch (Exception $e) {} ?> + + type == "video/x-flv" || $attach_f->type == "video/mp4" || $attach_f->type == "video/x-m4v")) : ?> + media_title,0,0,0,0,0,'AttachmentTitle'); ?> + +
    • + attachments)) : ?> +
    +
    + + attachments = null; unset($attach_i,$attach_f,$_ctx->file_url); ?> + + + posts->hasComments() || $_ctx->posts->commentsActive())) : ?> + exists("meta")) { @$params['from'] .= ', '.$core->prefix.'meta META '; +@$params['sql'] .= 'AND META.post_id = P.post_id '; +$params['sql'] .= "AND META.meta_type = 'tag' "; +$params['sql'] .= "AND META.meta_id = '".$core->con->escape($_ctx->meta->meta_id)."' "; +} ?> +posts !== null) { $params['post_id'] = $_ctx->posts->post_id; $core->blog->withoutPassword(false); +} +$params['comment_trackback'] = false; +if ($_ctx->nb_comment_per_page !== null) { $params['limit'] = $_ctx->nb_comment_per_page; } +if ($_ctx->exists("categories")) { $params['cat_id'] = $_ctx->categories->cat_id; } +if ($_ctx->exists("langs")) { $params['sql'] = "AND P.post_lang = '".$core->blog->con->escape($_ctx->langs->post_lang)."' "; } +$params['order'] = 'comment_dt asc'; +$_ctx->comments = $core->blog->getComments($params); unset($params); +if ($_ctx->posts !== null) { $core->blog->withoutPassword(true);} +?> +comments->fetch()) : ?> + comments->isStart()) : ?> +
    +

    +
    + +
    comments->index()+1; ?>. + comments->getDate(''),0,0,0,0,0,'CommentDate'); ?>, comments->getTime(''),0,0,0,0,0,'CommentTime'); ?> + comments->getAuthorLink(),0,0,0,0,0,'CommentAuthorLink'); ?>
    + +
    + + hasBehavior('publicCommentBeforeContent')) { $core->callBehavior('publicCommentBeforeContent',$core,$_ctx);} ?> + + comments->getContent(0),0,0,0,0,0,'CommentContent'); ?> + + hasBehavior('publicCommentAfterContent')) { $core->callBehavior('publicCommentAfterContent',$core,$_ctx);} ?> +
    + comments->isEnd()) : ?> +
    +
    + + comments = null; ?> + + + posts->commentsActive()) : ?> + form_error !== null) : ?> +

    form_error !== null) { echo $_ctx->form_error; } ?>

    + + + +

    + + + +

    + + +
    + comment_preview !== null && $_ctx->comment_preview["preview"]) : ?> +
    +

    +
    +
    comment_preview["content"],0,0,0,0,0,'CommentPreviewContent'); ?>
    +
    +

    +
    + + +

    +
    + + hasBehavior('publicCommentFormBeforeContent')) { $core->callBehavior('publicCommentFormBeforeContent',$core,$_ctx);} ?> + +

    + " /> +

    + +

    + " /> +

    + +

    + " /> +

    + +

    + +

    + +

    + +

    + + hasBehavior('publicCommentFormAfterContent')) { $core->callBehavior('publicCommentFormAfterContent',$core,$_ctx);} ?> +
    + +
    +

    + comment_preview !== null && $_ctx->comment_preview["preview"]) : ?>

    +
    +
    + + + posts->hasTrackbacks() || $_ctx->posts->trackbacksActive())) : ?> +
    +

    + posts !== null) { $params['post_id'] = $_ctx->posts->post_id; $core->blog->withoutPassword(false); +} +$params['comment_trackback'] = true; +if ($_ctx->nb_comment_per_page !== null) { $params['limit'] = $_ctx->nb_comment_per_page; } +if ($_ctx->exists("categories")) { $params['cat_id'] = $_ctx->categories->cat_id; } +if ($_ctx->exists("langs")) { $params['sql'] = "AND P.post_lang = '".$core->blog->con->escape($_ctx->langs->post_lang)."' "; } +$params['order'] = 'comment_dt asc'; +$_ctx->pings = $core->blog->getComments($params); unset($params); +if ($_ctx->posts !== null) { $core->blog->withoutPassword(true);} +?> +pings->fetch()) : ?> + pings->isStart()) : ?> +
    + +
    pings->index()+1; ?>. + pings->getDate(''),0,0,0,0,0,'PingDate'); ?>, pings->getTime(''),0,0,0,0,0,'PingTime'); ?> + pings->comment_author,1,0,0,0,0,'PingBlogName'); ?>
    + +
    + + hasBehavior('publicPingBeforeContent')) { $core->callBehavior('publicPingBeforeContent',$core,$_ctx);} ?> + +

    blog->settings->comments_nofollow) { echo ' rel="nofollow"';} ?>>pings->getTrackbackTitle(),1,0,0,0,0,'PingTitle'); ?>

    + pings->getTrackbackContent(),0,0,0,0,0,'PingContent'); ?> + + hasBehavior('publicPingAfterContent')) { $core->callBehavior('publicPingAfterContent',$core,$_ctx);} ?> +
    + pings->isEnd()) : ?> +
    + + pings = null; ?> +
    + + + posts->trackbacksActive()) : ?> +

     : posts->trackbacksActive()) { echo $_ctx->posts->getTrackbackLink(); } ?> +

    + + + posts->commentsActive() || $_ctx->posts->trackbacksActive()) : ?> +

    /comments/posts->post_id,0,0,0,0,0,'EntryID'); ?>" + title="">

    + +
    +
    + + + +
    + +tpl->getData('_footer.html'); } catch (Exception $e) {} ?> +
    + + \ No newline at end of file diff --git a/cache/cbtpl/3d/2a/3d2ab7176958994fb44ae475a0e58648.php b/cache/cbtpl/3d/2a/3d2ab7176958994fb44ae475a0e58648.php new file mode 100644 index 0000000..8ff0822 --- /dev/null +++ b/cache/cbtpl/3d/2a/3d2ab7176958994fb44ae475a0e58648.php @@ -0,0 +1,16 @@ + + + + + + + + + +tpl->getData('user_head.html'); } catch (Exception $e) {} ?> +hasBehavior('publicHeadContent')) { $core->callBehavior('publicHeadContent',$core,$_ctx);} ?> + diff --git a/cache/cbtpl/62/e1/62e139c10241e743060059b9ff916ad8.php b/cache/cbtpl/62/e1/62e139c10241e743060059b9ff916ad8.php new file mode 100644 index 0000000..d82b021 --- /dev/null +++ b/cache/cbtpl/62/e1/62e139c10241e743060059b9ff916ad8.php @@ -0,0 +1,329 @@ + + + + + + + + <?php echo context::global_filter($_ctx->posts->post_title,1,0,0,0,0,'EntryTitle'); ?> - <?php echo context::global_filter($core->blog->name,1,0,0,0,0,'BlogName'); ?> + posts->getContent(0),1,1,180,0,0,'EntryContent'); ?>" /> + + + + + + + posts->getContent(0),1,1,180,0,0,'EntryContent'); ?>" /> + + + + + + + + + + " title="" /> + + blog->getNextPost($_ctx->posts,1,0,0); ?> +posts = $next_post; unset($next_post); +while ($_ctx->posts->fetch()) : ?>posts = null; ?> + + + blog->getNextPost($_ctx->posts,-1,0,0); ?> +posts = $prev_post; unset($prev_post); +while ($_ctx->posts->fetch()) : ?>posts = null; ?> + + + " /> + + tpl->getData('_head.html'); } catch (Exception $e) {} ?> + + + + + +
    +posts->trackbacksActive()) { echo $_ctx->posts->getTrackbackData(); } ?> + + +tpl->getData('_top.html'); } catch (Exception $e) {} ?> + +
    + +
    +
    + + + +
    +

    posts->post_title,1,0,0,0,0,'EntryTitle'); ?>

    + + + + hasBehavior('publicEntryBeforeContent')) { $core->callBehavior('publicEntryBeforeContent',$core,$_ctx);} ?> + + posts->isExtended()) : ?> +
    posts->getExcerpt(0),0,0,0,0,0,'EntryExcerpt'); ?>
    + + +
    posts->getContent(0),0,0,0,0,0,'EntryContent'); ?>
    + + meta = $objMeta->getMetaRecordset($_ctx->posts->post_meta,'tag'); $_ctx->meta->sort('meta_id_lower','asc'); ?>meta->fetch()) : ?> + meta->isStart()) : ?> + meta = null; unset($objMeta); ?> + + hasBehavior('publicEntryAfterContent')) { $core->callBehavior('publicEntryAfterContent',$core,$_ctx);} ?> + +
     
    +
    + + posts !== null && $core->media) { +$_ctx->attachments = new ArrayObject($core->media->getPostMedia($_ctx->posts->post_id)); +?> +attachments as $attach_i => $attach_f) : $GLOBALS['attach_i'] = $attach_i; $GLOBALS['attach_f'] = $attach_f;$_ctx->file_url = $attach_f->file_url; ?> + +
    +

    +
      + +
    • + type == "audio/mpeg3") : ?> + tpl->getData('_mp3_player.html'); } catch (Exception $e) {} ?> - + + type == "video/x-flv" || $attach_f->type == "video/mp4" || $attach_f->type == "video/x-m4v")) : ?> + tpl->getData('_flv_player.html'); } catch (Exception $e) {} ?> + + type == "video/x-flv" || $attach_f->type == "video/mp4" || $attach_f->type == "video/x-m4v")) : ?> + media_title,0,0,0,0,0,'AttachmentTitle'); ?> + +
    • + attachments)) : ?> +
    +
    + + attachments = null; unset($attach_i,$attach_f,$_ctx->file_url); ?> + + + posts->hasComments() || $_ctx->posts->commentsActive())) : ?> + exists("meta")) { @$params['from'] .= ', '.$core->prefix.'meta META '; +@$params['sql'] .= 'AND META.post_id = P.post_id '; +$params['sql'] .= "AND META.meta_type = 'tag' "; +$params['sql'] .= "AND META.meta_id = '".$core->con->escape($_ctx->meta->meta_id)."' "; +} ?> +posts !== null) { $params['post_id'] = $_ctx->posts->post_id; $core->blog->withoutPassword(false); +} +$params['comment_trackback'] = false; +if ($_ctx->nb_comment_per_page !== null) { $params['limit'] = $_ctx->nb_comment_per_page; } +if ($_ctx->exists("categories")) { $params['cat_id'] = $_ctx->categories->cat_id; } +if ($_ctx->exists("langs")) { $params['sql'] = "AND P.post_lang = '".$core->blog->con->escape($_ctx->langs->post_lang)."' "; } +$params['order'] = 'comment_dt asc'; +$_ctx->comments = $core->blog->getComments($params); unset($params); +if ($_ctx->posts !== null) { $core->blog->withoutPassword(true);} +?> +comments->fetch()) : ?> + comments->isStart()) : ?> +
    +

    +
    + +
    comments->index()+1; ?>. + comments->getDate(''),0,0,0,0,0,'CommentDate'); ?>, comments->getTime(''),0,0,0,0,0,'CommentTime'); ?> + comments->getAuthorLink(),0,0,0,0,0,'CommentAuthorLink'); ?>
    + +
    + + hasBehavior('publicCommentBeforeContent')) { $core->callBehavior('publicCommentBeforeContent',$core,$_ctx);} ?> + + comments->getContent(0),0,0,0,0,0,'CommentContent'); ?> + + hasBehavior('publicCommentAfterContent')) { $core->callBehavior('publicCommentAfterContent',$core,$_ctx);} ?> +
    + comments->isEnd()) : ?> +
    +
    + + comments = null; ?> + + + posts->commentsActive()) : ?> + form_error !== null) : ?> +

    form_error !== null) { echo $_ctx->form_error; } ?>

    + + + +

    + + + +

    + + + + +
    + comment_preview !== null && $_ctx->comment_preview["preview"]) : ?> +
    +

    +
    +
    comment_preview["content"],0,0,0,0,0,'CommentPreviewContent'); ?>
    +
    +

    +
    + + +

    +
    +
    + + hasBehavior('publicCommentFormBeforeContent')) { $core->callBehavior('publicCommentFormBeforeContent',$core,$_ctx);} ?> + +

    + " /> +

    + +

    + " /> +

    + +

    + " /> +

    + +

    + +

    + +

    +

    + + hasBehavior('publicCommentFormAfterContent')) { $core->callBehavior('publicCommentFormAfterContent',$core,$_ctx);} ?> +
    + +
    +

    + comment_preview !== null && $_ctx->comment_preview["preview"]) : ?>

    +
    +
    +
    + + + posts->hasTrackbacks() || $_ctx->posts->trackbacksActive())) : ?> +
    +

    + posts !== null) { $params['post_id'] = $_ctx->posts->post_id; $core->blog->withoutPassword(false); +} +$params['comment_trackback'] = true; +if ($_ctx->nb_comment_per_page !== null) { $params['limit'] = $_ctx->nb_comment_per_page; } +if ($_ctx->exists("categories")) { $params['cat_id'] = $_ctx->categories->cat_id; } +if ($_ctx->exists("langs")) { $params['sql'] = "AND P.post_lang = '".$core->blog->con->escape($_ctx->langs->post_lang)."' "; } +$params['order'] = 'comment_dt asc'; +$_ctx->pings = $core->blog->getComments($params); unset($params); +if ($_ctx->posts !== null) { $core->blog->withoutPassword(true);} +?> +pings->fetch()) : ?> + pings->isStart()) : ?> +
    + +
    pings->index()+1; ?>. + pings->getDate(''),0,0,0,0,0,'PingDate'); ?>, pings->getTime(''),0,0,0,0,0,'PingTime'); ?> + pings->comment_author,1,0,0,0,0,'PingBlogName'); ?>
    + +
    + + hasBehavior('publicPingBeforeContent')) { $core->callBehavior('publicPingBeforeContent',$core,$_ctx);} ?> + +

    blog->settings->comments_nofollow) { echo ' rel="nofollow"';} ?>>pings->getTrackbackTitle(),1,0,0,0,0,'PingTitle'); ?>

    + pings->getTrackbackContent(),0,0,0,0,0,'PingContent'); ?> + + hasBehavior('publicPingAfterContent')) { $core->callBehavior('publicPingAfterContent',$core,$_ctx);} ?> +
    + pings->isEnd()) : ?> +
    + + pings = null; ?> +
    + + + posts->trackbacksActive()) : ?> +

     : posts->trackbacksActive()) { echo $_ctx->posts->getTrackbackLink(); } ?> +

    + + + posts->commentsActive() || $_ctx->posts->trackbacksActive()) : ?> +

    /comments/posts->post_id,0,0,0,0,0,'EntryID'); ?>" + title="">

    + +
    +
    + + + +
    + +tpl->getData('_footer.html'); } catch (Exception $e) {} ?> +
    + + \ No newline at end of file diff --git a/cache/cbtpl/68/28/68289f8a2d83100b6bda1a3cccbbc63f.php b/cache/cbtpl/68/28/68289f8a2d83100b6bda1a3cccbbc63f.php new file mode 100644 index 0000000..a2f35de --- /dev/null +++ b/cache/cbtpl/68/28/68289f8a2d83100b6bda1a3cccbbc63f.php @@ -0,0 +1,230 @@ + + + + + + + + <?php echo context::global_filter($_ctx->categories->cat_title,1,0,0,0,0,'CategoryTitle'); ?> - <?php echo context::global_filter($core->blog->name,1,0,0,0,0,'BlogName'); ?><?php if(!context::PaginationStart()) : ?> - <?php echo __('page'); ?> <?php echo context::global_filter(context::PaginationPosition(0),0,0,0,0,0,'PaginationCurrent'); ?><?php endif; ?> + + + + + + + + + + + + + + + + + " title="" /> + + exists("meta")) { @$params['from'] .= ', '.$core->prefix.'meta META '; +@$params['sql'] .= 'AND META.post_id = P.post_id '; +$params['sql'] .= "AND META.meta_type = 'tag' "; +$params['sql'] .= "AND META.meta_id = '".$core->con->escape($_ctx->meta->meta_id)."' "; +} ?> +nb_entry_per_page; +$params['limit'] = array((($_page_number-1)*$params['limit']),$params['limit']); +if ($_ctx->exists("users")) { $params['user_id'] = $_ctx->users->user_id; } +if ($_ctx->exists("categories")) { $params['cat_id'] = $_ctx->categories->cat_id; } +if ($_ctx->exists("archives")) { $params['post_year'] = $_ctx->archives->year(); $params['post_month'] = $_ctx->archives->month(); unset($params['limit']); } +if ($_ctx->exists("langs")) { $params['post_lang'] = $_ctx->langs->post_lang; } +if (isset($_search)) { $params['search'] = $_search; } +$params['order'] = 'post_dt desc'; +$params['no_content'] = true; +$_ctx->post_params = $params; +$_ctx->posts = $core->blog->getPosts($params); unset($params); +?> +posts->fetch()) : ?> + posts->isStart()) : ?> + post_params; +$_ctx->pagination = $core->blog->getPosts($params,true); unset($params); +?> +pagination->f(0) > $_ctx->posts->count()) : ?> + + + + + + + + + + + + posts = null; $_ctx->post_params = null; ?> + + categories->cat_url."/atom",0,0,0,0,0,'CategoryFeedURL'); ?>" /> + + tpl->getData('_head.html'); } catch (Exception $e) {} ?> + + + +
    +tpl->getData('_top.html'); } catch (Exception $e) {} ?> + +
    + +
    +
    + +
    +

    categories = $core->blog->getCategoryParents($_ctx->categories->cat_id); +while ($_ctx->categories->fetch()) : ?>categories->cat_url,0,0,0,0,0,'CategoryURL'); ?>">categories->cat_title,1,0,0,0,0,'CategoryTitle'); ?>categories = null; ?> + categories->cat_title,1,0,0,0,0,'CategoryTitle'); ?>

    + categories->cat_desc,0,0,0,0,0,'CategoryDescription'); ?> + + categories->nb_post > 0) : ?> +

    categories->cat_url."/atom",0,0,0,0,0,'CategoryFeedURL'); ?>" + title="" class="feed"> + + blog->settings->allow_comments || $core->blog->settings->allow_trackbacks) : ?> + - categories->cat_url."/atom",0,0,0,0,0,'CategoryFeedURL'); ?>/comments" + title="" class="feed"> + +

    + +
    + + categories = $core->blog->getCategoryFirstChildren($_ctx->categories->cat_id); +while ($_ctx->categories->fetch()) : ?> + categories->isStart()) : ?> + + + categories = null; ?> + + exists("meta")) { @$params['from'] .= ', '.$core->prefix.'meta META '; +@$params['sql'] .= 'AND META.post_id = P.post_id '; +$params['sql'] .= "AND META.meta_type = 'tag' "; +$params['sql'] .= "AND META.meta_id = '".$core->con->escape($_ctx->meta->meta_id)."' "; +} ?> +nb_entry_per_page; +$params['limit'] = array((($_page_number-1)*$params['limit']),$params['limit']); +if ($_ctx->exists("users")) { $params['user_id'] = $_ctx->users->user_id; } +if ($_ctx->exists("categories")) { $params['cat_id'] = $_ctx->categories->cat_id; } +if ($_ctx->exists("archives")) { $params['post_year'] = $_ctx->archives->year(); $params['post_month'] = $_ctx->archives->month(); unset($params['limit']); } +if ($_ctx->exists("langs")) { $params['post_lang'] = $_ctx->langs->post_lang; } +if (isset($_search)) { $params['search'] = $_search; } +$params['order'] = 'post_dt desc'; +$_ctx->post_params = $params; +$_ctx->posts = $core->blog->getPosts($params); unset($params); +?> +posts->fetch()) : ?> +
    + + posts->firstPostOfDay()) : ?>

    posts->getDate(''),0,0,0,0,0,'EntryDate'); ?>

    + +

    posts->post_title,1,0,0,0,0,'EntryTitle'); ?>

    + + + + meta = $objMeta->getMetaRecordset($_ctx->posts->post_meta,'tag'); $_ctx->meta->sort('meta_id_lower','asc'); ?>meta->fetch()) : ?> + meta->isStart()) : ?> + meta = null; unset($objMeta); ?> + + hasBehavior('publicEntryBeforeContent')) { $core->callBehavior('publicEntryBeforeContent',$core,$_ctx);} ?> + + posts->isExtended()) : ?> +
    posts->getExcerpt(0),0,0,0,0,0,'EntryExcerpt'); ?>
    +

    ...

    + + + posts->isExtended()) : ?> +
    posts->getContent(0),0,0,0,0,0,'EntryContent'); ?>
    + + + hasBehavior('publicEntryAfterContent')) { $core->callBehavior('publicEntryAfterContent',$core,$_ctx);} ?> + + posts->countMedia() || ($_ctx->posts->hasComments() || $_ctx->posts->commentsActive()) || ($_ctx->posts->hasTrackbacks() || $_ctx->posts->trackbacksActive())) : ?> + + +
    + + posts->isEnd()) : ?> + post_params; +$_ctx->pagination = $core->blog->getPosts($params,true); unset($params); +?> +pagination->f(0) > $_ctx->posts->count()) : ?> +

    - + + -

    + + + posts = null; $_ctx->post_params = null; ?> +
    +
    + + + +
    + +tpl->getData('_footer.html'); } catch (Exception $e) {} ?> +
    + + \ No newline at end of file diff --git a/cache/cbtpl/8b/ae/8bae1e7eb3f0cd863c169541fdad8d0e.php b/cache/cbtpl/8b/ae/8bae1e7eb3f0cd863c169541fdad8d0e.php new file mode 100644 index 0000000..3cdda34 --- /dev/null +++ b/cache/cbtpl/8b/ae/8bae1e7eb3f0cd863c169541fdad8d0e.php @@ -0,0 +1,7 @@ + + +

    | + | +

    \ No newline at end of file diff --git a/cache/cbtpl/a7/06/a706cb39770a563585de2242a3226981.php b/cache/cbtpl/a7/06/a706cb39770a563585de2242a3226981.php new file mode 100644 index 0000000..cb3007c --- /dev/null +++ b/cache/cbtpl/a7/06/a706cb39770a563585de2242a3226981.php @@ -0,0 +1,73 @@ +xml version="1.0" encoding="utf-8""; ?> + + + <?php echo context::global_filter($core->blog->name,1,0,0,0,0,'BlogName'); ?><?php if ($_ctx->feed_subtitle !== null) { echo context::global_filter($_ctx->feed_subtitle,1,0,0,0,0,'SysFeedSubtitle');} ?> + blog->desc,1,0,0,0,0,'BlogDescription'); ?> + + + blog->upddt,$core->blog->settings->blog_timezone),0,0,0,0,0,'BlogUpdateDate'); ?> + + blog->settings->editor,1,0,0,0,0,'BlogEditor'); ?> + + blog->uid,0,0,0,0,0,'BlogFeedID'); ?> + Dotclear + + exists("meta")) { @$params['from'] .= ', '.$core->prefix.'meta META '; +@$params['sql'] .= 'AND META.post_id = P.post_id '; +$params['sql'] .= "AND META.meta_type = 'tag' "; +$params['sql'] .= "AND META.meta_id = '".$core->con->escape($_ctx->meta->meta_id)."' "; +} ?> +nb_entry_per_page; +$params['limit'] = array((($_page_number-1)*$params['limit']),$params['limit']); +if ($_ctx->exists("users")) { $params['user_id'] = $_ctx->users->user_id; } +if ($_ctx->exists("categories")) { $params['cat_id'] = $_ctx->categories->cat_id; } +if ($_ctx->exists("archives")) { $params['post_year'] = $_ctx->archives->year(); $params['post_month'] = $_ctx->archives->month(); unset($params['limit']); } +if ($_ctx->exists("langs")) { $params['post_lang'] = $_ctx->langs->post_lang; } +if (isset($_search)) { $params['search'] = $_search; } +$params['order'] = 'post_dt desc'; +$_ctx->post_params = $params; +$_ctx->posts = $core->blog->getPosts($params); unset($params); +?> +posts->fetch()) : ?> + + + <?php echo context::global_filter($_ctx->posts->post_title,1,0,0,0,0,'EntryTitle'); ?> + + posts->getFeedID(),0,0,0,0,0,'EntryFeedID'); ?> + posts->getISO8601Date(),0,0,0,0,0,'EntryDate'); ?> + posts->getAuthorCN(),1,0,0,0,0,'EntryAuthorCommonName'); ?> + posts->cat_id) : ?> + posts->cat_title,1,0,0,0,0,'EntryCategory'); ?> + + meta = $objMeta->getMetaRecordset($_ctx->posts->post_meta,'tag'); $_ctx->meta->sort('meta_id_lower','asc'); ?>meta->fetch()) : ?>meta->meta_id,0,0,0,0,0,'MetaID'); ?>meta = null; unset($objMeta); ?> + + posts->getExcerpt(1),1,0,0,0,0,'EntryExcerpt'); ?> + posts->getContent(1),1,0,0,0,0,'EntryContent'); ?> + + posts !== null && $core->media) { +$_ctx->attachments = new ArrayObject($core->media->getPostMedia($_ctx->posts->post_id)); +?> +attachments as $attach_i => $attach_f) : $GLOBALS['attach_i'] = $attach_i; $GLOBALS['attach_f'] = $attach_f;$_ctx->file_url = $attach_f->file_url; ?> + + attachments = null; unset($attach_i,$attach_f,$_ctx->file_url); ?> + + + + posts->commentsActive()) : ?> + posts->getURL(),0,0,0,0,0,'EntryURL'); ?>#comment-form + blog->url.$core->url->getBase("feed")."/atom",0,0,0,0,0,'BlogFeedURL'); ?>/comments/posts->post_id,0,0,0,0,0,'EntryID'); ?> + + + posts = null; $_ctx->post_params = null; ?> + + \ No newline at end of file diff --git a/cache/cbtpl/b0/5d/b05d35fd541ee9f5da5478faf45bb412.php b/cache/cbtpl/b0/5d/b05d35fd541ee9f5da5478faf45bb412.php new file mode 100644 index 0000000..e7c50c1 --- /dev/null +++ b/cache/cbtpl/b0/5d/b05d35fd541ee9f5da5478faf45bb412.php @@ -0,0 +1,71 @@ + + + + + + + + <?php echo __('Tags'); ?> - <?php echo context::global_filter($core->blog->name,1,0,0,0,0,'BlogName'); ?> + + + + + + + + + + + + + + + " title="" /> + + " /> + + tpl->getData('_head.html'); } catch (Exception $e) {} ?> + + + +
    +tpl->getData('_top.html'); } catch (Exception $e) {} ?> + +
    + +
    +
    + +
    +

    +
    + +
    + +
    + +
    +
    + + + +
    + +tpl->getData('_footer.html'); } catch (Exception $e) {} ?> +
    + + \ No newline at end of file diff --git a/cache/cbtpl/b0/f4/b0f4418e5a9e7ab1a68ede430ca901e4.php b/cache/cbtpl/b0/f4/b0f4418e5a9e7ab1a68ede430ca901e4.php new file mode 100644 index 0000000..a520b4c --- /dev/null +++ b/cache/cbtpl/b0/f4/b0f4418e5a9e7ab1a68ede430ca901e4.php @@ -0,0 +1,63 @@ + + + + + + + + <?php echo __('Document not found'); ?> - <?php echo context::global_filter($core->blog->name,1,0,0,0,0,'BlogName'); ?> + + + + + + + + + + + + + " /> + " /> + + tpl->getData('_head.html'); } catch (Exception $e) {} ?> + + + +
    +tpl->getData('_top.html'); } catch (Exception $e) {} ?> + +
    + +
    +
    + +
    +

    +
    + +
    +

    +
    + +
    +
    + + + +
    + +tpl->getData('_footer.html'); } catch (Exception $e) {} ?> +
    + + \ No newline at end of file diff --git a/cache/cbtpl/b9/d7/b9d701fcfceb205e24dd3c2658797c4e.php b/cache/cbtpl/b9/d7/b9d701fcfceb205e24dd3c2658797c4e.php new file mode 100644 index 0000000..e7f1ac6 --- /dev/null +++ b/cache/cbtpl/b9/d7/b9d701fcfceb205e24dd3c2658797c4e.php @@ -0,0 +1,207 @@ + + + + + + + + <?php echo context::global_filter($core->blog->name,1,0,0,0,0,'BlogName'); ?><?php if(!context::PaginationStart()) : ?> - <?php echo __('page'); ?> <?php echo context::global_filter(context::PaginationPosition(0),0,0,0,0,0,'PaginationCurrent'); ?><?php endif; ?> + + + + + + + + + + + + + + + + " /> + categories = $core->blog->getCategories($params); +?> +categories->fetch()) : ?> + categories->cat_url,0,0,0,0,0,'CategoryURL'); ?>" title="categories->cat_title,1,0,0,0,0,'CategoryTitle'); ?>" /> + categories = null; unset($params); ?> + + exists("meta")) { @$params['from'] .= ', '.$core->prefix.'meta META '; +@$params['sql'] .= 'AND META.post_id = P.post_id '; +$params['sql'] .= "AND META.meta_type = 'tag' "; +$params['sql'] .= "AND META.meta_id = '".$core->con->escape($_ctx->meta->meta_id)."' "; +} ?> +nb_entry_per_page; +$params['limit'] = array((($_page_number-1)*$params['limit']),$params['limit']); +if ($_ctx->exists("users")) { $params['user_id'] = $_ctx->users->user_id; } +if ($_ctx->exists("categories")) { $params['cat_id'] = $_ctx->categories->cat_id; } +if ($_ctx->exists("archives")) { $params['post_year'] = $_ctx->archives->year(); $params['post_month'] = $_ctx->archives->month(); unset($params['limit']); } +if ($_ctx->exists("langs")) { $params['post_lang'] = $_ctx->langs->post_lang; } +if (isset($_search)) { $params['search'] = $_search; } +$params['order'] = 'post_dt desc'; +$params['no_content'] = true; +$_ctx->post_params = $params; +$_ctx->posts = $core->blog->getPosts($params); unset($params); +?> +posts->fetch()) : ?> + posts->isStart()) : ?> + post_params; +$_ctx->pagination = $core->blog->getPosts($params,true); unset($params); +?> +pagination->f(0) > $_ctx->posts->count()) : ?> + + + + + + + + + + + + posts = null; $_ctx->post_params = null; ?> + + " /> + + " /> + + tpl->getData('_head.html'); } catch (Exception $e) {} ?> + + + +
    +tpl->getData('_top.html'); } catch (Exception $e) {} ?> + +
    + +
    +
    + exists("meta")) { @$params['from'] .= ', '.$core->prefix.'meta META '; +@$params['sql'] .= 'AND META.post_id = P.post_id '; +$params['sql'] .= "AND META.meta_type = 'tag' "; +$params['sql'] .= "AND META.meta_id = '".$core->con->escape($_ctx->meta->meta_id)."' "; +} ?> +nb_entry_per_page; +$params['limit'] = array((($_page_number-1)*$params['limit']),$params['limit']); +if ($_ctx->exists("users")) { $params['user_id'] = $_ctx->users->user_id; } +if ($_ctx->exists("categories")) { $params['cat_id'] = $_ctx->categories->cat_id; } +if ($_ctx->exists("archives")) { $params['post_year'] = $_ctx->archives->year(); $params['post_month'] = $_ctx->archives->month(); unset($params['limit']); } +if ($_ctx->exists("langs")) { $params['post_lang'] = $_ctx->langs->post_lang; } +if (isset($_search)) { $params['search'] = $_search; } +$params['order'] = 'post_dt desc'; +$_ctx->post_params = $params; +$_ctx->posts = $core->blog->getPosts($params); unset($params); +?> +posts->fetch()) : ?> +
    + + posts->firstPostOfDay()) : ?>

    posts->getDate(''),0,0,0,0,0,'EntryDate'); ?>

    + +

    posts->post_title,1,0,0,0,0,'EntryTitle'); ?>

    + + + + meta = $objMeta->getMetaRecordset($_ctx->posts->post_meta,'tag'); $_ctx->meta->sort('meta_id_lower','asc'); ?>meta->fetch()) : ?> + meta->isStart()) : ?> + meta = null; unset($objMeta); ?> + + hasBehavior('publicEntryBeforeContent')) { $core->callBehavior('publicEntryBeforeContent',$core,$_ctx);} ?> + + posts->isExtended()) : ?> +
    posts->getExcerpt(0),0,0,0,0,0,'EntryExcerpt'); ?>
    +

    ...

    + + + posts->isExtended()) : ?> +
    posts->getContent(0),0,0,0,0,0,'EntryContent'); ?>
    + + + hasBehavior('publicEntryAfterContent')) { $core->callBehavior('publicEntryAfterContent',$core,$_ctx);} ?> + + posts->countMedia() || ($_ctx->posts->hasComments() || $_ctx->posts->commentsActive()) || ($_ctx->posts->hasTrackbacks() || $_ctx->posts->trackbacksActive())) : ?> + + +
    + + posts->isEnd()) : ?> + post_params; +$_ctx->pagination = $core->blog->getPosts($params,true); unset($params); +?> +pagination->f(0) > $_ctx->posts->count()) : ?> +

    - + + -

    + + + posts = null; $_ctx->post_params = null; ?> +
    +
    + + + +
    + +tpl->getData('_footer.html'); } catch (Exception $e) {} ?> +
    + + \ No newline at end of file diff --git a/cache/cbtpl/c1/cd/c1cd28bd66b4517eec04f3abde1cb6c0.php b/cache/cbtpl/c1/cd/c1cd28bd66b4517eec04f3abde1cb6c0.php new file mode 100644 index 0000000..173e2a1 --- /dev/null +++ b/cache/cbtpl/c1/cd/c1cd28bd66b4517eec04f3abde1cb6c0.php @@ -0,0 +1,211 @@ + + + + + + + + <?php echo __('Search'); ?> - <?php if (isset($_search)) { echo sprintf(__('%1$s'),context::global_filter($_search,1,0,0,0,0,'SysSearchString'),$_search_count);} ?> - <?php echo context::global_filter($core->blog->name,1,0,0,0,0,'BlogName'); ?><?php if(!context::PaginationStart()) : ?> - <?php echo __('page'); ?> <?php echo context::global_filter(context::PaginationPosition(0),0,0,0,0,0,'PaginationCurrent'); ?><?php endif; ?> + + + + + + + + + + + + + + + " title="" /> + + exists("meta")) { @$params['from'] .= ', '.$core->prefix.'meta META '; +@$params['sql'] .= 'AND META.post_id = P.post_id '; +$params['sql'] .= "AND META.meta_type = 'tag' "; +$params['sql'] .= "AND META.meta_id = '".$core->con->escape($_ctx->meta->meta_id)."' "; +} ?> +nb_entry_per_page; +$params['limit'] = array((($_page_number-1)*$params['limit']),$params['limit']); +if ($_ctx->exists("users")) { $params['user_id'] = $_ctx->users->user_id; } +if ($_ctx->exists("categories")) { $params['cat_id'] = $_ctx->categories->cat_id; } +if ($_ctx->exists("archives")) { $params['post_year'] = $_ctx->archives->year(); $params['post_month'] = $_ctx->archives->month(); unset($params['limit']); } +if ($_ctx->exists("langs")) { $params['post_lang'] = $_ctx->langs->post_lang; } +if (isset($_search)) { $params['search'] = $_search; } +$params['order'] = 'post_dt desc'; +$params['no_content'] = true; +$_ctx->post_params = $params; +$_ctx->posts = $core->blog->getPosts($params); unset($params); +?> +posts->fetch()) : ?> + posts->isStart()) : ?> + post_params; +$_ctx->pagination = $core->blog->getPosts($params,true); unset($params); +?> +pagination->f(0) > $_ctx->posts->count()) : ?> + + + + + + + + + + + + posts = null; $_ctx->post_params = null; ?> + + " /> + + tpl->getData('_head.html'); } catch (Exception $e) {} ?> + + + +
    +tpl->getData('_top.html'); } catch (Exception $e) {} ?> + +
    + +
    +
    + +
    +

    + +

    %1$s returned no result.'),context::global_filter($_search,1,0,0,0,0,'SysSearchString'),$_search_count);} ?>

    + + +

    %1$s returned %2$s result.'),context::global_filter($_search,1,0,0,0,0,'SysSearchString'),$_search_count);} ?>

    + + 1)) : ?> +

    %1$s returned %2$s results.'),context::global_filter($_search,1,0,0,0,0,'SysSearchString'),$_search_count);} ?>

    + +
    + + exists("meta")) { @$params['from'] .= ', '.$core->prefix.'meta META '; +@$params['sql'] .= 'AND META.post_id = P.post_id '; +$params['sql'] .= "AND META.meta_type = 'tag' "; +$params['sql'] .= "AND META.meta_id = '".$core->con->escape($_ctx->meta->meta_id)."' "; +} ?> +nb_entry_per_page; +$params['limit'] = array((($_page_number-1)*$params['limit']),$params['limit']); +if ($_ctx->exists("users")) { $params['user_id'] = $_ctx->users->user_id; } +if ($_ctx->exists("categories")) { $params['cat_id'] = $_ctx->categories->cat_id; } +if ($_ctx->exists("archives")) { $params['post_year'] = $_ctx->archives->year(); $params['post_month'] = $_ctx->archives->month(); unset($params['limit']); } +if ($_ctx->exists("langs")) { $params['post_lang'] = $_ctx->langs->post_lang; } +if (isset($_search)) { $params['search'] = $_search; } +$params['order'] = 'post_dt desc'; +$_ctx->post_params = $params; +$_ctx->posts = $core->blog->getPosts($params); unset($params); +?> +posts->fetch()) : ?> +
    + + posts->firstPostOfDay()) : ?>

    posts->getDate(''),0,0,0,0,0,'EntryDate'); ?>

    + +

    posts->post_title,1,0,0,0,0,'EntryTitle'); ?>

    + + + + meta = $objMeta->getMetaRecordset($_ctx->posts->post_meta,'tag'); $_ctx->meta->sort('meta_id_lower','asc'); ?>meta->fetch()) : ?> + meta->isStart()) : ?> + meta = null; unset($objMeta); ?> + + hasBehavior('publicEntryBeforeContent')) { $core->callBehavior('publicEntryBeforeContent',$core,$_ctx);} ?> + + posts->isExtended()) : ?> +
    posts->getExcerpt(0),0,0,0,0,0,'EntryExcerpt'); ?>
    +

    ...

    + + + posts->isExtended()) : ?> +
    posts->getContent(0),0,0,0,0,0,'EntryContent'); ?>
    + + + hasBehavior('publicEntryAfterContent')) { $core->callBehavior('publicEntryAfterContent',$core,$_ctx);} ?> + + posts->countMedia() || ($_ctx->posts->hasComments() || $_ctx->posts->commentsActive()) || ($_ctx->posts->hasTrackbacks() || $_ctx->posts->trackbacksActive())) : ?> + + +
    + + posts->isEnd()) : ?> + post_params; +$_ctx->pagination = $core->blog->getPosts($params,true); unset($params); +?> +pagination->f(0) > $_ctx->posts->count()) : ?> +

    - + + -

    + + + posts = null; $_ctx->post_params = null; ?> +
    +
    + + + +
    + +tpl->getData('_footer.html'); } catch (Exception $e) {} ?> +
    + + \ No newline at end of file diff --git a/cache/cbtpl/d6/6a/d66aceb2839fdeb0b5251550574000be.php b/cache/cbtpl/d6/6a/d66aceb2839fdeb0b5251550574000be.php new file mode 100644 index 0000000..f3216ff --- /dev/null +++ b/cache/cbtpl/d6/6a/d66aceb2839fdeb0b5251550574000be.php @@ -0,0 +1,5 @@ + + +hasBehavior('publicFooterContent')) { $core->callBehavior('publicFooterContent',$core,$_ctx);} ?> \ No newline at end of file diff --git a/cache/cbtpl/e1/53/e153e91980f2acce5c73feac0a840192.php b/cache/cbtpl/e1/53/e153e91980f2acce5c73feac0a840192.php new file mode 100644 index 0000000..24da2b8 --- /dev/null +++ b/cache/cbtpl/e1/53/e153e91980f2acce5c73feac0a840192.php @@ -0,0 +1,173 @@ + + + + + + + + <?php echo __('Archives'); ?> - <?php echo context::global_filter(dt::dt2str('%B %Y',$_ctx->archives->dt),0,0,0,0,0,'ArchiveDate'); ?> - <?php echo context::global_filter($core->blog->name,1,0,0,0,0,'BlogName'); ?> + + + + + + + + + + + + + + + " title="" /> + " title="" /> + + + archives->dt;$_ctx->archives = $core->blog->getDates($params); unset($params); +?> +archives->fetch()) : ?>archives = null; ?> + archives->dt;$_ctx->archives = $core->blog->getDates($params); unset($params); +?> +archives->fetch()) : ?>archives = null; ?> + + exists("meta")) { @$params['from'] .= ', '.$core->prefix.'meta META '; +@$params['sql'] .= 'AND META.post_id = P.post_id '; +$params['sql'] .= "AND META.meta_type = 'tag' "; +$params['sql'] .= "AND META.meta_id = '".$core->con->escape($_ctx->meta->meta_id)."' "; +} ?> +nb_entry_per_page; +$params['limit'] = array((($_page_number-1)*$params['limit']),$params['limit']); +if ($_ctx->exists("users")) { $params['user_id'] = $_ctx->users->user_id; } +if ($_ctx->exists("categories")) { $params['cat_id'] = $_ctx->categories->cat_id; } +if ($_ctx->exists("archives")) { $params['post_year'] = $_ctx->archives->year(); $params['post_month'] = $_ctx->archives->month(); unset($params['limit']); } +if ($_ctx->exists("langs")) { $params['post_lang'] = $_ctx->langs->post_lang; } +if (isset($_search)) { $params['search'] = $_search; } +$params['order'] = 'post_dt desc'; +$params['no_content'] = true; +$_ctx->post_params = $params; +$_ctx->posts = $core->blog->getPosts($params); unset($params); +?> +posts->fetch()) : ?> + + posts = null; $_ctx->post_params = null; ?> + + tpl->getData('_head.html'); } catch (Exception $e) {} ?> + + + +
    +tpl->getData('_top.html'); } catch (Exception $e) {} ?> + +
    + +
    +
    + + + +
    +

    archives->dt),0,0,0,0,0,'ArchiveDate'); ?>

    +
    + +
    + exists("meta")) { @$params['from'] .= ', '.$core->prefix.'meta META '; +@$params['sql'] .= 'AND META.post_id = P.post_id '; +$params['sql'] .= "AND META.meta_type = 'tag' "; +$params['sql'] .= "AND META.meta_id = '".$core->con->escape($_ctx->meta->meta_id)."' "; +} ?> +nb_entry_per_page; +$params['limit'] = array((($_page_number-1)*$params['limit']),$params['limit']); +if ($_ctx->exists("users")) { $params['user_id'] = $_ctx->users->user_id; } +if ($_ctx->exists("categories")) { $params['cat_id'] = $_ctx->categories->cat_id; } +if ($_ctx->exists("archives")) { $params['post_year'] = $_ctx->archives->year(); $params['post_month'] = $_ctx->archives->month(); unset($params['limit']); } +if ($_ctx->exists("langs")) { $params['post_lang'] = $_ctx->langs->post_lang; } +if (isset($_search)) { $params['search'] = $_search; } +$params['order'] = 'post_dt desc'; +$params['no_content'] = true; +$_ctx->post_params = $params; +$_ctx->posts = $core->blog->getPosts($params); unset($params); +?> +posts->fetch()) : ?> + + posts->firstPostOfDay()) : ?>

    posts->getDate(''),0,0,0,0,0,'EntryDate'); ?>

    + +

    posts->post_title,1,0,0,0,0,'EntryTitle'); ?>

    + + + posts = null; $_ctx->post_params = null; ?> +
    +
    +
    + + + +
    + +tpl->getData('_footer.html'); } catch (Exception $e) {} ?> +
    + + \ No newline at end of file diff --git a/cache/cbtpl/f7/f4/f7f41a7bdbfd5f0616a3e4b89660a6a8.php b/cache/cbtpl/f7/f4/f7f41a7bdbfd5f0616a3e4b89660a6a8.php new file mode 100644 index 0000000..e69de29 diff --git a/cache/daorg/68/cb/68cbfef3c40e3d56b4fb94709e2b9321.ser b/cache/daorg/68/cb/68cbfef3c40e3d56b4fb94709e2b9321.ser new file mode 100644 index 0000000000000000000000000000000000000000..0ce3b4e46d5f733c8c9c6037ae49188aa9a31407 GIT binary patch literal 27052 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'') { + return $GLOBALS['__l10n'][$str]; + } else { + return $str; + } +} + +function fetchRemote($src,&$dest,$step=0) # Rudimentary HTTP client +{ + if ($step > 3) { + return false; + } + + $src = parse_url($src); + $host = $src['host']; + $path = $src['path']; + + if (($s = @fsockopen($host,80,$errno,$errstr,5)) === false) { + return false; + } + + fwrite($s, + 'GET '.$path." HTTP/1.0\r\n" + .'Host: '.$host."\r\n" + ."User-Agent: Dotclear Net Install\r\n" + ."Accept: text/xml,application/xml,application/xhtml+xml,text/html,text/plain,image/png,image/jpeg,image/gif,*/*\r\n" + ."\r\n" + ); + + $i = 0; + $in_content = false; + while (!feof($s)) + { + $line = fgets($s,4096); + + if (rtrim($line,"\r\n") == '' && !$in_content) { + $in_content = true; + $i++; + continue; + } + + if ($i == 0) { + if (!preg_match('/HTTP\/(\\d\\.\\d)\\s*(\\d+)\\s*(.*)/',rtrim($line,"\r\n"), $m)) { + fclose($s); + return false; + } + $status = (integer) $m[2]; + if ($status < 200 || $status >= 400) { + fclose($s); + return false; + } + } + + if (!$in_content) + { + if (preg_match('/Location:\s+?(.+)$/',rtrim($line,"\r\n"),$m)) { + fclose($s); + return fetchRemote(trim($m[1]),$dest,$step+1); + } + $i++; + continue; + } + + if (is_resource($dest)) { + fwrite($dest,$line); + } else { + $dest .= $line; + } + + $i++; + } + + fclose($s); + return true; +} + +function getLanguage($default = 'en') +{ + if (!empty($_REQUEST['lang'])) { + return $_REQUEST['lang']; + } + if (!empty($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { + $languages = explode(',',$_SERVER['HTTP_ACCEPT_LANGUAGE']); + $l = explode(';',$languages[0]); + $dlang = substr(trim($l[0]),0,2); + return strtolower($dlang); + } + return $default; +} + +function getLocation() +{ + $server_name = explode(':',$_SERVER['HTTP_HOST']); + $server_name = $server_name[0]; + if ($_SERVER['SERVER_PORT'] == '443') + { + $scheme = 'https'; + $port = ''; + } + elseif (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') + { + $scheme = 'https'; + $port = ($_SERVER['SERVER_PORT'] != '443') ? ':'.$_SERVER['SERVER_PORT'] : ''; + } + else + { + $scheme = 'http'; + $port = ($_SERVER['SERVER_PORT'] != '80') ? ':'.$_SERVER['SERVER_PORT'] : ''; + } + + $loc = preg_replace('#/$#','',dirname($_SERVER['SCRIPT_NAME'])); + + return $scheme.'://'.$server_name.$port.$loc.'/'; +} + +function openPage() +{ + header('Content-Type: text/html; charset=UTF-8'); + echo + ''."\n". + ''."\n". + "\n". + ' '."\n". + ' '.__('Dotclear 2 NetInstall').''."\n". + ' '."\n". + ' '."\n". + ''."\n". + ''."\n". + '
    '."\n". + '

    '.__('Dotclear NetInstall').'

    '."\n". + '
    '."\n"; +} + +function closePage() +{ + echo + '
    '."\n". + '
    '."\n". + ''."\n". + ''; +} + +function initPHP5() +{ + $htaccess = dirname(__FILE__).'/.htaccess'; + if (file_exists($htaccess)) { + if (!is_readable($htaccess) || !is_writable($htaccess)) { + return false; + } + } + $rawdatas = ''; + if (!fetchRemote(DC_LOADER_SERVICE.'hosting.txt',$rawdatas)) { + return false; + } + $rawdatas = explode("\n",$rawdatas); + if (!($my_hostname = @gethostbyaddr($_SERVER['SERVER_ADDR']))) { + return false; + } + $found = false; + foreach ($rawdatas as $line) { + list($name,$hostname,$rule) = explode('|',trim($line)); + if (preg_match('!'.preg_quote($hostname).'$!',$my_hostname)) { + $found = $rule; + break; + } + } + if ($found) { + if (false !== ($fh = @fopen($htaccess,"ab"))) { + fwrite($fh,"\n".$found); + fclose($fh); + return true; + } + } + return false; +} + +function cleanFiles() +{ + @unlink(dirname(__FILE__).'/dcl_files.php'); + @unlink(dirname(__FILE__).'/dcl_unzip.php'); + @unlink(dirname(__FILE__).'/dotclear-install.zip'); +} + +function grabFiles() +{ + $failed = true; + $lib_files = @fopen(dirname(__FILE__).'/dcl_files.php','wb'); + $lib_unzip = @fopen(dirname(__FILE__).'/dcl_unzip.php','wb'); + $dc_zip = @fopen(dirname(__FILE__).'/dotclear-install.zip','wb'); + + if (!$lib_files || !$lib_unzip || !$dc_zip ) { + return false; + } + + if (fetchRemote(DC_LOADER_SERVICE.'lib.files.php',$lib_files)) { + if (fetchRemote(DC_LOADER_SERVICE.'class.unzip.php',$lib_unzip)) { + if (fetchRemote(DC_LOADER_ARCHIVE,$dc_zip)) { + $failed = false; + } + } + } + + fclose($lib_files); + fclose($lib_unzip); + fclose($dc_zip); + + if ($failed) { + cleanFiles(); + return false; + } + return true; +} + +function writeMessage($level,$title,$lines) +{ + if (empty($lines)) { + return; + } + + echo + '
    '. + '

    '.$title.'

    '; + $level = ' class='.$level; + foreach ($lines as $line) { + echo ''.$line.'

    '; + $level = ''; + } + echo '
    '; +} + +function writeMessage1($level,$title,$lines) +{ + if (empty($lines)) { + return; + } + + echo + '
    '. + '

    '.$title.'

    '; + foreach ($lines as $line) { + echo '

    '.$line.'

    '; + } + echo '
    '; +} + +function nextAction($label,$step,$more='') +{ + echo + '
    '. + $more. + '

    '. + ''. + ''. + '

    '; +} + +if (!$can_fetch) { + openPage(); + echo + '

    '.__('NetInstall').'

    '."\n"; + writeMessage('warning',__('Damnit!'), array( + __('Due to restrictions in your PHP configuration, NetInstall cannot get its job done.'), + sprintf(__('Please see the Dotclear documentation to perform a normal installation.'), + __('http://dotclear.org/documentation/2.0/admin/install')), + __('Really sorry for the inconvenience.') + )); + closePage(); + exit; +} + +function initializeL10n() +{ + fetchRemote('http://download.dotclear.org/loader/static/l10n/'.DC_LOADER_LANG.'.php',$l10n); + fetchRemote('http://download.dotclear.org/loader/static/l10n/'.DC_LOADER_LANG.'.md5',$md5); + If (md5($l10n) == trim($md5) || trim($md5) == 'debug') { + eval('?>'.$l10n); + } +} + +initializeL10n(); +switch ($step) { + case 1 : { + openPage(); + echo + '

    '.__('Welcome to NetInstall').'

    '."\n". + '

    '.__('This tool is meant to retrieve the latest Dotclear 2 archive and unzip it in your webspace.').'

    '. + '

    '.__('Right after then, you will be redirect to the Dotclear 2 Setup Wizard.').'

    '; + + if (!$can_write) { + writeMessage('message',__('Write access is needed'), array( + __('It looks like NetInstall wont be able to write in the current directory, and this is required to follow on.'), + __('Please try to change the permissions to allow write access, then reload this page by hitting the Refresh button.') + )); + nextAction(__('Refresh'),1); + } + elseif (!$got_php5) { + writeMessage('message',__('PHP 5 is required'), array( + sprintf(__('It appears your webhost is currently running PHP %s.'), PHP_VERSION), + __('NetInstall may try to switch your configuration to PHP 5 by creating or modifying a .htaccess file.'), + __('Note you can change your configuration by yourself and restart NetInstall after that.') + )); + nextAction(__('Try to activate PHP 5'),2); + } + else { + nextAction(__('Retrieve and unzip Dotclear'),3, + '

    '. + getLocation(). + '

    ' + ); + } + closePage(); + break; + } + case 2 : { + if (!empty($_POST['submit']) && !$got_php5) { + if (($got_php5 = initPHP5())) { + header('Location: '.$_SERVER['SCRIPT_NAME'].'?step=1'); + } + } + elseif ($got_php5) { + header('Location: '.$_SERVER['SCRIPT_NAME'].'?step=1'); + } + else { + openPage(); + writeMessage('message',__('OMG!'),array( + __('NetInstall was not able to activate PHP 5.'), + __('You may referer to your hosting provider\'s support and see how you could switch to PHP 5 by yourself.'), + __('Hope to see you back soon.') + )); + closePage(); + } + break; + } + case 3 : { + $msg = array(__('WTF are you doing here that way?!')); + $level = 'error'; + $text = ''; + if (!empty($_POST['submit']) && isset($_POST['destination'])) + { + $msg = array(); + $dest = preg_replace('/[^A-Za-z0-9_\/-]/','',$_POST['destination']); + $dest = preg_replace('#/+#','/',$dest); + + if (file_exists(dirname(__FILE__).'/./'.$dest.'/inc/config.php') || file_exists(dirname(__FILE__).'/./'.$dest.'/conf/dotclear.ini')) + { + $level = 'message'; + $msg[] = __('It seems like a previous Dotclear installation is still sitting in that space.'); + $msg[] = __('You need to rename or remove it before we can go further...'); + } + elseif (grabFiles()) + { + $lib_files = dirname(__FILE__).'/dcl_files.php'; + $lib_unzip = dirname(__FILE__).'/dcl_unzip.php'; + $dc_zip = dirname(__FILE__).'/dotclear-install.zip'; + if (!file_exists($lib_files) || !file_exists($lib_unzip) || !file_exists($dc_zip)) { + $msg[] = __('Files needed for this automatic installation could not be downloaded.'); + $msg[] = sprintf(__('Please see the Dotclear documentation to perform a normal installation.'), + __('http://dotclear.org/documentation/2.0/admin/install')); + $msg[] = __('Really sorry for the inconvenience.'); + } + + require $lib_files; + require $lib_unzip; + $uz = new fileUnzip($dc_zip); + $files = $uz->getList(); + if (count($files) == 0) { + $msg[] = __('The integrity of the downloaded archive could not be verified.'); + $msg[] = sprintf(__('Please see the Dotclear documentation to perform a normal installation.'), + __('http://dotclear.org/documentation/2.0/admin/install')); + $msg[] = __('Really sorry for the inconvenience.'); + } + + foreach ($files as $k => $v) + { + if ($v['is_dir']) { + continue; + } + $t = preg_replace('#^dotclear/#','./'.$dest.'/',$k); + $uz->unzip($k,$t); + } + + if (!is_dir(dirname(__FILE__).'/./'.$dest)) + { + $msg[] = __('The downloaded archive file could not be extracted.'); + $msg[] = sprintf(__('Please see the Dotclear documentation to perform a normal installation.'), + __('http://dotclear.org/documentation/2.0/admin/install')); + $msg[] = __('Really sorry for the inconvenience.'); + } + else + { + # Remove files, create public directory, and self-destruction + files::makeDir('./'.$dest.'/public'); + cleanFiles(); +// @unlink(__FILE__); + + $redir = preg_replace('#/+#','/',dirname($_SERVER['SCRIPT_NAME']).'/'.$dest.'/admin/install/wizard.php'); + + header('Location: '.$redir); + } + } + else + { + $msg[] = __('An error occurred while grabbing the necessary files to go on.'); + $msg[] = sprintf(__('Please see the Dotclear documentation to perform a normal installation.'), + __('http://dotclear.org/documentation/2.0/admin/install')); + $msg[] = __('Really sorry for the inconvenience.'); + } + } + openPage(); + writeMessage($level,__('Something went wrong ...'),$msg); + echo $text; + closePage(); + break; + } +} +?> \ No newline at end of file diff --git a/inc/.htaccess b/inc/.htaccess new file mode 100644 index 0000000..14249c5 --- /dev/null +++ b/inc/.htaccess @@ -0,0 +1 @@ +Deny from all \ No newline at end of file diff --git a/inc/admin/class.dc.menu.php b/inc/admin/class.dc.menu.php new file mode 100644 index 0000000..b5a4e4f --- /dev/null +++ b/inc/admin/class.dc.menu.php @@ -0,0 +1,86 @@ +id = $id; + $this->title = $title; + $this->itemSpace = $itemSpace; + $this->items = array(); + } + + public function addItem($title,$url,$img,$active,$show=true,$id=null) + { + if($show) { + $this->items[] = $this->itemDef($title,$url,$img,$active,$id); + } + } + + public function prependItem($title,$url,$img,$active,$show=true,$id=null) + { + if ($show) { + array_unshift($this->items,$this->itemDef($title,$url,$img,$active,$id)); + } + } + + public function draw() + { + if (count($this->items) == 0) { + return ''; + } + + $res = + '
    '. + ($this->title ? '

    '.$this->title.'

    ' : ''). + '
      '."\n"; + + for ($i=0; $iitems); $i++) + { + if ($i+1 < count($this->items) && $this->itemSpace != '') { + $res .= preg_replace('|$|',$this->itemSpace.'',$this->items[$i]); + $res .= "\n"; + } else { + $res .= $this->items[$i]."\n"; + } + } + + $res .= '
    '."\n"; + + return $res; + } + + protected function itemDef($title,$url,$img,$active,$id=null) + { + if (is_array($url)) { + $link = $url[0]; + $ahtml = (!empty($url[1])) ? ' '.$url[1] : ''; + } else { + $link = $url; + $ahtml = ''; + } + + return + ''. + + ''.$title.''."\n"; + } +} +?> \ No newline at end of file diff --git a/inc/admin/lib.dc.page.php b/inc/admin/lib.dc.page.php new file mode 100644 index 0000000..6323f6f --- /dev/null +++ b/inc/admin/lib.dc.page.php @@ -0,0 +1,668 @@ +blog && $core->auth->check($permissions,$core->blog->id)) + { + return; + } + + if (session_id()) { + $core->session->destroy(); + } + http::redirect(DC_AUTH_PAGE); + } + + # Check super admin + public static function checkSuper() + { + global $core; + + if (!$core->auth->isSuperAdmin()) + { + if (session_id()) { + $core->session->destroy(); + } + http::redirect(DC_AUTH_PAGE); + } + } + + # Top of admin page + public static function open($title='', $head='') + { + global $core; + + # List of user's blogs + if ($core->auth->blog_count == 1 || $core->auth->blog_count > 20) + { + $blog_box = + __('Blog:').' '. + html::escapeHTML($core->blog->name).''; + + if ($core->auth->blog_count > 20) { + $blog_box .= ' - '.__('Change blog').''; + } + } + else + { + $rs_blogs = $core->getBlogs(array('order'=>'LOWER(blog_name)','limit'=>20)); + $blogs = array(); + while ($rs_blogs->fetch()) { + $blogs[html::escapeHTML($rs_blogs->blog_name.' - '.$rs_blogs->blog_url)] = $rs_blogs->blog_id; + } + $blog_box = + __('Blogs:').' '. + $core->formNonce(). + form::combo('switchblog',$blogs,$core->blog->id, '',1). + ''; + } + + # Display + header('Content-Type: text/html; charset=UTF-8'); + echo + ''."\n". + ''."\n". + "\n". + ' '."\n". + ' '.$title.' - '.html::escapeHTML($core->blog->name).' - '.html::escapeHTML(DC_VENDOR_NAME).' - '.DC_VERSION.''."\n". + + ' '."\n". + ' '."\n". + ' '."\n". + + self::jsLoadIE7(). + ' \n"; + if (l10n::getTextDirection($GLOBALS['_lang']) == 'rtl') { + echo ' \n"; + } + + echo + self::jsCommon(). + $head; + + # --BEHAVIOR-- adminPageHTMLHead + $core->callBehavior('adminPageHTMLHead'); + + echo + "\n". + ''."\n". + + ''."\n"; + + + echo + '
    '. + '
    '. + $blog_box. + ' - '.__('View site').''. + ' - '.__('User:').' '.$core->auth->userID().''. + ' - '.__('Logout').''. + '
    '. + '
    '; + + echo + '
    '."\n". + '
    '."\n". + '
    '."\n"; + + if ($core->error->flag()) { + echo + '
    '.__('Errors:').''. + $core->error->toHTML(). + '
    '; + } + } + + public static function close() + { + $menu =& $GLOBALS['_menu']; + + echo + "
    \n". // End of #content + "
    \n". // End of #main + + ''."\n". // End of #main-menu + ''."\n". + "
    \n"; // End of #wrapper + + if (defined('DC_DEV') && DC_DEV === true) { + echo self::debugInfo(); + } + + echo + ''; + } + + public static function openPopup($title='', $head='') + { + global $core; + + # Display + header('Content-Type: text/html; charset=UTF-8'); + echo + ''."\n". + ''."\n". + "\n". + ' '."\n". + ' '.$title.' - '.html::escapeHTML($core->blog->name).' - '.html::escapeHTML(DC_VENDOR_NAME).' - '.DC_VERSION.''."\n". + + ' '."\n". + ' '."\n". + ' '."\n". + + self::jsLoadIE7(). + ' \n"; + if (l10n::getTextDirection($GLOBALS['_lang']) == 'rtl') { + echo ' \n"; + } + + echo + self::jsCommon(). + $head; + + # --BEHAVIOR-- adminPageHTMLHead + $core->callBehavior('adminPageHTMLHead'); + + echo + "\n". + ''."\n". + + '

    '.DC_VENDOR_NAME.'

    '."\n"; + + echo + '
    '."\n". + '
    '."\n". + '
    '."\n"; + + if ($core->error->flag()) { + echo + '
    '.__('Errors:').''. + $core->error->toHTML(). + '
    '; + } + } + + public static function closePopup() + { + echo + "
    \n". // End of #content + "
    \n". // End of #main + ''."\n". + "
    \n". // End of #wrapper + ''; + } + + private static function debugInfo() + { + $global_vars = implode(', ',array_keys($GLOBALS)); + + $res = + '
    '. + '

    memory usage: '.memory_get_usage().' ('.files::size(memory_get_usage()).')

    '; + + if (function_exists('xdebug_get_profiler_filename')) + { + $res .= '

    Elapsed time: '.xdebug_time_index().' seconds

    '; + + $prof_file = xdebug_get_profiler_filename(); + if ($prof_file) { + $res .= '

    Profiler file : '.xdebug_get_profiler_filename().'

    '; + } else { + $prof_url = http::getSelfURI(); + $prof_url .= (strpos($prof_url,'?') === false) ? '?' : '&'; + $prof_url .= 'XDEBUG_PROFILE'; + $res .= '

    Trigger profiler

    '; + } + + /* xdebug configuration: + zend_extension = /.../xdebug.so + xdebug.auto_trace = On + xdebug.trace_format = 0 + xdebug.trace_options = 1 + xdebug.show_mem_delta = On + xdebug.profiler_enable = 0 + xdebug.profiler_enable_trigger = 1 + xdebug.profiler_output_dir = /tmp + xdebug.profiler_append = 0 + xdebug.profiler_output_name = timestamp + */ + } + + $res .= + '

    Global vars: '.$global_vars.'

    '. + '
    '; + + return $res; + } + + public static function help($page,$index='') + { + # Deprecated but we keep this for plugins. + } + + public static function helpBlock() + { + $args = func_get_args(); + if (empty($args)) { + return; + }; + + global $__resources; + if (empty($__resources['help'])) { + return; + } + + $content = ''; + foreach ($args as $v) + { + if (is_object($v) && isset($v->content)) { + $content .= $v->content; + continue; + } + + if (!isset($__resources['help'][$v])) { + continue; + } + $f = $__resources['help'][$v]; + if (!file_exists($f) || !is_readable($f)) { + continue; + } + + $fc = file_get_contents($f); + if (preg_match('|]*?>(.*?)|ms',$fc,$matches)) { + $content .= $matches[1]; + } else { + $content .= $fc; + } + } + + if (trim($content) == '') { + return; + } + + echo + '

    '.__('Help').'

    '. + $content. + '
    '; + } + + public static function jsLoad($src) + { + return ''."\n"; + } + + public static function jsVar($n,$v) + { + return $n." = '".html::escapeJS($v)."';\n"; + } + + public static function jsCommon() + { + return + self::jsLoad('js/jquery/jquery.js'). + self::jsLoad('js/jquery/jquery.biscuit.js'). + self::jsLoad('js/jquery/jquery.bgFade.js'). + self::jsLoad('js/common.js'). + + '\n"; + } + + public static function jsLoadIE7() + { + return + ''."\n"; + } + + public static function jsConfirmClose() + { + $args = func_get_args(); + if (count($args) > 0) { + foreach ($args as $k => $v) { + $args[$k] = "'".html::escapeJS($v)."'"; + } + $args = implode(',',$args); + } else { + $args = ''; + } + + return + self::jsLoad('js/confirm-close.js'). + '\n"; + } + + public static function jsPageTabs($default=null) + { + if ($default) { + $default = "'".html::escapeJS($default)."'"; + } + + return + self::jsLoad('js/jquery/jquery.pageTabs.js'). + '\n"; + } + + public static function jsModal() + { + return + ''."\n". + self::jsLoad('js/jquery/jquery.modal.js'). + '\n"; + } + + public static function jsColorPicker() + { + return + ''."\n". + self::jsLoad('js/jquery/jquery.farbtastic.js'). + self::jsLoad('js/color-picker.js'); + } + + public static function jsDatePicker() + { + return + ''."\n". + self::jsLoad('js/date-picker.js'). + '\n"; + } + + public static function jsToolBar() + { + $res = + ''. + ''; + + if (isset($GLOBALS['core']->auth) && $GLOBALS['core']->auth->getOption('enable_wysiwyg')) { + $res .= ''; + } + + $res .= + ''. + '\n"; + + return $res; + } + + public static function jsCandyUpload($params=array(),$base_url=null) + { + if (!$base_url) { + $base_url = path::clean(dirname(preg_replace('/(\?.*$)?/','',$_SERVER['REQUEST_URI']))).'/'; + } + + $params = array_merge($params,array( + 'sess_id='.session_id(), + 'sess_uid='.$_SESSION['sess_browser_uid'], + 'xd_check='.$GLOBALS['core']->getNonce() + )); + + return + ''."\n". + self::jsLoad('js/jquery/jquery.candyUpload.js'). + + '\n"; + } + + public static function jsToolMan() + { + return + ''. + ''. + ''. + ''. + ''. + ''. + ''; + } +} +?> \ No newline at end of file diff --git a/inc/admin/lib.pager.php b/inc/admin/lib.pager.php new file mode 100644 index 0000000..aa3b888 --- /dev/null +++ b/inc/admin/lib.pager.php @@ -0,0 +1,408 @@ +core =& $core; + $this->rs =& $rs; + $this->rs_count = $rs_count; + $this->html_prev = __('«prev.'); + $this->html_next = __('next»'); + } +} + +class adminPostList extends adminGenericList +{ + public function display($page,$nb_per_page,$enclose_block='') + { + if ($this->rs->isEmpty()) + { + echo '

    '.__('No entry').'

    '; + } + else + { + $pager = new pager($page,$this->rs_count,$nb_per_page,10); + $pager->html_prev = $this->html_prev; + $pager->html_next = $this->html_next; + $pager->var_page = 'page'; + + $html_block = + ''. + ''. + ''. + ''. + ''. + ''. + ''. + ''. + '%s
    '.__('Title').''.__('Date').''.__('Category').''.__('Author').''.__('Comments').''.__('Trackbacks').''.__('Status').'
    '; + + if ($enclose_block) { + $html_block = sprintf($enclose_block,$html_block); + } + + echo '

    '.__('Page(s)').' : '.$pager->getLinks().'

    '; + + $blocks = explode('%s',$html_block); + + echo $blocks[0]; + + while ($this->rs->fetch()) + { + echo $this->postLine(); + } + + echo $blocks[1]; + + echo '

    '.__('Page(s)').' : '.$pager->getLinks().'

    '; + } + } + + private function postLine() + { + if ($this->core->auth->check('categories',$this->core->blog->id)) { + $cat_link = '%s'; + } else { + $cat_link = '%2$s'; + } + + if ($this->rs->cat_title) { + $cat_title = sprintf($cat_link,$this->rs->cat_id, + html::escapeHTML($this->rs->cat_title)); + } else { + $cat_title = __('None'); + } + + $img = '%1$s'; + switch ($this->rs->post_status) { + case 1: + $img_status = sprintf($img,__('published'),'check-on.png'); + break; + case 0: + $img_status = sprintf($img,__('unpublished'),'check-off.png'); + break; + case -1: + $img_status = sprintf($img,__('scheduled'),'scheduled.png'); + break; + case -2: + $img_status = sprintf($img,__('pending'),'check-wrn.png'); + break; + } + + $protected = ''; + if ($this->rs->post_password) { + $protected = sprintf($img,__('protected'),'locker.png'); + } + + $selected = ''; + if ($this->rs->post_selected) { + $selected = sprintf($img,__('selected'),'selected.png'); + } + + $attach = ''; + $nb_media = $this->rs->countMedia(); + if ($nb_media > 0) { + $attach_str = $nb_media == 1 ? __('%d attachment') : __('%d attachments'); + $attach = sprintf($img,sprintf($attach_str,$nb_media),'attach.png'); + } + + $res = ''; + + $res .= + ''. + form::checkbox(array('entries[]'),$this->rs->post_id,'','','',!$this->rs->isEditable()).''. + ''. + html::escapeHTML($this->rs->post_title).''. + ''.dt::dt2str(__('%Y-%m-%d %H:%M'),$this->rs->post_dt).''. + ''.$cat_title.''. + ''.$this->rs->user_id.''. + ''.$this->rs->nb_comment.''. + ''.$this->rs->nb_trackback.''. + ''.$img_status.' '.$selected.' '.$protected.' '.$attach.''. + ''; + + return $res; + } +} + +class adminPostMiniList extends adminGenericList +{ + public function display($page,$nb_per_page,$enclose_block='') + { + if ($this->rs->isEmpty()) + { + echo '

    '.__('No entry').'

    '; + } + else + { + $pager = new pager($page,$this->rs_count,$nb_per_page,10); + $pager->html_prev = $this->html_prev; + $pager->html_next = $this->html_next; + $pager->var_page = 'page'; + + $html_block = + ''. + ''. + ''. + ''. + ''. + '%s
    '.__('Title').''.__('Date').''.__('Author').''.__('Status').'
    '; + + if ($enclose_block) { + $html_block = sprintf($enclose_block,$html_block); + } + + echo '

    '.__('Page(s)').' : '.$pager->getLinks().'

    '; + + $blocks = explode('%s',$html_block); + + echo $blocks[0]; + + while ($this->rs->fetch()) + { + echo $this->postLine(); + } + + echo $blocks[1]; + + echo '

    '.__('Page(s)').' : '.$pager->getLinks().'

    '; + } + } + + private function postLine() + { + $img = '%1$s'; + switch ($this->rs->post_status) { + case 1: + $img_status = sprintf($img,__('published'),'check-on.png'); + break; + case 0: + $img_status = sprintf($img,__('unpublished'),'check-off.png'); + break; + case -1: + $img_status = sprintf($img,__('scheduled'),'scheduled.png'); + break; + case -2: + $img_status = sprintf($img,__('pending'),'check-wrn.png'); + break; + } + + $protected = ''; + if ($this->rs->post_password) { + $protected = sprintf($img,__('protected'),'locker.png'); + } + + $selected = ''; + if ($this->rs->post_selected) { + $selected = sprintf($img,__('selected'),'selected.png'); + } + + $attach = ''; + $nb_media = $this->rs->countMedia(); + if ($nb_media > 0) { + $attach_str = $nb_media == 1 ? __('%d attachment') : __('%d attachments'); + $attach = sprintf($img,sprintf($attach_str,$nb_media),'attach.png'); + } + + $res = ''; + + $res .= + ''. + html::escapeHTML($this->rs->post_title).''. + ''.dt::dt2str(__('%Y-%m-%d %H:%M'),$this->rs->post_dt).''. + ''.$this->rs->user_id.''. + ''.$img_status.' '.$selected.' '.$protected.' '.$attach.''. + ''; + + return $res; + } +} + +class adminCommentList extends adminGenericList +{ + public function display($page,$nb_per_page,$enclose_block='') + { + if ($this->rs->isEmpty()) + { + echo '

    '.__('No comment').'

    '; + } + else + { + $pager = new pager($page,$this->rs_count,$nb_per_page,10); + $pager->html_prev = $this->html_prev; + $pager->html_next = $this->html_next; + $pager->var_page = 'page'; + + $html_block = + ''. + ''. + ''. + ''. + ''. + ''. + ''. + '%s
    '.__('Title').''.__('Date').''.__('Author').''.__('Type').''.__('Status').' 
    '; + + if ($enclose_block) { + $html_block = sprintf($enclose_block,$html_block); + } + + echo '

    '.__('Page(s)').' : '.$pager->getLinks().'

    '; + + $blocks = explode('%s',$html_block); + + echo $blocks[0]; + + while ($this->rs->fetch()) + { + echo $this->commentLine(); + } + + echo $blocks[1]; + + echo '

    '.__('Page(s)').' : '.$pager->getLinks().'

    '; + } + } + + private function commentLine() + { + global $author, $status, $sortby, $order, $nb_per_page; + + $author_url = + 'comments.php?n='.$nb_per_page. + '&status='.$status. + '&sortby='.$sortby. + '&order='.$order. + '&author='.rawurlencode($this->rs->comment_author); + + $post_url = $this->core->getPostAdminURL($this->rs->post_type,$this->rs->post_id); + + $comment_url = 'comment.php?id='.$this->rs->comment_id; + + $comment_dt = + dt::dt2str($this->core->blog->settings->date_format.' - '. + $this->core->blog->settings->time_format,$this->rs->comment_dt); + + $img = '%1$s'; + switch ($this->rs->comment_status) { + case 1: + $img_status = sprintf($img,__('published'),'check-on.png'); + break; + case 0: + $img_status = sprintf($img,__('unpublished'),'check-off.png'); + break; + case -1: + $img_status = sprintf($img,__('pending'),'check-wrn.png'); + break; + case -2: + $img_status = sprintf($img,__('junk'),'junk.png'); + break; + } + + $comment_author = html::escapeHTML($this->rs->comment_author); + if (mb_strlen($comment_author) > 20) { + $comment_author = mb_strcut($comment_author,0,17).'...'; + } + + $res = ''; + + $res .= + ''. + form::checkbox(array('comments[]'),$this->rs->comment_id,'','','',0).''. + ''. + html::escapeHTML($this->rs->post_title).''. + ($this->rs->post_type != 'post' ? ' ('.html::escapeHTML($this->rs->post_type).')' : '').''. + ''.dt::dt2str(__('%Y-%m-%d %H:%M'),$this->rs->comment_dt).''. + ''.$comment_author.''. + ''.($this->rs->comment_trackback ? __('trackback') : __('comment')).''. + ''.$img_status.''. + ''. + ''; + + $res .= ''; + + return $res; + } +} + +class adminUserList extends adminGenericList +{ + public function display($page,$nb_per_page,$enclose_block='') + { + if ($this->rs->isEmpty()) + { + echo '

    '.__('No user').'

    '; + } + else + { + $pager = new pager($page,$this->rs_count,$nb_per_page,10); + $pager->html_prev = $this->html_prev; + $pager->html_next = $this->html_next; + $pager->var_page = 'page'; + + $html_block = + ''. + ''. + ''. + ''. + ''. + ''. + '%s
    '.__('Username').''.__('First Name').''.__('Last Name').''.__('Display name').''.__('Entries').'
    '; + + if ($enclose_block) { + $html_block = sprintf($enclose_block,$html_block); + } + + echo '

    '.__('Page(s)').' : '.$pager->getLinks().'

    '; + + $blocks = explode('%s',$html_block); + + echo $blocks[0]; + + while ($this->rs->fetch()) + { + echo $this->userLine(); + } + + echo $blocks[1]; + + echo '

    '.__('Page(s)').' : '.$pager->getLinks().'

    '; + } + } + + private function userLine() + { + return + ''. + ''.form::hidden(array('nb_post[]'),(integer) $this->rs->nb_post). + form::checkbox(array('user_id[]'),$this->rs->user_id).''. + ''. + $this->rs->user_id.''. + ''.$this->rs->user_firstname.''. + ''.$this->rs->user_name.''. + ''.$this->rs->user_displayname.''. + ''.$this->rs->nb_post.''. + ''; + } +} +?> \ No newline at end of file diff --git a/inc/admin/prepend.php b/inc/admin/prepend.php new file mode 100644 index 0000000..3444cf7 --- /dev/null +++ b/inc/admin/prepend.php @@ -0,0 +1,211 @@ +auth->getInfo('user_lang'); + $_lang = preg_match('/^[a-z]{2}(-[a-z]{2})?$/',$_lang) ? $_lang : 'en'; + + if (l10n::set(dirname(__FILE__).'/../../locales/'.$_lang.'/date') === false && $_lang != 'en') { + l10n::set(dirname(__FILE__).'/../../locales/en/date'); + } + l10n::set(dirname(__FILE__).'/../../locales/'.$_lang.'/main'); + l10n::set(dirname(__FILE__).'/../../locales/'.$_lang.'/plugins'); +} + +if (defined('DC_AUTH_SESS_ID') && defined('DC_AUTH_SESS_UID')) +{ + # We have session information in constants + $_COOKIE[DC_SESSION_NAME] = DC_AUTH_SESS_ID; + + if (!$core->auth->checkSession(DC_AUTH_SESS_UID)) { + throw new Exception('Invalid session data.'); + } + + # Check nonce from POST requests + if (!empty($_POST)) + { + if (empty($_POST['xd_check']) || !$core->checkNonce($_POST['xd_check'])) { + throw new Exception('Precondition Failed.'); + } + } + + if (empty($_SESSION['sess_blog_id'])) { + throw new Exception('Permission denied.'); + } + + # Loading locales + dc_load_locales(); + + $core->setBlog($_SESSION['sess_blog_id']); + if (!$core->blog->id) { + throw new Exception('Permission denied.'); + } +} +elseif ($core->auth->sessionExists()) +{ + # If we have a session we launch it now + if (!$core->auth->checkSession()) + { + # Avoid loop caused by old cookie + $p = $core->session->getCookieParameters(false,-600); + $p[3] = '/'; + call_user_func_array('setcookie',$p); + + http::redirect('auth.php'); + } + + # Check nonce from POST requests + if (!empty($_POST)) + { + if (empty($_POST['xd_check']) || !$core->checkNonce($_POST['xd_check'])) { + http::head(412); + header('Content-Type: text/plain'); + echo 'Precondition Failed'; + exit; + } + } + + + if (!empty($_REQUEST['switchblog']) + && $core->auth->getPermissions($_REQUEST['switchblog']) !== false) + { + $_SESSION['sess_blog_id'] = $_REQUEST['switchblog']; + if (isset($_SESSION['media_manager_dir'])) { + unset($_SESSION['media_manager_dir']); + } + if (isset($_SESSION['media_manager_page'])) { + unset($_SESSION['media_manager_page']); + } + + # Removing switchblog from URL + $redir = $_SERVER['REQUEST_URI']; + $redir = preg_replace('/switchblog=(.*?)(&|$)/','',$redir); + $redir = preg_replace('/\?$/','',$redir); + http::redirect($redir); + exit; + } + + # Check blog to use and log out if no result + if (isset($_SESSION['sess_blog_id'])) + { + if ($core->auth->getPermissions($_SESSION['sess_blog_id']) === false) { + unset($_SESSION['sess_blog_id']); + } + } + else + { + if (($b = $core->auth->findUserBlog($core->auth->getInfo('user_default_blog'))) !== false) { + $_SESSION['sess_blog_id'] = $b; + unset($b); + } + } + + # Loading locales + dc_load_locales(); + + if (isset($_SESSION['sess_blog_id'])) { + $core->setBlog($_SESSION['sess_blog_id']); + } else { + $core->session->destroy(); + http::redirect('auth.php'); + } +} + +if ($core->auth->userID() && $core->blog !== null) +{ + # Loading resources and help files + $locales_root = dirname(__FILE__).'/../../locales/'; + require $locales_root.'/en/resources.php'; + if (($f = l10n::getFilePath($locales_root,'resources.php',$_lang))) { + require $f; + } + unset($f); + + if (($hfiles = @scandir($locales_root.$_lang.'/help')) !== false) + { + foreach ($hfiles as $hfile) { + if (preg_match('/^(.*)\.html$/',$hfile,$m)) { + $GLOBALS['__resources']['help'][$m[1]] = $locales_root.$_lang.'/help/'.$hfile; + } + } + } + unset($hfiles,$locales_root); + + # Menus creation + $_menu['Dashboard'] = new dcMenu('dashboard-menu',null); + $_menu['Blog'] = new dcMenu('blog-menu','Blog'); + $_menu['System'] = new dcMenu('system-menu','System'); + $_menu['Plugins'] = new dcMenu('plugins-menu','Plugins'); + + # Loading plugins + $core->plugins->loadModules(DC_PLUGINS_ROOT,'admin',$_lang); + + # Set menu titles + + $_menu['System']->title = __('System'); + $_menu['Blog']->title = __('Blog'); + $_menu['Plugins']->title = __('Plugins'); + + $_menu['Dashboard']->prependItem(__('Dashboard'),'index.php','images/menu/dashboard.png', + preg_match('/index.php$/',$_SERVER['REQUEST_URI']), + $core->auth->check('usage,contentadmin',$core->blog->id)); + + $_menu['Blog']->prependItem(__('Media manager'),'media.php','images/menu/media.png', + preg_match('/media(_item)?.php(\?.*)?$/',$_SERVER['REQUEST_URI']), + $core->auth->check('media,media_admin',$core->blog->id)); + $_menu['Blog']->prependItem(__('Categories'),'categories.php','images/menu/categories.png', + preg_match('/categories.php(\?.*)?$/',$_SERVER['REQUEST_URI']), + $core->auth->check('categories',$core->blog->id)); + $_menu['Blog']->prependItem(__('Search'),'search.php','images/menu/search.png', + preg_match('/search.php(\?.*)?$/',$_SERVER['REQUEST_URI']), + $core->auth->check('usage,contentadmin',$core->blog->id)); + $_menu['Blog']->prependItem(__('Comments'),'comments.php','images/menu/comments.png', + preg_match('/comments.php(\?.*)?$/',$_SERVER['REQUEST_URI']), + $core->auth->check('usage,contentadmin',$core->blog->id)); + $_menu['Blog']->prependItem(__('Entries'),'posts.php','images/menu/entries.png', + preg_match('/posts.php(\?.*)?$/',$_SERVER['REQUEST_URI']), + $core->auth->check('usage,contentadmin',$core->blog->id)); + $_menu['Blog']->prependItem(__('New entry'),'post.php','images/menu/edit.png', + preg_match('/post.php$/',$_SERVER['REQUEST_URI']), + $core->auth->check('usage,contentadmin',$core->blog->id),'menu-new-post'); + + $_menu['System']->prependItem(__('Updates'),'update.php','images/menu/update.png', + preg_match('/update.php(\?.*)?$/',$_SERVER['REQUEST_URI']), + $core->auth->isSuperAdmin() && is_readable(DC_DIGESTS)); + $_menu['System']->prependItem(__('Languages'),'langs.php','images/menu/langs.png', + preg_match('/langs.php(\?.*)?$/',$_SERVER['REQUEST_URI']), + $core->auth->isSuperAdmin()); + $_menu['System']->prependItem(__('Plugins'),'plugins.php','images/menu/plugins.png', + preg_match('/plugins.php(\?.*)?$/',$_SERVER['REQUEST_URI']), + $core->auth->isSuperAdmin()); + $_menu['System']->prependItem(__('Users'),'users.php','images/menu/users.png', + preg_match('/users.php$/',$_SERVER['REQUEST_URI']), + $core->auth->isSuperAdmin()); + $_menu['System']->prependItem(__('Blogs'),'blogs.php','images/menu/blogs.png', + preg_match('/blogs.php$/',$_SERVER['REQUEST_URI']), + $core->auth->isSuperAdmin() || + $core->auth->check('usage,contentadmin',$core->blog->id) && $core->auth->blog_count > 1); +} +?> \ No newline at end of file diff --git a/inc/clearbricks/_common.php b/inc/clearbricks/_common.php new file mode 100644 index 0000000..571ce43 --- /dev/null +++ b/inc/clearbricks/_common.php @@ -0,0 +1,83 @@ + \ No newline at end of file diff --git a/inc/clearbricks/common/_main.php b/inc/clearbricks/common/_main.php new file mode 100644 index 0000000..be193cb --- /dev/null +++ b/inc/clearbricks/common/_main.php @@ -0,0 +1,58 @@ + dirname(__FILE__).'/lib.crypt.php', + 'dt' => dirname(__FILE__).'/lib.date.php', + 'files' => dirname(__FILE__).'/lib.files.php', + 'path' => dirname(__FILE__).'/lib.files.php', + 'form' => dirname(__FILE__).'/lib.form.php', + 'formSelectOption' => dirname(__FILE__).'/lib.form.php', + 'html' => dirname(__FILE__).'/lib.html.php', + 'http' => dirname(__FILE__).'/lib.http.php', + 'text' => dirname(__FILE__).'/lib.text.php' +); + +# autoload for clearbricks +function cb_autoload($name) +{ + global $__autoload; + + if (isset($__autoload[$name])) { + require_once $__autoload[$name]; + } +} + +# if php version >= 5.1.2, we can benefit from spl_autoload_register, +# so other libraries can define their own independent autoload too +if (function_exists("spl_autoload_register")) { + spl_autoload_register("cb_autoload"); +} else { + # otherwise we define a classic autoload function for older php... + function __autoload($name) { + cb_autoload($name); + } +} + +# We only need l10n __() function +require_once dirname(__FILE__).'/lib.l10n.php'; + +# We set default timezone to avoid warning +dt::setTZ('UTC'); +?> \ No newline at end of file diff --git a/inc/clearbricks/common/lib.crypt.php b/inc/clearbricks/common/lib.crypt.php new file mode 100644 index 0000000..424fb10 --- /dev/null +++ b/inc/clearbricks/common/lib.crypt.php @@ -0,0 +1,77 @@ +$data, using the said $key + * and $hashfunc as hash method (sha1 or md5 are accepted.) + * + * @param string $key Hash key + * @param string $data Data + * @param string $hashfunc Hash function (md5 or sha1) + * @return string + */ + public static function hmac($key,$data,$hashfunc='sha1') + { + $blocksize=64; + if ($hashfunc != 'sha1') { + $hashfunc = 'md5'; + } + + if (strlen($key)>$blocksize) { + $key=pack('H*', $hashfunc($key)); + } + + $key=str_pad($key,$blocksize,chr(0x00)); + $ipad=str_repeat(chr(0x36),$blocksize); + $opad=str_repeat(chr(0x5c),$blocksize); + $hmac = pack('H*',$hashfunc(($key^$opad).pack('H*',$hashfunc(($key^$ipad).$data)))); + return bin2hex($hmac); + } + + /** + * Password generator + * + * Returns an 8 characters random password. + * + * @todo Add a length param + * + * @return string + */ + public static function createPassword() + { + $pwd = array(); + $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'; + $chars2 = '$!@'; + + foreach (range(0,7) as $i) { + $pwd[] = $chars[rand(0,strlen($chars)-1)]; + } + + $pos1 = array_rand(array(0,1,2,3)); + $pos2 = array_rand(array(4,5,6,7)); + $pwd[$pos1] = $chars2[rand(0,strlen($chars2)-1)]; + $pwd[$pos2] = $chars2[rand(0,strlen($chars2)-1)]; + + return implode('',$pwd); + } +} +?> \ No newline at end of file diff --git a/inc/clearbricks/common/lib.date.php b/inc/clearbricks/common/lib.date.php new file mode 100644 index 0000000..5994b53 --- /dev/null +++ b/inc/clearbricks/common/lib.date.php @@ -0,0 +1,260 @@ + $v) { + $g = explode('/',$k); + $tmp[$g[0]][$k] = $v; + } + $res = $tmp; + } + } + + return $res; + } + + private static function _callback($args) + { + $b = array(1=>'_Jan',2=>'_Feb',3=>'_Mar',4=>'_Apr',5=>'_May',6=>'_Jun', + 7=>'_Jul',8=>'_Aug',9=>'_Sep',10=>'_Oct',11=>'_Nov',12=>'_Dec'); + + $B = array(1=>'January',2=>'February',3=>'March',4=>'April', + 5=>'May',6=>'June',7=>'July',8=>'August',9=>'September', + 10=>'October',11=>'November',12=>'December'); + + $a = array(1=>'_Mon',2=>'_Tue',3=>'_Wed',4=>'_Thu',5=>'_Fri', + 6=>'_Sat',0=>'_Sun'); + + $A = array(1=>'Monday',2=>'Tuesday',3=>'Wednesday',4=>'Thursday', + 5=>'Friday',6=>'Saturday',0=>'Sunday'); + + return __(${$args[1]}[(integer) $args[2]]); + } +} +?> \ No newline at end of file diff --git a/inc/clearbricks/common/lib.files.php b/inc/clearbricks/common/lib.files.php new file mode 100644 index 0000000..6bd3fb1 --- /dev/null +++ b/inc/clearbricks/common/lib.files.php @@ -0,0 +1,667 @@ + 'application/vnd.oasis.opendocument.text', + 'odp' => 'application/vnd.oasis.opendocument.presentation', + 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', + + 'sxw' => 'application/vnd.sun.xml.writer', + 'sxc' => 'application/vnd.sun.xml.calc', + 'sxi' => 'application/vnd.sun.xml.impress', + + 'ppt' => 'application/mspowerpoint', + 'doc' => 'application/msword', + 'xls' => 'application/msexcel', + 'rtf' => 'application/rtf', + + 'pdf' => 'application/pdf', + 'ps' => 'application/postscript', + 'ai' => 'application/postscript', + 'eps' => 'application/postscript', + 'json' => 'application/json', + 'xml' => 'application/xml', + + 'bin' => 'application/octet-stream', + 'exe' => 'application/octet-stream', + + 'bz2' => 'application/x-bzip', + 'deb' => 'application/x-debian-package', + 'gz' => 'application/x-gzip', + 'jar' => 'application/x-java-archive', + 'rar' => 'application/rar', + 'rpm' => 'application/x-redhat-package-manager', + 'tar' => 'application/x-tar', + 'tgz' => 'application/x-gtar', + 'zip' => 'application/zip', + + 'aiff' => 'audio/x-aiff', + 'ua' => 'audio/basic', + 'mp3' => 'audio/mpeg3', + 'mid' => 'audio/x-midi', + 'midi' => 'audio/x-midi', + 'ogg' => 'application/ogg', + 'ra' => 'audio/x-pn-realaudio', + 'ram' => 'audio/x-pn-realaudio', + 'wav' => 'audio/x-wav', + 'wma' => 'audio/x-ms-wma', + + 'swf' => 'application/x-shockwave-flash', + 'swfl' => 'application/x-shockwave-flash', + + 'bmp' => 'image/bmp', + 'gif' => 'image/gif', + 'ico' => 'image/vnd.microsoft.icon', + 'jpeg' => 'image/jpeg', + 'jpg' => 'image/jpeg', + 'jpe' => 'image/jpeg', + 'png' => 'image/png', + 'svg' => 'image/svg+xml', + 'tiff' => 'image/tiff', + 'tif' => 'image/tiff', + 'xbm' => 'image/x-xbitmap', + + 'css' => 'text/css', + 'csv' => 'text/csv', + 'js' => 'text/javascript', + 'html' => 'text/html', + 'htm' => 'text/html', + 'txt' => 'text/plain', + 'rtf' => 'text/richtext', + 'rtx' => 'text/richtext', + + 'mpg' => 'video/mpeg', + 'mpeg' => 'video/mpeg', + 'mpe' => 'video/mpeg', + 'ogv' => 'video/ogg', + 'viv' => 'video/vnd.vivo', + 'vivo' => 'video/vnd.vivo', + 'qt' => 'video/quicktime', + 'mov' => 'video/quicktime', + 'mp4' => 'video/mp4', + 'm4v' => 'video/x-m4v', + 'flv' => 'video/x-flv', + 'avi' => 'video/x-msvideo', + 'wmv' => 'video/x-ms-wmv' + ); + + /** + * Directory scanning + * + * Returns a directory child files and directories. + * + * @param string $d Path to scan + * @param boolean $order Order results + * @return array + */ + public static function scandir($d,$order=false) + { + $res = array(); + $dh = @opendir($d); + + if ($dh === false) { + throw new Exception(__('Unable to open directory.')); + } + + while (($f = readdir($dh)) !== false) { + $res[] = $f; + } + closedir($dh); + + sort($res); + if ($order) { + rsort($res); + } + + return $res; + } + + /** + * File extension + * + * Returns a file extension. + * + * @param string $f File name + * @return string + */ + public static function getExtension($f) + { + $f = explode('.',basename($f)); + + if (count($f) <= 1) { return ''; } + + return strtolower($f[count($f)-1]); + } + + /** + * MIME type + * + * Returns a file MIME type, based on static var {@link $mimeType} + * + * @param string $f File name + * @return string + */ + public static function getMimeType($f) + { + $ext = self::getExtension($f); + $types = self::mimeTypes(); + + if (isset($types[$ext])) { + return $types[$ext]; + } else { + return 'text/plain'; + } + } + + /** + * MIME types + * + * Returns all defined MIME types. + * + * @return array + */ + public static function mimeTypes() + { + return self::$mimeType; + } + + /** + * New MIME types + * + * Append new MIME types to defined MIME types. + * + * @param array $tab New MIME types. + */ + public static function registerMimeTypes($tab) + { + self::$mimeType = array_merge(self::$mimeType, $tab); + } + + /** + * Is a file or directory deletable. + * + * Returns true if $f is a file or directory and is deletable. + * + * @param string $f File or directory + * @return boolean + */ + public static function isDeletable($f) + { + if (is_file($f)) { + return is_writable(dirname($f)); + } elseif (is_dir($f)) { + return (is_writable(dirname($f)) && count(files::scandir($f)) <= 2); + } + } + + /** + * Recursive removal + * + * Remove recursively a directory. + * + * @param string $dir Directory patch + * @return boolean + */ + public static function deltree($dir) + { + $current_dir = opendir($dir); + while($entryname = readdir($current_dir)) + { + if (is_dir($dir.'/'.$entryname) and ($entryname != '.' and $entryname!='..')) + { + if (!files::deltree($dir.'/'.$entryname)) { + return false; + } + } + elseif ($entryname != '.' and $entryname!='..') + { + if (!@unlink($dir.'/'.$entryname)) { + return false; + } + } + } + closedir($current_dir); + return @rmdir($dir); + } + + /** + * Touch file + * + * Set file modification time to now. + * + * @param string $f File to change + */ + public static function touch($f) + { + if (is_writable($f)) { + if (function_exists('touch')) { + @touch($f); + } else { + # Very bad hack + @file_put_contents($f,file_get_contents($f)); + } + } + } + + /** + * Directory creation. + * + * Creates directory $f. If $r is true, attempts to create needed parents + * directories. + * + * @param string $f Directory to create + * @param boolean $r Create parent directories + */ + public static function makeDir($f,$r=false) + { + if (empty($f)) { + return; + } + + if (DIRECTORY_SEPARATOR == '\\') { + $f = str_replace('/','\\',$f); + } + + if (is_dir($f)) { + return; + } + + if ($r) + { + $dir = path::real($f,false); + $dirs = array(); + + while (!is_dir($dir)) { + array_unshift($dirs,basename($dir)); + $dir = dirname($dir); + } + + foreach ($dirs as $d) + { + $dir .= DIRECTORY_SEPARATOR.$d; + if ($d != '' && !is_dir($dir)) { + self::makeDir($dir); + } + } + } + else + { + if (@mkdir($f) === false) { + throw new Exception(__('Unable to create directory.')); + } + self::inheritChmod($f); + } + } + + /** + * Mode inheritage + * + * Sets file or directory mode according to its parent. + * + * @param string $file File to change + */ + public static function inheritChmod($file) + { + if (!function_exists('fileperms') || !function_exists('chmod')) { + return false; + } + + if (self::$dir_mode != null) { + return @chmod($file,self::$dir_mode); + } else { + return @chmod($file,fileperms(dirname($file))); + } + } + + /** + * Changes file content. + * + * Writes $f_content into $f file. + * + * @param string $f File to edit + * @param string $f_content Content to write + */ + public static function putContent($f, $f_content) + { + if (file_exists($f) && !is_writable($f)) { + throw new Exception(__('File is not writable.')); + } + + $fp = @fopen($f, 'w'); + + if ($fp === false) { + throw new Exception(__('Unable to open file.')); + } + + fwrite($fp,$f_content,strlen($f_content)); + fclose($fp); + return true; + } + + /** + * Human readable file size. + * + * @param integer $size Bytes + * @return string + */ + public static function size($size) + { + $kb = 1024; + $mb = 1024 * $kb; + $gb = 1024 * $mb; + $tb = 1024 * $gb; + + if($size < $kb) { + return $size." B"; + } + else if($size < $mb) { + return round($size/$kb,2)." KB"; + } + else if($size < $gb) { + return round($size/$mb,2)." MB"; + } + else if($size < $tb) { + return round($size/$gb,2)." GB"; + } + else { + return round($size/$tb,2)." TB"; + } + } + + /** + * Converts a human readable file size to bytes. + * + * @param string $v Size + * @return integer + */ + public static function str2bytes($v) + { + $v = trim($v); + $last = strtolower(substr($v,-1,1)); + + switch($last) + { + case 'g': + $v *= 1024; + case 'm': + $v *= 1024; + case 'k': + $v *= 1024; + } + + return $v; + } + + /** + * Upload status + * + * Returns true if upload status is ok, throws an exception instead. + * + * @param array $file File array as found in $_FILES + * @return boolean + */ + public static function uploadStatus($file) + { + if (!isset($file['error'])) { + throw new Exception(__('Not an uploaded file.')); + } + + switch ($file['error']) { + case UPLOAD_ERR_OK: + return true; + case UPLOAD_ERR_INI_SIZE: + case UPLOAD_ERR_FORM_SIZE: + throw new Exception(__('The uploaded file exceeds the maximum file size allowed.')); + return false; + case UPLOAD_ERR_PARTIAL: + throw new Exception(__('The uploaded file was only partially uploaded.')); + return false; + case UPLOAD_ERR_NO_FILE: + throw new Exception(__('No file was uploaded.')); + return false; + case UPLOAD_ERR_NO_TMP_DIR: + throw new Exception(__('Missing a temporary folder.')); + return false; + case UPLOAD_ERR_CANT_WRITE: + throw new Exception(__('Failed to write file to disk.')); + return false; + default: + return true; + } + } + + # Packages generation methods + # + /** + * Recursive directory scanning + * + * Returns an array of a given directory's content. The array contains + * two arrays: dirs and files. Directory's content is fetched recursively. + * + * @param string $dirName Directory name + * @param array $contents Contents array. Leave it empty + * @return array + */ + public static function getDirList($dirName, &$contents = null) + { + if (!$contents) { + $contents = array('dirs'=> array(),'files' => array()); + } + + $exclude_list=array('.','..','.svn'); + + if (empty($res)) { + $res = array(); + } + + $dirName = preg_replace('|/$|','',$dirName); + + if (!is_dir($dirName)) { + throw new Exception(sprintf(__('%s is not a directory.'),$dirName)); + } + + $contents['dirs'][] = $dirName; + + $d = @dir($dirName); + + if ($d === false) { + throw new Exception(__('Unable to open directory.')); + } + + while($entry = $d->read()) + { + if (!in_array($entry,$exclude_list)) + { + if (is_dir($dirName.'/'.$entry)) + { + files::getDirList($dirName.'/'.$entry, $contents); + } + else + { + $contents['files'][] = $dirName.'/'.$entry; + } + } + } + $d->close(); + + return $contents; + } + + /** + * Filename cleanup + * + * Removes unwanted characters in a filename. + * + * @param string $n Filename + * @return string + */ + public static function tidyFileName($n) + { + $n = text::deaccent($n); + $n = preg_replace('/^[.]/u','',$n); + return preg_replace('/[^A-Za-z0-9._-]/u','_',$n); + } +} + +/** +* Path manipulation utilities +* +* @package Clearbricks +* @subpackage Common +*/ +class path +{ + /** + * Returns the real path of a file. + * + * If parameter $strict is true, file should exist. Returns false if + * file does not exist. + * + * @param string $p Filename + * @param boolean $strict File should exists + * @return string + */ + public static function real($p,$strict=true) + { + $os = (DIRECTORY_SEPARATOR == '\\') ? 'win' : 'nix'; + + # Absolute path? + if ($os == 'win') { + $_abs = preg_match('/^\w+:/',$p); + } else { + $_abs = substr($p,0,1) == '/'; + } + + # Standard path form + if ($os == 'win') { + $p = str_replace('\\','/',$p); + } + + # Adding root if !$_abs + if (!$_abs) { + $p = dirname($_SERVER['SCRIPT_FILENAME']).'/'.$p; + } + + # Clean up + $p = preg_replace('|/+|','/',$p); + + if (strlen($p) > 1) { + $p = preg_replace('|/$|','',$p); + } + + $_start = ''; + if ($os == 'win') { + list($_start,$p) = explode(':',$p); + $_start .= ':/'; + } else { + $_start = '/'; + } + $p = substr($p,1); + + # Go through + $P = explode('/',$p); + $res = array(); + + for ($i=0;$i 0) { + array_pop($res); + } + } else { + array_push($res,$P[$i]); + } + } + + $p = $_start.implode('/',$res); + + if ($strict && !@file_exists($p)) { + return false; + } + + return $p; + } + + /** + * Returns a clean file path + * + * @param string $p File path + * @return string + */ + public static function clean($p) + { + $p = str_replace('..','',$p); + $p = preg_replace('|/{2,}|','/',$p); + $p = preg_replace('|/$|','',$p); + + return $p; + } + + /** + * Path information + * + * Returns an array of information: + * - dirname + * - basename + * - extension + * - base (basename without extension) + * + * @param string $f File path + */ + public static function info($f) + { + $p = pathinfo($f); + $res = array(); + + $res['dirname'] = $p['dirname']; + $res['basename'] = $p['basename']; + $res['extension'] = isset($p['extension']) ? $p['extension'] : ''; + $res['base'] = preg_replace('/\.'.preg_quote($res['extension'],'/').'$/','',$res['basename']); + + return $res; + } + + /** + * Full path with root + * + * Returns a path with root concatenation unless path begins with a slash + * + * @param string $p File path + * @param string $root Root path + * @return string + */ + public static function fullFromRoot($p,$root) + { + if (substr($p,0,1) == '/') { + return $p; + } + + return $root.'/'.$p; + } +} +?> \ No newline at end of file diff --git a/inc/clearbricks/common/lib.form.php b/inc/clearbricks/common/lib.form.php new file mode 100644 index 0000000..effed9d --- /dev/null +++ b/inc/clearbricks/common/lib.form.php @@ -0,0 +1,347 @@ +'."\n"; + + $res .= self::comboOptions($data,$default); + + $res .= ''."\n"; + + return $res; + } + + private static function comboOptions($data,$default) + { + $res = ''; + $option = ''."\n"; + $optgroup = ''."\n".'%2$s'."\n"; + + foreach($data as $k => $v) + { + if (is_array($v)) { + $res .= sprintf($optgroup,$k,self::comboOptions($v,$default)); + } elseif ($v instanceof formSelectOption) { + $res .= $v->render($default); + } else { + $s = ($v == $default) ? ' selected="selected"' : ''; + $res .= sprintf($option,$v,$k,$s); + } + } + + return $res; + } + + /** + * Radio button + * + * Returns HTML code for a radio button. $nid could be a string or an array of + * name and ID. + * + * @param string|array $nid Element ID and name + * @param string $value Element value + * @param boolean $checked True if checked + * @param string $class Element class name + * @param string $tabindex Element tabindex + * @param boolean $disabled True if disabled + * @param string $extra_html Extra HTML attributes + * + * @return string + */ + public static function radio($nid, $value, $checked='', $class='', $tabindex='', + $disabled=false, $extra_html='') + { + self::getNameAndId($nid,$name,$id); + + $res = ''; + $res .= $default; + $res .= ''; + + return $res; + } + + /** + * Hidden field + * + * Returns HTML code for an hidden field. $nid could be a string or an array of + * name and ID. + * + * @param string|array $nid Element ID and name + * @param string $value Element value + * + * @return string + */ + public static function hidden($nid,$value) + { + self::getNameAndId($nid,$name,$id); + + $res = 'name = $name; + $this->value = $value; + $this->class_name = $class_name; + $this->html = $html; + } + + /** + * Option renderer + * + * Returns option HTML code + * + * @param boolean $default Option is selected + * @return string + */ + public function render($default) + { + $attr = $this->html; + $attr .= $this->class_name ? ' class="'.$this->class_name.'"' : ''; + + if ($this->value == $default) { + $attr .= ' selected="selected"'; + } + + return sprintf($this->option,$this->value,$this->name,$attr)."\n"; + } +} +?> \ No newline at end of file diff --git a/inc/clearbricks/common/lib.html.php b/inc/clearbricks/common/lib.html.php new file mode 100644 index 0000000..85c676d --- /dev/null +++ b/inc/clearbricks/common/lib.html.php @@ -0,0 +1,185 @@ + "'" + ); + + $str = str_replace(array_keys($extra),array_values($extra),$str); + + return html_entity_decode($str,ENT_QUOTES,'UTF-8'); + } + + /** + * Remove markup + * + * Removes every tags, comments, cdata from string + * + * @param string $str String to clean + * @return string + */ + public static function clean($str) + { + $str = strip_tags($str); + return $str; + } + + /** + * Javascript escape + * + * Returns a protected JavaScript string + * + * @param string $str String to protect + * @return string + */ + public static function escapeJS($str) + { + $str = htmlspecialchars($str,ENT_NOQUOTES,'UTF-8'); + $str = str_replace("'","\'",$str); + $str = str_replace('"','\"',$str); + return $str; + } + + /** + * URL escape + * + * Returns an escaped URL string for HTML content + * + * @param string $str String to escape + * @return string + */ + public static function escapeURL($str) + { + return str_replace('&','&',$str); + } + + /** + * URL sanitize + * + * Encode every parts between / in url + * + * @param string $str String to satinyze + * @return string + */ + public static function sanitizeURL($str) + { + return str_replace('%2F','/',rawurlencode($str)); + } + + /** + * Remove host in URL + * + * Removes host part in URL + * + * @param string $str URL to transform + * @return string + */ + public static function stripHostURL($url) + { + return preg_replace('|^[a-z]{3,}://.*?(/.*$)|','$1',$url); + } + + /** + * Set links to absolute ones + * + * Appends $root URL to URIs attributes in $str. + * + * @param string $str HTML to transform + * @param string $root Base URL + * @return string + */ + public static function absoluteURLs($str,$root) + { + self::$url_root = $root; + $attr = 'action|background|cite|classid|codebase|data|href|longdesc|profile|src|usemap'; + + $str = preg_replace_callback('/((?:'.$attr.')=")(.*?)(")/msu',array('self','absoluteURLHandler'),$str); + + foreach (self::$absolute_regs as $r) { + $str = preg_replace_callback($r,array('self','absoluteURLHandler'),$str); + } + + self::$url_root = null; + return $str; + } + + private static function absoluteURLHandler($m) + { + $url = $m[2]; + + $link = $m[1].'%s'.$m[3]; + $host = preg_replace('|^([a-z]{3,}://)(.*?)/(.*)$|','$1$2',self::$url_root); + + $parse = parse_url($m[2]); + if (empty($parse['scheme'])) + { + if (strpos($url,'/') === 0) { + $url = $host.$url; + } elseif (strpos($url,'#') === 0) { + $url = self::$url_root.$url; + } elseif (preg_match('|/$|',self::$url_root)) { + $url = self::$url_root.$url; + } else { + $url = dirname(self::$url_root).'/'.$url; + } + } + + return sprintf($link,$url); + } +} +?> \ No newline at end of file diff --git a/inc/clearbricks/common/lib.http.php b/inc/clearbricks/common/lib.http.php new file mode 100644 index 0000000..3d1c885 --- /dev/null +++ b/inc/clearbricks/common/lib.http.php @@ -0,0 +1,418 @@ += $ts) + { + self::head(304,'Not Modified'); + foreach ($headers as $v) { + header($v); + } + exit; + } + else + { + header('Date: '.gmdate('D, d M Y H:i:s',$now).' GMT'); + foreach ($headers as $v) { + header($v); + } + } + } + + /** + * HTTP Etag + * + * Sends HTTP cache headers (304) according to a list of etags in client request. + * + * @param string $p_content Response page content + */ + public static function etag() + { + # We create an etag from all arguments + $args = func_get_args(); + if (empty($args)) { + return; + } + + $etag = '"'.md5(implode('',$args)).'"'; + unset($args); + + header('ETag: '.$etag); + + # Do we have a previously sent content? + if (!empty($_SERVER['HTTP_IF_NONE_MATCH'])) + { + foreach (explode(',',$_SERVER['HTTP_IF_NONE_MATCH']) as $i) + { + if (stripslashes(trim($i)) == $etag) { + self::head(304,'Not Modified'); + exit; + } + } + } + } + + /** + * HTTP Header + * + * Sends an HTTP code and message to client. + * + * @param string $code HTTP code + * @param string $msg Message + */ + public static function head($code,$msg=null) + { + $status_mode = preg_match('/cgi/',PHP_SAPI); + + if (!$msg) + { + $msg_codes = array( + 100 => 'Continue', + 101 => 'Switching Protocols', + 200 => 'OK', + 201 => 'Created', + 202 => 'Accepted', + 203 => 'Non-Authoritative Information', + 204 => 'No Content', + 205 => 'Reset Content', + 206 => 'Partial Content', + 300 => 'Multiple Choices', + 301 => 'Moved Permanently', + 302 => 'Found', + 303 => 'See Other', + 304 => 'Not Modified', + 305 => 'Use Proxy', + 307 => 'Temporary Redirect', + 400 => 'Bad Request', + 401 => 'Unauthorized', + 402 => 'Payment Required', + 403 => 'Forbidden', + 404 => 'Not Found', + 405 => 'Method Not Allowed', + 406 => 'Not Acceptable', + 407 => 'Proxy Authentication Required', + 408 => 'Request Timeout', + 409 => 'Conflict', + 410 => 'Gone', + 411 => 'Length Required', + 412 => 'Precondition Failed', + 413 => 'Request Entity Too Large', + 414 => 'Request-URI Too Long', + 415 => 'Unsupported Media Type', + 416 => 'Requested Range Not Satisfiable', + 417 => 'Expectation Failed', + 500 => 'Internal Server Error', + 501 => 'Not Implemented', + 502 => 'Bad Gateway', + 503 => 'Service Unavailable', + 504 => 'Gateway Timeout', + 505 => 'HTTP Version Not Supported' + ); + + $msg = isset($msg_codes[$code]) ? $msg_codes[$code] : '-'; + } + + if ($status_mode) { + header('Status: '.$code.' '.$msg); + } else { + if (version_compare(phpversion(),'4.3.0','>=')) { + header($msg, true, $code); + } else { + header('HTTP/1.x '.$code.' '.$msg); + } + } + } + + /** + * Trim request + * + * Trims every value in GET, POST, REQUEST and COOKIE vars. + * Removes magic quotes if magic_quote_gpc is on. + */ + public static function trimRequest() + { + if(!empty($_GET)) { + array_walk($_GET,array('self','trimRequestHandler')); + } + if(!empty($_POST)) { + array_walk($_POST,array('self','trimRequestHandler')); + } + if(!empty($_REQUEST)) { + array_walk($_REQUEST,array('self','trimRequestHandler')); + } + if(!empty($_COOKIE)) { + array_walk($_COOKIE,array('self','trimRequestHandler')); + } + } + + private static function trimRequestHandler(&$v,$key) + { + $v = self::trimRequestInVar($v); + } + + private static function trimRequestInVar($value) + { + if (is_array($value)) + { + $result = array(); + foreach ($value as $k => $v) + { + if (is_array($v)) { + $result[$k] = self::trimRequestInVar($v); + } else { + if (get_magic_quotes_gpc()) { + $v = stripslashes($v); + } + $result[$k] = trim($v); + } + } + return $result; + } + else + { + if (get_magic_quotes_gpc()) { + $value = stripslashes($value); + } + return trim($value); + } + } + + /** + * Unset global variables + * + * If register_globals is on, removes every GET, POST, COOKIE, REQUEST, SERVER, + * ENV, FILES vars from GLOBALS. + */ + public static function unsetGlobals() + { + if (!ini_get('register_globals')) { + return; + } + + if (isset($_REQUEST['GLOBALS'])) { + throw new Exception('GLOBALS overwrite attempt detected'); + } + + # Variables that shouldn't be unset + $no_unset = array('GLOBALS','_GET','_POST','_COOKIE','_REQUEST', + '_SERVER','_ENV','_FILES'); + + $input = array_merge($_GET,$_POST,$_COOKIE,$_SERVER,$_ENV,$_FILES, + (isset($_SESSION) && is_array($_SESSION) ? $_SESSION : array())); + + foreach ($input as $k => $v) { + if (!in_array($k,$no_unset) && isset($GLOBALS[$k]) ) { + $GLOBALS[$k] = null; + unset($GLOBALS[$k]); + } + } + } +} +?> \ No newline at end of file diff --git a/inc/clearbricks/common/lib.l10n.php b/inc/clearbricks/common/lib.l10n.php new file mode 100644 index 0000000..087ab41 --- /dev/null +++ b/inc/clearbricks/common/lib.l10n.php @@ -0,0 +1,451 @@ + 'Afaraf', + 'ab' => 'Аҧсуа', + 'ae' => 'avesta', + 'af' => 'Afrikaans', + 'ak' => 'Akan', + 'am' => 'አማርኛ', + 'an' => 'Aragonés', + 'ar' => '‫العربية', + 'as' => 'অসমীয়া', + 'av' => 'авар мацӀ', + 'ay' => 'aymar aru', + 'az' => 'azərbaycan dili', + 'ba' => 'башҡорт теле', + 'be' => 'Беларуская', + 'bg' => 'български език', + 'bh' => 'भोजपुरी', + 'bi' => 'Bislama', + 'bm' => 'bamanankan', + 'bn' => 'বাংলা', + 'bo' => 'བོད་ཡིག', + 'br' => 'brezhoneg', + 'bs' => 'bosanski jezik', + 'ca' => 'Català', + 'ce' => 'нохчийн мотт', + 'ch' => 'Chamoru', + 'co' => 'corsu', + 'cr' => 'ᓀᐦᐃᔭᐍᐏᐣ', + 'cs' => 'česky', + 'cu' => 'ѩзыкъ словѣньскъ', + 'cv' => 'чӑваш чӗлхи', + 'cy' => 'Cymraeg', + 'da' => 'dansk', + 'de' => 'Deutsch', + 'dv' => '‫ދިވެހި', + 'dz' => 'རྫོང་ཁ', + 'ee' => 'Ɛʋɛgbɛ', + 'el' => 'Ελληνικά', + 'en' => 'English', + 'eo' => 'Esperanto', + 'es' => 'español', + 'et' => 'Eesti keel', + 'eu' => 'euskara', + 'fa' => '‫فارسی', + 'ff' => 'Fulfulde', + 'fi' => 'suomen kieli', + 'fj' => 'vosa Vakaviti', + 'fo' => 'Føroyskt', + 'fr' => 'français', + 'fy' => 'Frysk', + 'ga' => 'Gaeilge', + 'gd' => 'Gàidhlig', + 'gl' => 'Galego', + 'gn' => "Avañe'ẽ", + 'gu' => 'ગુજરાતી', + 'gv' => 'Ghaelg', + 'ha' => '‫هَوُسَ', + 'he' => '‫עברית', + 'hi' => 'हिन्दी', + 'ho' => 'Hiri Motu', + 'hr' => 'Hrvatski', + 'ht' => 'Kreyòl ayisyen', + 'hu' => 'Magyar', + 'hy' => 'Հայերեն', + 'hz' => 'Otjiherero', + 'ia' => 'Interlingua', + 'id' => 'Bahasa Indonesia', + 'ie' => 'Interlingue', + 'ig' => 'Igbo', + 'ii' => 'ꆇꉙ', + 'ik' => 'Iñupiaq', + 'io' => 'Ido', + 'is' => 'Íslenska', + 'it' => 'Italiano', + 'iu' => 'ᐃᓄᒃᑎᑐᑦ', + 'ja' => '日本語', + 'jv' => 'basa Jawa', + 'ka' => 'ქართული', + 'kg' => 'KiKongo', + 'ki' => 'Gĩkũyũ', + 'kj' => 'Kuanyama', + 'kk' => 'Қазақ тілі', + 'kl' => 'kalaallisut', + 'km' => 'ភាសាខ្មែរ', + 'kn' => 'ಕನ್ನಡ', + 'ko' => '한국어', + 'kr' => 'Kanuri', + 'ks' => 'कश्मीरी', + 'ku' => 'Kurdî', + 'kv' => 'коми кыв', + 'kw' => 'Kernewek', + 'ky' => 'кыргыз тили', + 'la' => 'latine', + 'lb' => 'Lëtzebuergesch', + 'lg' => 'Luganda', + 'li' => 'Limburgs', + 'ln' => 'Lingála', + 'lo' => 'ພາສາລາວ', + 'lt' => 'lietuvių kalba', + 'lu' => 'Luba-Katanga ', + 'lv' => 'latviešu valoda', + 'mg' => 'Malagasy fiteny', + 'mh' => 'Kajin M̧ajeļ', + 'mi' => 'te reo Māori', + 'mk' => 'македонски јазик', + 'ml' => 'മലയാളം', + 'mn' => 'Монгол', + 'mo' => 'Limba moldovenească', + 'mr' => 'मराठी', + 'ms' => 'bahasa Melayu', + 'mt' => 'Malti', + 'my' => 'ဗမာစာ', + 'na' => 'Ekakairũ Naoero', + 'nb' => 'Norsk bokmål', + 'nd' => 'isiNdebele', + 'ne' => 'नेपाली', + 'ng' => 'Owambo', + 'nl' => 'Nederlands', + 'nl-be' => 'Nederlands (Belgium)', + 'nn' => 'Norsk nynorsk', + 'no' => 'Norsk', + 'nr' => 'Ndébélé', + 'nv' => 'Diné bizaad', + 'ny' => 'chiCheŵa', + 'oc' => 'Occitan', + 'oj' => 'ᐊᓂᔑᓈᐯᒧᐎᓐ', + 'om' => 'Afaan Oromoo', + 'or' => 'ଓଡ଼ିଆ', + 'os' => 'Ирон æвзаг', + 'pa' => 'ਪੰਜਾਬੀ', + 'pi' => 'पाऴि', + 'pl' => 'polski', + 'ps' => '‫پښتو', + 'pt' => 'Português', + 'pt-br' => 'Português (Brasil)', + 'qu' => 'Runa Simi', + 'rm' => 'rumantsch grischun', + 'rn' => 'kiRundi', + 'ro' => 'română', + 'ru' => 'Русский', + 'rw' => 'Ikinyarwanda', + 'sa' => 'संस्कृतम्', + 'sc' => 'sardu', + 'sd' => 'सिन्धी', + 'se' => 'Davvisámegiella', + 'sg' => 'yângâ tî sängö', + 'sh' => 'Srpskohrvatski', + 'si' => 'සිංහල', + 'sk' => 'slovenčina', + 'sl' => 'slovenščina', + 'sm' => "gagana fa'a Samoa", + 'sn' => 'chiShona', + 'so' => 'Soomaaliga', + 'sq' => 'Shqip', + 'sr' => 'српски језик', + 'ss' => 'SiSwati', + 'st' => 'seSotho', + 'su' => 'Basa Sunda', + 'sv' => 'Svenska', + 'sw' => 'Kiswahili', + 'ta' => 'தமிழ்', + 'te' => 'తెలుగు', + 'tg' => 'тоҷикӣ', + 'th' => 'ไทย', + 'ti' => 'ትግርኛ', + 'tk' => 'Türkmen', + 'tl' => 'Tagalog', + 'tn' => 'seTswana', + 'to' => 'faka Tonga', + 'tr' => 'Türkçe', + 'ts' => 'xiTsonga', + 'tt' => 'татарча', + 'tw' => 'Twi', + 'ty' => 'Reo Mā`ohi', + 'ug' => 'Uyƣurqə', + 'uk' => 'Українська', + 'ur' => '‫اردو', + 'uz' => "O'zbek", + 've' => 'tshiVenḓa', + 'vi' => 'Tiếng Việt', + 'vo' => 'Volapük', + 'wa' => 'Walon', + 'wo' => 'Wollof', + 'xh' => 'isiXhosa', + 'yi' => '‫ייִדיש', + 'yo' => 'Yorùbá', + 'za' => 'Saɯ cueŋƅ', + 'zh' => '中文', + 'zh-hk' => '中文 (香港)', + 'zh-tw' => '中文 (臺灣)', + 'zu' => 'isiZulu' + ); + } + + $langs = self::$langs; + if ($name_with_code) { + foreach ($langs as $k => &$v) { + $v = '('.$k.') '.$v; + } + } + + if ($flip) { + return array_flip($langs); + } + + return $langs; + } + + /** + * Text direction + * + * Returns text direction for a given language. + * If text direction was forced with {@link $text_direction}, returns this + * value. + * + * @param string $lang Language code + * @return string + */ + public static function getTextDirection($lang) + { + if (self::$text_direction) { + return self::$text_direction; + } + + if (preg_match('/^(ar|dv|fa|ha|he|ps|ur|yi)$/i',$lang)) { + return 'rtl'; + } + return 'ltr'; + } +} +?> \ No newline at end of file diff --git a/inc/clearbricks/common/lib.text.php b/inc/clearbricks/common/lib.text.php new file mode 100644 index 0000000..fabe582 --- /dev/null +++ b/inc/clearbricks/common/lib.text.php @@ -0,0 +1,355 @@ + $p) { + $str = preg_replace('/['.$p.']/u',$r,$str); + } + + return $str; + } + + /** + * String to URL + * + * Transforms a string to a proper URL. + * + * @param string $str String to transform + * @param boolean $with_slashes Keep slashes in URL + * @return string + */ + public static function str2URL($str,$with_slashes=true) + { + $str = self::deaccent($str); + $str = preg_replace('/[^A-Za-z0-9_\s\'\:\/[\]-]/','',$str); + + return self::tidyURL($str,$with_slashes); + } + + /** + * URL cleanup + * + * @param string $str URL to tidy + * @param boolean $keep_slashes Keep slashes in URL + * @param boolean $keep_spaces Keep spaces in URL + * @return string + */ + public static function tidyURL($str,$keep_slashes=true,$keep_spaces=false) + { + $str = strip_tags($str); + $str = str_replace(array('?','&','#','=','+','<','>','"','%'),'',$str); + $str = str_replace("'",' ',$str); + $str = preg_replace('/[\s]+/',' ',trim($str)); + + if (!$keep_slashes) { + $str = str_replace('/','-',$str); + } + + if (!$keep_spaces) { + $str = str_replace(' ','-',$str); + } + + $str = preg_replace('/[-]+/','-',$str); + + # Remove path changes in URL + $str = preg_replace('%^/%','',$str); + $str = preg_replace('%\.+/%','',$str); + + return $str; + } + + /** + * Cut string + * + * Returns a cuted string on spaced at given length $l. + * + * @param string $str String to cut + * @param integer $l Length to keep + * @return string + */ + public static function cutString($str,$l) + { + $s = preg_split('/([\s]+)/u',$str,-1,PREG_SPLIT_DELIM_CAPTURE); + + $res = ''; + $L = 0; + + if (mb_strlen($s[0]) >= $l) { + return mb_substr($s[0],0,$l); + } + + foreach ($s as $v) + { + $L = $L+mb_strlen($v); + + if ($L > $l) { + break; + } else { + $res .= $v; + } + } + + return trim($res); + } + + /** + * Split words + * + * Returns an array of words from a given string. + * + * @param string $str Words to split + * @return array + */ + public static function splitWords($str) + { + $non_word = '\x{0000}-\x{002F}\x{003A}-\x{0040}\x{005b}-\x{0060}\x{007B}-\x{007E}\x{00A0}-\x{00BF}\s'; + if (preg_match_all('/([^'.$non_word.']{3,})/msu',html::clean($str),$match)) { + foreach ($match[1] as $i => $v) { + $match[1][$i] = mb_strtolower($v); + } + return $match[1]; + } + return array(); + } + + /** + * Encoding detection + * + * Returns the encoding (in lowercase) of given $str. + * + * @param string $str String + * @return string + */ + public static function detectEncoding($str) + { + return strtolower(mb_detect_encoding($str.' ', + 'UTF-8,ISO-8859-1,ISO-8859-2,ISO-8859-3,'. + 'ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,'. + 'ISO-8859-9,ISO-8859-10,ISO-8859-13,ISO-8859-14,ISO-8859-15')); + } + + /** + * UTF8 conversions + * + * Returns an UTF-8 converted string. If $encoding is not specified, the + * function will try to detect encoding. + * + * @param string $str String to convert + * @param string $encoding Optionnal "from" encoding + * @return string + */ + public static function toUTF8($str,$encoding=null) + { + if (!$encoding) { + $encoding = self::detectEncoding($str); + } + + if ($encoding != 'utf-8') { + $str = iconv($encoding,'UTF-8',$str); + } + + return $str; + } + + /** + * Find bad UTF8 tokens + * + * Locates the first bad byte in a UTF-8 string returning it's + * byte index in the string + * PCRE Pattern to locate bad bytes in a UTF-8 string + * Comes from W3 FAQ: Multilingual Forms + * Note: modified to include full ASCII range including control chars + * + * @copyright Harry Fuecks + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html GNU LGPL 2.1 + * @link http://phputf8.sourceforge.net + * + * @param string $str String to search + * @return integer|false + */ + public static function utf8badFind($str) + { + $UTF8_BAD = + '([\x00-\x7F]'. # ASCII (including control chars) + '|[\xC2-\xDF][\x80-\xBF]'. # non-overlong 2-byte + '|\xE0[\xA0-\xBF][\x80-\xBF]'. # excluding overlongs + '|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}'. # straight 3-byte + '|\xED[\x80-\x9F][\x80-\xBF]'. # excluding surrogates + '|\xF0[\x90-\xBF][\x80-\xBF]{2}'. # planes 1-3 + '|[\xF1-\xF3][\x80-\xBF]{3}'. # planes 4-15 + '|\xF4[\x80-\x8F][\x80-\xBF]{2}'. # plane 16 + '|(.{1}))'; # invalid byte + $pos = 0; + $badList = array(); + + while (preg_match('/'.$UTF8_BAD.'/S', $str, $matches)) { + $bytes = strlen($matches[0]); + if ( isset($matches[2])) { + return $pos; + } + $pos += $bytes; + $str = substr($str,$bytes); + } + return false; + } + + /** + * UTF8 cleanup + * + * Replaces non utf8 bytes in $str by $repl. + * + * @copyright Harry Fuecks + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html GNU LGPL 2.1 + * @link http://phputf8.sourceforge.net + * + * @param string $str String to clean + * @param string $repl Replacement string + * @return string + */ + public static function cleanUTF8($str,$repl='?') + { + while (($bad_index = self::utf8badFind($str)) !== false) { + $str = substr_replace($str,$repl,$bad_index,1); + } + + return $str; + } + + /** + * BOM removal + * + * Removes BOM from the begining of a string if present. + * + * @param string $str String to clean + * @return string + */ + public static function removeBOM($str) + { + if (substr_count($str,'')) { + return str_replace('','',$str); + } + + return $str; + } + + /** + * Quoted printable conversion + * + * Encodes given str to quoted printable + * + * @param string $str String to encode + * @return string + */ + public static function QPEncode($str) + { + $res = ''; + + foreach (preg_split("/\r?\n/msu", $str) as $line) + { + $l = ''; + preg_match_all('/./',$line,$m); + + foreach ($m[0] as $c) + { + $a = ord($c); + + if ($a < 32 || $a == 61 || $a > 126) { + $c = sprintf('=%02X',$a); + } + + $l .= $c; + } + + $res .= $l."\r\n"; + } + return $res; + } +} +?> \ No newline at end of file diff --git a/inc/clearbricks/common/tz.dat b/inc/clearbricks/common/tz.dat new file mode 100644 index 0000000..09cc367 --- /dev/null +++ b/inc/clearbricks/common/tz.dat @@ -0,0 +1,407 @@ +Africa/Abidjan +Africa/Accra +Africa/Addis_Ababa +Africa/Algiers +Africa/Asmera +Africa/Bamako +Africa/Bangui +Africa/Banjul +Africa/Bissau +Africa/Blantyre +Africa/Brazzaville +Africa/Bujumbura +Africa/Cairo +Africa/Casablanca +Africa/Ceuta +Africa/Conakry +Africa/Dakar +Africa/Dar_es_Salaam +Africa/Djibouti +Africa/Douala +Africa/El_Aaiun +Africa/Freetown +Africa/Gaborone +Africa/Harare +Africa/Johannesburg +Africa/Kampala +Africa/Khartoum +Africa/Kigali +Africa/Kinshasa +Africa/Lagos +Africa/Libreville +Africa/Lome +Africa/Luanda +Africa/Lubumbashi +Africa/Lusaka +Africa/Malabo +Africa/Maputo +Africa/Maseru +Africa/Mbabane +Africa/Mogadishu +Africa/Monrovia +Africa/Nairobi +Africa/Ndjamena +Africa/Niamey +Africa/Nouakchott +Africa/Ouagadougou +Africa/Porto-Novo +Africa/Sao_Tome +Africa/Timbuktu +Africa/Tripoli +Africa/Tunis +Africa/Windhoek + + +America/Adak +America/Anchorage +America/Anguilla +America/Antigua +America/Araguaina +America/Argentina/Buenos_Aires +America/Argentina/Catamarca +America/Argentina/ComodRivadavia +America/Argentina/Cordoba +America/Argentina/Jujuy +America/Argentina/La_Rioja +America/Argentina/Mendoza +America/Argentina/Rio_Gallegos +America/Argentina/San_Juan +America/Argentina/Tucuman +America/Argentina/Ushuaia +America/Aruba +America/Asuncion +America/Bahia +America/Barbados +America/Belem +America/Belize +America/Boa_Vista +America/Bogota +America/Boise +America/Cambridge_Bay +America/Campo_Grande +America/Cancun +America/Caracas +America/Cayenne +America/Cayman +America/Chicago +America/Chihuahua +America/Costa_Rica +America/Cuiaba +America/Curacao +America/Danmarkshavn +America/Dawson +America/Dawson_Creek +America/Denver +America/Detroit +America/Dominica +America/Edmonton +America/Eirunepe +America/El_Salvador +America/Fortaleza +America/Glace_Bay +America/Godthab +America/Goose_Bay +America/Grand_Turk +America/Grenada +America/Guadeloupe +America/Guatemala +America/Guayaquil +America/Guyana +America/Halifax +America/Havana +America/Hermosillo +America/Indiana/Indianapolis +America/Indiana/Knox +America/Indiana/Marengo +America/Indiana/Vevay +America/Indianapolis +America/Inuvik +America/Iqaluit +America/Jamaica +America/Juneau +America/Kentucky/Louisville +America/Kentucky/Monticello +America/La_Paz +America/Lima +America/Los_Angeles +America/Louisville +America/Maceio +America/Managua +America/Manaus +America/Martinique +America/Mazatlan +America/Menominee +America/Merida +America/Mexico_City +America/Miquelon +America/Monterrey +America/Montevideo +America/Montreal +America/Montserrat +America/Nassau +America/New_York +America/Nipigon +America/Nome +America/Noronha +America/North_Dakota/Center +America/Panama +America/Pangnirtung +America/Paramaribo +America/Phoenix +America/Port-au-Prince +America/Port_of_Spain +America/Porto_Velho +America/Puerto_Rico +America/Rainy_River +America/Rankin_Inlet +America/Recife +America/Regina +America/Rio_Branco +America/Santiago +America/Santo_Domingo +America/Sao_Paulo +America/Scoresbysund +America/Shiprock +America/St_Johns +America/St_Kitts +America/St_Lucia +America/St_Thomas +America/St_Vincent +America/Swift_Current +America/Tegucigalpa +America/Thule +America/Thunder_Bay +America/Tijuana +America/Toronto +America/Tortola +America/Vancouver +America/Whitehorse +America/Winnipeg +America/Yakutat +America/Yellowknife + + +Antarctica/Casey +Antarctica/Davis +Antarctica/DumontDUrville +Antarctica/Mawson +Antarctica/McMurdo +Antarctica/Palmer +Antarctica/Rothera +Antarctica/South_Pole +Antarctica/Syowa +Antarctica/Vostok + + +Arctic/Longyearbyen + + +Asia/Aden +Asia/Almaty +Asia/Amman +Asia/Anadyr +Asia/Aqtau +Asia/Aqtobe +Asia/Ashgabat +Asia/Baghdad +Asia/Bahrain +Asia/Baku +Asia/Bangkok +Asia/Beirut +Asia/Bishkek +Asia/Brunei +Asia/Calcutta +Asia/Choibalsan +Asia/Chongqing +Asia/Colombo +Asia/Damascus +Asia/Dhaka +Asia/Dili +Asia/Dubai +Asia/Dushanbe +Asia/Gaza +Asia/Harbin +Asia/Hong_Kong +Asia/Hovd +Asia/Irkutsk +Asia/Istanbul +Asia/Jakarta +Asia/Jayapura +Asia/Jerusalem +Asia/Kabul +Asia/Kamchatka +Asia/Karachi +Asia/Kashgar +Asia/Katmandu +Asia/Krasnoyarsk +Asia/Kuala_Lumpur +Asia/Kuching +Asia/Kuwait +Asia/Macau +Asia/Magadan +Asia/Makassar +Asia/Manila +Asia/Muscat +Asia/Nicosia +Asia/Novosibirsk +Asia/Omsk +Asia/Oral +Asia/Phnom_Penh +Asia/Pontianak +Asia/Pyongyang +Asia/Qatar +Asia/Qyzylorda +Asia/Rangoon +Asia/Riyadh +Asia/Saigon +Asia/Sakhalin +Asia/Samarkand +Asia/Seoul +Asia/Shanghai +Asia/Singapore +Asia/Taipei +Asia/Tashkent +Asia/Tbilisi +Asia/Tehran +Asia/Thimphu +Asia/Tokyo +Asia/Ulaanbaatar +Asia/Urumqi +Asia/Vientiane +Asia/Vladivostok +Asia/Yakutsk +Asia/Yekaterinburg +Asia/Yerevan + + +Atlantic/Azores +Atlantic/Bermuda +Atlantic/Canary +Atlantic/Cape_Verde +Atlantic/Faeroe +Atlantic/Jan_Mayen +Atlantic/Madeira +Atlantic/Reykjavik +Atlantic/South_Georgia +Atlantic/St_Helena +Atlantic/Stanley + + +Australia/Adelaide +Australia/Brisbane +Australia/Broken_Hill +Australia/Darwin +Australia/Hobart +Australia/Lindeman +Australia/Lord_Howe +Australia/Melbourne +Australia/Perth +Australia/Sydney + + +Europe/Amsterdam +Europe/Andorra +Europe/Athens +Europe/Belfast +Europe/Belgrade +Europe/Berlin +Europe/Bratislava +Europe/Brussels +Europe/Bucharest +Europe/Budapest +Europe/Chisinau +Europe/Copenhagen +Europe/Dublin +Europe/Gibraltar +Europe/Helsinki +Europe/Istanbul +Europe/Kaliningrad +Europe/Kiev +Europe/Lisbon +Europe/Ljubljana +Europe/London +Europe/Luxembourg +Europe/Madrid +Europe/Malta +Europe/Mariehamn +Europe/Minsk +Europe/Monaco +Europe/Moscow +Europe/Nicosia +Europe/Oslo +Europe/Paris +Europe/Prague +Europe/Riga +Europe/Rome +Europe/Samara +Europe/San_Marino +Europe/Sarajevo +Europe/Simferopol +Europe/Skopje +Europe/Sofia +Europe/Stockholm +Europe/Tallinn +Europe/Tirane +Europe/Uzhgorod +Europe/Vaduz +Europe/Vatican +Europe/Vienna +Europe/Vilnius +Europe/Warsaw +Europe/Zagreb +Europe/Zaporozhye +Europe/Zurich + + +Indian/Antananarivo +Indian/Chagos +Indian/Christmas +Indian/Cocos +Indian/Comoro +Indian/Kerguelen +Indian/Mahe +Indian/Maldives +Indian/Mauritius +Indian/Mayotte +Indian/Reunion + + +Pacific/Apia +Pacific/Auckland +Pacific/Chatham +Pacific/Easter +Pacific/Efate +Pacific/Enderbury +Pacific/Fakaofo +Pacific/Fiji +Pacific/Funafuti +Pacific/Galapagos +Pacific/Gambier +Pacific/Guadalcanal +Pacific/Guam +Pacific/Honolulu +Pacific/Johnston +Pacific/Kiritimati +Pacific/Kosrae +Pacific/Kwajalein +Pacific/Majuro +Pacific/Marquesas +Pacific/Midway +Pacific/Nauru +Pacific/Niue +Pacific/Norfolk +Pacific/Noumea +Pacific/Pago_Pago +Pacific/Palau +Pacific/Pitcairn +Pacific/Ponape +Pacific/Port_Moresby +Pacific/Rarotonga +Pacific/Saipan +Pacific/Tahiti +Pacific/Tarawa +Pacific/Tongatapu +Pacific/Truk +Pacific/Wake +Pacific/Wallis +Pacific/Yap \ No newline at end of file diff --git a/inc/clearbricks/dblayer/class.cursor.php b/inc/clearbricks/dblayer/class.cursor.php new file mode 100644 index 0000000..1565894 --- /dev/null +++ b/inc/clearbricks/dblayer/class.cursor.php @@ -0,0 +1,258 @@ + + * openCursor('table'); + * $cur->field1 = 1; + * $cur->field2 = 'foo'; + * $cur->insert(); // Insert field ... + * + * $cur->update('WHERE field3 = 4'); // ... or update field + * ?> + * + * + * @see dbLayer::openCursor() + * @param dbLayer &$con Connection object + * @param string $table Table name + */ + public function __construct($con,$table) + { + $this->__con =& $con; + $this->setTable($table); + } + + /** + * Set table + * + * Changes working table and resets data + * + * @param string $table Table name + */ + public function setTable($table) + { + $this->__table = $table; + $this->__data = array(); + } + + /** + * Set field + * + * Set value $v to a field named $n. Value could be + * an string, an integer, a float, a null value or an array. + * + * If value is an array, its first value will be interpreted as a SQL + * command. String values will be automatically escaped. + * + * @see __set() + * @param string $n Field name + * @param mixed $v Field value + */ + public function setField($n,$v) + { + $this->__data[$n] = $v; + } + + /** + * Unset field + * + * Remove a field from data set. + * + * @param string $n Field name + */ + public function unsetField($n) + { + unset($this->__data[$n]); + } + + /** + * Field exists + * + * @return boolean true if field named $n exists + */ + public function isField($n) + { + return isset($this->__data[$n]); + } + + /** + * Field value + * + * @see __get() + * @return mixed value for a field named $n + */ + public function getField($n) + { + if (isset($this->__data[$n])) { + return $this->__data[$n]; + } + + return null; + } + + /** + * Set Field + * + * Magic alias for {@link setField()} + */ + public function __set($n,$v) + { + $this->setField($n,$v); + } + + /** + * Field value + * + * Magic alias for {@link getField()} + * + * @return mixed value for a field named $n + */ + public function __get($n) + { + return $this->getField($n); + } + + /** + * Empty data set + * + * Removes all data from data set + */ + public function clean() + { + $this->__data = array(); + } + + private function formatFields() + { + $data = array(); + + foreach ($this->__data as $k => $v) + { + $k = $this->__con->escapeSystem($k); + + if (is_null($v)) { + $data[$k] = 'NULL'; + } elseif (is_string($v)) { + $data[$k] = "'".$this->__con->escape($v)."'"; + } elseif (is_array($v)) { + $data[$k] = $v[0]; + } else { + $data[$k] = $v; + } + } + + return $data; + } + + /** + * Get insert query + * + * Returns the generated INSERT query + * + * @return string + */ + public function getInsert() + { + $data = $this->formatFields(); + + $insReq = 'INSERT INTO '.$this->__con->escapeSystem($this->__table)." (\n". + implode(",\n",array_keys($data))."\n) VALUES (\n". + implode(",\n",array_values($data))."\n) "; + + return $insReq; + } + + /** + * Get update query + * + * Returns the generated UPDATE query + * + * @param string $where WHERE condition + * @return string + */ + public function getUpdate($where) + { + $data = $this->formatFields(); + $fields = array(); + + $updReq = 'UPDATE '.$this->__con->escapeSystem($this->__table)." SET \n"; + + foreach ($data as $k => $v) { + $fields[] = $k.' = '.$v.""; + } + + $updReq .= implode(",\n",$fields); + $updReq .= "\n".$where; + + return $updReq; + } + + /** + * Execute insert query + * + * Executes the generated INSERT query + */ + public function insert() + { + if (!$this->__table) { + throw new Exception('No table name.'); + } + + $insReq = $this->getInsert(); + + $this->__con->execute($insReq); + + return true; + } + + /** + * Execute update query + * + * Executes the generated UPDATE query + * + * @param string $where WHERE condition + */ + public function update($where) + { + if (!$this->__table) { + throw new Exception('No table name.'); + } + + $updReq = $this->getUpdate($where); + + $this->__con->execute($updReq); + + return true; + } +} +?> \ No newline at end of file diff --git a/inc/clearbricks/dblayer/class.mysql.php b/inc/clearbricks/dblayer/class.mysql.php new file mode 100644 index 0000000..662d7e8 --- /dev/null +++ b/inc/clearbricks/dblayer/class.mysql.php @@ -0,0 +1,253 @@ +db_post_connect($link,$database); + + return $link; + } + + /** @ignore */ + public function db_pconnect($host,$user,$password,$database) + { + if (!function_exists('mysql_pconnect')) { + throw new Exception('PHP MySQL functions are not available'); + } + + if (($link = @mysql_pconnect($host,$user,$password)) === false) { + throw new Exception('Unable to connect to database'); + } + + $this->db_post_connect($link,$database); + + return $link; + } + + /** @ignore */ + private function db_post_connect($link,$database) + { + if (@mysql_select_db($database,$link) === false) { + throw new Exception('Unable to use database '.$database); + } + + if (version_compare($this->db_version($link),'4.1','>=')) + { + $this->db_query($link,'SET NAMES utf8'); + $this->db_query($link,'SET CHARACTER SET utf8'); + $this->db_query($link,"SET COLLATION_CONNECTION = 'utf8_general_ci'"); + $this->db_query($link,"SET COLLATION_SERVER = 'utf8_general_ci'"); + $this->db_query($link,"SET CHARACTER_SET_SERVER = 'utf8'"); + $this->db_query($link,"SET CHARACTER_SET_DATABASE = 'utf8'"); + } + } + + /** @ignore */ + public function db_close($handle) + { + if (is_resource($handle)) { + mysql_close($handle); + } + } + + /** @ignore */ + public function db_version($handle) + { + if (is_resource($handle)) { + return mysql_get_server_info(); + } + return null; + } + + /** @ignore */ + public function db_query($handle,$query) + { + if (is_resource($handle)) + { + $res = @mysql_query($query,$handle); + if ($res === false) { + $e = new Exception($this->db_last_error($handle)); + $e->sql = $query; + throw $e; + } + return $res; + } + } + + /** @ignore */ + public function db_exec($handle,$query) + { + return $this->db_query($handle,$query); + } + + /** @ignore */ + public function db_num_fields($res) + { + if (is_resource($res)) { + return mysql_num_fields($res); + } + return 0; + } + + /** @ignore */ + public function db_num_rows($res) + { + if (is_resource($res)) { + return mysql_num_rows($res); + } + return 0; + } + + /** @ignore */ + public function db_field_name($res,$position) + { + if (is_resource($res)) { + return mysql_field_name($res,$position); + } + } + + /** @ignore */ + public function db_field_type($res,$position) + { + if (is_resource($res)) { + return mysql_field_type($res,$position); + } + } + + /** @ignore */ + public function db_fetch_assoc($res) + { + if (is_resource($res)) { + return mysql_fetch_assoc($res); + } + } + + /** @ignore */ + public function db_result_seek($res,$row) + { + if (is_resource($res)) { + return mysql_data_seek($res,$row); + } + } + + /** @ignore */ + public function db_changes($handle,$res) + { + if (is_resource($handle)) { + return mysql_affected_rows($handle); + } + } + + /** @ignore */ + public function db_last_error($handle) + { + if (is_resource($handle)) + { + $e = mysql_error($handle); + if ($e) { + return $e.' ('.mysql_errno($handle).')'; + } + } + return false; + } + + /** @ignore */ + public function db_escape_string($str,$handle=null) + { + if (is_resource($handle)) { + return mysql_real_escape_string($str,$handle); + } else { + return mysql_escape_string($str); + } + } + + /** @ignore */ + public function db_write_lock($table) + { + try { + $this->execute('LOCK TABLES '.$this->escapeSystem($table).' WRITE'); + } catch (Exception $e) { + # As lock is a privilege in MySQL, we can avoid errors with weak_locks static var + if (!self::$weak_locks) { + throw $e; + } + } + } + + /** @ignore */ + public function db_unlock() + { + try { + $this->execute('UNLOCK TABLES'); + } catch (Exception $e) { + if (!self::$weak_locks) { + throw $e; + } + } + } + + /** @ignore */ + public function vacuum($table) + { + $this->execute('OPTIMIZE TABLE '.$this->escapeSystem($table)); + } + + /** @ignore */ + public function dateFormat($field,$pattern) + { + $pattern = str_replace('%M','%i',$pattern); + + return 'DATE_FORMAT('.$field.','."'".$this->escape($pattern)."') "; + } + + /** @ignore */ + public function concat() + { + $args = func_get_args(); + return 'CONCAT('.implode(',',$args).')'; + } + + /** @ignore */ + public function escapeSystem($str) + { + return '`'.$str.'`'; + } + } +} +?> \ No newline at end of file diff --git a/inc/clearbricks/dblayer/class.pgsql.php b/inc/clearbricks/dblayer/class.pgsql.php new file mode 100644 index 0000000..66f8d05 --- /dev/null +++ b/inc/clearbricks/dblayer/class.pgsql.php @@ -0,0 +1,280 @@ +get_connection_string($host,$user,$password,$database); + + if (($link = @pg_connect($str)) === false) { + throw new Exception('Unable to connect to database'); + } + + return $link; + } + + /** @ignore */ + public function db_pconnect($host,$user,$password,$database) + { + if (!function_exists('pg_pconnect')) { + throw new Exception('PHP PostgreSQL functions are not available'); + } + + $str = $this->get_connection_string($host,$user,$password,$database); + + if (($link = @pg_pconnect($str)) === false) { + throw new Exception('Unable to connect to database'); + } + + return $link; + } + + /** @ignore */ + public function db_close($handle) + { + if (is_resource($handle)) { + pg_close($handle); + } + } + + /** @ignore */ + public function db_version($handle) + { + if (is_resource($handle)) + { + return pg_parameter_status($handle,'server_version'); + } + return null; + } + + /** @ignore */ + public function db_query($handle,$query) + { + if (is_resource($handle)) + { + $res = @pg_query($handle,$query); + if ($res === false) { + $e = new Exception($this->db_last_error($handle)); + $e->sql = $query; + throw $e; + } + return $res; + } + } + + /** @ignore */ + public function db_exec($handle,$query) + { + return $this->db_query($handle,$query); + } + + /** @ignore */ + public function db_num_fields($res) + { + if (is_resource($res)) { + return pg_num_fields($res); + } + return 0; + } + + /** @ignore */ + public function db_num_rows($res) + { + if (is_resource($res)) { + return pg_num_rows($res); + } + return 0; + } + + /** @ignore */ + public function db_field_name($res,$position) + { + if (is_resource($res)) { + return pg_field_name($res,$position); + } + } + + /** @ignore */ + public function db_field_type($res,$position) + { + if (is_resource($res)) { + return pg_field_type($res,$position); + } + } + + /** @ignore */ + public function db_fetch_assoc($res) + { + if (is_resource($res)) { + return pg_fetch_assoc($res); + } + } + + /** @ignore */ + public function db_result_seek($res,$row) + { + if (is_resource($res)) { + return pg_result_seek($res,(int) $row); + } + return false; + } + + /** @ignore */ + public function db_changes($handle,$res) + { + if (is_resource($handle) && is_resource($res)) { + return pg_affected_rows($res); + } + } + + /** @ignore */ + public function db_last_error($handle) + { + if (is_resource($handle)) { + return pg_last_error($handle); + } + return false; + } + + /** @ignore */ + public function db_escape_string($str,$handle=null) + { + return pg_escape_string($str); + } + + /** @ignore */ + public function db_write_lock($table) + { + $this->execute('BEGIN'); + $this->execute('LOCK TABLE '.$this->escapeSystem($table).' IN EXCLUSIVE MODE'); + } + + /** @ignore */ + public function db_unlock() + { + $this->execute('END'); + } + + /** @ignore */ + public function vacuum($table) + { + $this->execute('VACUUM FULL '.$this->escapeSystem($table)); + } + + /** @ignore */ + public function dateFormat($field,$pattern) + { + $rep = array( + '%d' => 'DD', + '%H' => 'HH24', + '%M' => 'MI', + '%m' => 'MM', + '%S' => 'SS', + '%Y' => 'YYYY' + ); + + $pattern = str_replace(array_keys($rep),array_values($rep),$pattern); + + return 'TO_CHAR('.$field.','."'".$this->escape($pattern)."') "; + } + + /** + * Function call + * + * Calls a PostgreSQL function an returns the result as a {@link record}. + * After $name, you can add any parameters you want to append + * them to the PostgreSQL function. You don't need to escape string in + * arguments. + * + * @param string $name Function name + * @return record + */ + public function callFunction($name) + { + $data = func_get_args(); + array_shift($data); + + foreach ($data as $k => $v) + { + if (is_null($v)) { + $data[$k] = 'NULL'; + } elseif (is_string($v)) { + $data[$k] = "'".$this->escape($v)."'"; + } elseif (is_array($v)) { + $data[$k] = $v[0]; + } else { + $data[$k] = $v; + } + } + + $req = + 'SELECT '.$name."(\n". + implode(",\n",array_values($data)). + "\n) "; + + return $this->select($req); + } + } +} +?> \ No newline at end of file diff --git a/inc/clearbricks/dblayer/class.sqlite.php b/inc/clearbricks/dblayer/class.sqlite.php new file mode 100644 index 0000000..97fbe73 --- /dev/null +++ b/inc/clearbricks/dblayer/class.sqlite.php @@ -0,0 +1,278 @@ +db_post_connect($link,$database); + + return $link; + } + + /** @ignore */ + public function db_pconnect($host,$user,$password,$database) + { + if (!class_exists('PDO') || !in_array('sqlite',PDO::getAvailableDrivers())) { + throw new Exception('PDO SQLite class is not available'); + } + + $link = new PDO('sqlite:'.$database,null,null,array(PDO::ATTR_PERSISTENT => true)); + $this->db_post_connect($link,$database); + + return $link; + } + + /** @ignore */ + private function db_post_connect($handle,$database) + { + if ($handle instanceof PDO) { + $this->db_exec($handle,'PRAGMA short_column_names = 1'); + $this->db_exec($handle,'PRAGMA encoding = "UTF-8"'); + $handle->sqliteCreateFunction('now',array($this,'now'),0); + } + } + + /** @ignore */ + public function db_close($handle) + { + if ($handle instanceof PDO) { + $handle = null; + $this->__link = null; + } + } + + /** @ignore */ + public function db_version($handle) + { + if ($handle instanceof PDO) { + return $handle->getAttribute(PDO::ATTR_SERVER_VERSION); + } + } + + # There is no other way than get all selected data in a staticRecord + /** @ignore */ + public function select($sql) + { + $result = $this->db_query($this->__link,$sql); + $this->__last_result =& $result; + + $info = array(); + $info['con'] =& $this; + $info['cols'] = $this->db_num_fields($result); + $info['info'] = array(); + + for ($i=0; $i<$info['cols']; $i++) { + $info['info']['name'][] = $this->db_field_name($result,$i); + $info['info']['type'][] = $this->db_field_type($result,$i); + } + + $data = array(); + while ($r = $result->fetch(PDO::FETCH_ASSOC)) + { + $R = array(); + foreach ($r as $k => $v) { + $k = preg_replace('/^(.*)\./','',$k); + $R[$k] = $v; + $R[] =& $R[$k]; + } + $data[] = $R; + } + + $info['rows'] = count($data); + $result->closeCursor(); + + return new staticRecord($data,$info); + } + + /** @ignore */ + public function db_query($handle,$query) + { + if ($handle instanceof PDO) + { + $res = $handle->query($query); + if ($res === false) { + $e = new Exception($this->db_last_error($handle)); + $e->sql = $query; + throw $e; + } + + return $res; + } + } + + /** @ignore */ + public function db_exec($handle,$query) + { + return $this->db_query($handle,$query); + } + + /** @ignore */ + public function db_num_fields($res) + { + if ($res instanceof PDOStatement) { + return $res->columnCount(); + } + return 0; + } + + /** @ignore */ + public function db_num_rows($res) + { + } + + /** @ignore */ + public function db_field_name($res,$position) + { + if ($res instanceof PDOStatement) { + $m = $res->getColumnMeta($position); + return preg_replace('/^.+\./','',$m['name']); # we said short_column_names = 1 + } + } + + /** @ignore */ + public function db_field_type($res,$position) + { + if ($res instanceof PDOStatement) { + $m = $res->getColumnMeta($position); + switch ($m['pdo_type']) { + case PDO::PARAM_BOOL: + return 'boolean'; + case PDO::PARAM_NULL: + return 'null'; + case PDO::PARAM_INT: + return 'integer'; + default: + return 'varchar'; + } + } + } + + /** @ignore */ + public function db_fetch_assoc($res) + { + } + + /** @ignore */ + public function db_result_seek($res,$row) + { + } + + /** @ignore */ + public function db_changes($handle,$res) + { + if ($res instanceof PDOStatement) { + return $res->rowCount(); + } + } + + /** @ignore */ + public function db_last_error($handle) + { + if ($handle instanceof PDO) { + $err = $handle->errorInfo(); + return $err[2].' ('.$err[1].')'; + } + return false; + } + + /** @ignore */ + public function db_escape_string($str,$handle=null) + { + if ($handle instanceof PDO) { + return trim($handle->quote($str),"'"); + } + return $str; + } + + /** @ignore */ + public function escapeSystem($str) + { + return "'".$this->escape($str)."'"; + } + + /** @ignore */ + public function begin() + { + if ($this->__link instanceof PDO) { + $this->__link->beginTransaction(); + } + } + + /** @ignore */ + public function commit() + { + if ($this->__link instanceof PDO) { + $this->__link->commit(); + } + } + + /** @ignore */ + public function rollback() + { + if ($this->__link instanceof PDO) { + $this->__link->rollBack(); + } + } + + /** @ignore */ + public function db_write_lock($table) + { + $this->execute('BEGIN EXCLUSIVE TRANSACTION'); + } + + /** @ignore */ + public function db_unlock() + { + $this->execute('END'); + } + + /** @ignore */ + public function vacuum($table) + { + $this->execute('VACUUM '.$this->escapeSystem($table)); + } + + /** @ignore */ + public function dateFormat($field,$pattern) + { + return "strftime('".$this->escape($pattern)."',".$field.') '; + } + + # Internal SQLite function that adds NOW() SQL function. + /** @ignore */ + public function now() + { + return date('Y-m-d H:i:s'); + } + } +} +?> \ No newline at end of file diff --git a/inc/clearbricks/dblayer/dblayer.php b/inc/clearbricks/dblayer/dblayer.php new file mode 100644 index 0000000..ee22b13 --- /dev/null +++ b/inc/clearbricks/dblayer/dblayer.php @@ -0,0 +1,1144 @@ +$position. + * + * @param resource $res Resource result + * @param integer $position Field position + * @return string + */ + function db_field_name($res,$position); + + /** + * Field type + * + * This method should return the field type a the given position + * $position. + * + * @param resource $res Resource result + * @param integer $position Field position + * @return string + */ + function db_field_type($res,$position); + + /** + * Fetch result + * + * This method should fetch one line of result and return an associative array + * with field name as key and field value as value. + * + * @param resource $res Resource result + * @return array + */ + function db_fetch_assoc($res); + + /** + * Move result cursor + * + * This method should move result cursor on given row position $row + * and return true on success. + * + * @param resource $res Resource result + * @param integer $position Row position + * @return boolean + */ + function db_result_seek($res,$row); + + /** + * Affected rows + * + * This method should return number of rows affected by INSERT, UPDATE or + * DELETE queries. + * + * @param resource $handle Resource link + * @param resource $res Resource result + * @return integer + */ + function db_changes($handle,$res); + + /** + * Last error + * + * This method should return the last error string for the current connection. + * + * @param resource $handle Resource link + * @return string + */ + function db_last_error($handle); + + /** + * Escape string + * + * This method should return an escaped string for the current connection. + * + * @param string $str String to escape + * @param resource $handle Resource link + * @return string + */ + function db_escape_string($str,$handle=null); + + /** + * Acquiere Write lock + * + * This method should lock the given table in write access. + * + * @param string $table Table name + */ + function db_write_lock($table); + + /** + * Release lock + * + * This method should releases an acquiered lock. + */ + function db_unlock(); +} + +/** +* Database Abstraction Layer class +* +* Base class for database abstraction. Each driver extends this class and +* implements {@link i_dbLayer} interface. +* +* @package Clearbricks +* @subpackage DBLayer +*/ +class dbLayer +{ + /** @var string Driver name */ + protected $__driver = null; + + /** @var string Database version */ + protected $__version = null; + + /** @var resource Database resource link */ + protected $__link; + + /** @var resource Last result resource link */ + protected $__last_result; + + /** + * Start connection + * + * Static function to use to init database layer. Returns a object extending + * dbLayer. + * + * @param string $driver Driver name + * @param string $host Database hostname + * @param string $database Database name + * @param string $user User ID + * @param string $password Password + * @param string $persistent Persistent connection + * @return object + */ + public static function init($driver,$host,$database,$user='',$password='',$persistent=false) + { + if (file_exists(dirname(__FILE__).'/class.'.$driver.'.php')) { + require_once dirname(__FILE__).'/class.'.$driver.'.php'; + $driver_class = $driver.'Connection'; + } else { + trigger_error('Unable to load DB layer for '.$driver,E_USER_ERROR); + exit(1); + } + + return new $driver_class($host,$database,$user,$password,$persistent); + } + + /** + * @param string $host Database hostname + * @param string $database Database name + * @param string $user User ID + * @param string $password Password + * @param string $persistent Persistent connection + */ + public function __construct($host,$database,$user='',$password='',$persistent=false) + { + if ($persistent) { + $this->__link = $this->db_pconnect($host,$user,$password,$database); + } else { + $this->__link = $this->db_connect($host,$user,$password,$database); + } + + $this->__version = $this->db_version($this->__link); + $this->__database = $database; + } + + /** + * Closes database connection. + */ + public function close() + { + $this->db_close($this->__link); + } + + /** + * Returns database driver name + * + * @return string + */ + public function driver() + { + return $this->__driver; + } + + /** + * Returns database driver version + * + * @return string + */ + public function version() + { + return $this->__version; + } + + /** + * Returns current database name + * + * @return string + */ + public function database() + { + return $this->__database; + } + + /** + * Returns link resource + * + * @return resource + */ + public function link() + { + return $this->__link; + } + + /** + * Run query and get results + * + * Executes a query and return a {@link record} object. + * + * @param string $sql SQL query + * @return record + */ + public function select($sql) + { + $result = $this->db_query($this->__link,$sql); + + $this->__last_result =& $result; + + $info = array(); + $info['con'] =& $this; + $info['cols'] = $this->db_num_fields($result); + $info['rows'] = $this->db_num_rows($result); + $info['info'] = array(); + + for ($i=0; $i<$info['cols']; $i++) { + $info['info']['name'][] = $this->db_field_name($result,$i); + $info['info']['type'][] = $this->db_field_type($result,$i); + } + + return new record($result,$info); + } + + /** + * Run query + * + * Executes a query and return true if succeed + * + * @param string $sql SQL query + * @return true + */ + public function execute($sql) + { + $result = $this->db_exec($this->__link,$sql); + + $this->__last_result =& $result; + + return true; + } + + /** + * Begin transaction + * + * Begins a transaction. Transaction should be {@link commit() commited} + * or {@link rollback() rollbacked}. + */ + public function begin() + { + $this->execute('BEGIN'); + } + + /** + * Commit transaction + * + * Commits a previoulsy started transaction. + */ + public function commit() + { + $this->execute('COMMIT'); + } + + /** + * Rollback transaction + * + * Rollbacks a previously started transaction. + */ + public function rollback() + { + $this->execute('ROLLBACK'); + } + + /** + * Aquiere write lock + * + * This method lock the given table in write access. + * + * @param string $table Table name + */ + public function writeLock($table) + { + $this->db_write_lock($table); + } + + /** + * Release lock + * + * This method releases an acquiered lock. + */ + public function unlock() + { + $this->db_unlock(); + } + + /** + * Vacuum the table given in argument. + * + * @param string $table Table name + */ + public function vacuum($table) + { + } + + /** + * Changed rows + * + * Returns the number of lines affected by the last DELETE, INSERT or UPDATE + * query. + * + * @return integer + */ + public function changes() + { + return $this->db_changes($this->__link,$this->__last_result); + } + + /** + * Last error + * + * Returns the last database error or false if no error. + * + * @return string|false + */ + public function error() + { + $err = $this->db_last_error($this->__link); + + if (!$err) { + return false; + } + + return $err; + } + + /** + * Date formatting + * + * Returns a query fragment with date formater. + * + * The following modifiers are accepted: + * + * - %d : Day of the month, numeric + * - %H : Hour 24 (00..23) + * - %M : Minute (00..59) + * - %m : Month numeric (01..12) + * - %S : Seconds (00..59) + * - %Y : Year, numeric, four digits + * + * @param string $field Field name + * @param string $pattern Date format + * @return string + */ + public function dateFormat($field,$pattern) + { + return + 'TO_CHAR('.$field.','."'".$this->escape($pattern)."') "; + } + + /** + * Query Limit + * + * Returns a LIMIT query fragment. $arg1 could be an array of + * offset and limit or an integer which is only limit. If $arg2 + * is given and $arg1 is an integer, it would become limit. + * + * @param array|integer $arg1 array or integer with limit intervals + * @param array|null $arg2 integer or null + * @return string + */ + public function limit($arg1, $arg2=null) + { + if (is_array($arg1)) + { + $arg1 = array_values($arg1); + $arg2 = isset($arg1[1]) ? $arg1[1] : null; + $arg1 = $arg1[0]; + } + + if ($arg2 === null) { + $sql = ' LIMIT '.(integer) $arg1.' '; + } else { + $sql = ' LIMIT '.(integer) $arg2.' OFFSET '.$arg1.' '; + } + + return $sql; + } + + /** + * IN fragment + * + * Returns a IN query fragment where $in could be an array, a string, + * an integer or null + * + * @param array|string|integer|null $in "IN" values + * @return string + */ + public function in($in) + { + if (is_null($in)) + { + return ' IN (NULL) '; + } + elseif (is_string($in)) + { + return " IN ('".$this->escape($in)."') "; + } + elseif (is_array($in)) + { + foreach ($in as $i => $v) { + if (is_null($v)) { + $in[$i] = 'NULL'; + } elseif (is_string($v)) { + $in[$i] = "'".$this->escape($v)."'"; + } + } + return ' IN ('.implode(',',$in).') '; + } + else + { + return ' IN ( '.(integer) $in.') '; + } + } + + /** + * Concat strings + * + * Returns SQL concatenation of methods arguments. Theses arguments + * should be properly escaped when needed. + * + * @return string + */ + public function concat() + { + $args = func_get_args(); + return implode(' || ',$args); + } + + /** + * Escape string + * + * Returns SQL protected string or array values. + * + * @param string|array $i String or array to protect + * @return string|array + */ + public function escape($i) + { + if (is_array($i)) { + foreach ($i as $k => $s) { + $i[$k] = $this->db_escape_string($s,$this->__link); + } + return $i; + } + + return $this->db_escape_string($i,$this->__link); + } + + /** + * System escape string + * + * Returns SQL system protected string. + * + * @param string $str String to protect + * @return string + */ + public function escapeSystem($str) + { + return '"'.$str.'"'; + } + + /** + * Cursor object + * + * Returns a new instance of {@link cursor} class on $table for + * the current connection. + * + * @param string $table Target table + * @return cursor + */ + public function openCursor($table) + { + return new cursor($this,$table); + } +} + +/** +* Query Result Record Class +* +* This class acts as an iterator over database query result. It does not fetch +* all results on instantiation and thus, depending on database engine, should not +* fill PHP process memory. +* +* @package Clearbricks +* @subpackage DBLayer +*/ +class record +{ + /** @var resource Database resource link */ + protected $__link; + + /** @var resource Query result resource */ + protected $__result; + + /** @var array Result information array */ + protected $__info; + + /** @var array List of static functions that extend record */ + protected $__extend = array(); + + /** @var integer Current result position */ + protected $__index = 0; + + /** @var array Current result row content */ + protected $__row = false; + + private $__fetch = false; + + /** + * Constructor + * + * Creates class instance from result link and some informations. + * $info is an array with the following content: + * + * - con => database object instance + * - cols => number of columns + * - rows => number of rows + * - info[name] => an array with columns names + * - info[type] => an array with columns types + * + * @param resource $result Resource result + * @param array $info Information array + */ + public function __construct($result,$info) + { + $this->__result = $result; + $this->__info = $info; + $this->__link = $info['con']->link(); + $this->index(0); + } + + /** + * To staticRecord + * + * Converts this record to a {@link staticRecord} instance. + */ + public function toStatic() + { + if ($this instanceof staticRecord) { + return $this; + } + return new staticRecord($this->__result,$this->__info); + } + + /** + * Magic call + * + * Magic call function. Calls function added by {@link extend()} if exists, passing it + * self object and arguments. + * + * @return mixed + */ + public function __call($f,$args) + { + if (isset($this->__extend[$f])) + { + array_unshift($args,$this); + return call_user_func_array($this->__extend[$f],$args); + } + + trigger_error('Call to undefined method record::'.$f.'()',E_USER_ERROR); + } + + /** + * Magic get + * + * Alias for {@link field()}. + * + * @param string|integer $n Field name + * @return string + */ + public function __get($n) + { + return $this->field($n); + } + + /** + * Get field + * + * Alias for {@link field()}. + * + * @param string|integer $n Field name + * @return string + */ + public function f($n) + { + return $this->field($n); + } + + /** + * Get field + * + * Retrieve field value by its name or column position. + * + * @param string|integer $n Field name + * @return string + */ + public function field($n) + { + return $this->__row[$n]; + } + + /** + * Field exists + * + * Returns true if a field exists. + * + * @param string $n Field name + * @return string + */ + public function exists($n) + { + return isset($this->__row[$n]); + } + + /** + * Extend record + * + * Extends this instance capabilities by adding all public static methods of + * $class to current instance. Class methods should take at least + * this record as first parameter. + * + * @see __call() + * + * @param string $class Class name + */ + public function extend($class) + { + if (!class_exists($class)) { + return; + } + + $c = new ReflectionClass($class); + foreach ($c->getMethods() as $m) { + if ($m->isStatic() && $m->isPublic()) { + $this->__extend[$m->name] = array($class,$m->name); + } + } + } + + /** + * Returns record extensions. + * + * @return array + */ + public function extensions() + { + return $this->__extend; + } + + private function setRow() + { + $this->__row = $this->__info['con']->db_fetch_assoc($this->__result); + + if ($this->__row !== false) + { + foreach ($this->__row as $k => $v) { + $this->__row[] =& $this->__row[$k]; + } + return true; + } + else + { + return false; + } + } + + /** + * Returns the current index position (0 is first) or move to $row if + * specified. + * + * @param integer $row Row number to move + * @return integer + */ + public function index($row=null) + { + if ($row === null) { + return $this->__index === null ? 0 : $this->__index; + } + + if ($row < 0 || $row+1 > $this->__info['rows']) { + return false; + } + + if ($this->__info['con']->db_result_seek($this->__result,(integer) $row)) + { + $this->__index = $row; + $this->setRow(); + $this->__info['con']->db_result_seek($this->__result,(integer) $row); + return true; + } + return false; + } + + /** + * One step move index + * + * This method moves index forward and return true until index is not + * the last one. You can use it to loop over record. Example: + * + * fetch()) { + * echo $rs->field1; + * } + * ?> + * + * + * @return boolean + */ + public function fetch() + { + if (!$this->__fetch) { + $this->__fetch = true; + $i = -1; + } else { + $i = $this->__index; + } + + if (!$this->index($i+1)) { + $this->__fetch = false; + $this->__index = 0; + return false; + } + + return true; + } + + /** + * Moves index to first position. + * + * @return boolean + */ + public function moveStart() + { + return $this->index(0); + } + + /** + * Moves index to last position. + * + * @return boolean + */ + public function moveEnd() + { + return $this->index($this->__info['rows']-1); + } + + /** + * Moves index to next position. + * + * @return boolean + */ + public function moveNext() + { + return $this->index($this->__index+1); + } + + /** + * Moves index to previous position. + * + * @return boolean + */ + public function movePrev() + { + return $this->index($this->__index-1); + } + + /** + * @return boolean true if index is at last position + */ + public function isEnd() + { + return $this->__index+1 == $this->count(); + } + + /** + * @return boolean true if index is at first position. + */ + public function isStart() + { + return $this->__index <= 0; + } + + /** + * @return boolean true if record contains no result. + */ + public function isEmpty() + { + return $this->count() == 0; + } + + /** + * @return integer number of rows in record + */ + public function count() + { + return $this->__info['rows']; + } + + /** + * @return array array of columns, with name as key and type as value. + */ + public function columns() + { + return $this->__info['info']['name']; + } + + /** + * @return array all rows in record. + */ + public function rows() + { + return $this->getData(); + } + + /** + * All data + * + * Returns an array of all rows in record. This method is called by rows(). + * + * @return array + */ + protected function getData() + { + $res = array(); + + if ($this->count() == 0) { + return $res; + } + + $this->__info['con']->db_result_seek($this->__result,0); + while (($r = $this->__info['con']->db_fetch_assoc($this->__result)) !== false) { + foreach ($r as $k => $v) { + $r[] =& $r[$k]; + } + $res[] = $r; + } + $this->__info['con']->db_result_seek($this->__result,$this->__index); + + return $res; + } +} + +/** +* Query Result Static Record Class +* +* Unlike record class, this one contains all results in an associative array. +* +* @package Clearbricks +* @subpackage DBLayer +*/ +class staticRecord extends record +{ + /** @var array Data array */ + public $__data = array(); + + private $__sortfield; + private $__sortsign; + + /** @ignore */ + public function __construct($result,$info) + { + if (is_array($result)) + { + $this->__info = $info; + $this->__data = $result; + } + else + { + parent::__construct($result,$info); + $this->__data = parent::getData(); + } + + unset($this->__link); + unset($this->__result); + } + + /** + * Static record from array + * + * Returns a new instance of object from an associative array. + * + * @param array $data Data array + * @return staticRecord + */ + public static function newFromArray($data) + { + if (!is_array($data)) { + $data = array(); + } + + $data = array_values($data); + + if (empty($data) || !is_array($data[0])) { + $cols = 0; + } else { + $cols = count($data[0]); + } + + $info = array( + 'con' => null, + 'info' => null, + 'cols' => $cols, + 'rows' => count($data) + ); + + return new self($data,$info); + } + + /** @ignore */ + public function field($n) + { + return $this->__data[$this->__index][$n]; + } + + /** @ignore */ + public function exists($n) + { + return isset($this->__data[$this->__index][$n]); + } + + /** @ignore */ + public function index($row=null) + { + if ($row === null) { + return $this->__index; + } + + if ($row < 0 || $row+1 > $this->__info['rows']) { + return false; + } + + $this->__index = $row; + return true; + } + + /** @ignore */ + public function rows() + { + return $this->__data; + } + + /** + * Changes value of a given field in the current row. + * + * @param string $n Field name + * @param string $v Field value + */ + public function set($n,$v) + { + if ($this->__index === null) { + return false; + } + + $this->__data[$this->__index][$n] = $v; + } + + /** + * Sorts values by a field in a given order. + * + * @param string $field Field name + * @param string $order Sort type (asc or desc) + */ + public function sort($field,$order='asc') + { + if (!isset($this->__data[0][$field])) { + return false; + } + + $this->__sortfield = $field; + $this->__sortsign = strtolower($order) == 'asc' ? 1 : -1; + + usort($this->__data,array($this,'sortCallback')); + + $this->__sortfield = null; + $this->__sortsign = null; + } + + private function sortCallback($a,$b) + { + $a = $a[$this->__sortfield]; + $b = $b[$this->__sortfield]; + + # Integer values + if ($a == (string) (integer) $a && $b == (string) (integer) $b) { + $a = (integer) $a; + $b = (integer) $b; + return ($a - $b) * $this->__sortsign; + } + + return strcmp($a,$b) * $this->__sortsign; + } +} +?> \ No newline at end of file diff --git a/inc/clearbricks/dbschema/class.dbschema.php b/inc/clearbricks/dbschema/class.dbschema.php new file mode 100644 index 0000000..54ac086 --- /dev/null +++ b/inc/clearbricks/dbschema/class.dbschema.php @@ -0,0 +1,310 @@ +array + */ + function db_get_tables(); + + /** + This method should return an associative array of columns in given table + $table with column names in keys. Each line value is an array + with following values: + + - [type] data type (string) + - [len] data length (integer or null) + - [null] is null? (boolean) + - [default] default value (string) + + @param table string Table name + @return array + */ + function db_get_columns($table); + + /** + This method should return an array of keys in given table + $table. Each line value is an array with following values: + + - [name] index name (string) + - [primary] primary key (boolean) + - [unique] unique key (boolean) + - [cols] columns (array) + + @param table string Table name + @return array + */ + function db_get_keys($table); + + /** + This method should return an array of indexes in given table + $table. Each line value is an array with following values: + + - [name] index name (string) + - [type] index type (string) + - [cols] columns (array) + + @param table string Table name + @return array + */ + function db_get_indexes($table); + + /** + This method should return an array of foreign keys in given table + $table. Each line value is an array with following values: + + - [name] key name (string) + - [c_cols] child columns (array) + - [p_table] parent table (string) + - [p_cols] parent columns (array) + - [update] on update statement (string) + - [delete] on delete statement (string) + + @param table string Table name + @return array + */ + function db_get_references($table); + + function db_create_table($name,$fields); + + function db_create_field($table,$name,$type,$len,$null,$default); + + function db_create_primary($table,$name,$cols); + + function db_create_unique($table,$name,$cols); + + function db_create_index($table,$name,$type,$cols); + + function db_create_reference($name,$c_table,$c_cols,$p_table,$p_cols,$update,$delete); + + function db_alter_field($table,$name,$type,$len,$null,$default); + + function db_alter_primary($table,$name,$newname,$cols); + + function db_alter_unique($table,$name,$newname,$cols); + + function db_alter_index($table,$name,$newname,$type,$cols); + + function db_alter_reference($name,$newname,$c_table,$c_cols,$p_table,$p_cols,$update,$delete); + + function db_drop_unique($table,$name); +} + +class dbSchema +{ + protected $con; + + public function __construct($con) + { + $this->con =& $con; + } + + public static function init($con) + { + $driver = $con->driver(); + $driver_class = $driver.'Schema'; + + if (!class_exists($driver_class)) + { + if (file_exists(dirname(__FILE__).'/class.'.$driver.'.dbschema.php')) { + require dirname(__FILE__).'/class.'.$driver.'.dbschema.php'; + } else { + trigger_error('Unable to load DB schema layer for '.$driver,E_USER_ERROR); + exit(1); + } + } + + return new $driver_class($con); + } + + /** + Database data type to universal data type conversion. + + @param type string Type name + @param leng integer Field length (in/out) + @param default string Default field value (in/out) + @return string + */ + public function dbt2udt($type,&$len,&$default) + { + $c = array( + 'bool' => 'boolean', + 'int2' => 'smallint', + 'int' => 'integer', + 'int4' => 'integer', + 'int8' => 'bigint', + 'float4' => 'real', + 'double precision' => 'float', + 'float8' => 'float', + 'decimal' => 'numeric', + 'character varying' => 'varchar', + 'character' => 'char' + ); + + if (isset($c[$type])) { + return $c[$type]; + } + + return $type; + } + + /** + Universal data type to database data tye conversion. + + @param type string Type name + @param leng integer Field length (in/out) + @param default string Default field value (in/out) + @return string + */ + public function udt2dbt($type,&$len,&$default) + { + return $type; + } + + /** + Returns an array of all table names. + + @see i_dbSchema::db_get_tables + @return array + */ + public function getTables() + { + return $this->db_get_tables(); + } + + /** + Returns an array of columns (name and type) of a given table. + + @see i_dbSchema::db_get_columns + @param table string Table name + @return array + */ + public function getColumns($table) + { + return $this->db_get_columns($table); + } + + /** + Returns an array of index of a given table. + + @see i_dbSchema::db_get_keys + @param table string Table name + @return array + */ + public function getKeys($table) + { + return $this->db_get_keys($table); + } + + /** + Returns an array of indexes of a given table. + + @see i_dbSchema::db_get_index + @param table string Table name + @return array + */ + public function getIndexes($table) + { + return $this->db_get_indexes($table); + } + + /** + Returns an array of foreign keys of a given table. + + @see i_dbSchema::db_get_references + @param table string Table name + @return array + */ + public function getReferences($table) + { + return $this->db_get_references($table); + } + + public function createTable($name,$fields) + { + return $this->db_create_table($name,$fields); + } + + public function createField($table,$name,$type,$len,$null,$default) + { + return $this->db_create_field($table,$name,$type,$len,$null,$default); + } + + public function createPrimary($table,$name,$cols) + { + return $this->db_create_primary($table,$name,$cols); + } + + public function createUnique($table,$name,$cols) + { + return $this->db_create_unique($table,$name,$cols); + } + + public function createIndex($table,$name,$type,$cols) + { + return $this->db_create_index($table,$name,$type,$cols); + } + + public function createReference($name,$c_table,$c_cols,$p_table,$p_cols,$update,$delete) + { + return $this->db_create_reference($name,$c_table,$c_cols,$p_table,$p_cols,$update,$delete); + } + + public function alterField($table,$name,$type,$len,$null,$default) + { + return $this->db_alter_field($table,$name,$type,$len,$null,$default); + } + + public function alterPrimary($table,$name,$newname,$cols) + { + return $this->db_alter_primary($table,$name,$newname,$cols); + } + + public function alterUnique($table,$name,$newname,$cols) + { + return $this->db_alter_unique($table,$name,$newname,$cols); + } + + public function alterIndex($table,$name,$newname,$type,$cols) + { + return $this->db_alter_index($table,$name,$newname,$type,$cols); + } + + public function alterReference($name,$newname,$c_table,$c_cols,$p_table,$p_cols,$update,$delete) + { + return $this->db_alter_reference($name,$newname,$c_table,$c_cols,$p_table,$p_cols,$update,$delete); + } + + public function dropUnique($table,$name) + { + return $this->db_drop_unique($table,$name); + } + + public function flushStack() + { + } +} +?> \ No newline at end of file diff --git a/inc/clearbricks/dbschema/class.dbstruct.php b/inc/clearbricks/dbschema/class.dbstruct.php new file mode 100644 index 0000000..20dec7d --- /dev/null +++ b/inc/clearbricks/dbschema/class.dbstruct.php @@ -0,0 +1,639 @@ +con =& $con; + $this->prefix = $prefix; + } + + public function driver() + { + return $this->con->driver(); + } + + public function table($name) + { + $this->tables[$name] = new dbStructTable($name); + return $this->tables[$name]; + } + + public function __get($name) + { + if (!isset($this->tables[$name])) { + return $this->table($name); + } + + return $this->tables[$name]; + } + + public function reverse() + { + $schema = dbSchema::init($this->con); + + # Get tables + $tables = $schema->getTables(); + + foreach ($tables as $t_name) + { + if ($this->prefix && strpos($t_name,$this->prefix) !== 0) { + continue; + } + + $t = $this->table($t_name); + + # Get columns + $cols = $schema->getColumns($t_name); + + foreach ($cols as $c_name => $col) { + $type = $schema->dbt2udt($col['type'],$col['len'],$col['default']); + $t->field($c_name,$type,$col['len'],$col['null'],$col['default'],true); + } + + # Get keys + $keys = $schema->getKeys($t_name); + + foreach ($keys as $k) + { + $args = $k['cols']; + array_unshift($args,$k['name']); + + if ($k['primary']) { + call_user_func_array(array($t,'primary'),$args); + } elseif ($k['unique']) { + call_user_func_array(array($t,'unique'),$args); + } + } + + # Get indexes + $idx = $schema->getIndexes($t_name); + foreach ($idx as $i) + { + $args = array($i['name'],$i['type']); + $args = array_merge($args,$i['cols']); + + call_user_func_array(array($t,'index'),$args); + } + + # Get foreign keys + $ref = $schema->getReferences($t_name); + foreach ($ref as $r) { + $t->reference($r['name'],$r['c_cols'],$r['p_table'],$r['p_cols'],$r['update'],$r['delete']); + } + } + } + + /** + Synchronize this schema taken from database with $schema. + + @param s dbStruct Structure to synchronize with + */ + public function synchronize($s) + { + $this->tables = array(); + $this->reverse(); + + if (!($s instanceof self)) { + throw new Exception('Invalid database schema'); + } + + $tables = $s->getTables(); + + $table_create = array(); + $key_create = array(); + $index_create = array(); + $reference_create = array(); + + $field_create = array(); + $field_update = array(); + $key_update = array(); + $index_update = array(); + $reference_update = array(); + + $got_work = false; + + $schema = dbSchema::init($this->con); + + foreach ($tables as $tname => $t) + { + if (!$this->tableExists($tname)) + { + # Table does not exist, create table + $table_create[$tname] = $t->getFields(); + + # Add keys, indexes and references + $keys = $t->getKeys(); + $indexes = $t->getIndexes(); + $references = $t->getReferences(); + + foreach ($keys as $k => $v) { + $key_create[$tname][$this->prefix.$k] = $v; + } + foreach ($indexes as $k => $v) { + $index_create[$tname][$this->prefix.$k] = $v; + } + foreach ($references as $k => $v) { + $v['p_table'] = $this->prefix.$v['p_table']; + $reference_create[$tname][$this->prefix.$k] = $v; + } + + $got_work = true; + } + else # Table exists + { + # Check new fields to create + $fields = $t->getFields(); + $db_fields = $this->tables[$tname]->getFields(); + foreach ($fields as $fname => $f) + { + if (!$this->tables[$tname]->fieldExists($fname)) + { + # Field doest not exist, create it + $field_create[$tname][$fname] = $f; + $got_work = true; + } + elseif ($this->fieldsDiffer($db_fields[$fname],$f)) + { + # Field exists and differs from db version + $field_update[$tname][$fname] = $f; + $got_work = true; + } + } + + # Check keys to add or upgrade + $keys = $t->getKeys(); + $db_keys = $this->tables[$tname]->getKeys(); + + foreach ($keys as $kname => $k) + { + if ($k['type'] == 'primary' && $this->con->driver() == 'mysql') { + $kname = 'PRIMARY'; + } else { + $kname = $this->prefix.$kname; + } + + $db_kname = $this->tables[$tname]->keyExists($kname,$k['type'],$k['cols']); + if (!$db_kname) + { + # Key does not exist, create it + $key_create[$tname][$kname] = $k; + $got_work = true; + } + elseif ($this->keysDiffer($db_kname,$db_keys[$db_kname]['cols'],$kname,$k['cols'])) + { + # Key exists and differs from db version + $key_update[$tname][$db_kname] = array_merge(array('name'=>$kname),$k); + $got_work = true; + } + } + + # Check index to add or upgrade + $idx = $t->getIndexes(); + $db_idx = $this->tables[$tname]->getIndexes(); + + foreach ($idx as $iname => $i) + { + $iname = $this->prefix.$iname; + $db_iname = $this->tables[$tname]->indexExists($iname,$i['type'],$i['cols']); + + if (!$db_iname) + { + # Index does not exist, create it + $index_create[$tname][$iname] = $i; + $got_work = true; + } + elseif ($this->indexesDiffer($db_iname,$db_idx[$db_iname],$iname,$i)) + { + # Index exists and differs from db version + $index_update[$tname][$db_iname] = array_merge(array('name'=>$iname),$i); + $got_work = true; + } + } + + # Check references to add or upgrade + $ref = $t->getReferences(); + $db_ref = $this->tables[$tname]->getReferences(); + + foreach ($ref as $rname => $r) + { + $rname = $this->prefix.$rname; + $r['p_table'] = $this->prefix.$r['p_table']; + $db_rname = $this->tables[$tname]->referenceExists($rname,$r['c_cols'],$r['p_table'],$r['p_cols']); + + if (!$db_rname) + { + # Reference does not exist, create it + $reference_create[$tname][$rname] = $r; + $got_work = true; + } + elseif ($this->referencesDiffer($db_rname,$db_ref[$db_rname],$rname,$r)) + { + $reference_update[$tname][$db_rname] = array_merge(array('name'=>$rname),$r); + $got_work = true; + } + } + } + } + + if (!$got_work) { + return; + } + + # Create tables + foreach ($table_create as $table => $fields) + { + $schema->createTable($table,$fields); + } + + # Create new fields + foreach ($field_create as $tname => $fields) + { + foreach ($fields as $fname => $f) { + $schema->createField($tname,$fname,$f['type'],$f['len'],$f['null'],$f['default']); + } + } + + # Update fields + foreach ($field_update as $tname => $fields) + { + foreach ($fields as $fname => $f) { + $schema->alterField($tname,$fname,$f['type'],$f['len'],$f['null'],$f['default']); + } + } + + # Create new keys + foreach ($key_create as $tname => $keys) + { + foreach ($keys as $kname => $k) + { + if ($k['type'] == 'primary') { + $schema->createPrimary($tname,$kname,$k['cols']); + } elseif ($k['type'] == 'unique') { + $schema->createUnique($tname,$kname,$k['cols']); + } + } + } + + # Update keys + foreach ($key_update as $tname => $keys) + { + foreach ($keys as $kname => $k) + { + if ($k['type'] == 'primary') { + $schema->alterPrimary($tname,$kname,$k['name'],$k['cols']); + } elseif ($k['type'] == 'unique') { + $schema->alterUnique($tname,$kname,$k['name'],$k['cols']); + } + } + } + + # Create indexes + foreach ($index_create as $tname => $index) + { + foreach ($index as $iname => $i) { + $schema->createIndex($tname,$iname,$i['type'],$i['cols']); + } + } + + # Update indexes + foreach ($index_update as $tname => $index) + { + foreach ($index as $iname => $i) { + $schema->alterIndex($tname,$iname,$i['name'],$i['type'],$i['cols']); + } + } + + # Create references + foreach ($reference_create as $tname => $ref) + { + foreach ($ref as $rname => $r) + { + $schema->createReference($rname,$tname,$r['c_cols'],$r['p_table'],$r['p_cols'],$r['update'],$r['delete']); + } + } + + # Update references + foreach ($reference_update as $tname => $ref) + { + foreach ($ref as $rname => $r) { + $schema->alterReference($rname,$r['name'],$tname,$r['c_cols'],$r['p_table'],$r['p_cols'],$r['update'],$r['delete']); + } + } + + # Flush execution stack + $schema->flushStack(); + + return + count($table_create) + count($key_create) + count($index_create) + + count($reference_create) + count($field_create) + count($field_update) + + count($key_update) + count($index_update) + count($reference_update); + } + + public function getTables() + { + $res = array(); + foreach ($this->tables as $t => $v) + { + $res[$this->prefix.$t] = $v; + } + + return $res; + } + + public function tableExists($name) + { + return isset($this->tables[$name]); + } + + private function fieldsDiffer($db_field,$schema_field) + { + $d_type = $db_field['type']; + $d_len = (integer) $db_field['len']; + $d_default = $db_field['default']; + $d_null = $db_field['null']; + + $s_type = $schema_field['type']; + $s_len = (integer) $schema_field['len']; + $s_default = $schema_field['default']; + $s_null = $schema_field['null']; + + return $d_type != $s_type || $d_len != $s_len || $d_default != $s_default || $d_null != $s_null; + } + + private function keysDiffer($d_name,$d_cols,$s_name,$s_cols) + { + return $d_name != $s_name || $d_cols != $s_cols; + } + + private function indexesDiffer($d_name,$d_i,$s_name,$s_i) + { + return $d_name != $s_name || $d_i['cols'] != $s_i['cols'] || $d_i['type'] != $s_i['type']; + } + + private function referencesDiffer($d_name,$d_r,$s_name,$s_r) + { + return + $d_name != $s_name || $d_r['c_cols'] != $s_r['c_cols'] + || $d_r['p_table'] != $s_r['p_table'] || $d_r['p_cols'] != $s_r['p_cols'] + || $d_r['update'] != $s_r['update'] || $d_r['delete'] != $s_r['delete']; + } +} + +class dbStructTable +{ + protected $name; + protected $has_primary = false; + + protected $fields = array(); + protected $keys = array(); + protected $indexes = array(); + protected $references = array(); + + /** + Universal data types supported by dbSchema + + SMALLINT : signed 2 bytes integer + INTEGER : signed 4 bytes integer + BIGINT : signed 8 bytes integer + REAL : signed 4 bytes floating point number + FLOAT : signed 8 bytes floating point number + NUMERIC : exact numeric type + + DATE : Calendar date (day, month and year) + TIME : Time of day + TIMESTAMP : Date and time + + CHAR : A fixed n-length character string + VARCHAR : A variable length character string + TEXT : A variable length of text + */ + protected $allowed_types = array( + 'smallint','integer','bigint','real','float','numeric', + 'date','time','timestamp', + 'char','varchar','text' + ); + + public function __construct($name) + { + $this->name = $name; + return $this; + } + + public function getFields() + { + return $this->fields; + } + + public function getKeys($primary=null) + { + return $this->keys; + } + + public function getIndexes() + { + return $this->indexes; + } + + public function getReferences() + { + return $this->references; + } + + public function fieldExists($name) + { + return isset($this->fields[$name]); + } + + public function keyExists($name,$type,$cols) + { + # Look for key with the same name + if (isset($this->keys[$name])) { + return $name; + } + + # Look for key with the same columns list and type + foreach ($this->keys as $n => $k) + { + if ($k['cols'] == $cols && $k['type'] == $type) { + # Same columns and type, return new name + return $n; + } + } + + return false; + } + + public function indexExists($name,$type,$cols) + { + # Look for key with the same name + if (isset($this->indexes[$name])) { + return $name; + } + + # Look for index with the same columns list and type + foreach ($this->indexes as $n => $i) + { + if ($i['cols'] == $cols && $i['type'] == $type) { + # Same columns and type, return new name + return $n; + } + } + + return false; + } + + public function referenceExists($name,$c_cols,$p_table,$p_cols) + { + if (isset($this->references[$name])) { + return $name; + } + + # Look for reference with same chil columns, parent table and columns + foreach ($this->references as $n => $r) + { + if ($c_cols == $r['c_cols'] && $p_table == $r['p_table'] && $p_cols == $r['p_cols']) { + # Only name differs, return new name + return $n; + } + } + + return false; + } + + public function field($name,$type,$len,$null=true,$default=false,$to_null=false) + { + $type = strtolower($type); + + if (!in_array($type,$this->allowed_types)) + { + if ($to_null) { + $type = null; + } else { + throw new Exception('Invalid data type '.$type.' in schema'); + } + } + + $this->fields[$name] = array( + 'type' => $type, + 'len' => (integer) $len, + 'default' => $default, + 'null' => (boolean) $null + ); + + return $this; + } + + public function __call($name,$args) + { + array_unshift($args,$name); + return call_user_func_array(array($this,'field'),$args); + } + + public function primary($name,$col) + { + if ($this->has_primary) { + throw new Exception(sprintf('Table %s already has a primary key',$this->name)); + } + + $cols = func_get_args(); + array_shift($cols); + + return $this->newKey('primary',$name,$cols); + } + + public function unique($name,$col) + { + $cols = func_get_args(); + array_shift($cols); + + return $this->newKey('unique',$name,$cols); + } + + public function index($name,$type,$col) + { + $cols = func_get_args(); + array_shift($cols); + array_shift($cols); + + $this->checkCols($cols); + + $this->indexes[$name] = array( + 'type' => strtolower($type), + 'cols' => $cols + ); + + return $this; + } + + public function reference($name,$c_cols,$p_table,$p_cols,$update=false,$delete=false) + { + if (!is_array($p_cols)) { + $p_cols = array($p_cols); + } + if (!is_array($c_cols)) { + $c_cols = array($c_cols); + } + + $this->checkCols($c_cols); + + $this->references[$name] = array( + 'c_cols' => $c_cols, + 'p_table' => $p_table, + 'p_cols' => $p_cols, + 'update' => $update, + 'delete' => $delete + ); + } + + protected function newKey($type,$name,$cols) + { + $this->checkCols($cols); + + $this->keys[$name] = array( + 'type' => $type, + 'cols' => $cols + ); + + if ($type == 'primary') { + $this->has_primary = true; + } + + return $this; + } + + protected function checkCols($cols) + { + foreach ($cols as $v) { + if (!preg_match('/^\(.*?\)$/',$v) && !isset($this->fields[$v])) { + throw new Exception(sprintf('Field %s does not exist in table %s',$v,$this->name)); + } + } + } +} +?> \ No newline at end of file diff --git a/inc/clearbricks/dbschema/class.mysql.dbschema.php b/inc/clearbricks/dbschema/class.mysql.dbschema.php new file mode 100644 index 0000000..af1963f --- /dev/null +++ b/inc/clearbricks/dbschema/class.mysql.dbschema.php @@ -0,0 +1,470 @@ +con->select($sql); + + $res = array(); + while ($rs->fetch()) { + $res[] = $rs->f(0); + } + return $res; + } + + public function db_get_columns($table) + { + $sql = 'SHOW COLUMNS FROM '.$this->con->escapeSystem($table); + $rs = $this->con->select($sql); + + $res = array(); + while ($rs->fetch()) + { + $field = trim($rs->f('Field')); + $type = trim($rs->f('Type')); + $null = strtolower($rs->f('Null')) == 'yes'; + $default = $rs->f('Default'); + + $len = null; + if (preg_match('/^(.+?)\(([\d,]+)\)$/si',$type,$m)) { + $type = $m[1]; + $len = (integer) $m[2]; + } + + if ($default != '' && !is_numeric($default)) { + $default = "'".$default."'"; + } + + $res[$field] = array( + 'type' => $type, + 'len' => $len, + 'null' => $null, + 'default' => $default + ); + } + return $res; + } + + public function db_get_keys($table) + { + $sql = 'SHOW INDEX FROM '.$this->con->escapeSystem($table); + $rs = $this->con->select($sql); + + $t = array(); + $res = array(); + while ($rs->fetch()) + { + $key_name = $rs->f('Key_name'); + $unique = $rs->f('Non_unique') == 0; + $seq = $rs->f('Seq_in_index'); + $col_name = $rs->f('Column_name'); + + if ($key_name == 'PRIMARY' || $unique) { + $t[$key_name]['cols'][$seq] = $col_name; + $t[$key_name]['unique'] = $unique; + } + } + + foreach ($t as $name => $idx) + { + ksort($idx['cols']); + + $res[] = array( + 'name' => $name, + 'primary' => $name == 'PRIMARY', + 'unique' => $idx['unique'], + 'cols' => array_values($idx['cols']) + ); + } + + return $res; + } + + public function db_get_indexes($table) + { + $sql = 'SHOW INDEX FROM '.$this->con->escapeSystem($table); + $rs = $this->con->select($sql); + + $t = array(); + $res = array(); + while ($rs->fetch()) + { + $key_name = $rs->f('Key_name'); + $unique = $rs->f('Non_unique') == 0; + $seq = $rs->f('Seq_in_index'); + $col_name = $rs->f('Column_name'); + $type = $rs->f('Index_type'); + + if ($key_name != 'PRIMARY' && !$unique) { + $t[$key_name]['cols'][$seq] = $col_name; + $t[$key_name]['type'] = $type; + } + } + + foreach ($t as $name => $idx) + { + ksort($idx['cols']); + + $res[] = array( + 'name' => $name, + 'type' => $idx['type'], + 'cols' => $idx['cols'] + ); + } + + return $res; + } + + public function db_get_references($table) + { + $sql = 'SHOW CREATE TABLE '.$this->con->escapeSystem($table); + $rs = $this->con->select($sql); + + $s = $rs->f(1); + + $res = array(); + + $n = preg_match_all('/^\s*CONSTRAINT\s+`(.+?)`\s+FOREIGN\s+KEY\s+\((.+?)\)\s+REFERENCES\s+`(.+?)`\s+\((.+?)\)(.*?)$/msi',$s,$match); + if ($n > 0) + { + foreach ($match[1] as $i => $name) + { + # Columns transformation + $t_cols = str_replace('`','',$match[2][$i]); + $t_cols = explode(',',$t_cols); + $r_cols = str_replace('`','',$match[4][$i]); + $r_cols = explode(',',$r_cols); + + # ON UPDATE|DELETE + $on = trim($match[5][$i],', '); + $on_delete = null; + $on_update = null; + if ($on != '') { + if (preg_match('/ON DELETE (.+?)(?:\s+ON|$)/msi',$on,$m)) { + $on_delete = strtolower(trim($m[1])); + } + if (preg_match('/ON UPDATE (.+?)(?:\s+ON|$)/msi',$on,$m)) { + $on_update = strtolower(trim($m[1])); + } + } + + $res[] = array ( + 'name' => $name, + 'c_cols' => $t_cols, + 'p_table' => $match[3][$i], + 'p_cols' => $r_cols, + 'update' => $on_update, + 'delete' => $on_delete + ); + } + } + return $res; + } + + public function db_create_table($name,$fields) + { + $a = array(); + + foreach ($fields as $n => $f) + { + $type = $f['type']; + $len = (integer) $f['len']; + $default = $f['default']; + $null = $f['null']; + + $type = $this->udt2dbt($type,$len,$default); + $len = $len > 0 ? '('.$len.')' : ''; + $null = $null ? 'NULL' : 'NOT NULL'; + + if ($default === null) { + $default = 'DEFAULT NULL'; + } elseif ($default !== false) { + $default = 'DEFAULT '.$default.' '; + } else { + $default = ''; + } + + $a[] = + $this->con->escapeSystem($n).' '. + $type.$len.' '.$null.' '.$default; + } + + $sql = + 'CREATE TABLE '.$this->con->escapeSystem($name)." (\n". + implode(",\n",$a). + "\n) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin "; + + $this->con->execute($sql); + } + + public function db_create_field($table,$name,$type,$len,$null,$default) + { + $type = $this->udt2dbt($type,$len,$default); + $len = (integer) $len > 0 ? '('.(integer) $len.')' : ''; + $null = $null ? 'NULL' : 'NOT NULL'; + + if ($default === null) { + $default = 'DEFAULT NULL'; + } elseif ($default !== false) { + $default = 'DEFAULT '.$default; + } else { + $default = ''; + } + + $sql = + 'ALTER TABLE '.$this->con->escapeSystem($table).' '. + 'ADD COLUMN '.$this->con->escapeSystem($name).' '. + $type.$len.' '.$null.' '.$default; + + $this->con->execute($sql); + } + + public function db_create_primary($table,$name,$cols) + { + $c = array(); + foreach ($cols as $v) { + $c[] = $this->con->escapeSystem($v); + } + + $sql = + 'ALTER TABLE '.$this->con->escapeSystem($table).' '. + 'ADD CONSTRAINT PRIMARY KEY ('.implode(',',$c).') '; + + $this->con->execute($sql); + } + + public function db_create_unique($table,$name,$cols) + { + $c = array(); + foreach ($cols as $v) { + $c[] = $this->con->escapeSystem($v); + } + + $sql = + 'ALTER TABLE '.$this->con->escapeSystem($table).' '. + 'ADD CONSTRAINT UNIQUE KEY '.$this->con->escapeSystem($name).' '. + '('.implode(',',$c).') '; + + $this->con->execute($sql); + } + + public function db_create_index($table,$name,$type,$cols) + { + $c = array(); + foreach ($cols as $v) { + $c[] = $this->con->escapeSystem($v); + } + + $sql = + 'ALTER TABLE '.$this->con->escapeSystem($table).' '. + 'ADD INDEX '.$this->con->escapeSystem($name).' USING '.$type.' '. + '('.implode(',',$c).') '; + + $this->con->execute($sql); + } + + public function db_create_reference($name,$c_table,$c_cols,$p_table,$p_cols,$update,$delete) + { + $c = array(); + $p = array(); + foreach ($c_cols as $v) { + $c[] = $this->con->escapeSystem($v); + } + foreach ($p_cols as $v) { + $p[] = $this->con->escapeSystem($v); + } + + $sql = + 'ALTER TABLE '.$this->con->escapeSystem($c_table).' '. + 'ADD CONSTRAINT '.$name.' FOREIGN KEY '. + '('.implode(',',$c).') '. + 'REFERENCES '.$this->con->escapeSystem($p_table).' '. + '('.implode(',',$p).') '; + + if ($update) { + $sql .= 'ON UPDATE '.$update.' '; + } + if ($delete) { + $sql .= 'ON DELETE '.$delete.' '; + } + + $this->con->execute($sql); + } + + public function db_alter_field($table,$name,$type,$len,$null,$default) + { + $type = $this->udt2dbt($type,$len,$default); + $len = (integer) $len > 0 ? '('.(integer) $len.')' : ''; + $null = $null ? 'NULL' : 'NOT NULL'; + + if ($default === null) { + $default = 'DEFAULT NULL'; + } elseif ($default !== false) { + $default = 'DEFAULT '.$default; + } else { + $default = ''; + } + + $sql = + 'ALTER TABLE '.$this->con->escapeSystem($table).' '. + 'CHANGE COLUMN '.$this->con->escapeSystem($name).' '.$this->con->escapeSystem($name).' '. + $type.$len.' '.$null.' '.$default; + + $this->con->execute($sql); + } + + public function db_alter_primary($table,$name,$newname,$cols) + { + $c = array(); + foreach ($cols as $v) { + $c[] = $this->con->escapeSystem($v); + } + + $sql = + 'ALTER TABLE '.$this->con->escapeSystem($table).' '. + 'DROP PRIMARY KEY, ADD PRIMARY KEY '. + '('.implode(',',$c).') '; + + $this->con->execute($sql); + } + + public function db_alter_unique($table,$name,$newname,$cols) + { + $c = array(); + foreach ($cols as $v) { + $c[] = $this->con->escapeSystem($v); + } + + $sql = + 'ALTER TABLE '.$this->con->escapeSystem($table).' '. + 'DROP INDEX '.$this->con->escapeSystem($name).', '. + 'ADD UNIQUE '.$this->con->escapeSystem($newname).' '. + '('.implode(',',$c).') '; + + $this->con->execute($sql); + } + + public function db_alter_index($table,$name,$newname,$type,$cols) + { + $c = array(); + foreach ($cols as $v) { + $c[] = $this->con->escapeSystem($v); + } + + $sql = + 'ALTER TABLE '.$this->con->escapeSystem($table).' '. + 'DROP INDEX '.$this->con->escapeSystem($name).', '. + 'ADD INDEX '.$this->con->escapeSystem($newname).' '. + 'USING '.$type.' '. + '('.implode(',',$c).') '; + + $this->con->execute($sql); + } + + public function db_alter_reference($name,$newname,$c_table,$c_cols,$p_table,$p_cols,$update,$delete) + { + $sql = + 'ALTER TABLE '.$this->con->escapeSystem($c_table).' '. + 'DROP FOREIGN KEY '.$this->con->escapeSystem($name); + + $this->con->execute($sql); + $this->createReference($newname,$c_table,$c_cols,$p_table,$p_cols,$update,$delete); + } + + public function db_drop_unique($table,$name) + { + $sql = + 'ALTER TABLE '.$this->con->escapeSystem($table).' '. + 'DROP INDEX '.$this->con->escapeSystem($name); + $this->con->execute($sql); + } + } +} +?> \ No newline at end of file diff --git a/inc/clearbricks/dbschema/class.pgsql.dbschema.php b/inc/clearbricks/dbschema/class.pgsql.dbschema.php new file mode 100644 index 0000000..3745713 --- /dev/null +++ b/inc/clearbricks/dbschema/class.pgsql.dbschema.php @@ -0,0 +1,400 @@ + 'no action', + 'r' => 'restrict', + 'c' => 'cascade', + 'n' => 'set null', + 'd' => 'set default' + ); + + public function dbt2udt($type,&$len,&$default) + { + $type = parent::dbt2udt($type,$len,$default); + + return $type; + } + + public function udt2dbt($type,&$len,&$default) + { + $type = parent::udt2dbt($type,$len,$default); + + return $type; + } + + public function db_get_tables() + { + $sql = + 'SELECT table_name '. + 'FROM information_schema.tables '. + "WHERE table_schema = 'public' "; + + $rs = $this->con->select($sql); + + $res = array(); + while ($rs->fetch()) { + $res[] = $rs->f(0); + } + return $res; + } + + public function db_get_columns($table) + { + $sql = + 'SELECT column_name, udt_name, character_maximum_length, '. + 'is_nullable, column_default '. + 'FROM information_schema.columns '. + "WHERE table_name = '".$this->con->escape($table)."' "; + + $rs = $this->con->select($sql); + + $res = array(); + while ($rs->fetch()) + { + $field = trim($rs->column_name); + $type = trim($rs->udt_name); + $null = strtolower($rs->is_nullable) == 'yes'; + $default = $rs->column_default; + $len = $rs->character_maximum_length; + + if ($len == '') { + $len = null; + } + + $default = preg_replace('/::([\w\d\s]*)$/','',$default); + + $res[$field] = array( + 'type' => $type, + 'len' => $len, + 'null' => $null, + 'default' => $default + ); + } + + return $res; + } + + public function db_get_keys($table) + { + $sql = + 'SELECT DISTINCT ON(cls.relname) cls.oid, cls.relname as idxname, indisunique::integer, indisprimary::integer, '. + 'indnatts, tab.relname as tabname, contype, amname '. + 'FROM pg_index idx '. + 'JOIN pg_class cls ON cls.oid=indexrelid '. + 'JOIN pg_class tab ON tab.oid=indrelid '. + 'LEFT OUTER JOIN pg_tablespace ta on ta.oid=cls.reltablespace '. + 'JOIN pg_namespace n ON n.oid=tab.relnamespace '. + 'JOIN pg_am am ON am.oid=cls.relam '. + "LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0') ". + 'LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid) '. + 'LEFT OUTER JOIN pg_description des ON des.objoid=con.oid '. + 'LEFT OUTER JOIN pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0) '. + "WHERE tab.relname = '".$this->con->escape($table)."' ". + "AND contype IN ('p','u') ". + 'ORDER BY cls.relname '; + + $rs = $this->con->select($sql); + + $res = array(); + while ($rs->fetch()) + { + $k = array( + 'name' => $rs->idxname, + 'primary' => (boolean) $rs->indisprimary, + 'unique' => (boolean) $rs->indisunique, + 'cols' => array() + ); + + for ($i=1; $i<=$rs->indnatts; $i++) { + $cols = $this->con->select('SELECT pg_get_indexdef('.$rs->oid.'::oid, '.$i.', true);'); + $k['cols'][] = $cols->f(0); + } + + $res[] = $k; + } + + return $res; + } + + public function db_get_indexes($table) + { + $sql = + 'SELECT DISTINCT ON(cls.relname) cls.oid, cls.relname as idxname, n.nspname, '. + 'indnatts, tab.relname as tabname, contype, amname '. + 'FROM pg_index idx '. + 'JOIN pg_class cls ON cls.oid=indexrelid '. + 'JOIN pg_class tab ON tab.oid=indrelid '. + 'LEFT OUTER JOIN pg_tablespace ta on ta.oid=cls.reltablespace '. + 'JOIN pg_namespace n ON n.oid=tab.relnamespace '. + 'JOIN pg_am am ON am.oid=cls.relam '. + "LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0') ". + 'LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid) '. + 'LEFT OUTER JOIN pg_description des ON des.objoid=con.oid '. + 'LEFT OUTER JOIN pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0) '. + "WHERE tab.relname = '".$this->con->escape($table)."' ". + 'AND conname IS NULL '. + 'ORDER BY cls.relname '; + + $rs = $this->con->select($sql); + + $res = array(); + while ($rs->fetch()) + { + $k = array( + 'name' => $rs->idxname, + 'type' => $rs->amname, + 'cols' => array() + ); + + for ($i=1; $i<=$rs->indnatts; $i++) { + $cols = $this->con->select('SELECT pg_get_indexdef('.$rs->oid.'::oid, '.$i.', true);'); + $k['cols'][] = $cols->f(0); + } + + $res[] = $k; + } + + return $res; + } + + public function db_get_references($table) + { + $sql = + 'SELECT ct.oid, conname, condeferrable, condeferred, confupdtype, '. + 'confdeltype, confmatchtype, conkey, confkey, conrelid, confrelid, cl.relname as fktab, '. + 'cr.relname as reftab '. + 'FROM pg_constraint ct '. + 'JOIN pg_class cl ON cl.oid=conrelid '. + 'JOIN pg_namespace nl ON nl.oid=cl.relnamespace '. + 'JOIN pg_class cr ON cr.oid=confrelid '. + 'JOIN pg_namespace nr ON nr.oid=cr.relnamespace '. + "WHERE contype='f' ". + "AND cl.relname = '".$this->con->escape($table)."' ". + 'ORDER BY conname '; + + $rs = $this->con->select($sql); + + $cols_sql = + 'SELECT a1.attname as conattname, a2.attname as confattname '. + 'FROM pg_attribute a1, pg_attribute a2 '. + 'WHERE a1.attrelid=%1$s::oid AND a1.attnum=%2$s '. + 'AND a2.attrelid=%3$s::oid AND a2.attnum=%4$s '; + + $res = array(); + while ($rs->fetch()) + { + $conkey = preg_replace('/[^\d]/','',$rs->conkey); + $confkey = preg_replace('/[^\d]/','',$rs->confkey); + + $k = array( + 'name' => $rs->conname, + 'c_cols' => array(), + 'p_table' => $rs->reftab, + 'p_cols' => array(), + 'update' => $this->ref_actions_map[$rs->confupdtype], + 'delete' => $this->ref_actions_map[$rs->confdeltype] + ); + + $cols = $this->con->select(sprintf($cols_sql,$rs->conrelid,$conkey,$rs->confrelid,$confkey)); + while ($cols->fetch()) { + $k['c_cols'][] = $cols->conattname; + $k['p_cols'][] = $cols->confattname; + } + + $res[] = $k; + } + + return $res; + } + + public function db_create_table($name,$fields) + { + $a = array(); + + foreach ($fields as $n => $f) + { + $type = $f['type']; + $len = (integer) $f['len']; + $default = $f['default']; + $null = $f['null']; + + $type = $this->udt2dbt($type,$len,$default); + $len = $len > 0 ? '('.$len.')' : ''; + $null = $null ? 'NULL' : 'NOT NULL'; + + if ($default === null) { + $default = 'DEFAULT NULL'; + } elseif ($default !== false) { + $default = 'DEFAULT '.$default.' '; + } else { + $default = ''; + } + + $a[] = + $n.' '. + $type.$len.' '.$null.' '.$default; + } + + $sql = + 'CREATE TABLE '.$name." (\n". + implode(",\n",$a). + "\n)"; + + $this->con->execute($sql); + } + + public function db_create_field($table,$name,$type,$len,$null,$default) + { + $type = $this->udt2dbt($type,$len,$default); + $len = $len > 0 ? '('.$len.')' : ''; + $null = $null ? 'NULL' : 'NOT NULL'; + + if ($default === null) { + $default = 'DEFAULT NULL'; + } elseif ($default !== false) { + $default = 'DEFAULT '.$default.' '; + } else { + $default = ''; + } + + $sql = + 'ALTER TABLE '.$table.' ADD COLUMN '.$name.' '. + $type.$len.' '.$null.' '.$default; + + $this->con->execute($sql); + } + + public function db_create_primary($table,$name,$cols) + { + $sql = + 'ALTER TABLE '.$table.' '. + 'ADD CONSTRAINT '.$name.' PRIMARY KEY ('.implode(",",$cols).') '; + + $this->con->execute($sql); + } + + public function db_create_unique($table,$name,$cols) + { + $sql = + 'ALTER TABLE '.$table.' '. + 'ADD CONSTRAINT '.$name.' UNIQUE ('.implode(',',$cols).') '; + + $this->con->execute($sql); + } + + public function db_create_index($table,$name,$type,$cols) + { + $sql = + 'CREATE INDEX '.$name.' ON '.$table.' USING '.$type. + '('.implode(',',$cols).') '; + + $this->con->execute($sql); + } + + public function db_create_reference($name,$c_table,$c_cols,$p_table,$p_cols,$update,$delete) + { + $sql = + 'ALTER TABLE '.$c_table.' '. + 'ADD CONSTRAINT '.$name.' FOREIGN KEY '. + '('.implode(',',$c_cols).') '. + 'REFERENCES '.$p_table.' '. + '('.implode(',',$p_cols).') '; + + if ($update) { + $sql .= 'ON UPDATE '.$update.' '; + } + if ($delete) { + $sql .= 'ON DELETE '.$delete.' '; + } + + $this->con->execute($sql); + } + + public function db_alter_field($table,$name,$type,$len,$null,$default) + { + $type = $this->udt2dbt($type,$len,$default); + $len = (integer) $len > 0 ? '('.(integer) $len.')' : ''; + + $sql = 'ALTER TABLE '.$table.' ALTER COLUMN '.$name.' TYPE '.$type.$len; + $this->con->execute($sql); + + if ($default === null) { + $default = 'SET DEFAULT NULL'; + } elseif ($default !== false) { + $default = 'SET DEFAULT '.$default; + } else { + $default = 'DROP DEFAULT'; + } + + $sql = 'ALTER TABLE '.$table.' ALTER COLUMN '.$name.' '.$default; + $this->con->execute($sql); + + $null = $null ? 'DROP NOT NULL' : 'SET NOT NULL'; + $sql = 'ALTER TABLE '.$table.' ALTER COLUMN '.$name.' '.$null; + $this->con->execute($sql); + } + + public function db_alter_primary($table,$name,$newname,$cols) + { + $sql = 'ALTER TABLE '.$table.' DROP CONSTRAINT '.$name; + $this->con->execute($sql); + + $this->createPrimary($table,$newname,$cols); + } + + public function db_alter_unique($table,$name,$newname,$cols) + { + $sql = 'ALTER TABLE '.$table.' DROP CONSTRAINT '.$name; + $this->con->execute($sql); + + $this->createUnique($table,$newname,$cols); + } + + public function db_alter_index($table,$name,$newname,$type,$cols) + { + $sql = 'DROP INDEX '.$name; + $this->con->execute($sql); + + $this->createIndex($table,$newname,$type,$cols); + } + + public function db_alter_reference($name,$newname,$c_table,$c_cols,$p_table,$p_cols,$update,$delete) + { + $sql = 'ALTER TABLE '.$c_table.' DROP CONSTRAINT '.$name; + $this->con->execute($sql); + + $this->createReference($newname,$c_table,$c_cols,$p_table,$p_cols,$update,$delete); + } + + public function db_drop_unique($table,$name) + { + $sql = 'ALTER TABLE '.$table.' DROP CONSTRAINT '.$name; + $this->con->execute($sql); + } + } +} +?> \ No newline at end of file diff --git a/inc/clearbricks/dbschema/class.sqlite.dbschema.php b/inc/clearbricks/dbschema/class.sqlite.dbschema.php new file mode 100644 index 0000000..aa0b336 --- /dev/null +++ b/inc/clearbricks/dbschema/class.sqlite.dbschema.php @@ -0,0 +1,515 @@ +table_stack as $table => $def) + { + $sql = 'CREATE TABLE '.$table." (\n".implode(",\n",$def)."\n)\n "; + $this->con->execute($sql); + } + + foreach ($this->x_stack as $x) + { + $this->con->execute($x); + } + + } + + public function db_get_tables() + { + $res = array(); + $sql = "SELECT * FROM sqlite_master WHERE type = 'table'"; + $rs = $this->con->select($sql); + + $res = array(); + while ($rs->fetch()) { + $res[] = $rs->tbl_name; + } + + return $res; + } + + public function db_get_columns($table) + { + $sql = 'PRAGMA table_info('.$this->con->escapeSystem($table).')'; + $rs = $this->con->select($sql); + + $res = array(); + while ($rs->fetch()) + { + $field = trim($rs->name); + $type = trim($rs->type); + $null = trim($rs->notnull) == 0; + $default = trim($rs->dflt_value); + + $len = null; + if (preg_match('/^(.+?)\(([\d,]+)\)$/si',$type,$m)) { + $type = $m[1]; + $len = (integer) $m[2]; + } + + $res[$field] = array( + 'type' => $type, + 'len' => $len, + 'null' => $null, + 'default' => $default + ); + } + return $res; + } + + public function db_get_keys($table) + { + $t = array(); + $res = array(); + + # Get primary keys first + $sql = "SELECT sql FROM sqlite_master WHERE type='table' AND name='".$this->con->escape($table)."'"; + $rs = $this->con->select($sql); + + if ($rs->isEmpty()) { + return array(); + } + + # Get primary keys + $n = preg_match_all('/^\s*CONSTRAINT\s+([^,]+?)\s+PRIMARY\s+KEY\s+\((.+?)\)/msi',$rs->sql,$match); + if ($n > 0) + { + foreach ($match[1] as $i => $name) + { + $cols = preg_split('/\s*,\s*/',$match[2][$i]); + $res[] = array( + 'name' => $name, + 'primary' => true, + 'unique' => false, + 'cols' => $cols + ); + } + } + + # Get unique keys + $n = preg_match_all('/^\s*CONSTRAINT\s+([^,]+?)\s+UNIQUE\s+\((.+?)\)/msi',$rs->sql,$match); + if ($n > 0) + { + foreach ($match[1] as $i => $name) + { + $cols = preg_split('/\s*,\s*/',$match[2][$i]); + $res[] = array( + 'name' => $name, + 'primary' => false, + 'unique' => true, + 'cols' => $cols + ); + } + } + + return $res; + } + + public function db_get_indexes($table) + { + $sql = 'PRAGMA index_list('.$this->con->escapeSystem($table).')'; + $rs = $this->con->select($sql); + + $res = array(); + while ($rs->fetch()) + { + if (preg_match('/^sqlite_/',$rs->name)) { + continue; + } + + $idx = $this->con->select('PRAGMA index_info('.$this->con->escapeSystem($rs->name).')'); + $cols = array(); + while ($idx->fetch()) { + $cols[] = $idx->name; + } + + $res[] = array( + 'name' => $rs->name, + 'type' => 'btree', + 'cols' => $cols + ); + } + + return $res; + } + + public function db_get_references($table) + { + $sql = 'SELECT * FROM sqlite_master WHERE type=\'trigger\' AND tbl_name = \'%1$s\' AND name LIKE \'%2$s_%%\' '; + $res = array(); + + # Find constraints on table + $bir = $this->con->select(sprintf($sql,$this->con->escape($table),'bir')); + $bur = $this->con->select(sprintf($sql,$this->con->escape($table),'bur')); + + if ($bir->isEmpty() || $bur->isempty()) { + return $res; + } + + while ($bir->fetch()) + { + # Find child column and parent table and column + if (!preg_match('/FROM\s+(.+?)\s+WHERE\s+(.+?)\s+=\s+NEW\.(.+?)\s*?\) IS\s+NULL/msi',$bir->sql,$m)) { + continue; + } + + $c_col = $m[3]; + $p_table = $m[1]; + $p_col = $m[2]; + + # Find on update + $on_update = 'restrict'; + $aur = $this->con->select(sprintf($sql,$this->con->escape($p_table),'aur')); + while ($aur->fetch()) + { + if (!preg_match('/AFTER\s+UPDATE/msi',$aur->sql)) { + continue; + } + + if (preg_match('/UPDATE\s+'.$table.'\s+SET\s+'.$c_col.'\s*=\s*NEW.'.$p_col. + '\s+WHERE\s+'.$c_col.'\s*=\s*OLD\.'.$p_col.'/msi',$aur->sql)) { + $on_update = 'cascade'; + break; + } + + if (preg_match('/UPDATE\s+'.$table.'\s+SET\s+'.$c_col.'\s*=\s*NULL'. + '\s+WHERE\s+'.$c_col.'\s*=\s*OLD\.'.$p_col.'/msi',$aur->sql)) { + $on_update = 'set null'; + break; + } + } + + # Find on delete + $on_delete = 'restrict'; + $bdr = $this->con->select(sprintf($sql,$this->con->escape($p_table),'bdr')); + while ($bdr->fetch()) + { + if (!preg_match('/BEFORE\s+DELETE/msi',$bdr->sql)) { + continue; + } + + if (preg_match('/DELETE\s+FROM\s+'.$table.'\s+WHERE\s+'.$c_col.'\s*=\s*OLD\.'.$p_col.'/msi',$bdr->sql)) { + $on_delete = 'cascade'; + break; + } + + if (preg_match('/UPDATE\s+'.$table.'\s+SET\s+'.$c_col.'\s*=\s*NULL'. + '\s+WHERE\s+'.$c_col.'\s*=\s*OLD\.'.$p_col.'/msi',$bdr->sql)) { + $on_update = 'set null'; + break; + } + } + + $res[] = array( + 'name' => substr($bir->name,4), + 'c_cols' => array($c_col), + 'p_table' => $p_table, + 'p_cols' => array($p_col), + 'update' => $on_update, + 'delete' => $on_delete + ); + } + + return $res; + } + + public function db_create_table($name,$fields) + { + $a = array(); + + foreach ($fields as $n => $f) + { + $type = $f['type']; + $len = (integer) $f['len']; + $default = $f['default']; + $null = $f['null']; + + $type = $this->udt2dbt($type,$len,$default); + $len = $len > 0 ? '('.$len.')' : ''; + $null = $null ? 'NULL' : 'NOT NULL'; + + if ($default === null) { + $default = 'DEFAULT NULL'; + } elseif ($default !== false) { + $default = 'DEFAULT '.$default.' '; + } else { + $default = ''; + } + + $a[] = $n.' '.$type.$len.' '.$null.' '.$default; + } + + $this->table_stack[$name][] = implode(",\n",$a); + $this->table_hist[$name] = $fields; + } + + public function db_create_field($table,$name,$type,$len,$null,$default) + { + $type = $this->udt2dbt($type,$len,$default); + $len = $len > 0 ? '('.$len.')' : ''; + $null = $null ? 'NULL' : 'NOT NULL'; + + if ($default === null) { + $default = 'DEFAULT NULL'; + } elseif ($default !== false) { + $default = 'DEFAULT '.$default.' '; + } else { + $default = ''; + } + + $sql = + 'ALTER TABLE '.$this->con->escapeSystem($table).' '. + 'ADD COLUMN '.$this->con->escapeSystem($name).' '. + $type.$len.' '.$null.' '.$default; + + $this->con->execute($sql); + } + + public function db_create_primary($table,$name,$cols) + { + $this->table_stack[$table][] = 'CONSTRAINT '.$name.' PRIMARY KEY ('.implode(',',$cols).') '; + } + + public function db_create_unique($table,$name,$cols) + { + $this->table_stack[$table][] = 'CONSTRAINT '.$name.' UNIQUE ('.implode(',',$cols).') '; + } + + public function db_create_index($table,$name,$type,$cols) + { + $this->x_stack[] = 'CREATE INDEX '.$name.' ON '.$table.' ('.implode(',',$cols).') '; + } + + public function db_create_reference($name,$c_table,$c_cols,$p_table,$p_cols,$update,$delete) + { + if (!isset($this->table_hist[$c_table])) { + return; + } + + if (count($c_cols) > 1 || count($p_cols) > 1) { + throw new Exception('SQLite UDBS does not support multiple columns foreign keys'); + } + + $c_col = $c_cols[0]; + $p_col = $p_cols[0]; + + $update = strtolower($update); + $delete = strtolower($delete); + + $cnull = $this->table_hist[$c_table][$c_col]['null']; + + # Create constraint + $this->x_stack[] = + 'CREATE TRIGGER bir_'.$name."\n". + 'BEFORE INSERT ON '.$c_table."\n". + "FOR EACH ROW BEGIN\n". + ' SELECT RAISE(ROLLBACK,\'insert on table "'.$c_table.'" violates foreign key constraint "'.$name.'"\')'."\n". + ' WHERE '. + ($cnull ? 'NEW.'.$c_col." IS NOT NULL\n AND " : ''). + '(SELECT '.$p_col.' FROM '.$p_table.' WHERE '.$p_col.' = NEW.'.$c_col.") IS NULL;\n". + "END;\n"; + + # Update constraint + $this->x_stack[] = + 'CREATE TRIGGER bur_'.$name."\n". + 'BEFORE UPDATE ON '.$c_table."\n". + "FOR EACH ROW BEGIN\n". + ' SELECT RAISE(ROLLBACK,\'update on table "'.$c_table.'" violates foreign key constraint "'.$name.'"\')'."\n". + ' WHERE '. + ($cnull ? 'NEW.'.$c_col." IS NOT NULL\n AND " : ''). + '(SELECT '.$p_col.' FROM '.$p_table.' WHERE '.$p_col.' = NEW.'.$c_col.") IS NULL;\n". + "END;\n"; + + # ON UPDATE + if ($update == 'cascade') + { + $this->x_stack[] = + 'CREATE TRIGGER aur_'.$name."\n". + 'AFTER UPDATE ON '.$p_table."\n". + "FOR EACH ROW BEGIN\n". + ' UPDATE '.$c_table.' SET '.$c_col.' = NEW.'.$p_col.' WHERE '.$c_col.' = OLD.'.$p_col.";\n". + "END;\n"; + } + elseif ($update == 'set null') + { + $this->x_stack[] = + 'CREATE TRIGGER aur_'.$name."\n". + 'AFTER UPDATE ON '.$p_table."\n". + "FOR EACH ROW BEGIN\n". + ' UPDATE '.$c_table.' SET '.$c_col.' = NULL WHERE '.$c_col.' = OLD.'.$p_col.";\n". + "END;\n"; + } + else # default on restrict + { + $this->x_stack[] = + 'CREATE TRIGGER burp_'.$name."\n". + 'BEFORE UPDATE ON '.$p_table."\n". + "FOR EACH ROW BEGIN\n". + ' SELECT RAISE (ROLLBACK,\'update on table "'.$p_table.'" violates foreign key constraint "'.$name.'"\')'."\n". + ' WHERE (SELECT '.$c_col.' FROM '.$c_table.' WHERE '.$c_col.' = OLD.'.$p_col.") IS NOT NULL;\n". + "END;\n"; + } + + # ON DELETE + if ($delete == 'cascade') + { + $this->x_stack[] = + 'CREATE TRIGGER bdr_'.$name."\n". + 'BEFORE DELETE ON '.$p_table."\n". + "FOR EACH ROW BEGIN\n". + ' DELETE FROM '.$c_table.' WHERE '.$c_col.' = OLD.'.$p_col.";\n". + "END;\n"; + } + elseif ($delete == 'set null') + { + $this->x_stack[] = + 'CREATE TRIGGER bdr_'.$name."\n". + 'BEFORE DELETE ON '.$p_table."\n". + "FOR EACH ROW BEGIN\n". + ' UPDATE '.$c_table.' SET '.$c_col.' = NULL WHERE '.$c_col.' = OLD.'.$p_col.";\n". + "END;\n"; + } + else + { + $this->x_stack[] = + 'CREATE TRIGGER bdr_'.$name."\n". + 'BEFORE DELETE ON '.$p_table."\n". + "FOR EACH ROW BEGIN\n". + ' SELECT RAISE (ROLLBACK,\'delete on table "'.$p_table.'" violates foreign key constraint "'.$name.'"\')'."\n". + ' WHERE (SELECT '.$c_col.' FROM '.$c_table.' WHERE '.$c_col.' = OLD.'.$p_col.") IS NOT NULL;\n". + "END;\n"; + } + } + + public function db_alter_field($table,$name,$type,$len,$null,$default) + { + $type = $this->udt2dbt($type,$len,$default); + if ($type != 'integer' && $type != 'text' && $type != 'timestamp') { + throw new Exception('SQLite fields cannot be changed.'); + } + } + + public function db_alter_primary($table,$name,$newname,$cols) + { + throw new Exception('SQLite primary key cannot be changed.'); + } + + public function db_alter_unique($table,$name,$newname,$cols) + { + throw new Exception('SQLite unique index cannot be changed.'); + } + + public function db_alter_index($table,$name,$newname,$type,$cols) + { + $this->con->execute('DROP INDEX IF EXISTS '.$name); + $this->con->execute('CREATE INDEX '.$newname.' ON '.$table.' ('.implode(',',$cols).') '); + } + + public function db_alter_reference($name,$newname,$c_table,$c_cols,$p_table,$p_cols,$update,$delete) + { + $this->con->execute('DROP TRIGGER IF EXISTS bur_'.$name); + $this->con->execute('DROP TRIGGER IF EXISTS burp_'.$name); + $this->con->execute('DROP TRIGGER IF EXISTS bir_'.$name); + $this->con->execute('DROP TRIGGER IF EXISTS aur_'.$name); + $this->con->execute('DROP TRIGGER IF EXISTS bdr_'.$name); + + $this->table_hist[$c_table] = $this->db_get_columns($c_table); + $this->db_create_reference($newname,$c_table,$c_cols,$p_table,$p_cols,$update,$delete); + } + + public function db_drop_unique($table,$name) + { + throw new Exception('SQLite unique index cannot be removed.'); + } + } +} +?> \ No newline at end of file diff --git a/inc/clearbricks/filemanager/class.filemanager.php b/inc/clearbricks/filemanager/class.filemanager.php new file mode 100644 index 0000000..3096ee8 --- /dev/null +++ b/inc/clearbricks/filemanager/class.filemanager.php @@ -0,0 +1,614 @@ +array(),'files'=>array()); + + /** + * Constructor + * + * New filemanage istance. Note that filemanage is a jail in given root + * path. You won't be able to access files outside {@link $root} path with + * the object's methods. + * + * @param string $root Root path + * @param string $root_url Root URL + */ + public function __construct($root,$root_url='') + { + $this->root = $this->pwd = path::real($root); + $this->root_url = $root_url; + + if (!preg_match('#/$#',$this->root_url)) { + $this->root_url = $this->root_url.'/'; + } + + if (!$this->root) { + throw new Exception('Invalid root directory.'); + } + } + + /** + * Change directory + * + * Changes working directory. $dir is relative to instance {@link $root} + * directory. + * + * @param string $dir Directory + */ + public function chdir($dir) + { + $realdir = path::real($this->root.'/'.path::clean($dir)); + if (!$realdir || !is_dir($realdir)) { + throw new Exception('Invalid directory.'); + } + + if ($this->isExclude($realdir)) { + throw new Exception('Directory is excluded.'); + } + + $this->pwd = $realdir; + } + + /** + * Get working directory + * + * Returns working directory path. + * + * @return string + */ + public function getPwd() + { + return $this->pwd; + } + + /** + * Current directory is writable + * + * @return boolean true if working directory is writable + */ + public function writable() + { + if (!$this->pwd) { + return false; + } + + return is_writable($this->pwd); + } + + /** + * Add exclusion + * + * Appends an exclusion to exclusions list. $f should be a regexp. + * + * @see $exclude_list + * @param string $f Exclusion regexp + */ + public function addExclusion($f) + { + if (is_array($f)) + { + foreach ($f as $v) { + if (($V = path::real($v)) !== false) { + $this->exclude_list[] = $V; + } + } + } + elseif (($F = path::real($f)) !== false) + { + $this->exclude_list[] = $F; + } + } + + /** + * Path is excluded + * + * Returns true if path (file or directory) $f is excluded. $f path is + * relative to {@link $root} path. + * + * @see $exclude_list + * @param string $f Path to match + * @return boolean + */ + protected function isExclude($f) + { + foreach ($this->exclude_list as $v) + { + if (strpos($f,$v) === 0) { + return true; + } + } + + return false; + } + + /** + * File is excluded + * + * Returns true if file $f is excluded. $f path is relative to {@link $root} + * path. + * + * @see $exclude_pattern + * @param string $f File to match + * @return boolean + */ + protected function isFileExclude($f) + { + if (!$this->exclude_pattern) { + return false; + } + + return preg_match($this->exclude_pattern,$f); + } + + /** + * Item in jail + * + * Returns true if file or directory $f is in jail (ie. not outside the + * {@link $root} directory). + * + * @param string $f Path to match + * @return boolean + */ + protected function inJail($f) + { + $f = path::real($f); + + if ($f !== false) { + return preg_match('|^'.preg_quote($this->root,'|').'|',$f); + } + + return false; + } + + /** + * File in files + * + * Returns true if file $f is in files array of {@link $dir}. + * + * @param string $f File to match + * @return boolean + */ + public function inFiles($f) + { + foreach ($this->dir['files'] as $v) { + if ($v->relname == $f) { + return true; + } + } + return false; + } + + /** + * Directory list + * + * Creates list of items in working directory and append it to {@link $dir} + * + * @uses sortHandler() + * @uses fileItem + */ + public function getDir() + { + $dir = path::clean($this->pwd); + + $dh = @opendir($dir); + + if ($dh === false) { + throw new Exception('Unable to read directory.'); + } + + $d_res = $f_res = array(); + + while (($file = readdir($dh)) !== false) + { + $fname = $dir.'/'.$file; + + if ($this->inJail($fname) && !$this->isExclude($fname)) + { + if (is_dir($fname) && $file != '.') { + $tmp = new fileItem($fname,$this->root,$this->root_url); + if ($file == '..') { + $tmp->parent = true; + } + $d_res[] = $tmp; + } + + if (is_file($fname) && strpos($file,'.') !== 0 && !$this->isFileExclude($file)) { + $f_res[] = new fileItem($fname,$this->root,$this->root_url); + } + } + } + closedir($dh); + + $this->dir = array('dirs'=>$d_res,'files'=>$f_res); + usort($this->dir['dirs'],array($this,'sortHandler')); + usort($this->dir['files'],array($this,'sortHandler')); + } + + /** + * Root directories + * + * Returns an array of directory under {@link $root} directory. + * + * @uses fileItem + * @return array + */ + public function getRootDirs() + { + $d = files::getDirList($this->root); + + $dir = array(); + + foreach ($d['dirs'] as $v) { + $dir[] = new fileItem($v,$this->root,$this->root_url); + } + + return $dir; + } + + /** + * Upload file + * + * Move $tmp file to its final destination $dest and + * returns the destination file path. + * $dest should be in jail. This method will throw exception + * if the file cannot be written. + * + * You should first verify upload status, with {@link files::uploadStatus()} + * or PHP native functions. + * + * @see files::uploadStatus() + * @param string $tmp Temporary uploaded file path + * @param string $dest Destination file + * @param string $overwrite overwrite mode + * @return string Destination real path + */ + public function uploadFile($tmp,$dest,$overwrite=false) + { + $dest = $this->pwd.'/'.path::clean($dest); + + if ($this->isFileExclude($dest)) { + throw new Exception(__('Uploading this file is not allowed.')); + } + + if (!$this->inJail(dirname($dest))) { + throw new Exception(__('Destination directory is not in jail.')); + } + + if (!$overwrite && file_exists($dest)) { + throw new Exception(__('File already exists.')); + } + + if (!is_writable(dirname($dest))) { + throw new Exception(__('Cannot write in this directory.')); + } + + if (@move_uploaded_file($tmp,$dest) === false) { + throw new Exception(__('An error occurred while writing the file.')); + } + + files::inheritChmod($dest); + return path::real($dest); + } + + /** + * Upload file by bits + * + * Creates a new file $dest with contents of $bits and + * return the destination file path. + * $dest should be in jail. This method will throw exception + * if file cannot be written. + * + * @param string $bits Destination file content + * @param string $dest Destination file + * @return string Destination real path + */ + public function uploadBits($name,$bits) + { + $dest = $this->pwd.'/'.path::clean($name); + + if ($this->isFileExclude($dest)) { + throw new Exception(__('Uploading this file is not allowed.')); + } + + if (!$this->inJail(dirname($dest))) { + throw new Exception(__('Destination directory is not in jail.')); + } + + if (!is_writable(dirname($dest))) { + throw new Exception(__('Cannot write in this directory.')); + } + + $fp = @fopen($dest,'wb'); + if ($fp === false) { + throw new Exception(__('An error occurred while writing the file.')); + } + + fwrite($fp,$bits); + fclose($fp); + files::inheritChmod($dest); + + return path::real($dest); + } + + /** + * New directory + * + * Creates a new directory $d relative to working directory. + * + * @param string $d Directory name + */ + public function makeDir($d) + { + files::makeDir($this->pwd.'/'.path::clean($d)); + } + + /** + * Move file + * + * Moves a file $s to a new destination $d. Both + * $s and $d are relative to {@link $root}. + * + * @param string $s Source file + * @param string $d Destination file + */ + public function moveFile($s,$d) + { + $s = $this->root.'/'.path::clean($s); + $d = $this->root.'/'.path::clean($d); + + if (($s = path::real($s)) === false) { + throw new Exception(__('Source file does not exist.')); + } + + $dest_dir = path::real(dirname($d)); + + if (!$this->inJail($s)) { + throw new Exception(__('File is not in jail.')); + } + if (!$this->inJail($dest_dir)) { + throw new Exception(__('File is not in jail.')); + } + + if (!is_writable($dest_dir)) { + throw new Exception(__('Destination directory is not writable.')); + } + + if (@rename($s,$d) === false) { + throw new Exception(__('Unable to rename file.')); + } + } + + /** + * Remove item + * + * Removes a file or directory $f which is relative to working + * directory. + * + * @param string $f Path to remove + */ + public function removeItem($f) + { + $file = path::real($this->pwd.'/'.path::clean($f)); + + if (is_file($file)) { + $this->removeFile($f); + } elseif (is_dir($file)) { + $this->removeDir($f); + } + } + + /** + * Remove item + * + * Removes a file $f which is relative to working directory. + * + * @param string $f File to remove + */ + public function removeFile($f) + { + $f = path::real($this->pwd.'/'.path::clean($f)); + + if (!$this->inJail($f)) { + throw new Exception(__('File is not in jail.')); + } + + if (!files::isDeletable($f)) { + throw new Exception(__('File cannot be removed.')); + } + + if (@unlink($f) === false) { + throw new Exception(__('File cannot be removed.')); + } + } + + /** + * Remove item + * + * Removes a directory $d which is relative to working directory. + * + * @param string $d Directory to remove + */ + public function removeDir($d) + { + $d = path::real($this->pwd.'/'.path::clean($d)); + + if (!$this->inJail($d)) { + throw new Exception(__('Directory is not in jail.')); + } + + if (!files::isDeletable($d)) { + throw new Exception(__('Directory cannot be removed.')); + } + + if (@rmdir($d) === false) { + throw new Exception(__('Directory cannot be removed.')); + } + } + + /** + * SortHandler + * + * This method is called by {@link getDir()} to sort files. Can be overrided + * in inherited classes. + * + * @param fileItem $a fileItem object + * @param fileItem $b fileItem object + * @return integer + */ + protected function sortHandler($a,$b) + { + if ($a->parent && !$b->parent || !$a->parent && $b->parent) { + return ($a->parent) ? -1 : 1; + } + return strcasecmp($a->basename,$b->basename); + } +} + +/** +* File item +* +* File item class used by {@link filemanager}. In this class {@link $file} could +* be either a file or a directory. +* +* @package Clearbricks +* @subpackage Filemanager +*/ +class fileItem +{ + /** @var string Complete path to file */ + public $file; + + /** @var string File basename */ + public $basename; + + /** @var string File directory name */ + public $dir; + + /** @var string File URL */ + public $file_url; + + /** @var string File directory URL */ + public $dir_url; + + /** @var string File extension */ + public $extension; + + /** @var string File path relative to $root given in constructor */ + public $relname; + + /** @var boolean Parent directory (ie. "..") */ + public $parent = false; + + + /** @var string File MimeType. See {@link files::getMimeType()}. */ + public $type; + + /** @var integer File modification timestamp */ + public $mtime; + + /** @var integer File size */ + public $size; + + /** @var integer File permissions mode */ + public $mode; + + /** @var integer File owner ID */ + public $uid; + + /** @var integer File group ID */ + public $gid; + + /** @var boolean True if file or directory is writable */ + public $w; + + /** @var boolean True if file is a directory */ + public $d; + + /** @var boolean True if file file is executable or directory is traversable */ + public $x; + + /** @var boolean True if file is a file */ + public $f; + + /** @var boolean True if file or directory is deletable */ + public $del; + + /** + * Constructor + * + * Creates an instance of fileItem object. + * + * @param string $file Absolute file or directory path + * @param string $root File root path + * @param string $root_url File root URL + */ + public function __construct($file,$root,$root_url='') + { + $file = path::real($file); + $stat = stat($file); + $path = path::info($file); + + $rel = preg_replace('/^'.preg_quote($root,'/').'\/?/','',$file); + + $this->file = $file; + $this->basename = $path['basename']; + $this->dir = $path['dirname']; + $this->relname = $rel; + + $this->file_url = str_replace('%2F','/',rawurlencode($rel)); + $this->file_url = $root_url.$this->file_url; + + $this->dir_url = dirname($this->file_url); + $this->extension = $path['extension']; + + $this->mtime = $stat[9]; + $this->size = $stat[7]; + $this->mode = $stat[2]; + $this->uid = $stat[4]; + $this->gid = $stat[5]; + $this->w = is_writable($file); + $this->d = is_dir($file); + $this->f = is_file($file); + $this->x = file_exists($file.'/.'); + $this->del = files::isDeletable($file); + + $this->type = $this->d ? null : files::getMimeType($file); + $this->type_prefix = preg_replace('/^(.+?)\/.+$/','$1',$this->type); + } +} +?> \ No newline at end of file diff --git a/inc/clearbricks/html.filter/class.html.filter.php b/inc/clearbricks/html.filter/class.html.filter.php new file mode 100644 index 0000000..ba22c4c --- /dev/null +++ b/inc/clearbricks/html.filter/class.html.filter.php @@ -0,0 +1,676 @@ +parser = xml_parser_create('UTF-8'); + xml_set_object($this->parser,$this); + xml_set_element_handler($this->parser, 'tag_open', 'tag_close'); + xml_set_character_data_handler($this->parser, 'cdata'); + xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, false); + + $this->removeTags( + 'applet','base','basefont','body','center','dir','font', + 'frame','frameset','head','html','isindex', + 'link','menu','meta','noframes','script','style' + ); + + $this->removeAttributes( + 'onclick','ondblclick','onfocus','onkeydown','onkeypress', + 'onkeyup','onload','onmousedown','onmousemove','onmouseout', + 'onmouseover','onmouseup','onreset','onselect','onsubmit', + 'onunload' + ); + } + + /** + * Append tags + * + * Appends tags to remove. Each method argument is a tag. Example: + * + * + * removeTags('frame','script'); + * ?> + * + */ + public function removeTags() + { + foreach ($this->argsArray(func_get_args()) as $tag) { + $this->removed_tags[] = $tag; + } + } + + /** + * Append attributes + * + * Appends attributes to remove. Each method argument is an attribute. Example: + * + * + * removeAttributes('onclick','onunload'); + * ?> + * + */ + public function removeAttributes() + { + foreach ($this->argsArray(func_get_args()) as $a) { + $this->removed_attrs[] = $a; + } + } + + /** + * Append attributes for tags + * + * Appends attributes to remove from specific tags. Each method argument is + * an array of tags with attributes. Example: + * + * + * removeTagAttributes(array('a' => array('src','title'))); + * ?> + * + */ + public function removeTagAttributes($tag) + { + $args = $this->argsArray(func_get_args()); + array_shift($args); + + foreach ($args as $a) { + $this->removed_tag_attrs[$tag][] = $a; + } + } + + /** + * Known tags + * + * Creates a list of known tags. + * + * @param array $t Tags array + */ + public function setTags($t) + { + if (is_array($t)) { + $this->tags = $t; + } + } + + /** + * Apply filter + * + * This method applies filter on given $str string. It will first + * try to use tidy extension if exists and then apply the filter. + * + * @param string $str String to filter + * @return string Filtered string + */ + public function apply($str) + { + if (extension_loaded('tidy') && class_exists('tidy')) + { + $config = array( + 'doctype' => 'strict', + 'drop-proprietary-attributes' => true, + 'drop-font-tags' => true, + 'escape-cdata' => true, + 'indent' => false, + 'join-classes' => false, + 'join-styles' => true, + 'lower-literals' => true, + 'output-xhtml' => true, + 'show-body-only' => true, + 'wrap' => 80 + ); + + $str = '

    tt

    '.$str; // Fixes a big issue + + $tidy = new tidy; + $tidy->parseString($str, $config, 'utf8'); + $tidy->cleanRepair(); + + $str = (string) $tidy; + + $str = preg_replace('#^

    tt

    \s?#','',$str); + } + else + { + $str = $this->miniTidy($str); + } + + # Removing open comments, open CDATA and processing instructions + $str = preg_replace('%%msu','',$str); + $str = str_replace(' + $fc = preg_replace('/(^\s*)?/ms','',$fc); + + # Compile blocks + foreach ($this->blocks as $b => $f) { + $pattern = sprintf($this->tag_block,preg_quote($b,'#')); + + $fc = preg_replace_callback('#'.$pattern.'#ms', + array($this,'compileBlock'),$fc); + } + + # Compile values + foreach ($this->values as $v => $f) { + $pattern = sprintf($this->tag_value,preg_quote($v,'#')); + + $fc = preg_replace_callback('#'.$pattern.'#ms', + array($this,'compileValue'),$fc); + } + + return $fc; + } + + protected function compileBlock($match) + { + $b = $match[1]; + $content = $match[3]; + $attr = $this->getAttrs($match[2]); + + # Call block function + return call_user_func($this->blocks[$b],$attr,$content); + } + + protected function compileValue($match) + { + $v = $match[1]; + $attr = isset($match[2]) ? $this->getAttrs($match[2]) : array(); + $str_attr = isset($match[2]) ? $match[2] : null; + + return call_user_func($this->values[$v],$attr,ltrim($str_attr)); + } + + protected function getAttrs($str) + { + $res = array(); + if (preg_match_all('|([a-zA-Z0-9_:-]+)="(.+?)"|ms',$str,$m) > 0) { + foreach ($m[1] as $i => $v) { + $res[$v] = $m[2][$i]; + } + } + return $res; + } +} +?> \ No newline at end of file diff --git a/inc/clearbricks/text.wiki2xhtml/class.wiki2xhtml.php b/inc/clearbricks/text.wiki2xhtml/class.wiki2xhtml.php new file mode 100644 index 0000000..d0c4b96 --- /dev/null +++ b/inc/clearbricks/text.wiki2xhtml/class.wiki2xhtml.php @@ -0,0 +1,1267 @@ + Added ``inline html`` support +# +# 3.2.5 +# => Changed longdesc by title in images +# +# 3.2.4 +# => Auto links +# => Code cleanup +# +# 3.2.3 +# Olivier +# => PHP5 Strict +# +# 3.2.2 +# Olivier +# => Changement de la gestion des URL spéciales +# +# 3.2.1 +# Olivier +# => Changement syntaxe des macros +# +# 3.2 +# Olivier +# => Changement de fonctionnement des macros +# => Passage de fonctions externes pour les macros et les mots wiki +# +# 3.1d +# Jérôme Lipowicz +# => antispam +# Olivier +# => centrage d'image +# +# 3.1c +# Olivier +# => Possibilité d'échaper les | dans les marqueurs avec \ +# +# 3.1b +# Nicolas Chachereau +# => Changement de regexp pour la correction syntaxique +# +# 3.1a +# Olivier +# => Bug du Call-time pass-by-reference +# +# 3.1 +# Olivier +# => Ajout des macros «««..»»» +# => Ajout des blocs vides øøø +# => Ajout du niveau de titre paramétrable +# => Option de blocage du parseur dans les
    +#			=> Titres au format setext (experimental, désactivé)
    +#
    +# 3.0
    +# Olivier		=> Récriture du parseur inline, plus d'erreur XHTML
    +#			=> Ajout d'une vérification d'intégrité pour les listes
    +#			=> Les acronymes sont maintenant dans un fichier texte
    +#			=> Ajout d'un tag images ((..)), del --..-- et ins ++..++
    +#			=> Plus possible de faire des liens JS [lien|javascript:...]
    +#			=> Ajout des notes de bas de page §§...§§
    +#			=> Ajout des mots wiki
    +#
    +# 2.5
    +# Olivier		=> Récriture du code, plus besoin du saut de ligne entre blocs !=
    +#
    +# 2.0
    +# Stephanie	=> correction des PCRE et ajout de fonctionnalités
    +# Mathieu 	=> ajout du strip-tags, implementation des options, reconnaissance automatique d'url, etc.
    +# Olivier		=> chagement de active_link en active_urls
    +#			=> ajout des options pour les blocs
    +#			=> intégration de l'aide dans le code, avec les options
    +#			=> début de quelque chose pour la reconnaissance auto d'url (avec Mat)
    +
    +# TODO :
    +# Mathieu	=> active_wiki_urls (modifier wikiParseUrl ?)
    +# 		=> active_auto_urls
    +#
    +# *		=> ajouter des options.
    +# 		=> trouver un meilleur nom pour active_link ? (pour le jour ou ca sera tellement une usine
    +#		   a gaz que on generera des tags  :)
    +#
    +
    +# Wiki2xhtml
    +
    +class wiki2xhtml
    +{
    +	public $__version__ = '3.2.6';
    +	
    +	public $T;
    +	public $opt;
    +	public $line;
    +	public $acro_table;
    +	public $foot_notes;
    +	public $macros;
    +	public $functions;
    +	
    +	public $tags;
    +	public $open_tags;
    +	public $close_tags;
    +	public $custom_tags = array();
    +	public $all_tags;
    +	public $tag_pattern;
    +	public $escape_table;
    +	public $allowed_inline = array();
    +	
    +	function __construct()
    +	{
    +		# Mise en place des options
    +		$this->setOpt('active_title',1);		# Activation des titres !!!
    +		$this->setOpt('active_setext_title',0);	# Activation des titres setext (EXPERIMENTAL)
    +		$this->setOpt('active_hr',1);			# Activation des 
    + $this->setOpt('active_lists',1); # Activation des listes + $this->setOpt('active_quote',1); # Activation du
    + $this->setOpt('active_pre',1); # Activation du
    +		$this->setOpt('active_empty',1);		# Activation du bloc vide øøø
    +		$this->setOpt('active_auto_urls',0);	# Activation de la reconnaissance d'url
    +		$this->setOpt('active_auto_br',0);	# Activation du saut de ligne automatique (dans les paragraphes)
    +		$this->setOpt('active_antispam',1);	# Activation de l'antispam pour les emails
    +		$this->setOpt('active_urls',1);		# Activation des liens []
    +		$this->setOpt('active_auto_img',1);	# Activation des images automatiques dans les liens []
    +		$this->setOpt('active_img',1);		# Activation des images (())
    +		$this->setOpt('active_anchor',1);		# Activation des ancres ~...~
    +		$this->setOpt('active_em',1);			# Activation du  ''...''
    +		$this->setOpt('active_strong',1);		# Activation du  __...__
    +		$this->setOpt('active_br',1);			# Activation du 
    %%% + $this->setOpt('active_q',1); # Activation du {{...}} + $this->setOpt('active_code',1); # Activation du @@...@@ + $this->setOpt('active_acronym',1); # Activation des acronymes + $this->setOpt('active_ins',1); # Activation des ins ++..++ + $this->setOpt('active_del',1); # Activation des del --..-- + $this->setOpt('active_inline_html',1); # Activation du HTML inline ``...`` + $this->setOpt('active_footnotes',1); # Activation des notes de bas de page + $this->setOpt('active_wikiwords',0); # Activation des mots wiki + $this->setOpt('active_macros',1); # Activation des macros /// /// + + $this->setOpt('parse_pre',1); # Parser l'intérieur de blocs
     ?
    +		
    +		$this->setOpt('active_fr_syntax',1);	# Corrections syntaxe FR
    +		
    +		$this->setOpt('first_title_level',3);	# Premier niveau de titre 
    +		
    +		$this->setOpt('note_prefix','wiki-footnote');
    +		$this->setOpt('note_str','

    Notes

    %s
    '); + $this->setOpt('words_pattern', + '((?setOpt('auto_url_pattern', + '%(?setOpt('acronyms_file',dirname(__FILE__).'/acronyms.txt'); + + $this->acro_table = $this->__getAcronyms(); + $this->foot_notes = array(); + $this->functions = array(); + $this->macros = array(); + + $this->registerFunction('macro:html',array($this,'__macroHTML')); + } + + function setOpt($option, $value) + { + $this->opt[$option] = $value; + } + + function setOpts($options) + { + if (!is_array($options)) { + return; + } + + foreach ($options as $k => $v) { + $this->opt[$k] = $v; + } + } + + function getOpt($option) + { + return (!empty($this->opt[$option])) ? $this->opt[$option] : false; + } + + function registerFunction($type,$name) + { + if (is_callable($name)) { + $this->functions[$type] = $name; + } + } + + function transform($in) + { + # Initialisation des tags + $this->__initTags(); + $this->foot_notes = array(); + + # Récupération des macros + if ($this->getOpt('active_macros')) { + $in = preg_replace('#^///(.*?)///($|\r)#mse',"\\\$this->__getMacro('\\1')",$in); + } + + # Vérification du niveau de titre + if ($this->getOpt('first_title_level') > 4) { + $this->setOpt('first_title_level',4); + } + + $res = str_replace("\r", '', $in); + + $escape_pattern = array(); + + # traitement des titres à la setext + if ($this->getOpt('active_setext_title') && $this->getOpt('active_title')) { + $res = preg_replace('/^(.*)\n[=]{5,}$/m','!!!$1',$res); + $res = preg_replace('/^(.*)\n[-]{5,}$/m','!!$1',$res); + } + + # Transformation des mots Wiki + if ($this->getOpt('active_wikiwords') && $this->getOpt('words_pattern')) { + $res = preg_replace('/'.$this->getOpt('words_pattern').'/msu','¶¶¶$1¶¶¶',$res); + } + + # Transformation des URLs automatiques + if ($this->getOpt('active_auto_urls')) + { + $active_urls = $this->getOpt('active_urls'); + + $this->setOpt('active_urls',1); + $this->__initTags(); + + # If urls are not active, escape URLs tags + if (!$active_urls) + { + $res = preg_replace( + '%(?tags['a'])).'])%msU', + '\\\$1',$res + ); + } + + # Transforms urls + $res = preg_replace($this->getOpt('auto_url_pattern'),'[$1$2]',$res); + + } + + $this->T = explode("\n",$res); + $this->T[] = ''; + + # Parse les blocs + $res = $this->__parseBlocks(); + + # Line break + if ($this->getOpt('active_br')) { + $res = preg_replace('/(?', $res); + $escape_pattern[] = '%%%'; + } + + # Nettoyage des \s en trop + $res = preg_replace('/([\s]+)(<\/p>|<\/li>|<\/pre>)/', '$2', $res); + $res = preg_replace('/(
  • )([\s]+)/', '$1', $res); + + # On vire les escapes + if (!empty($escape_pattern)) { + $res = preg_replace('/\\\('.implode('|',$escape_pattern).')/','$1',$res); + } + + # On vire les ¶¶¶MotWiki¶¶¶ qui sont resté (dans les url...) + if ($this->getOpt('active_wikiwords') && $this->getOpt('words_pattern')) { + $res = preg_replace('/¶¶¶'.$this->getOpt('words_pattern').'¶¶¶/msu','$1',$res); + } + + # On remet les macros + if ($this->getOpt('active_macros')) { + $res = preg_replace('/^##########MACRO#([0-9]+)#$/mse','\$this->__putMacro("$1")',$res); + } + + # Auto line break dans les paragraphes + if ($this->getOpt('active_auto_br')) { + $res = preg_replace_callback('%(

    )(.*?)(

    )%msu',array($this,'__autoBR'),$res); + } + + # On ajoute les notes + if (count($this->foot_notes) > 0) + { + $res_notes = ''; + $i = 1; + foreach ($this->foot_notes as $k => $v) { + $res_notes .= "\n".'

    ['.$i.'] '.$v.'

    '; + $i++; + } + $res .= sprintf("\n".$this->getOpt('note_str')."\n",$res_notes); + } + + return $res; + } + + /* PRIVATE + --------------------------------------------------- */ + + function __initTags() + { + $tags = array( + 'em' => array("''","''"), + 'strong' => array('__','__'), + 'acronym' => array('??','??'), + 'a' => array('[',']'), + 'img' => array('((','))'), + 'q' => array('{{','}}'), + 'code' => array('@@','@@'), + 'anchor' => array('~','~'), + 'del' => array('--','--'), + 'ins' => array('++','++'), + 'inline' => array('``','``'), + 'note' => array('$$','$$'), + 'word' => array('¶¶¶','¶¶¶') + ); + + $this->tags = array_merge($tags,$this->custom_tags); + + # Suppression des tags selon les options + if (!$this->getOpt('active_urls')) { + unset($this->tags['a']); + } + if (!$this->getOpt('active_img')) { + unset($this->tags['img']); + } + if (!$this->getOpt('active_anchor')) { + unset($this->tags['anchor']); + } + if (!$this->getOpt('active_em')) { + unset($this->tags['em']); + } + if (!$this->getOpt('active_strong')) { + unset($this->tags['strong']); + } + if (!$this->getOpt('active_q')) { + unset($this->tags['q']); + } + if (!$this->getOpt('active_code')) { + unset($this->tags['code']); + } + if (!$this->getOpt('active_acronym')) { + unset($this->tags['acronym']); + } + if (!$this->getOpt('active_ins')) { + unset($this->tags['ins']); + } + if (!$this->getOpt('active_del')) { + unset($this->tags['del']); + } + if (!$this->getOpt('active_inline_html')) { + unset($this->tags['inline']); + } + if (!$this->getOpt('active_footnotes')) { + unset($this->tags['note']); + } + if (!$this->getOpt('active_wikiwords')) { + unset($this->tags['word']); + } + + $this->open_tags = $this->__getTags(); + $this->close_tags = $this->__getTags(false); + $this->all_tags = $this->__getAllTags(); + $this->tag_pattern = $this->__getTagsPattern(); + + $this->escape_table = $this->all_tags; + array_walk($this->escape_table,create_function('&$a','$a = \'\\\\\'.$a;')); + } + + function __getTags($open=true) + { + $res = array(); + foreach ($this->tags as $k => $v) { + $res[$k] = ($open) ? $v[0] : $v[1]; + } + return $res; + } + + function __getAllTags() + { + $res = array(); + foreach ($this->tags as $v) { + $res[] = $v[0]; + $res[] = $v[1]; + } + return array_values(array_unique($res)); + } + + function __getTagsPattern($escape=false) + { + $res = $this->all_tags; + array_walk($res,create_function('&$a','$a = preg_quote($a,"/");')); + + if (!$escape) { + return '/(?T); + + for ($i=0; $i<$max; $i++) + { + $pre_mode = $mode; + $pre_type = $type; + $end = ($i+1 == $max); + + $line = $this->__getLine($i,$type,$mode); + + if ($type != 'pre' || $this->getOpt('parse_pre')) { + $line = $this->__inlineWalk($line); + } + + $res .= $this->__closeLine($type,$mode,$pre_type,$pre_mode); + $res .= $this->__openLine($type,$mode,$pre_type,$pre_mode); + + # P dans les blockquotes + if ($type == 'blockquote' && trim($line) == '' && $pre_type == $type) { + $res .= "

    \n

    "; + } + + # Correction de la syntaxe FR dans tous sauf pre et hr + # Sur idée de Christophe Bonijol + # Changement de regex (Nicolas Chachereau) + if ($this->getOpt('active_fr_syntax') && $type != null && $type != 'pre' && $type != 'hr') { + $line = preg_replace('%[ ]+([:?!;\x{00BB}](\s|$))%u',' $1',$line); + $line = preg_replace('%(\x{00AB})[ ]+%u','$1 ',$line); + } + + $res .= $line; + } + + return trim($res); + } + + function __getLine($i,&$type,&$mode) + { + $pre_type = $type; + $pre_mode = $mode; + $type = $mode = null; + + if (empty($this->T[$i])) { + return false; + } + + $line = htmlspecialchars($this->T[$i],ENT_NOQUOTES); + + # Ligne vide + if (empty($line)) + { + $type = null; + } + elseif ($this->getOpt('active_empty') && preg_match('/^øøø(.*)$/',$line,$cap)) + { + $type = null; + $line = trim($cap[1]); + } + # Titre + elseif ($this->getOpt('active_title') && preg_match('/^([!]{1,4})(.*)$/',$line,$cap)) + { + $type = 'title'; + $mode = strlen($cap[1]); + $line = trim($cap[2]); + } + # Ligne HR + elseif ($this->getOpt('active_hr') && preg_match('/^[-]{4}[- ]*$/',$line)) + { + $type = 'hr'; + $line = null; + } + # Blockquote + elseif ($this->getOpt('active_quote') && preg_match('/^(>|;:)(.*)$/',$line,$cap)) + { + $type = 'blockquote'; + $line = trim($cap[2]); + } + # Liste + elseif ($this->getOpt('active_lists') && preg_match('/^([*#]+)(.*)$/',$line,$cap)) + { + $type = 'list'; + $mode = $cap[1]; + $valid = true; + + # Vérification d'intégrité + $dl = ($type != $pre_type) ? 0 : strlen($pre_mode); + $d = strlen($mode); + $delta = $d-$dl; + + if ($delta < 0 && strpos($pre_mode,$mode) !== 0) { + $valid = false; + } + if ($delta > 0 && $type == $pre_type && strpos($mode,$pre_mode) !== 0) { + $valid = false; + } + if ($delta == 0 && $mode != $pre_mode) { + $valid = false; + } + if ($delta > 1) { + $valid = false; + } + + if (!$valid) { + $type = 'p'; + $mode = null; + $line = '
    '.$line; + } else { + $line = trim($cap[2]); + } + } + # Préformaté + elseif ($this->getOpt('active_pre') && preg_match('/^[ ]{1}(.*)$/',$line,$cap)) + { + $type = 'pre'; + $line = $cap[1]; + } + # Paragraphe + else { + $type = 'p'; + $line = trim($line); + } + + return $line; + } + + function __openLine($type,$mode,$pre_type,$pre_mode) + { + $open = ($type != $pre_type); + + if ($open && $type == 'p') + { + return "\n

    "; + } + elseif ($open && $type == 'blockquote') + { + return "\n

    "; + } + elseif (($open || $mode != $pre_mode) && $type == 'title') + { + $fl = $this->getOpt('first_title_level'); + $fl = $fl+3; + $l = $fl-$mode; + return "\n'; + } + elseif ($open && $type == 'pre') + { + return "\n

    ";
    +		}
    +		elseif ($open && $type == 'hr')
    +		{
    +			return "\n
    "; + } + elseif ($type == 'list') + { + $dl = ($open) ? 0 : strlen($pre_mode); + $d = strlen($mode); + $delta = $d-$dl; + $res = ''; + + if($delta > 0) { + if(substr($mode, -1, 1) == '*') { + $res .= "
      \n"; + } else { + $res .= "
        \n"; + } + } elseif ($delta < 0) { + $res .= "\n"; + for($j = 0; $j < abs($delta); $j++) { + if (substr($pre_mode,(0 - $j - 1), 1) == '*') { + $res .= "
    \n
  • \n"; + } else { + $res .= "\n\n"; + } + } + } else { + $res .= "\n"; + } + + return $res."
  • "; + } + else + { + return null; + } + } + + function __closeLine($type,$mode,$pre_type,$pre_mode) + { + $close = ($type != $pre_type); + + if ($close && $pre_type == 'p') + { + return "

    \n"; + } + elseif ($close && $pre_type == 'blockquote') + { + return "

  • \n"; + } + elseif (($close || $mode != $pre_mode) && $pre_type == 'title') + { + $fl = $this->getOpt('first_title_level'); + $fl = $fl+3; + $l = $fl-$pre_mode; + return '\n"; + } + elseif ($close && $pre_type == 'pre') + { + return "
    \n"; + } + elseif ($close && $pre_type == 'list') + { + $res = ''; + for($j = 0; $j < strlen($pre_mode); $j++) { + if(substr($pre_mode,(0 - $j - 1), 1) == '*') { + $res .= "\n"; + } else { + $res .= "\n"; + } + } + return $res; + } + else + { + return "\n"; + } + } + + + /* Inline + --------------------------------------------------- */ + function __inlineWalk($str,$allow_only=null) + { + $tree = preg_split($this->tag_pattern,$str,-1,PREG_SPLIT_DELIM_CAPTURE); + + $res = ''; + for ($i=0; $iopen_tags)) && + ($allow_only == null || in_array(array_search($tree[$i],$this->open_tags),$allow_only))) + { + $tag = array_search($tree[$i],$this->open_tags); + $tag_type = 'open'; + + if (($tidy = $this->__makeTag($tree,$tag,$i,$i,$attr,$tag_type)) !== false) + { + if ($tag != '') { + $res .= '<'.$tag.$attr; + $res .= ($tag_type == 'open') ? '>' : ' />'; + } + $res .= $tidy; + } + else + { + $res .= $tree[$i]; + } + } + else + { + $res .= $tree[$i]; + } + } + + # Suppression des echappements + $res = str_replace($this->escape_table,$this->all_tags,$res); + + return $res; + } + + function __makeTag(&$tree,&$tag,$position,&$j,&$attr,&$type) + { + $res = ''; + $closed = false; + + $itag = $this->close_tags[$tag]; + + # Recherche fermeture + for ($i=$position+1;$i__parseLink($res,$tag,$attr,$type); + break; + case 'img': + $type = 'close'; + $res = $this->__parseImg($res,$attr); + break; + case 'acronym': + $res = $this->__parseAcronym($res,$attr); + break; + case 'q': + $res = $this->__parseQ($res,$attr); + break; + case 'anchor': + $tag = 'a'; + $res = $this->__parseAnchor($res,$attr); + break; + case 'note': + $tag = ''; + $res = $this->__parseNote($res); + break; + case 'inline': + $tag = ''; + $res = $this->__parseInlineHTML($res); + break; + case 'word': + $res = $this->parseWikiWord($res,$tag,$attr,$type); + break; + default : + $res = $this->__inlineWalk($res); + break; + } + + if ($type == 'open' && $tag != '') { + $res .= ''; + } + $j = $i; + break; + } + } + + return $res; + } + else + { + return false; + } + } + + function __splitTagsAttr($str) + { + $res = preg_split('/(? $v) { + $res[$k] = str_replace("\|",'|',$v); + } + + return $res; + } + + # Antispam (Jérôme Lipowicz) + function __antiSpam($str) + { + $encoded = bin2hex($str); + $encoded = chunk_split($encoded, 2, '%'); + $encoded = '%'.substr($encoded, 0, strlen($encoded) - 1); + return $encoded; + } + + function __parseLink($str,&$tag,&$attr,&$type) + { + $n_str = $this->__inlineWalk($str,array('acronym','img')); + $data = $this->__splitTagsAttr($n_str); + $no_image = false; + + # Only URL in data + if (count($data) == 1) + { + $url = trim($str); + $content = strlen($url) > 35 ? substr($url,0,35).'...' : $url; + $lang = ''; + $title = $url; + } + elseif (count($data) > 1) + { + $url = trim($data[1]); + $content = $data[0]; + $lang = (!empty($data[2])) ? $this->protectAttr($data[2],true) : ''; + $title = (!empty($data[3])) ? $data[3] : ''; + $no_image = (!empty($data[4])) ? (boolean) $data[4] : false; + } + + # Remplacement si URL spéciale + $this->__specialUrls($url,$content,$lang,$title); + + # On vire les   dans l'url + $url = str_replace(' ',' ',$url); + + if (preg_match('/^(.+)[.](gif|jpg|jpeg|png)$/', $url) && !$no_image && $this->getOpt('active_auto_img')) + { + # On ajoute les dimensions de l'image si locale + # Idée de Stephanie + $img_size = null; + if (!preg_match('#[a-zA-Z]+://#', $url)) { + if (preg_match('#^/#',$url)) { + $path_img = $_SERVER['DOCUMENT_ROOT'] . $url; + } else { + $path_img = $url; + } + + $img_size = @getimagesize($path_img); + } + + $attr = ' src="'.$this->protectAttr($this->protectUrls($url)).'"'. + $attr .= (count($data) > 1) ? ' alt="'.$this->protectAttr($content).'"' : ' alt=""'; + $attr .= ($lang) ? ' lang="'.$lang.'"' : ''; + $attr .= ($title) ? ' title="'.$this->protectAttr($title).'"' : ''; + $attr .= (is_array($img_size)) ? ' '.$img_size[3] : ''; + + $tag = 'img'; + $type = 'close'; + return null; + } + else + { + if ($this->getOpt('active_antispam') && preg_match('/^mailto:/',$url)) { + $content = $content == $url ? preg_replace('%^mailto:%','',$content) : $content; + $url = 'mailto:'.$this->__antiSpam(substr($url,7)); + + } + + $attr = ' href="'.$this->protectAttr($this->protectUrls($url)).'"'; + $attr .= ($lang) ? ' hreflang="'.$lang.'"' : ''; + $attr .= ($title) ? ' title="'.$this->protectAttr($title).'"' : ''; + + return $content; + } + } + + function __specialUrls(&$url,&$content,&$lang,&$title) + { + foreach ($this->functions as $k => $v) + { + if (strpos($k,'url:') === 0 && strpos($url,substr($k,4)) === 0) + { + $res = call_user_func($v,$url,$content); + + $url = isset($res['url']) ? $res['url'] : $url; + $content = isset($res['content']) ? $res['content'] : $content; + $lang = isset($res['lang']) ? $res['lang'] : $lang; + $title = isset($res['title']) ? $res['title'] : $title; + + break; + } + } + } + + function __parseImg($str,&$attr) + { + $data = $this->__splitTagsAttr($str); + + $alt = ''; + $url = $data[0]; + if (!empty($data[1])) { + $alt = $data[1]; + } + + $attr = ' src="'.$this->protectAttr($this->protectUrls($url)).'"'; + $attr .= ' alt="'.$this->protectAttr($alt).'"'; + + if (!empty($data[2])) { + $data[2] = strtoupper($data[2]); + if ($data[2] == 'G' || $data[2] == 'L') { + $attr .= ' style="float:left; margin: 0 1em 1em 0;"'; + } elseif ($data[2] == 'D' || $data[2] == 'R') { + $attr .= ' style="float:right; margin: 0 0 1em 1em;"'; + } elseif ($data[2] == 'C') { + $attr .= ' style="display:block; margin:0 auto;"'; + } + } + + if (!empty($data[3])) { + $attr .= ' title="'.$this->protectAttr($data[3]).'"'; + } + + return null; + } + + function __parseQ($str,&$attr) + { + $str = $this->__inlineWalk($str); + $data = $this->__splitTagsAttr($str); + + $content = $data[0]; + $lang = (!empty($data[1])) ? $this->protectAttr($data[1],true) : ''; + + $attr .= (!empty($lang)) ? ' lang="'.$lang.'"' : ''; + $attr .= (!empty($data[2])) ? ' cite="'.$this->protectAttr($this->protectUrls($data[2])).'"' : ''; + + return $content; + } + + function __parseAnchor($str,&$attr) + { + $name = $this->protectAttr($str,true); + + if ($name != '') { + $attr = ' name="'.$name.'"'; + } + return null; + } + + function __parseNote($str) + { + $i = count($this->foot_notes)+1; + $id = $this->getOpt('note_prefix').'-'.$i; + $this->foot_notes[$id] = $this->__inlineWalk($str); + return '\['.$i.'\]'; + } + + function __parseInlineHTML($str) + { + return str_replace(array('>','<'),array('>','<'),$str); + } + + # Obtenir un acronyme + function __parseAcronym($str,&$attr) + { + $data = $this->__splitTagsAttr($str); + + $acronym = $data[0]; + $title = $lang = ''; + + if (count($data) > 1) + { + $title = $data[1]; + $lang = (!empty($data[2])) ? $this->protectAttr($data[2],true) : ''; + } + + if ($title == '' && !empty($this->acro_table[$acronym])) { + $title = $this->acro_table[$acronym]; + } + + $attr = ($title) ? ' title="'.$this->protectAttr($title).'"' : ''; + $attr .= ($lang) ? ' lang="'.$lang.'"' : ''; + + return $acronym; + } + + # Définition des acronymes, dans le fichier acronyms.txt + function __getAcronyms() + { + $file = $this->getOpt('acronyms_file'); + $res = array(); + + if (file_exists($file)) + { + if (($fc = @file($file)) !== false) + { + foreach ($fc as $v) + { + $v = trim($v); + if ($v != '') + { + $p = strpos($v,':'); + $K = (string) trim(substr($v,0,$p)); + $V = (string) trim(substr($v,($p+1))); + + if ($K) { + $res[$K] = $V; + } + } + } + } + } + + return $res; + } + + # Mots wiki (pour héritage) + function parseWikiWord($str,&$tag,&$attr,&$type) + { + $tag = $attr = ''; + + if (isset($this->functions['wikiword'])) { + return call_user_func($this->functions['wikiword'],$str); + } + + return $str; + } + + /* Protection des attributs */ + function protectAttr($str,$name=false) + { + if ($name && !preg_match('/^[A-Za-z][A-Za-z0-9_:.-]*$/',$str)) { + return ''; + } + + return str_replace(array("'",'"'),array(''','"'),$str); + } + + /* Protection des urls */ + function protectUrls($str) + { + if (preg_match('/^javascript:/',$str)) { + $str = '#'; + } + + return $str; + } + + /* Auto BR */ + function __autoBR($m) + { + return $m[1].str_replace("\n","
    \n",$m[2]).$m[3]; + } + + /* Macro + --------------------------------------------------- */ + function __getMacro($s) + { + $this->macros[] = str_replace('\"','"',$s); + return 'øøø##########MACRO#'.(count($this->macros)-1).'#'; + } + + function __putMacro($id) + { + $id = (integer) $id; + if (isset($this->macros[$id])) + { + $content = str_replace("\r",'',$this->macros[$id]); + + $c = explode("\n",$content); + + # première ligne, premier mot + $fl = trim($c[0]); + $fw = $fl; + + if ($fl) { + if (strpos($fl,' ') !== false) { + $fw = substr($fl,0,strpos($fl,' ')); + } + $content = implode("\n",array_slice($c,1)); + } + + if ($c[0] == "\n") { + $content = implode("\n",array_slice($c,1)); + } + + if ($fw) + { + if (isset($this->functions['macro:'.$fw])) + { + return call_user_func($this->functions['macro:'.$fw],$content,$fl); + } + } + + # Si on n'a rien pu faire, on retourne le tout sous + # forme de
    +			return '
    '.htmlspecialchars($this->macros[$id]).'
    '; + } + + return null; + } + + function __macroHTML($s) + { + return $s; + } + + /* Aide et debug + --------------------------------------------------- */ + function help() + { + $help['b'] = array(); + $help['i'] = array(); + + $help['b'][] = 'Laisser une ligne vide entre chaque bloc de même nature.'; + $help['b'][] = 'Paragraphe : du texte et une ligne vide'; + + if ($this->getOpt('active_title')) { + $help['b'][] = 'Titre : !!!, !!, '. + '! pour des titres plus ou moins importants'; + } + + if ($this->getOpt('active_hr')) { + $help['b'][] = 'Trait horizontal : ----'; + } + + if ($this->getOpt('active_lists')) { + $help['b'][] = 'Liste : ligne débutant par * ou '. + '#. Il est possible de mélanger les listes '. + '(*#*) pour faire des listes de plusieurs niveaux. '. + 'Respecter le style de chaque niveau'; + } + + if ($this->getOpt('active_pre')) { + $help['b'][] = 'Texte préformaté : espace devant chaque ligne de texte'; + } + + if ($this->getOpt('active_quote')) { + $help['b'][] = 'Bloc de citation : > ou '. + ';: devant chaque ligne de texte'; + } + + if ($this->getOpt('active_fr_syntax')) { + $help['i'][] = 'La correction de ponctuation est active. Un espace '. + 'insécable remplacera automatiquement tout espace '. + 'précédant les marques ";","?",":" et "!".'; + } + + if ($this->getOpt('active_em')) { + $help['i'][] = 'Emphase : deux apostrophes \'\'texte\'\''; + } + + if ($this->getOpt('active_strong')) { + $help['i'][] = 'Forte emphase : deux soulignés __texte__'; + } + + if ($this->getOpt('active_br')) { + $help['i'][] = 'Retour forcé à la ligne : %%%'; + } + + if ($this->getOpt('active_ins')) { + $help['i'][] = 'Insertion : deux plus ++texte++'; + } + + if ($this->getOpt('active_del')) { + $help['i'][] = 'Suppression : deux moins --texte--'; + } + + if ($this->getOpt('active_urls')) { + $help['i'][] = 'Lien : [url], [nom|url], '. + '[nom|url|langue] ou [nom|url|langue|titre].'; + + $help['i'][] = 'Image : comme un lien mais avec une extension d\'image.'. + '
    Pour désactiver la reconnaissance d\'image mettez 0 dans un dernier '. + 'argument. Par exemple [image|image.gif||0] fera un lien vers l\'image au '. + 'lieu de l\'afficher.'. + '
    Il est conseillé d\'utiliser la nouvelle syntaxe.'; + } + + if ($this->getOpt('active_img')) { + $help['i'][] = 'Image (nouvelle syntaxe) : '. + '((url|texte alternatif)), '. + '((url|texte alternatif|position)) ou '. + '((url|texte alternatif|position|description longue)). '. + '
    La position peut prendre les valeur L ou G (gauche), R ou D (droite) ou C (centré).'; + } + + if ($this->getOpt('active_anchor')) { + $help['i'][] = 'Ancre : ~ancre~'; + } + + if ($this->getOpt('active_acronym')) { + $help['i'][] = 'Acronyme : ??acronyme?? ou '. + '??acronyme|titre??'; + } + + if ($this->getOpt('active_q')) { + $help['i'][] = 'Citation : {{citation}}, '. + '{{citation|langue}} ou {{citation|langue|url}}'; + } + + if ($this->getOpt('active_code')) { + $help['i'][] = 'Code : @@code ici@@'; + } + + if ($this->getOpt('active_footnotes')) { + $help['i'][] = 'Note de bas de page : $$Corps de la note$$'; + } + + $res = '
    '; + + $res .= '
    Blocs
    '; + if (count($help['b']) > 0) + { + $res .= '
    • '; + $res .= implode(' ;
    • ', $help['b']); + $res .= '.
    '; + } + $res .= '
    '; + + $res .= '
    Éléments en ligne
    '; + if (count($help['i']) > 0) + { + $res .= '
    • '; + $res .= implode(' ;
    • ', $help['i']); + $res .= '.
    '; + } + $res .= '
    '; + + $res .= '
    '; + + return $res; + } + + /* + function debug() + { + $mode = $type = null; + $max = count($this->T); + + $res = + ''. + ''; + + for ($i=0; $i<$max; $i++) + { + $pre_mode = $mode; + $pre_type = $type; + + $line = $this->__getLine($i,$type,$mode); + + $res .= + ''. + ''; + + } + $res .= '
    p-modep-typemodetypechaine
    '.$pre_mode.''.$pre_type.''.$mode.''.$type.''.$line.'
    '; + + return $res; + } + //*/ +} + +?> \ No newline at end of file diff --git a/inc/clearbricks/url.handler/class.url.handler.php b/inc/clearbricks/url.handler/class.url.handler.php new file mode 100644 index 0000000..72ab627 --- /dev/null +++ b/inc/clearbricks/url.handler/class.url.handler.php @@ -0,0 +1,203 @@ +mode = $mode; + } + + public function register($type,$url,$representation,$handler) + { + $this->types[$type] = array( + 'url' => $url, + 'representation' => $representation, + 'handler' => $handler + ); + } + + public function registerDefault($handler) + { + $this->default_handler = $handler; + } + + public function unregister($type) + { + if (isset($this->types[$type])) { + unset($this->types[$type]); + } + } + + public function getTypes() + { + return $this->types; + } + + public function getBase($type) + { + if (isset($this->types[$type])) { + return $this->types[$type]['url']; + } + return null; + } + + public function getDocument() + { + $type = $args = ''; + + if ($this->mode == 'path_info') + { + $part = substr($_SERVER['PATH_INFO'],1); + } + else + { + $part = ''; + + $qs = $this->parseQueryString(); + + # Recreates some _GET and _REQUEST pairs + if (!empty($qs)) + { + foreach ($_GET as $k => $v) { + if (isset($_REQUEST[$k])) { + unset($_REQUEST[$k]); + } + } + $_GET = $qs; + $_REQUEST = array_merge($qs,$_REQUEST); + + list($k,$v) = each($qs); + if ($v === null) { + $part = $k; + unset($_GET[$k]); + unset($_REQUEST[$k]); + } + } + } + + $_SERVER['URL_REQUEST_PART'] = $part; + + $this->getArgs($part,$type,$args); + + if (!$type) + { + $this->type = 'default'; + $this->callDefaultHandler($args); + } + else + { + $this->type = $type; + $this->callHandler($type,$args); + } + } + + public function getArgs($part,&$type,&$args) + { + if ($part == '') { + $type = null; + $args = null; + return; + } + + $this->sortTypes(); + + foreach ($this->types as $k => $v) + { + $repr = $v['representation']; + if ($repr == $part) { + $type = $k; + $args = null; + return; + } + elseif (preg_match('#'.$repr.'#',$part,$m)) + { + $type = $k; + $args = isset($m[1]) ? $m[1] : null; + return; + } + } + + # No type, pass args to default + $args = $part; + } + + public function callHandler($type,$args) + { + if (!isset($this->types[$type])) { + throw new Exception('Unknown URL type'); + } + + $handler = $this->types[$type]['handler']; + if (!is_callable($handler)) { + throw new Exception('Unable to call function'); + } + + call_user_func($handler,$args); + } + + public function callDefaultHandler($args) + { + if (!is_callable($this->default_handler)) { + throw new Exception('Unable to call function'); + } + + call_user_func($this->default_handler,$args); + } + + protected function parseQueryString() + { + if (!empty($_SERVER['QUERY_STRING'])) + { + $q = explode('&',$_SERVER['QUERY_STRING']); + $T = array(); + foreach ($q as $v) + { + $t = explode('=',$v,2); + + $t[0] = rawurldecode($t[0]); + if (!isset($t[1])) { + $T[$t[0]] = null; + } else { + $T[$t[0]] = urldecode($t[1]); + } + } + + return $T; + } + return array(); + } + + protected function sortTypes() + { + foreach ($this->types as $k => $v) { + $r[$k] = $v['url']; + } + array_multisort($r,SORT_DESC,$this->types); + } +} +?> \ No newline at end of file diff --git a/inc/clearbricks/zip/class.unzip.php b/inc/clearbricks/zip/class.unzip.php new file mode 100644 index 0000000..dad397a --- /dev/null +++ b/inc/clearbricks/zip/class.unzip.php @@ -0,0 +1,522 @@ +file_name = $file_name; + } + + public function __destruct() + { + $this->close(); + } + + public function close() + { + if ($this->fp) { + fclose($this->fp); + $this->fp = null; + } + + if ($this->memory_limit) { + ini_set('memory_limit',$this->memory_limit); + } + } + + public function getList($stop_on_file=false,$exclude=false) + { + if (!empty($this->compressed_list)) { + return $this->compressed_list; + } + + if (!$this->loadFileListByEOF($stop_on_file,$exclude)) { + if(!$this->loadFileListBySignatures($stop_on_file,$exclude)) { + return false; + } + } + + return $this->compressed_list; + } + + public function unzipAll($target) + { + if (empty($this->compressed_list)) { + $this->getList(); + } + + foreach ($this->compressed_list as $k => $v) + { + if ($v['is_dir']) { + continue; + } + + $this->unzip($k,$target.'/'.$k); + } + } + + public function unzip($file_name,$target=false) + { + if (empty($this->compressed_list)) { + $this->getList($file_name); + } + + if (!isset($this->compressed_list[$file_name])) { + throw new Exception(sprintf(__('File %s is not compressed in the zip.'),$file_name)); + } + $details =& $this->compressed_list[$file_name]; + + if ($details['is_dir']) { + throw new Exception(sprintf(__('Trying to unzip a folder name %s'),$file_name)); + } + + if (!$details['uncompressed_size']) { + return $this->putContent('',$target); + } + + if ($target) { + $this->testTargetDir(dirname($target)); + } + + fseek($this->fp(),$details['contents_start_offset']); + + $this->memoryAllocate($details['compressed_size']); + return $this->uncompress( + fread($this->fp(), $details['compressed_size']), + $details['compression_method'], + $details['uncompressed_size'], + $target + ); + } + + public function getFilesList() + { + if (empty($this->compressed_list)) { + $this->getList(); + } + + $res = array(); + foreach ($this->compressed_list as $k => $v) { + if (!$v['is_dir']) { + $res[] = $k; + } + } + return $res; + } + + public function getDirsList() + { + if (empty($this->compressed_list)) { + $this->getList(); + } + + $res = array(); + foreach ($this->compressed_list as $k => $v) { + if ($v['is_dir']) { + $res[] = substr($k,0,-1); + } + } + return $res; + } + + public function getRootDir() + { + if (empty($this->compressed_list)) { + $this->getList(); + } + + $files = $this->getFilesList(); + $dirs = $this->getDirsList(); + + $root_files = 0; + $root_dirs = 0; + foreach ($files as $v) { if (strpos($v,'/') === false) { $root_files++; }} + foreach ($dirs as $v) { if (strpos($v,'/') === false) { $root_dirs++; }} + + if ($root_files == 0 && $root_dirs == 1) { + return $dirs[0]; + } else { + return false; + } + } + + public function isEmpty() + { + if (empty($this->compressed_list)) { + $this->getList(); + } + + return count($this->compressed_list) == 0; + } + + public function hasFile($f) + { + if (empty($this->compressed_list)) { + $this->getList(); + } + + return isset($this->compressed_list[$f]); + } + + protected function fp() + { + if ($this->fp === null) { + $this->fp = @fopen($this->file_name,'rb'); + } + + if ($this->fp === false) { + throw new Exception('Unable to open file.'); + } + + return $this->fp; + } + + protected function putContent($content,$target=false) + { + if ($target) { + $r = @file_put_contents($target,$content); + if ($r === false) { + throw new Exception(__('Unable to write destination file.')); + } + files::inheritChmod($target); + return true; + } + return $content; + } + + protected function testTargetDir($dir) + { + if (is_dir($dir) && !is_writable($dir)) { + throw new Exception(__('Unable to write in target directory, permission denied.')); + } + + if (!is_dir($dir)) { + files::makeDir($dir,true); + } + } + + protected function uncompress($content,$mode,$size,$target=false) + { + switch ($mode) + { + case 0: + # Not compressed + $this->memoryAllocate($size*2); + return $this->putContent($content,$target); + case 1: + throw new Exception('Shrunk mode is not supported.'); + case 2: + case 3: + case 4: + case 5: + throw new Exception('Compression factor '.($mode-1).' is not supported.'); + case 6: + throw new Exception('Implode is not supported.'); + case 7: + throw new Exception('Tokenizing compression algorithm is not supported.'); + case 8: + # Deflate + if (!function_exists('gzinflate')) { + throw new Exception('Gzip functions are not available.'); + } + $this->memoryAllocate($size*2); + return $this->putContent(gzinflate($content,$size),$target); + case 9: + throw new Exception('Enhanced Deflating is not supported.'); + case 10: + throw new Exception('PKWARE Date Compression Library Impoloding is not supported.'); + case 12: + # Bzip2 + if (!function_exists('bzdecompress')) { + throw new Exception('Bzip2 functions are not available.'); + } + $this->memoryAllocate($size*2); + return $this->putContent(bzdecompress($content),$target); + case 18: + throw new Exception('IBM TERSE is not supported.'); + default: + throw new Exception('Unknown uncompress method'); + } + } + + protected function loadFileListByEOF($stop_on_file=false,$exclude=false) + { + $fp = $this->fp(); + + for ($x=0; $x<1024; $x++) + { + fseek($fp,-22-$x,SEEK_END); + $signature = fread($fp,4); + + if ($signature == $this->dir_sig_e) + { + $dir_list = array(); + + $eodir = array( + 'disk_number_this' => unpack('v', fread($fp,2)), + 'disk_number' => unpack('v', fread($fp,2)), + 'total_entries_this' => unpack('v', fread($fp,2)), + 'total_entries' => unpack('v', fread($fp,2)), + 'size_of_cd' => unpack('V', fread($fp,4)), + 'offset_start_cd' => unpack('V', fread($fp,4)) + ); + + $zip_comment_len = unpack('v', fread($fp,2)); + $eodir['zipfile_comment'] = $zip_comment_len[1] ? fread($fp,$zip_comment_len) : ''; + + $this->eo_central = array( + 'disk_number_this' => $eodir['disk_number_this'][1], + 'disk_number' => $eodir['disk_number'][1], + 'total_entries_this' => $eodir['total_entries_this'][1], + 'total_entries' => $eodir['total_entries'][1], + 'size_of_cd' => $eodir['size_of_cd'][1], + 'offset_start_cd' => $eodir['offset_start_cd'][1], + 'zipfile_comment' => $eodir['zipfile_comment'] + ); + + fseek($fp, $this->eo_central['offset_start_cd']); + $signature = fread($fp,4); + + while ($signature == $this->dir_sig) + { + $dir = array(); + $dir['version_madeby'] = unpack("v",fread($fp, 2)); # version made by + $dir['version_needed'] = unpack("v",fread($fp, 2)); # version needed to extract + $dir['general_bit_flag'] = unpack("v",fread($fp, 2)); # general purpose bit flag + $dir['compression_method'] = unpack("v",fread($fp, 2)); # compression method + $dir['lastmod_time'] = unpack("v",fread($fp, 2)); # last mod file time + $dir['lastmod_date'] = unpack("v",fread($fp, 2)); # last mod file date + $dir['crc-32'] = fread($fp,4); # crc-32 + $dir['compressed_size'] = unpack("V",fread($fp, 4)); # compressed size + $dir['uncompressed_size'] = unpack("V",fread($fp, 4)); # uncompressed size + + $file_name_len = unpack("v",fread($fp, 2)); # filename length + $extra_field_len = unpack("v",fread($fp, 2)); # extra field length + $file_comment_len = unpack("v",fread($fp, 2)); # file comment length + + $dir['disk_number_start'] = unpack("v",fread($fp, 2)); # disk number start + $dir['internal_attributes'] = unpack("v",fread($fp, 2)); # internal file attributes-byte1 + $dir['external_attributes1'] = unpack("v",fread($fp, 2)); # external file attributes-byte2 + $dir['external_attributes2'] = unpack("v",fread($fp, 2)); # external file attributes + $dir['relative_offset'] = unpack("V",fread($fp, 4)); # relative offset of local header + $dir['file_name'] = $this->cleanFileName(fread($fp, $file_name_len[1])); # filename + $dir['extra_field'] = $extra_field_len[1] ? fread($fp, $extra_field_len[1]) : ''; # extra field + $dir['file_comment'] = $file_comment_len[1] ? fread($fp, $file_comment_len[1]) : ''; # file comment + + $dir_list[$dir['file_name']] = array( + 'version_madeby' => $dir['version_madeby'][1], + 'version_needed' => $dir['version_needed'][1], + 'general_bit_flag' => str_pad(decbin($dir['general_bit_flag'][1]), 8, '0', STR_PAD_LEFT), + 'compression_method' => $dir['compression_method'][1], + 'lastmod_datetime' => $this->getTimeStamp($dir['lastmod_date'][1],$dir['lastmod_time'][1]), + 'crc-32' => str_pad(dechex(ord($dir['crc-32'][3])), 2, '0', STR_PAD_LEFT). + str_pad(dechex(ord($dir['crc-32'][2])), 2, '0', STR_PAD_LEFT). + str_pad(dechex(ord($dir['crc-32'][1])), 2, '0', STR_PAD_LEFT). + str_pad(dechex(ord($dir['crc-32'][0])), 2, '0', STR_PAD_LEFT), + 'compressed_size' => $dir['compressed_size'][1], + 'uncompressed_size' => $dir['uncompressed_size'][1], + 'disk_number_start' => $dir['disk_number_start'][1], + 'internal_attributes' => $dir['internal_attributes'][1], + 'external_attributes1' => $dir['external_attributes1'][1], + 'external_attributes2' => $dir['external_attributes2'][1], + 'relative_offset' => $dir['relative_offset'][1], + 'file_name' => $dir['file_name'], + 'extra_field' => $dir['extra_field'], + 'file_comment' => $dir['file_comment'] + ); + $signature = fread($fp, 4); + } + + foreach ($dir_list as $k => $v) + { + if ($exclude && preg_match($exclude,$k)) { + continue; + } + + $i = $this->getFileHeaderInformation($v['relative_offset']); + + $this->compressed_list[$k]['file_name'] = $k; + $this->compressed_list[$k]['is_dir'] = $v['external_attributes1'] == 16 || substr($k,-1,1) == '/'; + $this->compressed_list[$k]['compression_method'] = $v['compression_method']; + $this->compressed_list[$k]['version_needed'] = $v['version_needed']; + $this->compressed_list[$k]['lastmod_datetime'] = $v['lastmod_datetime']; + $this->compressed_list[$k]['crc-32'] = $v['crc-32']; + $this->compressed_list[$k]['compressed_size'] = $v['compressed_size']; + $this->compressed_list[$k]['uncompressed_size'] = $v['uncompressed_size']; + $this->compressed_list[$k]['lastmod_datetime'] = $v['lastmod_datetime']; + $this->compressed_list[$k]['extra_field'] = $i['extra_field']; + $this->compressed_list[$k]['contents_start_offset'] = $i['contents_start_offset']; + + if(strtolower($stop_on_file) == strtolower($k)) { + break; + } + } + return true; + } + } + return false; + } + + protected function loadFileListBySignatures($stop_on_file=false,$exclude=false) + { + $fp = $this->fp(); + fseek($fp,0); + + $return = false; + while(true) + { + $details = $this->getFileHeaderInformation(); + if (!$details) { + fseek($fp,12-4,SEEK_CUR); # 12: Data descriptor - 4: Signature (that will be read again) + $details = $this->getFileHeaderInformation(); + } + if (!$details) { + break; + } + $filename = $details['file_name']; + + if ($exclude && preg_match($exclude,$filename)) { + continue; + } + + $this->compressed_list[$filename] = $details; + $return = true; + + if (strtolower($stop_on_file) == strtolower($filename)) { + break; + } + } + + return $return; + } + + protected function getFileHeaderInformation($start_offset=false) + { + $fp = $this->fp(); + + if ($start_offset !== false) { + fseek($fp,$start_offset); + } + + $signature = fread($fp, 4); + if ($signature == $this->zip_sig) + { + # Get information about the zipped file + $file = array(); + $file['version_needed'] = unpack("v",fread($fp, 2)); # version needed to extract + $file['general_bit_flag'] = unpack("v",fread($fp, 2)); # general purpose bit flag + $file['compression_method'] = unpack("v",fread($fp, 2)); # compression method + $file['lastmod_time'] = unpack("v",fread($fp, 2)); # last mod file time + $file['lastmod_date'] = unpack("v",fread($fp, 2)); # last mod file date + $file['crc-32'] = fread($fp,4); # crc-32 + $file['compressed_size'] = unpack("V",fread($fp, 4)); # compressed size + $file['uncompressed_size'] = unpack("V",fread($fp, 4)); # uncompressed size + + $file_name_len = unpack("v",fread($fp, 2)); # filename length + $extra_field_len = unpack("v",fread($fp, 2)); # extra field length + + $file['file_name'] = $this->cleanFileName(fread($fp,$file_name_len[1])); # filename + $file['extra_field'] = $extra_field_len[1] ? fread($fp, $extra_field_len[1]) : ''; # extra field + $file['contents_start_offset'] = ftell($fp); + + # Look for the next file + fseek($fp, $file['compressed_size'][1], SEEK_CUR); + + # Mount file table + $i = array( + 'file_name' => $file['file_name'], + 'is_dir' => substr($file['file_name'],-1,1) == '/', + 'compression_method' => $file['compression_method'][1], + 'version_needed' => $file['version_needed'][1], + 'lastmod_datetime' => $this->getTimeStamp($file['lastmod_date'][1],$file['lastmod_time'][1]), + 'crc-32' => str_pad(dechex(ord($file['crc-32'][3])), 2, '0', STR_PAD_LEFT). + str_pad(dechex(ord($file['crc-32'][2])), 2, '0', STR_PAD_LEFT). + str_pad(dechex(ord($file['crc-32'][1])), 2, '0', STR_PAD_LEFT). + str_pad(dechex(ord($file['crc-32'][0])), 2, '0', STR_PAD_LEFT), + 'compressed_size' => $file['compressed_size'][1], + 'uncompressed_size' => $file['uncompressed_size'][1], + 'extra_field' => $file['extra_field'], + 'general_bit_flag' => str_pad(decbin($file['general_bit_flag'][1]), 8, '0', STR_PAD_LEFT), + 'contents_start_offset'=>$file['contents_start_offset'] + ); + return $i; + } + return false; + } + + protected function getTimeStamp($date,$time) + { + $BINlastmod_date = str_pad(decbin($date), 16, '0', STR_PAD_LEFT); + $BINlastmod_time = str_pad(decbin($time), 16, '0', STR_PAD_LEFT); + $lastmod_dateY = bindec(substr($BINlastmod_date, 0, 7))+1980; + $lastmod_dateM = bindec(substr($BINlastmod_date, 7, 4)); + $lastmod_dateD = bindec(substr($BINlastmod_date, 11, 5)); + $lastmod_timeH = bindec(substr($BINlastmod_time, 0, 5)); + $lastmod_timeM = bindec(substr($BINlastmod_time, 5, 6)); + $lastmod_timeS = bindec(substr($BINlastmod_time, 11, 5)) * 2; + + return mktime($lastmod_timeH, $lastmod_timeM, $lastmod_timeS, $lastmod_dateM, $lastmod_dateD, $lastmod_dateY); + } + + protected function cleanFileName($n) + { + $n = str_replace('../','',$n); + $n = preg_replace('#^/+#','',$n); + return $n; + } + + protected function memoryAllocate($size) + { + $mem_used = function_exists('memory_get_usage') ? @memory_get_usage() : 4000000; + $mem_limit = @ini_get('memory_limit'); + if ($mem_used && $mem_limit) + { + $mem_limit = files::str2bytes($mem_limit); + $mem_avail = $mem_limit-$mem_used-(512*1024); + $mem_needed = $size; + + if ($mem_needed > $mem_avail) + { + if (@ini_set('memory_limit',$mem_limit+$mem_needed+$mem_used) === false) { + throw new Exception(__('Not enough memory to open file.')); + } + + if (!$this->memory_limit) { + $this->memory_limit = $mem_limit; + } + } + } + } +} +?> \ No newline at end of file diff --git a/inc/clearbricks/zip/class.zip.php b/inc/clearbricks/zip/class.zip.php new file mode 100644 index 0000000..f62c419 --- /dev/null +++ b/inc/clearbricks/zip/class.zip.php @@ -0,0 +1,370 @@ +fp = $out_fp; + } + + public function __destruct() + { + $this->close(); + } + + public function close() + { + if ($this->memory_limit) { + ini_set('memory_limit',$this->memory_limit); + } + } + + public function addExclusion($reg) + { + $this->exclusions[] = $reg; + } + + public function addFile($file,$name=null) + { + $file = preg_replace('#[\\\/]+#','/',$file); + + if (!$name) { + $name = $file; + } + $name = $this->formatName($name); + + if ($this->isExcluded($name)) { + return; + } + + if (!file_exists($file) || !is_file($file)) { + throw new Exception(__('File does not exist')); + } + if (!is_readable($file)) { + throw new Exception(__('Cannot read file')); + } + + $info = stat($file); + + $this->entries[$name] = array( + 'file' => $file, + 'is_dir' => false, + 'mtime' => $info['mtime'], + 'size' => $info['size'] + ); + } + + public function addDirectory($dir,$name=null,$recursive=false) + { + $dir = preg_replace('#[\\\/]+#','/',$dir); + if (substr($dir,-1-1) != '/') { + $dir .= '/'; + } + + if (!$name && $name !== '') { + $name = $dir; + } + + if ($this->isExcluded($name)) { + return; + } + + if ($name !== '') + { + if (substr($name,-1,1) != '/') { + $name .= '/'; + } + + $name = $this->formatName($name); + + if ($name !== '') + { + $this->entries[$name] = array( + 'file' => null, + 'is_dir' => true, + 'mtime' => time(), + 'size' => 0 + ); + } + } + + if ($recursive) + { + if (!is_dir($dir)) { + throw new Exception(__('Directory does not exist')); + } + if (!is_readable($dir)) { + throw new Exception(__('Cannot read directory')); + } + + $D = dir($dir); + while (($e = $D->read()) !== false) { + if ($e == '.' || $e == '..') { + continue; + } + + if (is_dir($dir.'/'.$e)) { + $this->addDirectory($dir.$e,$name.$e,true); + } elseif (is_file($dir.'/'.$e)) { + $this->addFile($dir.$e,$name.$e); + } + } + } + } + + public function write() + { + foreach ($this->entries as $name => $v) + { + if ($v['is_dir']) { + $this->writeDirectory($name); + } else { + $this->writeFile($name,$v['file'],$v['size'],$v['mtime']); + } + } + + $ctrldir = implode('',$this->ctrl_dir); + + fwrite($this->fp, + $ctrldir. + $this->eof_ctrl_dir. + pack('v',sizeof($this->ctrl_dir)). # total # of entries "on this disk" + pack('v',sizeof($this->ctrl_dir)). # total # of entries overall + pack('V',strlen($ctrldir)). # size of central dir + pack('V',$this->old_offset). # offset to start of central dir + "\x00\x00" # .zip file comment length + ); + } + + protected function writeDirectory($name) + { + if (!isset($this->entries[$name])) { + return; + } + + $mdate = $this->makeDate(time()); + $mtime = $this->makeTime(time()); + + # Data descriptor + $data_desc = + "\x50\x4b\x03\x04". + "\x0a\x00". # ver needed to extract + "\x00\x00". # gen purpose bit flag + "\x00\x00". # compression method + pack('v',$mtime). # last mod time + pack('v',$mdate). # last mod date + pack('V',0). # crc32 + pack('V',0). # compressed filesize + pack('V',0). # uncompressed filesize + pack('v',strlen($name)). # length of pathname + pack('v',0). # extra field length + $name. # end of "local file header" segment + pack('V',0). # crc32 + pack('V',0). # compressed filesize + pack('V',0); # uncompressed filesize + + $new_offset = $this->old_offset + strlen($data_desc); + fwrite($this->fp,$data_desc); + + # Add to central record + $cdrec = + "\x50\x4b\x01\x02". + "\x00\x00". # version made by + "\x0a\x00". # version needed to extract + "\x00\x00". # gen purpose bit flag + "\x00\x00". # compression method + pack('v',$mtime). # last mod time + pack('v',$mdate). # last mod date + pack('V',0). # crc32 + pack('V',0). # compressed filesize + pack('V',0). # uncompressed filesize + pack('v',strlen($name)). # length of filename + pack('v',0). # extra field length + pack('v',0). # file comment length + pack('v',0). # disk number start + pack('v',0). # internal file attributes + pack('V',16). # external file attributes - 'directory' bit set + pack('V',$this->old_offset). # relative offset of local header + $name; + + $this->old_offset = $new_offset; + $this->ctrl_dir[] = $cdrec; + } + + protected function writeFile($name,$file,$size,$mtime) + { + if (!isset($this->entries[$name])) { + return; + } + + $size = filesize($file); + $this->memoryAllocate($size*3); + + $content = file_get_contents($file); + + $unc_len = strlen($content); + $crc = crc32($content); + $zdata = gzdeflate($content); + $c_len = strlen($zdata); + + unset($content); + + $mdate = $this->makeDate($mtime); + $mtime = $this->makeTime($mtime); + + # Data descriptor + $data_desc = + "\x50\x4b\x03\x04". + "\x14\x00". # ver needed to extract + "\x00\x00". # gen purpose bit flag + "\x08\x00". # compression method + pack('v',$mtime). # last mod time + pack('v',$mdate). # last mod date + pack('V',$crc). # crc32 + pack('V',$c_len). # compressed filesize + pack('V',$unc_len). # uncompressed filesize + pack('v',strlen($name)). # length of filename + pack('v',0). # extra field length + $name. # end of "local file header" segment + $zdata. # "file data" segment + pack('V',$crc). # crc32 + pack('V',$c_len). # compressed filesize + pack('V',$unc_len); # uncompressed filesize + + fwrite($this->fp,$data_desc); + unset($zdata); + + $new_offset = $this->old_offset + strlen($data_desc); + + # Add to central directory record + $cdrec = + "\x50\x4b\x01\x02". + "\x00\x00". # version made by + "\x14\x00". # version needed to extract + "\x00\x00". # gen purpose bit flag + "\x08\x00". # compression method + pack('v',$mtime). # last mod time + pack('v',$mdate). # last mod date + pack('V',$crc). # crc32 + pack('V',$c_len). # compressed filesize + pack('V',$unc_len). # uncompressed filesize + pack('v',strlen($name)). # length of filename + pack('v',0). # extra field length + pack('v',0). # file comment length + pack('v',0). # disk number start + pack('v',0). # internal file attributes + pack('V',32). # external file attributes - 'archive' bit set + pack('V',$this->old_offset). # relative offset of local header + $name; + + $this->old_offset = $new_offset; + $this->ctrl_dir[] = $cdrec; + } + + protected function formatName($name) + { + if (substr($name,0,1) == '/') { + $name = substr($name,1); + } + + return $name; + } + + protected function isExcluded($name) + { + foreach ($this->exclusions as $reg) { + if (preg_match($reg,$name)) { + return true; + } + } + + return false; + } + + protected function makeDate($ts) + { + $year = date('Y',$ts)-1980; + if ($year < 0) { + $year = 0; + } + + $year = sprintf('%07b',$year); + $month = sprintf('%04b',date('n',$ts)); + $day = sprintf('%05b',date('j',$ts)); + + return bindec($year.$month.$day); + } + + protected function makeTime($ts) + { + $hour = sprintf('%05b',date('G',$ts)); + $minute = sprintf('%06b',date('i',$ts)); + $second = sprintf('%05b',ceil(date('s',$ts)/2)); + + return bindec($hour.$minute.$second); + } + + protected function memoryAllocate($size) + { + $mem_used = function_exists('memory_get_usage') ? @memory_get_usage() : 4000000; + $mem_limit = @ini_get('memory_limit'); + if ($mem_used && $mem_limit) + { + $mem_limit = files::str2bytes($mem_limit); + $mem_avail = $mem_limit-$mem_used-(512*1024); + $mem_needed = $size; + + if ($mem_needed > $mem_avail) + { + if (@ini_set('memory_limit',$mem_limit+$mem_needed+$mem_used) === false) { + throw new Exception(__('Not enough memory to open file.')); + } + + if (!$this->memory_limit) { + $this->memory_limit = $mem_limit; + } + } + } + } +} +?> \ No newline at end of file diff --git a/inc/config.php b/inc/config.php new file mode 100644 index 0000000..16f2adb --- /dev/null +++ b/inc/config.php @@ -0,0 +1,67 @@ + \ No newline at end of file diff --git a/inc/config.php.in b/inc/config.php.in new file mode 100644 index 0000000..ce888b3 --- /dev/null +++ b/inc/config.php.in @@ -0,0 +1,67 @@ + \ No newline at end of file diff --git a/inc/core/class.dc.auth.php b/inc/core/class.dc.auth.php new file mode 100644 index 0000000..c19b7a2 --- /dev/null +++ b/inc/core/class.dc.auth.php @@ -0,0 +1,593 @@ +dcCore dcCore instance + protected $con; ///< connection Database connection object + + protected $user_table; ///< string User table name + protected $perm_table; ///< string Perm table name + + protected $user_id; ///< string Current user ID + protected $user_info = array(); ///< array Array with user information + protected $user_options = array(); ///< a Array with user options + protected $user_admin; ///< boolean User is super admin + protected $permissions = array(); ///< array Permissions for each blog + protected $allow_pass_change = true; ///< boolean User can change its password + protected $blogs = array(); ///< array List of blogs on which the user has permissions + public $blog_count = null; ///< integer Count of user blogs + + protected $perm_types; ///< array Permission types + + /** + Class constructor. Takes dcCore object as single argument. + + @param core dcCore dcCore object + */ + public function __construct(&$core) + { + $this->core =& $core; + $this->con =& $core->con; + $this->blog_table = $core->prefix.'blog'; + $this->user_table = $core->prefix.'user'; + $this->perm_table = $core->prefix.'permissions'; + + $this->perm_types = array( + 'admin' => __('administrator'), + 'usage' => __('manage their own entries and comments'), + 'publish' => __('publish entries and comments'), + 'delete' => __('delete entries and comments'), + 'contentadmin' => __('manage all entries and comments'), + 'categories' => __('manage categories'), + 'media' => __('manage their own media items'), + 'media_admin' => __('manage all media items') + ); + } + + /// @name Credentials and user permissions + //@{ + /** + Checks if user exists and can log in. $pwd argument is optionnal + while you may need to check user without password. This method will create + credentials and populate all needed object properties. + + @param user_id string User ID + @param pwd string User password + @param user_key string User key check + @return boolean + */ + public function checkUser($user_id, $pwd=null, $user_key=null) + { + # Check user and password + $strReq = 'SELECT user_id, user_super, user_pwd, user_name, '. + 'user_firstname, user_displayname, user_email, user_url, '. + 'user_default_blog, user_options, '. + 'user_lang, user_tz, user_post_status, user_creadt, user_upddt '. + 'FROM '.$this->con->escapeSystem($this->user_table).' '. + "WHERE user_id = '".$this->con->escape($user_id)."' "; + + $rs = $this->con->select($strReq); + + if ($rs->isEmpty()) { + return false; + } + + $rs->extend('rsExtUser'); + + if ($pwd != '') + { + if (crypt::hmac(DC_MASTER_KEY,$pwd) != $rs->user_pwd) { + sleep(rand(2,5)); + return false; + } + } + elseif ($user_key != '') + { + if (http::browserUID(DC_MASTER_KEY.$rs->user_id.$rs->user_pwd) != $user_key) { + return false; + } + } + + $this->user_id = $rs->user_id; + $this->user_admin = (boolean) $rs->user_super; + + $this->user_info['user_pwd'] = $rs->user_pwd; + $this->user_info['user_name'] = $rs->user_name; + $this->user_info['user_firstname'] = $rs->user_firstname; + $this->user_info['user_displayname'] = $rs->user_displayname; + $this->user_info['user_email'] = $rs->user_email; + $this->user_info['user_url'] = $rs->user_url; + $this->user_info['user_default_blog'] = $rs->user_default_blog; + $this->user_info['user_lang'] = $rs->user_lang; + $this->user_info['user_tz'] = $rs->user_tz; + $this->user_info['user_post_status'] = $rs->user_post_status; + $this->user_info['user_creadt'] = $rs->user_creadt; + $this->user_info['user_upddt'] = $rs->user_upddt; + + $this->user_info['user_cn'] = dcUtils::getUserCN($rs->user_id, $rs->user_name, + $rs->user_firstname, $rs->user_displayname); + + $this->user_options = array_merge($this->core->userDefaults(),$rs->options()); + + # Get permissions on blogs + if ($this->findUserBlog() === false) { + return false; + } + return true; + } + + /** + This method only check current user password. + + @param pwd string User password + @return boolean + */ + public function checkPassword($pwd) + { + if (!empty($this->user_info['user_pwd'])) { + return $pwd == $this->user_info['user_pwd']; + } + + return false; + } + + /** + This method checks if user session cookie exists + + @return boolean + */ + public function sessionExists() + { + return isset($_COOKIE[DC_SESSION_NAME]); + } + + /** + This method checks user session validity. + + @return boolean + */ + public function checkSession($uid=null) + { + $this->core->session->start(); + + # If session does not exist, logout. + if (!isset($_SESSION['sess_user_id'])) { + $this->core->session->destroy(); + return false; + } + + # Check here for user and IP address + $this->checkUser($_SESSION['sess_user_id']); + $uid = $uid ? $uid : http::browserUID(DC_MASTER_KEY); + + $user_can_log = $this->userID() !== null && $uid == $_SESSION['sess_browser_uid']; + + if (!$user_can_log) { + $this->core->session->destroy(); + return false; + } + + return true; + } + + /** + Checks if user is super admin + + @return boolean + */ + public function isSuperAdmin() + { + return $this->user_admin; + } + + /** + Checks if user has permissions given in $permissions for blog + $blog_id. $permissions is a coma separated list of + permissions. + + @param permissions string Permissions list + @param blog_id string Blog ID + @return boolean + */ + public function check($permissions,$blog_id) + { + if ($this->user_admin) { + return true; + } + + $p = explode(',',$permissions); + $b = $this->getPermissions($blog_id); + + if ($b != false) + { + if (isset($b['admin'])) { + return true; + } + + foreach ($p as $v) + { + if (isset($b[$v])) { + return true; + } + } + } + + return false; + } + + /** + Returns true if user is allowed to change its password. + + @return boolean + */ + public function allowPassChange() + { + return $this->allow_pass_change; + } + //@} + + /// @name User code handlers + //@{ + public function getUserCode() + { + $code = + pack('a32',$this->userID()). + pack('H*',crypt::hmac(DC_MASTER_KEY,$this->getInfo('user_pwd'))); + return bin2hex($code); + } + + public function checkUserCode($code) + { + $code = @pack('H*',$code); + + $user_id = trim(@pack('a32',substr($code,0,32))); + $pwd = @unpack('H40hex',substr($code,32,40)); + + if ($user_id === false || $pwd === false) { + return false; + } + + $pwd = $pwd['hex']; + + $strReq = 'SELECT user_id, user_pwd '. + 'FROM '.$this->user_table.' '. + "WHERE user_id = '".$this->con->escape($user_id)."' "; + + $rs = $this->con->select($strReq); + + if ($rs->isEmpty()) { + return false; + } + + if (crypt::hmac(DC_MASTER_KEY,$rs->user_pwd) != $pwd) { + return false; + } + + return $rs->user_id; + } + //@} + + + /// @name Sudo + //@{ + /** + Calls $f function with super admin rights. + + @param f callback Callback function + @return mixed Function result + */ + public function sudo($f) + { + if (!is_callable($f)) { + throw new Exception($f.' function doest not exist'); + } + + $args = func_get_args(); + array_shift($args); + + if ($this->user_admin) { + $res = call_user_func_array($f,$args); + } else { + $this->user_admin = true; + try { + $res = call_user_func_array($f,$args); + $this->user_admin = false; + } catch (Exception $e) { + $this->user_admin = false; + throw $e; + } + } + + return $res; + } + //@} + + /// @name User information and options + //@{ + /** + Returns user permissions for a blog as an array which looks like: + + - [blog_id] + - [permission] => true + - ... + + @return array + */ + public function getPermissions($blog_id) + { + if (isset($this->blogs[$blog_id])) { + return $this->blogs[$blog_id]; + } + + if ($this->blog_count === null) { + $this->blog_count = $this->core->getBlogs(array(),true)->f(0); + } + + if ($this->user_admin) { + $strReq = 'SELECT blog_id '. + 'from '.$this->blog_table.' '. + "WHERE blog_id = '".$this->con->escape($blog_id)."' "; + $rs = $this->con->select($strReq); + + $this->blogs[$blog_id] = $rs->isEmpty() ? false : array('admin' => true); + + return $this->blogs[$blog_id]; + } + + $strReq = 'SELECT permissions '. + 'FROM '.$this->perm_table.' '. + "WHERE user_id = '".$this->con->escape($this->user_id)."' ". + "AND blog_id = '".$this->con->escape($blog_id)."' ". + "AND (permissions LIKE '%|usage|%' OR permissions LIKE '%|admin|%' OR permissions LIKE '%|contentadmin|%') "; + $rs = $this->con->select($strReq); + + $this->blogs[$blog_id] = $rs->isEmpty() ? false : $this->parsePermissions($rs->permissions); + + return $this->blogs[$blog_id]; + } + + public function findUserBlog($blog_id=null) + { + if ($blog_id && $this->getPermissions($blog_id) !== false) + { + return $blog_id; + } + else + { + if ($this->user_admin) + { + $strReq = 'SELECT blog_id '. + 'FROM '.$this->blog_table.' '. + 'ORDER BY blog_id ASC '. + $this->con->limit(1); + } + else + { + $strReq = 'SELECT blog_id '. + 'FROM '.$this->perm_table.' '. + "WHERE user_id = '".$this->con->escape($this->user_id)."' ". + "AND (permissions LIKE '%|usage|%' OR permissions LIKE '%|admin|%' OR permissions LIKE '%|contentadmin|%') ". + 'ORDER BY blog_id ASC '. + $this->con->limit(1); + } + + $rs = $this->con->select($strReq); + if (!$rs->isEmpty()) { + return $rs->blog_id; + } + } + + return false; + } + + /** + Returns current user ID + + @return string + */ + public function userID() + { + return $this->user_id; + } + + /** + Returns information about a user . + + @param n string Information name + @return string Information value + */ + public function getInfo($n) + { + if (isset($this->user_info[$n])) { + return $this->user_info[$n]; + } + + return null; + } + + /** + Returns a specific user option + + @param n string Option name + @return string Option value + */ + public function getOption($n) + { + if (isset($this->user_options[$n])) { + return $this->user_options[$n]; + } + return null; + } + + /** + Returns all user options in an associative array. + + @return array + */ + public function getOptions() + { + return $this->user_options; + } + //@} + + /// @name Permissions + //@{ + /** + Returns an array with permissions parsed from the string $level + + @param level string Permissions string + @return array + */ + public function parsePermissions($level) + { + $level = preg_replace('/^\|/','',$level); + $level = preg_replace('/\|$/','',$level); + + $res = array(); + foreach (explode('|',$level) as $v) { + $res[$v] = true; + } + return $res; + } + + /** + Returns perm_types property content. + + @return array + */ + public function getPermissionsTypes() + { + return $this->perm_types; + } + + /** + Adds a new permission type. + + @param name string Permission name + @param title string Permission title + */ + public function setPermissionType($name,$title) + { + $this->perm_types[$name] = $title; + } + //@} + + /// @name Password recovery + //@{ + /** + Add a recover key to a specific user identified by its email and + password. + + @param user_id string User ID + @param user_email string User Email + @return string Recover key + */ + public function setRecoverKey($user_id,$user_email) + { + $strReq = 'SELECT user_id '. + 'FROM '.$this->user_table.' '. + "WHERE user_id = '".$this->con->escape($user_id)."' ". + "AND user_email = '".$this->con->escape($user_email)."' "; + + $rs = $this->con->select($strReq); + + if ($rs->isEmpty()) { + throw new Exception(__('That user does not exist in the database.')); + } + + $key = md5(uniqid()); + + $cur = $this->con->openCursor($this->user_table); + $cur->user_recover_key = $key; + + $cur->update("WHERE user_id = '".$this->con->escape($user_id)."'"); + + return $key; + } + + /** + Creates a new user password using recovery key. Returns an array: + + - user_email + - user_id + - new_pass + + @param recover_key string Recovery key + @return array + */ + public function recoverUserPassword($recover_key) + { + $strReq = 'SELECT user_id, user_email '. + 'FROM '.$this->user_table.' '. + "WHERE user_recover_key = '".$this->con->escape($recover_key)."' "; + + $rs = $this->con->select($strReq); + + if ($rs->isEmpty()) { + throw new Exception(__('That key does not exist in the database.')); + } + + $new_pass = crypt::createPassword(); + + $cur = $this->con->openCursor($this->user_table); + $cur->user_pwd = crypt::hmac(DC_MASTER_KEY,$new_pass); + $cur->user_recover_key = null; + + $cur->update("WHERE user_recover_key = '".$this->con->escape($recover_key)."'"); + + return array('user_email' => $rs->user_email, 'user_id' => $rs->user_id, 'new_pass' => $new_pass); + } + //@} + + /** @name User management callbacks + This 3 functions only matter if you extend this class and use + DC_AUTH_CLASS constant. + These are called after core user management functions. + Could be useful if you need to add/update/remove stuff in your + LDAP directory or other third party authentication database. + */ + //@{ + + /** + Called after core->addUser + @see dcCore::addUser + @param cur cursor User cursor + */ + public function afterAddUser(&$cur) {} + + /** + Called after core->updUser + @see dcCore::updUser + @param id string User ID + @param cur cursor User cursor + */ + public function afterUpdUser($id,&$cur) {} + + /** + Called after core->delUser + @see dcCore::delUser + @param id string User ID + */ + public function afterDelUser($id) {} + //@} +} +?> \ No newline at end of file diff --git a/inc/core/class.dc.blog.php b/inc/core/class.dc.blog.php new file mode 100644 index 0000000..60a55d4 --- /dev/null +++ b/inc/core/class.dc.blog.php @@ -0,0 +1,2006 @@ +dcCore dcCore instance + public $con; ///< connection Database connection object + public $prefix; ///< string Database table prefix + + public $id; ///< string Blog ID + public $uid; ///< string Blog unique ID + public $name; ///< string Blog name + public $desc; ///< string Blog description + public $url; ///< string Blog URL + public $host; ///< string Blog host + public $creadt; ///< string Blog creation date + public $upddt; ///< string Blog last update date + public $status; ///< string Blog status + + public $settings; ///< dcSettings dcSettings object + public $themes_path; ///< string Blog theme path + public $public_path; ///< string Blog public path + + private $post_status = array(); + private $comment_status = array(); + + private $categories; + + public $without_password = true; ///< boolean Disallow entries password protection + + /** + Inits dcBlog object + + @param core dcCore Dotclear core reference + @param id string Blog ID + */ + public function __construct(&$core, $id) + { + $this->con =& $core->con; + $this->prefix = $core->prefix; + $this->core =& $core; + + if (($b = $this->core->getBlog($id)) !== false) + { + $this->id = $id; + $this->uid = $b->blog_uid; + $this->name = $b->blog_name; + $this->desc = $b->blog_desc; + $this->url = $b->blog_url; + $this->host = preg_replace('|^([a-z]{3,}://)(.*?)/.*$|','$1$2',$this->url); + $this->creadt = strtotime($b->blog_creadt); + $this->upddt = strtotime($b->blog_upddt); + $this->status = $b->blog_status; + + $this->settings = new dcSettings($this->core,$this->id); + + $this->themes_path = path::fullFromRoot($this->settings->themes_path,DC_ROOT); + $this->public_path = path::fullFromRoot($this->settings->public_path,DC_ROOT); + + $this->post_status['-2'] = __('pending'); + $this->post_status['-1'] = __('scheduled'); + $this->post_status['0'] = __('unpublished'); + $this->post_status['1'] = __('published'); + + $this->comment_status['-2'] = __('junk'); + $this->comment_status['-1'] = __('pending'); + $this->comment_status['0'] = __('unpublished'); + $this->comment_status['1'] = __('published'); + + # --BEHAVIOR-- coreBlogConstruct + $this->core->callBehavior('coreBlogConstruct',$this); + } + } + + /// @name Common public methods + //@{ + /** + Returns blog URL ending with a question mark. + */ + public function getQmarkURL() + { + if (substr($this->url,-1) != '?') { + return $this->url.'?'; + } + + return $this->url; + } + + /** + Returns an entry status name given to a code. Status are translated, never + use it for tests. If status code does not exist, returns unpublished. + + @param s integer Status code + @return string Blog status name + */ + public function getPostStatus($s) + { + if (isset($this->post_status[$s])) { + return $this->post_status[$s]; + } + return $this->post_status['0']; + } + + /** + Returns an array of available entry status codes and names. + + @return array Simple array with codes in keys and names in value + */ + public function getAllPostStatus() + { + return $this->post_status; + } + + /** + Returns an array of available comment status codes and names. + + @return array Simple array with codes in keys and names in value + */ + public function getAllCommentStatus() + { + return $this->comment_status; + } + + /** + Disallows entries password protection. You need to set it to + false while serving a public blog. + + @param v boolean + */ + public function withoutPassword($v) + { + $this->without_password = (boolean) $v; + } + //@} + + /// @name Triggers methods + //@{ + /** + Updates blog last update date. Should be called every time you change + an element related to the blog. + */ + public function triggerBlog() + { + $cur = $this->con->openCursor($this->prefix.'blog'); + + $cur->blog_upddt = date('Y-m-d H:i:s'); + + $cur->update("WHERE blog_id = '".$this->con->escape($this->id)."' "); + + # --BEHAVIOR-- coreBlogAfterTriggerBlog + $this->core->callBehavior('coreBlogAfterTriggerBlog',$cur); + } + + /** + Updates comment and trackback counters in post table. Should be called + every time a comment or trackback is added, removed or changed its status. + + @param id integer Comment ID + @param del boolean If comment is delete, set this to true + */ + public function triggerComment($id,$del=false) + { + $id = (integer) $id; + + $strReq = 'SELECT post_id, comment_trackback '. + 'FROM '.$this->prefix.'comment '. + 'WHERE comment_id = '.$id.' '; + + $rs = $this->con->select($strReq); + + $post_id = $rs->post_id; + $tb = (boolean) $rs->comment_trackback; + + $strReq = 'SELECT COUNT(post_id) '. + 'FROM '.$this->prefix.'comment '. + 'WHERE post_id = '.(integer) $post_id.' '. + 'AND comment_trackback = '.(integer) $tb.' '. + 'AND comment_status = 1 '; + + if ($del) { + $strReq .= 'AND comment_id <> '.$id.' '; + } + + $rs = $this->con->select($strReq); + + $cur = $this->con->openCursor($this->prefix.'post'); + + if ($rs->isEmpty()) { + return; + } + + if ($tb) { + $cur->nb_trackback = (integer) $rs->f(0); + } else { + $cur->nb_comment = (integer) $rs->f(0); + } + + $cur->update('WHERE post_id = '.(integer) $post_id); + } + //@} + + /// @name Categories management methods + //@{ + public function categories() + { + if (!($this->categories instanceof dcCategories)) { + $this->categories = new dcCategories($this->core); + } + + return $this->categories; + } + + /** + Retrieves categories. $params is an associative array which can + take the following parameters: + + - post_type: Get only entries with given type (default "post") + - cat_url: filter on cat_url field + - cat_id: filter on cat_id field + - start: start with a given category + - level: categories level to retrieve + + @param params array Parameters + @return record + */ + public function getCategories($params=array()) + { + $c_params = array(); + if (isset($params['post_type'])) { + $c_params['post_type'] = $params['post_type']; + unset($params['post_type']); + } + $counter = $this->getCategoriesCounter($c_params); + + $without_empty = $this->core->auth->userID() == false; # For public display + + $start = isset($params['start']) ? (integer) $params['start'] : 0; + $l = isset($params['level']) ? (integer) $params['level'] : 0; + + $rs = $this->categories()->getChildren($start,null,'desc'); + + # Get each categories total posts count + $data = array(); + $stack = array(); + $level = 0; + $cols = $rs->columns(); + while ($rs->fetch()) + { + $nb_post = isset($counter[$rs->cat_id]) ? (integer) $counter[$rs->cat_id] : 0; + + if ($rs->level > $level) { + $nb_total = $nb_post; + $stack[$rs->level] = (integer) $nb_post; + } elseif ($rs->level == $level) { + $nb_total = $nb_post; + $stack[$rs->level] += $nb_post; + } else { + $nb_total = $stack[$rs->level+1] + $nb_post; + if (isset($stack[$rs->level])) { + $stack[$rs->level] += $nb_total; + } else { + $stack[$rs->level] = $nb_total; + } + unset($stack[$rs->level+1]); + } + + if ($nb_total == 0 && $without_empty) { + continue; + } + + $level = $rs->level; + + $t = array(); + foreach ($cols as $c) { + $t[$c] = $rs->f($c); + } + $t['nb_post'] = $nb_post; + $t['nb_total'] = $nb_total; + + if ($l == 0 || ($l > 0 && $l == $rs->level)) { + array_unshift($data,$t); + } + } + + # We need to apply filter after counting + if (!empty($params['cat_id'])) + { + $found = false; + foreach ($data as $v) { + if ($v['cat_id'] == $params['cat_id']) { + $found = true; + $data = array($v); + break; + } + } + if (!$found) { + $data = array(); + } + } + + if (!empty($params['cat_url']) && empty($params['cat_id'])) + { + $found = false; + foreach ($data as $v) { + if ($v['cat_url'] == $params['cat_url']) { + $found = true; + $data = array($v); + break; + } + } + if (!$found) { + $data = array(); + } + } + + return staticRecord::newFromArray($data); + } + + /** + Retrieves a category by its ID. + + @param id integer Category ID + @return record + */ + public function getCategory($id) + { + return $this->getCategories(array('cat_id' => $id)); + } + + /** + Retrieves parents of a given category. + + @param id integer Category ID + @return record + */ + public function getCategoryParents($id) + { + return $this->categories()->getParents($id); + } + + /** + Retrieves first parent of a given category. + + @param id integer Category ID + @return record + */ + public function getCategoryParent($id) + { + return $this->categories()->getParent($id); + } + + /** + Retrieves all category's first children + + @param id integer Category ID + @return record + */ + public function getCategoryFirstChildren($id) + { + return $this->getCategories(array('start' => $id,'level' => $id == 0 ? 1 : 2)); + } + + private function getCategoriesCounter($params=array()) + { + $strReq = + 'SELECT C.cat_id, COUNT(P.post_id) AS nb_post '. + 'FROM '.$this->prefix.'category AS C '. + 'JOIN '.$this->prefix."post P ON (C.cat_id = P.cat_id AND P.blog_id = '".$this->con->escape($this->id)."' ) ". + "WHERE C.blog_id = '".$this->con->escape($this->id)."' "; + + if (!$this->core->auth->userID()) { + $strReq .= 'AND P.post_status = 1 '; + } + + if (!empty($params['post_type'])) { + $strReq .= "AND post_type = '".$this->con->escape($params['post_type'])."' "; + } + + $strReq .= 'GROUP BY C.cat_id '; + + $rs = $this->con->select($strReq); + $counters = array(); + while ($rs->fetch()) { + $counters[$rs->cat_id] = $rs->nb_post; + } + + return $counters; + } + + /** + Creates a new category. Takes a cursor as input and returns the new category + ID. + + @param cur cursor Category cursor + @return integer New category ID + */ + public function addCategory($cur,$parent=0) + { + if (!$this->core->auth->check('categories',$this->id)) { + throw new Exception(__('You are not allowed to add categories')); + } + + $url = array(); + if ($parent != 0) + { + $rs = $this->getCategory($parent); + if ($rs->isEmpty()) { + $url = array(); + } else { + $url[] = $rs->cat_url; + } + } + + if ($cur->cat_url == '') { + $url[] = text::tidyURL($cur->cat_title,false); + } else { + $url[] = $cur->cat_url; + } + + $cur->cat_url = implode('/',$url); + + $this->getCategoryCursor($cur); + $cur->blog_id = (string) $this->id; + + $this->categories()->addNode($cur,$parent); + $this->triggerBlog(); + + return $cur->cat_id; + } + + /** + Updates an existing category. + + @param id integer Category ID + @param cur cursor Category cursor + */ + public function updCategory($id,&$cur) + { + if (!$this->core->auth->check('categories',$this->id)) { + throw new Exception(__('You are not allowed to update categories')); + } + + if ($cur->cat_url == '') + { + $url = array(); + $rs = $this->categories()->getParents($id); + while ($rs->fetch()) { + if ($rs->index() == $rs->count()-1) { + $url[] = $rs->cat_url; + } + } + + + $url[] = text::tidyURL($cur->cat_title,false); + $cur->cat_url = implode('/',$url); + } + + $this->getCategoryCursor($cur,$id); + + $cur->update( + 'WHERE cat_id = '.(integer) $id.' '. + "AND blog_id = '".$this->con->escape($this->id)."' "); + $this->triggerBlog(); + } + + /** + DEPRECATED METHOD. Use dcBlog::setCategoryParent and dcBlog::moveCategory + instead. + + @param id integer Category ID + @param order integer Category position + */ + public function updCategoryOrder($id,$order) + { + return; + } + + /** + Set a category parent + + @param id integer Category ID + @param parent integer Parent Category ID + */ + public function setCategoryParent($id,$parent) + { + $this->categories()->setNodeParent($id,$parent); + $this->triggerBlog(); + } + + /** + Set category position + + @param id integer Category ID + @param sibling integer Sibling Category ID + @param move integer Order (before|after) + */ + public function setCategoryPosition($id,$sibling,$move) + { + $this->categories()->setNodePosition($id,$sibling,$move); + $this->triggerBlog(); + } + + /** + Deletes a category. + + @param id integer Category ID + */ + public function delCategory($id) + { + if (!$this->core->auth->check('categories',$this->id)) { + throw new Exception(__('You are not allowed to delete categories')); + } + + $strReq = 'SELECT COUNT(post_id) AS nb_post '. + 'FROM '.$this->prefix.'post '. + 'WHERE cat_id = '.(integer) $id.' '. + "AND blog_id = '".$this->con->escape($this->id)."' "; + + $rs = $this->con->select($strReq); + + if ($rs->nb_post > 0) { + throw new Exception(__('This category is not empty.')); + } + + $this->categories()->deleteNode($id,true); + $this->triggerBlog(); + } + + /** + Reset categories order and relocate them to first level + */ + public function resetCategoriesOrder() + { + if (!$this->core->auth->check('categories',$this->id)) { + throw new Exception(__('You are not allowed to delete categories')); + } + + $this->categories()->resetOrder(); + } + + private function checkCategory($title,$url,$id=null) + { + $strReq = 'SELECT cat_id '. + 'FROM '.$this->prefix.'category '. + "WHERE cat_url = '".$this->con->escape($url)."' ". + "AND blog_id = '".$this->con->escape($this->id)."' "; + + if ($id !== null) { + $strReq .= 'AND cat_id <> '.(integer) $id.' '; + } + + $rs = $this->con->select($strReq); + + if (!$rs->isEmpty()) { + throw new Exception(__('Category URL must be unique.')); + } + } + + private function getCategoryCursor(&$cur,$id=null) + { + if ($cur->cat_title == '') { + throw new Exception(__('You must provide a category title')); + } + + # If we don't have any cat_url, let's do one + if ($cur->cat_url == '') { + $cur->cat_url = text::tidyURL($cur->cat_title,false); + } + + # Still empty ? + if ($cur->cat_url == '') { + throw new Exception(__('You must provide a category URL')); + } else { + $cur->cat_url = text::tidyURL($cur->cat_url,true); + } + + # Check if title or url are unique + $this->checkCategory($cur->cat_title,$cur->cat_url,$id); + + if ($cur->cat_desc !== null) { + $cur->cat_desc = $this->core->HTMLfilter($cur->cat_desc); + } + } + //@} + + /// @name Entries management methods + //@{ + /** + Retrieves entries. $params is an array taking the following + optionnal parameters: + + - no_content: Don't retrieve entry content (excerpt and content) + - post_type: Get only entries with given type (default "post", array for many types and '' for no type) + - post_id: (integer) Get entry with given post_id + - post_url: Get entry with given post_url field + - user_id: (integer) Get entries belonging to given user ID + - cat_id: (string or array) Get entries belonging to given category ID + - cat_id_not: deprecated (use cat_id with "id ?not" instead) + - cat_url: (string or array) Get entries belonging to given category URL + - cat_url_not: deprecated (use cat_url with "url ?not" instead) + - post_status: (integer) Get entries with given post_status + - post_selected: (boolean) Get select flaged entries + - post_year: (integer) Get entries with given year + - post_month: (integer) Get entries with given month + - post_day: (integer) Get entries with given day + - post_lang: Get entries with given language code + - search: Get entries corresponding of the following search string + - columns: (array) More columns to retrieve + - sql: Append SQL string at the end of the query + - from: Append SQL string after "FROM" statement in query + - order: Order of results (default "ORDER BY post_dt DES") + - limit: Limit parameter + + Please note that on every cat_id or cat_url, you can add ?not to exclude + the category and ?sub to get subcategories. + + @param params array Parameters + @param count_only boolean Only counts results + @return record A record with some more capabilities + */ + public function getPosts($params=array(),$count_only=false) + { + if ($count_only) + { + $strReq = 'SELECT count(P.post_id) '; + } + else + { + if (!empty($params['no_content'])) { + $content_req = ''; + } else { + $content_req = + 'post_excerpt, post_excerpt_xhtml, '. + 'post_content, post_content_xhtml, post_notes, '; + } + + if (!empty($params['columns']) && is_array($params['columns'])) { + $content_req .= implode(', ',$params['columns']).', '; + } + + $strReq = + 'SELECT P.post_id, P.blog_id, P.user_id, P.cat_id, post_dt, '. + 'post_tz, post_creadt, post_upddt, post_format, post_password, '. + 'post_url, post_lang, post_title, '.$content_req. + 'post_type, post_meta, post_status, post_selected, post_position, '. + 'post_open_comment, post_open_tb, nb_comment, nb_trackback, '. + 'U.user_name, U.user_firstname, U.user_displayname, U.user_email, '. + 'U.user_url, '. + 'C.cat_title, C.cat_url, C.cat_desc '; + } + + $strReq .= + 'FROM '.$this->prefix.'post P '. + 'INNER JOIN '.$this->prefix.'user U ON U.user_id = P.user_id '. + 'LEFT OUTER JOIN '.$this->prefix.'category C ON P.cat_id = C.cat_id '; + + if (!empty($params['from'])) { + $strReq .= $params['from'].' '; + } + + $strReq .= + "WHERE P.blog_id = '".$this->con->escape($this->id)."' "; + + if (!$this->core->auth->check('contentadmin',$this->id)) { + $strReq .= 'AND ((post_status = 1 '; + + if ($this->without_password) { + $strReq .= 'AND post_password IS NULL '; + } + $strReq .= ') '; + + if ($this->core->auth->userID()) { + $strReq .= "OR P.user_id = '".$this->con->escape($this->core->auth->userID())."')"; + } else { + $strReq .= ') '; + } + } + + #Adding parameters + if (isset($params['post_type'])) + { + if (is_array($params['post_type']) && !empty($params['post_type'])) { + $strReq .= 'AND post_type '.$this->con->in($params['post_type']); + } elseif ($params['post_type'] != '') { + $strReq .= "AND post_type = '".$this->con->escape($params['post_type'])."' "; + } + } + else + { + $strReq .= "AND post_type = 'post' "; + } + + if (!empty($params['post_id'])) { + if (is_array($params['post_id'])) { + array_walk($params['post_id'],create_function('&$v,$k','if($v!==null){$v=(integer)$v;}')); + } else { + $params['post_id'] = array((integer) $params['post_id']); + } + $strReq .= 'AND P.post_id '.$this->con->in($params['post_id']); + } + + if (!empty($params['post_url'])) { + $strReq .= "AND post_url = '".$this->con->escape($params['post_url'])."' "; + } + + if (!empty($params['user_id'])) { + $strReq .= "AND U.user_id = '".$this->con->escape($params['user_id'])."' "; + } + + if (!empty($params['cat_id'])) + { + if (!is_array($params['cat_id'])) { + $params['cat_id'] = array($params['cat_id']); + } + if (!empty($params['cat_id_not'])) { + array_walk($params['cat_id'],create_function('&$v,$k','$v=$v." ?not";')); + } + $strReq .= 'AND '.$this->getPostsCategoryFilter($params['cat_id'],'cat_id').' '; + } + elseif (!empty($params['cat_url'])) + { + if (!is_array($params['cat_url'])) { + $params['cat_url'] = array($params['cat_url']); + } + if (!empty($params['cat_url_not'])) { + array_walk($params['cat_url'],create_function('&$v,$k','$v=$v." ?not";')); + } + $strReq .= 'AND '.$this->getPostsCategoryFilter($params['cat_url'],'cat_url').' '; + } + + /* Other filters */ + if (isset($params['post_status'])) { + $strReq .= 'AND post_status = '.(integer) $params['post_status'].' '; + } + + if (isset($params['post_selected'])) { + $strReq .= 'AND post_selected = '.(integer) $params['post_selected'].' '; + } + + if (!empty($params['post_year'])) { + $strReq .= 'AND '.$this->con->dateFormat('post_dt','%Y').' = '. + "'".sprintf('%04d',$params['post_year'])."' "; + } + + if (!empty($params['post_month'])) { + $strReq .= 'AND '.$this->con->dateFormat('post_dt','%m').' = '. + "'".sprintf('%02d',$params['post_month'])."' "; + } + + if (!empty($params['post_day'])) { + $strReq .= 'AND '.$this->con->dateFormat('post_dt','%d').' = '. + "'".sprintf('%02d',$params['post_day'])."' "; + } + + if (!empty($params['post_lang'])) { + $strReq .= "AND P.post_lang = '".$this->con->escape($params['post_lang'])."' "; + } + + if (!empty($params['search'])) + { + $words = text::splitWords($params['search']); + + if (!empty($words)) + { + # --BEHAVIOR-- corePostSearch + if ($this->core->hasBehavior('corePostSearch')) { + $this->core->callBehavior('corePostSearch',$this->core,array(&$words,&$strReq,&$params)); + } + + if ($words) + { + foreach ($words as $i => $w) { + $words[$i] = "post_words LIKE '%".$this->con->escape($w)."%'"; + } + $strReq .= 'AND '.implode(' AND ',$words).' '; + } + } + } + + if (!empty($params['sql'])) { + $strReq .= $params['sql'].' '; + } + + if (!$count_only) + { + if (!empty($params['order'])) { + $strReq .= 'ORDER BY '.$this->con->escape($params['order']).' '; + } else { + $strReq .= 'ORDER BY post_dt DESC '; + } + } + + if (!$count_only && !empty($params['limit'])) { + $strReq .= $this->con->limit($params['limit']); + } + + $rs = $this->con->select($strReq); + $rs->core = $this->core; + $rs->_nb_media = array(); + $rs->extend('rsExtPost'); + + # --BEHAVIOR-- coreBlogGetPosts + $this->core->callBehavior('coreBlogGetPosts',$rs); + + return $rs; + } + + /** + Returns a record with post id, title and date for next or previous post + according to the post ID. + $dir could be 1 (next post) or -1 (previous post). + + @param post_id integer Post ID + @param dir integer Search direction + @param restrict_to_category boolean Restrict to post with same category + @param restrict_to_lang boolean Restrict to post with same lang + @return record + */ + public function getNextPost($post,$dir,$restrict_to_category=false, $restrict_to_lang=false) + { + $dt = $post->post_dt; + $post_id = (integer) $post->post_id; + + if($dir > 0) { + $sign = '>'; + $order = 'ASC'; + } + else { + $sign = '<'; + $order = 'DESC'; + } + + $params['post_type'] = $post->post_type; + $params['limit'] = 1; + $params['order'] = 'post_dt '.$order.', P.post_id '.$order; + $params['sql'] = + 'AND ( '. + " (post_dt = '".$this->con->escape($dt)."' AND P.post_id ".$sign." ".$post_id.") ". + " OR post_dt ".$sign." '".$this->con->escape($dt)."' ". + ') '; + + if ($restrict_to_category) { + $params['sql'] .= $post->cat_id ? 'AND P.cat_id = '.(integer) $post->cat_id : 'AND P.cat_id IS NULL'; + } + + if ($restrict_to_lang) { + $params['sql'] .= $post->post_lang ? 'AND P.post_lang = \''. $this->con->escape($post->post_lang) .'\'': 'AND P.post_lang IS NULL'; + } + + $rs = $this->getPosts($params); + + if ($rs->isEmpty()) { + return null; + } + + return $rs; + } + + /** + Retrieves different languages and post count on blog, based on post_lang + field. $params is an array taking the following optionnal + parameters: + + - post_type: Get only entries with given type (default "post", '' for no type) + - lang: retrieve post count for selected lang + - order: order statement (default post_lang DESC) + + @param params array Parameters + @return record + */ + public function getLangs($params=array()) + { + $strReq = 'SELECT COUNT(post_id) as nb_post, post_lang '. + 'FROM '.$this->prefix.'post '. + "WHERE blog_id = '".$this->con->escape($this->id)."' ". + "AND post_lang <> '' ". + "AND post_lang IS NOT NULL "; + + if (!$this->core->auth->check('contentadmin',$this->id)) { + $strReq .= 'AND ((post_status = 1 '; + + if ($this->without_password) { + $strReq .= 'AND post_password IS NULL '; + } + $strReq .= ') '; + + if ($this->core->auth->userID()) { + $strReq .= "OR user_id = '".$this->con->escape($this->core->auth->userID())."')"; + } else { + $strReq .= ') '; + } + } + + if (isset($params['post_type'])) { + if ($params['post_type'] != '') { + $strReq .= "AND post_type = '".$this->con->escape($params['post_type'])."' "; + } + } else { + $strReq .= "AND post_type = 'post' "; + } + + if (isset($params['lang'])) { + $strReq .= "AND post_lang = '".$this->con->escape($params['lang'])."' "; + } + + $strReq .= 'GROUP BY post_lang '; + + $order = 'desc'; + if (!empty($params['order']) && preg_match('/^(desc|asc)$/i',$params['order'])) { + $order = $params['order']; + } + $strReq .= 'ORDER BY post_lang '.$order.' '; + + return $this->con->select($strReq); + } + + /** + Returns a record with all distinct blog dates and post count. + $params is an array taking the following optionnal parameters: + + - type: (day|month|year) Get days, months or years + - year: (integer) Get dates for given year + - month: (integer) Get dates for given month + - day: (integer) Get dates for given day + - cat_id: (integer) Category ID filter + - cat_url: Category URL filter + - post_lang: lang of the posts + - next: Get date following match + - previous: Get date before match + - order: Sort by date "ASC" or "DESC" + + @param params array Parameters array + @return record + */ + public function getDates($params=array()) + { + $dt_f = '%Y-%m-%d'; + $dt_fc = '%Y%m%d'; + if (isset($params['type'])) { + if ($params['type'] == 'year') { + $dt_f = '%Y-01-01'; + $dt_fc = '%Y0101'; + } elseif ($params['type'] == 'month') { + $dt_f = '%Y-%m-01'; + $dt_fc = '%Y%m01'; + } + } + $dt_f .= ' 00:00:00'; + $dt_fc .= '000000'; + + $cat_field = $catReq = $limit = ''; + + if (!empty($params['cat_id'])) { + $catReq = 'AND P.cat_id = '.(integer) $params['cat_id'].' '; + $cat_field = ', C.cat_url '; + } elseif (!empty($params['cat_url'])) { + $catReq = "AND C.cat_url = '".$this->con->escape($params['cat_url'])."' "; + $cat_field = ', C.cat_url '; + } + if (!empty($params['post_lang'])) { + $catReq = 'AND P.post_lang = \''. $params['post_lang'].'\' '; + } + + $strReq = 'SELECT DISTINCT('.$this->con->dateFormat('post_dt',$dt_f).') AS dt '. + $cat_field. + ',COUNT(P.post_id) AS nb_post '. + 'FROM '.$this->prefix.'post P LEFT JOIN '.$this->prefix.'category C '. + 'ON P.cat_id = C.cat_id '. + "WHERE P.blog_id = '".$this->con->escape($this->id)."' ". + $catReq; + + if (!$this->core->auth->check('contentadmin',$this->id)) { + $strReq .= 'AND ((post_status = 1 '; + + if ($this->without_password) { + $strReq .= 'AND post_password IS NULL '; + } + $strReq .= ') '; + + if ($this->core->auth->userID()) { + $strReq .= "OR P.user_id = '".$this->con->escape($this->core->auth->userID())."')"; + } else { + $strReq .= ') '; + } + } + + if (!empty($params['post_type'])) { + $strReq .= "AND post_type = '".$this->con->escape($params['post_type'])."' "; + } + + if (!empty($params['year'])) { + $strReq .= 'AND '.$this->con->dateFormat('post_dt','%Y')." = '".sprintf('%04d',$params['year'])."' "; + } + + if (!empty($params['month'])) { + $strReq .= 'AND '.$this->con->dateFormat('post_dt','%m')." = '".sprintf('%02d',$params['month'])."' "; + } + + if (!empty($params['day'])) { + $strReq .= 'AND '.$this->con->dateFormat('post_dt','%d')." = '".sprintf('%02d',$params['day'])."' "; + } + + # Get next or previous date + if (!empty($params['next']) || !empty($params['previous'])) + { + if (!empty($params['next'])) { + $pdir = ' > '; + $params['order'] = 'asc'; + $dt = $params['next']; + } else { + $pdir = ' < '; + $params['order'] = 'desc'; + $dt = $params['previous']; + } + + $dt = date('YmdHis',strtotime($dt)); + + $strReq .= 'AND '.$this->con->dateFormat('post_dt',$dt_fc).$pdir."'".$dt."' "; + $limit = $this->con->limit(1); + } + + $strReq .= 'GROUP BY dt '.$cat_field; + + $order = 'desc'; + if (!empty($params['order']) && preg_match('/^(desc|asc)$/i',$params['order'])) { + $order = $params['order']; + } + + $strReq .= + 'ORDER BY dt '.$order.' '. + $limit; + + $rs = $this->con->select($strReq); + $rs->extend('rsExtDates'); + return $rs; + } + + /** + Creates a new entry. Takes a cursor as input and returns the new entry + ID. + + @param cur cursor Post cursor + @return integer New post ID + */ + public function addPost($cur) + { + if (!$this->core->auth->check('usage,contentadmin',$this->id)) { + throw new Exception(__('You are not allowed to create an entry')); + } + + $this->con->writeLock($this->prefix.'post'); + try + { + # Get ID + $rs = $this->con->select( + 'SELECT MAX(post_id) '. + 'FROM '.$this->prefix.'post ' + ); + + $cur->post_id = (integer) $rs->f(0) + 1; + $cur->blog_id = (string) $this->id; + $cur->post_creadt = date('Y-m-d H:i:s'); + $cur->post_upddt = date('Y-m-d H:i:s'); + $cur->post_tz = $this->core->auth->getInfo('user_tz'); + + # Post excerpt and content + $this->getPostContent($cur,$cur->post_id); + + $this->getPostCursor($cur); + + $cur->post_url = $this->getPostURL($cur->post_url,$cur->post_dt,$cur->post_title,$cur->post_id); + + if (!$this->core->auth->check('publish,contentadmin',$this->id)) { + $cur->post_status = -2; + } + + $cur->insert(); + $this->con->unlock(); + } + catch (Exception $e) + { + $this->con->unlock(); + throw $e; + } + + $this->triggerBlog(); + + return $cur->post_id; + } + + /** + Updates an existing post. + + @param id integer Post ID + @param cur cursor Post cursor + */ + public function updPost($id,&$cur) + { + if (!$this->core->auth->check('usage,contentadmin',$this->id)) { + throw new Exception(__('You are not allowed to update entries')); + } + + $id = (integer) $id; + + if (empty($id)) { + throw new Exception(__('No such entry ID')); + } + + # Post excerpt and content + $this->getPostContent($cur,$id); + + $this->getPostCursor($cur); + + if ($cur->post_url !== null) { + $cur->post_url = $this->getPostURL($cur->post_url,$cur->post_dt,$cur->post_title,$id); + } + + if (!$this->core->auth->check('publish,contentadmin',$this->id)) { + $cur->unsetField('post_status'); + } + + $cur->post_upddt = date('Y-m-d H:i:s'); + + #�If user is only "usage", we need to check the post's owner + if (!$this->core->auth->check('contentadmin',$this->id)) + { + $strReq = 'SELECT post_id '. + 'FROM '.$this->prefix.'post '. + 'WHERE post_id = '.$id.' '. + "AND user_id = '".$this->con->escape($this->core->auth->userID())."' "; + + $rs = $this->con->select($strReq); + + if ($rs->isEmpty()) { + throw new Exception(__('You are not allowed to edit this entry')); + } + } + + $cur->update('WHERE post_id = '.$id.' '); + $this->triggerBlog(); + } + + /** + Updates post status. + + @param id integer Post ID + @param status integer Post status + */ + public function updPostStatus($id,$status) + { + if (!$this->core->auth->check('publish,contentadmin',$this->id)) { + throw new Exception(__('You are not allowed to change this entry status')); + } + + $id = (integer) $id; + $status = (integer) $status; + + #If user can only publish, we need to check the post's owner + if (!$this->core->auth->check('contentadmin',$this->id)) + { + $strReq = 'SELECT post_id '. + 'FROM '.$this->prefix.'post '. + 'WHERE post_id = '.$id.' '. + "AND blog_id = '".$this->con->escape($this->id)."' ". + "AND user_id = '".$this->con->escape($this->core->auth->userID())."' "; + + $rs = $this->con->select($strReq); + + if ($rs->isEmpty()) { + throw new Exception(__('You are not allowed to change this entry status')); + } + } + + $cur = $this->con->openCursor($this->prefix.'post'); + + $cur->post_status = $status; + $cur->post_upddt = date('Y-m-d H:i:s'); + + $cur->update( + 'WHERE post_id = '.$id.' '. + "AND blog_id = '".$this->con->escape($this->id)."' " + ); + $this->triggerBlog(); + } + + public function updPostSelected($id,$selected) + { + if (!$this->core->auth->check('usage,contentadmin',$this->id)) { + throw new Exception(__('You are not allowed to change this entry category')); + } + + $id = (integer) $id; + $selected = (boolean) $selected; + + # If user is only usage, we need to check the post's owner + if (!$this->core->auth->check('contentadmin',$this->id)) + { + $strReq = 'SELECT post_id '. + 'FROM '.$this->prefix.'post '. + 'WHERE post_id = '.$id.' '. + "AND blog_id = '".$this->con->escape($this->id)."' ". + "AND user_id = '".$this->con->escape($this->core->auth->userID())."' "; + + $rs = $this->con->select($strReq); + + if ($rs->isEmpty()) { + throw new Exception(__('You are not allowed to mark this entry as selected')); + } + } + + $cur = $this->con->openCursor($this->prefix.'post'); + + $cur->post_selected = (integer) $selected; + $cur->post_upddt = date('Y-m-d H:i:s'); + + $cur->update( + 'WHERE post_id = '.$id.' '. + "AND blog_id = '".$this->con->escape($this->id)."' " + ); + $this->triggerBlog(); + } + + /** + Updates post category. $cat_id can be null. + + @param id integer Post ID + @param cat_id integer Category ID + */ + public function updPostCategory($id,$cat_id) + { + if (!$this->core->auth->check('usage,contentadmin',$this->id)) { + throw new Exception(__('You are not allowed to change this entry category')); + } + + $id = (integer) $id; + $cat_id = (integer) $cat_id; + + # If user is only usage, we need to check the post's owner + if (!$this->core->auth->check('contentadmin',$this->id)) + { + $strReq = 'SELECT post_id '. + 'FROM '.$this->prefix.'post '. + 'WHERE post_id = '.$id.' '. + "AND blog_id = '".$this->con->escape($this->id)."' ". + "AND user_id = '".$this->con->escape($this->core->auth->userID())."' "; + + $rs = $this->con->select($strReq); + + if ($rs->isEmpty()) { + throw new Exception(__('You are not allowed to change this entry category')); + } + } + + $cur = $this->con->openCursor($this->prefix.'post'); + + $cur->cat_id = ($cat_id ? $cat_id : null); + $cur->post_upddt = date('Y-m-d H:i:s'); + + $cur->update( + 'WHERE post_id = '.$id.' '. + "AND blog_id = '".$this->con->escape($this->id)."' " + ); + $this->triggerBlog(); + } + + /** + Deletes a post. + + @param id integer Post ID + */ + public function delPost($id) + { + if (!$this->core->auth->check('delete,contentadmin',$this->id)) { + throw new Exception(__('You are not allowed to delete entries')); + } + + $id = (integer) $id; + + if (empty($id)) { + throw new Exception(__('No such entry ID')); + } + + #If user can only delete, we need to check the post's owner + if (!$this->core->auth->check('contentadmin',$this->id)) + { + $strReq = 'SELECT post_id '. + 'FROM '.$this->prefix.'post '. + 'WHERE post_id = '.$id.' '. + "AND blog_id = '".$this->con->escape($this->id)."' ". + "AND user_id = '".$this->con->escape($this->core->auth->userID())."' "; + + $rs = $this->con->select($strReq); + + if ($rs->isEmpty()) { + throw new Exception(__('You are not allowed to delete this entry')); + } + } + + + $strReq = 'DELETE FROM '.$this->prefix.'post '. + 'WHERE post_id = '.$id.' '. + "AND blog_id = '".$this->con->escape($this->id)."' "; + + $this->con->execute($strReq); + $this->triggerBlog(); + } + + /** + Publishes all entries flaged as "scheduled". + */ + public function publishScheduledEntries() + { + $strReq = 'SELECT post_id, post_dt, post_tz '. + 'FROM '.$this->prefix.'post '. + 'WHERE post_status = -1 '. + "AND blog_id = '".$this->con->escape($this->id)."' "; + + $rs = $this->con->select($strReq); + + $now = dt::toUTC(time()); + $to_change = array(); + + if ($rs->isEmpty()) { + return; + } + + while ($rs->fetch()) + { + # Now timestamp with post timezone + $now_tz = $now + dt::getTimeOffset($rs->post_tz,$now); + + # Post timestamp + $post_ts = strtotime($rs->post_dt); + + # If now_tz >= post_ts, we publish the entry + if ($now_tz >= $post_ts) { + $to_change[] = (integer) $rs->post_id; + } + } + + if (!empty($to_change)) + { + $strReq = + 'UPDATE '.$this->prefix.'post SET '. + 'post_status = 1 '. + "WHERE blog_id = '".$this->con->escape($this->id)."' ". + 'AND post_id '.$this->con->in($to_change).' '; + + $this->con->execute($strReq); + $this->triggerBlog(); + } + } + + /** + Retrieves all users having posts on current blog. + + @param post_type string post_type filter (post) + @return record + */ + public function getPostsUsers($post_type='post') + { + $strReq = 'SELECT P.user_id, user_name, user_firstname, '. + 'user_displayname, user_email '. + 'FROM '.$this->prefix.'post P, '.$this->prefix.'user U '. + 'WHERE P.user_id = U.user_id '. + "AND blog_id = '".$this->con->escape($this->id)."' "; + + if ($post_type) { + $strReq .= "AND post_type = '".$this->con->escape($post_type)."' "; + } + + $strReq .= 'GROUP BY P.user_id, user_name, user_firstname, user_displayname, user_email '; + + return $this->con->select($strReq); + } + + private function getPostsCategoryFilter($arr,$field='cat_id') + { + $field = $field == 'cat_id' ? 'cat_id' : 'cat_url'; + + $sub = array(); + $not = array(); + $queries = array(); + + foreach ($arr as $v) + { + $v = trim($v); + $args = preg_split('/\s*[?]\s*/',$v,-1,PREG_SPLIT_NO_EMPTY); + $id = array_shift($args); + $args = array_flip($args); + + if (isset($args['not'])) { $not[$id] = 1; } + if (isset($args['sub'])) { $sub[$id] = 1; } + if ($field == 'cat_id') { + $queries[$id] = 'P.cat_id = '.(integer) $id; + } else { + $queries[$id] = "C.cat_url = '".$this->con->escape($id)."' "; + } + } + + if (!empty($sub)) { + $rs = $this->con->select( + 'SELECT cat_id, cat_url, cat_lft, cat_rgt FROM '.$this->prefix.'category '. + "WHERE blog_id = '".$this->con->escape($this->id)."' ". + 'AND '.$field.' '.$this->con->in(array_keys($sub)) + ); + + while ($rs->fetch()) { + $queries[$rs->f($field)] = '(C.cat_lft BETWEEN '.$rs->cat_lft.' AND '.$rs->cat_rgt.')'; + } + } + + # Create queries + $sql = array( + 0 => array(), # wanted categories + 1 => array() # excluded categories + ); + + foreach ($queries as $id => $q) { + $sql[(integer) isset($not[$id])][] = $q; + } + + $sql[0] = implode(' OR ',$sql[0]); + $sql[1] = implode(' OR ',$sql[1]); + + if ($sql[0]) { + $sql[0] = '('.$sql[0].')'; + } else { + unset($sql[0]); + } + + if ($sql[1]) { + $sql[1] = '(P.cat_id IS NULL OR NOT('.$sql[1].'))'; + } else { + unset($sql[1]); + } + + return implode(' AND ',$sql); + } + + private function getPostCursor(&$cur,$post_id=null) + { + if ($cur->post_title == '') { + throw new Exception(__('No entry title')); + } + + if ($cur->post_content == '') { + throw new Exception(__('No entry content')); + } + + if ($cur->post_password === '') { + $cur->post_password = null; + } + + if ($cur->post_dt == '') { + $offset = dt::getTimeOffset($this->core->auth->getInfo('user_tz')); + $now = time() + $offset; + $cur->post_dt = date('Y-m-d H:i:00',$now); + } + + $post_id = is_int($post_id) ? $post_id : $cur->post_id; + + if ($cur->post_content_xhtml == '') { + throw new Exception(__('No entry content')); + } + + # Words list + if ($cur->post_title !== null && $cur->post_excerpt_xhtml !== null + && $cur->post_content_xhtml !== null) + { + $words = + $cur->post_title.' '. + $cur->post_excerpt_xhtml.' '. + $cur->post_content_xhtml; + + $cur->post_words = implode(' ',text::splitWords($words)); + } + } + + private function getPostContent(&$cur,$post_id) + { + $post_excerpt = $cur->post_excerpt; + $post_excerpt_xhtml = $cur->post_excerpt_xhtml; + $post_content = $cur->post_content; + $post_content_xhtml = $cur->post_content_xhtml; + + $this->setPostContent( + $post_id,$cur->post_format,$cur->post_lang, + $post_excerpt,$post_excerpt_xhtml, + $post_content,$post_content_xhtml + ); + + $cur->post_excerpt = $post_excerpt; + $cur->post_excerpt_xhtml = $post_excerpt_xhtml; + $cur->post_content = $post_content; + $cur->post_content_xhtml = $post_content_xhtml; + } + + /** + Creates post HTML content, taking format and lang into account. + + @param post_id integer Post ID + @param format string Post format + @param lang string Post lang + @param excerpt string Post excerpt + @param[out] excerpt_xhtml string Post excerpt HTML + @param content string Post content + @param[out] content_xhtml string Post content HTML + */ + public function setPostContent($post_id,$format,$lang,&$excerpt,&$excerpt_xhtml,&$content,&$content_xhtml) + { + if ($format == 'wiki') + { + $this->core->initWikiPost(); + $this->core->wiki2xhtml->setOpt('note_prefix','pnote-'.$post_id); + if (strpos($lang,'fr') === 0) { + $this->core->wiki2xhtml->setOpt('active_fr_syntax',1); + } + } + + if ($excerpt) { + $excerpt_xhtml = $this->core->callFormater($format,$excerpt); + $excerpt_xhtml = $this->core->HTMLfilter($excerpt_xhtml); + } else { + $excerpt_xhtml = ''; + } + + if ($content) { + $content_xhtml = $this->core->callFormater($format,$content); + $content_xhtml = $this->core->HTMLfilter($content_xhtml); + } else { + $content_xhtml = ''; + } + + # --BEHAVIOR-- coreAfterPostContentFormat + $this->core->callBehavior('coreAfterPostContentFormat',array( + 'excerpt' => &$excerpt, + 'content' => &$content, + 'excerpt_xhtml' => &$excerpt_xhtml, + 'content_xhtml' => &$content_xhtml + )); + } + + /** + Returns URL for a post according to blog setting post_url_format. + It will try to guess URL and append some figures if needed. + + @param url string Origin URL, could be empty + @param post_dt string Post date (in YYYY-MM-DD HH:mm:ss) + @param post_title string Post title + @param post_id integer Post ID + @return string result URL + */ + public function getPostURL($url,$post_dt,$post_title,$post_id) + { + $url = trim($url); + + $url_patterns = array( + '{y}' => date('Y',strtotime($post_dt)), + '{m}' => date('m',strtotime($post_dt)), + '{d}' => date('d',strtotime($post_dt)), + '{t}' => text::tidyURL($post_title), + '{id}' => (integer) $post_id + ); + + # If URL is empty, we create a new one + if ($url == '') + { + # Transform with format + $url = str_replace( + array_keys($url_patterns), + array_values($url_patterns), + $this->settings->post_url_format + ); + } + else + { + $url = text::tidyURL($url); + } + + # Let's check if URL is taken... + $strReq = 'SELECT post_url FROM '.$this->prefix.'post '. + "WHERE post_url = '".$this->con->escape($url)."' ". + 'AND post_id <> '.(integer) $post_id. ' '. + "AND blog_id = '".$this->con->escape($this->id)."' ". + 'ORDER BY post_url DESC'; + + $rs = $this->con->select($strReq); + + if (!$rs->isEmpty()) + { + $strReq = 'SELECT post_url FROM '.$this->prefix.'post '. + "WHERE post_url LIKE '".$this->con->escape($url)."%' ". + 'AND post_id <> '.(integer) $post_id. ' '. + "AND blog_id = '".$this->con->escape($this->id)."' ". + 'ORDER BY post_url DESC '; + + $rs = $this->con->select($strReq); + $a = array(); + while ($rs->fetch()) { + $a[] = $rs->post_url; + } + + natsort($a); + $t_url = end($a); + + if (preg_match('/(.*?)([0-9]+)$/',$t_url,$m)) { + $i = (integer) $m[2]; + $url = $m[1]; + } else { + $i = 1; + } + + return $url.($i+1); + } + + # URL is empty? + if ($url == '') { + throw new Exception(__('Empty entry URL')); + } + + return $url; + } + //@} + + /// @name Comments management methods + //@{ + /** + Retrieves comments. $params is an array taking the following + optionnal parameters: + + - no_content: Don't retrieve comment content + - post_type: Get only entries with given type (default no type, array for many types) + - post_id: (integer) Get comments belonging to given post_id + - cat_id: (integer or array) Get comments belonging to entries of given category ID + - comment_id: (integer) Get comment with given ID + - comment_status: (integer) Get comments with given comment_status + - comment_trackback: (integer) Get only comments (0) or trackbacks (1) + - comment_ip: (string) Get comments with given IP address + - post_url: Get entry with given post_url field + - user_id: (integer) Get entries belonging to given user ID + - q_author: Search comments by author + - sql: Append SQL string at the end of the query + - from: Append SQL string after "FROM" statement in query + - order: Order of results (default "ORDER BY comment_dt DES") + - limit: Limit parameter + + @param params array Parameters + @param count_only boolean Only counts results + @return record A record with some more capabilities + */ + public function getComments($params=array(),$count_only=false) + { + if ($count_only) + { + $strReq = 'SELECT count(comment_id) '; + } + else + { + if (!empty($params['no_content'])) { + $content_req = ''; + } else { + $content_req = 'comment_content, '; + } + + $strReq = + 'SELECT C.comment_id, comment_dt, comment_tz, comment_upddt, '. + 'comment_author, comment_email, comment_site, '. + $content_req.' comment_trackback, comment_status, '. + 'comment_spam_status, comment_spam_filter, comment_ip, '. + 'P.post_title, P.post_url, P.post_id, P.post_password, P.post_type, '. + 'P.post_dt, P.user_id, U.user_email, U.user_url '; + } + + $strReq .= + 'FROM '.$this->prefix.'comment C '. + 'INNER JOIN '.$this->prefix.'post P ON C.post_id = P.post_id '. + 'INNER JOIN '.$this->prefix.'user U ON P.user_id = U.user_id '; + + if (!empty($params['from'])) { + $strReq .= $params['from'].' '; + } + + $strReq .= + "WHERE P.blog_id = '".$this->con->escape($this->id)."' "; + + if (!$this->core->auth->check('contentadmin',$this->id)) { + $strReq .= 'AND ((comment_status = 1 AND P.post_status = 1 '; + + if ($this->without_password) { + $strReq .= 'AND post_password IS NULL '; + } + $strReq .= ') '; + + if ($this->core->auth->userID()) { + $strReq .= "OR P.user_id = '".$this->con->escape($this->core->auth->userID())."')"; + } else { + $strReq .= ') '; + } + } + + if (!empty($params['post_type'])) + { + if (is_array($params['post_type']) && !empty($params['post_type'])) { + $strReq .= 'AND post_type '.$this->con->in($params['post_type']); + } else { + $strReq .= "AND post_type = '".$this->con->escape($params['post_type'])."' "; + } + } + + if (!empty($params['post_id'])) { + $strReq .= 'AND P.post_id = '.(integer) $params['post_id'].' '; + } + + if (!empty($params['cat_id'])) { + $strReq .= 'AND P.cat_id = '.(integer) $params['cat_id'].' '; + } + + if (!empty($params['comment_id'])) { + $strReq .= 'AND comment_id = '.(integer) $params['comment_id'].' '; + } + + if (isset($params['comment_status'])) { + $strReq .= 'AND comment_status = '.(integer) $params['comment_status'].' '; + } + + if (!empty($params['comment_status_not'])) + { + $strReq .= 'AND comment_status <> '.(integer) $params['comment_status_not'].' '; + } + + if (isset($params['comment_trackback'])) { + $strReq .= 'AND comment_trackback = '.(integer) (boolean) $params['comment_trackback'].' '; + } + + if (isset($params['comment_ip'])) { + $strReq .= "AND comment_ip = '".$this->con->escape($params['comment_ip'])."' "; + } + + if (isset($params['q_author'])) { + $q_author = $this->con->escape(str_replace('*','%',strtolower($params['q_author']))); + $strReq .= "AND LOWER(comment_author) LIKE '".$q_author."' "; + } + + if (!empty($params['search'])) + { + $words = text::splitWords($params['search']); + + if (!empty($words)) + { + # --BEHAVIOR coreCommentSearch + if ($this->core->hasBehavior('coreCommentSearch')) { + $this->core->callBehavior('coreCommentSearch',$this->core,array(&$words,&$strReq,&$params)); + } + + if ($words) + { + foreach ($words as $i => $w) { + $words[$i] = "comment_words LIKE '%".$this->con->escape($w)."%'"; + } + $strReq .= 'AND '.implode(' AND ',$words).' '; + } + } + } + + if (!empty($params['sql'])) { + $strReq .= $params['sql'].' '; + } + + if (!$count_only) + { + if (!empty($params['order'])) { + $strReq .= 'ORDER BY '.$this->con->escape($params['order']).' '; + } else { + $strReq .= 'ORDER BY comment_dt DESC '; + } + } + + if (!$count_only && !empty($params['limit'])) { + $strReq .= $this->con->limit($params['limit']); + } + + $rs = $this->con->select($strReq); + $rs->core = $this->core; + $rs->extend('rsExtComment'); + + # --BEHAVIOR-- coreBlogGetComments + $this->core->callBehavior('coreBlogGetComments',$rs); + + return $rs; + } + + /** + Creates a new comment. Takes a cursor as input and returns the new comment + ID. + + @param cur cursor Comment cursor + @return integer New comment ID + */ + public function addComment($cur) + { + $this->con->writeLock($this->prefix.'comment'); + try + { + # Get ID + $rs = $this->con->select( + 'SELECT MAX(comment_id) '. + 'FROM '.$this->prefix.'comment ' + ); + + $cur->comment_id = (integer) $rs->f(0) + 1; + $cur->comment_upddt = date('Y-m-d H:i:s'); + + $offset = dt::getTimeOffset($this->settings->blog_timezone); + $cur->comment_dt = date('Y-m-d H:i:s',time() + $offset); + $cur->comment_tz = $this->settings->blog_timezone; + + $this->getCommentCursor($cur); + + if ($cur->comment_ip === null) { + $cur->comment_ip = http::realIP(); + } + + # --BEHAVIOR-- coreBeforeCommentCreate + $this->core->callBehavior('coreBeforeCommentCreate',$this,$cur); + + $cur->insert(); + $this->con->unlock(); + } + catch (Exception $e) + { + $this->con->unlock(); + throw $e; + } + + # --BEHAVIOR-- coreAfterCommentCreate + $this->core->callBehavior('coreAfterCommentCreate',$this,$cur); + + $this->triggerComment($cur->comment_id); + if ($cur->comment_status != -2) { + $this->triggerBlog(); + } + return $cur->comment_id; + } + + /** + Updates an existing comment. + + @param id integer Comment ID + @param cur cursor Comment cursor + */ + public function updComment($id,&$cur) + { + if (!$this->core->auth->check('usage,contentadmin',$this->id)) { + throw new Exception(__('You are not allowed to update comments')); + } + + $id = (integer) $id; + + if (empty($id)) { + throw new Exception(__('No such comment ID')); + } + + $rs = $this->getComments(array('comment_id' => $id)); + + if ($rs->isEmpty()) { + throw new Exception(__('No such comment ID')); + } + + #If user is only usage, we need to check the post's owner + if (!$this->core->auth->check('contentadmin',$this->id)) + { + if ($rs->user_id != $this->core->auth->userID()) { + throw new Exception(__('You are not allowed to update this comment')); + } + } + + $this->getCommentCursor($cur); + + $cur->comment_upddt = date('Y-m-d H:i:s'); + + if (!$this->core->auth->check('publish,contentadmin',$this->id)) { + $cur->unsetField('comment_status'); + } + + # --BEHAVIOR-- coreBeforeCommentUpdate + $this->core->callBehavior('coreBeforeCommentUpdate',$this,$cur,$rs); + + $cur->update('WHERE comment_id = '.$id.' '); + + # --BEHAVIOR-- coreAfterCommentUpdate + $this->core->callBehavior('coreAfterCommentUpdate',$this,$cur,$rs); + + $this->triggerComment($id); + $this->triggerBlog(); + } + + /** + Updates comment status. + + @param id integer Comment ID + @param status integer Comment status + */ + public function updCommentStatus($id,$status) + { + if (!$this->core->auth->check('publish,contentadmin',$this->id)) { + throw new Exception(__("You are not allowed to change this comment's status")); + } + + $cur = $this->con->openCursor($this->prefix.'comment'); + $cur->comment_status = (integer) $status; + $this->updComment($id,$cur); + } + + /** + Delete a comment + + @param id integer Comment ID + */ + public function delComment($id) + { + if (!$this->core->auth->check('delete,contentadmin',$this->id)) { + throw new Exception(__('You are not allowed to delete comments')); + } + + $id = (integer) $id; + + if (empty($id)) { + throw new Exception(__('No such comment ID')); + } + + #If user can only delete, we need to check the post's owner + if (!$this->core->auth->check('contentadmin',$this->id)) + { + $strReq = 'SELECT P.post_id '. + 'FROM '.$this->prefix.'post P, '.$this->prefix.'comment C '. + 'WHERE P.post_id = C.post_id '. + "AND P.blog_id = '".$this->con->escape($this->id)."' ". + 'AND comment_id = '.$id.' '. + "AND user_id = '".$this->con->escape($this->core->auth->userID())."' "; + + $rs = $this->con->select($strReq); + + if ($rs->isEmpty()) { + throw new Exception(__('You are not allowed to delete this comment')); + } + } + + $strReq = 'DELETE FROM '.$this->prefix.'comment '. + 'WHERE comment_id = '.$id.' '; + + $this->triggerComment($id,true); + $this->con->execute($strReq); + $this->triggerBlog(); + } + + private function getCommentCursor(&$cur) + { + if ($cur->comment_content !== null && $cur->comment_content == '') { + throw new Exception(__('You must provide a comment')); + } + + if ($cur->comment_author !== null && $cur->comment_author == '') { + throw new Exception(__('You must provide an author name')); + } + + if ($cur->comment_email != '' && !text::isEmail($cur->comment_email)) { + throw new Exception(__('Email address is not valid.')); + } + + if ($cur->comment_site !== null && $cur->comment_site != '') { + if (!preg_match('|^http(s?)://|',$cur->comment_site)) { + $cur->comment_site = 'http://'.$cur->comment_site; + } + } + + if ($cur->comment_status === null) { + $cur->comment_status = (integer) $this->settings->comments_pub; + } + + # Words list + if ($cur->comment_content !== null) + { + $cur->comment_words = implode(' ',text::splitWords($cur->comment_content)); + } + } + //@} +} +?> diff --git a/inc/core/class.dc.categories.php b/inc/core/class.dc.categories.php new file mode 100644 index 0000000..9263da0 --- /dev/null +++ b/inc/core/class.dc.categories.php @@ -0,0 +1,483 @@ +core =& $core; + $this->con =& $core->con; + $this->blog_id = $core->blog->id; + $this->table = $core->prefix.'category'; + $this->add_condition = array('blog_id' => "'".$this->con->escape($this->blog_id)."'"); + } + + public function getChildren($start=0,$id=null,$sort='asc',$fields=array()) + { + $fields = array_merge(array('cat_title','cat_url','cat_desc'),$fields); + return parent::getChildren($start,$id,$sort,$fields); + } + + public function getParents($id,$fields=array()) + { + $fields = array_merge(array('cat_title','cat_url','cat_desc'),$fields); + return parent::getParents($id,$fields); + } + + public function getParent($id,$fields=array()) + { + $fields = array_merge(array('cat_title','cat_url','cat_desc'),$fields); + return parent::getParent($id,$fields); + } +} + +abstract class nestedTree +{ + protected $con; + + protected $table; + protected $f_left; + protected $f_right; + protected $f_id; + + protected $add_condition = array(); + + protected $parents; + + public function __construct(&$con) + { + $this->con =& $con; + } + + public function getChildren($start=0,$id=null,$sort='asc',$fields=array()) + { + $fields = count($fields) > 0 ? ', C2.'.implode(', C2.',$fields) : ''; + + $sql = 'SELECT C2.'.$this->f_id.', C2.'.$this->f_left.', C2.'.$this->f_right.', COUNT(C1.'.$this->f_id.') AS level ' + . $fields.' ' + . 'FROM '.$this->table.' AS C1, '.$this->table.' AS C2 %s ' + . 'WHERE C2.'.$this->f_left.' BETWEEN C1.'.$this->f_left.' AND C1.'.$this->f_right.' ' + . ' %s ' + . $this->getCondition('AND','C2.') + . $this->getCondition('AND','C1.') + . 'GROUP BY C2.'.$this->f_id.', C2.'.$this->f_left.', C2.'.$this->f_right.' '.$fields.' ' + . ' %s ' + . 'ORDER BY C2.'.$this->f_left.' '.($sort == 'asc' ? 'ASC' : 'DESC').' '; + + $from = $where = ''; + if ($start > 0) { + $from = ', '.$this->table.' AS C3'; + $where = 'AND C3.'.$this->f_id.' = '.(integer) $start.' AND C1.'.$this->f_left.' >= C3.'.$this->f_left.' AND C1.'.$this->f_right.' <= C3.'.$this->f_right; + $where .= $this->getCondition('AND','C3.'); + } + + $having = ''; + if ($id !== null) { + $having = ' HAVING C2.'.$this->f_id.' = '.(integer) $id; + } + + $sql = sprintf($sql,$from,$where,$having); + + return $this->con->select($sql); + } + + public function getParents($id,$fields=array()) + { + $fields = count($fields) > 0 ? ', C1.'.implode(', C1.',$fields) : ''; + + return $this->con->select( + 'SELECT C1.'.$this->f_id.' '.$fields.' ' + . 'FROM '.$this->table.' C1, '.$this->table.' C2 ' + . 'WHERE C2.'.$this->f_id.' = '.(integer) $id.' ' + . 'AND C1.'.$this->f_left.' < C2.'.$this->f_left.' ' + . 'AND C1.'.$this->f_right.' > C2.'.$this->f_right.' ' + . $this->getCondition('AND','C2.') + . $this->getCondition('AND','C1.') + . 'ORDER BY C1.'.$this->f_left.' ASC ' + ); + } + + public function getParent($id,$fields=array()) + { + $fields = count($fields) > 0 ? ', C1.'.implode(', C1.',$fields) : ''; + + return $this->con->select( + 'SELECT C1.'.$this->f_id.' '.$fields.' ' + . 'FROM '.$this->table.' C1, '.$this->table.' C2 ' + . 'WHERE C2.'.$this->f_id.' = '.(integer) $id.' ' + . 'AND C1.'.$this->f_left.' < C2.'.$this->f_left.' ' + . 'AND C1.'.$this->f_right.' > C2.'.$this->f_right.' ' + . $this->getCondition('AND','C2.') + . $this->getCondition('AND','C1.') + . 'ORDER BY C1.'.$this->f_left.' DESC ' + . $this->con->limit(1) + ); + } + + /* ------------------------------------------------ + * Tree manipulations + * ---------------------------------------------- */ + public function addNode($data,$target=0) + { + if (!is_array($data) && !($data instanceof cursor)) { + throw new Exception('Invalid data block'); + } + + if (is_array($data)) + { + $D = $data; + $data = $this->con->openCursor($this->table); + foreach ($D as $k => $v) { + $data->{$k} = $v; + } + unset($D); + } + + # We want to put it at the end + $this->con->writeLock($this->table); + try + { + $rs = $this->con->select('SELECT MAX('.$this->f_id.') as n_id FROM '.$this->table); + $id = $rs->n_id; + + $rs = $this->con->select( + 'SELECT MAX('.$this->f_right.') as n_r '. + 'FROM '.$this->table. + $this->getCondition('WHERE') + ); + $last = $rs->n_r == 0 ? 1 : $rs->n_r; + + $data->{$this->f_id} = $id+1; + $data->{$this->f_left} = $last+1; + $data->{$this->f_right} = $last+2; + + $data->insert(); + $this->con->unlock(); + try { + $this->setNodeParent($id+1,$target); + return $data->{$this->f_id}; + } catch (Exception $e) {} # We don't mind error in this case + } + catch (Exception $e) + { + $this->con->unlock(); + throw $e; + } + } + + public function deleteNode($node,$keep_children=true) + { + $node = (integer) $node; + + $rs = $this->getChildren(0,$node); + if ($rs->isEmpty()) { + throw new Exception('Node does not exist.'); + } + $node_left = (integer) $rs->{$this->f_left}; + $node_right = (integer) $rs->{$this->f_right}; + + try + { + $this->con->begin(); + + if ($keep_children) + { + $this->con->execute('DELETE FROM '.$this->table.' WHERE '.$this->f_id.' = '.$node); + + $sql = 'UPDATE '.$this->table.' SET ' + . $this->f_right.' = CASE ' + . 'WHEN '.$this->f_right.' BETWEEN '.$node_left.' AND '.$node_right.' ' + . 'THEN '.$this->f_right.' - 1 ' + . 'WHEN '.$this->f_right.' > '.$node_right.' ' + . 'THEN '.$this->f_right.' - 2 ' + . 'ELSE '.$this->f_right.' ' + . 'END, ' + . $this->f_left.' = CASE ' + . 'WHEN '.$this->f_left.' BETWEEN '.$node_left.' AND '.$node_right.' ' + . 'THEN '.$this->f_left.' - 1 ' + . 'WHEN '.$this->f_left.' > '.$node_right.' ' + . 'THEN '.$this->f_left.' - 2 ' + . 'ELSE '.$this->f_left.' ' + . 'END ' + . 'WHERE '.$this->f_right.' > '.$node_left + . $this->getCondition(); + + $this->con->execute($sql); + } + else + { + $this->con->execute('DELETE FROM '.$this->table.' WHERE '.$this->f_left.' BETWEEN '.$node_left.' AND '.$node_right); + + $node_delta = $node_right - $node_left + 1; + $sql = 'UPDATE '.$this->table.' SET ' + . $this->f_left.' = CASE ' + . 'WHEN '.$this->f_left.' > '.$node_left.' ' + . 'THEN '.$this->f_left.' - ('.$node_delta.') ' + . 'ELSE '.$this->f_left.' ' + . 'END, ' + . $this->f_right.' = CASE ' + . 'WHEN '.$this->f_right.' > '.$node_left.' ' + . 'THEN '.$this->f_right.' - ('.$node_delta.') ' + . 'ELSE '.$this->f_right.' ' + . 'END ' + . 'WHERE '.$this->f_right.' > '.$node_right + . $this->getCondition(); + } + + $this->con->commit(); + } + catch (Exception $e) + { + $this->con->rollback(); + throw $e; + } + } + + public function resetOrder() + { + $rs = $this->con->select( + 'SELECT '.$this->f_id.' ' + .'FROM '.$this->table.' ' + .$this->getCondition('WHERE') + .'ORDER BY '.$this->f_left.' ASC ' + ); + + $lft = 2; + $this->con->begin(); + try + { + while ($rs->fetch()) { + $this->con->execute( + 'UPDATE '.$this->table.' SET ' + .$this->f_left.' = '.($lft++).', ' + .$this->f_right.' = '.($lft++).' ' + .'WHERE '.$this->f_id .' = '.(integer) $rs->{$this->f_id}.' ' + .$this->getCondition() + ); + } + $this->con->commit(); + } + catch (Exception $e) + { + $this->con->rollback(); + throw $e; + } + } + + public function setNodeParent($node,$target=0) + { + if ($node == $target) { + return; + } + $node = (integer) $node; + $target = (integer) $target; + + $rs = $this->getChildren(0,$node); + if ($rs->isEmpty()) { + throw new Exception('Node does not exist.'); + } + $node_left = (integer) $rs->{$this->f_left}; + $node_right = (integer) $rs->{$this->f_right}; + $node_level = (integer) $rs->level; + + if ($target > 0) + { + $rs = $this->getChildren(0,$target); + } + else + { + $rs = $this->con->select( + 'SELECT MIN('.$this->f_left.')-1 AS '.$this->f_left.', MAX('.$this->f_right.')+1 AS '.$this->f_right.', 0 AS level '. + 'FROM '.$this->table.' '. + $this->getCondition('WHERE') + ); + } + $target_left = (integer) $rs->{$this->f_left}; + $target_right = (integer) $rs->{$this->f_right}; + $target_level = (integer) $rs->level; + + if ($node_left == $target_left + || ($target_left >= $node_left && $target_left <= $node_right) + || ($node_level == $target_level+1 && $node_left > $target_left && $node_right < $target_right) + ) + { + throw new Exception('Cannot move tree'); + } + + if ($target_left < $node_left && $target_right > $node_right && $target_level < $node_level -1) + { + $sql = 'UPDATE '.$this->table.' SET ' + . $this->f_right.' = CASE ' + . 'WHEN '.$this->f_right.' BETWEEN '.($node_right+1).' AND '.($target_right-1).' ' + . 'THEN '.$this->f_right.'-('.($node_right-$node_left+1).') ' + . 'WHEN '.$this->f_left.' BETWEEN '.$node_left.' AND '.$node_right.' ' + . 'THEN '.$this->f_right.'+'.((($target_right-$node_right-$node_level+$target_level)/2)*2+$node_level-$target_level-1).' ' + . 'ELSE ' + . $this->f_right.' ' + . 'END, ' + . $this->f_left.' = CASE ' + . 'WHEN '.$this->f_left.' BETWEEN '.($node_right+1).' AND '.($target_right-1).' ' + . 'THEN '.$this->f_left.'-('.($node_right-$node_left+1).') ' + . 'WHEN '.$this->f_left.' BETWEEN '.$node_left.' AND '.$node_right.' ' + . 'THEN '.$this->f_left.'+'.((($target_right-$node_right-$node_level+$target_level)/2)*2+$node_level-$target_level-1).' ' + . 'ELSE '.$this->f_left.' ' + . 'END ' + . 'WHERE '.$this->f_left.' BETWEEN '.($target_left+1).' AND '.($target_right-1).''; + } + elseif ($target_left < $node_left) + { + $sql = 'UPDATE '.$this->table.' SET ' + . $this->f_left.' = CASE ' + . 'WHEN '.$this->f_left.' BETWEEN '.$target_right.' AND '.($node_left-1).' ' + . 'THEN '.$this->f_left.'+'.($node_right-$node_left+1).' ' + . 'WHEN '.$this->f_left.' BETWEEN '.$node_left.' AND '.$node_right.' ' + . 'THEN '.$this->f_left.'-('.($node_left-$target_right).') ' + . 'ELSE '.$this->f_left .' ' + . 'END, ' + . $this->f_right.' = CASE ' + . 'WHEN '.$this->f_right.' BETWEEN '.$target_right.' AND '.$node_left.' ' + . 'THEN '.$this->f_right.'+'.($node_right-$node_left+1).' ' + . 'WHEN '.$this->f_right.' BETWEEN '.$node_left.' AND '.$node_right.' ' + . 'THEN '.$this->f_right.'-('.($node_left-$target_right).') ' + . 'ELSE '.$this->f_right.' ' + . 'END ' + . 'WHERE ('.$this->f_left.' BETWEEN '.$target_left.' AND '.$node_right. ' ' + . 'OR '.$this->f_right.' BETWEEN '.$target_left.' AND '.$node_right.')'; + } + else + { + $sql = 'UPDATE '.$this->table.' SET ' + . $this->f_left.' = CASE ' + . 'WHEN '.$this->f_left.' BETWEEN '.$node_right.' AND '.$target_right.' ' + . 'THEN '.$this->f_left.'-'.($node_right-$node_left+1).' ' + . 'WHEN '.$this->f_left.' BETWEEN '.$node_left.' AND '.$node_right.' ' + . 'THEN '.$this->f_left.'+'.($target_right-1-$node_right).' ' + . 'ELSE '.$this->f_left.' ' + . 'END, ' + . $this->f_right.' = CASE ' + . 'WHEN '.$this->f_right.' BETWEEN '.($node_right+1).' AND '.($target_right-1).' ' + . 'THEN '.$this->f_right.'-'.($node_right-$node_left+1).' ' + . 'WHEN '.$this->f_right.' BETWEEN '.$node_left.' AND '.$node_right.' ' + . 'THEN '.$this->f_right.'+'.($target_right-1-$node_right).' ' + . 'ELSE '.$this->f_right.' ' + . 'END ' + . 'WHERE ('.$this->f_left.' BETWEEN '.$node_left.' AND '.$target_right.' ' + . 'OR '.$this->f_right.' BETWEEN '.$node_left.' AND '.$target_right.')'; + } + + $sql .= ' '.$this->getCondition(); + + $this->con->execute($sql); + } + + public function setNodePosition($nodeA,$nodeB,$position='after') + { + $nodeA = (integer) $nodeA; + $nodeB = (integer) $nodeB; + + $rs = $this->getChildren(0,$nodeA); + if ($rs->isEmpty()) { + throw new Exception('Node does not exist.'); + } + $A_left = $rs->{$this->f_left}; + $A_right = $rs->{$this->f_right}; + $A_level = $rs->level; + + $rs = $this->getChildren(0,$nodeB); + if ($rs->isEmpty()) { + throw new Exception('Node does not exist.'); + } + $B_left = $rs->{$this->f_left}; + $B_right = $rs->{$this->f_right}; + $B_level = $rs->level; + + if ($A_level != $B_level) { + throw new Exception('Cannot change position'); + } + + $rs = $this->getParents($nodeA); + $parentA = $rs->isEmpty() ? 0 : $rs->{$this->f_id}; + $rs = $this->getParents($nodeB); + $parentB = $rs->isEmpty() ? 0 : $rs->{$this->f_id}; + + if ($parentA != $parentB) { + throw new Exception('Cannot change position'); + } + + if ($position == 'before') + { + if ($A_left > $B_left) { + $sql = 'UPDATE '.$this->table.' SET ' + . $this->f_right.' = CASE WHEN '.$this->f_left.' BETWEEN '.$A_left.' AND '.$A_right.' THEN '.$this->f_right.' - ('.($A_left - $B_left).') ' + . 'WHEN '.$this->f_left.' BETWEEN '.$B_left.' AND '.($A_left - 1).' THEN '.$this->f_right.' + '.($A_right - $A_left + 1).' ELSE '.$this->f_right.' END, ' + . $this->f_left.' = CASE WHEN '.$this->f_left.' BETWEEN '.$A_left.' AND '.$A_right.' THEN '.$this->f_left.' - ('.($A_left - $B_left).') ' + . 'WHEN '.$this->f_left.' BETWEEN '.$B_left.' AND '.($A_left - 1).' THEN '.$this->f_left.' + '.($A_right - $A_left + 1).' ELSE '.$this->f_left.' END ' + . 'WHERE '.$this->f_left.' BETWEEN '.$B_left.' AND '.$A_right; + } else { + $sql = 'UPDATE '.$this->table.' SET ' + . $this->f_right.' = CASE WHEN '.$this->f_left.' BETWEEN '.$A_left.' AND '.$A_right.' THEN '.$this->f_right.' + '.(($B_left - $A_left) - ($A_right - $A_left + 1)).' ' + . 'WHEN '.$this->f_left.' BETWEEN '.($A_right + 1).' AND '.($B_left - 1).' THEN '.$this->f_right.' - ('.(($A_right - $A_left + 1)).') ELSE '.$this->f_right.' END, ' + . $this->f_left.' = CASE WHEN '.$this->f_left.' BETWEEN '.$A_left.' AND '.$A_right.' THEN '.$this->f_left.' + '.(($B_left - $A_left) - ($A_right - $A_left + 1)).' ' + . 'WHEN '.$this->f_left.' BETWEEN '.($A_right + 1).' AND '.($B_left - 1).' THEN '.$this->f_left.' - ('.($A_right - $A_left + 1).') ELSE '.$this->f_left.' END ' + . 'WHERE '.$this->f_left.' BETWEEN '.$A_left.' AND '.($B_left - 1); + } + } + else + { + if ($A_left > $B_left) { + $sql = 'UPDATE '.$this->table.' SET ' + . $this->f_right.' = CASE WHEN '.$this->f_left.' BETWEEN '.$A_left.' AND '.$A_right.' THEN '.$this->f_right.' - ('.($A_left - $B_left - ($B_right - $B_left + 1)).') ' + . 'WHEN '.$this->f_left.' BETWEEN '.($B_right + 1).' AND '.($A_left - 1).' THEN '.$this->f_right.' + '.($A_right - $A_left + 1).' ELSE '.$this->f_right.' END, ' + . $this->f_left.' = CASE WHEN '.$this->f_left.' BETWEEN '.$A_left.' AND '.$A_right.' THEN '.$this->f_left.' - ('.($A_left - $B_left - ($B_right - $B_left + 1)).') ' + . 'WHEN '.$this->f_left.' BETWEEN '.($B_right + 1).' AND '.($A_left - 1).' THEN '.$this->f_left.' + '.($A_right - $A_left + 1).' ELSE '.$this->f_left.' END ' + . 'WHERE '.$this->f_left.' BETWEEN '.($B_right + 1).' AND '.$A_right; + } else { + $sql = 'UPDATE '.$this->table.' SET ' + . $this->f_right.' = CASE WHEN '.$this->f_left.' BETWEEN '.$A_left.' AND '.$A_right.' THEN '.$this->f_right.' + '.($B_right - $A_right).' ' + . 'WHEN '.$this->f_left.' BETWEEN '.($A_right + 1).' AND '.$B_right.' THEN '.$this->f_right.' - ('.(($A_right - $A_left + 1)).') ELSE '.$this->f_right.' END, ' + . $this->f_left.' = CASE WHEN '.$this->f_left.' BETWEEN '.$A_left.' AND '.$A_right.' THEN '.$this->f_left.' + '.($B_right - $A_right).' ' + . 'WHEN '.$this->f_left.' BETWEEN '.($A_right + 1).' AND '.$B_right.' THEN '.$this->f_left.' - ('.($A_right - $A_left + 1).') ELSE '.$this->f_left.' END ' + . 'WHERE '.$this->f_left.' BETWEEN '.$A_left.' AND '.$B_right; + } + } + + $sql .= $this->getCondition(); + $this->con->execute($sql); + } + + protected function getCondition($start='AND',$prefix='') + { + if (empty($this->add_condition)) { + return ''; + } + + $w = array(); + foreach ($this->add_condition as $c => $n) { + $w[] = $prefix.$c.' = '.$n; + } + return ' '.$start.' '.implode(' AND ',$w).' '; + } +} +?> \ No newline at end of file diff --git a/inc/core/class.dc.core.php b/inc/core/class.dc.core.php new file mode 100644 index 0000000..778b3cd --- /dev/null +++ b/inc/core/class.dc.core.php @@ -0,0 +1,1461 @@ +connection Database connection object + public $prefix; ///< string Database tables prefix + public $blog; ///< dcBlog dcBlog object + public $error; ///< dcError dcError object + public $auth; ///< dcAuth dcAuth object + public $session; ///< sessionDB sessionDB object + public $url; ///< urlHandler urlHandler object + public $wiki2xhtml; ///< wiki2xhtml wiki2xhtml object + public $plugins; ///< dcModules dcModules object + public $media; ///< dcMedia dcMedia object + public $rest; ///< dcRestServer dcRestServer object + + private $versions = null; + private $formaters = array(); + private $behaviors = array(); + private $post_types = array(); + + /** + dcCore constructor inits everything related to Dotclear. It takes arguments + to init database connection. + + @param driver string Database driver name + @param host string Database hostname + @param db string Database name + @param user string Database username + @param password string Database password + @param prefix string DotClear tables prefix + @param persist boolean Persistent database connection + */ + public function __construct($driver, $host, $db, $user, $password, $prefix, $persist) + { + $this->con = dbLayer::init($driver,$host,$db,$user,$password,$persist); + + # define weak_locks for mysql + if ($this->con instanceof mysqlConnection) { + mysqlConnection::$weak_locks = true; + } + + $this->prefix = $prefix; + + $this->error = new dcError(); + $this->auth = $this->authInstance(); + $this->session = new sessionDB($this->con,$this->prefix.'session',DC_SESSION_NAME,'',null,DC_ADMIN_SSL); + $this->url = new urlHandler(); + + $this->plugins = new dcModules($this); + + $this->rest = new dcRestServer($this); + + $this->addFormater('xhtml', create_function('$s','return $s;')); + $this->addFormater('wiki', array($this,'wikiTransform')); + } + + private function authInstance() + { + # You can set DC_AUTH_CLASS to whatever you want. + # Your new class *should* inherits dcAuth. + if (!defined('DC_AUTH_CLASS')) { + $c = 'dcAuth'; + } else { + $c = DC_AUTH_CLASS; + } + + if (!class_exists($c)) { + throw new Exception('Authentication class '.$c.' does not exist.'); + } + + if ($c != 'dcAuth') + { + $r = new ReflectionClass($c); + $p = $r->getParentClass(); + + if (!$p || $p->name != 'dcAuth') { + throw new Exception('Authentication class '.$c.' does not inherit dcAuth.'); + } + } + + return new $c($this); + } + + + /// @name Blog init methods + //@{ + /** + Sets a blog to use in blog property. + + @param id string Blog ID + */ + public function setBlog($id) + { + $this->blog = new dcBlog($this, $id); + } + + /** + Unsets blog property. + */ + public function unsetBlog() + { + $this->blog = null; + } + //@} + + + /// @name Blog status methods + //@{ + /** + Returns an array of available blog status codes and names. + + @return array Simple array with codes in keys and names in value + */ + public function getAllBlogStatus() + { + return array( + 1 => __('online'), + 0 => __('offline'), + -1 => __('removed') + ); + } + + /** + Returns a blog status name given to a code. This is intended to be + human-readable and will be translated, so never use it for tests. + If status code does not exist, returns offline. + + @param s integer Status code + @return string Blog status name + */ + public function getBlogStatus($s) + { + $r = $this->getAllBlogStatus(); + if (isset($r[$s])) { + return $r[$s]; + } + return $r[0]; + } + //@} + + /// @name Admin nonce secret methods + //@{ + + public function getNonce() + { + return crypt::hmac(DC_MASTER_KEY,session_id()); + } + + public function checkNonce($secret) + { + if (!preg_match('/^([0-9a-f]{40,})$/i',$secret)) { + return false; + } + + return $secret == crypt::hmac(DC_MASTER_KEY,session_id()); + } + + public function formNonce() + { + if (!session_id()) { + return; + } + + return form::hidden(array('xd_check'),$this->getNonce()); + } + //@} + + + /// @name Text Formatters methods + //@{ + /** + Adds a new text formater which will call the function $func to + transform text. The function must be a valid callback and takes one + argument: the string to transform. It returns the transformed string. + + @param name string Formater name + @param func callback Function to use, must be a valid and callable callback + */ + public function addFormater($name,$func) + { + if (is_callable($func)) { + $this->formaters[$name] = $func; + } + } + + /** + Returns formaters list. + + @return array An array of formaters names in values. + */ + public function getFormaters() + { + return array_keys($this->formaters); + } + + /** + If $name is a valid formater, it returns $str + transformed using that formater. + + @param name string Formater name + @param str string String to transform + @return string String transformed + */ + public function callFormater($name,$str) + { + if (isset($this->formaters[$name])) { + return call_user_func($this->formaters[$name],$str); + } + + return $str; + } + //@} + + + /// @name Behaviors methods + //@{ + /** + Adds a new behavior to behaviors stack. $func must be a valid + and callable callback. + + @param behavior string Behavior name + @param func callback Function to call + */ + public function addBehavior($behavior,$func) + { + if (is_callable($func)) { + $this->behaviors[$behavior][] = $func; + } + } + + /** + Tests if a particular behavior exists in behaviors stack. + + @param behavior string Behavior name + @return boolean + */ + public function hasBehavior($behavior) + { + return isset($this->behaviors[$behavior]); + } + + /** + Get behaviors stack (or part of). + + @param behavior string Behavior name + @return array + */ + public function getBehaviors($behavior='') + { + if (empty($this->behaviors)) return null; + + if ($behavior == '') { + return $this->behaviors; + } elseif (isset($this->behaviors[$behavior])) { + return $this->behaviors[$behavior]; + } + + return array(); + } + + /** + Calls every function in behaviors stack for a given behavior and returns + concatened result of each function. + + Every parameters added after $behavior will be pass to + behavior calls. + + @param behavior string Behavior name + @return string Behavior concatened result + */ + public function callBehavior($behavior) + { + if (isset($this->behaviors[$behavior])) + { + $args = func_get_args(); + array_shift($args); + + $res = ''; + + foreach ($this->behaviors[$behavior] as $f) { + $res .= call_user_func_array($f,$args); + } + + return $res; + } + } + //@} + + /// @name Post types URLs management + //@{ + public function getPostAdminURL($type,$post_id,$escaped=true) + { + if (!isset($this->post_types[$type])) { + $type = 'post'; + } + + $url = sprintf($this->post_types[$type]['admin_url'],$post_id); + return $escaped ? html::escapeURL($url) : $url; + } + + public function getPostPublicURL($type,$post_url,$escaped=true) + { + if (!isset($this->post_types[$type])) { + $type = 'post'; + } + + $url = sprintf($this->post_types[$type]['public_url'],$post_url); + return $escaped ? html::escapeURL($url) : $url; + } + + public function setPostType($type,$admin_url,$public_url) + { + $this->post_types[$type] = array( + 'admin_url' => $admin_url, + 'public_url' => $public_url + ); + } + + public function getPostTypes() + { + return $this->post_types; + } + //@} + + /// @name Versions management methods + //@{ + /** + Returns a given $module version. + + @param module string Module name + @return string Module version + */ + public function getVersion($module='core') + { + # Fetch versions if needed + if (!is_array($this->versions)) + { + $strReq = 'SELECT module, version FROM '.$this->prefix.'version'; + $rs = $this->con->select($strReq); + + while ($rs->fetch()) { + $this->versions[$rs->module] = $rs->version; + } + } + + if (isset($this->versions[$module])) { + return $this->versions[$module]; + } else { + return null; + } + } + + /** + Sets $version to given $module. + + @param module string Module name + @param version string Module version + */ + public function setVersion($module,$version) + { + $cur_version = $this->getVersion($module); + + $cur = $this->con->openCursor($this->prefix.'version'); + $cur->module = (string) $module; + $cur->version = (string) $version; + + if ($cur_version === null) { + $cur->insert(); + } else { + $cur->update("WHERE module='".$this->con->escape($module)."'"); + } + + $this->versions[$module] = $version; + } + + /** + Removes given $module version entry. + + @param module string Module name + */ + public function delVersion($module) + { + $strReq = + 'DELETE FROM '.$this->prefix.'version '. + "WHERE module = '".$this->con->escape($module)."' "; + + $this->con->execute($strReq); + + if (is_array($this->versions)) { + unset($this->versions[$module]); + } + } + + //@} + + /// @name Users management methods + //@{ + /** + Returns a user by its ID. + + @param id string User ID + @return record + */ + public function getUser($id) + { + $params['user_id'] = $id; + + return $this->getUsers($params); + } + + /** + Returns a users list. $params is an array with the following + optionnal parameters: + + - q: search string (on user_id, user_name, user_firstname) + - user_id: user ID + - order: ORDER BY clause (default: user_id ASC) + - limit: LIMIT clause (should be an array ![limit,offset]) + + @param params array Parameters + @param count_only boolean Only counts results + @return record + */ + public function getUsers($params=array(),$count_only=false) + { + if ($count_only) + { + $strReq = + 'SELECT count(U.user_id) '. + 'FROM '.$this->prefix.'user U '. + 'WHERE NULL IS NULL '; + } + else + { + $strReq = + 'SELECT U.user_id,user_super,user_status,user_pwd,user_name,'. + 'user_firstname,user_displayname,user_email,user_url,'. + 'user_desc, user_lang,user_tz, user_post_status,user_options, '. + 'count(P.post_id) AS nb_post '. + 'FROM '.$this->prefix.'user U '. + 'LEFT JOIN '.$this->prefix.'post P ON U.user_id = P.user_id '. + 'WHERE NULL IS NULL '; + } + + if (!empty($params['q'])) { + $q = $this->con->escape(str_replace('*','%',strtolower($params['q']))); + $strReq .= 'AND ('. + "LOWER(U.user_id) LIKE '".$q."' ". + "OR LOWER(user_name) LIKE '".$q."' ". + "OR LOWER(user_firstname) LIKE '".$q."' ". + ') '; + } + + if (!empty($params['user_id'])) { + $strReq .= "AND U.user_id = '".$this->con->escape($params['user_id'])."' "; + } + + if (!$count_only) { + $strReq .= 'GROUP BY U.user_id,user_super,user_status,user_pwd,user_name,'. + 'user_firstname,user_displayname,user_email,user_url,'. + 'user_desc, user_lang,user_tz,user_post_status,user_options '; + + if (!empty($params['order']) && !$count_only) { + $strReq .= 'ORDER BY '.$this->con->escape($params['order']).' '; + } else { + $strReq .= 'ORDER BY U.user_id ASC '; + } + } + + if (!$count_only && !empty($params['limit'])) { + $strReq .= $this->con->limit($params['limit']); + } + + $rs = $this->con->select($strReq); + $rs->extend('rsExtUser'); + return $rs; + } + + /** + Create a new user. Takes a cursor as input and returns the new user ID. + + @param cur cursor User cursor + @return string + */ + public function addUser(&$cur) + { + if (!$this->auth->isSuperAdmin()) { + throw new Exception(__('You are not an administrator')); + } + + if ($cur->user_id == '') { + throw new Exception(__('No user ID given')); + } + + if ($cur->user_pwd == '') { + throw new Exception(__('No password given')); + } + + $this->getUserCursor($cur); + + if ($cur->user_creadt === null) { + $cur->user_creadt = array('NOW()'); + } + + $cur->insert(); + + $this->auth->afterAddUser($cur); + + return $cur->user_id; + } + + /** + Updates an existing user. Returns the user ID. + + @param id string User ID + @param cur cursor User cursor + @return string + */ + public function updUser($id,&$cur) + { + $this->getUserCursor($cur); + + if (($cur->user_id !== null || $id != $this->auth->userID()) && + !$this->auth->isSuperAdmin()) { + throw new Exception(__('You are not an administrator')); + } + + $cur->update("WHERE user_id = '".$this->con->escape($id)."' "); + + $this->auth->afterUpdUser($id,$cur); + + if ($cur->user_id !== null) { + $id = $cur->user_id; + } + + # Updating all user's blogs + $rs = $this->con->select( + 'SELECT DISTINCT(blog_id) FROM '.$this->prefix.'post '. + "WHERE user_id = '".$this->con->escape($id)."' " + ); + + while ($rs->fetch()) { + $b = new dcBlog($this,$rs->blog_id); + $b->triggerBlog(); + unset($b); + } + + return $id; + } + + /** + Deletes a user. + + @param id string User ID + */ + public function delUser($id) + { + if (!$this->auth->isSuperAdmin()) { + throw new Exception(__('You are not an administrator')); + } + + if ($id == $this->auth->userID()) { + return; + } + + $rs = $this->getUser($id); + + if ($rs->nb_post > 0) { + return; + } + + $strReq = 'DELETE FROM '.$this->prefix.'user '. + "WHERE user_id = '".$this->con->escape($id)."' "; + + $this->con->execute($strReq); + + $this->auth->afterDelUser($id); + } + + /** + Checks whether a user exists. + + @param id string User ID + @return boolean + */ + public function userExists($id) + { + $strReq = 'SELECT user_id '. + 'FROM '.$this->prefix.'user '. + "WHERE user_id = '".$this->con->escape($id)."' "; + + $rs = $this->con->select($strReq); + + return !$rs->isEmpty(); + } + + /** + Returns all user permissions as an array which looks like: + + - [blog_id] + - [name] => Blog name + - [url] => Blog URL + - [p] + - [permission] => true + - ... + + @param id string User ID + @return array + */ + public function getUserPermissions($id) + { + $strReq = 'SELECT B.blog_id, blog_name, blog_url, permissions '. + 'FROM '.$this->prefix.'permissions P '. + 'INNER JOIN '.$this->prefix.'blog B ON P.blog_id = B.blog_id '. + "WHERE user_id = '".$this->con->escape($id)."' "; + + $rs = $this->con->select($strReq); + + $res = array(); + + while ($rs->fetch()) + { + $res[$rs->blog_id] = array( + 'name' => $rs->blog_name, + 'url' => $rs->blog_url, + 'p' => $this->auth->parsePermissions($rs->permissions) + ); + } + + return $res; + } + + /** + Sets user permissions. The $perms array looks like: + + - [blog_id] => '|perm1|perm2|' + - ... + + @param id string User ID + @param perms array Permissions array + */ + public function setUserPermissions($id,$perms) + { + if (!$this->auth->isSuperAdmin()) { + throw new Exception(__('You are not an administrator')); + } + + $strReq = 'DELETE FROM '.$this->prefix.'permissions '. + "WHERE user_id = '".$this->con->escape($id)."' "; + + $this->con->execute($strReq); + + foreach ($perms as $blog_id => $p) { + $this->setUserBlogPermissions($id, $blog_id, $p, false); + } + } + + /** + Sets user permissions for a given blog. $perms is an array with + permissions in values + + @param id string User ID + @param blog_id string Blog ID + @param perms array Permissions + @param delete_first boolean Delete permissions before + */ + public function setUserBlogPermissions($id, $blog_id, $perms, $delete_first=true) + { + if (!$this->auth->isSuperAdmin()) { + throw new Exception(__('You are not an administrator')); + } + + $no_perm = empty($perms); + + $perms = '|'.implode('|',array_keys($perms)).'|'; + + $cur = $this->con->openCursor($this->prefix.'permissions'); + + $cur->user_id = (string) $id; + $cur->blog_id = (string) $blog_id; + $cur->permissions = $perms; + + if ($delete_first || $no_perm) + { + $strReq = 'DELETE FROM '.$this->prefix.'permissions '. + "WHERE blog_id = '".$this->con->escape($blog_id)."' ". + "AND user_id = '".$this->con->escape($id)."' "; + + $this->con->execute($strReq); + } + + if (!$no_perm) { + $cur->insert(); + } + } + + /** + Sets a user default blog. This blog will be selected when user log in. + + @param id string User ID + @param blog_id string Blog ID + */ + public function setUserDefaultBlog($id, $blog_id) + { + $cur = $this->con->openCursor($this->prefix.'user'); + + $cur->user_default_blog = (string) $blog_id; + + $cur->update("WHERE user_id = '".$this->con->escape($id)."'"); + } + + private function getUserCursor(&$cur) + { + if ($cur->isField('user_id') + && !preg_match('/^[A-Za-z0-9@._-]{2,}$/',$cur->user_id)) { + throw new Exception(__('User ID must contain at least 2 characters using letters, numbers or symbols.')); + } + + if ($cur->user_url !== null && $cur->user_url != '') { + if (!preg_match('|^http(s?)://|',$cur->user_url)) { + $cur->user_url = 'http://'.$cur->user_url; + } + } + + if ($cur->isField('user_pwd')) { + if (strlen($cur->user_pwd) < 6) { + throw new Exception(__('Password must contain at least 6 characters.')); + } + $cur->user_pwd = crypt::hmac(DC_MASTER_KEY,$cur->user_pwd); + } + + if ($cur->user_lang !== null && !preg_match('/^[a-z]{2}(-[a-z]{2})?$/',$cur->user_lang)) { + throw new Exception(__('Invalid user language code')); + } + + if ($cur->user_upddt === null) { + $cur->user_upddt = array('NOW()'); + } + + if ($cur->user_options !== null) { + $cur->user_options = serialize((array) $cur->user_options); + } + } + + /** + Returns user default settings in an associative array with setting names in + keys. + + @return array + */ + public function userDefaults() + { + return array( + 'edit_size' => 24, + 'enable_wysiwyg' => true, + 'post_format' => 'wiki', + ); + } + //@} + + /// @name Blog management methods + //@{ + /** + Returns all blog permissions (users) as an array which looks like: + + - [user_id] + - [name] => User name + - [firstname] => User firstname + - [displayname] => User displayname + - [super] => (true|false) super admin + - [p] + - [permission] => true + - ... + + @param id string Blog ID + @param with_super boolean Includes super admins in result + @return array + */ + public function getBlogPermissions($id,$with_super=true) + { + $strReq = + 'SELECT U.user_id AS user_id, user_super, user_name, user_firstname, '. + 'user_displayname, permissions '. + 'FROM '.$this->prefix.'user U '. + 'JOIN '.$this->prefix.'permissions P ON U.user_id = P.user_id '. + "WHERE blog_id = '".$this->con->escape($id)."' "; + + if ($with_super) { + $strReq .= + 'UNION '. + 'SELECT U.user_id AS user_id, user_super, user_name, user_firstname, '. + "user_displayname, NULL AS permissions ". + 'FROM '.$this->prefix.'user U '. + 'WHERE user_super = 1 '; + } + + $rs = $this->con->select($strReq); + + $res = array(); + + while ($rs->fetch()) + { + $res[$rs->user_id] = array( + 'name' => $rs->user_name, + 'firstname' => $rs->user_firstname, + 'displayname' => $rs->user_displayname, + 'super' => (boolean) $rs->user_super, + 'p' => $this->auth->parsePermissions($rs->permissions) + ); + } + + return $res; + } + + /** + Returns a blog of given ID. + + @param id string Blog ID + @return record + */ + public function getBlog($id) + { + $blog = $this->getBlogs(array('blog_id'=>$id)); + + if ($blog->isEmpty()) { + return false; + } + + return $blog; + } + + /** + Returns a record of blogs. $params is an array with the following + optionnal parameters: + + - blog_id: Blog ID + - q: Search string on blog_id, blog_name and blog_url + - limit: limit results + + @param params array Parameters + @param count_only boolean Count only results + @return record + */ + public function getBlogs($params=array(),$count_only=false) + { + $join = ''; // %1$s + $where = ''; // %2$s + + if ($count_only) + { + $strReq = 'SELECT count(B.blog_id) '. + 'FROM '.$this->prefix.'blog B '. + '%1$s '. + 'WHERE NULL IS NULL '. + '%2$s '; + } + else + { + $strReq = + 'SELECT B.blog_id, blog_uid, blog_url, blog_name, blog_desc, blog_creadt, '. + 'blog_upddt, blog_status '. + 'FROM '.$this->prefix.'blog B '. + '%1$s '. + 'WHERE NULL IS NULL '. + '%2$s '; + + if (!empty($params['order'])) { + $strReq .= 'ORDER BY '.$this->con->escape($params['order']).' '; + } else { + $strReq .= 'ORDER BY B.blog_id ASC '; + } + + if (!empty($params['limit'])) { + $strReq .= $this->con->limit($params['limit']); + } + } + + if ($this->auth->userID() && !$this->auth->isSuperAdmin()) + { + $join = 'INNER JOIN '.$this->prefix.'permissions PE ON B.blog_id = PE.blog_id '; + $where = + "AND PE.user_id = '".$this->con->escape($this->auth->userID())."' ". + "AND (permissions LIKE '%|usage|%' OR permissions LIKE '%|admin|%' OR permissions LIKE '%|contentadmin|%') ". + "AND blog_status IN (1,0) "; + } elseif (!$this->auth->userID()) { + $where = 'AND blog_status = 1 '; + } + + if (!empty($params['blog_id'])) { + $where .= "AND B.blog_id = '".$this->con->escape($params['blog_id'])."' "; + } + + if (!empty($params['q'])) { + $params['q'] = str_replace('*','%',$params['q']); + $where .= + 'AND ('. + "LOWER(B.blog_id) LIKE '".$this->con->escape($params['q'])."' ". + "OR LOWER(B.blog_name) LIKE '".$this->con->escape($params['q'])."' ". + "OR LOWER(B.blog_url) LIKE '".$this->con->escape($params['q'])."' ". + ') '; + } + + $strReq = sprintf($strReq,$join,$where); + return $this->con->select($strReq); + } + + /** + Creates a new blog. + + @param cur cursor Blog cursor + */ + public function addBlog($cur) + { + if (!$this->auth->isSuperAdmin()) { + throw new Exception(__('You are not an administrator')); + } + + $this->getBlogCursor($cur); + + $cur->blog_creadt = date('Y-m-d H:i:s'); + $cur->blog_upddt = date('Y-m-d H:i:s'); + $cur->blog_uid = md5(uniqid()); + + $cur->insert(); + } + + /** + Updates a given blog. + + @param id string Blog ID + @param cur cursor Blog cursor + */ + public function updBlog($id,$cur) + { + $this->getBlogCursor($cur); + + $cur->blog_upddt = date('Y-m-d H:i:s'); + + $cur->update("WHERE blog_id = '".$this->con->escape($id)."'"); + } + + private function getBlogCursor(&$cur) + { + if ($cur->blog_id !== null + && !preg_match('/^[A-Za-z0-9._-]{2,}$/',$cur->blog_id)) { + throw new Exception(__('Blog ID must contain at least 2 characters using letters, numbers or symbols.')); + } + + if ($cur->blog_name !== null && $cur->blog_name == '') { + throw new Exception(__('No blog name')); + } + + if ($cur->blog_url !== null && $cur->blog_url == '') { + throw new Exception(__('No blog URL')); + } + + if ($cur->blog_desc !== null) { + $cur->blog_desc = html::clean($cur->blog_desc); + } + } + + /** + Removes a given blog. + @warning This will remove everything related to the blog (posts, + categories, comments, links...) + + @param id string Blog ID + */ + public function delBlog($id) + { + if (!$this->auth->isSuperAdmin()) { + throw new Exception(__('You are not an administrator')); + } + + $strReq = 'DELETE FROM '.$this->prefix.'blog '. + "WHERE blog_id = '".$this->con->escape($id)."' "; + + $this->con->execute($strReq); + } + + /** + Checks if a blog exist. + + @param id string Blog ID + @return boolean + */ + public function blogExists($id) + { + $strReq = 'SELECT blog_id '. + 'FROM '.$this->prefix.'blog '. + "WHERE blog_id = '".$this->con->escape($id)."' "; + + $rs = $this->con->select($strReq); + + return !$rs->isEmpty(); + } + + /** + Count posts on a blog + + @param id string Blog ID + @param type string Post type + @return boolean + */ + public function countBlogPosts($id,$type=null) + { + $strReq = 'SELECT COUNT(post_id) '. + 'FROM '.$this->prefix.'post '. + "WHERE blog_id = '".$this->con->escape($id)."' "; + + if ($type) { + $strReq .= "AND post_type = '".$this->con->escape($type)."' "; + } + + return $this->con->select($strReq)->f(0); + } + //@} + + /// @name HTML Filter methods + //@{ + /** + Calls HTML filter to drop bad tags and produce valid XHTML output (if + tidy extension is present). If enable_html_filter blog setting is + false, returns not filtered string. + + @param str string String to filter + @return string Filtered string. + */ + public function HTMLfilter($str) + { + if ($this->blog instanceof dcBlog && !$this->blog->settings->enable_html_filter) { + return $str; + } + + $filter = new htmlFilter; + $str = trim($filter->apply($str)); + return $str; + } + //@} + + /// @name wiki2xhtml methods + //@{ + private function initWiki() + { + $this->wiki2xhtml = new wiki2xhtml; + } + + /** + Returns a transformed string with wiki2xhtml. + + @param str string String to transform + @return string Transformed string + */ + public function wikiTransform($str) + { + if (!($this->wiki2xhtml instanceof wiki2xhtml)) { + $this->initWiki(); + } + return $this->wiki2xhtml->transform($str); + } + + /** + Inits wiki2xhtml property for blog post. + */ + public function initWikiPost() + { + $this->initWiki(); + + $this->wiki2xhtml->setOpts(array( + 'active_title' => 1, + 'active_setext_title' => 0, + 'active_hr' => 1, + 'active_lists' => 1, + 'active_quote' => 1, + 'active_pre' => 1, + 'active_empty' => 1, + 'active_auto_br' => 0, + 'active_auto_urls' => 0, + 'active_urls' => 1, + 'active_auto_img' => 0, + 'active_img' => 1, + 'active_anchor' => 1, + 'active_em' => 1, + 'active_strong' => 1, + 'active_br' => 1, + 'active_q' => 1, + 'active_code' => 1, + 'active_acronym' => 1, + 'active_ins' => 1, + 'active_del' => 1, + 'active_footnotes' => 1, + 'active_wikiwords' => 0, + 'active_macros' => 1, + 'parse_pre' => 1, + 'active_fr_syntax' => 0, + 'first_title_level' => 3, + 'note_prefix' => 'wiki-footnote', + 'note_str' => '

    Notes

    %s
    ' + )); + + $this->wiki2xhtml->registerFunction('url:post',array($this,'wikiPostLink')); + + # --BEHAVIOR-- coreWikiPostInit + $this->callBehavior('coreInitWikiPost',$this->wiki2xhtml); + } + + /** + Inits wiki2xhtml property for simple blog comment (basic syntax). + */ + public function initWikiSimpleComment() + { + $this->initWiki(); + + $this->wiki2xhtml->setOpts(array( + 'active_title' => 0, + 'active_setext_title' => 0, + 'active_hr' => 0, + 'active_lists' => 0, + 'active_quote' => 0, + 'active_pre' => 0, + 'active_empty' => 0, + 'active_auto_br' => 1, + 'active_auto_urls' => 1, + 'active_urls' => 0, + 'active_auto_img' => 0, + 'active_img' => 0, + 'active_anchor' => 0, + 'active_em' => 0, + 'active_strong' => 0, + 'active_br' => 0, + 'active_q' => 0, + 'active_code' => 0, + 'active_acronym' => 0, + 'active_ins' => 0, + 'active_del' => 0, + 'active_footnotes' => 0, + 'active_wikiwords' => 0, + 'active_macros' => 0, + 'parse_pre' => 0, + 'active_fr_syntax' => 0 + )); + + # --BEHAVIOR-- coreInitWikiSimpleComment + $this->callBehavior('coreInitWikiSimpleComment',$this->wiki2xhtml); + } + + /** + Inits wiki2xhtml property for blog comment. + */ + public function initWikiComment() + { + $this->initWiki(); + + $this->wiki2xhtml->setOpts(array( + 'active_title' => 0, + 'active_setext_title' => 0, + 'active_hr' => 0, + 'active_lists' => 1, + 'active_quote' => 0, + 'active_pre' => 1, + 'active_empty' => 0, + 'active_auto_br' => 1, + 'active_auto_urls' => 1, + 'active_urls' => 1, + 'active_auto_img' => 0, + 'active_img' => 0, + 'active_anchor' => 0, + 'active_em' => 1, + 'active_strong' => 1, + 'active_br' => 1, + 'active_q' => 1, + 'active_code' => 1, + 'active_acronym' => 1, + 'active_ins' => 1, + 'active_del' => 1, + 'active_footnotes' => 0, + 'active_wikiwords' => 0, + 'active_macros' => 0, + 'parse_pre' => 0, + 'active_fr_syntax' => 0 + )); + + # --BEHAVIOR-- coreInitWikiComment + $this->callBehavior('coreInitWikiComment',$this->wiki2xhtml); + } + + public function wikiPostLink($url,$content) + { + if (!($this->blog instanceof dcBlog)) { + return array(); + } + + $post_id = abs((integer) substr($url,5)); + if (!$post_id) { + return array(); + } + + $post = $this->blog->getPosts(array('post_id'=>$post_id)); + if ($post->isEmpty()) { + return array(); + } + + $res = array('url' => $post->getURL()); + $post_title = $post->post_title; + + if ($content != $url) { + $res['title'] = html::escapeHTML($post->post_title); + } + + if ($content == '' || $content == $url) { + $res['content'] = html::escapeHTML($post->post_title); + } + + if ($post->post_lang) { + $res['lang'] = $post->post_lang; + } + + return $res; + } + //@} + + /// @name Maintenance methods + //@{ + /** + Creates default settings for active blog. Optionnal parameter + defaults replaces default params while needed. + + @param defaults array Default parameters + */ + public function blogDefaults($defaults=null) + { + if (!is_array($defaults)) + { + $defaults = array( + array('allow_comments','boolean',true, + 'Allow comments on blog'), + array('allow_trackbacks','boolean',true, + 'Allow trackbacks on blog'), + array('blog_timezone','string','Europe/London', + 'Blog timezone'), + array('comments_nofollow','boolean',true, + 'Add rel="nofollow" to comments URLs'), + array('comments_pub','boolean',true, + 'Publish comments immediately'), + array('comments_ttl','integer',0, + 'Number of days to keep comments open (0 means no ttl)'), + array('copyright_notice','string','','Copyright notice (simple text)'), + array('date_format','string','%A, %B %e %Y', + 'Date format. See PHP strftime function for patterns'), + array('editor','string','', + 'Person responsible of the content'), + array('enable_html_filter','boolean',0, + 'Enable HTML filter'), + array('enable_xmlrpc','boolean',0, + 'Enable XML/RPC interface'), + array('lang','string','en', + 'Default blog language'), + array('media_exclusion','string','', + 'File name exclusion pattern in media manager. (PCRE value)'), + array('media_img_m_size','integer',448, + 'Image medium size in media manager'), + array('media_img_s_size','integer',240, + 'Image small size in media manager'), + array('media_img_t_size','integer',100, + 'Image thumbnail size in media manager'), + array('media_img_title_pattern','string','Title ;; Date(%b %Y) ;; separator(, )', + 'Pattern to set image title when you insert it in a post'), + array('nb_post_per_page','integer',20, + 'Number of entries on home page and category pages'), + array('nb_post_per_feed','integer',20, + 'Number of entries on feeds'), + array('nb_comment_per_feed','integer',20, + 'Number of comments on feeds'), + array('post_url_format','string','{y}/{m}/{d}/{t}', + 'Post URL format. {y}: year, {m}: month, {d}: day, {id}: post id, {t}: entry title'), + array('public_path','string','public', + 'Path to public directory, begins with a / for a full system path'), + array('public_url','string','/public', + 'URL to public directory'), + array('robots_policy','string','INDEX,FOLLOW', + 'Search engines robots policy'), + array('short_feed_items','boolean',false, + 'Display short feed items'), + array('theme','string','default', + 'Blog theme'), + array('themes_path','string','themes', + 'Themes root path'), + array('themes_url','string','/themes', + 'Themes root URL'), + array('time_format','string','%H:%M', + 'Time format. See PHP strftime function for patterns'), + array('tpl_allow_php','boolean',false, + 'Allow PHP code in templates'), + array('tpl_use_cache','boolean',true, + 'Use template caching'), + array('trackbacks_pub','boolean',true, + 'Publish trackbacks immediately'), + array('trackbacks_ttl','integer',0, + 'Number of days to keep trackbacks open (0 means no ttl)'), + array('url_scan','string','query_string', + 'URL handle mode (path_info or query_string)'), + array('use_smilies','boolean',false, + 'Show smilies on entries and comments'), + array('wiki_comments','boolean',false, + 'Allow commenters to use a subset of wiki syntax') + ); + } + + $settings = new dcSettings($this,null); + $settings->setNameSpace('system'); + + foreach ($defaults as $v) { + $settings->put($v[0],$v[2],$v[1],$v[3],false,true); + } + } + + /** + Recreates entries search engine index. + + @param start integer Start entry index + @param limit integer Number of entry to index + + @return integer $start and $limit sum + */ + public function indexAllPosts($start=null,$limit=null) + { + $strReq = 'SELECT COUNT(post_id) '. + 'FROM '.$this->prefix.'post'; + $rs = $this->con->select($strReq); + $count = $rs->f(0); + + $strReq = 'SELECT post_id, post_title, post_excerpt_xhtml, post_content_xhtml '. + 'FROM '.$this->prefix.'post '; + + if ($start !== null && $limit !== null) { + $strReq .= $this->con->limit($start,$limit); + } + + $rs = $this->con->select($strReq,true); + + $cur = $this->con->openCursor($this->prefix.'post'); + + while ($rs->fetch()) + { + $words = $rs->post_title.' '. $rs->post_excerpt_xhtml.' '. + $rs->post_content_xhtml; + + $cur->post_words = implode(' ',text::splitWords($words)); + $cur->update('WHERE post_id = '.(integer) $rs->post_id); + $cur->clean(); + } + + if ($start+$limit > $count) { + return null; + } + return $start+$limit; + } + + /** + Recreates comments search engine index. + + @param start integer Start comment index + @param limit integer Number of comments to index + + @return integer $start and $limit sum + */ + public function indexAllComments($start=null,$limit=null) + { + $strReq = 'SELECT COUNT(comment_id) '. + 'FROM '.$this->prefix.'comment'; + $rs = $this->con->select($strReq); + $count = $rs->f(0); + + $strReq = 'SELECT comment_id, comment_content '. + 'FROM '.$this->prefix.'comment '; + + if ($start !== null && $limit !== null) { + $strReq .= $this->con->limit($start,$limit); + } + + $rs = $this->con->select($strReq); + + $cur = $this->con->openCursor($this->prefix.'comment'); + + while ($rs->fetch()) + { + $cur->comment_words = implode(' ',text::splitWords($rs->comment_content)); + $cur->update('WHERE comment_id = '.(integer) $rs->comment_id); + $cur->clean(); + } + + if ($start+$limit > $count) { + return null; + } + return $start+$limit; + } + + /** + Reinits nb_comment and nb_trackback in post table. + */ + public function countAllComments() + { + $strReq = 'SELECT COUNT(comment_id) AS nb, post_id '. + 'FROM '.$this->prefix.'comment '. + 'WHERE comment_trackback %s 1 '. + 'AND comment_status = 1 '. + 'GROUP BY post_id '; + + $rsC = $this->con->select(sprintf($strReq,'<>')); + $rsT = $this->con->select(sprintf($strReq,'=')); + + $cur = $this->con->openCursor($this->prefix.'post'); + while ($rsC->fetch()) { + $cur->nb_comment = (integer) $rsC->nb; + $cur->update('WHERE post_id = '.(integer) $rsC->post_id); + $cur->clean(); + } + + while ($rsT->fetch()) { + $cur->nb_trackback = (integer) $rsT->nb; + $cur->update('WHERE post_id = '.(integer) $rsT->post_id); + $cur->clean(); + } + } + + /** + Empty templates cache directory + */ + public function emptyTemplatesCache() + { + if (is_dir(DC_TPL_CACHE.'/cbtpl')) { + files::deltree(DC_TPL_CACHE.'/cbtpl'); + } + } + //@} +} +?> \ No newline at end of file diff --git a/inc/core/class.dc.error.php b/inc/core/class.dc.error.php new file mode 100644 index 0000000..2db5e02 --- /dev/null +++ b/inc/core/class.dc.error.php @@ -0,0 +1,129 @@ +array Errors stack + protected $flag = false; ///< boolean True if stack is not empty + protected $html_list = "
      \n%s
    \n"; ///< string HTML errors list pattern + protected $html_item = "
  • %s
  • \n"; ///< string HTML error item pattern + + /** + Object constructor. + */ + public function __construct() + { + $this->code = 0; + $this->msg = ''; + } + + /** + Object string representation. Returns errors stack. + + @return string + */ + public function __toString() + { + $res = ''; + + foreach ($this->errors as $msg) + { + $res .= $msg."\n"; + } + + return $res; + } + + /** + Adds an error to stack. + + @param msg string Error message + */ + public function add($msg) + { + $this->flag = true; + $this->errors[] = $msg; + } + + /** + Returns the value of flag property. + + @return boolean True if errors stack is not empty + */ + public function flag() + { + return $this->flag; + } + + /** + Resets errors stack. + */ + public function reset() + { + $this->flag = false; + $this->errors = array(); + } + + /** + Returns errors property. + + @return array + */ + public function getErrors() + { + return $this->errors; + } + + /** + Sets list and item properties. + + @param list string HTML errors list pattern + @param item string HTML error item pattern + */ + public function setHTMLFormat($list,$item) + { + $this->html_list = $list; + $this->html_item = $item; + } + + /** + Returns errors stack as HTML. + + @return string + */ + public function toHTML() + { + $res = ''; + + if ($this->flag) + { + foreach ($this->errors as $msg) + { + $res .= sprintf($this->html_item,$msg); + } + + $res = sprintf($this->html_list,$res); + } + + return $res; + } +} +?> \ No newline at end of file diff --git a/inc/core/class.dc.media.php b/inc/core/class.dc.media.php new file mode 100644 index 0000000..1205dd5 --- /dev/null +++ b/inc/core/class.dc.media.php @@ -0,0 +1,1070 @@ +dcCore dcCore instance + protected $con; ///< connection Database connection + protected $table; ///< string Media table name + protected $table_ref; ///< string Post-media relation table name + protected $type; ///< string Media type filter + protected $file_sort = 'name-asc'; + + protected $file_handler = array(); ///< array Array of callbacks + + public $thumb_tp = '%s/.%s_%s.jpg'; ///< string Thumbnail file pattern + + /** + array Tubmnail sizes: + - m: medium image + - s: small image + - t: thumbnail image + - sq: square image + */ + public $thumb_sizes = array( + 'm' => array(448,'ratio','medium'), + 's' => array(240,'ratio','small'), + 't' => array(100,'ratio','thumbnail'), + 'sq' => array(48,'crop','square') + ); + + public $icon_img = 'images/media/%s.png'; ///< string Icon file pattern + + /** + Object constructor. + + @param core dcCore dcCore instance + @param type string Media type filter + */ + public function __construct(&$core,$type='') + { + $this->core =& $core; + $this->con =& $core->con; + + if ($this->core->blog == null) { + throw new Exception(__('No blog defined.')); + } + + $this->table = $this->core->prefix.'media'; + $this->table_ref = $this->core->prefix.'post_media'; + $root = $this->core->blog->public_path; + + if (preg_match('#^http(s)?://#',$this->core->blog->settings->public_url)) { + $root_url = rawurldecode($this->core->blog->settings->public_url); + } else { + $root_url = rawurldecode($this->core->blog->host.path::clean($this->core->blog->settings->public_url)); + } + + if (!is_dir($root)) { + throw new Exception(sprintf(__('Directory %s does not exist.'),$root)); + } + + $this->type = $type; + + parent::__construct($root,$root_url); + $this->chdir(''); + + $this->path = $this->core->blog->settings->public_path; + + $this->addExclusion(DC_RC_PATH); + $this->addExclusion(dirname(__FILE__).'/../'); + + $this->exclude_pattern = $core->blog->settings->media_exclusion; + + # Event handlers + $this->addFileHandler('image/jpeg','create',array($this,'imageThumbCreate')); + $this->addFileHandler('image/png','create',array($this,'imageThumbCreate')); + $this->addFileHandler('image/gif','create',array($this,'imageThumbCreate')); + + $this->addFileHandler('image/png','update',array($this,'imageThumbUpdate')); + $this->addFileHandler('image/jpeg','update',array($this,'imageThumbUpdate')); + $this->addFileHandler('image/gif','update',array($this,'imageThumbUpdate')); + + $this->addFileHandler('image/png','remove',array($this,'imageThumbRemove')); + $this->addFileHandler('image/jpeg','remove',array($this,'imageThumbRemove')); + $this->addFileHandler('image/gif','remove',array($this,'imageThumbRemove')); + + $this->addFileHandler('image/jpeg','create',array($this,'imageMetaCreate')); + + # Thumbnails sizes + $this->thumb_sizes['m'][0] = abs($core->blog->settings->media_img_m_size); + $this->thumb_sizes['s'][0] = abs($core->blog->settings->media_img_s_size); + $this->thumb_sizes['t'][0] = abs($core->blog->settings->media_img_t_size); + } + + /** + Changes working directory. + + @param dir string Directory name. + */ + public function chdir($dir) + { + parent::chdir($dir); + $this->relpwd = preg_replace('/^'.preg_quote($this->root,'/').'\/?/','',$this->pwd); + } + + /** + Adds a new file handler for a given media type and event. + + Available events are: + - create: file creation + - update: file update + - remove: file deletion + + @param type string Media type + @param event string Event + @param function callback + */ + public function addFileHandler($type,$event,$function) + { + if (is_callable($function)) { + $this->file_handler[$type][$event][] = $function; + } + } + + protected function callFileHandler($type,$event) + { + if (!empty($this->file_handler[$type][$event])) + { + $args = func_get_args(); + array_shift($args); + array_shift($args); + + foreach ($this->file_handler[$type][$event] as $f) + { + call_user_func_array($f,$args); + } + } + } + + /** + Returns HTML breadCrumb for media manager navigation. + + @param href string URL pattern + @return string HTML code + */ + public function breadCrumb($href) + { + $res = ''; + if ($this->relpwd && $this->relpwd != '.') { + $pwd = ''; + foreach (explode('/',$this->relpwd) as $v) { + $pwd .= rawurlencode($v).'/'; + $res .= ''.$v.' / '; + } + } + return $res; + + } + + protected function fileRecord(&$rs) + { + if ($rs->isEmpty()) { return null; } + + if (!$this->isFileExclude($this->root.'/'.$rs->media_file) && is_file($this->root.'/'.$rs->media_file)) + { + $f = new fileItem($this->root.'/'.$rs->media_file,$this->root,$this->root_url); + + if ($this->type && $f->type_prefix != $this->type) { + return null; + } + + $meta = @simplexml_load_string($rs->media_meta); + + $f->editable = true; + $f->media_id = $rs->media_id; + $f->media_title = $rs->media_title; + $f->media_meta = $meta instanceof SimpleXMLElement ? $meta : simplexml_load_string(''); + $f->media_user = $rs->user_id; + $f->media_priv = (boolean) $rs->media_private; + $f->media_dt = strtotime($rs->media_dt); + $f->media_dtstr = dt::str('%Y-%m-%d %H:%M',$f->media_dt); + + $f->media_image = false; + + if (!$this->core->auth->check('media_admin',$this->core->blog->id) + && $this->core->auth->userID() != $f->media_user) { + $f->del = false; + $f->editable = false; + } + + $type_prefix = explode('/',$f->type); + $type_prefix = $type_prefix[0]; + + switch ($type_prefix) { + case 'image': + $f->media_image = true; + $f->media_icon = 'image'; + break; + case 'audio': + $f->media_icon = 'audio'; + break; + case 'text': + $f->media_icon = 'text'; + break; + case 'video': + $f->media_icon = 'video'; + break; + default: + $f->media_icon = 'blank'; + } + switch ($f->type) { + case 'application/msword': + case 'application/vnd.oasis.opendocument.text': + case 'application/vnd.sun.xml.writer': + case 'application/pdf': + case 'application/postscript': + $f->media_icon = 'document'; + break; + case 'application/msexcel': + case 'application/vnd.oasis.opendocument.spreadsheet': + case 'application/vnd.sun.xml.calc': + $f->media_icon = 'spreadsheet'; + break; + case 'application/mspowerpoint': + case 'application/vnd.oasis.opendocument.presentation': + case 'application/vnd.sun.xml.impress': + $f->media_icon = 'presentation'; + break; + case 'application/x-debian-package': + case 'application/x-gzip': + case 'application/x-java-archive': + case 'application/rar': + case 'application/x-redhat-package-manager': + case 'application/x-tar': + case 'application/x-gtar': + case 'application/zip': + $f->media_icon = 'package'; + break; + case 'application/octet-stream': + $f->media_icon = 'executable'; + break; + case 'application/x-shockwave-flash': + $f->media_icon = 'video'; + break; + case 'application/ogg': + $f->media_icon = 'audio'; + break; + case 'text/html': + $f->media_icon = 'html'; + break; + } + + $f->media_type = $f->media_icon; + $f->media_icon = sprintf($this->icon_img,$f->media_icon); + + # Thumbnails + $f->media_thumb = array(); + $p = path::info($f->relname); + $thumb = sprintf($this->thumb_tp,$this->root.'/'.$p['dirname'],$p['base'],'%s'); + $thumb_url = sprintf($this->thumb_tp,$this->root_url.$p['dirname'],$p['base'],'%s'); + + # Cleaner URLs + $thumb_url = preg_replace('#\./#','/',$thumb_url); + $thumb_url = preg_replace('#(?thumb_sizes as $suffix => $s) { + if (file_exists(sprintf($thumb,$suffix))) { + $f->media_thumb[$suffix] = sprintf($thumb_url,$suffix); + } + } + + if (isset($f->media_thumb['sq']) && $f->media_type == 'image') { + $f->media_icon = $f->media_thumb['sq']; + } + + return $f; + } + + return null; + } + + + public function setFileSort($type='name') + { + if (in_array($type,array('name-asc','name-desc','date-asc','date-desc'))) { + $this->file_sort = $type; + } + } + + protected function sortFileHandler($a,$b) + { + switch ($this->file_sort) + { + case 'date-asc': + if ($a->media_dt == $b->media_dt) { + return 0; + } + return ($a->media_dt < $b->media_dt) ? -1 : 1; + case 'date-desc': + if ($a->media_dt == $b->media_dt) { + return 0; + } + return ($a->media_dt > $b->media_dt) ? -1 : 1; + case 'name-desc': + return strcasecmp($b->basename,$a->basename); + case 'name-asc': + default: + return strcasecmp($a->basename,$b->basename); + } + + } + + /** + Gets current working directory content. + + @param type string Media type filter + */ + public function getDir($type=null) + { + if ($type) { + $this->type = $type; + } + + $media_dir = $this->relpwd ? $this->relpwd : '.'; + + $strReq = + 'SELECT media_file, media_id, media_path, media_title, media_meta, media_dt, '. + 'media_creadt, media_upddt, media_private, user_id '. + 'FROM '.$this->table.' '. + "WHERE media_path = '".$this->path."' ". + "AND media_dir = '".$this->con->escape($media_dir)."' "; + + if (!$this->core->auth->check('media_admin',$this->core->blog->id)) + { + $strReq .= 'AND (media_private <> 1 '; + + if ($this->core->auth->userID()) { + $strReq .= "OR user_id = '".$this->con->escape($this->core->auth->userID())."'"; + } + $strReq .= ') '; + } + + $rs = $this->con->select($strReq); + + parent::getDir(); + + $f_res = array(); + $p_dir = $this->dir; + + # If type is set, remove items from p_dir + if ($this->type) + { + foreach ($p_dir['files'] as $k => $f) { + if ($f->type_prefix != $this->type) { + unset($p_dir['files'][$k]); + } + } + } + + $f_reg = array(); + + while ($rs->fetch()) + { + # File in subdirectory, forget about it! + if (dirname($rs->media_file) != '.' && dirname($rs->media_file) != $this->relpwd) { + continue; + } + + if ($this->inFiles($rs->media_file)) + { + $f = $this->fileRecord($rs); + if ($f !== null) { + $f_res[] = $this->fileRecord($rs); + $f_reg[$rs->media_file] = 1; + } + } + elseif (!empty($p_dir['files']) && $this->relpwd == '') + { + # Physica file does not exist remove it from DB + # Because we don't want to erase everything on + # dotclear upgrade, do it only if there are files + # in directory and directory is root + $this->con->execute( + 'DELETE FROM '.$this->table.' '. + "WHERE media_path = '".$this->con->escape($this->path)."' ". + "AND media_file = '".$this->con->escape($rs->media_file)."' " + ); + $this->callFileHandler(files::getMimeType($rs->media_file),'remove',$this->pwd.'/'.$rs->media_file); + } + } + + $this->dir['files'] = $f_res; + foreach ($this->dir['dirs'] as $k => $v) { + $v->media_icon = sprintf($this->icon_img,'folder'); + } + + # Check files that don't exist in database and create them + if ($this->core->auth->check('media,media_admin',$this->core->blog->id)) + { + foreach ($p_dir['files'] as $f) + { + if (!isset($f_reg[$f->relname])) { + if (($id = $this->createFile($f->basename)) !== false) { + $this->dir['files'][] = $this->getFile($id); + } + } + } + } + usort($this->dir['files'],array($this,'sortFileHandler')); + } + + /** + Gets file by its id. Returns a filteItem object. + + @param id integer File ID + @return fileItem + */ + public function getFile($id) + { + $strReq = + 'SELECT media_id, media_path, media_title, '. + 'media_file, media_meta, media_dt, media_creadt, '. + 'media_upddt, media_private, user_id '. + 'FROM '.$this->table.' '. + "WHERE media_path = '".$this->path."' ". + 'AND media_id = '.(integer) $id.' '; + + if (!$this->core->auth->check('media_admin',$this->core->blog->id)) + { + $strReq .= 'AND (media_private <> 1 '; + + if ($this->core->auth->userID()) { + $strReq .= "OR user_id = '".$this->con->escape($this->core->auth->userID())."'"; + } + $strReq .= ') '; + } + + $rs = $this->con->select($strReq); + return $this->fileRecord($rs); + } + + /** + Returns media items attached to a blog post. Result is an array containing + fileItems objects. + + @param post_id integer Post ID + @param media_id integer Optionnal media ID + @return array Array of fileItems + */ + public function getPostMedia($post_id,$media_id=null) + { + $post_id = (integer) $post_id; + + $strReq = + 'SELECT media_file, M.media_id, media_path, media_title, media_meta, media_dt, '. + 'media_creadt, media_upddt, media_private, user_id '. + 'FROM '.$this->table.' M '. + 'INNER JOIN '.$this->table_ref.' PM ON (M.media_id = PM.media_id) '. + "WHERE media_path = '".$this->path."' ". + 'AND post_id = '.$post_id.' '; + + if ($media_id) { + $strReq .= 'AND M.media_id = '.(integer) $media_id.' '; + } + + $rs = $this->con->select($strReq); + + $res = array(); + + while ($rs->fetch()) { + $f = $this->fileRecord($rs); + if ($f !== null) { + $res[] = $f; + } + } + + return $res; + } + + /** + Attaches a media to a post. + + @param post_id integer Post ID + @param media_id integer Optionnal media ID + */ + public function addPostMedia($post_id,$media_id) + { + $post_id = (integer) $post_id; + $media_id = (integer) $media_id; + + $f = $this->getPostMedia($post_id,$media_id); + + if (!empty($f)) { + return; + } + + $cur = $this->con->openCursor($this->table_ref); + $cur->post_id = $post_id; + $cur->media_id = $media_id; + + $cur->insert(); + $this->core->blog->triggerBlog(); + } + + /** + Detaches a media from a post. + + @param post_id integer Post ID + @param media_id integer Optionnal media ID + */ + public function removePostMedia($post_id,$media_id) + { + $post_id = (integer) $post_id; + $media_id = (integer) $media_id; + + $strReq = 'DELETE FROM '.$this->table_ref.' '. + 'WHERE post_id = '.$post_id.' '. + 'AND media_id = '.$media_id.' '; + + $this->con->execute($strReq); + $this->core->blog->triggerBlog(); + } + + /** + Rebuilds database items collection. Optional $pwd parameter is + the path where to start rebuild. + + @param pwd string Directory to rebuild + */ + public function rebuild($pwd='') + { + if (!$this->core->auth->isSuperAdmin()) { + throw new Exception(__('You are not a super administrator.')); + } + + $this->chdir($pwd); + parent::getDir(); + + $dir = $this->dir; + + foreach ($dir['dirs'] as $d) { + if (!$d->parent) { + $this->rebuild($d->relname,false); + } + } + + foreach ($dir['files'] as $f) { + $this->chdir(dirname($f->relname)); + $this->createFile($f->basename); + } + + $this->rebuildDB($pwd); + } + + protected function rebuildDB($pwd) + { + $media_dir = $pwd ? $pwd : '.'; + + $strReq = + 'SELECT media_file, media_id '. + 'FROM '.$this->table.' '. + "WHERE media_path = '".$this->path."' ". + "AND media_dir = '".$this->con->escape($media_dir)."' "; + + $rs = $this->con->select($strReq); + + $delReq = 'DELETE FROM '.$this->table.' '. + 'WHERE media_id IN (%s) '; + $del_ids = array(); + + while ($rs->fetch()) + { + if (!is_file($this->root.'/'.$rs->media_file)) { + $del_ids[] = (integer) $rs->media_id; + } + } + + if (!empty($del_ids)) { + $this->con->execute(sprintf($delReq,implode(',',$del_ids))); + } + } + + public function makeDir($d) + { + $d = files::tidyFileName($d); + parent::makeDir($d); + } + + /** + Creates or updates a file in database. Returns new media ID or false if + file does not exist. + + @param name string File name (relative to working directory) + @param title string File title + @param private boolean File is private + @param dt string File date + @return integer New media ID + */ + public function createFile($name,$title=null,$private=false,$dt=null) + { + if (!$this->core->auth->check('media,media_admin',$this->core->blog->id)) { + throw new Exception(__('Permission denied.')); + } + + $file = $this->pwd.'/'.$name; + if (!file_exists($file)) { + return false; + } + + $media_file = $this->relpwd ? path::clean($this->relpwd.'/'.$name) : path::clean($name); + $media_type = files::getMimeType($name); + + $cur = $this->con->openCursor($this->table); + + $strReq = 'SELECT media_id '. + 'FROM '.$this->table.' '. + "WHERE media_path = '".$this->con->escape($this->path)."' ". + "AND media_file = '".$this->con->escape($media_file)."' "; + + $rs = $this->con->select($strReq); + + if ($rs->isEmpty()) + { + $this->con->writeLock($this->table); + try + { + $rs = $this->con->select('SELECT MAX(media_id) FROM '.$this->table); + $media_id = (integer) $rs->f(0) + 1; + + $cur->media_id = $media_id; + $cur->user_id = (string) $this->core->auth->userID(); + $cur->media_path = (string) $this->path; + $cur->media_file = (string) $media_file; + $cur->media_dir = (string) dirname($media_file); + $cur->media_creadt = array('NOW()'); + $cur->media_upddt = array('NOW()'); + + $cur->media_title = !$title ? (string) $name : (string) $title; + $cur->media_private = (integer) (boolean) $private; + + if ($dt) { + $cur->media_dt = (string) $dt; + } else { + $cur->media_dt = strftime('%Y-%m-%d %H:%M:%S',filemtime($file)); + } + + try { + $cur->insert(); + } catch (Exception $e) { + @unlink($name); + throw $e; + } + $this->con->unlock(); + } + catch (Exception $e) + { + $this->con->unlock(); + throw $e; + } + } + else + { + $media_id = (integer) $rs->media_id; + + $cur->media_upddt = array('NOW()'); + + $cur->update('WHERE media_id = '.$media_id); + } + + $this->callFileHandler($media_type,'create',$cur,$name,$media_id); + + return $media_id; + } + + /** + Updates a file in database. + + @param file fileItem Current fileItem object + @param newFile fileItem New fileItem object + */ + public function updateFile($file,$newFile) + { + if (!$this->core->auth->check('media,media_admin',$this->core->blog->id)) { + throw new Exception(__('Permission denied.')); + } + + $id = (integer) $file->media_id; + + if (!$id) { + throw new Exception('No file ID'); + } + + if (!$this->core->auth->check('media_admin',$this->core->blog->id) + && $this->core->auth->userID() != $file->media_user) { + throw new Exception(__('You are not the file owner.')); + } + + $cur = $this->con->openCursor($this->table); + + # We need to tidy newFile basename. If dir isn't empty, concat to basename + $newFile->relname = files::tidyFileName($newFile->basename); + if ($newFile->dir) { + $newFile->relname = $newFile->dir.'/'.$newFile->relname; + } + + if ($file->relname != $newFile->relname) { + $newFile->file = $this->root.'/'.$newFile->relname; + + if (file_exists($newFile->file)) { + throw new Exception(__('New file already exists.')); + } + + $this->moveFile($file->relname,$newFile->relname); + + $cur->media_file = (string) $newFile->relname; + $cur->media_dir = (string) dirname($newFile->relname); + } + + $cur->media_title = (string) $newFile->media_title; + $cur->media_dt = (string) $newFile->media_dtstr; + $cur->media_upddt = array('NOW()'); + $cur->media_private = (integer) $newFile->media_priv; + + $cur->update('WHERE media_id = '.$id); + + $this->callFileHandler($file->type,'update',$file,$newFile); + } + + /** + Uploads a file. + + @param tmp string Full path of temporary uploaded file + @param name string File name (relative to working directory) + @param title string File title + @param private boolean File is private + */ + public function uploadFile($tmp,$name,$title=null,$private=false,$overwrite=false) + { + if (!$this->core->auth->check('media,media_admin',$this->core->blog->id)) { + throw new Exception(__('Permission denied.')); + } + + $name = files::tidyFileName($name); + + parent::uploadFile($tmp,$name,$overwrite); + + return $this->createFile($name,$title,$private); + } + + /** + Creates a file from binary content. + + @param name string File name (relative to working directory) + @param bits string Binary file content + */ + public function uploadBits($name,$bits) + { + if (!$this->core->auth->check('media,media_admin',$this->core->blog->id)) { + throw new Exception(__('Permission denied.')); + } + + $name = files::tidyFileName($name); + + parent::uploadBits($name,$bits); + + return $this->createFile($name,null,null); + } + + /** + Removes a file. + + @param f fileItem fileItem object + */ + public function removeFile($f) + { + if (!$this->core->auth->check('media,media_admin',$this->core->blog->id)) { + throw new Exception(__('Permission denied.')); + } + + $media_file = $this->relpwd ? path::clean($this->relpwd.'/'.$f) : path::clean($f); + + $strReq = 'DELETE FROM '.$this->table.' '. + "WHERE media_path = '".$this->con->escape($this->path)."' ". + "AND media_file = '".$this->con->escape($media_file)."' "; + + if (!$this->core->auth->check('media_admin',$this->core->blog->id)) + { + $strReq .= "AND user_id = '".$this->con->escape($this->core->auth->userID())."'"; + } + + $this->con->execute($strReq); + + if ($this->con->changes() == 0) { + throw new Exception(__('File does not exist in the database.')); + } + + parent::removeFile($f); + + $this->callFileHandler(files::getMimeType($media_file),'remove',$f); + } + + /** + Extract zip file in current location + + @param f fileRecord fileRecord object + */ + public function inflateZipFile($f,$create_dir=true) + { + $zip = new fileUnzip($f->file); + $zip->getList(false,'#(^|/)(__MACOSX|\.svn|\.DS_Store|Thumbs\.db)(/|$)#'); + + if ($create_dir) + { + $zip_root_dir = $zip->getRootDir(); + if ($zip_root_dir != false) { + $destination = $zip_root_dir; + $target = $f->dir; + } else { + $destination = preg_replace('/\.([^.]+)$/','',$f->basename); + $target = $f->dir.'/'.$destination; + } + + if (is_dir($f->dir.'/'.$destination)) { + throw new Exception(sprintf(__('Extract destination directory %s already exists.'),dirname($f->relname).'/'.$destination)); + } + } + else + { + $target = $f->dir; + $destination = ''; + } + + $zip->unzipAll($target); + $zip->close(); + return dirname($f->relname).'/'.$destination; + } + + /** + Returns zip file content + + @param f fileRecord fileRecord object + @return array + */ + public function getZipContent($f) + { + $zip = new fileUnzip($f->file); + $list = $zip->getList(false,'#(^|/)(__MACOSX|\.svn|\.DS_Store|Thumbs\.db)(/|$)#'); + $zip->close(); + return $list; + } + + /* Image handlers + ------------------------------------------------------- */ + public function imageThumbCreate(&$cur,$f) + { + $file = $this->pwd.'/'.$f; + + if (!file_exists($file)) { + return false; + } + + $p = path::info($file); + $thumb = sprintf($this->thumb_tp,$p['dirname'],$p['base'],'%s'); + + try + { + $img = new imageTools(); + $img->loadImage($file); + + $w = $img->getW(); + $h = $img->getH(); + + $this->imageThumbRemove($f); + + foreach ($this->thumb_sizes as $suffix => $s) { + if ($s[0] > 0 && ($suffix == 'sq' || $w > $s[0] || $h > $s[0])) { + $img->resize($s[0],$s[0],$s[1]); + $img->output('jpeg',sprintf($thumb,$suffix),80); + } + } + $img->close(); + } + catch (Exception $e) + { + if ($cur === null) { # Called only if cursor is null (public call) + throw $e; + } + } + } + + protected function imageThumbUpdate(&$file,&$newFile) + { + if ($file->relname != $newFile->relname) + { + $p = path::info($file->relname); + $thumb_old = sprintf($this->thumb_tp,$p['dirname'],$p['base'],'%s'); + + $p = path::info($newFile->relname); + $thumb_new = sprintf($this->thumb_tp,$p['dirname'],$p['base'],'%s'); + + foreach ($this->thumb_sizes as $suffix => $s) { + try { + parent::moveFile(sprintf($thumb_old,$suffix),sprintf($thumb_new,$suffix)); + } catch (Exception $e) {} + } + } + } + + protected function imageThumbRemove($f) + { + $p = path::info($f); + $thumb = sprintf($this->thumb_tp,'',$p['base'],'%s'); + + foreach ($this->thumb_sizes as $suffix => $s) { + try { + parent::removeFile(sprintf($thumb,$suffix)); + } catch (Exception $e) {} + } + } + + protected function imageMetaCreate(&$cur,$f,$id) + { + $file = $this->pwd.'/'.$f; + + if (!file_exists($file)) { + return false; + } + + $xml = new xmlTag('meta'); + $meta = imageMeta::readMeta($file); + $xml->insertNode($meta); + + $c = $this->core->con->openCursor($this->table); + $c->media_meta = $xml->toXML(); + + if ($cur->media_title !== null && $cur->media_title == basename($cur->media_file)) + { + if ($meta['Title']) { + $c->media_title = $meta['Title']; + } + } + + if ($meta['DateTimeOriginal'] && $cur->media_dt === '') + { + # We set picture time to user timezone + $media_ts = strtotime($meta['DateTimeOriginal']); + if ($media_ts !== false) { + $o = dt::getTimeOffset($this->core->auth->getInfo('user_tz'),$media_ts); + $c->media_dt = dt::str('%Y-%m-%d %H:%M:%S',$media_ts+$o); + } + } + + $c->update('WHERE media_id = '.$id); + } + + /** + Returns HTML code for MP3 player + + @param url string MP3 URL to play + @param player string Player URL + @param args array Player parameters + @return string + */ + public static function mp3player($url,$player=null,$args=null) + { + if (!$player) { + $player = 'player_mp3.swf'; + } + + if (!is_array($args)) + { + $args = array( + 'showvolume' => 1, + 'loadingcolor' => 'ff9900', + 'bgcolor1' => 'eeeeee', + 'bgcolor2' => 'cccccc', + 'buttoncolor' => '0066cc', + 'buttonovercolor' => 'ff9900', + 'slidercolor1' => 'cccccc', + 'slidercolor2' => '999999', + 'sliderovercolor' => '0066cc' + ); + } + + $args['mp3'] = $url; + + if (empty($args['width'])) { + $args['width'] = 200; + } + if (empty($args['height'])) { + $args['height'] = 20; + } + + $vars = array(); + foreach ($args as $k => $v) { + $vars[] = $k.'='.$v; + } + + return + ''. + ''. + ''. + ''. + ''; + } + + public static function flvplayer($url,$player=null,$args=null) + { + if (!$player) { + $player = 'player_flv.swf'; + } + + if (!is_array($args)) + { + $args = array( + 'margin' => 1, + 'showvolume' => 1, + 'showtime' => 1, + 'showfullscreen' => 1, + 'buttonovercolor' => 'ff9900', + 'slidercolor1' => 'cccccc', + 'slidercolor2' => '999999', + 'sliderovercolor' => '0066cc' + ); + } + + $args['flv'] = $url; + + if (empty($args['width'])) { + $args['width'] = 400; + } + if (empty($args['height'])) { + $args['height'] = 300; + } + + $vars = array(); + foreach ($args as $k => $v) { + $vars[] = $k.'='.$v; + } + + return + ''. + ''. + ''. + ''. + ''. + ''; + } +} +?> diff --git a/inc/core/class.dc.modules.php b/inc/core/class.dc.modules.php new file mode 100644 index 0000000..c916c69 --- /dev/null +++ b/inc/core/class.dc.modules.php @@ -0,0 +1,519 @@ +dcCore dcCore instance + + /** + Object constructor. + + @param core dcCore dcCore instance + */ + public function __construct(&$core) + { + $this->core =& $core; + } + + /** + Loads modules. $path could be a separated list of paths + (path separator depends on your OS). + + $ns indicates if an additionnal file needs to be loaded on plugin + load, value could be: + - admin (loads module's _admin.php) + - public (loads module's _public.php) + - xmlrpc (loads module's _xmlrpc.php) + + $lang indicates if we need to load a lang file on plugin + loading. + */ + public function loadModules($path,$ns=null,$lang=null) + { + $this->path = explode(PATH_SEPARATOR,$path); + $this->ns = $ns; + + foreach ($this->path as $root) + { + if (!is_dir($root) || !is_readable($root)) { + continue; + } + + if (substr($root,-1) != '/') { + $root .= '/'; + } + + if (($d = @dir($root)) === false) { + continue; + } + + while (($entry = $d->read()) !== false) + { + $full_entry = $root.'/'.$entry; + + if ($entry != '.' && $entry != '..' && is_dir($full_entry) + && file_exists($full_entry.'/_define.php')) + { + if (!file_exists($full_entry.'/_disabled')) + { + $this->id = $entry; + $this->mroot = $full_entry; + require $full_entry.'/_define.php'; + $this->id = null; + $this->mroot = null; + } + else + { + $this->disabled[$entry] = array( + 'root' => $full_entry, + 'root_writable' => is_writable($full_entry) + ); + } + } + } + $d->close(); + } + + # Sort plugins + uasort($this->modules,array($this,'sortModules')); + + # Load translation, _prepend and ns_file + foreach ($this->modules as $id => $m) + { + if (file_exists($m['root'].'/_prepend.php')) + { + $r = require $m['root'].'/_prepend.php'; + + # If _prepend.php file returns null (ie. it has a void return statement) + if (is_null($r)) { + continue; + } + unset($r); + } + + $this->loadModuleL10N($id,$lang,'main'); + if ($ns == 'admin') { + $this->loadModuleL10Nresources($id,$lang); + } + $this->loadNsFile($id,$ns); + } + } + + public function requireDefine($dir,$id) + { + if (file_exists($dir.'/_define.php')) { + $this->id = $id; + require $dir.'/_define.php'; + $this->id = null; + } + } + + /** + This method registers a module in modules list. You should use this to + register a new module. + + $permissions is a comma separated list of permissions for your + module. If $permissions is null, only super admin has access to + this module. + + $priority is an integer. Modules are sorted by priority and name. + Lowest priority comes first. + + @param name string Module name + @param desc string Module description + @param author string Module author name + @param version string Module version + @param permissions string Module permissions + @param priority integer Module priority + */ + public function registerModule($name,$desc,$author,$version,$permissions=null,$priority=1000) + { + if ($this->ns == 'admin') { + if ($permissions == '' && !$this->core->auth->isSuperAdmin()) { + return; + } elseif (!$this->core->auth->check($permissions,$this->core->blog->id)) { + return; + } + } + + if ($this->id) { + $this->modules[$this->id] = array( + 'root' => $this->mroot, + 'name' => $name, + 'desc' => $desc, + 'author' => $author, + 'version' => $version, + 'permissions' => $permissions, + 'priority' => $priority === null ? 1000 : (integer) $priority, + 'root_writable' => is_writable($this->mroot) + ); + } + } + + public function resetModulesList() + { + $this->modules = array(); + } + + public static function installPackage($zip_file,dcModules &$modules) + { + $zip = new fileUnzip($zip_file); + $zip->getList(false,'#(^|/)(__MACOSX|\.svn|\.DS_Store|Thumbs\.db)(/|$)#'); + + $zip_root_dir = $zip->getRootDir(); + $define = ''; + if ($zip_root_dir != false) { + $target = dirname($zip_file); + $destination = $target.'/'.$zip_root_dir; + $define = $zip_root_dir.'/_define.php'; + $has_define = $zip->hasFile($define); + } else { + $target = dirname($zip_file).'/'.preg_replace('/\.([^.]+)$/','',basename($zip_file)); + $destination = $target; + $define = '_define.php'; + $has_define = $zip->hasFile($define); + } + + if ($zip->isEmpty()) { + $zip->close(); + unlink($zip_file); + throw new Exception(__('Empty module zip file.')); + } + + if (!$has_define) { + $zip->close(); + unlink($zip_file); + throw new Exception(__('The zip file does not appear to be a valid Dotclear module.')); + } + + $ret_code = 1; + + if (is_dir($destination)) + { + # test for update + $sandbox = clone $modules; + $zip->unzip($define, $target.'/_define.php'); + + $sandbox->resetModulesList(); + $sandbox->requireDefine($target,basename($destination)); + unlink($target.'/_define.php'); + $new_modules = $sandbox->getModules(); + + if (!empty($new_modules)) + { + $tmp = array_keys($new_modules); + $id = $tmp[0]; + $cur_module = $modules->getModules($id); + if (!empty($cur_module) && $new_modules[$id]['version'] != $cur_module['version']) + { + # delete old module + if (!files::deltree($destination)) { + throw new Exception(__('An error occurred during module deletion.')); + } + $ret_code = 2; + } + else + { + $zip->close(); + unlink($zip_file); + throw new Exception(sprintf(__('Unable to upgrade "%s". (same version)'),basename($destination))); + } + } + else + { + $zip->close(); + unlink($zip_file); + throw new Exception(sprintf(__('Unable to read new _define.php file'))); + } + } + $zip->unzipAll($target); + $zip->close(); + unlink($zip_file); + return $ret_code; + } + + /** + This method installs all modules having a _install file. + + @see dcModules::installModule + */ + public function installModules() + { + $res = array('success'=>array(),'failure'=>array()); + foreach ($this->modules as $id => &$m) + { + $i = $this->installModule($id,$msg); + if ($i === true) { + $res['success'][$id] = true; + } elseif ($i === false) { + $res['failure'][$id] = $msg; + } + } + + return $res; + } + + /** + This method installs module with ID $id and having a _install + file. This file should throw exception on failure or true if it installs + successfully. + + $msg is an out parameter that handle installer message. + + @param id string Module ID + @param msg string Module installer message + @return boolean + */ + public function installModule($id,&$msg) + { + try { + $i = $this->loadModuleFile($this->modules[$id]['root'].'/_install.php'); + if ($i === true) { + return true; + } + } catch (Exception $e) { + $msg = $e->getMessage(); + return false; + } + + return null; + } + + public function deleteModule($id,$disabled=false) + { + if ($disabled) { + $p =& $this->disabled; + } else { + $p =& $this->modules; + } + + if (!isset($p[$id])) { + throw new Exception(__('No such module.')); + } + + if (!files::deltree($p[$id]['root'])) { + throw new Exception(__('Cannot remove module files')); + } + } + + public function deactivateModule($id) + { + if (!isset($this->modules[$id])) { + throw new Exception(__('No such module.')); + } + + if (!$this->modules[$id]['root_writable']) { + throw new Exception(__('Cannot deactivate plugin.')); + } + + if (@file_put_contents($this->modules[$id]['root'].'/_disabled','')) { + throw new Exception(__('Cannot deactivate plugin.')); + } + } + + public function activateModule($id) + { + if (!isset($this->disabled[$id])) { + throw new Exception(__('No such module.')); + } + + if (!$this->disabled[$id]['root_writable']) { + throw new Exception(__('Cannot activate plugin.')); + } + + if (@unlink($this->disabled[$id]['root'].'/_disabled') === false) { + throw new Exception(__('Cannot activate plugin.')); + } + } + + /** + This method will search for file $file in language + $lang for module $id. + + $file should not have any extension. + + @param id string Module ID + @param lang string Language code + @param file string File name (without extension) + */ + public function loadModuleL10N($id,$lang,$file) + { + if (!$lang || !isset($this->modules[$id])) { + return; + } + + $lfile = $this->modules[$id]['root'].'/locales/%s/%s'; + if (l10n::set(sprintf($lfile,$lang,$file)) === false && $lang != 'en') { + l10n::set(sprintf($lfile,'en',$file)); + } + } + + public function loadModuleL10Nresources($id,$lang) + { + if (!$lang || !isset($this->modules[$id])) { + return; + } + + $f = l10n::getFilePath($this->modules[$id]['root'].'/locales','resources.php',$lang); + if ($f) { + $this->loadModuleFile($f); + } + } + + /** + Returns all modules associative array or only one module if $id + is present. + + @param id string Optionnal module ID + @return array + */ + public function getModules($id=null) + { + if ($id && isset($this->modules[$id])) { + return $this->modules[$id]; + } + return $this->modules; + } + + /** + Returns true if the module with ID $id exists. + + @param id string Module ID + @return boolean + */ + public function moduleExists($id) + { + return isset($this->modules[$id]); + } + + /** + Returns all disabled modules in an array + + @return array + */ + public function getDisabledModules() + { + return $this->disabled; + } + + /** + Returns root path for module with ID $id. + + @param id string Module ID + @return string + */ + public function moduleRoot($id) + { + return $this->moduleInfo($id,'root'); + } + + /** + Returns a module information that could be: + - root + - name + - desc + - author + - version + - permissions + - priority + + @param id string Module ID + @param info string Information to retrieve + @return string + */ + public function moduleInfo($id,$info) + { + return isset($this->modules[$id][$info]) ? $this->modules[$id][$info] : null; + } + + /** + Loads namespace $ns specific files for all modules. + + @param ns string Namespace name + */ + public function loadNsFiles($ns=null) + { + foreach ($this->modules as $k => $v) { + $this->loadNsFile($k,$ns); + } + } + + /** + Loads namespace $ns specific file for module with ID + $id + + @param id string Module ID + @param ns string Namespace name + */ + public function loadNsFile($id,$ns=null) + { + switch ($ns) { + case 'admin': + $this->loadModuleFile($this->modules[$id]['root'].'/_admin.php'); + break; + case 'public': + $this->loadModuleFile($this->modules[$id]['root'].'/_public.php'); + break; + case 'xmlrpc': + $this->loadModuleFile($this->modules[$id]['root'].'/_xmlrpc.php'); + break; + } + } + + protected function loadModuleFile($________) + { + if (!file_exists($________)) { + return; + } + + self::$_k = array_keys($GLOBALS); + + foreach (self::$_k as self::$_n) { + if (!in_array(self::$_n,self::$superglobals)) { + global ${self::$_n}; + } + } + + return require $________; + } + + private function sortModules($a,$b) + { + if ($a['priority'] == $b['priority']) { + return strcasecmp($a['name'],$b['name']); + } + + return ($a['priority'] < $b['priority']) ? -1 : 1; + } +} +?> \ No newline at end of file diff --git a/inc/core/class.dc.rest.php b/inc/core/class.dc.rest.php new file mode 100644 index 0000000..b547679 --- /dev/null +++ b/inc/core/class.dc.rest.php @@ -0,0 +1,52 @@ +dcCore dcCore instance + */ + public function __construct(&$core) + { + parent::__construct(); + + $this->core =& $core; + } + + /** + Rest method call. + + @param name string Method name + @param get array GET parameters copy + @param post array POST parameters copy + @return mixed Rest method result + */ + protected function callFunction($name,$get,$post) + { + if (isset($this->functions[$name])) { + return call_user_func($this->functions[$name],$this->core,$get,$post); + } + } +} +?> \ No newline at end of file diff --git a/inc/core/class.dc.rs.extensions.php b/inc/core/class.dc.rs.extensions.php new file mode 100644 index 0000000..d17c81e --- /dev/null +++ b/inc/core/class.dc.rs.extensions.php @@ -0,0 +1,815 @@ +boolean + */ + public static function isEditable(&$rs) + { + # If user is admin or contentadmin, true + if ($rs->core->auth->check('contentadmin',$rs->core->blog->id)) { + return true; + } + + # No user id in result ? false + if (!$rs->exists('user_id')) { + return false; + } + + # If user is usage and owner of the entrie + if ($rs->core->auth->check('usage',$rs->core->blog->id) + && $rs->user_id == $rs->core->auth->userID()) { + return true; + } + + return false; + } + + /** + Returns whether post is deletable + + @param rs Invisible parameter + @return boolean + */ + public static function isDeletable(&$rs) + { + # If user is admin, or contentadmin, true + if ($rs->core->auth->check('contentadmin',$rs->core->blog->id)) { + return true; + } + + # No user id in result ? false + if (!$rs->exists('user_id')) { + return false; + } + + # If user has delete rights and is owner of the entrie + if ($rs->core->auth->check('delete',$rs->core->blog->id) + && $rs->user_id == $rs->core->auth->userID()) { + return true; + } + + return false; + } + + /** + Returns whether post is the first one of its day. + + @param rs Invisible parameter + @return boolean + */ + public static function firstPostOfDay(&$rs) + { + if ($rs->isStart()) { + return true; + } + + $cdate = date('Ymd',strtotime($rs->post_dt)); + $rs->movePrev(); + $ndate = date('Ymd',strtotime($rs->post_dt)); + $rs->moveNext(); + return $ndate != $cdate; + } + + /** + Returns whether post is the last one of its day. + + @param rs Invisible parameter + @return boolean + */ + public static function lastPostOfDay(&$rs) + { + if ($rs->isEnd()) { + return true; + } + + $cdate = date('Ymd',strtotime($rs->post_dt)); + $rs->moveNext(); + $ndate = date('Ymd',strtotime($rs->post_dt)); + $rs->movePrev(); + return $ndate != $cdate; + } + + /** + Returns whether comments are enabled on post. + + @param rs Invisible parameter + @return boolean + */ + public static function commentsActive(&$rs) + { + return + $rs->core->blog->settings->allow_comments + && $rs->post_open_comment + && ($rs->core->blog->settings->comments_ttl == 0 || + time()-($rs->core->blog->settings->comments_ttl*86400) < $rs->getTS()); + } + + /** + Returns whether trackbacks are enabled on post. + + @param rs Invisible parameter + @return boolean + */ + public static function trackbacksActive(&$rs) + { + return + $rs->core->blog->settings->allow_trackbacks + && $rs->post_open_tb + && ($rs->core->blog->settings->trackbacks_ttl == 0 || + time()-($rs->core->blog->settings->trackbacks_ttl*86400) < $rs->getTS()); + } + + /** + Returns whether post has at least one comment. + + @param rs Invisible parameter + @return boolean + */ + public static function hasComments(&$rs) + { + return $rs->nb_comment > 0; + } + + /** + Returns whether post has at least one trackbacks. + + @return boolean + */ + public static function hasTrackbacks(&$rs) + { + return $rs->nb_trackback > 0; + } + + /** + Returns full post URL. + + @param rs Invisible parameter + @return string + */ + public static function getURL(&$rs) + { + return $rs->core->blog->url.$rs->core->getPostPublicURL( + $rs->post_type,html::sanitizeURL($rs->post_url) + ); + } + + /** + Returns full post category URL. + + @param rs Invisible parameter + @return string + */ + public static function getCategoryURL(&$rs) + { + return $rs->core->blog->url.$rs->core->url->getBase('category').'/'. + html::sanitizeURL($rs->cat_url); + } + + /** + Returns whether post has an excerpt. + + @param rs Invisible parameter + @return boolean + */ + public static function isExtended(&$rs) + { + return $rs->post_excerpt_xhtml != ''; + } + + /** + Returns post timestamp. + + @param rs Invisible parameter + @return integer + */ + public static function getTS(&$rs) + { + return strtotime($rs->post_dt); + } + + /** + Returns post date formating according ISO 8601 standard. + + @param rs Invisible parameter + @return string + */ + public static function getISO8601Date(&$rs) + { + return dt::iso8601($rs->getTS(),$rs->post_tz); + } + + /** + Returns post date formating according RFC 822. + + @param rs Invisible parameter + @return string + */ + public static function getRFC822Date(&$rs) + { + return dt::rfc822($rs->getTS(),$rs->post_tz); + } + + /** + Returns post date with $format as formatting pattern. If format + is empty, uses date_format blog setting. + + @param rs Invisible parameter + @param format string Date format pattern + @return string + */ + public static function getDate(&$rs,$format) + { + if ($format) { + return dt::dt2str($format,$rs->post_dt); + } else { + return dt::dt2str($rs->core->blog->settings->date_format,$rs->post_dt); + } + } + + /** + Returns post time with $format as formatting pattern. If format + is empty, uses time_format blog setting. + + @param rs Invisible parameter + @param format string Time format pattern + @return string + */ + public static function getTime(&$rs,$format) + { + if ($format) { + return dt::dt2str($format,$rs->post_dt); + } else { + return dt::dt2str($rs->core->blog->settings->time_format,$rs->post_dt); + } + } + + /** + Returns author common name using user_id, user_name, user_firstname and + user_displayname fields. + + @param rs Invisible parameter + @return string + */ + public static function getAuthorCN(&$rs) + { + return dcUtils::getUserCN($rs->user_id, $rs->user_name, + $rs->user_firstname, $rs->user_displayname); + } + + /** + Returns author common name with a link if he specified one in its + preferences. + + @param rs Invisible parameter + @return string + */ + public static function getAuthorLink(&$rs) + { + $res = '%1$s'; + $url = $rs->user_url; + if ($url) { + $res = '%1$s'; + } + + return sprintf($res,html::escapeHTML($rs->getAuthorCN()),html::escapeHTML($url)); + } + + /** + Returns author e-mail address. If $encoded is true, "@" sign is + replaced by "%40" and "." by "%2e". + + @param rs Invisible parameter + @param encoded boolean Encode address. + @return string + */ + public static function getAuthorEmail(&$rs,$encoded=true) + { + if ($encoded) { + return strtr($rs->user_email,array('@'=>'%40','.'=>'%2e')); + } + return $rs->user_email; + } + + /** + Returns post feed unique ID. + + @param rs Invisible parameter + @return string + */ + public static function getFeedID(&$rs) + { + return 'urn:md5:'.md5($rs->core->blog->uid.$rs->post_id); + + $url = parse_url($rs->core->blog->url); + $date_part = date('Y-m-d',strtotime($rs->post_creadt)); + + return 'tag:'.$url['host'].','.$date_part.':'.$rs->post_id; + } + + /** + Returns trackback RDF information block in HTML comment. + + @param rs Invisible parameter + @return string + */ + public static function getTrackbackData(&$rs) + { + return + "\n"; + } + + /** + Returns post trackback full URL. + + @param rs Invisible parameter + @return string + */ + public static function getTrackbackLink(&$rs) + { + return $rs->core->blog->url.$rs->core->url->getBase('trackback').'/'.$rs->post_id; + } + + /** + Returns post content. If $absolute_urls is true, appends full + blog URL to each relative post URLs. + + @param rs Invisible parameter + @param absolute_urls boolean With absolute URLs + @return string + */ + public static function getContent(&$rs,$absolute_urls=false) + { + if ($absolute_urls) { + return html::absoluteURLs($rs->post_content_xhtml,$rs->getURL()); + } else { + return $rs->post_content_xhtml; + } + } + + /** + Returns post excerpt. If $absolute_urls is true, appends full + blog URL to each relative post URLs. + + @param rs Invisible parameter + @param absolute_urls boolean With absolute URLs + @return string + */ + public static function getExcerpt(&$rs,$absolute_urls=false) + { + if ($absolute_urls) { + return html::absoluteURLs($rs->post_excerpt_xhtml,$rs->getURL()); + } else { + return $rs->post_excerpt_xhtml; + } + } + + /** + Returns post media count using a subquery. + + @param rs Invisible parameter + @return integer + */ + public static function countMedia(&$rs) + { + if (isset($rs->_nb_media[$rs->index()])) + { + return $rs->_nb_media[$rs->index()]; + } + else + { + $strReq = + 'SELECT count(media_id) '. + 'FROM '.$rs->core->prefix.'post_media '. + 'WHERE post_id = '.(integer) $rs->post_id.' '; + + $res = (integer) $rs->core->con->select($strReq)->f(0); + $rs->_nb_media[$rs->index()] = $res; + return $res; + } + } +} + +/** +@ingroup DC_CORE +@brief Dotclear comment record helpers. + +This class adds new methods to database comment results. +You can call them on every record comming from dcBlog::getComments and similar +methods. + +@warning You should not give the first argument (usualy $rs) of every described +function. +*/ +class rsExtComment +{ + /** + Returns comment date with $format as formatting pattern. If + format is empty, uses date_format blog setting. + + @param rs Invisible parameter + @param format string Date format pattern + @return string + */ + public static function getDate(&$rs,$format) + { + if ($format) { + return dt::dt2str($format,$rs->comment_dt); + } else { + return dt::dt2str($rs->core->blog->settings->date_format,$rs->comment_dt); + } + } + + /** + Returns comment time with $format as formatting pattern. If + format is empty, uses time_format blog setting. + + @param rs Invisible parameter + @param format string Date format pattern + @return string + */ + public static function getTime(&$rs,$format) + { + if ($format) { + return dt::dt2str($format,$rs->comment_dt); + } else { + return dt::dt2str($rs->core->blog->settings->time_format,$rs->comment_dt); + } + } + + /** + Returns comment timestamp. + + @param rs Invisible parameter + @return integer + */ + public static function getTS(&$rs) + { + return strtotime($rs->comment_dt); + } + + /** + Returns comment date formating according ISO 8601 standard. + + @param rs Invisible parameter + @return string + */ + public static function getISO8601Date(&$rs) + { + return dt::iso8601($rs->getTS(),$rs->comment_tz); + } + + /** + Returns comment date formating according RFC 822. + + @param rs Invisible parameter + @return string + */ + public static function getRFC822Date(&$rs) + { + return dt::rfc822($rs->getTS(),$rs->comment_tz); + } + + /** + Returns comment content. If $absolute_urls is true, appends full + blog URL to each relative post URLs. + + @param rs Invisible parameter + @param absolute_urls boolean With absolute URLs + @return string + */ + public static function getContent(&$rs,$absolute_urls=false) + { + $res = $rs->comment_content; + + if ($rs->core->blog->settings->comments_nofollow) { + $res = preg_replace_callback('##ms',array('self','noFollowURL'),$res); + } + + if ($absolute_urls) { + $res = html::absoluteURLs($res,$rs->getPostURL()); + } + + return $res; + } + + private static function noFollowURL($m) + { + if (preg_match('/rel="nofollow"/',$m[1])) { + return $m[0]; + } + + return ''; + } + + /** + Returns comment author link to his website if he specified one. + + @param rs Invisible parameter + @return string + */ + public static function getAuthorURL(&$rs) + { + if (trim($rs->comment_site)) { + return trim($rs->comment_site); + } + } + + /** + Returns comment post full URL. + + @param rs Invisible parameter + @return string + */ + public static function getPostURL(&$rs) + { + return $rs->core->blog->url.$rs->core->getPostPublicURL( + $rs->post_type,html::sanitizeURL($rs->post_url) + ); + } + + /** + Returns comment author name in a link to his website if he specified one. + + @param rs Invisible parameter + @return string + */ + public static function getAuthorLink(&$rs) + { + $res = '%1$s'; + $url = $rs->getAuthorURL(); + if ($url) { + $res = '%1$s'; + } + + $nofollow = ''; + if ($rs->core->blog->settings->comments_nofollow) { + $nofollow = ' rel="nofollow"'; + } + + return sprintf($res,html::escapeHTML($rs->comment_author),html::escapeHTML($url),$nofollow); + } + + /** + Returns comment author e-mail address. If $encoded is true, + "@" sign is replaced by "%40" and "." by "%2e". + + @param rs Invisible parameter + @param encoded boolean Encode address. + @return string + */ + public static function getEmail(&$rs,$encoded=true) + { + if ($encoded) { + return strtr($rs->comment_email,array('@'=>'%40','.'=>'%2e')); + } + return $rs->comment_email; + } + + /** + Returns trackback site title if comment is a trackback. + + @param rs Invisible parameter + @return string + */ + public static function getTrackbackTitle(&$rs) + { + if ($rs->comment_trackback == 1 && + preg_match('|

    (.*?)

    |msU',$rs->comment_content, + $match)) { + return html::decodeEntities($match[1]); + } + } + + /** + Returns trackback content if comment is a trackback. + + @param rs Invisible parameter + @return string + */ + public static function getTrackbackContent(&$rs) + { + if ($rs->comment_trackback == 1) { + return preg_replace('|

    .*?

    |msU','', + $rs->comment_content); + } + } + + /** + Returns comment feed unique ID. + + @param rs Invisible parameter + @return string + */ + public static function getFeedID(&$rs) + { + return 'urn:md5:'.md5($rs->core->blog->uid.$rs->comment_id); + + $url = parse_url($rs->core->blog->url); + $date_part = date('Y-m-d',strtotime($rs->comment_dt)); + + return 'tag:'.$url['host'].','.$date_part.':'.$rs->comment_id; + } + + /** + Returns whether comment is from the post author. + + @param rs Invisible parameter + @return boolean + */ + public static function isMe(&$rs) + { + return + $rs->comment_email && $rs->comment_site && + $rs->comment_email == $rs->user_email && + $rs->comment_site == $rs->user_url; + } +} + +/** +@ingroup DC_CORE +@brief Dotclear dates record helpers. + +This class adds new methods to database dates results. +You can call them on every record comming from dcBlog::getDates. + +@warning You should not give the first argument (usualy $rs) of every described +function. +*/ +class rsExtDates +{ + /** + @param rs Invisible parameter + @return integer Date timestamp + */ + public static function ts(&$rs) + { + return strtotime($rs->dt); + } + + /** + @param rs Invisible parameter + @return string Date year + */ + public static function year(&$rs) + { + return date('Y',strtotime($rs->dt)); + } + + /** + @param rs Invisible parameter + @return string Date month + */ + public static function month(&$rs) + { + return date('m',strtotime($rs->dt)); + } + + /** + @param rs Invisible parameter + @return integer Date day + */ + public static function day(&$rs) + { + return date('d',strtotime($rs->dt)); + } + + /** + Returns date month archive full URL. + + @param rs Invisible parameter + @param core dcCore dcCore instance + @return integer + */ + public static function url(&$rs,&$core) + { + $url = date('Y/m',strtotime($rs->dt)); + + return $core->blog->url.$core->url->getBase('archive').'/'.$url; + } + + /** + Returns whether date is the first of year. + + @param rs Invisible parameter + @return boolean + */ + public static function yearHeader(&$rs) + { + if ($rs->isStart()) { + return true; + } + + $y = $rs->year(); + $rs->movePrev(); + $py = $rs->year(); + $rs->moveNext(); + + return $y != $py; + } + + /** + Returns whether date is the last of year. + + @param rs Invisible parameter + @return boolean + */ + public static function yearFooter(&$rs) + { + if ($rs->isEnd()) { + return true; + } + + $y = $rs->year(); + if ($rs->moveNext()) { + $ny = $rs->year(); + $rs->movePrev(); + return $y != $ny; + } + return false; + + } +} + +/** +@ingroup DC_CORE +@brief Dotclear dates record helpers. + +This class adds new methods to database dates results. +You can call them on every record comming from dcAuth::checkUser and +dcCore::getUsers. + +@warning You should not give the first argument (usualy $rs) of every described +function. +*/ +class rsExtUser +{ + /** + Returns a user option. + + @param rs Invisible parameter + @param name string Option name + @return string + */ + public static function option(&$rs,$name) + { + $options = self::options($rs); + + if (isset($options[$name])) { + return $options[$name]; + } + return null; + } + + /** + Returns all user options. + + @param rs Invisible parameter + @return array + */ + public static function options(&$rs) + { + $options = @unserialize($rs->user_options); + if (is_array($options)) { + return $options; + } + return array(); + } +} +?> \ No newline at end of file diff --git a/inc/core/class.dc.settings.php b/inc/core/class.dc.settings.php new file mode 100644 index 0000000..19f832b --- /dev/null +++ b/inc/core/class.dc.settings.php @@ -0,0 +1,330 @@ +connection Database connection object + protected $table; ///< string Permission table name + protected $blog_id; ///< string Blog ID + + protected $settings = array(); ///< array Associative settings array + protected $global_settings = array(); ///< array Global settings array + protected $local_settings = array(); ///< array Local settings array + + protected $ns; ///< string Current namespace + + /** + Object constructor. Retrieves blog settings and puts them in $settings + array. Local (blog) settings have a highest priority than global settings. + + @param core dcCore dcCore object + @param blog_id string Blog ID + */ + public function __construct(&$core,$blog_id) + { + $this->con =& $core->con; + $this->table = $core->prefix.'setting'; + $this->blog_id =& $blog_id; + + $this->getSettings(); + } + + private function getSettings() + { + $strReq = 'SELECT blog_id, setting_id, setting_ns, setting_value, '. + 'setting_type, setting_label '. + 'FROM '.$this->table.' '. + "WHERE blog_id = '".$this->con->escape($this->blog_id)."' ". + 'OR blog_id IS NULL '. + 'ORDER BY setting_ns, setting_id DESC '; + + try { + $rs = $this->con->select($strReq); + } catch (Exception $e) { + trigger_error(__('Unable to retrieve settings:').' '.$this->con->error(), E_USER_ERROR); + } + + while ($rs->fetch()) + { + $id = trim($rs->f('setting_id')); + $value = $rs->f('setting_value'); + $type = $rs->f('setting_type'); + + if ($type == 'float' || $type == 'double') { + $type = 'float'; + } elseif ($type != 'boolean' && $type != 'integer') { + $type = 'string'; + } + + settype($value,$type); + + $array = $rs->blog_id ? 'local' : 'global'; + + $this->{$array.'_settings'}[$id] = array( + 'ns' => $rs->f('setting_ns'), + 'value' => $value, + 'type' => $type, + 'label' => (string) $rs->f('setting_label'), + 'global' => $rs->blog_id == '' + ); + } + + $this->settings = $this->global_settings; + + foreach ($this->local_settings as $id => $v) { + $this->settings[$id] = $v; + } + + return true; + } + + private function settingExists($id,$global=false) + { + $array = $global ? 'global' : 'local'; + return isset($this->{$array.'_settings'}[$id]); + } + + /** + Sets a working namespace. You should do this before adding any setting. + + @param ns string Namespace name + */ + public function setNamespace($ns) + { + if (preg_match('/^[a-zA-Z][a-zA-Z0-9]+$/',$ns)) { + $this->ns = $ns; + } else { + throw new Exception(sprintf(__('Invalid setting namespace: %s'),$ns)); + } + } + + /** + Creates or updates a setting. + + $type could be 'string', 'integer', 'float', 'boolean' or null. If $type is + null and setting exists, it will keep current setting type. + + $value_change allow you to not change setting. Useful if you need to change + a setting label or type and don't want to change its value. + + Don't forget to set namespace before calling this method. + + @param id string Setting ID + @param value mixed Setting value + @param type string Setting type + @param label string Setting label + @param value_change boolean Change setting value or not + @param global boolean Setting is global + */ + public function put($id,$value,$type=null,$label=null,$value_change=true,$global=false) + { + if (!$this->ns) { + throw new Exception(__('No namespace specified')); + } + + if (!preg_match('/^[a-zA-Z][a-zA-Z0-9_]+$/',$id)) { + throw new Exception(sprintf(__('%s is not a valid setting id'),$id)); + } + + # We don't want to change setting value + if (!$value_change) + { + if (!$global && $this->settingExists($id,false)) { + $value = $this->local_settings[$id]['value']; + } elseif ($this->settingExists($id,true)) { + $value = $this->global_settings[$id]['value']; + } + } + + # Setting type + if ($type == 'double') + { + $type = 'float'; + } + elseif ($type === null) + { + if (!$global && $this->settingExists($id,false)) { + $type = $this->local_settings[$id]['type']; + } elseif ($this->settingExists($id,true)) { + $type = $this->global_settings[$id]['type']; + } else { + $type = 'string'; + } + } + elseif ($type != 'boolean' && $type != 'integer' && $type != 'float') + { + $type = 'string'; + } + + # We don't change label + if ($label == null) + { + if (!$global && $this->settingExists($id,false)) { + $label = $this->local_settings[$id]['label']; + } elseif ($this->settingExists($id,true)) { + $label = $this->global_settings[$id]['label']; + } + } + + settype($value,$type); + + $cur = $this->con->openCursor($this->table); + $cur->setting_value = ($type == 'boolean') ? (string) (integer) $value : (string) $value; + $cur->setting_type = $type; + $cur->setting_label = $label; + + #If we are local, compare to global value + if (!$global && $this->settingExists($id,true)) + { + $g = $this->global_settings[$id]; + $same_setting = $g['ns'] == $this->ns && $g['value'] == $value + && $g['type'] == $type && $g['label'] == $label; + + # Drop setting if same value as global + if ($same_setting && $this->settingExists($id,false)) { + $this->drop($id); + } elseif ($same_setting) { + return; + } + } + + if ($this->settingExists($id,$global) && $this->ns == $this->settings[$id]['ns']) + { + if ($global) { + $where = 'WHERE blog_id IS NULL '; + } else { + $where = "WHERE blog_id = '".$this->con->escape($this->blog_id)."' "; + } + + $cur->update($where."AND setting_id = '".$this->con->escape($id)."' "); + } + else + { + $cur->setting_id = $id; + $cur->blog_id = $global ? null : $this->blog_id; + $cur->setting_ns = $this->ns; + + $cur->insert(); + } + } + + /** + Removes an existing setting. Namespace + + @param id string Setting ID + */ + public function drop($id) + { + $strReq = 'DELETE FROM '.$this->table.' '; + + if ($this->blog_id === null) { + $strReq .= 'WHERE blog_id IS NULL '; + } else { + $strReq .= "WHERE blog_id = '".$this->con->escape($this->blog_id)."' "; + } + + $strReq .= "AND setting_id = '".$this->con->escape($id)."' "; + + $this->con->execute($strReq); + } + + /** + Returns setting value if exists. + + @param n string Setting name + @return mixed + */ + public function get($n) + { + if (isset($this->settings[$n]['value'])) { + return $this->settings[$n]['value']; + } + + return null; + } + + /** + Magic __get method. + @copydoc ::get + */ + public function __get($n) + { + return $this->get($n); + } + + /** + Sets a setting in $settings property. This sets the setting for script + execution time only and if setting exists. + + @param n string Setting name + @param v mixed Setting value + */ + public function set($n,$v) + { + if (isset($this->settings[$n])) { + $this->settings[$n]['value'] = $v; + } else { + $this->settings[$n] = array( + 'ns' => $this->ns, + 'value' => $v, + 'type' => gettype($n), + 'label' => '', + 'global' => false + ); + } + } + + /** + Magic __set method. + @copydoc ::set + */ + public function __set($n,$v) + { + $this->set($n,$v); + } + + /** + Returns $settings property content. + + @return array + */ + public function dumpSettings() + { + return $this->settings; + } + + /** + Returns $global_settings property content. + + @return array + */ + public function dumpGlobalSettings() + { + return $this->global_settings; + } + + /** + @pre + toto + @endpre + */ +} +?> \ No newline at end of file diff --git a/inc/core/class.dc.themes.php b/inc/core/class.dc.themes.php new file mode 100644 index 0000000..f4d6989 --- /dev/null +++ b/inc/core/class.dc.themes.php @@ -0,0 +1,84 @@ +$parent is a optional value to indicate them inheritance. + If $parent is null / not set, we simply fall back to + the standard behavior, by using 'default'. + + $priority is an integer. Modules are sorted by priority and name. + Lowest priority comes first. This property is currently ignored when dealing + with themes. + + @param name string Module name + @param desc string Module description + @param author string Module author name + @param version string Module version + @param parent string Module parent + @param priority integer Module priority + */ + public function registerModule($name,$desc,$author,$version,$parent = null,$priority = 1000) + { + if ($this->id) { + $this->modules[$this->id] = array( + 'root' => $this->mroot, + 'name' => $name, + 'desc' => $desc, + 'author' => $author, + 'version' => $version, + 'parent' => $parent, + 'priority' => 1000, + 'root_writable' => is_writable($this->mroot) + ); + } + } + + /** + Loads namespace $ns specific file for module with ID + $id + Note : actually, only 'public' namespace is supported with themes. + + @param id string Module ID + @param ns string Namespace name + */ + public function loadNsFile($id,$ns=null) + { + switch ($ns) { + case 'public': + $parent = $this->modules[$id]['parent']; + if ($parent) { + // This is not a real cascade - since we don't call loadNsFile -, + // thus limiting inclusion process. + // TODO : See if we have to change this. + $this->loadModuleFile($this->modules[$parent]['root'].'/_public.php'); + } + $this->loadModuleFile($this->modules[$id]['root'].'/_public.php'); + break; + } + } +} +?> \ No newline at end of file diff --git a/inc/core/class.dc.trackback.php b/inc/core/class.dc.trackback.php new file mode 100644 index 0000000..61fd878 --- /dev/null +++ b/inc/core/class.dc.trackback.php @@ -0,0 +1,404 @@ +dcCore dcCore instance + public $table; ///< string done pings table name + + /** + Object constructor + + @param core dcCore dcCore instance + */ + public function __construct(&$core) + { + $this->core =& $core; + $this->con =& $this->core->con; + $this->table = $this->core->prefix.'ping'; + } + + /// @name Send trackbacks + //@{ + /** + Get all pings sent for a given post. + + @param post_id integer Post ID + @return record + */ + public function getPostPings($post_id) + { + $strReq = 'SELECT ping_url, ping_dt '. + 'FROM '.$this->table.' '. + 'WHERE post_id = '.(integer) $post_id; + + return $this->con->select($strReq); + } + + /** + Sends a ping to given $url. + + @param url string URL to ping + @param post_id integer Post ID + @param post_title string Post title + @param post_excerpt string Post excerpt + @param post_url string Post URL + */ + public function ping($url,$post_id,$post_title,$post_excerpt,$post_url) + { + if ($this->core->blog === null) { + return false; + } + + $post_id = (integer) $post_id; + + # Check for previously done trackback + $strReq = 'SELECT post_id, ping_url FROM '.$this->table.' '. + 'WHERE post_id = '.$post_id.' '. + "AND ping_url = '".$this->con->escape($url)."' "; + + $rs = $this->con->select($strReq); + + if (!$rs->isEmpty()) { + throw new Exception(sprintf(__('%s has still been pinged'),$url)); + } + + $data = array( + 'title' => $post_title, + 'excerpt' => $post_excerpt, + 'url' => $post_url, + 'blog_name' => trim(html::escapeHTML(html::clean($this->core->blog->name))) + //,'__debug' => false + ); + + # Ping + try + { + $http = self::initHttp($url,$path); + $http->post($path,$data,'UTF-8'); + $res = $http->getContent(); + } + catch (Exception $e) + { + throw new Exception(__('Unable to ping URL')); + } + + $pattern = + '|.*(.*)(.*)'. + '((.*)(.*))?'. + '|msU'; + + if (!preg_match($pattern,$res,$match)) + { + throw new Exception(sprintf(__('%s is not a ping URL'),$url)); + } + + $ping_error = trim($match[1]); + $ping_msg = (!empty($match[4])) ? $match[4] : ''; + + if ($ping_error != '0') { + throw new Exception(sprintf(__('%s, ping error:'),$url).' '.$ping_msg); + } else { + # Notify ping result in database + $cur = $this->con->openCursor($this->table); + $cur->post_id = $post_id; + $cur->ping_url = $url; + $cur->ping_dt = array('NOW()'); + + $cur->insert(); + } + } + //@} + + /// @name Receive trackbacks + //@{ + /** + Receives a trackback and insert it as a comment of given post. + + @param post_id integer Post ID + */ + public function receive($post_id) + { + header('Content-Type: text/xml; charset=UTF-8'); + if (empty($_POST)) { + http::head(405,'Method Not Allowed'); + echo + ''."\n". + "\n". + " 1\n". + " POST request needed\n". + ""; + return; + } + + $post_id = (integer) $post_id; + + $title = !empty($_POST['title']) ? $_POST['title'] : ''; + $excerpt = !empty($_POST['excerpt']) ? $_POST['excerpt'] : ''; + $url = !empty($_POST['url']) ? $_POST['url'] : ''; + $blog_name = !empty($_POST['blog_name']) ? $_POST['blog_name'] : ''; + $charset = ''; + $comment = ''; + + $err = false; + $msg = ''; + + if ($this->core->blog === null) + { + $err = true; + $msg = 'No blog.'; + } + elseif ($url == '') + { + $err = true; + $msg = 'URL parameter is required.'; + } + elseif ($blog_name == '') { + $err = true; + $msg = 'Blog name is required.'; + } + + if (!$err) + { + $post = $this->core->blog->getPosts(array('post_id'=>$post_id,'post_type'=>'')); + + if ($post->isEmpty()) + { + $err = true; + $msg = 'No such post.'; + } + elseif (!$post->trackbacksActive()) + { + $err = true; + $msg = 'Trackbacks are not allowed for this post or weblog.'; + } + } + + if (!$err) + { + $charset = self::getCharsetFromRequest(); + + if (!$charset) { + $charset = mb_detect_encoding($title.' '.$excerpt.' '.$blog_name, + 'UTF-8,ISO-8859-1,ISO-8859-2,ISO-8859-3,'. + 'ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,'. + 'ISO-8859-9,ISO-8859-10,ISO-8859-13,ISO-8859-14,ISO-8859-15'); + } + + if (strtolower($charset) != 'utf-8') { + $title = iconv($charset,'UTF-8',$title); + $excerpt = iconv($charset,'UTF-8',$excerpt); + $blog_name = iconv($charset,'UTF-8',$blog_name); + } + + $title = trim(html::clean($title)); + $title = html::decodeEntities($title); + $title = html::escapeHTML($title); + $title = text::cutString($title,60); + + $excerpt = trim(html::clean($excerpt)); + $excerpt = html::decodeEntities($excerpt); + $excerpt = preg_replace('/\s+/ms',' ',$excerpt); + $excerpt = text::cutString($excerpt,252); + $excerpt = html::escapeHTML($excerpt).'...'; + + $blog_name = trim(html::clean($blog_name)); + $blog_name = html::decodeEntities($blog_name); + $blog_name = html::escapeHTML($blog_name); + $blog_name = text::cutString($blog_name,60); + + $url = trim(html::clean($url)); + + if (!$blog_name) { + $blog_name = 'Anonymous blog'; + } + + $comment = + "\n". + '

    '.($title ? $title : $blog_name)."

    \n". + '

    '.$excerpt.'

    '; + + $cur = $this->core->con->openCursor($this->core->prefix.'comment'); + $cur->comment_author = (string) $blog_name; + $cur->comment_site = (string) $url; + $cur->comment_content = (string) $comment; + $cur->post_id = $post_id; + $cur->comment_trackback = 1; + $cur->comment_status = $this->core->blog->settings->trackbacks_pub ? 1 : -1; + $cur->comment_ip = http::realIP(); + + try + { + # --BEHAVIOR-- publicBeforeTrackbackCreate + $this->core->callBehavior('publicBeforeTrackbackCreate',$cur); + if ($cur->post_id) { + $comment_id = $this->core->blog->addComment($cur); + + # --BEHAVIOR-- publicAfterTrackbackCreate + $this->core->callBehavior('publicAfterTrackbackCreate',$cur,$comment_id); + } + } + catch (Exception $e) + { + $err = 1; + $msg = 'Something went wrong : '.$e->getMessage(); + } + } + + + $debug_trace = + " \n". + ' '.$title."\n". + ' '.$excerpt."\n". + ' '.$url."\n". + ' '.$blog_name."\n". + ' '.$charset."\n". + ' '.$comment."\n". + " \n"; + + $resp = + ''."\n". + "\n". + ' '.(integer) $err."\n"; + + if ($msg) { + $resp .= ' '.$msg."\n"; + } + + if (!empty($_POST['__debug'])) { + $resp .= $debug_trace; + } + + echo $resp.""; + } + //@} + + private static function initHttp($url,&$path) + { + $client = netHttp::initClient($url,$path); + $client->setTimeout(5); + $client->setUserAgent('Dotclear - http://www.dotclear.org/'); + $client->useGzip(false); + $client->setPersistReferers(false); + + return $client; + } + + private static function getCharsetFromRequest() + { + if (isset($_SERVER['CONTENT_TYPE'])) + { + if (preg_match('|charset=([a-zA-Z0-9-]+)|',$_SERVER['CONTENT_TYPE'],$m)) { + return $m[1]; + } + } + + return null; + } + + /// @name Trackbacks auto discovery + //@{ + /** + Returns an array containing all discovered trackbacks URLs in + $text. + + @param text string Input text + @return array + */ + public function discover($text) + { + $res = array(); + + foreach ($this->getTextLinks($text) as $link) + { + if (($url = $this->getPingURL($link)) !== null) { + $res[] = $url; + } + } + + return $res; + } + //@} + + private function getTextLinks($text) + { + $res = array(); + + # href attribute on "a" tags + if (preg_match_all('/]+)>/ms', $text, $match, PREG_SET_ORDER)) + { + for ($i = 0; $i]+)>/ms', $text, $match, PREG_SET_ORDER)) + { + for ($i = 0; $iget($path); + $page_content = $http->getContent(); + } + catch (Exception $e) + { + return false; + } + + $pattern_rdf = + '/.*?'. + ''. + '.*?<\/rdf:RDF>'. + '/ms'; + + preg_match_all($pattern_rdf,$page_content,$rdf_all,PREG_SET_ORDER); + + for ($i=0; $i \ No newline at end of file diff --git a/inc/core/class.dc.update.php b/inc/core/class.dc.update.php new file mode 100644 index 0000000..b99da14 --- /dev/null +++ b/inc/core/class.dc.update.php @@ -0,0 +1,465 @@ + null, + 'href' => null, + 'checksum' => null, + 'info' => null, + 'notify' => true + ); + + protected $cache_ttl = '-6 hours'; + protected $forced_files = array(); + + /** + Constructor + + @param url string Versions file URL + @param subject string Subject to check + @param version string Version type + @param cache_dir string Directory cache path + */ + public function __construct($url,$subject,$version,$cache_dir) + { + $this->url = $url; + $this->subject = $subject; + $this->version = $version; + $this->cache_file = $cache_dir.'/'.$subject.'-'.$version; + } + + /** + Checks for Dotclear updates. + Returns latest version if available or false. + + @param version string Current version to compare + @return string Latest version if available + */ + public function check($version) + { + $this->getVersionInfo(); + $v = $this->getVersion(); + if ($v && version_compare($version,$v,'<')) { + return $v; + } + + return false; + } + + public function getVersionInfo() + { + # Check cached file + if (is_readable($this->cache_file) && filemtime($this->cache_file) > strtotime($this->cache_ttl)) + { + $c = @file_get_contents($this->cache_file); + $c = @unserialize($c); + if (is_array($c)) { + $this->version_info = $c; + return; + } + } + + $cache_dir = dirname($this->cache_file); + $can_write = (!is_dir($cache_dir) && is_writable(dirname($cache_dir))) + || (!file_exists($this->cache_file) && is_writable($cache_dir)) + || is_writable($this->cache_file); + + # If we can't write file, don't bug host with queries + if (!$can_write) { + return; + } + + if (!is_dir($cache_dir)) { + try { + files::makeDir($cache_dir); + } catch (Exception $e) { + return; + } + } + + # Try to get latest version number + try + { + $path = ''; + $client = netHttp::initClient($this->url,$path); + if ($client !== false) { + $client->setTimeout(4); + $client->setUserAgent($_SERVER['HTTP_USER_AGENT']); + $client->get($path); + + $this->readVersion($client->getContent()); + } + } + catch (Exception $e) {} + + # Create cache + file_put_contents($this->cache_file,serialize($this->version_info)); + } + + public function getVersion() + { + return $this->version_info['version']; + } + + public function getFileURL() + { + return $this->version_info['href']; + } + + public function getInfoURL() + { + return $this->version_info['info']; + } + + public function getChecksum() + { + return $this->version_info['checksum']; + } + + public function getNotify() + { + return $this->version_info['notify']; + } + + public function getForcedFiles() + { + return $this->forced_files; + } + + public function setForcedFiles() + { + $this->forced_files = func_get_args(); + } + + /** + Sets notification flag. + */ + public function setNotify($n) + { + + if (!is_writable($this->cache_file)) { + return; + } + + $this->version_info['notify'] = (boolean) $n; + file_put_contents($this->cache_file,serialize($this->version_info)); + } + + public function checkIntegrity($digests_file,$root) + { + if (!$digests_file) { + throw new Exception(__('Digests file not found.')); + } + + $changes = $this->md5sum($root,$digests_file); + + if (!empty($changes)) { + $e = new Exception('Some files have changed.',self::ERR_FILES_CHANGED); + $e->bad_files = $changes; + throw $e; + } + + return true; + } + + /** + Downloads new version to destination $dest. + */ + public function download($dest) + { + $url = $this->getFileURL(); + + if (!$url) { + throw new Exception(__('No file to download')); + } + + if (!is_writable(dirname($dest))) { + throw new Exception(__('Root directory is not writable.')); + } + + try + { + $client = netHttp::initClient($url,$path); + $client->setTimeout(4); + $client->setUserAgent($_SERVER['HTTP_USER_AGENT']); + $client->useGzip(false); + $client->setPersistReferers(false); + $client->setOutput($dest); + $client->get($path); + + if ($client->getStatus() != 200) { + @unlink($dest); + throw new Exception(); + } + } + catch (Exception $e) + { + throw new Exception(__('An error occurred while downloading archive.')); + } + } + + /** + Checks if archive was successfully downloaded. + */ + public function checkDownload($zip) + { + $cs = $this->getChecksum(); + + return $cs && is_readable($zip) && md5_file($zip) == $cs; + } + + /** + Backups changed files before an update. + */ + public function backup($zip_file,$zip_digests,$root,$root_digests,$dest) + { + if (!is_readable($zip_file)) { + throw new Exception(__('Archive not found.')); + } + + if (!is_readable($root_digests)) { + @unlink($zip_file); + throw new Exception(__('Unable to read current digests file.')); + } + + # Stop everything if a backup already exists and can not be overrided + if (!is_writable(dirname($dest)) && !file_exists($dest)) { + throw new Exception(__('Root directory is not writable.')); + } + + if (file_exists($dest) && !is_writable($dest)) { + return false; + } + + $b_fp = @fopen($dest,'wb'); + if ($b_fp === false) { + return false; + } + + $zip = new fileUnzip($zip_file); + $b_zip = new fileZip($b_fp); + + if (!$zip->hasFile($zip_digests)) + { + @unlink($zip_file); + throw new Exception(__('Downloaded file seems not to be a valid archive.')); + } + + $opts = FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES; + $cur_digests = file($root_digests,$opts); + $new_digests = explode("\n",$zip->unzip($zip_digests)); + $new_files = $this->getNewFiles($cur_digests,$new_digests); + $zip->close(); + unset($opts,$cur_digests,$new_digests,$zip); + + $not_readable = array(); + + if (!empty($this->forced_files)) { + $new_files = array_merge($new_files,$this->forced_files); + } + + foreach ($new_files as $file) + { + if (!$file || !file_exists($root.'/'.$file)) { + continue; + } + + try { + $b_zip->addFile($root.'/'.$file,$file); + } catch (Exception $e) { + $not_readable[] = $file; + } + } + + # If only one file is not readable, stop everything now + if (!empty($not_readable)) { + $e = new Exception('Some files are not readable.',self::ERR_FILES_UNREADABLE); + $e->bad_files = $not_readable; + throw $e; + } + + $b_zip->write(); + fclose($b_fp); + $b_zip->close(); + + return true; + } + + /** + Upgrade process. + */ + public function performUpgrade($zip_file,$zip_digests,$zip_root,$root,$root_digests) + { + if (!is_readable($zip_file)) { + throw new Exception(__('Archive not found.')); + } + + if (!is_readable($root_digests)) { + @unlink($zip_file); + throw new Exception(__('Unable to read current digests file.')); + } + + $zip = new fileUnzip($zip_file); + + if (!$zip->hasFile($zip_digests)) + { + @unlink($zip_file); + throw new Exception(__('Downloaded file seems not to be a valid archive.')); + } + + $opts = FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES; + $cur_digests = file($root_digests,$opts); + $new_digests = explode("\n",$zip->unzip($zip_digests)); + $new_files = self::getNewFiles($cur_digests,$new_digests); + + if (!empty($this->forced_files)) { + $new_files = array_merge($new_files,$this->forced_files); + } + + $zip_files = array(); + $not_writable = array(); + + foreach ($new_files as $file) + { + if (!$file) { + continue; + } + + if (!$zip->hasFile($zip_root.'/'.$file)) { + @unlink($zip_file); + throw new Exception(__('Incomplete archive.')); + } + + $dest = $dest_dir = $root.'/'.$file; + while (!is_dir($dest_dir = dirname($dest_dir))); + + if ((file_exists($dest) && !is_writable($dest)) || + (!file_exists($dest) && !is_writable($dest_dir))) { + $not_writable[] = $file; + continue; + } + + $zip_files[] = $file; + } + + # If only one file is not writable, stop everything now + if (!empty($not_writable)) { + $e = new Exception('Some files are not writable',self::ERR_FILES_UNWRITALBE); + $e->bad_files = $not_writable; + throw $e; + } + + # Everything's fine, we can write files, then do it now + $can_touch = function_exists('touch'); + foreach ($zip_files as $file) { + $zip->unzip($zip_root.'/'.$file, $root.'/'.$file); + if ($can_touch) { + @touch($root.'/'.$file); + } + } + @unlink($zip_file); + } + + protected function getNewFiles($cur_digests,$new_digests) + { + $cur_md5 = $cur_path = $cur_digests; + $new_md5 = $new_path = $new_digests; + + array_walk($cur_md5, array($this,'parseLine'),1); + array_walk($cur_path,array($this,'parseLine'),2); + array_walk($new_md5, array($this,'parseLine'),1); + array_walk($new_path,array($this,'parseLine'),2); + + $cur = array_combine($cur_md5,$cur_path); + $new = array_combine($new_md5,$new_path); + + return array_values(array_diff_key($new,$cur)); + } + + protected function readVersion($str) + { + try + { + $xml = new SimpleXMLElement($str,LIBXML_NOERROR); + $r = $xml->xpath("/versions/subject[@name='".$this->subject."']/release[@name='".$this->version."']"); + + if (!empty($r) && is_array($r)) + { + $r = $r[0]; + $this->version_info['version'] = isset($r['version']) ? (string) $r['version'] : null; + $this->version_info['href'] = isset($r['href']) ? (string) $r['href'] : null; + $this->version_info['checksum'] = isset($r['checksum']) ? (string) $r['checksum'] : null; + $this->version_info['info'] = isset($r['info']) ? (string) $r['info'] : null; + } + } + catch (Exception $e) + { + throw $e; + } + } + + protected function md5sum($root,$digests_file) + { + if (!is_readable($digests_file)) { + throw new Exception(__('Unable to read digests file.')); + } + + $opts = FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES; + $contents = file($digests_file,$opts); + + $changes = array(); + + foreach ($contents as $digest) + { + if (!preg_match('#^([\da-f]{32})\s+(.+?)$#',$digest,$m)) { + continue; + } + + $md5 = $m[1]; + $filename = $root.'/'.$m[2]; + + # Invalid checksum + if (!is_readable($filename) || md5_file($filename) !== $md5) { + $changes[] = substr($m[2],2); + } + } + + # No checksum found in digests file + if (empty($md5)) { + throw new Exception(__('Invalid digests file.')); + } + + return $changes; + } + + protected function parseLine(&$v,$k,$n) + { + if (!preg_match('#^([\da-f]{32})\s+(.+?)$#',$v,$m)) { + return; + } + + $v = $n == 1 ? md5($m[2].$m[1]) : substr($m[2],2); + } +} +?> \ No newline at end of file diff --git a/inc/core/class.dc.utils.php b/inc/core/class.dc.utils.php new file mode 100644 index 0000000..040292c --- /dev/null +++ b/inc/core/class.dc.utils.php @@ -0,0 +1,53 @@ +user_id, user_name, user_firstname and + user_displayname. + + @param user_id string User ID + @param user_name string User's name + @param user_firstname string User's first name + @param user_displayname string User's display name + @return string + */ + public static function getUserCN($user_id, $user_name, $user_firstname, $user_displayname) + { + if (!empty($user_displayname)) { + return $user_displayname; + } + + if (!empty($user_name)) { + if (!empty($user_firstname)) { + return $user_firstname.' '.$user_name; + } else { + return $user_name; + } + } elseif (!empty($user_firstname)) { + return $user_firstname; + } + + return $user_id; + } +} + +?> \ No newline at end of file diff --git a/inc/core/class.dc.xmlrpc.php b/inc/core/class.dc.xmlrpc.php new file mode 100644 index 0000000..e3d07c2 --- /dev/null +++ b/inc/core/class.dc.xmlrpc.php @@ -0,0 +1,1634 @@ +core =& $core; + $this->blog_id = $blog_id; + + # Blogger methods + $this->addCallback('blogger.newPost',array($this,'blogger_newPost'), + array('string','string','string','string','string','string','integer'), + 'New post'); + + $this->addCallback('blogger.editPost',array($this,'blogger_editPost'), + array('boolean','string','string','string','string','string','integer'), + 'Edit a post'); + + $this->addCallback('blogger.getPost',array($this,'blogger_getPost'), + array('struct','string','integer','string','string'), + 'Return a posts by ID'); + + $this->addCallback('blogger.deletePost',array($this,'blogger_deletePost'), + array('string','string','string','string','string','integer'), + 'Delete a post'); + + $this->addCallback('blogger.getRecentPosts',array($this,'blogger_getRecentPosts'), + array('array','string','string','string','string','integer'), + 'Return a list of recent posts'); + + $this->addCallback('blogger.getUsersBlogs',array($this,'blogger_getUserBlogs'), + array('struct','string','string','string'), + "Return user's blog"); + + $this->addCallback('blogger.getUserInfo',array($this,'blogger_getUserInfo'), + array('struct','string','string','string'), + 'Return User Info'); + + # Metaweblog methods + $this->addCallback('metaWeblog.newPost',array($this,'mw_newPost'), + array('string','string','string','string','struct','boolean'), + 'Creates a new post, and optionnaly publishes it.'); + + $this->addCallback('metaWeblog.editPost',array($this,'mw_editPost'), + array('boolean','string','string','string','struct','boolean'), + 'Updates information about an existing entry'); + + $this->addCallback('metaWeblog.getPost',array($this,'mw_getPost'), + array('struct','string','string','string'), + 'Returns information about a specific post'); + + $this->addCallback('metaWeblog.getRecentPosts',array($this,'mw_getRecentPosts'), + array('array','string','string','string','integer'), + 'List of most recent posts in the system'); + + $this->addCallback('metaWeblog.getCategories',array($this,'mw_getCategories'), + array('array','string','string','string'), + 'List of all categories defined in the weblog'); + + $this->addCallback('metaWeblog.newMediaObject',array($this,'mw_newMediaObject'), + array('struct','string','string','string','struct'), + 'Upload a file on the web server'); + + # MovableType methods + $this->addCallback('mt.getRecentPostTitles',array($this,'mt_getRecentPostTitles'), + array('array','string','string','string','integer'), + 'List of most recent posts in the system'); + + $this->addCallback('mt.getCategoryList',array($this,'mt_getCategoryList'), + array('array','string','string','string'), + 'List of all categories defined in the weblog'); + + $this->addCallback('mt.getPostCategories',array($this,'mt_getPostCategories'), + array('array','string','string','string'), + 'List of all categories to which the post is assigned'); + + $this->addCallback('mt.setPostCategories',array($this,'mt_setPostCategories'), + array('boolean','string','string','string','array'), + 'Sets the categories for a post'); + + $this->addCallback('mt.publishPost',array($this,'mt_publishPost'), + array('boolean','string','string','string'), + 'Retrieve pings list for a post'); + + $this->addCallback('mt.supportedMethods',array($this,'listMethods'), + array(),'Retrieve information about the XML-RPC methods supported by the server.'); + + $this->addCallback('mt.supportedTextFilters',array($this,'mt_supportedTextFilters'), + array(),'Retrieve information about supported text filters.'); + + # WordPress methods + $this->addCallback('wp.getUsersBlogs',array($this,'wp_getUsersBlogs'), + array('array','string','string'), + 'Retrieve the blogs of the user.'); + + $this->addCallback('wp.getPage',array($this,'wp_getPage'), + array('struct','integer','integer','string','string'), + 'Get the page identified by the page ID.'); + + $this->addCallback('wp.getPages',array($this,'wp_getPages'), + array('array','integer','string','string','integer'), + 'Get an array of all the pages on a blog.'); + + $this->addCallback('wp.newPage',array($this,'wp_newPage'), + array('integer','integer','string','string','struct','boolean'), + 'Create a new page.'); + + $this->addCallback('wp.deletePage',array($this,'wp_deletePage'), + array('boolean','integer','string','string','integer'), + 'Removes a page from the blog.'); + + $this->addCallback('wp.editPage',array($this,'wp_editPage'), + array('boolean','integer','integer','string','string','struct','boolean'), + 'Make changes to a blog page.'); + + $this->addCallback('wp.getPageList',array($this,'wp_getPageList'), + array('array','integer','string','string'), + 'Get an array of all the pages on a blog. Just the minimum details, lighter than wp.getPages.'); + + $this->addCallback('wp.getAuthors',array($this,'wp_getAuthors'), + array('array','integer','string','string'), + 'Get an array of users for the blog.'); + + $this->addCallback('wp.getCategories',array($this,'wp_getCategories'), + array('array','integer','string','string'), + 'Get an array of available categories on a blog.'); + + $this->addCallback('wp.getTags',array($this,'wp_getTags'), + array('array','integer','string','string'), + 'Get list of all tags for the blog.'); + + $this->addCallback('wp.newCategory',array($this,'wp_newCategory'), + array('integer','integer','string','string','struct'), + 'Create a new category.'); + + $this->addCallback('wp.deleteCategory',array($this,'wp_deleteCategory'), + array('boolean','integer','string','string','integer'), + 'Delete a category with a given ID.'); + + $this->addCallback('wp.suggestCategories',array($this,'wp_suggestCategories'), + array('array','integer','string','string','string','integer'), + 'Get an array of categories that start with a given string.'); + + $this->addCallback('wp.uploadFile',array($this,'wp_uploadFile'), + array('struct','integer','string','string','struct'), + 'Upload a file'); + + $this->addCallback('wp.getPostStatusList',array($this,'wp_getPostStatusList'), + array('array','integer','string','string'), + 'Retrieve all of the post statuses.'); + + $this->addCallback('wp.getPageStatusList',array($this,'wp_getPageStatusList'), + array('array','integer','string','string'), + 'Retrieve all of the pages statuses.'); + + $this->addCallback('wp.getPageTemplates',array($this,'wp_getPageTemplates'), + array('struct','integer','string','string'), + 'Retrieve page templates.'); + + $this->addCallback('wp.getOptions',array($this,'wp_getOptions'), + array('struct','integer','string','string','array'), + 'Retrieve blog options'); + + $this->addCallback('wp.setOptions',array($this,'wp_setOptions'), + array('struct','integer','string','string','struct'), + 'Update blog options'); + + $this->addCallback('wp.getComment',array($this,'wp_getComment'), + array('struct','integer','string','string','integer'), + "Gets a comment, given it's comment ID."); + + $this->addCallback('wp.getCommentCount',array($this,'wp_getCommentCount'), + array('array','integer','string','string','integer'), + 'Retrieve comment count.'); + + $this->addCallback('wp.getComments',array($this,'wp_getComments'), + array('array','integer','string','string','struct'), + 'Gets a set of comments for a given post.'); + + $this->addCallback('wp.deleteComment',array($this,'wp_deleteComment'), + array('boolean','integer','string','string','integer'), + 'Delete a comment with given ID.'); + + $this->addCallback('wp.editComment',array($this,'wp_editComment'), + array('boolean','integer','string','string','integer','struct'), + 'Edit a comment with given ID.'); + + $this->addCallback('wp.newComment',array($this,'wp_newComment'), + array('integer','integer','string','string','integer','struct'), + 'Create a new comment for a given post ID.'); + + $this->addCallback('wp.getCommentStatusList',array($this,'wp_getCommentStatusList'), + array('array','integer','string','string'), + 'Retrieve all of the comment statuses.'); + } + + public function serve($data=false,$encoding='UTF-8') + { + parent::serve(false,$encoding); + } + + public function call($methodname,$args) + { + try { + $rsp = parent::call($methodname,$args); + $this->debugTrace($methodname,$args,$rsp); + return $rsp; + } catch (Exception $e) { + $this->debugTrace($methodname,$args,array($e->getMessage(),$e->getCode())); + throw $e; + } + } + + private function debugTrace($methodname,$args,$rsp) + { + if (!$this->debug) { + return; + } + + if (($fp = @fopen($this->debug_file,'a')) !== false) + { + fwrite($fp,'['.date('r').']'.' '.$methodname); + + if ($this->trace_args) { + fwrite($fp,"\n- args ---\n".var_export($args,1)); + } + + if ($this->trace_response) { + fwrite($fp,"\n- response ---\n".var_export($rsp,1)); + } + fwrite($fp,"\n"); + fclose($fp); + } + } + + /* Internal methods + --------------------------------------------------- */ + private function setUser($user_id,$pwd) + { + if ($this->core->auth->userID() == $user_id) { + return true; + } + + if ($this->core->auth->checkUser($user_id,$pwd) !== true) { + throw new Exception('Login error'); + } + + return true; + } + + private function setBlog() + { + if (!$this->blog_id) { + throw new Exception('No blog ID given.'); + } + + if ($this->blog_loaded) { + return true; + } + + $this->core->setBlog($this->blog_id); + $this->blog_loaded = true; + + if (!$this->core->blog->id) { + $this->core->blog = null; + throw new Exception('Blog does not exist.'); + } + + if (!$this->core->blog->settings->enable_xmlrpc || + !$this->core->auth->check('usage,contentadmin',$this->core->blog->id)) { + $this->core->blog = null; + throw new Exception('Not enough permissions on this blog.'); + } + + foreach ($this->core->plugins->getModules() as $id => $m) { + $this->core->plugins->loadNsFile($id,'xmlrpc'); + } + + return true; + } + + private function getPostRS($post_id,$user,$pwd,$post_type='post') + { + $this->setUser($user,$pwd); + $this->setBlog(); + $rs = $this->core->blog->getPosts(array( + 'post_id' => (integer) $post_id, + 'post_type' => $post_type + )); + + if ($rs->isEmpty()) { + throw new Exception('This entry does not exist'); + } + + return $rs; + } + + private function getCatID($cat_url) + { + $rs = $this->core->blog->getCategories(array('cat_url' => $cat_url)); + + return $rs->isEmpty() ? null : $rs->cat_id; + } + + /* Generic methods + --------------------------------------------------- */ + private function newPost($blog_id,$user,$pwd,$content,$struct=array(),$publish=true) + { + $this->setUser($user,$pwd); + $this->setBlog(); + + $title = !empty($struct['title']) ? $struct['title'] : ''; + $excerpt = !empty($struct['mt_excerpt']) ? $struct['mt_excerpt'] : ''; + $description = !empty($struct['description']) ? $struct['description'] : null; + $dateCreated = !empty($struct['dateCreated']) ? $struct['dateCreated'] : null; + $open_comment = isset($struct['mt_allow_comments']) ? $struct['mt_allow_comments'] : 1; + $open_tb = isset($struct['mt_allow_pings']) ? $struct['mt_allow_pings'] : 1; + + if ($description !== null) { + $content = $description; + } + + if (!$title) { + $title = text::cutString(html::clean($content),25).'...'; + } + + $excerpt_xhtml = $this->core->callFormater('xhtml',$excerpt); + $content_xhtml = $this->core->callFormater('xhtml',$content); + + if (empty($content)) { + throw new Exception('Cannot create an empty entry'); + } + + $cur = $this->core->con->openCursor($this->core->prefix.'post'); + + $cur->user_id = $this->core->auth->userID(); + $cur->post_lang = $this->core->auth->getInfo('user_lang'); + $cur->post_title = trim($title); + $cur->post_content = $content; + $cur->post_excerpt = $excerpt; + $cur->post_content_xhtml = $content_xhtml; + $cur->post_excerpt_xhtml = $excerpt_xhtml; + $cur->post_open_comment = (integer) ($open_comment == 1); + $cur->post_open_tb = (integer) ($open_tb == 1); + $cur->post_status = (integer) $publish; + $cur->post_format = 'xhtml'; + + if ($dateCreated) { + if ($dateCreated instanceof xmlrpcDate) { + $cur->post_dt = date('Y-m-d H:i:00',$dateCreated->getTimestamp()); + } elseif (is_string($dateCreated) && @strtotime($dateCreated)) { + $cur->post_dt = date('Y-m-d H:i:00',strtotime($dateCreated)); + } + } + + # Categories in an array + if (isset($struct['categories']) && is_array($struct['categories'])) + { + $categories = $struct['categories']; + $cat_id = !empty($categories[0]) ? $categories[0] : null; + + $cur->cat_id = $this->getCatID($cat_id); + } + + if (isset($struct['wp_slug'])) { + $cur->post_url = $struct['wp_slug']; + } + + if (isset($struct['wp_password'])) { + $cur->post_password = $struct['wp_password']; + } + + $cur->post_type = 'post'; + if (!empty($struct['post_type'])) { + $cur->post_type = $struct['post_type']; + } + + if ($cur->post_type == 'post') + { + # --BEHAVIOR-- xmlrpcBeforeNewPost + $this->core->callBehavior('xmlrpcBeforeNewPost',$this,$cur,$content,$struct,$publish); + + $post_id = $this->core->blog->addPost($cur); + + # --BEHAVIOR-- xmlrpcAfterNewPost + $this->core->callBehavior('xmlrpcAfterNewPost',$this,$post_id,$cur,$content,$struct,$publish); + } + elseif ($cur->post_type == 'page') + { + if (isset($struct['wp_page_order'])) { + $cur->post_position = (integer) $struct['wp_page_order']; + } + + $this->core->blog->settings->post_url_format = '{t}'; + + $post_id = $this->core->blog->addPost($cur); + } + else + { + throw new Exception('Invalid post type',401); + } + + return (string) $post_id; + } + + private function editPost($post_id,$user,$pwd,$content,$struct=array(),$publish=true) + { + $post_id = (integer) $post_id; + + $post_type = 'post'; + if (!empty($struct['post_type'])) { + $post_type = $struct['post_type']; + } + + $post = $this->getPostRS($post_id,$user,$pwd,$post_type); + + $title = (!empty($struct['title'])) ? $struct['title'] : ''; + $excerpt = (!empty($struct['mt_excerpt'])) ? $struct['mt_excerpt'] : ''; + $description = (!empty($struct['description'])) ? $struct['description'] : null; + $dateCreated = !empty($struct['dateCreated']) ? $struct['dateCreated'] : null; + $open_comment = (isset($struct['mt_allow_comments'])) ? $struct['mt_allow_comments'] : 1; + $open_tb = (isset($struct['mt_allow_pings'])) ? $struct['mt_allow_pings'] : 1; + + if ($description !== null) { + $content = $description; + } + + if (!$title) { + $title = text::cutString(html::clean($content),25).'...'; + } + + $excerpt_xhtml = $this->core->callFormater('xhtml',$excerpt); + $content_xhtml = $this->core->callFormater('xhtml',$content); + + if (empty($content)) { + throw new Exception('Cannot create an empty entry'); + } + + $cur = $this->core->con->openCursor($this->core->prefix.'post'); + + $cur->post_type = $post_type; + $cur->post_title = trim($title); + $cur->post_content = $content; + $cur->post_excerpt = $excerpt; + $cur->post_content_xhtml = $content_xhtml; + $cur->post_excerpt_xhtml = $excerpt_xhtml; + $cur->post_open_comment = (integer) ($open_comment == 1); + $cur->post_open_tb = (integer) ($open_tb == 1); + $cur->post_status = (integer) $publish; + $cur->post_format = 'xhtml'; + $cur->post_url = $post->post_url; + + + if ($dateCreated) { + if ($dateCreated instanceof xmlrpcDate) { + $cur->post_dt = date('Y-m-d H:i:00',$dateCreated->getTimestamp()); + } elseif (is_string($dateCreated) && @strtotime($dateCreated)) { + $cur->post_dt = date('Y-m-d H:i:00',strtotime($dateCreated)); + } + } else { + $cur->post_dt = $post->post_dt; + } + + # Categories in an array + if (isset($struct['categories']) && is_array($struct['categories'])) + { + $categories = $struct['categories']; + $cat_id = !empty($categories[0]) ? $categories[0] : null; + + $cur->cat_id = $this->getCatID($cat_id); + } + + if (isset($struct['wp_slug'])) { + $cur->post_url = $struct['wp_slug']; + } + + if (isset($struct['wp_password'])) { + $cur->post_password = $struct['wp_password']; + } + + if ($cur->post_type == 'post') + { + # --BEHAVIOR-- xmlrpcBeforeEditPost + $this->core->callBehavior('xmlrpcBeforeEditPost',$this,$post_id,$cur,$content,$struct,$publish); + + $this->core->blog->updPost($post_id,$cur); + + # --BEHAVIOR-- xmlrpcAfterEditPost + $this->core->callBehavior('xmlrpcAfterEditPost',$this,$post_id,$cur,$content,$struct,$publish); + } + elseif ($cur->post_type == 'page') + { + if (isset($struct['wp_page_order'])) { + $cur->post_position = (integer) $struct['wp_page_order']; + } + + $this->core->blog->settings->post_url_format = '{t}'; + + $this->core->blog->updPost($post_id,$cur); + } + else + { + throw new Exception('Invalid post type',401); + } + + return true; + } + + private function getPost($post_id,$user,$pwd,$type='mw') + { + $post_id = (integer) $post_id; + + $post = $this->getPostRS($post_id,$user,$pwd); + + $res = array(); + + $res['dateCreated'] = new xmlrpcDate($post->getTS()); + $res['userid'] = $post->user_id; + $res['postid'] = $post->post_id; + + if ($post->cat_id) { + $res['categories'] = array($post->cat_url); + } + + if ($type == 'blogger') { + $res['content'] = $post->post_content_xhtml; + } + + if ($type == 'mt' || $type == 'mw') { + $res['title'] = $post->post_title; + } + + if ($type == 'mw') { + $res['description'] = $post->post_content_xhtml; + $res['link'] = $res['permaLink'] = $post->getURL(); + $res['mt_excerpt'] = $post->post_excerpt_xhtml; + $res['mt_text_more'] = ''; + $res['mt_allow_comments'] = (integer) $post->post_open_comment; + $res['mt_allow_pings'] = (integer) $post->post_open_tb; + $res['mt_convert_breaks'] = ''; + $res['mt_keywords'] = ''; + } + + # --BEHAVIOR-- xmlrpcGetPostInfo + $this->core->callBehavior('xmlrpcGetPostInfo',$this,$type,array(&$res)); + + return $res; + } + + private function deletePost($post_id,$user,$pwd) + { + $post_id = (integer) $post_id; + + $this->getPostRS($post_id,$user,$pwd); + $this->core->blog->delPost($post_id); + + return true; + } + + private function getRecentPosts($blog_id,$user,$pwd,$nb_post,$type='mw') + { + $this->setUser($user,$pwd); + $this->setBlog(); + + $nb_post = (integer) $nb_post; + + if ($nb_post > 50) { + throw new Exception('Cannot retrieve more than 50 entries'); + } + + $params = array(); + $params['limit'] = $nb_post; + + $posts = $this->core->blog->getPosts($params); + + $res = array(); + while ($posts->fetch()) + { + $tres = array(); + + $tres['dateCreated'] = new xmlrpcDate($posts->getTS()); + $tres['userid'] = $posts->user_id; + $tres['postid'] = $posts->post_id; + + if ($posts->cat_id) { + $tres['categories'] = array($posts->cat_url); + } + + if ($type == 'blogger') { + $tres['content'] = $posts->post_content_xhtml; + } + + if ($type == 'mt' || $type == 'mw') { + $tres['title'] = $posts->post_title; + } + + if ($type == 'mw') { + $tres['description'] = $posts->post_content_xhtml; + $tres['link'] = $tres['permaLink'] = $posts->getURL(); + $tres['mt_excerpt'] = $posts->post_excerpt_xhtml; + $tres['mt_text_more'] = ''; + $tres['mt_allow_comments'] = (integer) $posts->post_open_comment; + $tres['mt_allow_pings'] = (integer) $posts->post_open_tb; + $tres['mt_convert_breaks'] = ''; + $tres['mt_keywords'] = ''; + } + + # --BEHAVIOR-- xmlrpcGetPostInfo + $this->core->callBehavior('xmlrpcGetPostInfo',$this,$type,array(&$tres)); + + $res[] = $tres; + } + + return $res; + } + + private function getUserBlogs($user,$pwd) + { + $this->setUser($user,$pwd); + $this->setBlog(); + + return array(array( + 'url' => $this->core->blog->url, + 'blogid' => '1', + 'blogName' => $this->core->blog->name + )); + } + + private function getUserInfo($user,$pwd) + { + $this->setUser($user,$pwd); + + return array( + 'userid' => $this->core->auth->userID(), + 'firstname' => $this->core->auth->getInfo('user_firstname'), + 'lastname' => $this->core->auth->getInfo('user_name'), + 'nickname' => $this->core->auth->getInfo('user_displayname'), + 'email' => $this->core->auth->getInfo('user_email'), + 'url' => $this->core->auth->getInfo('user_url') + ); + } + + private function getCategories($blog_id,$user,$pwd) + { + $this->setUser($user,$pwd); + $this->setBlog(); + $rs = $this->core->blog->getCategories(); + + $res = array(); + + $l = $rs->level; + $stack = array('',$rs->cat_url); + + while ($rs->fetch()) + { + $d = $rs->level - $l; + if ($d == 0) { + array_pop($stack); + $parent = end($stack); + } elseif ($d > 0) { + $parent = end($stack); + } elseif ($d < 0) { + $D = abs($d); + for ($i=0; $i<=$D; $i++) { + array_pop($stack); + } + $parent = end($stack); + } + + $res[] = array( + 'categoryId' => $rs->cat_url, + 'parentId' => $parent, + 'description' => $rs->cat_title, + 'categoryName' => $rs->cat_url, + 'htmlUrl' => $this->core->blog->url.$this->core->url->getBase('category').'/'.$rs->cat_url, + 'rssUrl' => $this->core->blog->url.$this->core->url->getBase('feed').'/category/'.$rs->cat_url.'/rss2' + ); + + $stack[] = $rs->cat_url; + $l = $rs->level; + } + + return $res; + } + + private function getPostCategories($post_id,$user,$pwd) + { + $post_id = (integer) $post_id; + + $post = $this->getPostRS($post_id,$user,$pwd); + + return array( + array( + 'categoryName' => $post->cat_url, + 'categoryId' => (string) $post->cat_url, + 'isPrimary' => true + ) + ); + } + + private function setPostCategories($post_id,$user,$pwd,$categories) + { + $post_id = (integer) $post_id; + + $post = $this->getPostRS($post_id,$user,$pwd); + + $cat_id = (!empty($categories[0]['categoryId'])) ? $categories[0]['categoryId'] : null; + + foreach($categories as $v) + { + if (isset($v['isPrimary']) && $v['isPrimary']) { + $cat_id = $v['categoryId']; + break; + } + } + + # w.bloggar sends -1 for no category. + if ($cat_id == -1) { + $cat_id = null; + } + + if ($cat_id) { + $cat_id = $this->getCatID($cat_id); + } + + $this->core->blog->updPostCategory($post_id,(integer) $cat_id); + + return true; + } + + private function publishPost($post_id,$user,$pwd) + { + $post_id = (integer) $post_id; + + $this->getPostRS($post_id,$user,$pwd); + + # --BEHAVIOR-- xmlrpcBeforePublishPost + $this->core->callBehavior('xmlrpcBeforePublishPost',$this,$post_id); + + $this->core->blog->updPostStatus($post_id,1); + + # --BEHAVIOR-- xmlrpcAfterPublishPost + $this->core->callBehavior('xmlrpcAfterPublishPost',$this,$post_id); + + return true; + } + + private function newMediaObject($blog_id,$user,$pwd,$file) + { + if (empty($file['name'])) { + throw new Exception('No file name'); + } + + if (empty($file['bits'])) { + throw new Exception('No file content'); + } + + $file_name = $file['name']; + $file_bits = $file['bits']; + + $this->setUser($user,$pwd); + $this->setBlog(); + + $media = new dcMedia($this->core); + + $dir_name = path::clean(dirname($file_name)); + $file_name = basename($file_name); + + $dir_name = preg_replace('!^/!','',$dir_name); + if ($dir_name != '') + { + $dir = explode('/',$dir_name); + $cwd = './'; + foreach ($dir as $v) + { + $v = files::tidyFileName($v); + $cwd .= $v.'/'; + $media->makeDir($v); + $media->chdir($cwd); + } + } + + $media_id = $media->uploadBits($file_name,$file_bits); + + $f = $media->getFile($media_id); + return array( + 'file' => $file_name, + 'url' => $f->file_url, + 'type' => files::getMimeType($file_name) + ); + } + + private function translateWpStatus($s) + { + $status = array( + 'draft' => -2, + 'pending' => -2, + 'private' => 0, + 'publish' => 1, + 'scheduled' => -1 + ); + + if (is_int($s)) { + $status = array_flip($status); + return isset($status[$s]) ? $status[$s] : $status[-2]; + } else { + return isset($status[$s]) ? $status[$s] : $status['pending']; + } + } + + private function translateWpCommentstatus($s) + { + $status = array( + 'hold' => -1, + 'approve' => 0, + 'spam' => -2 + ); + + if (is_int($s)) { + $status = array_flip($status); + return isset($status[$s]) ? $status[$s] : $status[0]; + } else { + return isset($status[$s]) ? $status[$s] : $status['approve']; + } + } + + private function translateWpOptions($options=array()) + { + $timezone = 0; + if ($this->core->blog->settings->blog_timezone) { + $timezone = dt::getTimeOffset($this->core->blog->settings->blog_timezone)/3600; + } + + $res = array ( + 'software_name' => array ( + 'desc' => 'Software Name', + 'readonly' => true, + 'value' => 'Dotclear' + ), + 'software_version' => array ( + 'desc' => 'Software Version', + 'readonly' => true, + 'value' => DC_VERSION + ), + 'blog_url' => array ( + 'desc' => 'Blog URL', + 'readonly' => true, + 'value' => $this->core->blog->url + ), + 'time_zone' => array ( + 'desc' => 'Time Zone', + 'readonly' => true, + 'value' => (string) $timezone + ), + 'blog_title' => array ( + 'desc' => 'Blog Title', + 'readonly' => false, + 'value' => $this->core->blog->name + ), + 'blog_tagline' => array ( + 'desc' => 'Blog Tagline', + 'readonly' => false, + 'value' => $this->core->blog->desc + ), + 'date_format' => array ( + 'desc' => 'Date Format', + 'readonly' => false, + 'value' => $this->core->blog->settings->date_format + ), + 'time_format' => array ( + 'desc' => 'Time Format', + 'readonly' => false, + 'value' => $this->core->blog->settings->time_format + ) + ); + + if (!empty($options)) + { + $r = array(); + foreach ($options as $v) { + if (isset($res[$v])) { + $r[$v] = $res[$v]; + } + } + return $r; + } + + return $res; + } + + private function getPostStatusList($blog_id,$user,$pwd) + { + $this->setUser($user,$pwd); + $this->setBlog(); + + return array( + 'draft' => 'Draft', + 'pending' => 'Pending Review', + 'private' => 'Private', + 'publish' => 'Published', + 'scheduled' => 'Scheduled' + ); + } + + private function getPageStatusList($blog_id,$user,$pwd) + { + $this->setUser($user,$pwd); + $this->setBlog(); + $this->checkPagesPermission(); + + return array( + 'draft' => 'Draft', + 'private' => 'Private', + 'published' => 'Published', + 'scheduled' => 'Scheduled' + ); + } + + private function checkPagesPermission() + { + if (!$this->core->plugins->moduleExists('pages')) { + throw new Exception('Pages management is not available on this blog.'); + } + + if (!$this->core->auth->check('pages,contentadmin',$this->core->blog->id)) { + throw new Exception('Not enough permissions to edit pages.',401); + } + } + + private function getPages($blog_id,$user,$pwd,$limit=null,$id=null) + { + $this->setUser($user,$pwd); + $this->setBlog(); + $this->checkPagesPermission(); + + $params = array( + 'post_type' => 'page', + 'order' => 'post_position ASC, post_title ASC' + ); + + if ($id) { + $params['post_id'] = (integer) $id; + } + if ($limit) { + $params['limit'] = $limit; + } + + $posts = $this->core->blog->getPosts($params); + + $res = array(); + while ($posts->fetch()) + { + $tres = array( + "dateCreated" => new xmlrpcDate($posts->getTS()), + "userid" => $posts->user_id, + "page_id" => $posts->post_id, + "page_status" => $this->translateWpStatus((integer) $posts->post_status), + "description" => $posts->post_content_xhtml, + "title" => $posts->post_title, + "link" => $posts->getURL(), + "permaLink" => $posts->getURL(), + "categories" => array(), + "excerpt" => $posts->post_excerpt_xhtml, + "text_more" => '', + "mt_allow_comments" => (integer) $posts->post_open_comment, + "mt_allow_pings" => (integer) $posts->post_open_tb, + "wp_slug" => $posts->post_url, + "wp_password" => $posts->post_password, + "wp_author" => $posts->getAuthorCN(), + "wp_page_parent_id" => 0, + "wp_page_parent_title" => '', + "wp_page_order" => $posts->post_position, + "wp_author_id" => $posts->user_id, + "wp_author_display_name" => $posts->getAuthorCN(), + "date_created_gmt" => new xmlrpcDate(dt::iso8601($posts->getTS(),$posts->post_tz)), + "custom_fields" => array(), + "wp_page_template" => 'default' + ); + + # --BEHAVIOR-- xmlrpcGetPageInfo + $this->core->callBehavior('xmlrpcGetPageInfo',$this,array(&$tres)); + + $res[] = $tres; + } + + return $res; + } + + private function newPage($blog_id,$user,$pwd,$struct,$publish) + { + $this->setUser($user,$pwd); + $this->setBlog(); + $this->checkPagesPermission(); + + $struct['post_type'] = 'page'; + + return $this->newPost($blog_id,$user,$pwd,null,$struct,$publish); + } + + private function editPage($page_id,$user,$pwd,$struct,$publish) + { + $this->setUser($user,$pwd); + $this->setBlog(); + $this->checkPagesPermission(); + + $struct['post_type'] = 'page'; + + return $this->editPost($page_id,$user,$pwd,null,$struct,$publish); + } + + private function deletePage($page_id,$user,$pwd) + { + $this->setUser($user,$pwd); + $this->setBlog(); + $this->checkPagesPermission(); + + $page_id = (integer) $page_id; + + $this->getPostRS($page_id,$user,$pwd,'page'); + $this->core->blog->delPost($page_id); + + return true; + } + + private function getAuthors($user,$pwd) + { + $this->setUser($user,$pwd); + $this->setBlog(); + + $rs = $this->core->getBlogPermissions($this->core->blog->id); + $res = array(); + + foreach($rs as $k => $v) + { + $res[] = array( + 'user_id' => $k, + 'user_login' => $k, + 'display_name' => dcUtils::getUserCN($k,$v['name'],$v['firstname'],$v['displayname']) + ); + } + return $res; + } + + private function getTags($user,$pwd) + { + if (!class_exists('dcMeta')) { + throw new Exception('Metadata management is not available on this blog.'); + } + + $this->setUser($user,$pwd); + $this->setBlog(); + + $meta = new dcMeta($this->core); + + $tags = $meta->getMeta('tag'); + $tags->sort('meta_id_lower','asc'); + + $res = array(); + $url = $this->core->blog->url.$this->core->url->getBase('tag').'/%s'; + $f_url = $this->core->blog->url.$this->core->url->getBase('tag_feed').'/%s'; + while ($tags->fetch()) + { + $res[] = array( + 'tag_id' => $tags->meta_id, + 'name' => $tags->meta_id, + 'count' => $tags->count, + 'slug' => $tags->meta_id, + 'html_url' => sprintf($url,$tags->meta_id), + 'rss_url' => sprintf($f_url,$tags->meta_id) + ); + } + return $res; + } + + private function newCategory($user,$pwd,$struct) + { + $this->setUser($user,$pwd); + $this->setBlog(); + + if (empty($struct['name'])) { + throw new Exception('You mus give a category name.'); + } + + $cur = $this->core->con->openCursor($this->core->prefix.'category'); + $cur->cat_title = $struct['name']; + + if (!empty($struct['slug'])) { + $cur->cat_url = $struct['slug']; + } + if (!empty($struct['category_description'])) { + $cur->cat_desc = $struct['category_description']; + if (html::clean($cur->cat_desc) == $cur->cat_desc) { + $cur->cat_desc = '

    '.$cur->cat_desc.'

    '; + } + } + + $parent = !empty($struct['category_parent']) ? (integer) $struct['category_parent'] : 0; + + $id = $this->core->blog->addCategory($cur,$parent); + $rs = $this->core->blog->getCategory($id); + return $rs->cat_url; + } + + private function deleteCategory($user,$pwd,$cat_id) + { + $this->setUser($user,$pwd); + $this->setBlog(); + + $c = $this->core->blog->getCategories(array('cat_url' => $cat_id)); + if ($c->isEmpty()) { + throw new Exception(__('This category does not exist.')); + } + $cat_id = $c->cat_id; + unset($c); + + $this->core->blog->delCategory((integer) $cat_id); + return true; + } + + private function searchCategories($user,$pwd,$category,$limit) + { + $this->setUser($user,$pwd); + $this->setBlog(); + + $strReq = 'SELECT cat_id, cat_title, cat_url '. + 'FROM '.$this->core->prefix.'category '. + "WHERE blog_id = '".$this->core->con->escape($this->core->blog->id)."' ". + "AND LOWER(cat_title) LIKE LOWER('%".$this->core->con->escape($category)."%') ". + ($limit > 0 ? $this->core->con->limit($limit) : ''); + + $rs = $this->core->con->select($strReq); + + $res = array(); + while ($rs->fetch()) + { + $res[] = array( + 'category_id' => $rs->cat_url, + 'category_name' => $rs->cat_url + ); + } + return $res; + } + + private function countComments($user,$pwd,$post_id) + { + $this->setUser($user,$pwd); + $this->setBlog(); + + $res = array( + 'approved' => 0, + 'awaiting_moderation' => 0, + 'spam' => 0, + 'total' => 0 + ); + $rs = $this->core->blog->getComments(array('post_id' => $post_id)); + + while ($rs->fetch()) { + $res['total']++; + if ($rs->comment_status == 1) { + $res['approved']++; + } elseif ($rs->comment_status == -2) { + $res['spam']++; + } else { + $res['awaiting_moderation']++; + } + } + return $res; + } + + private function getComments($user,$pwd,$struct,$id=null) + { + $this->setUser($user,$pwd); + $this->setBlog(); + + $params = array(); + + if (!empty($struct['status'])) { + $params['comment_status'] = $this->translateWpCommentstatus($struct['status']); + } + + if (!empty($struct['post_id'])) { + $params['post_id'] = (integer) $struct['post_id']; + } + + if (isset($id)) { + $params['comment_id'] = $id; + } + + $offset = !empty($struct['offset']) ? (integer) $struct['offset'] : 0; + $limit = !empty($struct['number']) ? (integer) $struct['number'] : 10; + $params['limit'] = array($offset,$limit); + + $rs = $this->core->blog->getComments($params); + $res = array(); + while ($rs->fetch()) + { + $res[] = array( + 'date_created_gmt' => new xmlrpcDate($rs->getTS()), + 'user_id' => $rs->user_id, + 'comment_id' => $rs->comment_id, + 'parent' => 0, + 'status' => $this->translateWpCommentstatus((integer) $rs->comment_status), + 'content' => $rs->comment_content, + 'link' => $rs->getPostURL().'#c'.$rs->comment_id, + 'post_id' => $rs->post_id, + 'post_title' => $rs->post_title, + 'author' => $rs->comment_author, + 'author_url' => $rs->comment_site, + 'author_email' => $rs->comment_email, + 'author_ip' => $rs->comment_ip, + ); + } + return $res; + } + + private function addComment($user,$pwd,$post_id,$struct) + { + $this->setUser($user,$pwd); + $this->setBlog(); + + if (empty($struct['content'])) { + throw new Exception('Sorry, you cannot post an empty comment',401); + } + + if (is_numeric($post_id)) { + $p['post_id'] = $post_id; + } else { + $p['post_url'] = $post_id; + } + $rs = $this->core->blog->getPosts($p); + if ($rs->isEmpty()) { + throw new Exception('Sorry, no such post.',404); + } + + $cur = $this->core->con->openCursor($this->core->prefix.'comment'); + + $cur->comment_author = $this->core->auth->getInfo('user_cn'); + $cur->comment_email = $this->core->auth->getInfo('user_email'); + $cur->comment_site = $this->core->auth->getInfo('user_url'); + + $cur->comment_content = $struct['content']; + $cur->post_id = (integer) $post_id; + + $id = $this->core->blog->addComment($cur); + return $id; + } + + private function updComment($user,$pwd,$comment_id,$struct) + { + $this->setUser($user,$pwd); + $this->setBlog(); + + $cur = $this->core->con->openCursor($this->core->prefix.'comment'); + + if (isset($struct['status'])) { + $cur->comment_status = $this->translateWpCommentstatus($struct['status']); + } + + if (isset($struct['date_created_gmt'])) { + if ($struct['date_created_gmt'] instanceof xmlrpcDate) { + $cur->comment_dt = date('Y-m-d H:i:00',$struct['date_created_gmt']->getTimestamp()); + } elseif (is_string($struct['date_created_gmt']) && @strtotime($struct['date_created_gmt'])) { + $cur->comment_dt = date('Y-m-d H:i:00',strtotime($struct['date_created_gmt'])); + } + $cur->comment_dt = $struct['date_created_gmt']; + } + + if (isset($struct['content'])) { + $cur->comment_content = $struct['content']; + } + + if (isset($struct['author'])) { + $cur->comment_author = $struct['author']; + } + + if (isset($struct['author_url'])) { + $cur->comment_site = $struct['author_url']; + } + + if (isset($struct['author_email'])) { + $cur->comment_email = $struct['author_email']; + } + + $this->core->blog->updComment($comment_id,$cur); + return true; + } + + private function delComment($user,$pwd,$comment_id) + { + $this->setUser($user,$pwd); + $this->setBlog(); + + $this->core->blog->delComment($comment_id); + return true; + } + + /* Blogger methods + --------------------------------------------------- */ + public function blogger_newPost($appkey,$blogid,$username,$password,$content,$publish) + { + return $this->newPost($blogid,$username,$password,$content,array(),$publish); + } + + public function blogger_editPost($appkey,$postid,$username,$password,$content,$publish) + { + return $this->editPost($postid,$username,$password,$content,array(),$publish); + } + + public function blogger_getPost($appkey,$postid,$username,$password) + { + return $this->getPost($postid,$username,$password,'blogger'); + } + + public function blogger_deletePost($appkey,$postid,$username,$password,$publish) + { + return $this->deletePost($postid,$username,$password); + } + + public function blogger_getRecentPosts($appkey,$blogid,$username,$password,$numberOfPosts) + { + return $this->getRecentPosts($blogid,$username,$password,$numberOfPosts,'blogger'); + } + + public function blogger_getUserBlogs($appkey,$username,$password) + { + return $this->getUserBlogs($username,$password); + } + + public function blogger_getUserInfo($appkey,$username,$password) + { + return $this->getUserInfo($username,$password); + } + + + /* Metaweblog methods + ------------------------------------------------------- */ + public function mw_newPost($blogid,$username,$password,$content,$publish) + { + return $this->newPost($blogid,$username,$password,'',$content,$publish); + } + + public function mw_editPost($postid,$username,$password,$content,$publish) + { + return $this->editPost($postid,$username,$password,'',$content,$publish); + } + + public function mw_getPost($postid,$username,$password) + { + return $this->getPost($postid,$username,$password,'mw'); + } + + public function mw_getRecentPosts($blogid,$username,$password,$numberOfPosts) + { + return $this->getRecentPosts($blogid,$username,$password,$numberOfPosts,'mw'); + } + + public function mw_getCategories($blogid,$username,$password) + { + return $this->getCategories($blogid,$username,$password); + } + + public function mw_newMediaObject($blogid,$username,$password,$file) + { + return $this->newMediaObject($blogid,$username,$password,$file); + } + + /* MovableType methods + --------------------------------------------------- */ + public function mt_getRecentPostTitles($blogid,$username,$password,$numberOfPosts) + { + return $this->getRecentPosts($blogid,$username,$password,$numberOfPosts,'mt'); + } + + public function mt_getCategoryList($blogid,$username,$password) + { + return $this->getCategories($blogid,$username,$password); + } + + public function mt_getPostCategories($postid,$username,$password) + { + return $this->getPostCategories($postid,$username,$password); + } + + public function mt_setPostCategories($postid,$username,$password,$categories) + { + return $this->setPostCategories($postid,$username,$password,$categories); + } + + public function mt_publishPost($postid,$username,$password) + { + return $this->publishPost($postid,$username,$password); + } + + public function mt_supportedTextFilters() + { + return array(); + } + + /* WordPress methods + --------------------------------------------------- */ + public function wp_getUsersBlogs($username,$password) + { + return $this->getUserBlogs($username,$password); + } + + public function wp_getPage($blogid,$pageid,$username,$password) + { + $res = $this->getPages($blogid,$username,$password,null,$pageid); + + if (empty($res)) { + throw new Exception('Sorry, no such page',404); + } + + return $res[0]; + } + + public function wp_getPages($blogid,$username,$password,$num=10) + { + return $this->getPages($blogid,$username,$password,$num); + } + + public function wp_newPage($blogid,$username,$password,$content,$publish) + { + return $this->newPage($blogid,$username,$password,$content,$publish); + } + + public function wp_deletePage($blogid,$username,$password,$pageid) + { + return $this->deletePage($pageid,$username,$password); + } + + public function wp_editPage($blogid,$pageid,$username,$password,$content,$publish) + { + return $this->editPage($pageid,$username,$password,$content,$publish); + } + + public function wp_getPageList($blogid,$username,$password) + { + $A = $this->getPages($blogid,$username,$password); + $res = array(); + foreach ($A as $v) { + $res[] = array( + 'page_id' => $v['page_id'], + 'page_title' => $v['title'], + 'page_parent_id' => $v['wp_page_parent_id'], + 'dateCreated' => $v['dateCreated'], + 'date_created_gmt' => $v['date_created_gmt'] + ); + } + return $res; + } + + public function wp_getAuthors($blogid,$username,$password) + { + return $this->getAuthors($username,$password); + } + + public function wp_getCategories($blogid,$username,$password) + { + return $this->getCategories($blogid,$username,$password); + } + + public function wp_getTags($blogid,$username,$password) + { + return $this->getTags($username,$password); + } + + public function wp_newCategory($blogid,$username,$password,$content) + { + return $this->newCategory($username,$password,$content); + } + + public function wp_deleteCategory($blogid,$username,$password,$categoryid) + { + return $this->deleteCategory($username,$password,$categoryid); + } + + public function wp_suggestCategories($blogid,$username,$password,$category,$max_results=0) + { + return $this->searchCategories($username,$password,$category,$max_results); + } + + public function wp_uploadFile($blogid,$username,$password,$file) + { + return $this->newMediaObject($blogid,$username,$password,$file); + } + + public function wp_getPostStatusList($blogid,$username,$password) + { + return $this->getPostStatusList($blogid,$username,$password); + } + + public function wp_getPageStatusList($blogid,$username,$password) + { + return $this->getPostStatusList($blogid,$username,$password); + } + + public function wp_getPageTemplates($blogid,$username,$password) + { + return array('Default' => 'default'); + } + + public function wp_getOptions($blogid,$username,$password,$options=array()) + { + $this->setUser($username,$password); + $this->setBlog(); + + return $this->translateWpOptions($options); + } + + public function wp_setOptions($blogid,$username,$password,$options) + { + $this->setUser($username,$password); + $this->setBlog(); + + if (!$this->core->auth->check('admin',$this->core->blog->id)) { + throw new Exception('Not enough permissions to edit options.',401); + } + + $opt = $this->translateWpOptions(); + + $done = array(); + $blog_changes = false; + $cur = $this->core->con->openCursor($this->core->prefix.'blog'); + + $this->core->blog->settings->setNameSpace('system'); + + foreach ($options as $name => $value) + { + if (!isset($opt[$name]) || $opt[$name]['readonly']) { + continue; + } + + switch ($name) + { + case 'blog_title': + $blog_changes = true; + $cur->blog_name = $value; + $done[] = $name; + break; + case 'blog_tagline': + $blog_changes = true; + $cur->blog_desc = $value; + $done[] = $name; + break; + case 'date_format': + $this->core->blog->settings->put('date_format',$value); + $done[] = $name; + break; + case 'time_format': + $this->core->blog->settings->put('time_format',$value); + $done[] = $name; + break; + } + } + + if ($blog_changes) { + $this->core->updBlog($this->core->blog->id,$cur); + $this->core->setBlog($this->core->blog->id); + } + + return $this->translateWpOptions($done); + } + + public function wp_getComment($blogid,$username,$password,$commentid) + { + $res = $this->getComments($username,$password,array(),$commentid); + + if (empty($res)) { + throw new Exception('Sorry, no such comment',404); + } + + return $res[0]; + } + + public function wp_getCommentCount($blogid,$username,$password,$postid) + { + return $this->countComments($username,$password,$postid); + } + + public function wp_getComments($blogid,$username,$password,$struct) + { + return $this->getComments($username,$password,$struct); + } + + public function wp_deleteComment($blogid,$username,$password,$commentid) + { + return $this->delComment($username,$password,$commentid); + } + + public function wp_editComment($blogid,$username,$password,$commentid,$content) + { + return $this->updComment($username,$password,$commentid,$content); + } + + public function wp_newComment($blogid,$username,$password,$postid,$content) + { + return $this->addComment($username,$password,$postid,$content); + } + + public function wp_getCommentStatusList($blogid,$username,$password) + { + $this->setUser($username,$password); + $this->setBlog(); + + return array( + 'hold' => 'Unapproved', + 'approve' => 'Approved', + 'spam' => 'Spam' + ); + } +} +?> \ No newline at end of file diff --git a/inc/core_error.php b/inc/core_error.php new file mode 100644 index 0000000..fcf0b60 --- /dev/null +++ b/inc/core_error.php @@ -0,0 +1,63 @@ + + + + + + + + + + Dotclear - Error + + + + +
    +

    Dotclear

    +

    +
    + + \ No newline at end of file diff --git a/inc/dbschema/db-schema.php b/inc/dbschema/db-schema.php new file mode 100644 index 0000000..1628fb9 --- /dev/null +++ b/inc/dbschema/db-schema.php @@ -0,0 +1,253 @@ +blog + ->blog_id ('varchar', 32, false) + ->blog_uid ('varchar', 32, false) + ->blog_creadt ('timestamp', 0, false, 'now()') + ->blog_upddt ('timestamp', 0, false, 'now()') + ->blog_url ('varchar', 255, false) + ->blog_name ('varchar', 255, false) + ->blog_desc ('text', 0, true) + ->blog_status ('smallint', 0, false, 1) + + ->primary('pk_blog','blog_id') + ; + +$_s->category + ->cat_id ('bigint', 0, false) + ->blog_id ('varchar', 32, false) + ->cat_title ('varchar', 255, false) + ->cat_url ('varchar', 255, false) + ->cat_desc ('text', 0, true) + ->cat_position ('integer', 0, true, 0) + ->cat_lft ('integer', 0, true) + ->cat_rgt ('integer', 0, true) + + ->primary('pk_category','cat_id') + + ->unique('uk_cat_url','cat_url','blog_id') + ; + +$_s->session + ->ses_id ('varchar', 40, false) + ->ses_time ('integer', 0, false, 0) + ->ses_start ('integer', 0, false, 0) + ->ses_value ('text', 0, false) + + ->primary('pk_session','ses_id') + ; + +$_s->setting + ->setting_id ('varchar', 255, false) + ->blog_id ('varchar', 32, true) + ->setting_ns ('varchar', 32, false, "'system'") + ->setting_value ('text', 0, true, null) + ->setting_type ('varchar', 8, false, "'string'") + ->setting_label ('text', 0, true) + + ->unique('uk_setting','setting_id','blog_id') + ; + +$_s->user + ->user_id ('varchar', 32, false) + ->user_super ('smallint', 0, true) + ->user_status ('smallint', 0, false, 1) + ->user_pwd ('varchar', 40, false) + ->user_recover_key ('varchar', 32, true, null) + ->user_name ('varchar', 255, true, null) + ->user_firstname ('varchar', 255, true, null) + ->user_displayname ('varchar', 255, true, null) + ->user_email ('varchar', 255, true, null) + ->user_url ('varchar', 255, true, null) + ->user_desc ('text', 0, true) + ->user_default_blog ('varchar', 32, true, null) + ->user_options ('text', 0, true) + ->user_lang ('varchar', 5, true, null) + ->user_tz ('varchar', 128, false, "'UTC'") + ->user_post_status ('smallint', 0, false, -2) + ->user_creadt ('timestamp', 0, false, 'now()') + ->user_upddt ('timestamp', 0, false, 'now()') + + ->primary('pk_user','user_id') + ; + +$_s->permissions + ->user_id ('varchar', 32, false) + ->blog_id ('varchar', 32, false) + ->permissions ('text', 0, true) + + ->primary('pk_permissions','user_id','blog_id') + ; + +$_s->post + ->post_id ('bigint', 0, false) + ->blog_id ('varchar', 32, false) + ->user_id ('varchar', 32, false) + ->cat_id ('bigint', 0, true) + ->post_dt ('timestamp', 0, false, 'now()') + ->post_tz ('varchar', 128, false, "'UTC'") + ->post_creadt ('timestamp', 0, false, 'now()') + ->post_upddt ('timestamp', 0, false, 'now()') + ->post_password ('varchar', 32, true, null) + ->post_type ('varchar', 32, false, "'post'") + ->post_format ('varchar', 32, false, "'xhtml'") + ->post_url ('varchar', 255, false) + ->post_lang ('varchar', 5, true, null) + ->post_title ('varchar', 255, true, null) + ->post_excerpt ('text', 0, true, null) + ->post_excerpt_xhtml ('text', 0, true, null) + ->post_content ('text', 0, true, null) + ->post_content_xhtml ('text', 0, false) + ->post_notes ('text', 0, true, null) + ->post_words ('text', 0, true, null) + ->post_status ('smallint', 0, false, 0) + ->post_selected ('smallint', 0, false, 0) + ->post_position ('integer', 0, false, 0) + ->post_open_comment ('smallint', 0, false, 0) + ->post_open_tb ('smallint', 0, false, 0) + ->nb_comment ('integer', 0, false, 0) + ->nb_trackback ('integer', 0, false, 0) + + ->primary('pk_post','post_id') + + ->unique('uk_post_url','post_url','post_type','blog_id') + ; + +$_s->media + ->media_id ('bigint', 0, false) + ->user_id ('varchar', 32, false) + ->media_path ('varchar', 255, false) + ->media_title ('varchar', 255, false) + ->media_file ('varchar', 255, false) + ->media_dir ('varchar', 255, false, "'.'") + ->media_meta ('text', 0, true, null) + ->media_dt ('timestamp', 0, false, 'now()') + ->media_creadt ('timestamp', 0, false, 'now()') + ->media_upddt ('timestamp', 0, false, 'now()') + ->media_private ('smallint', 0, false, 0) + + ->primary('pk_media','media_id') + ; + +$_s->post_media + ->media_id ('bigint', 0, false) + ->post_id ('bigint', 0, false) + + ->primary('pk_post_media','media_id','post_id') + ; + +$_s->log + ->log_id ('bigint', 0, false) + ->user_id ('varchar', 32, true) + ->blog_id ('varchar', 32, true) + ->log_table ('varchar', 255, false) + ->log_dt ('timestamp', 0, false, 'now()') + ->log_ip ('varchar', 39, false) + ->log_msg ('varchar', 255, false) + + ->primary('pk_log','log_id') + ; + +$_s->version + ->module ('varchar', 64, false) + ->version ('varchar', 32, false) + + ->primary('pk_version','module') + ; + +$_s->ping + ->post_id ('bigint', 0, false) + ->ping_url ('varchar', 255, false) + ->ping_dt ('timestamp', 0, false, 'now()') + + ->primary('pk_ping','post_id','ping_url') + ; + +$_s->comment + ->comment_id ('bigint', 0, false) + ->post_id ('bigint', 0, false) + ->comment_dt ('timestamp', 0, false, 'now()') + ->comment_tz ('varchar', 128, false, "'UTC'") + ->comment_upddt ('timestamp', 0, false, 'now()') + ->comment_author ('varchar', 255, true, null) + ->comment_email ('varchar', 255, true, null) + ->comment_site ('varchar', 255, true, null) + ->comment_content ('text', 0, true) + ->comment_words ('text', 0, true, null) + ->comment_ip ('varchar', 39, true, null) + ->comment_status ('smallint', 0, true, 0) + ->comment_spam_status ('varchar', 128, true, 0) + ->comment_spam_filter ('varchar', 32, true, null) + ->comment_trackback ('smallint', 0, false, 0) + + ->primary('pk_comment','comment_id') + ; + +/* References indexes +-------------------------------------------------------- */ +$_s->category->index ('idx_category_blog_id', 'btree', 'blog_id'); +$_s->category->index ('idx_category_cat_lft_blog_id', 'btree', 'blog_id', 'cat_lft'); +$_s->category->index ('idx_category_cat_rgt_blog_id', 'btree', 'blog_id', 'cat_rgt'); +$_s->setting->index ('idx_setting_blog_id', 'btree', 'blog_id'); +$_s->user->index ('idx_user_user_default_blog', 'btree', 'user_default_blog'); +$_s->permissions->index ('idx_permissions_blog_id', 'btree', 'blog_id'); +$_s->post->index ('idx_post_cat_id', 'btree', 'cat_id'); +$_s->post->index ('idx_post_user_id', 'btree', 'user_id'); +$_s->post->index ('idx_post_blog_id', 'btree', 'blog_id'); +$_s->media->index ('idx_media_user_id', 'btree', 'user_id'); +$_s->post_media->index ('idx_post_media_post_id', 'btree', 'post_id'); +$_s->log->index ('idx_log_user_id', 'btree', 'user_id'); +$_s->comment->index ('idx_comment_post_id', 'btree', 'post_id'); + +/* Performance indexes +-------------------------------------------------------- */ +$_s->comment->index ('idx_comment_post_id_dt_status', 'btree', 'post_id', 'comment_dt', 'comment_status'); +$_s->post->index ('idx_post_post_dt', 'btree', 'post_dt'); +$_s->post->index ('idx_post_post_dt_post_id', 'btree', 'post_dt','post_id'); +$_s->post->index ('idx_blog_post_post_dt_post_id', 'btree', 'blog_id','post_dt','post_id'); +$_s->post->index ('idx_blog_post_post_status', 'btree', 'blog_id','post_status'); +$_s->blog->index ('idx_blog_blog_upddt', 'btree', 'blog_upddt'); +$_s->user->index ('idx_user_user_super', 'btree', 'user_super'); + +/* Foreign keys +-------------------------------------------------------- */ +$_s->category->reference('fk_category_blog','blog_id','blog','blog_id','cascade','cascade'); +$_s->setting->reference('fk_setting_blog','blog_id','blog','blog_id','cascade','cascade'); +$_s->user->reference('fk_user_default_blog','user_default_blog','blog','blog_id','cascade','set null'); +$_s->permissions->reference('fk_permissions_blog','blog_id','blog','blog_id','cascade','cascade'); +$_s->permissions->reference('fk_permissions_user','user_id','user','user_id','cascade','cascade'); +$_s->post->reference('fk_post_category','cat_id','category','cat_id','cascade','set null'); +$_s->post->reference('fk_post_user','user_id','user','user_id','cascade','cascade'); +$_s->post->reference('fk_post_blog','blog_id','blog','blog_id','cascade','cascade'); +$_s->media->reference('fk_media_user','user_id','user','user_id','cascade','cascade'); +$_s->post_media->reference('fk_media','media_id','media','media_id','cascade','cascade'); +$_s->post_media->reference('fk_media_post','post_id','post','post_id','cascade','cascade'); +$_s->ping->reference('fk_ping_post','post_id','post','post_id','cascade','cascade'); +$_s->comment->reference('fk_comment_post','post_id','post','post_id','cascade','cascade'); +$_s->log->reference('fk_log_blog','blog_id','blog','blog_id','cascade','set null'); + +/* PostgreSQL specific indexes +-------------------------------------------------------- */ +if ($_s->driver() == 'pgsql') +{ + $_s->setting->index ('idx_setting_blog_id_null', 'btree', '(blog_id IS NULL)'); + $_s->media->index ('idx_media_media_path', 'btree', 'media_path', 'media_dir'); +} +?> \ No newline at end of file diff --git a/inc/dbschema/upgrade-cli.php b/inc/dbschema/upgrade-cli.php new file mode 100644 index 0000000..13613e5 --- /dev/null +++ b/inc/dbschema/upgrade-cli.php @@ -0,0 +1,52 @@ +#!/usr/bin/env php +con->begin(); + try { + $changes = dotclearUpgrade(&$core); + } catch (Exception $e) { + $core->con->rollback(); + throw $e; + } + $core->con->commit(); + echo 'Upgrade process successfully completed ('.$changes."). \n"; + exit(0); +} +catch (Exception $e) +{ + echo $e->getMessage()."\n"; + exit(1); +} +?> \ No newline at end of file diff --git a/inc/dbschema/upgrade.php b/inc/dbschema/upgrade.php new file mode 100644 index 0000000..5a1b812 --- /dev/null +++ b/inc/dbschema/upgrade.php @@ -0,0 +1,142 @@ +getVersion('core'); + + if ($version === null) { + return false; + } + + if (version_compare($version,DC_VERSION,'<') == 1) + { + try + { + if ($core->con->driver() == 'sqlite') { + throw new Exception(__('SQLite Database Schema cannot be upgraded.')); + } + + # Database upgrade + $_s = new dbStruct($core->con,$core->prefix); + require dirname(__FILE__).'/db-schema.php'; + + $si = new dbStruct($core->con,$core->prefix); + $changes = $si->synchronize($_s); + + /* Some other upgrades + ------------------------------------ */ + # Populate media_dir field (since 2.0-beta3.3) + if (version_compare($version,'2.0-beta3.3','<')) + { + $strReq = 'SELECT media_id, media_file FROM '.$core->prefix.'media '; + $rs_m = $core->con->select($strReq); + while($rs_m->fetch()) { + $cur = $core->con->openCursor($core->prefix.'media'); + $cur->media_dir = dirname($rs_m->media_file); + $cur->update('WHERE media_id = '.(integer) $rs_m->media_id); + } + } + + if (version_compare($version,'2.0-beta7.3','<')) + { + # Blowup becomes default theme + $strReq = 'UPDATE '.$core->prefix.'setting '. + "SET setting_value = '%s' ". + "WHERE setting_id = 'theme' ". + "AND setting_value = '%s' ". + 'AND blog_id IS NOT NULL '; + $core->con->execute(sprintf($strReq,'blueSilence','default')); + $core->con->execute(sprintf($strReq,'default','blowup')); + } + + if (version_compare($version,'2.1-alpha2-r2383','<')) + { + $schema = dbSchema::init($core->con); + $schema->dropUnique($core->prefix.'category',$core->prefix.'uk_cat_title'); + + # Reindex categories + $rs = $core->con->select( + 'SELECT cat_id, cat_title, blog_id '. + 'FROM '.$core->prefix.'category '. + 'ORDER BY blog_id ASC , cat_position ASC ' + ); + $cat_blog = $rs->blog_id; + $i = 2; + while ($rs->fetch()) { + if ($cat_blog != $rs->blog_id) { + $i = 2; + } + $core->con->execute( + 'UPDATE '.$core->prefix.'category SET ' + .'cat_lft = '.($i++).', cat_rgt = '.($i++).' '. + 'WHERE cat_id = '.(integer) $rs->cat_id + ); + $cat_blog = $rs->blog_id; + } + } + + if (version_compare($version,'2.1.6','<=')) + { + # ie7js has been upgraded + $ie7files = array ( + 'ie7-base64.php ', + 'ie7-content.htc', + 'ie7-core.js', + 'ie7-css2-selectors.js', + 'ie7-css3-selectors.js', + 'ie7-css-strict.js', + 'ie7-dhtml.js', + 'ie7-dynamic-attributes.js', + 'ie7-fixed.js', + 'ie7-graphics.js', + 'ie7-html4.js', + 'ie7-ie5.js', + 'ie7-layout.js', + 'ie7-load.htc', + 'ie7-object.htc', + 'ie7-overflow.js', + 'ie7-quirks.js', + 'ie7-server.css', + 'ie7-standard-p.js', + 'ie7-xml-extras.js' + ); + foreach ($ie7files as $f) { + @unlink(DC_ROOT.'/admin/js/ie7/'.$f); + } + } + + $core->setVersion('core',DC_VERSION); + $core->blogDefaults(); + + # Drop content from session table + $core->con->execute('DELETE FROM '.$core->prefix.'session '); + + # Empty templates cache directory + try { + $core->emptyTemplatesCache(); + } catch (Exception $e) {} + + return $changes; + } + catch (Exception $e) + { + throw new Exception(__('Something went wrong with auto upgrade:'). + ' '.$e->getMessage()); + } + } + + # No upgrade? + return false; +} +?> \ No newline at end of file diff --git a/inc/digests b/inc/digests new file mode 100644 index 0000000..8ad2662 --- /dev/null +++ b/inc/digests @@ -0,0 +1,531 @@ +3a1c6cc728dddc258091a601f28a9c12 ./inc/swf/swfupload.swf +362b9537b53c8d3eb363598e5f38fb8b ./inc/swf/player_mp3.swf +9dcb71aec92e94b1b905192412a1f2a5 ./inc/swf/player_flv.swf +18ff6240e31ccadc7e1a63db0afb9ae0 ./inc/core/class.dc.media.php +d14d28e70ccb6028c038861728298329 ./inc/core/class.dc.update.php +096468190e67d8e3ff44c6f4a81fa4b1 ./inc/core/class.dc.categories.php +8fbf442f092b6da5e18ab55766bdde2a ./inc/core/class.dc.xmlrpc.php +42c635f3085466704b8ea752c02c9918 ./inc/core/class.dc.error.php +6558c346e6308e15f7c39ba051347d26 ./inc/core/class.dc.utils.php +0191ee5ffb45f0af14e27d07ea4c077d ./inc/core/class.dc.rest.php +2cdfe25f28ba62d3e2e9293931deb43e ./inc/core/class.dc.themes.php +466e62c97781015f72d27e4de1c3ab0b ./inc/core/class.dc.auth.php +494c9a4c0c2494b69c7d31ab25157455 ./inc/core/class.dc.rs.extensions.php +2376b6e6399d9bff92d39067dc35c321 ./inc/core/class.dc.trackback.php +bfbb0c6cb9a699929e2bf3c4c29fef4a ./inc/core/class.dc.settings.php +036a7b3ec5634cdad6c555ba215ae19b ./inc/core/class.dc.blog.php +1c1338e5f700ad38dba4801741251597 ./inc/core/class.dc.modules.php +1453376f19e35d3bc203a21380ba89ad ./inc/core/class.dc.core.php +d9261f6761ffc3e8d14293d196c961e7 ./inc/clearbricks/net/class.net.socket.php +280613489841de5b4ec85ee300851592 ./inc/clearbricks/zip/class.unzip.php +056182476f51e6c5e80cf0460524e0dd ./inc/clearbricks/zip/class.zip.php +500f1a3a8b33c149157741489ca51ad5 ./inc/clearbricks/mail/class.socket.mail.php +0bd7854fbca81ae4a6f78a75e9dd4974 ./inc/clearbricks/mail/class.mail.php +567eadb4af2b986d1a28a0f243255522 ./inc/clearbricks/rest/class.rest.php +c86dcac25e84dc49a0ab98fd6befeb0f ./inc/clearbricks/dblayer/class.pgsql.php +4023755972fdc74509bc49e70353245b ./inc/clearbricks/dblayer/class.mysql.php +fa10d27aa59682a59ffa13eadf8b664c ./inc/clearbricks/dblayer/class.sqlite.php +1c35e6a84a5db695dc9b9f8a0e913f3b ./inc/clearbricks/dblayer/dblayer.php +45f56a2cc770dce9c3db6ba48af22dd5 ./inc/clearbricks/dblayer/class.cursor.php +95660aed4163cea3edefbf722c971f50 ./inc/clearbricks/html.validator/class.html.validator.php +cd01379889d351003cdf481163edd159 ./inc/clearbricks/html.filter/class.html.filter.php +0f9ffdd56e5848cf7da180cd154453a0 ./inc/clearbricks/image/class.image.tools.php +03e7cf2145d28aeedf29a7c061f8e4f9 ./inc/clearbricks/image/class.image.meta.php +546fde4538dd36615535f9ca1abc9a7a ./inc/clearbricks/filemanager/class.filemanager.php +da9d2c8705847220fe0645b0ba81e0aa ./inc/clearbricks/pager/class.pager.php +93a9889af02b59605a8b7257dacaa6d5 ./inc/clearbricks/net.http.feed/class.feed.parser.php +1f01f605ca981b5aa6c3954ce00c1c3f ./inc/clearbricks/net.http.feed/class.feed.reader.php +74b2a9cb057b9c7fa81ebb8a23f6c722 ./inc/clearbricks/net.xmlrpc/class.net.xmlrpc.php +09d98ed0469c11fe6a64d5add21cf0bd ./inc/clearbricks/dbschema/class.dbschema.php +3d6b710784806c85a63c99a8f13b0b7d ./inc/clearbricks/dbschema/class.mysql.dbschema.php +85ebfeb20519bf427d4ca87dcd0d4d13 ./inc/clearbricks/dbschema/class.sqlite.dbschema.php +2d08b40008b003f7a46befd1a77f4fb3 ./inc/clearbricks/dbschema/class.dbstruct.php +9f528ba8e5ef50a372a4cabc778cfcbe ./inc/clearbricks/dbschema/class.pgsql.dbschema.php +e8c5e70379f9d5b042d0a48d42559c1b ./inc/clearbricks/template/class.template.php +f61cf71413b6ab77edb00f5a512a73fd ./inc/clearbricks/_common.php +e3cc1e949b8cc8b2c48fb44f88861801 ./inc/clearbricks/url.handler/class.url.handler.php +d630292807c771d0e6108f8cccf9204a ./inc/clearbricks/common/lib.form.php +8cf4506eabae4a66014b25126153e44b ./inc/clearbricks/common/lib.text.php +53f8e535da21c1f1ec0246a643d01993 ./inc/clearbricks/common/tz.dat +66f31da31787db17a7ebb57421f757b8 ./inc/clearbricks/common/lib.l10n.php +007d3a3c24ff185327db271a65d9ef69 ./inc/clearbricks/common/lib.crypt.php +f0fb3f420cdeb4fd482ec43482b4e967 ./inc/clearbricks/common/_main.php +710e0b928554748db4a7d1846595a1f8 ./inc/clearbricks/common/lib.date.php +a318b8492bdb59b25ac93eb738013099 ./inc/clearbricks/common/lib.html.php +c8647ddc62dfbfdf69d469bfe03a0eb4 ./inc/clearbricks/common/lib.files.php +26b1be314b40bd3ebf624a38f1e0edb8 ./inc/clearbricks/common/lib.http.php +7d92d7db792825e01bff2d837095f313 ./inc/clearbricks/net.http/class.net.http.php +4bdfaf313a531de79e76c4b8b2d066c2 ./inc/clearbricks/text.wiki2xhtml/class.wiki2xhtml.php +2bed897d0ca4fd8aa7bb0b496fa6d1c2 ./inc/clearbricks/session.db/class.session.db.php +5034bd1336f60b708d9b1e980745988a ./inc/config.php.in +ff28eb3d5e9ae5cf909d5ec828c12de0 ./inc/admin/lib.pager.php +8ae4aa567cd1134818297268cb79e42f ./inc/admin/prepend.php +a6b91b473f4ad91fa41ef729fe90f24e ./inc/admin/class.dc.menu.php +39d16d043b0ad50ed0d73a2e49f83025 ./inc/admin/lib.dc.page.php +f9c5a0c91995a57e6baf126bcbd8b363 ./inc/dbschema/upgrade.php +d59926193023ae80dadb0c38ef347923 ./inc/dbschema/upgrade-cli.php +94fc7bf265d59925e1522d9e373bc1fe ./inc/dbschema/db-schema.php +209634bb0238704c4874c35d615ae59e ./inc/.htaccess +0176f5a9b0bac43ab1e1bbe33ed031cd ./inc/prepend.php +6038f9fb2eae878766345ffa586d401b ./inc/load_plugin_file.php +2921e08ddb06de37a3a8d5a1f3fcc888 ./inc/public/lib.tpl.context.php +c6f97bb39ca5107c55009ebf5e788a46 ./inc/public/prepend.php +d89e9d192b1c4181122a0f10fa69f298 ./inc/public/lib.urlhandlers.php +f60ba2b8f32356dd8ab4eee7ae4bb5d4 ./inc/public/rs.extension.php +554c0a70e8cd904d036100bfea1399fa ./inc/public/class.dc.template.php +28c6875823874e3583f035e138f0f705 ./inc/public/default-templates/atom.xml +689693d92c875db96a5bea4b306a4135 ./inc/public/default-templates/rss2.xml +a7006baa75d1c133d57acbe1f559abce ./inc/public/default-templates/rss2.xsl +252faf814965810e53ceaebca99110b8 ./inc/public/default-templates/rss2-comments.xml +9fc1fe3303129e8f38e5853daa71c11e ./inc/public/default-templates/atom-comments.xml +51adbab39d35dfd7a53bde657dd6de09 ./inc/public/default-templates/password-form.html +8cba75d3dfc9154015eb95b64e64e083 ./inc/core_error.php +4f5bbbb21f6fcb084682403822c85337 ./admin/js/ie7/IE7.js +288656dde1e8e77e7da43fe71931eeba ./admin/js/ie7/IE8.js +45becbb1ba3486fa9961b9c47614d2a0 ./admin/js/ie7/blank.gif +15c61b8ebd70424b725a8e39c7ca80c9 ./admin/js/ie7/ie7-recalc.js +e94e0c941ea37d090c39ef10c06a02f5 ./admin/js/ie7/ie7-squish.js +3090e7db27d11c74c19d41489d91af30 ./admin/js/jsToolBar/jsToolBar.js +92c3d043218f868cf339b120dd6d51b7 ./admin/js/jsToolBar/popup_posts.js +e3f0393f5bc344afddb314075193f8de ./admin/js/jsToolBar/popup_link.js +fdf73b7d33b9d76e223d42a155eeeacd ./admin/js/jsToolBar/popup_media.js +bd64332e1fbced1a9921d8fe30380006 ./admin/js/jsToolBar/jsToolBar.dotclear.js +15f0e8797ab0c5f256d03ee4b747686f ./admin/js/jsToolBar/jsToolBar.wysiwyg.js +050846e84f432233d2290997e6a20783 ./admin/js/color-picker.js +08451c09111e763c2354993025b07a66 ./admin/js/_comment.js +2819411a33e1dce79a21aeceaed37a5e ./admin/js/_post.js +787f768271c8bb6b582b102c68a4211f ./admin/js/common.js +e3b5113a5cfed6a1d9dfa72834e5fb0d ./admin/js/_preferences.js +fb7b1c55f3f25ef21f94cb237bb88b88 ./admin/js/_index.js +44c7923c51c9e8b5185d70078a1652cc ./admin/js/dragsort-tablerows.js +eadf36bbd468ceb62957c39b82cb1b07 ./admin/js/_users.js +cf014d803ae8195a2473b48b1f2c92b6 ./admin/js/_langs.js +a4f58f2e708d54d966341654a1b9710f ./admin/js/filter-controls.js +bfeba52298d8b24e30236eb02e6b1f60 ./admin/js/_media.js +a90da2f0f50f7aff0bc42990b04ca921 ./admin/js/_blog_theme.js +334a1345290da857abe41f3807c14967 ./admin/js/date-picker.js +81b61be64f338c2fd40da2bf47d2183e ./admin/js/_categories.js +49e972305f261af8830eac093dbed82f ./admin/js/confirm-close.js +dacda4414ed2d1db6b25ed16bdcc8ee9 ./admin/js/_media_item.js +10b1885ee8c7ad1c439bc3de868d4bb4 ./admin/js/_trackbacks.js +478c38cb403ab2cfb6b0affac12d3148 ./admin/js/jquery/jquery.pageTabs.js +447ce7210d6451137e4e93ac39cd9c8f ./admin/js/jquery/jquery.farbtastic.js +ce7a22089d470d15dc6a061bf7fe3d09 ./admin/js/jquery/jquery.bgFade.js +aee44d7ab273cd5d53611bad4ab0e11b ./admin/js/jquery/jquery.js +7f5f5bb62524a0ec4be1985031e7e141 ./admin/js/jquery/jquery.modal.js +93e11ef8585fbfa48f6dc595eb17a12c ./admin/js/jquery/jquery.biscuit.js +ad20456532afaf966bdc8ee50d00209d ./admin/js/jquery/jquery.candyUpload.js +aa314073e0ef73b815959563872f6c2e ./admin/js/_permissions.js +614f3c5a1eec10b7b83f4c0f38b2e67b ./admin/js/_posts_list.js +b46e51e327a0bb8f2711f230fc1467b0 ./admin/js/tool-man/dragsort.js +814404153ee1d350adf4bf7d1eae4cf8 ./admin/js/tool-man/core.js +6084f5f1fbcb14b085014ffa06961029 ./admin/js/tool-man/drag.js +02fba17f9a80f43ad07c55f2e092e7de ./admin/js/tool-man/coordinates.js +7d13dc9c59316624c051e6256c86bcb7 ./admin/js/tool-man/events.js +af77cd03cd87c611f1f495d6d29bab44 ./admin/js/tool-man/css.js +87aabde2f9d09bac13b8483e369cca38 ./admin/js/tool-man/cookies.js +fd92ba025b34df5e3784ae9cca6c4f8d ./admin/js/_permissions_blog.js +20f7eabec172e5c6cb511181e1b1ae57 ./admin/js/_comments.js +f0f861db8bed322c14508f592aeef119 ./admin/js/_plugins.js +29698c9e3ac842ca5c30abe9a69b338a ./admin/js/_category.js +00db46ceb034d8e909105225f4a0a5d4 ./admin/blogs.php +e487586329acb6096938fd9dfe626a70 ./admin/posts_actions.php +0fe85f696c9210e87d98f9987433e991 ./admin/blog_del.php +8e45eb714a43536dbfb5e99d6d53ca26 ./admin/update.php +f73c46ef14a0e1b75eaf3cb58c6ccecf ./admin/plugins.php +d2751a29c317ba588b12cb0f00f3f21f ./admin/popup_posts.php +b816dd28a252d2a2727365b48f41e6bb ./admin/style/jsToolBar/jsToolBar.css +3e0f67a5296128dbe1857c1935f6da47 ./admin/style/jsToolBar/bt_link.png +64cdd7af332808399e65fa0538761c2d ./admin/style/jsToolBar/resize.png +6a388ba1cdeff25c79d540333b96ed27 ./admin/style/jsToolBar/bt_clean.png +a6ae01491523b9335334eea1b98c136f ./admin/style/jsToolBar/bt_img_select.png +828adda895735a8624fd819506078af7 ./admin/style/jsToolBar/bt_br.png +e5aae58c14ca63c366fe02acec03d928 ./admin/style/jsToolBar/bt_em.png +0c7181b5c37930f422fb9e6e7488c1d9 ./admin/style/jsToolBar/bt_img.png +ee7ee162173d1b91896415988e8cd006 ./admin/style/jsToolBar/bt_bquote.png +47c71f6ee3cf31296ff1f18348748754 ./admin/style/jsToolBar/bt_ins.png +e9f233c1c309337911b5b03fb9e1dbc4 ./admin/style/jsToolBar/bt_pre.png +22ad5189d9d94f9a24af5311ad06805b ./admin/style/jsToolBar/bt_paragraph.png +2ca06c1c3e80079ea378fe061e4cfdc3 ./admin/style/jsToolBar/bt_code.png +78d7a07a669055db5c3966edc31c94e4 ./admin/style/jsToolBar/bt_ol.png +a3a4c43798d387734737ed81a65eb7f9 ./admin/style/jsToolBar/bt_quote.png +94a2fd910832b31e18b4bb4e63f9aa79 ./admin/style/jsToolBar/bt_strong.png +e7e674fbd3612010f154475c449b3b79 ./admin/style/jsToolBar/bt_del.png +e43a1380a8ae14425ca9ce400dd336b7 ./admin/style/jsToolBar/bt_post.png +39f73a440303baed6920a769370091da ./admin/style/jsToolBar/bt_ul.png +dc66f1288966eba4739b35f590b43e41 ./admin/style/candyUpload/style.css +caa11e523e5a3ed38d90480bed5d5a73 ./admin/style/candyUpload/loader.png +0f4c059f8aceadfb2dd932e7a02ce22a ./admin/style/candyUpload/cancel.png +493914ba4fd6581eb119500982c9b137 ./admin/style/msg-error.png +d8d0578b583b3879b3ee697fb4068648 ./admin/style/modal/modal.css +14a0936bd54fd18c22b5e7fb86ba26a3 ./admin/style/modal/loader.gif +4134330cedefac4a9075a7756ca496bd ./admin/style/modal/close.png +2f3a444b380a72b9073880cd7d22ae43 ./admin/style/package.png +7c598bafd53a127ee25043a7b1956e96 ./admin/style/default.css +ff0826bd48edc94b38534ce3d2d26997 ./admin/style/footer-bg.png +d905059cafb6ddd38cabba894c3dbee1 ./admin/style/tab-bg.png +2f7d618efdcae3859b36bbfa38fc75bf ./admin/style/page-bg.png +9c3e7b71f42e2d6c64b52fe7d46d5f16 ./admin/style/grid.png +003b8b1d1103cff11a707c5f80861a75 ./admin/style/default-rtl.css +5a7ae1d8c8b2343a9e5a4aebf4234392 ./admin/style/farbtastic/marker.png +2b6d304868ff398c17252b7b0a0414c4 ./admin/style/farbtastic/wheel.png +fbbd113ed6e6cf4adcab0f720b3b9b9c ./admin/style/farbtastic/farbtastic.css +c6dc921c0d6f2197793d9174b4267ca0 ./admin/style/farbtastic/mask.png +5afe28dbeb084fc5cd47212fa33b300b ./admin/style/tab-n-l.png +0b57db80571f538897e663bee26cb5a2 ./admin/style/tab-n-r.png +57688345aa080a9a391efc40608ce98b ./admin/style/dotclear-logo.png +af7d5adfaf36b1b1d83061295d5f68da ./admin/style/msg-std.png +6bc7580d52332c7267cb94f357630700 ./admin/style/drag.png +6fbf1d5cf4953ace09e5041a53d477ec ./admin/style/head-bg.png +4606f74acbdf16980fb16b8bc1e60099 ./admin/style/tab-c-l.png +b4671dcafdcd2a1ba6450d03acfce3b3 ./admin/style/tab-c-r.png +5625c7bc5997742b45925105fd9a4303 ./admin/style/magnifier.png +895cb5dd1b08be6bbf3ebd423248e3be ./admin/style/cat-bg.png +28551d64a9bbc7045c4b8eff4869afbe ./admin/style/iesucks.css +37e482ed14e13a1a8a141deb0eea81f2 ./admin/style/date-picker.css +60561d6c50898f057cc37eed843be317 ./admin/style/tab-l-l.png +8e603ba37b2b50e342a3135a6e2c2127 ./admin/style/head-logo.png +4b7349095e157bd0e83c841cb2d3747d ./admin/style/tab-l-r.png +e6e2cc17d4e986318d8b5a7750918157 ./admin/xmlrpc.php +e19529bc96ec56b62aa00e0647c15020 ./admin/auth.php +128057016b1339ef139cdb3d5fda9300 ./admin/post.php +fd589b6457f2d38e050aea8059ee4d4c ./admin/permissions.php +871d5fb3cf0490d2a7c1938fda35e438 ./admin/blog.php +d7023399307c45b30a3f34d180528841 ./admin/plugin.php +8df147fc78f19b966494c221ed3aa131 ./admin/media.php +045d75fc9de350bb0492beadf2d7fe69 ./admin/media_item.php +f0adbe078cc42ac3ec356b1fa2cd67cd ./admin/images/plus.png +2e6ca41f8d5d7c256594ffcc05b06e24 ./admin/images/menu/edit.png +097a854b6f9cbe35a0d09b01f745b487 ./admin/images/menu/blogs.png +d9edc49028ec933be21a2cde223cf55f ./admin/images/menu/dashboard.png +7a45e5d3af30b8b2f6e481b74ed18e08 ./admin/images/menu/update.png +778ef6ba7b0569d8c2a33eb036dfdcb1 ./admin/images/menu/plugins.png +af904ee4f98c3d0454f970eb90198cf7 ./admin/images/menu/blog-theme-b.png +bfed5f95ca5157d3fde0f4e4a4eaa9a3 ./admin/images/menu/media.png +4f4b1dab66fa2901815c0fec68a39371 ./admin/images/menu/entries.png +da47c798afefd12b44076cb827c6d019 ./admin/images/menu/comments.png +36c86b1fea44340979269e5d0653448d ./admin/images/menu/search.png +91e09572a6d2b47498eb7633808fccbd ./admin/images/menu/user-pref-b.png +15c7649c7f91216e9221c6114e941f48 ./admin/images/menu/blog-pref-b.png +db79ab64acee2cd9b7ac686deea28737 ./admin/images/menu/entries-b.png +00e426d4817de89ec7586c162c10ad74 ./admin/images/menu/users.png +05ddb3df17ac3336804ab562d1dea18c ./admin/images/menu/edit-b.png +6c24e8664283448459c6d2ec96863b25 ./admin/images/menu/comments-b.png +ae2e6d937abe776bf651094a736aa003 ./admin/images/menu/categories.png +f7a4f2dd4f9b5c679e2744822e56ed48 ./admin/images/menu/langs.png +86583b1fd690088cd78f91983aaf8575 ./admin/images/dotclear_pw.png +50bf28433834e6d2f6f46d1b84421d2b ./admin/images/media/video.png +8e35fccfaa42070297cef723428183ba ./admin/images/media/blank.png +7e619d7762995a3c3ef9edfb3b6b4c92 ./admin/images/media/spreadsheet.png +c2b2d27914d57241d3d0e96a66ede1ca ./admin/images/media/package.png +487708f4b8f6fa0ecff78f26ded3806a ./admin/images/media/html.png +90864902424cf16cd85d2a6e54fe0272 ./admin/images/media/document.png +be57e76497791a2540d91f9149f38a6b ./admin/images/media/audio.png +6884619665a6a6a91996236dd26ad2fc ./admin/images/media/text.png +27013d32dfc30e5512ff184c2869bb3f ./admin/images/media/image.png +34f401c85ee26edfffb2c317ae2b1b54 ./admin/images/media/presentation.png +c6db076f177ccaf062d017c5db228085 ./admin/images/media/folder.png +4d8611170bd9173aa87cfbd4878ac588 ./admin/images/media/executable.png +61334007afc261a93d677bd3460ee36d ./admin/images/trash.png +c8806b7d90e29532ec65e74933c4ea67 ./admin/images/selected.png +e7c196b87a5e022549b71e6f4e811d18 ./admin/images/menu_on.png +c3380a4422bb8a7e8756a6a167ddea22 ./admin/images/check-off.png +355fbab6dc8dc6c779ba687bcc187fd7 ./admin/images/scheduled.png +913ff19cacf4d03fc835b4255c236c79 ./admin/images/picker.png +3ee61de988743c744af9b9224d35284b ./admin/images/minus.png +b742e51edacbf99451e12c5bb01531b0 ./admin/images/junk.png +f86e9d6679d8b27334bbb8df82b1c7d9 ./admin/images/menu_off.png +45c5ccf8249c5ec4800b9e0c3d34b7ca ./admin/images/check-wrn.png +02437c955382fa358b357632557a6f4e ./admin/images/attach.png +dfab5698cd3abbb30538331690413d30 ./admin/images/locker.png +cb8f61218854ef04d73714cc52aa5dbc ./admin/images/check-on.png +07181f8c47f322410aea182338b031b3 ./admin/images/date-picker.png +fc080751a6ae822596cbdb54c97c4fd6 ./admin/images/edit-mini.png +93d023c510f85f951839c251814291ab ./admin/images/noscreenshot.png +8776864d4c4505e2cc4040a418497bc9 ./admin/images/help.png +87f5dea12797a8eb428ea1954866584c ./admin/index.php +f10ae181969bd912a9eb68da2956c23d ./admin/permissions_blog.php +64c3e93f7e541ed757142e5de18380e9 ./admin/posts.php +17036fa2d8a7656614b781a4c7b9426f ./admin/comments.php +9c7d01d916f3aa1d881ee7819667263b ./admin/popup_link.php +3f65bb3cbd860e9fb81f3b2d6277c5b7 ./admin/services.php +290ee52f1bc1a016f251f036d4ff2478 ./admin/search.php +3548d9af451b2e6af1809b555d4c88e8 ./admin/blog_theme.php +9bf0b3af8f41807602ef2323dd006762 ./admin/comments_actions.php +fbdcee6ef06a409e23260133941e4244 ./admin/comment.php +a701b5ad177608322c0008ba9f424e11 ./admin/user.php +3b1fcad912db22bc88c58011e6fb720d ./admin/dispatcher.php +3f23b0534157d6ed65e94c1b8ea9dcd1 ./admin/preferences.php +6c154f459f2f87a830edc64d949a6db0 ./admin/users.php +e5375f24957f9d5d52631519e049d266 ./admin/install/index.php +5c09c6c55a50b6ad49beb4147d4dea49 ./admin/install/check.php +ac45ae7c40f5e3412e6ba051420ca33f ./admin/install/wizard.php +487561551d32cae95ad8a7fd15485617 ./admin/category.php +153aab11365f581e9f0b50378013d4e2 ./admin/post_media.php +c4ce01f48c57bd31b755c102486ae9f9 ./admin/blog_pref.php +0d89d53b637614bde68935d36e77fee0 ./admin/categories.php +7b91f4c7e8861f0af36c7a08a7b2df5e ./admin/trackbacks.php +7411861ab76537f6c52d7b6cdc243a32 ./admin/langs.php +597e43bb54850373eeb2c2676f30f3fd ./locales/en/date.po +fc51ec4fe28cadc83913b369fc77d65a ./locales/en/help/comments.html +d5122c309d77b7a499fab7dec52e9b29 ./locales/en/help/blog_pref.html +5591fcbe6853807c82659bddda528325 ./locales/en/help/media.html +c260a45249e6e678ce089d7ef6b88e98 ./locales/en/help/post.html +efc9a224297e6902a5f0efa196bc7c6f ./locales/en/help/wiki.html +601f769c326ea8920e0ff67e64cb9c01 ./locales/en/help/categories.html +dac7cda43ac667f5689ef48e8ca36c4d ./locales/en/help/user_pref.html +09352986157f34af6730061ce06bd8cd ./locales/en/help/posts.html +bcaf88842838bc943ec14f2dec691466 ./locales/en/date.lang.php +086e64533816640d615e69afeba0b680 ./locales/en/resources.php +d7f6cc471b5bc7cd871e4d395b8c276e ./locales/fr/date.po +087aaec908f335474f273d81fcfec249 ./locales/fr/help/core_media.html +1019b0c0fd0cf1e2b1b354e0d1df4f18 ./locales/fr/help/core_user_pref.html +a9f897d204180419de34dcfdc9b18f76 ./locales/fr/help/themeEditor.html +2bc53951d2998ab67979a5b1ea4f3df9 ./locales/fr/help/core_comments.html +996bbf4b20290530884d25844b1ee32d ./locales/fr/help/blowupConfig.html +2f8538f01d3c3a46faa42595f1bc42ef ./locales/fr/help/core_categories.html +5b1623e4a9bb1b32ec9f9a4b7bae3366 ./locales/fr/help/core_post.html +e38f790349f0accca7c63a7f76671c0c ./locales/fr/help/core_posts.html +590e7cdb6a0010defabfae0c5e1554c2 ./locales/fr/help/core_wiki.html +068c9bc2bc27a2478cb5af2fd97e9645 ./locales/fr/help/core_blog_pref.html +b251c88e5e41bf4b381d4398018c5fbb ./locales/fr/public.lang.php +9bc4415f19d72a5762c782a31bcb955f ./locales/fr/date.lang.php +e44ca473dcb048250e0fc7ec025eb91a ./locales/fr/main.po +8ba1a2c161a45493e40da4ff2955b97f ./locales/fr/plugins.po +bfff3c066a52b55cfbcf1f89d282a91a ./locales/fr/plugins.lang.php +6920fcce560d9d1c6e2b3bf007f76dc5 ./locales/fr/resources.php +97ba3984d4efc605b977a27a3811f35e ./locales/fr/public.po +fc6f85748920e451eb3231a9261c2a2e ./locales/fr/main.lang.php +d4ff299dabd4b8334cc7259d0eb65b6e ./locales/README +04abe6412946b1fa2ed72963a7f8237c ./index.php +aee44d7ab273cd5d53611bad4ab0e11b ./themes/default/js/jquery.js +0399de1c63edf55deb1cffa811905d57 ./themes/default/js/jquery.cookie.js +d7dc9f56f2b68076900853c61b8a6fcf ./themes/default/js/post.js +a802d1f382c8b22d1e6c6e28ae618498 ./themes/default/img/trackback.png +74eb29efade1edeff692446b5e6f8258 ./themes/default/img/commentmy-b.png +ef130b60877aad5a4cc8d4c5ead17317 ./themes/default/img/commentmy-t.png +f3b1ebaf5a27959228b736f87db11776 ./themes/default/img/page-bg.png +e199613e6ec2cead05b92a6f2c76e2ec ./themes/default/img/comment-b.png +90835fdf81ee294b89674795ee6ed71f ./themes/default/img/tag.png +3f7ae2737f49605199554ccac96dc748 ./themes/default/img/comment-t.png +c85f9d3ea9319236e67db78be1707478 ./themes/default/img/page-b.png +42fa213bf2a5b110afeb7552767700c6 ./themes/default/img/page-t.png +68f80507e1d6123f57c5f25f006a699f ./themes/default/img/feed.png +e4d37aac2d638c4a358a7fd4c76b2789 ./themes/default/img/attach.png +19741777bd991f387b6d01d187f9cacc ./themes/default/img/comment.png +dff6f47c5dcfce7c1a909f015f43a91b ./themes/default/img/body-bg.png +a2877d50faebc326ce5984496cb3fe3b ./themes/default/tpl/404.html +16bdc8783f0b0b181bca2922afa6707f ./themes/default/tpl/_head.html +6c96c9afa5258bfe009b97197324286c ./themes/default/tpl/category.html +94df989e651b3fab9ae5f889da8957a5 ./themes/default/tpl/_top.html +b8901ab0ebed68dc2c989fb5bca4506e ./themes/default/tpl/archive_month.html +a1751e1f10a3b96b05d0401c97e72008 ./themes/default/tpl/.htaccess +4672a386be84c3b8aabe7f0f11eadd1f ./themes/default/tpl/_footer.html +4aceb31c39646ddef57802c8e6d09cf3 ./themes/default/tpl/archive.html +c0859258eafc9dfdeb5c77310738527b ./themes/default/tpl/_mp3_player.html +3f32c76d09e83f0dc647d80ae76f561c ./themes/default/tpl/tag.html +b34754e53b51132b11c3f15e9275c196 ./themes/default/tpl/post.html +51c379d5e96b3cfff2410872ab2cdeb4 ./themes/default/tpl/user_head.html +7964b89c503810f4c29a9277b8bce384 ./themes/default/tpl/tags.html +e68a44c097d3ff407fff0efa118cec64 ./themes/default/tpl/search.html +4fd60dab641f6d4a6992091e9d001ed9 ./themes/default/tpl/home.html +d29f8d7ed1bdd0a755d696885a4086a5 ./themes/default/tpl/_flv_player.html +ffdba5c2bedd3e76d57eca1cb07e5e44 ./themes/default/_define.php +646621422212fb347c48849b2c0dce90 ./themes/default/style.css +acdc336f9249b84310c6bc541d6e66ed ./themes/default/smilies/laugh.png +e8cfd3101dc2a0cdb7a343e1b873a38f ./themes/default/smilies/cry.png +062fe26eb6105ce6bbc0d133b50c4fcc ./themes/default/smilies/confused.png +c8372d57625893f1c06a409cf1fb84d5 ./themes/default/smilies/sad.png +c1fa8d897b82f938e2abada9bfa7c2c1 ./themes/default/smilies/redface.png +f97fc26a57559afec46806aa42083d9c ./themes/default/smilies/eek.png +919a6951304ce994203f86edd3f5d359 ./themes/default/smilies/dizzy.png +5933cf36a8be5147933b6499d589eb01 ./themes/default/smilies/idea.png +d2855d2d68f6467db69219534638f4bb ./themes/default/smilies/exclam.png +93d6fed1604e9e479f65940e52884ac3 ./themes/default/smilies/lol.png +0d16e0502c576f32662ad14dfde3cf53 ./themes/default/smilies/rolleyes.png +18f5ac3609425f10e910e64d5620edda ./themes/default/smilies/cool.png +1808a6c8affe37c094a038dc983b0ffc ./themes/default/smilies/mrgreen.png +d3671aa8ccb54bbc9b89a83ba202b626 ./themes/default/smilies/smilies.txt +51b2f454563975cc4b2fcc07d31ce12d ./themes/default/smilies/alien.png +5b36ab1e0f2c2dde883a6e32cc3feebf ./themes/default/smilies/smile.png +a1650e5c1ff8e9f40ef90828011f91fa ./themes/default/smilies/normal.png +efe8138e2d0b366a9dcdbe1c6ab75eee ./themes/default/smilies/evil.png +987742e347ef66bbc2b6b9546a0aa360 ./themes/default/smilies/angry.png +83362893d53db01b5595a7e8021fcdac ./themes/default/smilies/wink.png +57a457e1818d6e9419ced9366d2e33dc ./themes/default/smilies/razz.png +9ae025a44deba07f3e3fe2c3992e5d9c ./themes/default/smilies/arrow.png +25adf8de879b3e83c12ab668bc3c983f ./themes/default/smilies/question.png +32f2a33008491d7c070d70cfc64585c0 ./themes/default/smilies/surprised.png +c75e685b085a7e188b42f995626ec3be ./themes/default/screenshot.jpg +4e6c671f9777afc2948fb172631e7611 ./themes/default/print.css +28e5e068b8b973e3d1997ba7c24205f2 ./themes/blueSilence/img/background.png +8ebf5666d9d8bac9fdeedbd17daaa348 ./themes/blueSilence/img/report.png +a58dc745b52f9bb33a44fb9ccd5a776d ./themes/blueSilence/img/rss.png +a56d97cb87cfd1970760fff3345af5d8 ./themes/blueSilence/img/tag.png +f7a34b6d7c3641b7afa0132a9723ece3 ./themes/blueSilence/img/top.jpg +f9e699b16c85dd103e725d70efdacd2f ./themes/blueSilence/img/li.png +ab2a5e87e0c395d12a221485be1ff821 ./themes/blueSilence/img/commentaire.png +4c8c6a8fe121912b6cf6a8edaa920aec ./themes/blueSilence/img/tags.png +e8bb6589fe0e7bc810acc4c350f2a54d ./themes/blueSilence/img/commentaire_bulle.png +851317b61d8b6b08d6bb58c06896df21 ./themes/blueSilence/img/attach.png +c1dda264fa5d4120717ba558f01fe652 ./themes/blueSilence/img/footer.png +986f44c4d95f0b4d30defec242f0f76d ./themes/blueSilence/img/retrolien.png +e40bfe45e815e751015bf122e16fb1f2 ./themes/blueSilence/img/sidebar_li.png +4f5fd6f1c016f670fad151b0039886e1 ./themes/blueSilence/_define.php +4c99f9d0bd6843a5484740269dd72770 ./themes/blueSilence/style.css +6c0c644258713357329a5bcac1f44768 ./themes/blueSilence/screenshot.jpg +800bcd981cdcb38b2321d465db858147 ./themes/customCSS/_define.php +d41d8cd98f00b204e9800998ecf8427e ./themes/customCSS/style.css +4cd898ae3cb55d817c1046bba6c6b9ce ./themes/customCSS/_public.php +da18cf4aaed165d14dd612ed09a377b1 ./themes/customCSS/locales/fr/main.po +eb0e5f0211f741849acfccaf155b1be6 ./themes/customCSS/locales/fr/main.lang.php +602e79fa926e9b841f3f75e95bdca48a ./themes/customCSS/_config.php +9195e781a1146a794aa7678343af4a0d ./plugins/maintenance/_define.php +b60a33878195e9855dff47abe862e26e ./plugins/maintenance/icon.png +528f065f8f506656f2ac9cdae8a1732e ./plugins/maintenance/_admin.php +343e841912410913d232241164067cf5 ./plugins/maintenance/index.php +cb304b3d12e1493f07b1323ca1c9f6b1 ./plugins/metadata/_define.php +80155a9abf9d5583262fc1928027192f ./plugins/metadata/_install.php +39b72570feafa373b59b2e37166e383c ./plugins/metadata/style.css +d6f79878139ff3b303002f529999dab2 ./plugins/metadata/_widgets.php +7c51fbb5c908a74434dd16448703a324 ./plugins/metadata/_public.php +6e3a9c34cd45a3223f72436d21183d5b ./plugins/metadata/_prepend.php +6153779453db6919728b74eb0d3f5618 ./plugins/metadata/_admin.php +3987d3c7792f3a22864bdd14cc6ab62b ./plugins/metadata/class.dc.meta.php +ea2ce91dab0b252599fd2b04eda1a0c1 ./plugins/metadata/index.php +cac0a6c35ca3fcb985246bb197c48801 ./plugins/metadata/_xmlrpc.php +f2ca37bc37ff0e5cdc95370a0431d5c1 ./plugins/metadata/tags.php +828753a0de820938df6ae3a0676e97ad ./plugins/metadata/tags.png +52d2c48f3c56b68929129d335d04a4c0 ./plugins/metadata/tag_posts.php +ea424458edbdb1f6c4c01d4486019252 ./plugins/metadata/tag-add.png +0f942eb58886c0ec269507c0f8163d7f ./plugins/metadata/post.js +3dc636d068035accb61b00ee4fe4fcac ./plugins/pages/list.php +bf0f3b795af1195b0168599d82f0c549 ./plugins/pages/_define.php +30715dda782c45e93d3725ae4df17b51 ./plugins/pages/page.php +b98d94ece8f106a2292e3c81fa5ca113 ./plugins/pages/_widgets.php +e48c5cb3b44f1b16791327bb91c0e34d ./plugins/pages/_public.php +745d97d5c53c155c822166545190f003 ./plugins/pages/icon.png +383fb9e8763e4e5bea7cd6690fc88b16 ./plugins/pages/_prepend.php +d241f50078a5286feceac6f569ca896a ./plugins/pages/_admin.php +ba920f53414aa9e243c4c2ec9c0e3b35 ./plugins/pages/index.php +ea9b46834d4d768f1030ecd809a9fbe5 ./plugins/pages/icon-big.png +cf21a309465b3d8c9b7ebb2ae58de0ea ./plugins/pages/default-templates/page.html +8d06d95623305ca4e8190eaceb7d4cfa ./plugins/pings/lib.pings.php +6f49a0a44a3df7fd9a111b43ae9ee509 ./plugins/pings/_define.php +8ed6b5e4a1c64ef157af27035dd36710 ./plugins/pings/icon.png +a004559d94ac47d448a1ca906c9e8d72 ./plugins/pings/_admin.php +58e9f5d0040e26b1e193708b9552745b ./plugins/pings/index.php +5f826c13498df394b5c7a1a4b2972903 ./plugins/pings/post.js +49c2a00d5026bcb5975519ec3673f251 ./plugins/antispam/inc/class.dc.spamfilters.php +8a94ca06ec0f7fea031a34c5e33d6c05 ./plugins/antispam/inc/lib.dc.antispam.php +3b067c387d57ae696f9c754796cfe87f ./plugins/antispam/inc/class.dc.spamfilter.php +e87f7343d0758b41867c350847544e49 ./plugins/antispam/inc/lib.dc.antispam.url.php +b3c0fc9e29e60d1d371dd54d3ddc8fee ./plugins/antispam/_define.php +2ee8dfae1cf7bbe75a0a9a6728a16a4c ./plugins/antispam/_install.php +c28748b62667080cf3a0fbf5dd98f7b2 ./plugins/antispam/style.css +26a71db6f5842bfca51614af14d40449 ./plugins/antispam/_public.php +e0a3c27c4bee15b0cc9acb47d8d5fa80 ./plugins/antispam/icon.png +e3639b0227f46b75e25b8649f8d0b525 ./plugins/antispam/_prepend.php +e70ea13ca819364ead3b295eac0ec100 ./plugins/antispam/filters/class.dc.filter.linkslookup.php +c18038c662707206bb79370a32ef3999 ./plugins/antispam/filters/class.dc.filter.words.php +32a53ea01b6cfa6d9f84fb684fb745ee ./plugins/antispam/filters/class.dc.filter.ip.php +d654ea3e8c8598fc40938395124bf141 ./plugins/antispam/filters/class.dc.filter.iplookup.php +bd95e625b15104caf95fa2c85c7126b3 ./plugins/antispam/_admin.php +4328b42921acd050f9912622d3898c24 ./plugins/antispam/index.php +b82da4aa0a7b272ae5e2de8dd7359b3a ./plugins/antispam/feed.png +56dd843cb7ae5c0e71ea479c96136352 ./plugins/antispam/antispam.js +8c6505a27374d4f1cbef3362cf6f901a ./plugins/themeEditor/_define.php +df6d24d467b24cf0914f388864ff3000 ./plugins/themeEditor/style.css +5789e6f200e5634889714946356bc0b4 ./plugins/themeEditor/_admin.php +276b5f6b0381ed5d14ad9024aaa064bf ./plugins/themeEditor/index.php +e9a020825c231f7025aac4a313f9f602 ./plugins/themeEditor/class.themeEditor.php +6c62071513731346b5a251cf1ec2c1ef ./plugins/themeEditor/help.html +f75e3f88c0dea27c23c1b02486cf485d ./plugins/themeEditor/script.js +209634bb0238704c4874c35d615ae59e ./plugins/.htaccess +34750fedb71f2858ac9c451bee109aa7 ./plugins/blogroll/icon-small.png +5be6207fc2634cafcabedca5e7708e10 ./plugins/blogroll/edit.php +dff163989fc9d1941d6689e6db4fa9f4 ./plugins/blogroll/_define.php +59d33a02127d37539506f0f5f36ce3c9 ./plugins/blogroll/class.dc.importblogroll.php +da2dbd651ff5dddcf172d86b4cb63daf ./plugins/blogroll/_install.php +4e66c188ea53d182a678a3745884fb8b ./plugins/blogroll/_widgets.php +a35970aa5074ed40c5d4b4500ab556d7 ./plugins/blogroll/_public.php +921145b71dc3516a3d4ad60b68e78dad ./plugins/blogroll/icon.png +7303c091ac6b473839dbee7d70f814dc ./plugins/blogroll/locales/en/main.po +04f114d237e28b43baada59d68ae11a3 ./plugins/blogroll/locales/en/main.lang.php +b48b67849fa06c95ee73552a44e11abe ./plugins/blogroll/_prepend.php +90afd97ac0d6f8054239da6eb9e1240b ./plugins/blogroll/_admin.php +2b17bc2179de12ae4ef23e899be89bcd ./plugins/blogroll/class.dc.blogroll.php +349a097dae6a0aa822f0108c9fae1289 ./plugins/blogroll/index.php +16c051428cc53314f5bfe269aff1b8d1 ./plugins/akismet/_define.php +6ae97039acba2c1591d13ece6932a044 ./plugins/akismet/_prepend.php +930f6da919a4a7daf63a4baec1e5117a ./plugins/akismet/class.dc.filter.akismet.php +23361f3333c6d390813bd4aece69add5 ./plugins/aboutConfig/_define.php +b8baeee677712dd72df37e3a041a353b ./plugins/aboutConfig/icon.png +b9168dfac656478fb29863363486ae2d ./plugins/aboutConfig/_admin.php +c55f2aa45c22963a96ac10ff3be277a7 ./plugins/aboutConfig/index.php +038556fbe48e919ead6c101d6902932f ./plugins/externalMedia/_define.php +bc0a1f83d40449a030d2c16793bae775 ./plugins/externalMedia/popup.js +62b92949c582abcbe0cab2627f6a986e ./plugins/externalMedia/_admin.php +d2f4c40252d0e4c974df2039681435b7 ./plugins/externalMedia/bt_video.png +f221d727652b753df02590247f062d5d ./plugins/externalMedia/index.php +cf3694d85cc49a597e0602571409a7ea ./plugins/externalMedia/post.js +3e0bd4f8a787a2d0d34f246d3ea444f1 ./plugins/widgets/_define.php +fe3f620da53a4cc011d92894b894f264 ./plugins/widgets/style.css +28836e015ca92980acdba3e19a33c1e8 ./plugins/widgets/widgets.js +1d9265ec44b487c1e2be0c437aa0b0e0 ./plugins/widgets/_widgets_functions.php +505471d9316198939b981bc47ad12d07 ./plugins/widgets/_public.php +73e41e8ae95ef82fb2eb2529d2cf1ca3 ./plugins/widgets/_default_widgets.php +848c9d774eb3c3ebb3f25c3ed0a9fac9 ./plugins/widgets/icon.png +72d242e2ed2e4550ad4a24da01deafc5 ./plugins/widgets/class.widgets.php +86644c18aac829b9ddf826280f88be0f ./plugins/widgets/_admin.php +5affcbdca523969d8ea31d09f3af621f ./plugins/widgets/index.php +3b552f7e600dd6c98edc66e7e62ad1fb ./plugins/widgets/dragdrop.js +14fbced6e7458a7e4b3e10d969b5048e ./plugins/fairTrackbacks/_define.php +a967f6943de24a3e46e35182b6c4fe8d ./plugins/fairTrackbacks/_public.php +ada0cfdf0148421317943366b71d85be ./plugins/fairTrackbacks/_prepend.php +f569f055e740ef053ff9ca5d61b03efc ./plugins/fairTrackbacks/class.dc.filter.fairtrackbacks.php +d4bf4c07c1749e71f83d4c55632b4e95 ./plugins/blowupConfig/lib/class.blowup.config.php +1942d7e37e185fb289aa16757b6e876f ./plugins/blowupConfig/_define.php +656ca7404ded88fcbe79563b012e3e65 ./plugins/blowupConfig/config.js +9efefd97ec4e70402e86aa104ac62647 ./plugins/blowupConfig/_public.php +ab20193417b32b04f4036c68801b216c ./plugins/blowupConfig/_admin.php +a93df332a256a18530195dc1673f95f2 ./plugins/blowupConfig/index.php +f3b1ebaf5a27959228b736f87db11776 ./plugins/blowupConfig/alpha-img/page-bg.png +4e391773b51ea336fb0f647cb15379ef ./plugins/blowupConfig/alpha-img/comment-b.png +78e0f7cf458db47eef8b8ff7a241ac8e ./plugins/blowupConfig/alpha-img/comment-t.png +1c7448246376dc8cecee8f0479723099 ./plugins/blowupConfig/alpha-img/page-t/flamingo.png +f4c8777ac3a935e7b9f171a948a78280 ./plugins/blowupConfig/alpha-img/page-t/blank.png +68daa93bbe1ed00ff190cf851033fe93 ./plugins/blowupConfig/alpha-img/page-t/animals.png +a140e3ae9bf5dcc8c3152a315bd17cd3 ./plugins/blowupConfig/alpha-img/page-t/default.png +c1582964ea8ac500d8f1358cbc11b472 ./plugins/blowupConfig/alpha-img/page-t/typo.png +a13d367c5520f17ee7b3a2dd6cd8068f ./plugins/blowupConfig/alpha-img/page-t/roadrunner-1.png +a33e8d4310696d64bb065cddd23b5292 ./plugins/blowupConfig/alpha-img/page-t/roadrunner-2.png +c48b1a888ebd601e610a425c733367fa ./plugins/blowupConfig/alpha-img/page-t/rabbit.png +508813560e6465f057c07287ad40dd88 ./plugins/blowupConfig/alpha-img/page-t/flourish-1.png +7b79aa5c11177401d7b2cac032d09038 ./plugins/blowupConfig/alpha-img/page-t/flourish-2.png +722ad2b43138abc067ade1c4ed6d0297 ./plugins/blowupConfig/alpha-img/page-t/light-trails-1.png +ee440de20028785d2c0a4fd7b25ae060 ./plugins/blowupConfig/alpha-img/page-t/light-trails-2.png +3f9e394ed187b401c4446b77490944b6 ./plugins/blowupConfig/alpha-img/page-t/light-trails-3.png +ca76fc93ebbce051feb507869165ab6d ./plugins/blowupConfig/alpha-img/page-t/light-trails-4.png +4b3117cca2f73c47d5892684443c74fb ./plugins/blowupConfig/alpha-img/page-t/image-mask.png +ffacd6551c2bd0c863740e7c2fcc29e4 ./plugins/blowupConfig/alpha-img/page-t/butterflies.png +652d06f1c3f7057cd7ab6a01d22b72ba ./plugins/blowupConfig/alpha-img/page-b.png +52db59a23ae5743c614bf9457de0167a ./plugins/blowupConfig/alpha-img/gradient-d.png +bd908640438b6cc2088e81df0894c864 ./plugins/blowupConfig/alpha-img/gradient-l.png +d1e0bdff64011042f02910c6518b1d00 ./plugins/blowupConfig/alpha-img/gradient-m.png +81ef6980e71af45e03f56f66fa6fbd8e ./plugins/blowupConfig/help.html +67a59fdadac3ef3545015b4c0e15419d ./plugins/importExport/inc/flat/class.backupFile.php +d82d2e98a3eacc8d265a520eccb0116a ./plugins/importExport/inc/flat/class.db.export.php +38c5dbc68284930e00058d9bb98fe784 ./plugins/importExport/inc/flat/class.dc.import.php +2ba80acbd4984685a3028a5ee1cb0fce ./plugins/importExport/inc/class.dc.export.flat.php +8a883d5ee9caa0de210a91c0d160814a ./plugins/importExport/inc/class.dc.ieModule.php +5dacef6fdc0a3d9676bb2e1d28dcbeec ./plugins/importExport/inc/class.dc.import.dc1.php +50a742bd58ebf3b24c4f8f60a9fa28dd ./plugins/importExport/inc/class.dc.import.wp.php +daac7535525565d0cf272472a0f5fd22 ./plugins/importExport/inc/class.dc.import.flat.php +2740fd54e99ad819d774697a37eaf57e ./plugins/importExport/inc/class.dc.import.feed.php +5a1dfc62e8d2fdc1f1f73390e6d90ccc ./plugins/importExport/_define.php +caa11e523e5a3ed38d90480bed5d5a73 ./plugins/importExport/progress.png +7f63214bd02f1700fd236e470c19f579 ./plugins/importExport/icon.png +86c054457dacdcfda8000e02a8e71ac6 ./plugins/importExport/_admin.php +bff88e23be2c2f69d237fdcb099d0635 ./plugins/importExport/index.php +b39d8c8adaaac48561c435648faa0d64 ./plugins/importExport/script.js diff --git a/inc/load_plugin_file.php b/inc/load_plugin_file.php new file mode 100644 index 0000000..c97c5dc --- /dev/null +++ b/inc/load_plugin_file.php @@ -0,0 +1,87 @@ + \ No newline at end of file diff --git a/inc/prepend.php b/inc/prepend.php new file mode 100644 index 0000000..d5f4f8b --- /dev/null +++ b/inc/prepend.php @@ -0,0 +1,260 @@ +config.php
    file. '. + 'I need this before we can get started. Need more help? '. + 'We got it. '. + 'You can create a config.php '. + 'file through a web interface, but this doesn\'t work for all '. + 'server setups. The safest way is to manually create the file.' + ,10); +} + +require DC_RC_PATH; + +# Constants +define('DC_ROOT',path::real(dirname(__FILE__).'/..')); +define('DC_VERSION','2.1.7'); +define('DC_DIGESTS',dirname(__FILE__).'/digests'); +define('DC_L10N_ROOT',dirname(__FILE__).'/../locales'); +define('DC_L10N_UPDATE_URL','http://services.dotclear.net/dc2.l10n/?version=%s'); + +if (!defined('DC_VENDOR_NAME')) { + define('DC_VENDOR_NAME','Dotclear'); +} + +if (!defined('DC_XMLRPC_URL')) { + define('DC_XMLRPC_URL','%1$sxmlrpc/%2$s'); +} + +if (!defined('DC_ADMIN_SSL')) { + define('DC_ADMIN_SSL',false); +} + +if (defined('DC_FORCE_SCHEME_443') && DC_FORCE_SCHEME_443) { + http::$https_scheme_on_443 = true; +} + +if (!defined('DC_DBPERSIST')) { + define('DC_DBPERSIST',false); +} + +if (!defined('DC_UPDATE_URL')) { + define('DC_UPDATE_URL','http://download.dotclear.net/versions.xml'); +} + +if (!defined('DC_UPDATE_VERSION')) { + define('DC_UPDATE_VERSION','stable'); +} + +try { + $core = new dcCore(DC_DBDRIVER,DC_DBHOST,DC_DBNAME,DC_DBUSER,DC_DBPASSWORD,DC_DBPREFIX,DC_DBPERSIST); +} catch (Exception $e) { + __error($e->getMessage() + ,$e->getCode() == 0 ? + '

    This either means that the username and password information in '. + 'your config.php file is incorrect or we can\'t contact '. + 'the database server at "'.DC_DBHOST.'". This could mean your '. + 'host\'s database server is down.

    '. + '
    • Are you sure you have the correct username and password?
    • '. + '
    • Are you sure that you have typed the correct hostname?
    • '. + '
    • Are you sure that the database server is running?
    '. + '

    If you\'re unsure what these terms mean you should probably contact '. + 'your host. If you still need help you can always visit the '. + 'Dotclear Support Forums.

    ' + : '' + ,20); +} + +# If we have some __top_behaviors, we load them +if (isset($__top_behaviors) && is_array($__top_behaviors)) +{ + foreach ($__top_behaviors as $b) { + $core->addBehavior($b[0],$b[1]); + } + unset($b); +} + +http::trimRequest(); +try { + http::unsetGlobals(); +} catch (Exception $e) { + header('Content-Type: text/plain'); + echo $e->getMessage(); + exit; +} + +l10n::init(); + +$core->url->registerDefault(array('dcUrlHandlers','home')); +$core->url->register('lang','','^([a-zA-Z]{2}(?:-[a-z]{2})?(?:/page/[0-9]+)?)$',array('dcUrlHandlers','lang')); +$core->url->register('post','post','^post/(.+)$',array('dcUrlHandlers','post')); +$core->url->register('preview','preview','^preview/(.+)$',array('dcUrlHandlers','preview')); +$core->url->register('category','category','^category/(.+)$',array('dcUrlHandlers','category')); +$core->url->register('archive','archive','^archive(/.+)?$',array('dcUrlHandlers','archive')); + +$core->url->register('feed','feed','^feed/(.+)$',array('dcUrlHandlers','feed')); +$core->url->register('trackback','trackback','^trackback/(.+)$',array('dcUrlHandlers','trackback')); +$core->url->register('rsd','rsd','^rsd$',array('dcUrlHandlers','rsd')); +$core->url->register('xmlrpc','xmlrpc','^xmlrpc/(.+)$',array('dcUrlHandlers','xmlrpc')); + +$core->setPostType('post','post.php?id=%d',$core->url->getBase('post').'/%s'); + +# Store upload_max_filesize in bytes +$u_max_size = files::str2bytes(ini_get('upload_max_filesize')); +$p_max_size = files::str2bytes(ini_get('post_max_size')); +if ($p_max_size < $u_max_size) { + $u_max_size = $p_max_size; +} +define('DC_MAX_UPLOAD_SIZE',$u_max_size); +unset($u_max_size); unset($p_max_size); + +# Shutdown +register_shutdown_function('__shutdown'); + +function __shutdown() +{ + global $__shutdown; + if (is_array($__shutdown)) { + foreach ($__shutdown as $f) { + if (is_callable($f)) { + call_user_func($f); + } + } + } + + # Explicitly close session before DB connection + if (session_id()) { + session_write_close(); + } + $GLOBALS['core']->con->close(); +} + +function __error($summary,$message,$code=0) +{ + # Error codes + # 10 : no config file + # 20 : database issue + # 30 : blog is not defined + # 40 : template files creation + # 50 : no default theme + # 60 : template processing error + + if (CLI_MODE) + { + trigger_error($summary,E_USER_ERROR); + exit(1); + } + else + { + if (defined('DC_ERRORFILE') && is_file(DC_ERRORFILE)) { + include DC_ERRORFILE; + } else { + include dirname(__FILE__).'/core_error.php'; + } + exit; + } +} +?> \ No newline at end of file diff --git a/inc/public/class.dc.template.php b/inc/public/class.dc.template.php new file mode 100644 index 0000000..3045dd3 --- /dev/null +++ b/inc/public/class.dc.template.php @@ -0,0 +1,2916 @@ +remove_php = !$core->blog->settings->tpl_allow_php; + $this->use_cache = $core->blog->settings->tpl_use_cache; + + $this->tag_block = '|>)(.*?)'; + $this->tag_value = '{{tpl:(%s)(\s(.*?))?}}'; + + $this->core =& $core; + + # Transitional tags + $this->addValue('EntryTrackbackCount',array($this,'EntryPingCount')); + $this->addValue('EntryTrackbackData',array($this,'EntryPingData')); + $this->addValue('EntryTrackbackLink',array($this,'EntryPingLink')); + + # l10n + $this->addValue('lang',array($this,'l10n')); + + # Loops test tags + $this->addBlock('LoopPosition',array($this,'LoopPosition')); + + # Archives + $this->addBlock('Archives',array($this,'Archives')); + $this->addBlock('ArchivesHeader',array($this,'ArchivesHeader')); + $this->addBlock('ArchivesFooter',array($this,'ArchivesFooter')); + $this->addBlock('ArchivesYearHeader',array($this,'ArchivesYearHeader')); + $this->addBlock('ArchivesYearFooter',array($this,'ArchivesYearFooter')); + $this->addValue('ArchiveDate',array($this,'ArchiveDate')); + $this->addBlock('ArchiveNext',array($this,'ArchiveNext')); + $this->addBlock('ArchivePrevious',array($this,'ArchivePrevious')); + $this->addValue('ArchiveEntriesCount',array($this,'ArchiveEntriesCount')); + $this->addValue('ArchiveURL',array($this,'ArchiveURL')); + + # Attachments + $this->addBlock('Attachments',array($this,'Attachments')); + $this->addBlock('AttachmentsHeader',array($this,'AttachmentsHeader')); + $this->addBlock('AttachmentsFooter',array($this,'AttachmentsFooter')); + $this->addValue('AttachmentMimeType',array($this,'AttachmentMimeType')); + $this->addValue('AttachmentType',array($this,'AttachmentType')); + $this->addValue('AttachmentFileName',array($this,'AttachmentFileName')); + $this->addValue('AttachmentSize',array($this,'AttachmentSize')); + $this->addValue('AttachmentTitle',array($this,'AttachmentTitle')); + $this->addValue('AttachmentThumbnailURL',array($this,'AttachmentThumbnailURL')); + $this->addValue('AttachmentURL',array($this,'AttachmentURL')); + $this->addBlock('AttachmentIf',array($this,'AttachmentIf')); + $this->addValue('MediaURL',array($this,'MediaURL')); + + # Blog + $this->addValue('BlogArchiveURL',array($this,'BlogArchiveURL')); + $this->addValue('BlogCopyrightNotice',array($this,'BlogCopyrightNotice')); + $this->addValue('BlogDescription',array($this,'BlogDescription')); + $this->addValue('BlogEditor',array($this,'BlogEditor')); + $this->addValue('BlogFeedID',array($this,'BlogFeedID')); + $this->addValue('BlogFeedURL',array($this,'BlogFeedURL')); + $this->addValue('BlogRSDURL',array($this,'BlogRSDURL')); + $this->addValue('BlogName',array($this,'BlogName')); + $this->addValue('BlogLanguage',array($this,'BlogLanguage')); + $this->addValue('BlogThemeURL',array($this,'BlogThemeURL')); + $this->addValue('BlogUpdateDate',array($this,'BlogUpdateDate')); + $this->addValue('BlogID',array($this,'BlogID')); + $this->addValue('BlogURL',array($this,'BlogURL')); + $this->addValue('BlogPublicURL',array($this,'BlogPublicURL')); + $this->addValue('BlogQmarkURL',array($this,'BlogQmarkURL')); + $this->addValue('BlogMetaRobots',array($this,'BlogMetaRobots')); + + # Categories + $this->addBlock('Categories',array($this,'Categories')); + $this->addBlock('CategoriesHeader',array($this,'CategoriesHeader')); + $this->addBlock('CategoriesFooter',array($this,'CategoriesFooter')); + $this->addBlock('CategoryIf',array($this,'CategoryIf')); + $this->addBlock('CategoryFirstChildren',array($this,'CategoryFirstChildren')); + $this->addBlock('CategoryParents',array($this,'CategoryParents')); + $this->addValue('CategoryFeedURL',array($this,'CategoryFeedURL')); + $this->addValue('CategoryURL',array($this,'CategoryURL')); + $this->addValue('CategoryShortURL',array($this,'CategoryShortURL')); + $this->addValue('CategoryDescription',array($this,'CategoryDescription')); + $this->addValue('CategoryTitle',array($this,'CategoryTitle')); + + # Comments + $this->addBlock('Comments',array($this,'Comments')); + $this->addValue('CommentAuthor',array($this,'CommentAuthor')); + $this->addValue('CommentAuthorDomain',array($this,'CommentAuthorDomain')); + $this->addValue('CommentAuthorLink',array($this,'CommentAuthorLink')); + $this->addValue('CommentAuthorMailMD5',array($this,'CommentAuthorMailMD5')); + $this->addValue('CommentAuthorURL',array($this,'CommentAuthorURL')); + $this->addValue('CommentContent',array($this,'CommentContent')); + $this->addValue('CommentDate',array($this,'CommentDate')); + $this->addValue('CommentTime',array($this,'CommentTime')); + $this->addValue('CommentEmail',array($this,'CommentEmail')); + $this->addValue('CommentEntryTitle',array($this,'CommentEntryTitle')); + $this->addValue('CommentFeedID',array($this,'CommentFeedID')); + $this->addValue('CommentID',array($this,'CommentID')); + $this->addBlock('CommentIf',array($this,'CommentIf')); + $this->addValue('CommentIfFirst',array($this,'CommentIfFirst')); + $this->addValue('CommentIfMe',array($this,'CommentIfMe')); + $this->addValue('CommentIfOdd',array($this,'CommentIfOdd')); + $this->addValue('CommentIP',array($this,'CommentIP')); + $this->addValue('CommentOrderNumber',array($this,'CommentOrderNumber')); + $this->addBlock('CommentsFooter',array($this,'CommentsFooter')); + $this->addBlock('CommentsHeader',array($this,'CommentsHeader')); + $this->addValue('CommentPostURL',array($this,'CommentPostURL')); + $this->addBlock('IfCommentAuthorEmail',array($this,'IfCommentAuthorEmail')); + + # Comment preview + $this->addBlock('IfCommentPreview',array($this,'IfCommentPreview')); + $this->addValue('CommentPreviewName',array($this,'CommentPreviewName')); + $this->addValue('CommentPreviewEmail',array($this,'CommentPreviewEmail')); + $this->addValue('CommentPreviewSite',array($this,'CommentPreviewSite')); + $this->addValue('CommentPreviewContent',array($this,'CommentPreviewContent')); + $this->addValue('CommentPreviewCheckRemember',array($this,'CommentPreviewCheckRemember')); + + # Entries + $this->addBlock('DateFooter',array($this,'DateFooter')); + $this->addBlock('DateHeader',array($this,'DateHeader')); + $this->addBlock('Entries',array($this,'Entries')); + $this->addBlock('EntriesFooter',array($this,'EntriesFooter')); + $this->addBlock('EntriesHeader',array($this,'EntriesHeader')); + $this->addValue('EntryExcerpt',array($this,'EntryExcerpt')); + $this->addValue('EntryAttachmentCount',array($this,'EntryAttachmentCount')); + $this->addValue('EntryAuthorCommonName',array($this,'EntryAuthorCommonName')); + $this->addValue('EntryAuthorDisplayName',array($this,'EntryAuthorDisplayName')); + $this->addValue('EntryAuthorEmail',array($this,'EntryAuthorEmail')); + $this->addValue('EntryAuthorID',array($this,'EntryAuthorID')); + $this->addValue('EntryAuthorLink',array($this,'EntryAuthorLink')); + $this->addValue('EntryAuthorURL',array($this,'EntryAuthorURL')); + $this->addValue('EntryBasename',array($this,'EntryBasename')); + $this->addValue('EntryCategory',array($this,'EntryCategory')); + $this->addBlock('EntryCategoriesBreadcrumb',array($this,'EntryCategoriesBreadcrumb')); + $this->addValue('EntryCategoryID',array($this,'EntryCategoryID')); + $this->addValue('EntryCategoryURL',array($this,'EntryCategoryURL')); + $this->addValue('EntryCategoryShortURL',array($this,'EntryCategoryShortURL')); + $this->addValue('EntryCommentCount',array($this,'EntryCommentCount')); + $this->addValue('EntryContent',array($this,'EntryContent')); + $this->addValue('EntryDate',array($this,'EntryDate')); + $this->addValue('EntryFeedID',array($this,'EntryFeedID')); + $this->addValue('EntryFirstImage',array($this,'EntryFirstImage')); + $this->addValue('EntryID',array($this,'EntryID')); + $this->addBlock('EntryIf',array($this,'EntryIf')); + $this->addValue('EntryIfFirst',array($this,'EntryIfFirst')); + $this->addValue('EntryIfOdd',array($this,'EntryIfOdd')); + $this->addValue('EntryIfSelected',array($this,'EntryIfSelected')); + $this->addValue('EntryLang',array($this,'EntryLang')); + $this->addBlock('EntryNext',array($this,'EntryNext')); + $this->addValue('EntryPingCount',array($this,'EntryPingCount')); + $this->addValue('EntryPingData',array($this,'EntryPingData')); + $this->addValue('EntryPingLink',array($this,'EntryPingLink')); + $this->addBlock('EntryPrevious',array($this,'EntryPrevious')); + $this->addValue('EntryTitle',array($this,'EntryTitle')); + $this->addValue('EntryTime',array($this,'EntryTime')); + $this->addValue('EntryURL',array($this,'EntryURL')); + + # Languages + $this->addBlock('Languages',array($this,'Languages')); + $this->addBlock('LanguagesHeader',array($this,'LanguagesHeader')); + $this->addBlock('LanguagesFooter',array($this,'LanguagesFooter')); + $this->addValue('LanguageCode',array($this,'LanguageCode')); + $this->addBlock('LanguageIfCurrent',array($this,'LanguageIfCurrent')); + $this->addValue('LanguageURL',array($this,'LanguageURL')); + + # Pagination + $this->addBlock('Pagination',array($this,'Pagination')); + $this->addValue('PaginationCounter',array($this,'PaginationCounter')); + $this->addValue('PaginationCurrent',array($this,'PaginationCurrent')); + $this->addBlock('PaginationIf',array($this,'PaginationIf')); + $this->addValue('PaginationURL',array($this,'PaginationURL')); + + # Trackbacks + $this->addValue('PingBlogName',array($this,'PingBlogName')); + $this->addValue('PingContent',array($this,'PingContent')); + $this->addValue('PingDate',array($this,'PingDate')); + $this->addValue('PingEntryTitle',array($this,'PingEntryTitle')); + $this->addValue('PingFeedID',array($this,'PingFeedID')); + $this->addValue('PingID',array($this,'PingID')); + $this->addValue('PingIfFirst',array($this,'PingIfFirst')); + $this->addValue('PingIfOdd',array($this,'PingIfOdd')); + $this->addValue('PingIP',array($this,'PingIP')); + $this->addValue('PingNoFollow',array($this,'PingNoFollow')); + $this->addValue('PingOrderNumber',array($this,'PingOrderNumber')); + $this->addValue('PingPostURL',array($this,'PingPostURL')); + $this->addBlock('Pings',array($this,'Pings')); + $this->addBlock('PingsFooter',array($this,'PingsFooter')); + $this->addBlock('PingsHeader',array($this,'PingsHeader')); + $this->addValue('PingTime',array($this,'PingTime')); + $this->addValue('PingTitle',array($this,'PingTitle')); + $this->addValue('PingAuthorURL',array($this,'PingAuthorURL')); + + # System + $this->addValue('SysBehavior',array($this,'SysBehavior')); + $this->addBlock('SysIf',array($this,'SysIf')); + $this->addBlock('SysIfCommentPublished',array($this,'SysIfCommentPublished')); + $this->addBlock('SysIfCommentPending',array($this,'SysIfCommentPending')); + $this->addBlock('SysIfFormError',array($this,'SysIfFormError')); + $this->addValue('SysFeedSubtitle',array($this,'SysFeedSubtitle')); + $this->addValue('SysFormError',array($this,'SysFormError')); + $this->addValue('SysPoweredBy',array($this,'SysPoweredBy')); + $this->addValue('SysSearchString',array($this,'SysSearchString')); + $this->addValue('SysSelfURI',array($this,'SysSelfURI')); + } + + public function getData($________) + { + # --BEHAVIOR-- tplBeforeData + if ($this->core->hasBehavior('tplBeforeData')) + { + self::$_r = $this->core->callBehavior('tplBeforeData',$this->core); + if (self::$_r) { + return self::$_r; + } + } + + parent::getData($________); + + # --BEHAVIOR-- tplAfterData + if ($this->core->hasBehavior('tplAfterData')) { + $this->core->callBehavior('tplAfterData',$this->core,self::$_r); + } + + return self::$_r; + } + + protected function compileBlock($match) + { + $this->current_tag = $match[1]; + $content = $match[3]; + $attr = new ArrayObject($this->getAttrs($match[2])); + + # --BEHAVIOR-- templateBeforeBlock + $res = $this->core->callBehavior('templateBeforeBlock',$this->core,$this->current_tag,$attr); + + $res .= call_user_func($this->blocks[$this->current_tag],$attr,$content); + + # --BEHAVIOR-- templateAfterBlock + $res .= $this->core->callBehavior('templateAfterBlock',$this->core,$this->current_tag,$attr); + + return $res; + } + + protected function compileValue($match) + { + $this->current_tag = $match[1]; + + $str_attr = ''; + $attr = new ArrayObject(); + if (isset($match[2])) { + $str_attr = $match[2]; + $attr = new ArrayObject($this->getAttrs($match[2])); + } + + # --BEHAVIOR-- templateBeforeValue + $res = $this->core->callBehavior('templateBeforeValue',$this->core,$this->current_tag,$attr); + + $res .= call_user_func($this->values[$this->current_tag],$attr,ltrim($str_attr)); + + # --BEHAVIOR-- templateAfterValue + $res .= $this->core->callBehavior('templateAfterValue',$this->core,$this->current_tag,$attr); + + return $res; + } + + public function getFilters($attr) + { + $p[0] = '0'; # encode_xml + $p[1] = '0'; # remove_html + $p[2] = '0'; # cut_string + $p[3] = '0'; # lower_case + $p[4] = '0'; # upper_case + + $p[0] = (integer) (!empty($attr['encode_xml']) || !empty($attr['encode_html'])); + $p[1] = (integer) !empty($attr['remove_html']); + + if (!empty($attr['cut_string']) && (integer) $attr['cut_string'] > 0) { + $p[2] = (integer) $attr['cut_string']; + } + + $p[3] = (integer) !empty($attr['lower_case']); + $p[4] = (integer) !empty($attr['upper_case']); + + return "context::global_filter(%s,".implode(",",$p).",'".addslashes($this->current_tag)."')"; + } + + protected function getOperator($op) + { + switch (strtolower($op)) + { + case 'or': + case '||': + return '||'; + case 'and': + case '&&': + default: + return '&&'; + } + } + + /* TEMPLATE FUNCTIONS + ------------------------------------------------------- */ + + public function l10n($attr,$str_attr) + { + # Normalize content + $str_attr = preg_replace('/\s+/x',' ',$str_attr); + + return ""; + } + + public function LoopPosition($attr,$content) + { + $start = isset($attr['start']) ? (integer) $attr['start'] : '0'; + $length = isset($attr['length']) ? (integer) $attr['length'] : 'null'; + $even = isset($attr['even']) ? (integer) (boolean) $attr['even'] : 'null'; + + if ($start > 0) { + $start--; + } + + return + 'loopPosition('.$start.','.$length.','.$even.')) : ?>'. + $content. + ""; + } + + + /* Archives ------------------------------------------- */ + /*dtd + + + */ + public function Archives($attr,$content) + { + $p = '$params = array();'; + $p .= "\$params['type'] = 'month';\n"; + if (isset($attr['type'])) { + $p .= "\$params['type'] = '".addslashes($attr['type'])."';\n"; + } + + if (isset($attr['category'])) { + $p .= "\$params['cat_url'] = '".addslashes($attr['category'])."';\n"; + } + + $p .= "\$params['post_type'] = 'post';\n"; + if (isset($attr['post_type'])) { + $p .= "\$params['post_type'] = '".addslashes($attr['post_type'])."';\n"; + } + + if (isset($attr['post_lang'])) { + $p .= "\$params['post_lang'] = '".addslashes($attr['post_lang'])."';\n"; + } + + if (empty($attr['no_context'])) + { + $p .= + 'if ($_ctx->exists("categories")) { '. + "\$params['cat_id'] = \$_ctx->categories->cat_id; ". + "}\n"; + } + + $order = 'desc'; + if (isset($attr['order']) && preg_match('/^(desc|asc)$/i',$attr['order'])) { + $p .= "\$params['order'] = '".$attr['order']."';\n "; + } + + $res = "archives = $core->blog->getDates($params); unset($params);'."\n"; + $res .= "?>\n"; + + $res .= + 'archives->fetch()) : ?>'.$content.'archives = null; ?>'; + + return $res; + } + + /*dtd + + */ + public function ArchivesHeader($attr,$content) + { + return + "archives->isStart()) : ?>". + $content. + ""; + } + + /*dtd + + */ + public function ArchivesFooter($attr,$content) + { + return + "archives->isEnd()) : ?>". + $content. + ""; + } + + /*dtd + + */ + public function ArchivesYearHeader($attr,$content) + { + return + "archives->yearHeader()) : ?>". + $content. + ""; + } + + /*dtd + + */ + public function ArchivesYearFooter($attr,$content) + { + return + "archives->yearFooter()) : ?>". + $content. + ""; + } + + /*dtd + + + */ + public function ArchiveDate($attr) + { + $format = '%B %Y'; + if (!empty($attr['format'])) { + $format = addslashes($attr['format']); + } + + $f = $this->getFilters($attr); + return 'archives->dt)").'; ?>'; + } + + /*dtd + + */ + public function ArchiveEntriesCount($attr) + { + $f = $this->getFilters($attr); + return 'archives->nb_post').'; ?>'; + } + + /*dtd + + + */ + public function ArchiveNext($attr,$content) + { + $p = '$params = array();'; + $p .= "\$params['type'] = 'month';\n"; + if (isset($attr['type'])) { + $p .= "\$params['type'] = '".addslashes($attr['type'])."';\n"; + } + + $p .= "\$params['post_type'] = 'post';\n"; + if (isset($attr['post_type'])) { + $p .= "\$params['post_type'] = '".addslashes($attr['post_type'])."';\n"; + } + + if (isset($attr['post_lang'])) { + $p .= "\$params['post_lang'] = '".addslashes($attr['post_lang'])."';\n"; + } + + $p .= "\$params['next'] = \$_ctx->archives->dt;"; + + $res = "archives = $core->blog->getDates($params); unset($params);'."\n"; + $res .= "?>\n"; + + $res .= + 'archives->fetch()) : ?>'.$content.'archives = null; ?>'; + + return $res; + } + + /*dtd + + + */ + public function ArchivePrevious($attr,$content) + { + $p = '$params = array();'; + $p .= "\$params['type'] = 'month';\n"; + if (isset($attr['type'])) { + $p .= "\$params['type'] = '".addslashes($attr['type'])."';\n"; + } + + $p .= "\$params['post_type'] = 'post';\n"; + if (isset($attr['post_type'])) { + $p .= "\$params['post_type'] = '".addslashes($attr['post_type'])."';\n"; + } + + if (isset($attr['post_lang'])) { + $p .= "\$params['post_lang'] = '".addslashes($attr['post_lang'])."';\n"; + } + + $p .= "\$params['previous'] = \$_ctx->archives->dt;"; + + $res = "archives = $core->blog->getDates($params); unset($params);'."\n"; + $res .= "?>\n"; + + $res .= + 'archives->fetch()) : ?>'.$content.'archives = null; ?>'; + + return $res; + } + + /*dtd + + */ + public function ArchiveURL($attr) + { + $f = $this->getFilters($attr); + return 'archives->url($core)').'; ?>'; + } + + /* Attachments ---------------------------------------- */ + /*dtd + + */ + public function Attachments($attr,$content) + { + $res = + "posts !== null && $core->media) {'."\n". + '$_ctx->attachments = new ArrayObject($core->media->getPostMedia($_ctx->posts->post_id));'."\n". + "?>\n". + + 'attachments as $attach_i => $attach_f) : '. + '$GLOBALS[\'attach_i\'] = $attach_i; $GLOBALS[\'attach_f\'] = $attach_f;'. + '$_ctx->file_url = $attach_f->file_url; ?>'. + $content. + 'attachments = null; unset($attach_i,$attach_f,$_ctx->file_url); ?>'. + + "\n"; + + return $res; + } + + /*dtd + + */ + public function AttachmentsHeader($attr,$content) + { + return + "". + $content. + ""; + } + + /*dtd + + */ + public function AttachmentsFooter($attr,$content) + { + return + "attachments)) : ?>". + $content. + ""; + } + + /*dtd + + + */ + public function AttachmentIf($attr,$content) + { + $if = array(); + + $operator = isset($attr['operator']) ? $this->getOperator($attr['operator']) : '&&'; + + if (isset($attr['is_image'])) { + $sign = (boolean) $attr['is_image'] ? '' : '!'; + $if[] = $sign.'$attach_f->media_image'; + } + + if (isset($attr['has_thumb'])) { + $sign = (boolean) $attr['has_thumb'] ? '' : '!'; + $if[] = $sign.'isset($attach_f->media_thumb[\'sq\'])'; + } + + if (isset($attr['is_mp3'])) { + $sign = (boolean) $attr['is_mp3'] ? '==' : '!='; + $if[] = '$attach_f->type '.$sign.' "audio/mpeg3"'; + } + + if (isset($attr['is_flv'])) { + $sign = (boolean) $attr['is_flv'] ? '' : '!'; + $if[] = $sign. + '($attach_f->type == "video/x-flv" || '. + '$attach_f->type == "video/mp4" || '. + '$attach_f->type == "video/x-m4v")'; + } + + if (!empty($if)) { + return ''.$content.''; + } else { + return $content; + } + } + + /*dtd + + */ + public function AttachmentMimeType($attr) + { + $f = $this->getFilters($attr); + return 'type').'; ?>'; + } + + /*dtd + + */ + public function AttachmentType($attr) + { + $f = $this->getFilters($attr); + return 'media_type').'; ?>'; + } + + /*dtd + + */ + public function AttachmentFileName($attr) + { + $f = $this->getFilters($attr); + return 'basename').'; ?>'; + } + + /*dtd + + + */ + public function AttachmentSize($attr) + { + $f = $this->getFilters($attr); + if (!empty($attr['full'])) { + return 'size').'; ?>'; + } + return 'size)').'; ?>'; + } + + /*dtd + + */ + public function AttachmentTitle($attr) + { + $f = $this->getFilters($attr); + return 'media_title').'; ?>'; + } + + /*dtd + + */ + public function AttachmentThumbnailURL($attr) + { + $f = $this->getFilters($attr); + return + 'media_thumb[\'sq\'])) {'. + 'echo '.sprintf($f,'$attach_f->media_thumb[\'sq\']').';'. + '}'. + '?>'; + } + + /*dtd + + */ + public function AttachmentURL($attr) + { + $f = $this->getFilters($attr); + return 'file_url').'; ?>'; + } + + public function MediaURL($attr) + { + $f = $this->getFilters($attr); + return 'file_url').'; ?>'; + } + + /* Blog ----------------------------------------------- */ + /*dtd + + */ + public function BlogArchiveURL($attr) + { + $f = $this->getFilters($attr); + return 'blog->url.$core->url->getBase("archive")').'; ?>'; + } + + /*dtd + + */ + public function BlogCopyrightNotice($attr) + { + $f = $this->getFilters($attr); + return 'blog->settings->copyright_notice').'; ?>'; + } + + /*dtd + + */ + public function BlogDescription($attr) + { + $f = $this->getFilters($attr); + return 'blog->desc').'; ?>'; + } + + /*dtd + + */ + public function BlogEditor($attr) + { + $f = $this->getFilters($attr); + return 'blog->settings->editor').'; ?>'; + } + + /*dtd + + */ + public function BlogFeedID($attr) + { + $f = $this->getFilters($attr); + return 'blog->uid').'; ?>'; + } + + /*dtd + + + */ + public function BlogFeedURL($attr) + { + $type = !empty($attr['type']) ? $attr['type'] : 'atom'; + + if (!preg_match('#^(rss2|atom)$#',$type)) { + $type = 'atom'; + } + + $f = $this->getFilters($attr); + return 'blog->url.$core->url->getBase("feed")."/'.$type.'"').'; ?>'; + } + + /*dtd + + */ + public function BlogName($attr) + { + $f = $this->getFilters($attr); + return 'blog->name').'; ?>'; + } + + /*dtd + + */ + public function BlogLanguage($attr) + { + $f = $this->getFilters($attr); + return 'blog->settings->lang').'; ?>'; + } + + /*dtd + + */ + public function BlogThemeURL($attr) + { + $f = $this->getFilters($attr); + return 'blog->settings->themes_url."/".$core->blog->settings->theme').'; ?>'; + } + + /*dtd + + */ + public function BlogPublicURL($attr) + { + $f = $this->getFilters($attr); + return 'blog->settings->public_url').'; ?>'; + } + + /*dtd + + + */ + public function BlogUpdateDate($attr) + { + $format = ''; + if (!empty($attr['format'])) { + $format = addslashes($attr['format']); + } else { + $format = '%Y-%m-%d %H:%M:%S'; + } + + $iso8601 = !empty($attr['iso8601']); + $rfc822 = !empty($attr['rfc822']); + + $f = $this->getFilters($attr); + + if ($rfc822) { + return 'blog->upddt,\$core->blog->settings->blog_timezone)").'; ?>'; + } elseif ($iso8601) { + return 'blog->upddt,\$core->blog->settings->blog_timezone)").'; ?>'; + } else { + return 'blog->upddt)").'; ?>'; + } + } + + /*dtd + + */ + public function BlogID($attr) + { + $f = $this->getFilters($attr); + return 'blog->id').'; ?>'; + } + + /*dtd + + */ + public function BlogRSDURL($attr) + { + $f = $this->getFilters($attr); + return 'blog->url.$core->url->getBase(\'rsd\')').'; ?>'; + } + + /*dtd + + */ + public function BlogURL($attr) + { + $f = $this->getFilters($attr); + return 'blog->url').'; ?>'; + } + + /*dtd + + */ + public function BlogQmarkURL($attr) + { + $f = $this->getFilters($attr); + return 'blog->getQmarkURL()').'; ?>'; + } + + /*dtd + + + */ + public function BlogMetaRobots($attr) + { + $robots = isset($attr['robots']) ? addslashes($attr['robots']) : ''; + return "blog->settings->robots_policy,'".$robots."'); ?>"; + } + + /* Categories ----------------------------------------- */ + + /*dtd + + */ + public function Categories($attr,$content) + { + $p = "\$params = array();\n"; + + if (isset($attr['url'])) { + $p .= "\$params['cat_url'] = '".addslashes($attr['url'])."';\n"; + } + + if (!empty($attr['post_type'])) { + $p .= "\$params['post_type'] = '".addslashes($attr['post_type'])."';\n"; + } + + if (!empty($attr['level'])) { + $p .= "\$params['level'] = ".(integer) $attr['level'].";\n"; + } + + $res = "categories = $core->blog->getCategories($params);'."\n"; + $res .= "?>\n"; + $res .= 'categories->fetch()) : ?>'.$content.'categories = null; unset($params); ?>'; + + return $res; + } + + /*dtd + + */ + public function CategoriesHeader($attr,$content) + { + return + "categories->isStart()) : ?>". + $content. + ""; + } + + /*dtd + + */ + public function CategoriesFooter($attr,$content) + { + return + "categories->isEnd()) : ?>". + $content. + ""; + } + + /*dtd + + + */ + public function CategoryIf($attr,$content) + { + $if = array(); + $operator = isset($attr['operator']) ? $this->getOperator($attr['operator']) : '&&'; + + if (isset($attr['url'])) { + $url = addslashes(trim($attr['url'])); + if (substr($url,0,1) == '!') { + $url = substr($url,1); + $if[] = '($_ctx->categories->cat_url != "'.$url.'")'; + } else { + $if[] = '($_ctx->categories->cat_url == "'.$url.'")'; + } + } + + if (isset($attr['has_entries'])) { + $sign = (boolean) $attr['has_entries'] ? '>' : '=='; + $if[] = '$_ctx->categories->nb_post '.$sign.' 0'; + } + + if (!empty($if)) { + return ''.$content.''; + } else { + return $content; + } + } + + /*dtd + + */ + public function CategoryFirstChildren($attr,$content) + { + return + "categories = $core->blog->getCategoryFirstChildren($_ctx->categories->cat_id);'."\n". + 'while ($_ctx->categories->fetch()) : ?>'.$content.'categories = null; ?>'; + } + + /*dtd + + */ + public function CategoryParents($attr,$content) + { + return + "categories = $core->blog->getCategoryParents($_ctx->categories->cat_id);'."\n". + 'while ($_ctx->categories->fetch()) : ?>'.$content.'categories = null; ?>'; + } + + /*dtd + + + */ + public function CategoryFeedURL($attr) + { + $type = !empty($attr['type']) ? $attr['type'] : 'atom'; + + if (!preg_match('#^(rss2|atom)$#',$type)) { + $type = 'atom'; + } + + $f = $this->getFilters($attr); + return 'blog->url.$core->url->getBase("feed")."/category/".'. + '$_ctx->categories->cat_url."/'.$type.'"').'; ?>'; + } + + /*dtd + + */ + public function CategoryURL($attr) + { + $f = $this->getFilters($attr); + return 'blog->url.$core->url->getBase("category")."/".$_ctx->categories->cat_url').'; ?>'; + } + + /*dtd + + */ + public function CategoryShortURL($attr) + { + $f = $this->getFilters($attr); + return 'categories->cat_url').'; ?>'; + } + + /*dtd + + */ + public function CategoryDescription($attr) + { + $f = $this->getFilters($attr); + return 'categories->cat_desc').'; ?>'; + } + + /*dtd + + */ + public function CategoryTitle($attr) + { + $f = $this->getFilters($attr); + return 'categories->cat_title').'; ?>'; + } + + /* Entries -------------------------------------------- */ + /*dtd + + + */ + public function Entries($attr,$content) + { + $lastn = -1; + if (isset($attr['lastn'])) { + $lastn = abs((integer) $attr['lastn'])+0; + } + + $p = 'if (!isset($_page_number)) { $_page_number = 1; }'."\n"; + + if ($lastn != 0) { + if ($lastn > 0) { + $p .= "\$params['limit'] = ".$lastn.";\n"; + } else { + $p .= "\$params['limit'] = \$_ctx->nb_entry_per_page;\n"; + } + + if (!isset($attr['ignore_pagination']) || $attr['ignore_pagination'] == "0") { + $p .= "\$params['limit'] = array(((\$_page_number-1)*\$params['limit']),\$params['limit']);\n"; + } else { + $p .= "\$params['limit'] = array(0, \$params['limit']);\n"; + } + } + + if (isset($attr['author'])) { + $p .= "\$params['user_id'] = '".addslashes($attr['author'])."';\n"; + } + + if (isset($attr['category'])) { + $p .= "\$params['cat_url'] = '".addslashes($attr['category'])."';\n"; + $p .= "context::categoryPostParam(\$params);\n"; + } + + if (isset($attr['no_category'])) { + $p .= "@\$params['sql'] .= ' AND P.cat_id IS NULL ';\n"; + $p .= "unset(\$params['cat_url']);\n"; + } + + if (!empty($attr['type'])) { + $p .= "\$params['post_type'] = preg_split('/\s*,\s*/','".addslashes($attr['type'])."',-1,PREG_SPLIT_NO_EMPTY);\n"; + } + + if (!empty($attr['url'])) { + $p .= "\$params['post_url'] = '".addslashes($attr['url'])."';\n"; + } + + if (empty($attr['no_context'])) + { + $p .= + 'if ($_ctx->exists("users")) { '. + "\$params['user_id'] = \$_ctx->users->user_id; ". + "}\n"; + + $p .= + 'if ($_ctx->exists("categories")) { '. + "\$params['cat_id'] = \$_ctx->categories->cat_id; ". + "}\n"; + + $p .= + 'if ($_ctx->exists("archives")) { '. + "\$params['post_year'] = \$_ctx->archives->year(); ". + "\$params['post_month'] = \$_ctx->archives->month(); ". + "unset(\$params['limit']); ". + "}\n"; + + $p .= + 'if ($_ctx->exists("langs")) { '. + "\$params['post_lang'] = \$_ctx->langs->post_lang; ". + "}\n"; + + $p .= + 'if (isset($_search)) { '. + "\$params['search'] = \$_search; ". + "}\n"; + } + + + + $sortby = 'post_dt'; + $order = 'desc'; + if (isset($attr['sortby'])) { + switch ($attr['sortby']) { + case 'title': $sortby = 'post_title'; break; + case 'selected' : $sortby = 'post_selected'; break; + case 'author' : $sortby = 'user_id'; break; + case 'date' : $sortby = 'post_dt'; break; + case 'id' : $sortby = 'post_id'; break; + } + } + if (isset($attr['order']) && preg_match('/^(desc|asc)$/i',$attr['order'])) { + $order = $attr['order']; + } + + $p .= "\$params['order'] = '".$sortby." ".$order."';\n"; + + if (isset($attr['no_content']) && $attr['no_content']) { + $p .= "\$params['no_content'] = true;\n"; + } + + if (isset($attr['selected'])) { + $p .= "\$params['post_selected'] = ".(integer) (boolean) $attr['selected'].";"; + } + + $res = "post_params = $params;'."\n"; + $res .= '$_ctx->posts = $core->blog->getPosts($params); unset($params);'."\n"; + $res .= "?>\n"; + + $res .= + 'posts->fetch()) : ?>'.$content.'posts = null; $_ctx->post_params = null; ?>'; + + return $res; + } + + /*dtd + + */ + public function DateHeader($attr,$content) + { + return + "posts->firstPostOfDay()) : ?>". + $content. + ""; + } + + /*dtd + + */ + public function DateFooter($attr,$content) + { + return + "posts->lastPostOfDay()) : ?>". + $content. + ""; + } + + /*dtd + + + */ + public function EntryIf($attr,$content) + { + $if = array(); + $extended = null; + $hascategory = null; + + $operator = isset($attr['operator']) ? $this->getOperator($attr['operator']) : '&&'; + + if (isset($attr['type'])) { + $type = trim($attr['type']); + $type = !empty($type)?$type:'post'; + $if[] = '$_ctx->posts->post_type == "'.addslashes($type).'"'; + } + + if (isset($attr['url'])) { + $url = trim($attr['url']); + if (substr($url,0,1) == '!') { + $url = substr($url,1); + $if[] = '$_ctx->posts->post_url != "'.addslashes($url).'"'; + } else { + $if[] = '$_ctx->posts->post_url == "'.addslashes($url).'"'; + } + } + + if (isset($attr['category'])) { + $category = addslashes(trim($attr['category'])); + if (substr($category,0,1) == '!') { + $category = substr($category,1); + $if[] = '($_ctx->posts->cat_url != "'.$category.'")'; + } else { + $if[] = '($_ctx->posts->cat_url == "'.$category.'")'; + } + } + + if (isset($attr['first'])) { + $sign = (boolean) $attr['first'] ? '=' : '!'; + $if[] = '$_ctx->posts->index() '.$sign.'= 0'; + } + + if (isset($attr['odd'])) { + $sign = (boolean) $attr['odd'] ? '=' : '!'; + $if[] = '($_ctx->posts->index()+1)%2 '.$sign.'= 1'; + } + + if (isset($attr['extended'])) { + $sign = (boolean) $attr['extended'] ? '' : '!'; + $if[] = $sign.'$_ctx->posts->isExtended()'; + } + + if (isset($attr['selected'])) { + $sign = (boolean) $attr['selected'] ? '' : '!'; + $if[] = $sign.'(boolean)$_ctx->posts->post_selected'; + } + + if (isset($attr['has_category'])) { + $sign = (boolean) $attr['has_category'] ? '' : '!'; + $if[] = $sign.'$_ctx->posts->cat_id'; + } + + if (isset($attr['has_attachment'])) { + $sign = (boolean) $attr['has_attachment'] ? '' : '!'; + $if[] = $sign.'$_ctx->posts->countMedia()'; + } + + if (isset($attr['comments_active'])) { + $sign = (boolean) $attr['comments_active'] ? '' : '!'; + $if[] = $sign.'$_ctx->posts->commentsActive()'; + } + + if (isset($attr['pings_active'])) { + $sign = (boolean) $attr['pings_active'] ? '' : '!'; + $if[] = $sign.'$_ctx->posts->trackbacksActive()'; + } + + if (isset($attr['has_comment'])) { + $sign = (boolean) $attr['has_comment'] ? '' : '!'; + $if[] = $sign.'$_ctx->posts->hasComments()'; + } + + if (isset($attr['has_ping'])) { + $sign = (boolean) $attr['has_ping'] ? '' : '!'; + $if[] = $sign.'$_ctx->posts->hasTrackbacks()'; + } + + if (isset($attr['show_comments'])) { + if ((boolean) $attr['show_comments']) { + $if[] = '($_ctx->posts->hasComments() || $_ctx->posts->commentsActive())'; + } else { + $if[] = '(!$_ctx->posts->hasComments() && !$_ctx->posts->commentsActive())'; + } + } + + if (isset($attr['show_pings'])) { + if ((boolean) $attr['show_pings']) { + $if[] = '($_ctx->posts->hasTrackbacks() || $_ctx->posts->trackbacksActive())'; + } else { + $if[] = '(!$_ctx->posts->hasTrackbacks() && !$_ctx->posts->trackbacksActive())'; + } + } + + if (!empty($if)) { + return ''.$content.''; + } else { + return $content; + } + } + + /*dtd + + + */ + public function EntryIfFirst($attr) + { + $ret = isset($attr['return']) ? $attr['return'] : 'first'; + $ret = html::escapeHTML($ret); + + return + 'posts->index() == 0) { '. + "echo '".addslashes($ret)."'; } ?>"; + } + + /*dtd + + + */ + public function EntryIfOdd($attr) + { + $ret = isset($attr['return']) ? $attr['return'] : 'odd'; + $ret = html::escapeHTML($ret); + + return + 'posts->index()+1)%2 == 1) { '. + "echo '".addslashes($ret)."'; } ?>"; + } + + /*dtd + + + */ + public function EntryIfSelected($attr) + { + $ret = isset($attr['return']) ? $attr['return'] : 'selected'; + $ret = html::escapeHTML($ret); + + return + 'posts->post_selected) { '. + "echo '".addslashes($ret)."'; } ?>"; + } + + /*dtd + + + */ + public function EntryContent($attr) + { + $urls = '0'; + if (!empty($attr['absolute_urls'])) { + $urls = '1'; + } + + $f = $this->getFilters($attr); + + if (!empty($attr['full'])) { + return 'posts->getExcerpt('.$urls.')." ".$_ctx->posts->getContent('.$urls.')').'; ?>'; + } else { + return 'posts->getContent('.$urls.')').'; ?>'; + } + } + + /*dtd + + + */ + public function EntryExcerpt($attr) + { + $urls = '0'; + if (!empty($attr['absolute_urls'])) { + $urls = '1'; + } + + $f = $this->getFilters($attr); + return 'posts->getExcerpt('.$urls.')').'; ?>'; + } + + /*dtd + + + */ + public function EntryAttachmentCount($attr) + { + $none = 'no attachment'; + $one = 'one attachment'; + $more = '%d attachments'; + + if (isset($attr['none'])) { + $none = addslashes($attr['none']); + } + if (isset($attr['one'])) { + $one = addslashes($attr['one']); + } + if (isset($attr['more'])) { + $more = addslashes($attr['more']); + } + + return + "posts->countMedia() == 0) {\n". + " printf(__('".$none."'),(integer) \$_ctx->posts->countMedia());\n". + "} elseif (\$_ctx->posts->countMedia() == 1) {\n". + " printf(__('".$one."'),(integer) \$_ctx->posts->countMedia());\n". + "} else {\n". + " printf(__('".$more."'),(integer) \$_ctx->posts->countMedia());\n". + "} ?>"; + } + + /*dtd + + */ + public function EntryAuthorCommonName($attr) + { + $f = $this->getFilters($attr); + return 'posts->getAuthorCN()').'; ?>'; + } + + /*dtd + + */ + public function EntryAuthorDisplayName($attr) + { + $f = $this->getFilters($attr); + return 'posts->user_displayname').'; ?>'; + } + + /*dtd + + */ + public function EntryAuthorID($attr) + { + $f = $this->getFilters($attr); + return 'posts->user_id').'; ?>'; + } + + /*dtd + + + */ + public function EntryAuthorEmail($attr) + { + $p = 'true'; + if (isset($attr['spam_protected']) && !$attr['spam_protected']) { + $p = 'false'; + } + + $f = $this->getFilters($attr); + return 'posts->getAuthorEmail(".$p.")").'; ?>'; + } + + /*dtd + + */ + public function EntryAuthorLink($attr) + { + $f = $this->getFilters($attr); + return 'posts->getAuthorLink()').'; ?>'; + } + + /*dtd + + */ + public function EntryAuthorURL($attr) + { + $f = $this->getFilters($attr); + return 'posts->user_url').'; ?>'; + } + + /*dtd + + */ + public function EntryBasename($attr) + { + $f = $this->getFilters($attr); + return 'posts->post_url').'; ?>'; + } + + /*dtd + + */ + public function EntryCategory($attr) + { + $f = $this->getFilters($attr); + return 'posts->cat_title').'; ?>'; + } + + /*dtd + + */ + public function EntryCategoriesBreadcrumb($attr,$content) + { + return + "categories = $core->blog->getCategoryParents($_ctx->posts->cat_id);'."\n". + 'while ($_ctx->categories->fetch()) : ?>'.$content.'categories = null; ?>'; + } + + /*dtd + + */ + public function EntryCategoryID($attr) + { + $f = $this->getFilters($attr); + return 'posts->cat_id').'; ?>'; + } + + /*dtd + + */ + public function EntryCategoryURL($attr) + { + $f = $this->getFilters($attr); + return 'posts->getCategoryURL()').'; ?>'; + } + + /*dtd + + */ + public function EntryCategoryShortURL($attr) + { + $f = $this->getFilters($attr); + return 'posts->cat_url').'; ?>'; + } + + + /*dtd + + */ + public function EntryFeedID($attr) + { + $f = $this->getFilters($attr); + return 'posts->getFeedID()').'; ?>'; + } + + /*dtd + + + */ + public function EntryFirstImage($attr) + { + $size = !empty($attr['size']) ? $attr['size'] : ''; + $class = !empty($attr['class']) ? $attr['class'] : ''; + $with_category = !empty($attr['with_category']) ? 'true' : 'false'; + + return ""; + } + + /*dtd + + */ + public function EntryID($attr) + { + $f = $this->getFilters($attr); + return 'posts->post_id').'; ?>'; + } + + /*dtd + + */ + public function EntryLang($attr) + { + $f = $this->getFilters($attr); + return + 'posts->post_lang) { '. + 'echo '.sprintf($f,'$_ctx->posts->post_lang').'; '. + '} else {'. + 'echo '.sprintf($f,'$core->blog->settings->lang').'; '. + '} ?>'; + } + + /*dtd + + + */ + public function EntryNext($attr,$content) + { + $restrict_to_category = !empty($attr['restrict_to_category']) ? '1' : '0'; + $restrict_to_lang = !empty($attr['restrict_to_lang']) ? '1' : '0'; + + return + 'blog->getNextPost($_ctx->posts,1,'.$restrict_to_category.','.$restrict_to_lang.'); ?>'."\n". + ''. + + 'posts = $next_post; unset($next_post);'."\n". + 'while ($_ctx->posts->fetch()) : ?>'. + $content. + 'posts = null; ?>'. + "\n"; + } + + /*dtd + + + */ + public function EntryPrevious($attr,$content) + { + $restrict_to_category = !empty($attr['restrict_to_category']) ? '1' : '0'; + $restrict_to_lang = !empty($attr['restrict_to_lang']) ? '1' : '0'; + + return + 'blog->getNextPost($_ctx->posts,-1,'.$restrict_to_category.','.$restrict_to_lang.'); ?>'."\n". + ''. + + 'posts = $prev_post; unset($prev_post);'."\n". + 'while ($_ctx->posts->fetch()) : ?>'. + $content. + 'posts = null; ?>'. + "\n"; + } + + /*dtd + + */ + public function EntryTitle($attr) + { + $f = $this->getFilters($attr); + return 'posts->post_title').'; ?>'; + } + + /*dtd + + */ + public function EntryURL($attr) + { + $f = $this->getFilters($attr); + return 'posts->getURL()').'; ?>'; + } + + /*dtd + + + */ + public function EntryDate($attr) + { + $format = ''; + if (!empty($attr['format'])) { + $format = addslashes($attr['format']); + } + + $iso8601 = !empty($attr['iso8601']); + $rfc822 = !empty($attr['rfc822']); + + $f = $this->getFilters($attr); + + if ($rfc822) { + return 'posts->getRFC822Date()").'; ?>'; + } elseif ($iso8601) { + return 'posts->getISO8601Date()").'; ?>'; + } else { + return 'posts->getDate('".$format."')").'; ?>'; + } + } + + /*dtd + + + */ + public function EntryTime($attr) + { + $format = ''; + if (!empty($attr['format'])) { + $format = addslashes($attr['format']); + } + + $f = $this->getFilters($attr); + return 'posts->getTime('".$format."')").'; ?>'; + } + + /*dtd + + */ + public function EntriesHeader($attr,$content) + { + return + "posts->isStart()) : ?>". + $content. + ""; + } + + /*dtd + + */ + public function EntriesFooter($attr,$content) + { + return + "posts->isEnd()) : ?>". + $content. + ""; + } + + /*dtd + + + */ + public function EntryCommentCount($attr) + { + $none = 'no comment'; + $one = 'one comment'; + $more = '%d comments'; + + if (isset($attr['none'])) { + $none = addslashes($attr['none']); + } + if (isset($attr['one'])) { + $one = addslashes($attr['one']); + } + if (isset($attr['more'])) { + $more = addslashes($attr['more']); + } + + if (empty($attr['count_all'])) { + $operation = '$_ctx->posts->nb_comment'; + } else { + $operation = '($_ctx->posts->nb_comment + $_ctx->posts->nb_trackback)'; + } + + return + ""; + } + + /*dtd + + + */ + public function EntryPingCount($attr) + { + $none = 'no trackback'; + $one = 'one trackback'; + $more = '%d trackbacks'; + + if (isset($attr['none'])) { + $none = addslashes($attr['none']); + } + if (isset($attr['one'])) { + $one = addslashes($attr['one']); + } + if (isset($attr['more'])) { + $more = addslashes($attr['more']); + } + + return + "posts->nb_trackback == 0) {\n". + " printf(__('".$none."'),(integer) \$_ctx->posts->nb_trackback);\n". + "} elseif (\$_ctx->posts->nb_trackback == 1) {\n". + " printf(__('".$one."'),(integer) \$_ctx->posts->nb_trackback);\n". + "} else {\n". + " printf(__('".$more."'),(integer) \$_ctx->posts->nb_trackback);\n". + "} ?>"; + } + + /*dtd + + */ + public function EntryPingData($attr) + { + return "posts->trackbacksActive()) { echo \$_ctx->posts->getTrackbackData(); } ?>\n"; + } + + /*dtd + + */ + public function EntryPingLink($attr) + { + return "posts->trackbacksActive()) { echo \$_ctx->posts->getTrackbackLink(); } ?>\n"; + } + + /* Languages -------------------------------------- */ + /*dtd + + + */ + public function Languages($attr,$content) + { + $p = '$params = array();'; + + if (isset($attr['lang'])) { + $p = "\$params['lang'] = '".addslashes($attr['lang'])."';\n"; + } + + $order = 'desc'; + if (isset($attr['order']) && preg_match('/^(desc|asc)$/i',$attr['order'])) { + $p .= "\$params['order'] = '".$attr['order']."';\n "; + } + + $res = "langs = $core->blog->getLangs($params); unset($params);'."\n"; + $res .= "?>\n"; + + $res .= + 'langs->count() > 1) : '. + 'while ($_ctx->langs->fetch()) : ?>'.$content. + 'langs = null; endif; ?>'; + + return $res; + } + + /*dtd + + */ + public function LanguagesHeader($attr,$content) + { + return + "langs->isStart()) : ?>". + $content. + ""; + } + + /*dtd + + */ + public function LanguagesFooter($attr,$content) + { + return + "langs->isEnd()) : ?>". + $content. + ""; + } + + /*dtd + + */ + public function LanguageCode($attr) + { + $f = $this->getFilters($attr); + return 'langs->post_lang').'; ?>'; + } + + /*dtd + + */ + public function LanguageIfCurrent($attr,$content) + { + return + "cur_lang == \$_ctx->langs->post_lang) : ?>". + $content. + ""; + } + + /*dtd + + */ + public function LanguageURL($attr) + { + $f = $this->getFilters($attr); + return 'blog->url.$core->url->getBase("lang").$_ctx->langs->post_lang').'; ?>'; + } + + /* Pagination ------------------------------------- */ + /*dtd + + + */ + public function Pagination($attr,$content) + { + $p = "post_params;'."\n"; + $p .= '$_ctx->pagination = $core->blog->getPosts($params,true); unset($params);'."\n"; + $p .= "?>\n"; + + if (isset($attr['no_context'])) { + return $p.$content; + } + + return + $p. + 'pagination->f(0) > $_ctx->posts->count()) : ?>'. + $content. + ''; + } + + /*dtd + + */ + public function PaginationCounter($attr) + { + $f = $this->getFilters($attr); + return ''; + } + + /*dtd + + */ + public function PaginationCurrent($attr) + { + $offset = 0; + if (isset($attr['offset'])) { + $offset = (integer) $attr['offset']; + } + + $f = $this->getFilters($attr); + return ''; + } + + /*dtd + + + */ + public function PaginationIf($attr,$content) + { + $if = array(); + + if (isset($attr['start'])) { + $sign = (boolean) $attr['start'] ? '' : '!'; + $if[] = $sign.'context::PaginationStart()'; + } + + if (isset($attr['end'])) { + $sign = (boolean) $attr['end'] ? '' : '!'; + $if[] = $sign.'context::PaginationEnd()'; + } + + if (!empty($if)) { + return ''.$content.''; + } else { + return $content; + } + } + + /*dtd + + + */ + public function PaginationURL($attr) + { + $offset = 0; + if (isset($attr['offset'])) { + $offset = (integer) $attr['offset']; + } + + $f = $this->getFilters($attr); + return ''; + } + + /* Comments --------------------------------------- */ + /*dtd + + + */ + public function Comments($attr,$content) + { + $p = + "if (\$_ctx->posts !== null) { ". + "\$params['post_id'] = \$_ctx->posts->post_id; ". + "\$core->blog->withoutPassword(false);\n". + "}\n"; + + if (empty($attr['with_pings'])) { + $p .= "\$params['comment_trackback'] = false;\n"; + } + + $lastn = 0; + if (isset($attr['lastn'])) { + $lastn = abs((integer) $attr['lastn'])+0; + } + + if ($lastn > 0) { + $p .= "\$params['limit'] = ".$lastn.";\n"; + } else { + $p .= "if (\$_ctx->nb_comment_per_page !== null) { \$params['limit'] = \$_ctx->nb_comment_per_page; }\n"; + } + + if (empty($attr['no_context'])) + { + $p .= + 'if ($_ctx->exists("categories")) { '. + "\$params['cat_id'] = \$_ctx->categories->cat_id; ". + "}\n"; + + $p .= + 'if ($_ctx->exists("langs")) { '. + "\$params['sql'] = \"AND P.post_lang = '\".\$core->blog->con->escape(\$_ctx->langs->post_lang).\"' \"; ". + "}\n"; + } + + $order = 'asc'; + if (isset($attr['order']) && preg_match('/^(desc|asc)$/i',$attr['order'])) { + $order = $attr['order']; + } + + $p .= "\$params['order'] = 'comment_dt ".$order."';\n"; + + if (isset($attr['no_content']) && $attr['no_content']) { + $p .= "\$params['no_content'] = true;\n"; + } + + $res = "comments = $core->blog->getComments($params); unset($params);'."\n"; + $res .= "if (\$_ctx->posts !== null) { \$core->blog->withoutPassword(true);}\n"; + + if (!empty($attr['with_pings'])) { + $res .= '$_ctx->pings = $_ctx->comments;'."\n"; + } + + $res .= "?>\n"; + + $res .= + 'comments->fetch()) : ?>'.$content.'comments = null; ?>'; + + return $res; + } + + /*dtd + + */ + public function CommentAuthor($attr) + { + $f = $this->getFilters($attr); + return 'comments->comment_author").'; ?>'; + } + + /*dtd + + */ + public function CommentAuthorDomain($attr) + { + return 'comments->comment_site); ?>'; + } + + /*dtd + + */ + public function CommentAuthorLink($attr) + { + $f = $this->getFilters($attr); + return 'comments->getAuthorLink()').'; ?>'; + } + + /*dtd + + */ + public function CommentAuthorMailMD5($attr) + { + return 'comments->comment_email) ; ?>'; + } + + /*dtd + + */ + public function CommentAuthorURL($attr) + { + $f = $this->getFilters($attr); + return 'comments->getAuthorURL()').'; ?>'; + } + + /*dtd + + + */ + public function CommentContent($attr) + { + $urls = '0'; + if (!empty($attr['absolute_urls'])) { + $urls = '1'; + } + + $f = $this->getFilters($attr); + return 'comments->getContent('.$urls.')').'; ?>'; + } + + /*dtd + + + */ + public function CommentDate($attr) + { + $format = ''; + if (!empty($attr['format'])) { + $format = addslashes($attr['format']); + } + + $iso8601 = !empty($attr['iso8601']); + $rfc822 = !empty($attr['rfc822']); + + $f = $this->getFilters($attr); + + if ($rfc822) { + return 'comments->getRFC822Date()").'; ?>'; + } elseif ($iso8601) { + return 'comments->getISO8601Date()").'; ?>'; + } else { + return 'comments->getDate('".$format."')").'; ?>'; + } + } + + /*dtd + + + */ + public function CommentTime($attr) + { + $format = ''; + if (!empty($attr['format'])) { + $format = addslashes($attr['format']); + } + + $f = $this->getFilters($attr); + return 'comments->getTime('".$format."')").'; ?>'; + } + + /*dtd + + + */ + public function CommentEmail($attr) + { + $p = 'true'; + if (isset($attr['spam_protected']) && !$attr['spam_protected']) { + $p = 'false'; + } + + $f = $this->getFilters($attr); + return 'comments->getEmail(".$p.")").'; ?>'; + } + + /*dtd + + */ + public function CommentEntryTitle($attr) + { + $f = $this->getFilters($attr); + return 'comments->post_title').'; ?>'; + } + + /*dtd + + */ + public function CommentFeedID($attr) + { + $f = $this->getFilters($attr); + return 'comments->getFeedID()').'; ?>'; + } + + /*dtd + + */ + public function CommentID($attr) + { + return 'comments->comment_id; ?>'; + } + + /*dtd + + + */ + public function CommentIf($attr,$content) + { + $if = array(); + $is_ping = null; + + if (isset($attr['is_ping'])) { + $sign = (boolean) $attr['is_ping'] ? '' : '!'; + $if[] = $sign.'$_ctx->comments->comment_trackback'; + } + + if (!empty($if)) { + return ''.$content.''; + } else { + return $content; + } + } + + /*dtd + + + */ + public function CommentIfFirst($attr) + { + $ret = isset($attr['return']) ? $attr['return'] : 'first'; + $ret = html::escapeHTML($ret); + + return + 'comments->index() == 0) { '. + "echo '".addslashes($ret)."'; } ?>"; + } + + /*dtd + + + */ + public function CommentIfMe($attr) + { + $ret = isset($attr['return']) ? $attr['return'] : 'me'; + $ret = html::escapeHTML($ret); + + return + 'comments->isMe()) { '. + "echo '".addslashes($ret)."'; } ?>"; + } + + /*dtd + + + */ + public function CommentIfOdd($attr) + { + $ret = isset($attr['return']) ? $attr['return'] : 'odd'; + $ret = html::escapeHTML($ret); + + return + 'comments->index()+1)%2) { '. + "echo '".addslashes($ret)."'; } ?>"; + } + + /*dtd + + */ + public function CommentIP($attr) + { + return 'comments->comment_ip; ?>'; + } + + /*dtd + + */ + public function CommentOrderNumber($attr) + { + return 'comments->index()+1; ?>'; + } + + /*dtd + + */ + public function CommentsFooter($attr,$content) + { + return + "comments->isEnd()) : ?>". + $content. + ""; + } + + /*dtd + + */ + public function CommentsHeader($attr,$content) + { + return + "comments->isStart()) : ?>". + $content. + ""; + } + + /*dtd + + */ + public function CommentPostURL($attr) + { + $f = $this->getFilters($attr); + return 'comments->getPostURL()').'; ?>'; + } + + /*dtd + + */ + public function IfCommentAuthorEmail($attr,$content) + { + return + "comments->comment_email) : ?>". + $content. + ""; + } + + /* Comment preview -------------------------------- */ + /*dtd + + */ + public function IfCommentPreview($attr,$content) + { + return + 'comment_preview !== null && $_ctx->comment_preview["preview"]) : ?>'. + $content. + ''; + } + + /*dtd + + */ + public function CommentPreviewName($attr) + { + $f = $this->getFilters($attr); + return 'comment_preview["name"]').'; ?>'; + } + + /*dtd + + */ + public function CommentPreviewEmail($attr) + { + $f = $this->getFilters($attr); + return 'comment_preview["mail"]').'; ?>'; + } + + /*dtd + + */ + public function CommentPreviewSite($attr) + { + $f = $this->getFilters($attr); + return 'comment_preview["site"]').'; ?>'; + } + + /*dtd + + + */ + public function CommentPreviewContent($attr) + { + $f = $this->getFilters($attr); + + if (!empty($attr['raw'])) { + $co = '$_ctx->comment_preview["rawcontent"]'; + } else { + $co = '$_ctx->comment_preview["content"]'; + } + + return ''; + } + + /*dtd + + */ + public function CommentPreviewCheckRemember($attr) + { + return + "comment_preview['remember']) { echo ' checked=\"checked\"'; } ?>"; + } + + /* Trackbacks ------------------------------------- */ + /*dtd + + */ + public function PingBlogName($attr) + { + $f = $this->getFilters($attr); + return 'pings->comment_author').'; ?>'; + } + + /*dtd + + */ + public function PingContent($attr) + { + $f = $this->getFilters($attr); + return 'pings->getTrackbackContent()').'; ?>'; + } + + /*dtd + + + */ + public function PingDate($attr) + { + $format = ''; + if (!empty($attr['format'])) { + $format = addslashes($attr['format']); + } + + $iso8601 = !empty($attr['iso8601']); + $rfc822 = !empty($attr['rfc822']); + + $f = $this->getFilters($attr); + + if ($rfc822) { + return 'pings->getRFC822Date()").'; ?>'; + } elseif ($iso8601) { + return 'pings->getISO8601Date()").'; ?>'; + } else { + return 'pings->getDate('".$format."')").'; ?>'; + } + } + + /*dtd + + + */ + public function PingTime($attr) + { + $format = ''; + if (!empty($attr['format'])) { + $format = addslashes($attr['format']); + } + + $f = $this->getFilters($attr); + return 'pings->getTime('".$format."')").'; ?>'; + } + + /*dtd + + */ + public function PingEntryTitle($attr) + { + $f = $this->getFilters($attr); + return 'pings->post_title').'; ?>'; + } + + /*dtd + + */ + public function PingFeedID($attr) + { + $f = $this->getFilters($attr); + return 'pings->getFeedID()').'; ?>'; + } + + /*dtd + + */ + public function PingID($attr) + { + return 'pings->comment_id; ?>'; + } + + /*dtd + + + */ + public function PingIfFirst($attr) + { + $ret = isset($attr['return']) ? $attr['return'] : 'first'; + $ret = html::escapeHTML($ret); + + return + 'pings->index() == 0) { '. + "echo '".addslashes($ret)."'; } ?>"; + } + + /*dtd + + + */ + public function PingIfOdd($attr) + { + $ret = isset($attr['return']) ? $attr['return'] : 'odd'; + $ret = html::escapeHTML($ret); + + return + 'pings->index()+1)%2) { '. + "echo '".addslashes($ret)."'; } ?>"; + } + + /*dtd + + */ + public function PingIP($attr) + { + return 'pings->comment_ip; ?>'; + } + + /*dtd + + */ + public function PingNoFollow($attr) + { + return + 'blog->settings->comments_nofollow) { '. + 'echo \' rel="nofollow"\';'. + '} ?>'; + } + + /*dtd + + */ + public function PingOrderNumber($attr) + { + return 'pings->index()+1; ?>'; + } + + /*dtd + + */ + public function PingPostURL($attr) + { + $f = $this->getFilters($attr); + return 'pings->getPostURL()').'; ?>'; + } + + /*dtd + + + */ + public function Pings($attr,$content) + { + $p = + "if (\$_ctx->posts !== null) { ". + "\$params['post_id'] = \$_ctx->posts->post_id; ". + "\$core->blog->withoutPassword(false);\n". + "}\n"; + + $p .= "\$params['comment_trackback'] = true;\n"; + + $lastn = 0; + if (isset($attr['lastn'])) { + $lastn = abs((integer) $attr['lastn'])+0; + } + + if ($lastn > 0) { + $p .= "\$params['limit'] = ".$lastn.";\n"; + } else { + $p .= "if (\$_ctx->nb_comment_per_page !== null) { \$params['limit'] = \$_ctx->nb_comment_per_page; }\n"; + } + + if (empty($attr['no_context'])) + { + $p .= + 'if ($_ctx->exists("categories")) { '. + "\$params['cat_id'] = \$_ctx->categories->cat_id; ". + "}\n"; + + $p .= + 'if ($_ctx->exists("langs")) { '. + "\$params['sql'] = \"AND P.post_lang = '\".\$core->blog->con->escape(\$_ctx->langs->post_lang).\"' \"; ". + "}\n"; + } + + $order = 'asc'; + if (isset($attr['order']) && preg_match('/^(desc|asc)$/i',$attr['order'])) { + $order = $attr['order']; + } + + $p .= "\$params['order'] = 'comment_dt ".$order."';\n"; + + if (isset($attr['no_content']) && $attr['no_content']) { + $p .= "\$params['no_content'] = true;\n"; + } + + $res = "pings = $core->blog->getComments($params); unset($params);'."\n"; + $res .= "if (\$_ctx->posts !== null) { \$core->blog->withoutPassword(true);}\n"; + $res .= "?>\n"; + + $res .= + 'pings->fetch()) : ?>'.$content.'pings = null; ?>'; + + return $res; + } + + /*dtd + + */ + public function PingsFooter($attr,$content) + { + return + "pings->isEnd()) : ?>". + $content. + ""; + } + + /*dtd + + */ + public function PingsHeader($attr,$content) + { + return + "pings->isStart()) : ?>". + $content. + ""; + } + + /*dtd + + */ + public function PingTitle($attr) + { + $f = $this->getFilters($attr); + return 'pings->getTrackbackTitle()').'; ?>'; + } + + /*dtd + + */ + public function PingAuthorURL($attr) + { + $f = $this->getFilters($attr); + return 'pings->getAuthorURL()').'; ?>'; + } + + # System + /*dtd + + + */ + public function SysBehavior($attr,$raw) + { + if (!isset($attr['behavior'])) { + return; + } + + $b = addslashes($attr['behavior']); + return + 'hasBehavior(\''.$b.'\')) { '. + '$core->callBehavior(\''.$b.'\',$core,$_ctx);'. + '} ?>'; + } + + /*dtd + + + */ + public function SysIf($attr,$content) + { + $if = array(); + $is_ping = null; + + $operator = isset($attr['operator']) ? $this->getOperator($attr['operator']) : '&&'; + + if (isset($attr['categories'])) { + $sign = (boolean) $attr['categories'] ? '!' : '='; + $if[] = '$_ctx->categories '.$sign.'== null'; + } + + if (isset($attr['posts'])) { + $sign = (boolean) $attr['posts'] ? '!' : '='; + $if[] = '$_ctx->posts '.$sign.'== null'; + } + + if (isset($attr['blog_lang'])) { + $if[] = "\$core->blog->settings->lang == '".addslashes($attr['blog_lang'])."'"; + } + + if (isset($attr['current_tpl'])) { + $sign = '='; + if (substr($attr['current_tpl'],0,1) == '!') { + $sign = '!'; + $attr['current_tpl'] = substr($attr['current_tpl'],1); + } + $if[] = "\$_ctx->current_tpl ".$sign."= '".addslashes($attr['current_tpl'])."'"; + } + + if (isset($attr['current_mode'])) { + $sign = '='; + if (substr($attr['current_mode'],0,1) == '!') { + $sign = '!'; + $attr['current_mode'] = substr($attr['current_mode'],1); + } + $if[] = "\$core->url->type ".$sign."= '".addslashes($attr['current_mode'])."'"; + } + + if (isset($attr['has_tpl'])) { + $sign = ''; + if (substr($attr['has_tpl'],0,1) == '!') { + $sign = '!'; + $attr['has_tpl'] = substr($attr['has_tpl'],1); + } + $if[] = $sign."\$core->tpl->getFilePath('".addslashes($attr['has_tpl'])."') !== false"; + } + + if (isset($attr['has_tag'])) { + $sign = ''; + if (substr($attr['has_tag'],0,1) == '!') { + $sign = '!'; + $attr['has_tag'] = substr($attr['has_tag'],1); + } + $if[] = $sign."(\$core->tpl->tagExists('".addslashes($attr['has_tag'])."') )"; + } + + if (isset($attr['comments_active'])) { + $sign = (boolean) $attr['comments_active'] ? '' : '!'; + $if[] = $sign.'$core->blog->settings->allow_comments'; + } + + if (isset($attr['pings_active'])) { + $sign = (boolean) $attr['pings_active'] ? '' : '!'; + $if[] = $sign.'$core->blog->settings->allow_trackbacks'; + } + + if (isset($attr['wiki_comments'])) { + $sign = (boolean) $attr['wiki_comments'] ? '' : '!'; + $if[] = $sign.'$core->blog->settings->wiki_comments'; + } + + if (isset($attr['search_count']) && + preg_match('/^((=|!|>|<)=|(>|<))\s*[0-9]+$/',trim($attr['search_count']))) { + $if[] = '(isset($_search_count) && $_search_count '.html::decodeEntities($attr['search_count']).')'; + } + + if (!empty($if)) { + return ''.$content.''; + } else { + return $content; + } + } + + /*dtd + + */ + public function SysIfCommentPublished($attr,$content) + { + return + ''. + $content. + ''; + } + + /*dtd + + */ + public function SysIfCommentPending($attr,$content) + { + return + ''. + $content. + ''; + } + + /*dtd + + */ + public function SysFeedSubtitle($attr) + { + $f = $this->getFilters($attr); + return 'feed_subtitle !== null) { echo '.sprintf($f,'$_ctx->feed_subtitle').';} ?>'; + } + + /*dtd + + */ + public function SysIfFormError($attr,$content) + { + return + 'form_error !== null) : ?>'. + $content. + ''; + } + + /*dtd + + */ + public function SysFormError($attr) + { + return + 'form_error !== null) { echo $_ctx->form_error; } ?>'; + } + + public function SysPoweredBy($attr) + { + return + 'Dotclear"); ?>'; + } + + public function SysSearchString($attr) + { + $s = isset($attr['string']) ? $attr['string'] : '%1$s'; + + $f = $this->getFilters($attr); + return ''; + } + + public function SysSelfURI($attr) + { + $f = $this->getFilters($attr); + return ''; + } +} +?> diff --git a/inc/public/default-templates/atom-comments.xml b/inc/public/default-templates/atom-comments.xml new file mode 100644 index 0000000..7cd4efb --- /dev/null +++ b/inc/public/default-templates/atom-comments.xml @@ -0,0 +1,45 @@ + + + + {{tpl:BlogName encode_xml="1"}}{{tpl:SysFeedSubtitle encode_xml="1"}} + - {{tpl:lang Comments}} + {{tpl:BlogDescription encode_xml="1"}} + + + {{tpl:BlogUpdateDate iso8601="1"}} + + {{tpl:BlogEditor encode_xml="1"}} + + {{tpl:BlogFeedID}} + Dotclear + + + + + + [ping] {{tpl:PingEntryTitle encode_xml="1"}} - {{tpl:PingBlogName encode_xml="1"}} + + {{tpl:PingFeedID}} + {{tpl:PingDate iso8601="1"}} + {{tpl:PingBlogName encode_xml="1"}} + <p><a href="{{tpl:PingAuthorURL encode_xml="1"}}">{{tpl:PingTitle encode_xml="1"}}</a></p> {{tpl:PingContent encode_xml="1"}} + + + + + + + {{tpl:CommentEntryTitle encode_xml="1"}} - {{tpl:CommentAuthor encode_xml="1"}} + + {{tpl:CommentFeedID}} + {{tpl:CommentDate iso8601="1"}} + {{tpl:CommentAuthor encode_xml="1"}} + {{tpl:CommentContent absolute_urls="1" encode_xml="1"}} + + + + + \ No newline at end of file diff --git a/inc/public/default-templates/atom.xml b/inc/public/default-templates/atom.xml new file mode 100644 index 0000000..483c003 --- /dev/null +++ b/inc/public/default-templates/atom.xml @@ -0,0 +1,49 @@ + + + + {{tpl:BlogName encode_xml="1"}}{{tpl:SysFeedSubtitle encode_xml="1"}} + {{tpl:BlogDescription encode_xml="1"}} + + + {{tpl:BlogUpdateDate iso8601="1"}} + + {{tpl:BlogEditor encode_xml="1"}} + + {{tpl:BlogFeedID}} + Dotclear + + + + + {{tpl:EntryTitle encode_xml="1"}} + + {{tpl:EntryFeedID}} + {{tpl:EntryDate iso8601="1"}} + {{tpl:EntryAuthorCommonName encode_xml="1"}} + + {{tpl:EntryCategory encode_html="1"}} + + {{tpl:MetaID}} + + {{tpl:EntryExcerpt absolute_urls="1" encode_xml="1"}} + {{tpl:EntryContent absolute_urls="1" encode_xml="1"}} + + + + + + + + {{tpl:EntryURL}}#comment-form + {{tpl:BlogFeedURL type="atom"}}/comments/{{tpl:EntryID}} + + + + + \ No newline at end of file diff --git a/inc/public/default-templates/password-form.html b/inc/public/default-templates/password-form.html new file mode 100644 index 0000000..bbbf63c --- /dev/null +++ b/inc/public/default-templates/password-form.html @@ -0,0 +1,43 @@ + + + + + + + {{tpl:lang Password needed}} - {{tpl:BlogName encode_html="1"}} + + + + + + +
    +

    {{tpl:lang Password needed}}

    + +

    {{tpl:lang You must give a password to access this area.}}

    +

    + +
    + + + \ No newline at end of file diff --git a/inc/public/default-templates/rss2-comments.xml b/inc/public/default-templates/rss2-comments.xml new file mode 100644 index 0000000..ccea31b --- /dev/null +++ b/inc/public/default-templates/rss2-comments.xml @@ -0,0 +1,48 @@ + + + + + {{tpl:BlogName encode_xml="1"}}{{tpl:SysFeedSubtitle encode_xml="1"}} + - {{tpl:lang Comments}} + {{tpl:BlogURL}} + + {{tpl:BlogDescription encode_xml="1"}} + {{tpl:BlogLanguage}} + {{tpl:BlogUpdateDate rfc822="1"}} + {{tpl:BlogCopyrightNotice encode_xml="1"}} + http://blogs.law.harvard.edu/tech/rss + Dotclear + + + + + + [ping] {{tpl:PingEntryTitle encode_xml="1"}} - {{tpl:PingBlogName encode_xml="1"}} + {{tpl:PingPostURL encode_xml="1"}}#c{{tpl:PingID}} + {{tpl:PingFeedID}} + {{tpl:PingDate rfc822="1"}} + {{tpl:PingBlogName encode_xml="1"}} + + <p><a href="{{tpl:PingAuthorURL encode_xml="1"}}">{{tpl:PingTitle encode_xml="1"}}</a></p> + {{tpl:PingContent encode_xml="1"}} + + + + + + {{tpl:CommentEntryTitle encode_xml="1"}} - {{tpl:CommentAuthor encode_xml="1"}} + {{tpl:CommentPostURL encode_xml="1"}}#c{{tpl:CommentID}} + {{tpl:CommentFeedID}} + {{tpl:CommentDate rfc822="1"}} + {{tpl:CommentAuthor encode_xml="1"}} + + {{tpl:CommentContent absolute_urls="1" encode_xml="1"}} + + + + + + \ No newline at end of file diff --git a/inc/public/default-templates/rss2.xml b/inc/public/default-templates/rss2.xml new file mode 100644 index 0000000..5e82dff --- /dev/null +++ b/inc/public/default-templates/rss2.xml @@ -0,0 +1,49 @@ + + + + + {{tpl:BlogName encode_xml="1"}}{{tpl:SysFeedSubtitle encode_xml="1"}} + {{tpl:BlogURL}} + + {{tpl:BlogDescription encode_xml="1"}} + {{tpl:BlogLanguage}} + {{tpl:BlogUpdateDate rfc822="1"}} + {{tpl:BlogCopyrightNotice encode_xml="1"}} + http://blogs.law.harvard.edu/tech/rss + Dotclear + + + + + {{tpl:EntryTitle encode_xml="1"}} + {{tpl:EntryURL}} + {{tpl:EntryFeedID}} + {{tpl:EntryDate rfc822="1"}} + {{tpl:EntryAuthorCommonName encode_xml="1"}} + + {{tpl:EntryCategory encode_html="1"}} + + {{tpl:MetaID}} + + {{tpl:EntryExcerpt absolute_urls="1" encode_xml="1"}} + {{tpl:EntryContent absolute_urls="1" encode_xml="1"}} + + + + + + + {{tpl:EntryURL}}#comment-form + {{tpl:EntryURL}}#comment-form + {{tpl:BlogFeedURL}}/comments/{{tpl:EntryID}} + + + + + + \ No newline at end of file diff --git a/inc/public/default-templates/rss2.xsl b/inc/public/default-templates/rss2.xsl new file mode 100644 index 0000000..9dcd864 --- /dev/null +++ b/inc/public/default-templates/rss2.xsl @@ -0,0 +1,120 @@ + + + + + + + + + {{tpl:lang Subscribe to}} <xsl:value-of select="/rss/channel/title"/> + + + + +
    +
    +

    +

    +
    +
    +

    {{tpl:lang What is an RSS feed?}}

    +

    {{tpl:lang RSS feed is a free blog summary. It provides content + (either posts or comments) or summaries of content, together with links + to the full versions, and other metadata. The last published items may + then be read by your favorite RSS + aggregator.}}

    +

    {{tpl:lang Subscribe}}

    +

    {{tpl:lang Simply copy the following URL into your aggregator:}}

    +

    +
    +
    + +
    + +
    + + +
    + + + +
    +

    +
    +
    +
    + +
    \ No newline at end of file diff --git a/inc/public/lib.tpl.context.php b/inc/public/lib.tpl.context.php new file mode 100644 index 0000000..3e37c67 --- /dev/null +++ b/inc/public/lib.tpl.context.php @@ -0,0 +1,435 @@ +pop($name); + } else { + $this->stack[$name][] =& $var; + if ($var instanceof record) { + $this->stack['cur_loop'][] =& $var; + } + } + } + + public function __get($name) + { + if (!isset($this->stack[$name])) { + return null; + } + + $n = count($this->stack[$name]); + if ($n > 0) { + return $this->stack[$name][($n-1)]; + } + + return null; + } + + public function exists($name) + { + return isset($this->stack[$name][0]); + } + + public function pop($name) + { + if (isset($this->stack[$name])) { + $v = array_pop($this->stack[$name]); + if ($v instanceof record) { + array_pop($this->stack['cur_loop']); + } + unset($v); + } + } + + # Loop position tests + public function loopPosition($start,$length=null,$even=null) + { + if (!$this->cur_loop) { + return false; + } + + $index = $this->cur_loop->index(); + $size = $this->cur_loop->count(); + + $test = false; + if ($start >= 0) + { + $test = $index >= $start; + if ($length !== null) { + if ($length >= 0) { + $test = $test && $index < $start + $length; + } else { + $test = $test && $index < $size + $length; + } + } + } + else + { + $test = $index >= $size + $start; + if ($length !== null) { + if ($length >= 0) { + $test = $test && $index < $size + $start + $length; + } else { + $test = $test && $index < $size + $length; + } + } + } + + if ($even !== null) { + $test = $test && $index%2 == $even; + } + + return $test; + } + + # Static methods + public static function global_filter($str, + $encode_xml, $remove_html, $cut_string, $lower_case, $upper_case ,$tag='') + { + $args = func_get_args(); + array_pop($args); + $args[0] =& $str; + + # --BEHAVIOR-- publicBeforeContentFilter + $res = $GLOBALS['core']->callBehavior('publicBeforeContentFilter',$GLOBALS['core'],$tag,$args); + + if ($remove_html) { + $str = self::remove_html($str); + $str = preg_replace('/\s+/',' ',$str); + } + + if ($encode_xml) { + $str = self::encode_xml($str); + } + + if ($cut_string) { + $str = self::cut_string($str,(integer) $cut_string); + } + + if ($lower_case) { + $str = self::lower_case($str); + } elseif ($upper_case) { + $str = self::upper_case($str); + } + + # --BEHAVIOR-- publicAfterContentFilter + $res = $GLOBALS['core']->callBehavior('publicAfterContentFilter',$GLOBALS['core'],$tag,$args); + + return $str; + } + + + public static function cut_string($str,$l) + { + return text::cutString($str,$l); + } + + public static function encode_xml($str) + { + return html::escapeHTML($str); + } + + public static function remove_html($str) + { + return html::decodeEntities(html::clean($str)); + } + + public static function lower_case($str) + { + return mb_strtolower($str); + } + + public static function upper_case($str) + { + return mb_strtoupper($str); + } + + public static function categoryPostParam(&$p) + { + $not = substr($p['cat_url'],0,1) == '!'; + if ($not) { + $p['cat_url'] = substr($p['cat_url'],1); + } + + $p['cat_url'] = preg_split('/\s*,\s*/',$p['cat_url'],-1,PREG_SPLIT_NO_EMPTY); + + foreach ($p['cat_url'] as &$v) + { + if ($not) { + $v .= ' ?not'; + } + if ($GLOBALS['_ctx']->exists('categories') && preg_match('/#self/',$v)) { + $v = preg_replace('/#self/',$GLOBALS['_ctx']->categories->cat_url,$v); + } elseif ($GLOBALS['_ctx']->exists('posts') && preg_match('/#self/',$v)) { + $v = preg_replace('/#self/',$GLOBALS['_ctx']->posts->cat_url,$v); + } + } + } + + # Static methods for pagination + public static function PaginationNbPages() + { + global $_ctx; + + if ($_ctx->pagination === null) { + return false; + } + + $nb_posts = $_ctx->pagination->f(0); + $nb_per_page = $_ctx->post_params['limit'][1]; + + $nb_pages = ceil($nb_posts/$nb_per_page); + + return $nb_pages; + } + + public static function PaginationPosition($offset=0) + { + if (isset($GLOBALS['_page_number'])) { + $p = $GLOBALS['_page_number']; + } else { + $p = 1; + } + + $p = $p+$offset; + + $n = self::PaginationNbPages(); + if (!$n) { + return $p; + } + + if ($p > $n || $p <= 0) { + return 1; + } else { + return $p; + } + } + + public static function PaginationStart() + { + if (isset($GLOBALS['_page_number'])) { + return self::PaginationPosition() == 1; + } + + return true; + } + + public static function PaginationEnd() + { + if (isset($GLOBALS['_page_number'])) { + return self::PaginationPosition() == self::PaginationNbPages(); + } + + return false; + } + + public static function PaginationURL($offset=0) + { + $args = $_SERVER['URL_REQUEST_PART']; + + $n = self::PaginationPosition($offset); + + $args = preg_replace('#(^|/)page/([0-9]+)$#','',$args); + + $url = $GLOBALS['core']->blog->url.$args; + + if ($n > 1) { + $url = preg_replace('#/$#','',$url); + $url .= '/page/'.$n; + } + + # If search param + if (!empty($_GET['q'])) { + $s = strpos($url,'?') !== false ? '&' : '?'; + $url .= $s.'q='.rawurlencode($_GET['q']); + } + return $url; + } + + # Robots policy + public static function robotsPolicy($base,$over) + { + $pol = array('INDEX' => 'INDEX','FOLLOW' => 'FOLLOW', 'ARCHIVE' => 'ARCHIVE'); + $base = array_flip(preg_split('/\s*,\s*/',$base)); + $over = array_flip(preg_split('/\s*,\s*/',$over)); + + foreach ($pol as $k => &$v) + { + if (isset($base[$k]) || isset($base['NO'.$k])) { + $v = isset($base['NO'.$k]) ? 'NO'.$k : $k; + } + if (isset($over[$k]) || isset($over['NO'.$k])) { + $v = isset($over['NO'.$k]) ? 'NO'.$k : $k; + } + } + + if ($pol['ARCHIVE'] == 'ARCHIVE') { + unset($pol['ARCHIVE']); + } + + return implode(', ',$pol); + } + + # Smilies static methods + public static function getSmilies(&$blog) + { + $path = array(); + if (isset($GLOBALS['__theme'])) { + $path[] = $GLOBALS['__theme']; + } + $path[] = 'default'; + $definition = $blog->themes_path.'/%s/smilies/smilies.txt'; + $base_url = $blog->settings->themes_url.'/%s/smilies/'; + + $res = array(); + + foreach ($path as $t) + { + if (file_exists(sprintf($definition,$t))) { + $base_url = sprintf($base_url,$t); + return self::smiliesDefinition(sprintf($definition,$t),$base_url); + } + } + return false; + } + + public static function smiliesDefinition($f,$url) + { + $def = file($f); + + $res = array(); + foreach($def as $v) + { + $v = trim($v); + if (preg_match('|^([^\t]*)[\t]+(.*)$|',$v,$matches)) + { + $r = '/(\A|[\s]+|>)('.preg_quote($matches[1],'/').')([\s]+|[<]|\Z)/ms'; + $s = '$1$3'; + $res[$r] = $s; + } + } + + return $res; + } + + public static function addSmilies($str) + { + if (!isset($GLOBALS['__smilies']) || !is_array($GLOBALS['__smilies'])) { + return $str; + } + + return preg_replace(array_keys($GLOBALS['__smilies']),array_values($GLOBALS['__smilies']),$str); + } + + # First post image helpers + public static function EntryFirstImageHelper($size,$with_category,$class="") + { + if (!preg_match('/^sq|t|s|m|o$/',$size)) { + $size = 's'; + } + + global $core, $_ctx; + + $p_url = $core->blog->settings->public_url; + $p_site = preg_replace('#^(.+?//.+?)/(.*)$#','$1',$core->blog->url); + $p_root = $core->blog->public_path; + + $pattern = '(?:'.preg_quote($p_site,'/').')?'.preg_quote($p_url,'/'); + $pattern = sprintf('/]+/msu',$pattern); + + $src = ''; + $alt = ''; + + # We first look in post content + if ($_ctx->posts) + { + $subject = $_ctx->posts->post_excerpt_xhtml.$_ctx->posts->post_content_xhtml.$_ctx->posts->cat_desc; + if (preg_match_all($pattern,$subject,$m) > 0) + { + foreach ($m[1] as $i => $img) { + if (($src = self::ContentFirstImageLookup($p_root,$img,$size)) !== false) { + $src = $p_url.'/'.dirname($img).'/'.$src; + if (preg_match('/alt="([^"]+)"/',$m[0][$i],$malt)) { + $alt = $malt[1]; + } + break; + } + } + } + } + + # No src, look in category description if available + if (!$src && $with_category && $_ctx->categories) + { + if (preg_match_all($pattern,$_ctx->categories->cat_desc,$m) > 0) + { + foreach ($m[1] as $i => $img) { + if (($src = self::ContentFirstImageLookup($p_root,$img,$size)) !== false) { + $src = $p_url.'/'.dirname($img).'/'.$src; + if (preg_match('/alt="([^"]+)"/',$m[0][$i],$malt)) { + $alt = $malt[1]; + } + break; + } + } + }; + } + + if ($src) { + return ''.$alt.''; + } + } + + private static function ContentFirstImageLookup($root,$img,$size) + { + # Get base name and extension + $info = path::info($img); + $base = $info['base']; + + if (preg_match('/^\.(.+)_(sq|t|s|m)$/',$base,$m)) { + $base = $m[1]; + } + + $res = false; + if ($size != 'o' && file_exists($root.'/'.$info['dirname'].'/.'.$base.'_'.$size.'.jpg')) + { + $res = '.'.$base.'_'.$size.'.jpg'; + } + else + { + $f = $root.'/'.$info['dirname'].'/'.$base; + if (file_exists($f.'.'.$info['extension'])) { + $res = $base.'.'.$info['extension']; + } elseif (file_exists($f.'.jpg')) { + $res = $base.'.jpg'; + } elseif (file_exists($f.'.png')) { + $res = $base.'.png'; + } elseif (file_exists($f.'.gif')) { + $res = $base.'.gif'; + } + } + + if ($res) { + return $res; + } + return false; + } +} +?> \ No newline at end of file diff --git a/inc/public/lib.urlhandlers.php b/inc/public/lib.urlhandlers.php new file mode 100644 index 0000000..0eee676 --- /dev/null +++ b/inc/public/lib.urlhandlers.php @@ -0,0 +1,560 @@ +url->type = '404'; + echo $core->tpl->getData('404.html'); + + # --BEHAVIOR-- publicAfterDocument + $core->callBehavior('publicAfterDocument',$core); + exit; + } + + protected static function getPageNumber(&$args) + { + if (preg_match('#(^|/)page/([0-9]+)$#',$args,$m)) { + $n = (integer) $m[2]; + if ($n > 0) { + $args = preg_replace('#(^|/)page/([0-9]+)$#','',$args); + return $n; + } + } + + return false; + } + + protected static function serveDocument($tpl,$content_type='text/html',$http_cache=true,$http_etag=true) + { + $_ctx =& $GLOBALS['_ctx']; + $core =& $GLOBALS['core']; + + if ($_ctx->nb_entry_per_page === null) { + $_ctx->nb_entry_per_page = $core->blog->settings->nb_post_per_page; + } + + $tpl_file = $core->tpl->getFilePath($tpl); + + if (!$tpl_file) { + throw new Exception('Unable to find template'); + } + + if ($http_cache) { + $GLOBALS['mod_files'][] = $tpl_file; + http::cache($GLOBALS['mod_files'],$GLOBALS['mod_ts']); + } + + $result = new ArrayObject; + + header('Content-Type: '.$content_type.'; charset=UTF-8'); + $_ctx->current_tpl = $tpl; + $result['content'] = $core->tpl->getData($tpl); + $result['content_type'] = $content_type; + $result['tpl'] = $tpl; + $result['blogupddt'] = $core->blog->upddt; + + # --BEHAVIOR-- urlHandlerServeDocument + $core->callBehavior('urlHandlerServeDocument',$result); + + if ($http_cache && $http_etag) { + http::etag($result['content'],http::getSelfURI()); + } + echo $result['content']; + } + + public static function home($args) + { + $n = self::getPageNumber($args); + + if ($args && !$n) + { + # "Then specified URL went unrecognized by all URL handlers and + # defaults to the home page, but is not a page number. + self::p404(); + } + else + { + $core =& $GLOBALS['core']; + + if ($n) { + $GLOBALS['_page_number'] = $n; + $core->url->type = $n > 1 ? 'default-page' : 'default'; + } + + if (empty($_GET['q'])) { + self::serveDocument('home.html'); + $core->blog->publishScheduledEntries(); + } else { + self::search(); + } + } + } + + public static function search() + { + $_ctx =& $GLOBALS['_ctx']; + $core =& $GLOBALS['core']; + + $GLOBALS['_search'] = !empty($_GET['q']) ? rawurldecode($_GET['q']) : ''; + if ($GLOBALS['_search']) { + $GLOBALS['_search_count'] = $core->blog->getPosts(array('search' => $GLOBALS['_search']),true)->f(0); + } + + self::serveDocument('search.html'); + } + + public static function lang($args) + { + $_ctx =& $GLOBALS['_ctx']; + $core =& $GLOBALS['core']; + + $n = self::getPageNumber($args); + + $params['lang'] = $args; + $_ctx->langs = $core->blog->getLangs($params); + + if ($_ctx->langs->isEmpty()) { + # The specified language does not exist. + self::p404(); + } + else + { + if ($n) { + $GLOBALS['_page_number'] = $n; + } + $_ctx->cur_lang = $args; + self::home(null); + } + } + + public static function category($args) + { + $_ctx =& $GLOBALS['_ctx']; + $core =& $GLOBALS['core']; + + $n = self::getPageNumber($args); + + if ($args == '' && !$n) { + # No category was specified. + self::p404(); + } + else + { + $params['cat_url'] = $args; + $params['post_type'] = 'post'; + + $_ctx->categories = $core->blog->getCategories($params); + + if ($_ctx->categories->isEmpty()) { + # The specified category does no exist. + self::p404(); + } + else + { + if ($n) { + $GLOBALS['_page_number'] = $n; + } + self::serveDocument('category.html'); + } + } + } + + public static function archive($args) + { + $_ctx =& $GLOBALS['_ctx']; + $core =& $GLOBALS['core']; + + $year = $month = $cat_url = null; + # Nothing or year and month + if ($args == '') + { + self::serveDocument('archive.html'); + } + elseif (preg_match('|^/([0-9]{4})/([0-9]{2})$|',$args,$m)) + { + $params['year'] = $m[1]; + $params['month'] = $m[2]; + $params['type'] = 'month'; + $_ctx->archives = $core->blog->getDates($params); + + if ($_ctx->archives->isEmpty()) { + # There is no entries for the specified period. + self::p404(); + } + else + { + self::serveDocument('archive_month.html'); + } + } + else { + # The specified URL is not a date. + self::p404(); + } + } + + public static function post($args) + { + if ($args == '') { + # No entry was specified. + self::p404(); + } + else + { + $_ctx =& $GLOBALS['_ctx']; + $core =& $GLOBALS['core']; + + $core->blog->withoutPassword(false); + + $params = new ArrayObject(); + $params['post_url'] = $args; + + $_ctx->posts = $core->blog->getPosts($params); + + $_ctx->comment_preview = new ArrayObject(); + $_ctx->comment_preview['content'] = ''; + $_ctx->comment_preview['rawcontent'] = ''; + $_ctx->comment_preview['name'] = ''; + $_ctx->comment_preview['mail'] = ''; + $_ctx->comment_preview['site'] = ''; + $_ctx->comment_preview['preview'] = false; + $_ctx->comment_preview['remember'] = false; + + $core->blog->withoutPassword(true); + + + if ($_ctx->posts->isEmpty()) + { + # The specified entry does not exist. + self::p404(); + } + else + { + $post_id = $_ctx->posts->post_id; + $post_password = $_ctx->posts->post_password; + + # Password protected entry + if ($post_password != '' && !$_ctx->preview) + { + # Get passwords cookie + if (isset($_COOKIE['dc_passwd'])) { + $pwd_cookie = unserialize($_COOKIE['dc_passwd']); + } else { + $pwd_cookie = array(); + } + + # Check for match + if ((!empty($_POST['password']) && $_POST['password'] == $post_password) + || (isset($pwd_cookie[$post_id]) && $pwd_cookie[$post_id] == $post_password)) + { + $pwd_cookie[$post_id] = $post_password; + setcookie('dc_passwd',serialize($pwd_cookie),0,'/'); + } + else + { + self::serveDocument('password-form.html','text/html',false); + return; + } + } + + $post_comment = + isset($_POST['c_name']) && isset($_POST['c_mail']) && + isset($_POST['c_site']) && isset($_POST['c_content']) && + $_ctx->posts->commentsActive(); + + # Posting a comment + if ($post_comment) + { + # Spam trap + if (!empty($_POST['f_mail'])) { + http::head(412,'Precondition Failed'); + header('Content-Type: text/plain'); + echo "So Long, and Thanks For All the Fish"; + # Exits immediately the application to preserve the server. + exit; + } + + $name = $_POST['c_name']; + $mail = $_POST['c_mail']; + $site = $_POST['c_site']; + $content = $_POST['c_content']; + $preview = !empty($_POST['preview']); + + if ($content != '') + { + if ($core->blog->settings->wiki_comments) { + $core->initWikiComment(); + } else { + $core->initWikiSimpleComment(); + } + $content = $core->wikiTransform($content); + $content = $core->HTMLfilter($content); + } + + $_ctx->comment_preview['content'] = $content; + $_ctx->comment_preview['rawcontent'] = $_POST['c_content']; + $_ctx->comment_preview['name'] = $name; + $_ctx->comment_preview['mail'] = $mail; + $_ctx->comment_preview['site'] = $site; + + if ($preview) + { + # --BEHAVIOR-- publicBeforeCommentPreview + $core->callBehavior('publicBeforeCommentPreview',$_ctx->comment_preview); + + $_ctx->comment_preview['preview'] = true; + } + else + { + # Post the comment + $cur = $core->con->openCursor($core->prefix.'comment'); + $cur->comment_author = $name; + $cur->comment_site = html::clean($site); + $cur->comment_email = html::clean($mail); + $cur->comment_content = $content; + $cur->post_id = $_ctx->posts->post_id; + $cur->comment_status = $core->blog->settings->comments_pub ? 1 : -1; + $cur->comment_ip = http::realIP(); + + $redir = $_ctx->posts->getURL(); + $redir .= strpos($redir,'?') !== false ? '&' : '?'; + + try + { + if (!text::isEmail($cur->comment_email)) { + throw new Exception(__('You must provide a valid email address.')); + } + + # --BEHAVIOR-- publicBeforeCommentCreate + $core->callBehavior('publicBeforeCommentCreate',$cur); + if ($cur->post_id) { + $comment_id = $core->blog->addComment($cur); + + # --BEHAVIOR-- publicAfterCommentCreate + $core->callBehavior('publicAfterCommentCreate',$cur,$comment_id); + } + + if ($cur->comment_status == 1) { + $redir_arg = 'pub=1'; + } else { + $redir_arg = 'pub=0'; + } + + header('Location: '.$redir.$redir_arg); + } + catch (Exception $e) + { + $_ctx->form_error = $e->getMessage(); + $_ctx->form_error; + } + } + } + + # The entry + self::serveDocument('post.html'); + } + } + } + + public static function preview($args) + { + $core = $GLOBALS['core']; + $_ctx = $GLOBALS['_ctx']; + + if (!preg_match('#^(.+?)/([0-9a-z]{40})/(.+?)$#',$args,$m)) { + # The specified Preview URL is malformed. + self::p404(); + } + else + { + $user_id = $m[1]; + $user_key = $m[2]; + $post_url = $m[3]; + if (!$core->auth->checkUser($user_id,null,$user_key)) { + # The user has no access to the entry. + self::p404(); + } + else + { + $_ctx->preview = true; + self::post($post_url); + } + } + } + + public static function feed($args) + { + $type = null; + $comments = false; + $cat_url = false; + $post_id = null; + $params = array(); + $subtitle = ''; + + $mime = 'application/xml'; + + $_ctx =& $GLOBALS['_ctx']; + $core =& $GLOBALS['core']; + + if (preg_match('!^([a-z]{2}(-[a-z]{2})?)/(.*)$!',$args,$m)) { + $params['lang'] = $m[1]; + $args = $m[3]; + + $_ctx->langs = $core->blog->getLangs($params); + + if ($_ctx->langs->isEmpty()) { + # The specified language does not exist. + self::p404(); + return; + } else { + $_ctx->cur_lang = $m[1]; + } + } + + if (preg_match('#^rss2/xslt$#',$args,$m)) + { + # RSS XSLT stylesheet + self::serveDocument('rss2.xsl','text/xml'); + return; + } + elseif (preg_match('#^(atom|rss2)/comments/([0-9]+)$#',$args,$m)) + { + # Post comments feed + $type = $m[1]; + $comments = true; + $post_id = (integer) $m[2]; + } + elseif (preg_match('#^(?:category/(.+)/)?(atom|rss2)(/comments)?$#',$args,$m)) + { + # All posts or comments feed + $type = $m[2]; + $comments = !empty($m[3]); + if (!empty($m[1])) { + $cat_url = $m[1]; + } + } + else + { + # The specified Feed URL is malformed. + self::p404(); + return; + } + + if ($cat_url) + { + $params['cat_url'] = $cat_url; + $params['post_type'] = 'post'; + $_ctx->categories = $core->blog->getCategories($params); + + if ($_ctx->categories->isEmpty()) { + # The specified category does no exist. + self::p404(); + return; + } + + $subtitle = ' - '.$_ctx->categories->cat_title; + } + elseif ($post_id) + { + $params['post_id'] = $post_id; + $params['post_type'] = ''; + $_ctx->posts = $core->blog->getPosts($params); + + if ($_ctx->posts->isEmpty()) { + # The specified post does not exist. + self::p404(); + return; + } + + $subtitle = ' - '.$_ctx->posts->post_title; + } + + $tpl = $type; + if ($comments) { + $tpl .= '-comments'; + $_ctx->nb_comment_per_page = $core->blog->settings->nb_comment_per_feed; + } else { + $_ctx->nb_entry_per_page = $core->blog->settings->nb_post_per_feed; + $_ctx->short_feed_items = $core->blog->settings->short_feed_items; + } + $tpl .= '.xml'; + + if ($type == 'atom') { + $mime = 'application/atom+xml'; + } + + $_ctx->feed_subtitle = $subtitle; + + header('X-Robots-Tag: '.context::robotsPolicy($core->blog->settings->robots_policy,'')); + self::serveDocument($tpl,$mime); + if (!$comments && !$cat_url) { + $core->blog->publishScheduledEntries(); + } + } + + public static function trackback($args) + { + if (!preg_match('/^[0-9]+$/',$args)) { + # The specified trackback URL is not an number + self::p404(); + } else { + $tb = new dcTrackback($GLOBALS['core']); + $tb->receive($args); + } + } + + public static function rsd($args) + { + $core =& $GLOBALS['core']; + http::cache($GLOBALS['mod_files'],$GLOBALS['mod_ts']); + + header('Content-Type: text/xml; charset=UTF-8'); + echo + ''."\n". + ''."\n". + "\n". + " Dotclear\n". + " http://www.dotclear.org/\n". + ' '.html::escapeHTML($core->blog->url)."\n"; + + if ($core->blog->settings->enable_xmlrpc) + { + $u = sprintf(DC_XMLRPC_URL,$core->blog->url,$core->blog->id); + + echo + " \n". + ' '."\n". + ' '."\n". + ' '."\n". + ' '."\n". + " \n"; + } + + echo + "\n". + "\n"; + } + + public static function xmlrpc($args) + { + $core =& $GLOBALS['core']; + $server = new dcXmlRpc($core,$args); + $server->serve(); + } +} +?> \ No newline at end of file diff --git a/inc/public/prepend.php b/inc/public/prepend.php new file mode 100644 index 0000000..75fed25 --- /dev/null +++ b/inc/public/prepend.php @@ -0,0 +1,133 @@ +setBlog(DC_BLOG_ID); +} + +if ($core->blog->id == null) { + __error(__('Blog is not defined.') + ,__('Did you change your Blog ID?') + ,30); +} + +# Loading media +try { + $core->media = new dcMedia($core); +} catch (Exception $e) {} + +# Creating template context +$_ctx = new context(); +try { + $core->tpl = new dcTemplate(DC_TPL_CACHE,'$core->tpl',$core); +} catch (Exception $e) { + __error(__('Can\'t create template files.') + ,$e->getMessage() + ,40); +} + +# Loading locales +$_lang = $core->blog->settings->lang; +$_lang = preg_match('/^[a-z]{2}(-[a-z]{2})?$/',$_lang) ? $_lang : 'en'; + +if (l10n::set(dirname(__FILE__).'/../../locales/'.$_lang.'/date') === false && $_lang != 'en') { + l10n::set(dirname(__FILE__).'/../../locales/en/date'); +} +l10n::set(dirname(__FILE__).'/../../locales/'.$_lang.'/public'); +l10n::set(dirname(__FILE__).'/../../locales/'.$_lang.'/plugins'); + +# Loading plugins +$core->plugins->loadModules(DC_PLUGINS_ROOT,'public',$_lang); + +# Loading themes +$core->themes = new dcThemes($core); +$core->themes->loadModules($core->blog->themes_path); + +# Defining theme if not defined +if (!isset($__theme)) { + $__theme = $core->blog->settings->theme; +} + +if (!$core->themes->moduleExists($__theme)) { + $__theme = $core->blog->settings->theme = 'default'; +} + +$__parent_theme = $core->themes->moduleInfo($__theme,'parent'); +if ($__parent_theme) { + if (!$core->themes->moduleExists($__parent_theme)) { + $__theme = $core->blog->settings->theme = 'default'; + $__parent_theme = null; + } +} + +# If theme doesn't exist, stop everything +if (!$core->themes->moduleExists($__theme)) { + __error(__('Default theme not found.') + ,__('This either means you removed your default theme or set a wrong theme '. + 'path in your blog configuration. Please check theme_path value in '. + 'about:config module or reinstall default theme.') + ,50); +} + +# Loading _public.php file for selected theme +$core->themes->loadNsFile($__theme,'public'); + +# --BEHAVIOR-- publicPrepend +$core->callBehavior('publicPrepend',$core); + +# Prepare the HTTP cache thing +$mod_files = get_included_files(); +$mod_ts = array(); +$mod_ts[] = $core->blog->upddt; + +$__theme_tpl_path = array( + $core->blog->themes_path.'/'.$__theme.'/tpl' +); +if ($__parent_theme) { + $__theme_tpl_path[] = $core->blog->themes_path.'/'.$__parent_theme.'/tpl'; +} + +$core->tpl->setPath( + $__theme_tpl_path, + $core->blog->themes_path.'/default/tpl', + dirname(__FILE__).'/default-templates', + $core->tpl->getPath()); + +$core->url->mode = $core->blog->settings->url_scan; + +try { + # --BEHAVIOR-- publicBeforeDocument + $core->callBehavior('publicBeforeDocument',$core); + + $core->url->getDocument(); + + # --BEHAVIOR-- publicAfterDocument + $core->callBehavior('publicAfterDocument',$core); +} catch (Exception $e) { + __error($e->getMessage() + ,__('Something went wrong while loading template file for your blog.') + ,60); +} +?> \ No newline at end of file diff --git a/inc/public/rs.extension.php b/inc/public/rs.extension.php new file mode 100644 index 0000000..3456a82 --- /dev/null +++ b/inc/public/rs.extension.php @@ -0,0 +1,93 @@ +addBehavior('coreBlogGetPosts',array('rsExtendPublic','coreBlogGetPosts')); +$core->addBehavior('coreBlogGetComments',array('rsExtendPublic','coreBlogGetComments')); + +class rsExtendPublic +{ + public static function coreBlogGetPosts(&$rs) + { + $rs->extend('rsExtPostPublic'); + } + + public static function coreBlogGetComments(&$rs) + { + $rs->extend('rsExtCommentPublic'); + } +} + +class rsExtPostPublic extends rsExtPost +{ + public static function getContent(&$rs,$absolute_urls=false) + { + # Not very nice hack but it does the job :) + if (isset($GLOBALS['_ctx']) && $GLOBALS['_ctx']->short_feed_items === true) { + $_ctx =& $GLOBALS['_ctx']; + $c = parent::getContent($rs,$absolute_urls); + $c = context::remove_html($c); + $c = context::cut_string($c,350); + + $c = + '

    '.$c.'... '. + ''.__('Read').' '. + html::escapeHTML($rs->post_title).'

    '; + + return $c; + } + + if ($rs->core->blog->settings->use_smilies) + { + return self::smilies(parent::getContent($rs,$absolute_urls),$rs->core->blog); + } + + return parent::getContent($rs,$absolute_urls); + } + + public static function getExcerpt(&$rs,$absolute_urls=false) + { + if ($rs->core->blog->settings->use_smilies) + { + return self::smilies(parent::getExcerpt($rs,$absolute_urls),$rs->core->blog); + } + + return parent::getExcerpt($rs,$absolute_urls); + } + + protected static function smilies($c,&$blog) + { + if (!isset($GLOBALS['__smilies'])) { + $GLOBALS['__smilies'] = context::getSmilies($blog); + } + return context::addSmilies($c); + } +} + +class rsExtCommentPublic extends rsExtComment +{ + public static function getContent(&$rs,$absolute_urls=false) + { + if ($rs->core->blog->settings->use_smilies) + { + $c = parent::getContent($rs,$absolute_urls); + + if (!isset($GLOBALS['__smilies'])) { + $GLOBALS['__smilies'] = context::getSmilies($rs->core->blog); + } + return context::addSmilies($c); + } + + return parent::getContent($rs,$absolute_urls); + } +} +?> \ No newline at end of file diff --git a/inc/swf/player_flv.swf b/inc/swf/player_flv.swf new file mode 100644 index 0000000000000000000000000000000000000000..01ec373bb1f1f48fbe17200d9f01c6ae9e8f71a4 GIT binary patch literal 12975 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 \ No newline at end of file diff --git a/locales/README b/locales/README new file mode 100644 index 0000000..d021aa6 --- /dev/null +++ b/locales/README @@ -0,0 +1 @@ +Please see http://www.dotclear.org/translate diff --git a/locales/en/date.lang.php b/locales/en/date.lang.php new file mode 100644 index 0000000..726c436 --- /dev/null +++ b/locales/en/date.lang.php @@ -0,0 +1,38 @@ + \ No newline at end of file diff --git a/locales/en/date.po b/locales/en/date.po new file mode 100644 index 0000000..6f56683 --- /dev/null +++ b/locales/en/date.po @@ -0,0 +1,56 @@ +msgid "_Jan" +msgstr "Jan" + +msgid "_Feb" +msgstr "Feb" + +msgid "_Mar" +msgstr "Mar" + +msgid "_Apr" +msgstr "Apr" + +msgid "_May" +msgstr "May" + +msgid "_Jun" +msgstr "Jun" + +msgid "_Jul" +msgstr "Jul" + +msgid "_Aug" +msgstr "Aug" + +msgid "_Sep" +msgstr "Sep" + +msgid "_Oct" +msgstr "Oct" + +msgid "_Nov" +msgstr "Nov" + +msgid "_Dec" +msgstr "Dec" + +msgid "_Mon" +msgstr "Mon" + +msgid "_Tue" +msgstr "Tue" + +msgid "_Wed" +msgstr "Wed" + +msgid "_Thu" +msgstr "Thu" + +msgid "_Fri" +msgstr "Fri" + +msgid "_Sat" +msgstr "Sat" + +msgid "_Sun" +msgstr "Sun" \ No newline at end of file diff --git a/locales/en/help/blog_pref.html b/locales/en/help/blog_pref.html new file mode 100644 index 0000000..40b7ac1 --- /dev/null +++ b/locales/en/help/blog_pref.html @@ -0,0 +1,148 @@ + + + Blog settings + + + + +

    Blog details

    +
    +
    Blog ID
    +
    Unique ID of the blog. Mandatory, can only be modified by a super administrator.
    + +
    Blog name
    +
    Name of the blog, mandatory.
    + +
    Blog URL
    +
    Complete blog URL. Mandatory, can only be modified by a super administrator.
    + +
    Blog status
    +
    +
      +
    • online: blog open to visitors
    • +
    • offline: blog closed to visitors + but open to writers.
    • +
    • removed: blog closed to both visitors and writers.
    • +
    +
    + +
    Blog description
    +
    Here you can put any description you want for your blog. This is a + simple text, without formatting.
    +
    + +

    Blog configuration

    +
    +
    Blog editor's name
    +
    Name of the person responsible for the blog. It may be the owner or the + publisher if he exists.
    + +
    Copyright notice
    +
    Note about the reproduction rights for the blog.
    + +
    Default language
    +
    Language of the blog interface. Either this language is among the avalaible ones, + and the interface will be translated, or it is not, and the interface will then + default to English.
    + +
    Blog timezone
    +
    Defines the timezone that will be used for comments and trackbacks.
    + +
    Date formats
    +
    The date format of the blog posts. See the date and time + format reference section below for further details.
    + +
    Time format
    +
    The time format of the blog posts. See the date and time + format reference section below for further details.
    + +
    Display .. entries per page
    +
    The number will be used as the limit for the number of entries + on the homepage, the first page of each category and the rss feeds.
    + +
    Leave comments open for .. days
    +
    The number of days during wich comments and trackbacks will be open + after the post publication. When empty, the comments will be kept open + indefinitly.
    + +
    Display smilies on entries and comments
    +
    Display sequences of characters as :-) or ;-) as images.
    + +
    Accept comments
    +
    Globally accepts comments on the blog. Takes precedence over the + per post setting.
    + +
    Accept trackbacks
    +
    Globally accepts trackbacks on the blog. Takes precedence over the + per post setting.
    + +
    Moderate comments and trackbacks
    +
    With such an option, comments and trackbacks will be published after + editor agreement.
    + +
    Add "nofollow" relation on comments and trackbacks links
    +
    Adds an attribut on the links in comments and trackbacks, instructing the + search bots not to follow those links. This antispam features has yet to + prove its value.
    + +
    Wiki syntax for comments
    +
    Allows a subset of the wiki syntax to be used in comments.
    +
    + +

    Format reference

    +

    Some fields can be configured to format the date and time to your needs. +Here is a reference:

    + +
      +
    • %a: abreviated week day (local).
    • +
    • %A: complete week day (local).
    • +
    • %b: abbreviated month name (local).
    • +
    • %B: complete month name (local).
    • +
    • %c: default local date and time display.
    • +
    • %C: century (the year, divided by 100 and + round up beetween 00 and 99)
    • +
    • %d: numeric month day (from 01 to 31)
    • +
    • %D: identical to %m/%d/%y
    • +
    • %e: numeric month day (from 1 to 31)
    • +
    • %g: identical to %G, 2 digits.
    • +
    • %G: The year on 4 digits, according to the week number + (cf. %V). Format and value identical to %Y, except that if the number of the + week belongs to the preceding or following year, the current year + will be used instead.
    • +
    • %h: identical to %b
    • +
    • %H: digital hour of the day, 24H mode + (from 00 to 23)
    • +
    • %I: digital hour of the day, 12H mode + (from 01 to 12)
    • +
    • %j: day of the year, digital (from 001 to 366)
    • +
    • %m: month, digital (from 1 à 12)
    • +
    • %M: minute, digital
    • +
    • %n: newline character
    • +
    • %p: either `am' or `pm', according to the absolute time, + or depending of the local settings.
    • +
    • %r: the hour, a.m. and p.m. format
    • +
    • %R: the hour, 24h format
    • +
    • %S: seconds, digital
    • +
    • %t: tab character
    • +
    • %T: the current time (identical to %H:%M:%S)
    • +
    • %u: day week, digit, from 1 to 7. (1 stands for monday)
    • +
    • %U: week number, the first sundqy of the year being the + first day of the first week.
    • +
    • %V: the week numpber as defined in ISO + 8601:1988, digital, from 01 to 53. The week 1 is the first week + with more than 4 days in the current year, whose monday is the first day. + (Use %G or %g for the year elements corresponding to the number of the + week for the considered timestamp.)
    • +
    • %W: number of the week in the year, the first monday of + the year being the start of the first week
    • +
    • %w: day of the week, digital, 0 stands for sunday
    • +
    • %x: prefered format for the date without the time
    • +
    • %X: prefered format for the time without the date
    • +
    • %y: the year, two digits (from 00 to 99)
    • +
    • %Y: the year, four digits
    • +
    • %Z ou %z: timezone, name or abbreviation
    • +
    • %%: a litteral `%' character
    • +
    + + + diff --git a/locales/en/help/categories.html b/locales/en/help/categories.html new file mode 100644 index 0000000..983607c --- /dev/null +++ b/locales/en/help/categories.html @@ -0,0 +1,41 @@ + + + Categories + + + +

    Categories list

    +
    +
    Create a new category
    +
    Choose the name you wish to use for your new category + then click on Save to validate its creation. To modify it, + click on its name in the list.
    + +
    Change category order
    +
    To change the category order, drag and drop the categories by using + the arrow shaped images then click on save order. + If you do not see the arrows, use the numbered fields + beside each category.
    +
    + +

    Modifying a category

    +
    +
    Title
    +
    Choose the name you wish to give to your category + the click on Save to validate.
    + +
    URL
    +
    DotClear creates a default url for the category, making it reachable + with a path similar to this one : + http://monblog.tld/category/My-category. You can click + on the small lock on the right to modify it according to your needs.
    + +
    Description
    +
    What's inside the description field will be shown when selecting + one of the blog's categories. You can fill it with any kind of content + (paragraphs, lists, etc.) The format used for this field is HTML.
    + +
    + + + diff --git a/locales/en/help/comments.html b/locales/en/help/comments.html new file mode 100644 index 0000000..83338f2 --- /dev/null +++ b/locales/en/help/comments.html @@ -0,0 +1,58 @@ + + + Comments + + + +

    Filters for comment list

    +
    +
    Type:
    +
    None, comments or trackbacks.
    + +
    Status:
    +
      +
    • junk:
    • +
    • pending:
    • +
    • unpublished: offline ;
    • +
    • published: online.
    • +
    + +
    Order by:
    +
    Choose: date, entry title, author or status, then + choose the sort order.
    + +
    Sort
    +
    Choose whether the list will be sorted in ascending or descending order.
    + +
    Comment author.
    +
    The search is not case sensitive. If you want to search only a part of + the name, you can use the * generic character.
    + +
    Comments per page :
    +
    Allows you to choose the number of comments on each page of this list.
    +
    + +

    Modify or add a comment

    +
    +
    Author:
    +
    Author name. This field is mandatory.
    + +
    Email:
    +
    Author's email address.
    + +
    Web site:
    +
    URL of the comment author's blog or website.
    + +
    Status:
    +
      +
    • junk:
    • +
    • pending:
    • +
    • unpublished: offline
    • +
    • published: online
    • +
    + +
    Comment:
    +
    Comment's content. This field is html formated.
    +
    + + diff --git a/locales/en/help/media.html b/locales/en/help/media.html new file mode 100644 index 0000000..f81f9e8 --- /dev/null +++ b/locales/en/help/media.html @@ -0,0 +1,89 @@ + + + Media manager + + + + +

    Media list

    +

    The media manager's main page displays a list of available files (medias) +for the currently selected blog.

    + +

    You can click the icons or names of the medias in the folder or any +subfolder to display them.

    + +

    Selecting a MP3 sound file displays a player to immediately play +the file. The Flash plugin must be installed on your browser for +this player to operate.

    + +

    The images are displayed with a thumbnail when possible.

    + +

    Add files

    +
    +
    Choose a file
    +
    Here you can select one of your local files to send it on your + blog. Should the file be bigger than the maximum size, it will not be sent.
    + +
    Title
    +
    Optional title for the file you want to send.
    + +
    Private
    +
    Check this if you want the file to be private, i.e. accessible only by + its owner and not accessible from the blog.
    +
    + +

    New folder

    +

    This form allows you to create an new subfolder in the currently displayed +folder. Just choose a name for it as you would do on your own computer.

    + +

    Media details

    +

    This page displays a set of informations about the currently selected +file and allows you to perform a few operations.

    + +
    +
    File name
    +
    Change the file name of the current file.
    + +
    File title
    +
    Give a title to the file, or change the current one.
    + +
    File date
    +
    Change the file date.
    + +
    Private
    +
    Specify that the file will be hidden to anyone but its owner in the media manager.
    + +
    New directory
    +
    Allows you to move the file in another folder.
    + +
    Change file
    +
    With this form, you can replace the file while keeping all the attributes + (name, title...). As always, you have to respect the maximum file size.
    +
    + +

    A specific treatment for images

    +

    When you add an image, depending of its size, up to four versions will be made available:

    +
      +
    • square: a 48x48 pixels square thumbnail,
    • +
    • thumbnail: the image reduced to 100 pixels on its longest side.
    • +
    • small: the longuest side is reduced to 240 pixels.
    • +
    • medium: the longuest side is reduced to 500 pixels.
    • +
    • originale: the original, unchanged image.
    • +
    + +

    Add a file to an entry

    +

    You can easily attach a file to one of your posts. First, create a new post +and save it. Then click on "Add files to this entry" to open the media manager.

    + +

    Just click on the [+] icon (Attach this file to entry). The file will then +be attached to the post.

    + +

    The attached files will be shown on the post page, as a list beside the post content. +The MP3 files will be made available through the Flash player, so that they can easily by read by visitors.

    + +

    Podcast and broadcasting of music files

    +

    All attached files will be included in your RSS feeds, allowing for easy +podcasting of any type of file.

    + + + diff --git a/locales/en/help/post.html b/locales/en/help/post.html new file mode 100644 index 0000000..4282109 --- /dev/null +++ b/locales/en/help/post.html @@ -0,0 +1,125 @@ + + + Editing an entry + + + + +

    Editing an entry

    + +
    +
    Entry title
    +
    Type in the entry title. This field is mandatory.
    + +
    Excerpt
    +
    The content of this field will be shown in pages showing entries as + a list, such as the homepage or categories pages, followed by a "continue reading" + link. It will also be visible at the begining of the page showing the + whole post. Should you leave it blank, the content field will be shown + on the homepage and other entry list pages.
    + +
    Content
    +
    The content of your entry. This field is mandatory.
    + +
    Notes
    +
    This text area is for personal use, for notes or memos. What you enter here + will never be displayed on the blog..
    + +
    Category
    +
    Your entry's category. To create a new category, please see the + "categories" section. You can choose to leave + you entry without a category by selecting the blank line.
    + +
    Entry status
    +
    Allows you to choose your post's status: +
      +
    • pending: the publication status has not yet been decided.
    • +
    • scheduled: the post will be set online at the time and date + set in the Published on field.
    • +
    • unpublished: the post is offline.
    • +
    • published: the post is online.
    • +
    +
    + +
    Published on
    +
    Here you can change the post's publication date and time. If the post's + status is scheduled, it will come online at the said date and time.
    + +
    Text formating
    +
    To choose the post syntax. Wiki is a simplified syntax + and will be converted to valid xhtml ; Unless you have a perfect + understanding of html, we advise you to choose the wiki syntax. + See the Wiki syntax reference for more information.
    + +
    Accept comments
    +
    Select this box to allow your visitors to comment the entry. The corresponding + global setting is to be found in the blog settings.
    + +
    Accept trackbacks
    +
    A trackback is a way to let a portion of your entry as a comment on + another blog. Select this box to allow others to trackback your entry. The + corresponding global setting is to be found in the blog settings.
    + +
    Selected entry
    +
    The selected entries will be listed on your blog menu, under the title "Best + of me".
    + +
    Entry password
    +
    You can enter a password for your entry. A password protected entry will + not be displayed on your blog, it will only be reachable to those you will + give the entry url (see the view entry link) and password.
    + +
    Basename
    +
    By clicking on its lock, you can unprotect this field and and choose another + URL for your entry. If the URL you're trying to use is already used by another + entry, a number will be added to it.
    + +
    Entry lang.
    +
    The two character language code of your entry. It defaults to your (as a + user) language but you can change it to whatever language code you want, ie. + "en" or "fr-qc". This code is used for the entry's display, no chack is made + on it.
    + +
    Attachments
    +
    The attachments are all the medias you joined to the entry. The link add + file to this entry allows you to attach other files to the entry. Remember + to save your changes before clicking on this link. For further information, + see the media manager help.
    +
    + +

    Comments

    +
    +
    Comment list
    +
    On the Comments tab, you can read and change the status of + your entry's comments. If you're allowed to by the blog administrator, + you will be able to set your comments online or offline, to delete them or + to mark them as junk.
    + +
    Add a comment
    +
    On the Add a comment tab, you can reply to one of your entry's + comments without leaving your blog's backend. The syntax to be used here is + plain, unlimited, xhtml. Use the fields as if you were modifying a comment.
    +
    + +

    Trackback

    +

    To make a trackback, click on the Ping blogs link. +You will not see this link if your entry's status is not published.

    + +
    +
    URLs to ping
    +
    Paste here the trackback URLs you found in the posts you want to ping.
    + + +
    Send excerpt
    +
    This field defaults to your entry's first few sentences. That's wht will be + sent to the blog you're pinging, along with a link to your post. You can modify + the excerpt by editing this field.
    + + +
    Auto discover ping URLs
    +
    If your entries links specific posts and if the blog carrying those posts + is set to allow it, this tool will find the URLs to ping for you.
    +
    + + + diff --git a/locales/en/help/posts.html b/locales/en/help/posts.html new file mode 100644 index 0000000..82730c6 --- /dev/null +++ b/locales/en/help/posts.html @@ -0,0 +1,65 @@ + + + Managing entries + + + + +

    Filters for the entry list

    + +
    +
    Author
    +
    Allows you to filter by author.
    + +
    Category
    +
    Filter by category.
    + +
    Status
    +
      +
    • pending: posts whose publication status has not yet + been decided.
    • +
    • scheduled: post to be set online automatically.
    • +
    • unpublished: offline posts.
    • +
    • published: online posts.
    • +
    + +
    Selected
    +
    Only the selected posts, or the non selected ones.
    + +
    Month
    +
    Filter on a specific month and year.
    + +
    Language
    +
    Filter on the different languages used on the blog.
    + +
    Order by
    +
    Defines the list order, either on the date, the title, the author, + the status or the selected status.
    + +
    Sort
    +
    Choose whether the list will be sorted in ascending or descending order.
    + +
    Entries per page
    +
    Number of entries that will be displayed on each page of the resulting + set.
    +
    + +

    Selected entry actions

    +

    If your user permission level allows it, you can perform batch operations on the +entries you select in the list.

    + +
      +
    • Publish: set the entries online.
    • +
    • Unpublish: set the entries offline.
    • +
    • Schedule: schedule the entries to be set online at their + publication date.
    • +
    • Mark as pending: erase other publication status.
    • +
    • Change category: directs you to the category list to choose a + new one for the entries.
    • +
    • Change author: allows you to change the posts' author by + entering the new author's ID.
    • +
    • Delete: suppress the posts (this operation cannot be undone).
    • +
    + + + diff --git a/locales/en/help/user_pref.html b/locales/en/help/user_pref.html new file mode 100644 index 0000000..0da30cf --- /dev/null +++ b/locales/en/help/user_pref.html @@ -0,0 +1,61 @@ + + + User preferences + + + + +

    User preferences

    +
    +
    Name, First name
    +
    If the display name is empty, the author's name will be displayed + as his Firstname and Name as set here.
    + +
    Display name
    +
    You can choose here how your name will be displayed under your posts.
    + +
    Email
    +
    Address where will be sent the new comment notifications.
    + +
    URL
    +
    The user's web site. If set, the author name will be displayed as + a link to the said site.
    + +
    Preferred format
    +
    To choose the prefered post syntax. Wiki is a simplified syntax + and will be converted to valid xhtml ; Unless you have a perfect + understanding of html, we advise you to choose the wiki syntax.
    + +
    Default entry status
    +
    The default entry status can be set to: +
      +
    • pending: the publication status has not yet been decided.
    • +
    • scheduled: the post will be set online at the time and date + set in the Published on field.
    • +
    • unpublished: the post is offline.
    • +
    • published: the post is online.
    • +
    +
    + +
    Entry edit field height
    +
    The height of the Entry edit field. Defaults to 24.
    + +
    User language
    +
    The language in wich one publishes his posts. If the translation exists, + the interface will also be displayed in that language.
    + +
    User timezone
    +
    That choice will define the time displayed on post publication.
    + +
    Enable WYSIWYG mode
    +
    Allow the use of the WYSIWYG editor for the posts and description fields.
    +
    + +

    Change your password

    +

    To change your password, write down twice your password in the fields +New password and Confirm password. The minimal password +lenght is 6 characters.

    +

    If no new password is provided, the current one is kept.

    + + + diff --git a/locales/en/help/wiki.html b/locales/en/help/wiki.html new file mode 100644 index 0000000..3bf005e --- /dev/null +++ b/locales/en/help/wiki.html @@ -0,0 +1,85 @@ + + + Wiki syntax reference + + + + +

    Wiki syntax reference

    + +

    The wiki syntax is a way to enhance your text with a minimal set +of tags, studied to cover the basic needs (titles, paragraphs, quotes, +lists...)

    + +
    +
    Block elements
    +
    +
      +
    • Leave an empty line between two similar blocks.
    • +
    • Paragraph: free text, ended by an empty line if + another paragraph is to follow.
    • +
    • Title: !!! title, !! title + or ! title, allowing you to use three different levels of + heading.
    • +
    • Horizontal line: ----
    • +
    • Lists: Start each line with + * or # for unnumbered or numbered lists respectively. + List imbrication is done by mixing list markers this way: +
      +* item 1
      +** item 1.1
      +* item 2
      +*# item 2.1
      +...
      +
      +
    • +
    • Preformatted text: each line must start with a space.
    • +
    • Block quote: each line must start with a semicolon (>).
    • +
    +
    + +
    Formatting tags
    +
    +
      +
    • Emphasis: two quotes ''text''
    • +
    • Strong emphasis: two underscore __text__
    • +
    • New line: %%%
    • +
    • Insertion: two plusses ++text++
    • +
    • Deletion: two minuses --text--
    • +
    • Link: [url], [name|url], + [name|url|language] or [name|url|languagee|title]
    • +
    • Image: + ((url|alternative text)), + ((url|alternative text|position)) or + ((url|alternative text|position|long description)). +
      The position can be either L or G (left), R or D (right) or C (centered).
    • +
    • Anchor: ~anchor~
    • +
    • Acronym: ??acronym|title??
    • +
    • Inline HTML: two backquotes ``html code``
    • +
    • Inline quote: {{quote}}, + {{quote|language}} or {{quote|language|url}}
    • +
    • Code: @@code@@
    • +
    • Footnotes: $$footnote$$
    • +
    +
    + +
    Unformatted text
    +
    If you don't want one formatting character to be interpreted as such, add a +\ just before it. This way: +\[text in brackets without being a link\] +
    + +
    HTML Code
    +
    Even if you chose the wiki syntax, you may sometimes need a more +powerful formatting, i.e. HTML syntax. Do it the following way: +
    +///html
    +<p style="color:red">my text in red</p>
    +///
    +
    +
    +
    + + + + diff --git a/locales/en/resources.php b/locales/en/resources.php new file mode 100644 index 0000000..7aa2c62 --- /dev/null +++ b/locales/en/resources.php @@ -0,0 +1,33 @@ + 'http://dotclear.org/documentation/2.0', + 'Dotclear 2 presentation' => 'http://dotclear.org/documentation/2.0/overview/tour', + "User manual" => 'http://dotclear.org/documentation/2.0/usage', + "Installation and administration guides" => 'http://dotclear.org/documentation/2.0/admin' +); + +$__resources['help'] = array( + 'core_blog_pref' => dirname(__FILE__).'/help/blog_pref.html', + 'core_categories' => dirname(__FILE__).'/help/categories.html', + 'core_comments' => dirname(__FILE__).'/help/comments.html', + 'core_media' => dirname(__FILE__).'/help/media.html', + 'core_post' => dirname(__FILE__).'/help/post.html', + 'core_posts' => dirname(__FILE__).'/help/posts.html', + 'core_user_pref' => dirname(__FILE__).'/help/user_pref.html', + 'core_wiki' => dirname(__FILE__).'/help/wiki.html' +); +?> \ No newline at end of file diff --git a/locales/fr/date.lang.php b/locales/fr/date.lang.php new file mode 100644 index 0000000..638a9b2 --- /dev/null +++ b/locales/fr/date.lang.php @@ -0,0 +1,58 @@ + \ No newline at end of file diff --git a/locales/fr/date.po b/locales/fr/date.po new file mode 100644 index 0000000..a5b67dd --- /dev/null +++ b/locales/fr/date.po @@ -0,0 +1,132 @@ +# French translation of DotClear +# Copyright (C) 2006. +# Olivier Meunier , 2006. +msgid "" +msgstr "" +"Project-Id-Version: Dotclear 2\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2008-04-15 16:27+0200\n" +"PO-Revision-Date: 2008-04-15 16:34+0100\n" +"Last-Translator: Olivier Meunier \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: French\n" + +msgid "%Y-%m-%d %H:%M" +msgstr "%d/%m/%Y %H:%M" + +msgid "_Jan" +msgstr "janv." + +msgid "_Feb" +msgstr "fév." + +msgid "_Mar" +msgstr "mar." + +msgid "_Apr" +msgstr "avr." + +msgid "_May" +msgstr "mai" + +msgid "_Jun" +msgstr "juin" + +msgid "_Jul" +msgstr "juil." + +msgid "_Aug" +msgstr "août" + +msgid "_Sep" +msgstr "sept." + +msgid "_Oct" +msgstr "oct." + +msgid "_Nov" +msgstr "nov." + +msgid "_Dec" +msgstr "déc." + +msgid "January" +msgstr "janvier" + +msgid "February" +msgstr "février" + +msgid "March" +msgstr "mars" + +msgid "April" +msgstr "avril" + +msgid "May" +msgstr "mai" + +msgid "June" +msgstr "juin" + +msgid "July" +msgstr "juillet" + +msgid "August" +msgstr "août" + +msgid "September" +msgstr "septembre" + +msgid "October" +msgstr "octobre" + +msgid "November" +msgstr "novembre" + +msgid "December" +msgstr "décembre" + +msgid "_Mon" +msgstr "lun." + +msgid "_Tue" +msgstr "mar." + +msgid "_Wed" +msgstr "mer." + +msgid "_Thu" +msgstr "jeu." + +msgid "_Fri" +msgstr "ven." + +msgid "_Sat" +msgstr "sam." + +msgid "_Sun" +msgstr "dim." + +msgid "Monday" +msgstr "lundi" + +msgid "Tuesday" +msgstr "mardi" + +msgid "Wednesday" +msgstr "mercredi" + +msgid "Thursday" +msgstr "jeudi" + +msgid "Friday" +msgstr "vendredi" + +msgid "Saturday" +msgstr "samedi" + +msgid "Sunday" +msgstr "dimanche" diff --git a/locales/fr/help/blowupConfig.html b/locales/fr/help/blowupConfig.html new file mode 100644 index 0000000..9d41c14 --- /dev/null +++ b/locales/fr/help/blowupConfig.html @@ -0,0 +1,71 @@ + + + + Configuration du thème Blowup + + + +

    En modifiant la configuration du thème Blowup, vous pouvez personnaliser votre +thème très facilement. Pour cela, renseignez simplement les champs de configuration +ou choisissez un style prédéfini.

    + +

    Couleurs

    + +

    Quand vous devez indiquer une valeur de couleur, celle-ci doit être au format +hexadécimal. Par exemple : "#FF0000" donnera du rouge. Vous pouvez vous aider +de la pipette à côté de chaque champs de couleur.

    +

    Si vous manquez d'inspiration vous pouvez consulter :

    + + +

    Unités de mesure

    + +

    Quand vous devez indiquer une taille, celle-ci doit être suivie d'une unité +de mesure. Par exemple : "1em". Si vous n'indiquez aucune unité, la valeur +donnée prendra des pixels comme unité par défaut.

    +

    Les unités possibles sont :

    +
      +
    • px
    • +
    • em
    • +
    • ex
    • +
    • pt
    • +
    • %
    • +
    + +

    Images d'en-tête

    + +

    Vous pouvez choisir une image d'en-tête parmi une liste de nombreuses images +afin de remplacer celle utilisée par défaut.

    + +

    En choisissant "Personnalisé..." parmi la liste d'images, vous pourrez +déposer votre propre image. Celle-ci doit être au format JPG ou PNG et +avoir une largeur exacte de 800 pixels. + +

    Si vous déposez une image au format JPG, un cadre sera ajouté autours de +l'image, ce qui n'est pas le cas avec une image au format PNG (dont la +transparence sera également préservée).

    + +

    Styles prédéfinis

    + +

    Vous pouvez choisir un style prédéfini dans la liste d'option "Styles prédéfinis". +Une fois le style choisi, vous devez valider le formulaire pour appliquer les +changements.

    + +

    Vous pouvez ensuite modifier le style prédéfini comme bon vous semble.

    + +

    Import / export de configuration

    + +

    À la fin des options de Blowup, vous pouvez afficher une zone appelée "Import +/ export de configuration". Dans cette zone de texte se trouve la configuration +en cours d'utilisation. Vous pouvez la copier pour la partager avec d'autres.

    + +

    Pour appliquer (importer) une configuration, il suffit simplement de remplacer +le contenu de la zone de texte par celui que vous voulez utiliser. N'oubliez pas +de cliquer sur "appliquer le code".

    + + + \ No newline at end of file diff --git a/locales/fr/help/core_blog_pref.html b/locales/fr/help/core_blog_pref.html new file mode 100644 index 0000000..97a8aec --- /dev/null +++ b/locales/fr/help/core_blog_pref.html @@ -0,0 +1,190 @@ + + + Préférences du blog + + + + +

    Informations du blog

    +
    +
    Identifiant du blog
    +
    Identifiant unique du blog. Obligatoire, ne peut être modifié que par un + super administrateur.
    + +
    Nom du blog
    +
    Nom du blog, obligatoire.
    + +
    URL du blog
    +
    URL complète du blog. Obligatoire, ne peut être modifiée que par un super + administrateur.
    + +
    Méthode de lecture de l'URL
    +
    Définit le mode de lecture de l'URL. PATH_INFO est conseillé, QUERY_STRING + doit être utilisé si le premier ne fonctionne pas. En mode PATH_INFO, l'URL du + blog doit se terminer par un "/" et en mode QUERY_STRING, par un "?".
    + +
    État du blog
    +
    +
      +
    • en ligne : blog accessible aux visiteurs
    • +
    • hors ligne : blog inaccessible aux visiteurs + mais les rédacteurs peuvent se connecter
    • +
    • supprimé : blog inaccessible aux visiteurs + comme aux rédacteurs
    • +
    +
    + +
    Description du blog
    +
    Texte libre de description du blog. Il s'agit d'un texte simple, sans + formatage quelconque.
    +
    + +

    Configuration du blog

    +
    +
    Nom de l'éditeur du blog
    +
    Nom de la personne en charge du blog. Peut être le propriétaire ou le + directeur de publication s'il existe.
    + +
    Note de copyright
    +
    Note indiquant les droits de reproduction autorisés pour le blog.
    + +
    Langue par défaut
    +
    Langue de l'interface du blog. Si cette langue existe parmis les + traductions, l'interface sera traduite dans celle-ci, sinon elle apparaîtra + en Anglais.
    + +
    Fuseau horaire du blog
    +
    Définit le fuseau horaire qui sera utilisé pour dater les commentaires et + trackbacks entrant sur le blog.
    + +
    Format des dates
    +
    Indique le format de la date d'un billet sur le blog. Voir la section + "formatage des dates" pour plus détails.
    + +
    Format des heures
    +
    Indique le format de l'heure d'un billet sur le blog. Voir la section + "formatage des dates" pour plus détails.
    + +
    Laisser les commentaires ouvert durant .. jours
    +
    Permet d'indiquer le nombre de jours durant lesquels les commentaires + sont possibles sur un billet après sa publication. Aucune valeur laissera + les commentaires toujours ouverts.
    + +
    Laisser les rétroliens ouvert durant .. jours
    +
    Permet d'indiquer le nombre de jours durant lesquels les rétroliens + sont possibles sur un billet après sa publication. Aucune valeur laissera + les rétroliens toujours ouverts.
    + +
    Accepter les commentaires
    +
    Accepter globalement les commentaires sur le blog. Ce paramètre est + supérieur à celui autorisant ou non les commentaires sur un billet.
    + +
    Accepter les rétroliens
    +
    Accepter globalement les rétroliens sur le blog. Ce paramètre est + supérieur à celui autorisant ou non les rétroliens sur un billet.
    + +
    Modérer les commentaires
    +
    Si cette option est activée, les commentaires ne seront publiés qu'après + l'approbation d'un rédacteur.
    + +
    Modérer les rétroliens
    +
    Si cette option est activée, les rétroliens ne seront publiés qu'après + l'approbation d'un rédacteur.
    + +
    Ajouter la relation "nofollow" aux liens des commentaires et rétroliens
    +
    Ajoute un attribut sur les liens des commentaires et rétroliens indiquant + aux robots des moteurs de recherche de ne pas aller sur ce liens. Cette mesure + est censée permettre de lutter contre le spam mais n'a pas encore vraiment + prouvé son efficacité.
    + +
    Syntaxe wiki pour les commentaires
    +
    Autoriser quelques éléments de la syntaxe wiki dans les commentaires.
    + +
    Afficher .. billets par page
    +
    Le nombre donné sera utilisé comme limite d'affichage des billets sur la + page d'accueil et la première page de chaque catégorie.
    + +
    Afficher des émoticones dans les billets et commentaires
    +
    Remplacer certains symboles comme :-) ou ;-) en image.
    + +
    Afficher .. billets par flux de syndication
    +
    Le nombre donné sera utilisé comme limite d'affichage des billets dans + les flux de syndication.
    + +
    Afficher .. commentaires par flux de syndication
    +
    Le nombre donné sera utilisé comme limite d'affichage des commentaires dans + les flux de syndication.
    + +
    Tronquer le flux de syndication
    +
    Cette option permet de ne fournir qu'un extrait des billets dans les flux + de syndication.
    +
    + +

    Formatage des dates

    +

    Certains champs permettent de formater les dates avec des caractères +particuliers dont voici la définition :

    + +
      +
    • %a : nom abrégé du jour de la semaine (local).
    • +
    • %A : nom complet du jour de la semaine (local).
    • +
    • %b : nom abrégé du mois (local).
    • +
    • %B : nom complet du mois (local).
    • +
    • %c : représentation préférée pour les dates et + heures, en local.
    • +
    • %C : numéro de siècle (l'année, divisée par 100 et + arrondie entre 00 et 99)
    • +
    • %d : jour du mois en numérique (intervalle 01 à + 31)
    • +
    • %D : identique à %m/%d/%y
    • +
    • %e : numéro du jour du mois. Les chiffres sont + précédés d'un espace (de ' 1' à '31')
    • +
    • %g : identique à %G, sur 2 chiffres.
    • +
    • %G : L'année sur 4 chiffres correspondant au numéro + de semaine (voir %V). Même format et valeur que %Y, excepté que si le numéro + de la semaine appartient à l'année précédente ou suivante, l'année courante + sera utilisé à la place.
    • +
    • %h : identique à %b
    • +
    • %H : heure de la journée en numérique, et sur + 24-heures (intervalle de 00 à 23)
    • +
    • %I : heure de la journée en numérique, et sur 12- + heures (intervalle 01 à 12)
    • +
    • %j : jour de l'année, en numérique (intervalle 001 à + 366)
    • +
    • %m : mois en numérique (intervalle 1 à 12)
    • +
    • %M : minute en numérique
    • +
    • %n : newline character
    • +
    • %p : soit `am' ou `pm' en fonction de l'heure + absolue, ou en fonction des valeurs enregistrées en local.
    • +
    • %r : l'heure au format a.m. et p.m.
    • +
    • %R : l'heure au format 24h
    • +
    • %S : secondes en numérique
    • +
    • %t : tabulation
    • +
    • %T : l'heure actuelle (égal à %H:%M:%S)
    • +
    • %u : le numéro de jour dans la semaine, de 1 à 7. (1 + représente Lundi)
    • +
    • %U : numéro de semaine dans l'année, en considérant + le premier dimanche de l'année comme le premier jour de la première + semaine.
    • +
    • %V : le numéro de semaine comme défini dans l'ISO + 8601:1988, sous forme décimale, de 01 à 53. La semaine 1 est la première + semaine qui a plus de 4 jours dans l'année courante, et dont Lundi est le + premier jour. (Utilisez %G ou %g pour les éléments de l'année qui + correspondent au numéro de la semaine pour le timestamp donné.)
    • +
    • %W : numéro de semaine dans l'année, en considérant + le premier lundi de l'année comme le premier jour de la première semaine
    • +
    • %w : jour de la semaine, numérique, avec Dimanche = + 0
    • +
    • %x : format préféré de représentation de la date + sans l'heure
    • +
    • %X : format préféré de représentation de l'heure + sans la date
    • +
    • %y : l'année, numérique, sur deux chiffres (de 00 à + 99)
    • +
    • %Y : l'année, numérique, sur quatre chiffres
    • +
    • %Z ou %z : fuseau horaire, ou nom ou + abréviation
    • +
    • %% : un caractère `%' littéral
    • +
    + + + \ No newline at end of file diff --git a/locales/fr/help/core_categories.html b/locales/fr/help/core_categories.html new file mode 100644 index 0000000..22069a4 --- /dev/null +++ b/locales/fr/help/core_categories.html @@ -0,0 +1,43 @@ + + + Catégories + + + +

    Liste des categories

    +
    +
    Créer une nouvelle catégorie
    +
    Choisissez le nom que vous souhaitez donner à votre nouvelle catégorie + puis cliquer sur Enregistrer pour valider sa création. Pour la modifier, + cliquez sur son nom dans la liste.
    + +
    Changer l'ordre des catégories
    +
    Pour changer l'ordre des catégories, faites glisser les catégories en + utilisant les images en forme de flèche puis cliquez sur enregistrer + l'ordre. Si vous ne voyez pas les flèches, utilisez les champs + numérotés à côté de chaque catégorie.
    +
    + +

    Modifier une catégorie

    +
    +
    Titre
    +
    Choisissez le nom que vous souhaitez donner à votre nouvelle catégorie + puis cliquer sur Enregistrer pour valider sa création.
    + +
    URL
    +
    DotClear crée une url par défaut de la catégorie, qui sera ainsi + accessible avec un chemin de la forme + http://monblog.tld/category/Ma-categorie. En cliquant sur le + petit verrou situé à la droite, vous pouvez la modifier comme il vous + plaira.
    + +
    Description
    +
    Le contenu de ce champ de description sera affiché lors de la sélection + d'une catégorie dans le blog. Vous pouvez le remplir avec toute forme de + contenu (paragraphes, listes, etc.) Le format du texte de la description est + HTML.
    + +
    + + + \ No newline at end of file diff --git a/locales/fr/help/core_comments.html b/locales/fr/help/core_comments.html new file mode 100644 index 0000000..1fe0676 --- /dev/null +++ b/locales/fr/help/core_comments.html @@ -0,0 +1,59 @@ + + + Commentaires + + + +

    Filtres de la liste des commentaires

    +
    +
    Type :
    +
    Aucun ou commentaires ou rétroliens.
    + +
    État :
    +
      +
    • indésirable : reconnu comme spam ;
    • +
    • en attente : en attente de modération ;
    • +
    • non publié : hors ligne ;
    • +
    • publié : en ligne.
    • +
    + +
    Trier par :
    +
    Choisir : date, ou titre du billet, ou auteur ou état, puis indiquez si vous + souhaitez que les résultats s'affichent par ordre croissant ou décroissant.
    + +
    Trier
    +
    Indique l'ordre dans lequel on souhaite effectuer le tri.
    + +
    Auteur du commentaire.
    +
    Recherche indifféremment avec des minuscules ou majuscules. On peut chercher + sur une partie du nom en utilisant le caractère joker + *.
    + +
    Commentaires par page :
    +
    Détermine le nombre de commentaires affichés par page de cette liste.
    +
    + +

    Modifier ou ajouter un commentaire

    +
    +
    Auteur :
    +
    Nom de l'auteur. Ce champ est obligatoire.
    + +
    Email :
    +
    Adresse mail de l'auteur du commmentaire.
    + +
    Site web :
    +
    URL du site ou du blog de l'auteur du commentaire.
    + +
    État :
    +
      +
    • indésirable : reconnu comme spam ;
    • +
    • en attente : en attente de modération ;
    • +
    • non publié : hors ligne
    • +
    • publié : en ligne
    • +
    + +
    Commentaire :
    +
    Contenu du commentaire. Ce champ utilise la syntaxe HTML.
    +
    + + \ No newline at end of file diff --git a/locales/fr/help/core_media.html b/locales/fr/help/core_media.html new file mode 100644 index 0000000..6191dc0 --- /dev/null +++ b/locales/fr/help/core_media.html @@ -0,0 +1,96 @@ + + + Gestionnaire de media + + + + +

    Liste des media

    +

    La page principale du gestionnaire de media présente la liste des fichiers +(media) disponibles pour le blog en cours d'utilisation.

    + +

    Il est possible d'afficher les media dans dans des répertoires ou sous +répertoires en cliquant sur leurs icônes ou leurs noms.

    + +

    Les fichiers son au format MP3 sont présentés avec un lecteur permettant +d'en prendre immédiatement connaissance. Ce lecteur nécessite un lecteur (ou +plugin) Flash sur votre navigateur.

    + +

    Les images sont affichées avec une miniature quand cela est possible.

    + +

    Ajouter des fichiers

    +
    +
    Choisissez un fichier
    +
    Permet de choisir un fichier sur son disque dur pour l'envoyer sur le + blog. Si le fichier dépasse la taille maximale, il ne pourra être envoyé.
    + +
    Titre
    +
    Titre optionnel du fichier à envoyer.
    + +
    Privé
    +
    Indique que le fichier envoyé n'est visible que par son propriétaire tant + qu'il n'est pas publié sur le blog.
    +
    + +

    Nouveau répertoire

    +

    Ce formulaire permet de créer un nouveau répertoire dans le répertoire en +cours d'utilisation. Indiquez simplement un nom comme vous le feriez sur votre +ordinateur.

    + +

    Détail du media

    +

    La page individuelle d'un media présente un ensemble d'informations sur +celui-ci et permet d'effectuer quelques opérations.

    + +
    +
    Nom du fichier
    +
    Changer le nom du fichier en cours.
    + +
    Titre du fichier
    +
    Changer ou donner un titre au fichier en cours.
    + +
    Date du fichier
    +
    Changer la date du fichier.
    + +
    Privé
    +
    Changer le caractère privé ou nom du média.
    + +
    Nouveau répertoire
    +
    Permet de changer l'emplacement du fichier.
    + +
    Changer le fichier
    +
    Ce formulaire permet de changer le fichier tout en en conservant les + attributs (nom, titre...). Comme toujours, il ne peut dépasser la taille + maximalle indiquée.
    +
    + +

    Cas particulier des images

    +

    Lors de l'ajout d'une image, jusqu'à quatre versions de celle-ci peuvent +être disponibles (selon la taille de l'image d'origine) :

    +
      +
    • square : carré de 48 pixels de côté,
    • +
    • thumbnail : image réduite à 100 pixels sur son plus grand côté,
    • +
    • small : image réduite à 240 pixels sur son plus grand côté,
    • +
    • medium : image réduite à 500 pixes sur son plus grand côté,
    • +
    • originale : image originale non transformée.
    • +
    + +

    Attacher un fichier à un billet

    +

    Vous pouvez attacher un fichier à un billet très facilement. Commencez par +créer un nouveau billet et enregistrez-le. Cliquez alors sur "ajouter un fichier +au billet" pour ouvrir le gestionnaire de media.

    + +

    En cliquant sur l'icône [+] (Attacher un fichier au billet) vous pourrez +joindre le fichier à votre billet.

    + +

    Les fichiers attachés à un billet seront visibles sur la page individuelle +du billet, sous la forme d'une liste après le contenu du billet. Les fichiers +MP3 seront automatiquement accompagnés d'un lecteur en Flash permettant la +lecture directe du fichier.

    + +

    Podcast et diffusion de fichiers musicaux

    +

    Tous les fichiers attachés à un billet seront présents dans les fils RSS de +vos billets, vous permettant ainsi de réaliser des podcast de n'importe quel +type de fichier.

    + + + \ No newline at end of file diff --git a/locales/fr/help/core_post.html b/locales/fr/help/core_post.html new file mode 100644 index 0000000..54281a1 --- /dev/null +++ b/locales/fr/help/core_post.html @@ -0,0 +1,137 @@ + + + Rédaction d'un billet + + + + +

    Rédaction du billet

    + +
    +
    Titre du billet
    +
    Inscrivez le titre du billet. Ce champ est obligatoire.
    + +
    Extrait
    +
    Le contenu de ce champ s'affichera dans les pages présentant les listes de + billets telles que la page d'accueil ou le tri sur une catégorie, suivi d'un + lien « Lire la suite ». Il figurera également au début du billet dans le + contexte de l'affichage du billet seul. Si vous ne remplissez pas ce champ, le + champ Contenu sera intégralement affiché dès la page d'accueil.
    + +
    Contenu
    +
    Le contenu du billet. Ce champ est obligatoire.
    + +
    Notes
    +
    Cette zone de texte sert à la prise de notes ou pense-bête divers. Elle ne + sera jamais affichée sur le blog.
    + +
    Catégorie
    +
    La catégorie de votre billet. Pour créer une nouvelle catégorie, rendez vous + dans la section "catégories". Vous pouvez n'affecter + votre billet à aucune catégorie en choisissant la ligne vide.
    + +
    État du billet
    +
    Permet de choisir l'état du billet après enregistrement : +
      +
    • en attente : en attente de publication.
    • +
    • programmé : le billet sera mis en ligne aux date et heure + indiquées dans le champ Publié le.
    • +
    • non publié : billet hors ligne.
    • +
    • publié : billet en ligne.
    • +
    +
    + +
    Publié le
    +
    Permet de modifier la date et l'heure de publication du billet. Si vous avez + choisi le statut programmé il sera mis en ligne aux date et heure + définis dans ce champ.
    + +
    Format du texte
    +
    Permet de choisir la syntaxe de saisie du billet. Le wiki est une syntaxe + simplifiée et sera converti en xhtml valide ; à moins que vous maîtrisiez + parfaitement le HTML nous vous conseillons de la choisir de préférence. + Consultez la référence de la syntaxe Wiki pour plus + d'informations.
    + +
    Accepter les commentaires
    +
    Cochez ou décochez la case selon que vous souhaitez permettre ou interdire + les commentaires sur le billet en particulier. L'option pour permettre ou + autoriser de façon générale les commentaires se situe dans le menu Préférences + du blog.
    + +
    Accepter les rétroliens
    +
    Un rétrolien permet de signaler un billet dans les commentaires d'un autre + blog. Cochez ou décochez la case selon que vous souhaitez permettre ou interdire + les rétroliens sur le billet. L'option pour permettre ou autoriser de façon + générale les rétroliens se situe dans le menu Préférences du blog.
    + +
    Billet sélectionné
    +
    Les billets marqués comme sélectionnés apparaîtront dans le menu de votre + blog, sous l'intitulé « A retenir ».
    + +
    Mot de passe du billet
    +
    Permet de déterminer un mot de passe d'accès à un billet dans le blog. Un + billet protégé par mot de passe ne sera visible nulle part sur votre blog, vous + pourrez en donner l'adresse à vos lecteurs en vous rendant sur le lien + voir le billet.
    + +
    Basename
    +
    Ce champ permet de choisir une URL pour un billet autre que celle par défaut + après avoir cliqué sur le petit verrou placé à sa droite. Si vous essayez + d'utiliser une URL déjà existante, celle-ci se verra incrémentée d'un chiffre.
    + +
    Langue du billet
    +
    Code langue de votre billet. Par défaut, il s'agit du code de votre + langue. Vous pouvez le changer, par le code d'une autre langue, par + exemple "en", "fr-qc". Ce code est libre, il sera utilisé lors de l'affichage + des billets.
    + +
    Pièces jointes
    +
    Les pièces jointes sont tous les media attachés au billet. Le lien + d'ajout d'une pièce jointe permet de choisir un fichier à ajouter au billet. + Pensez à sauvegarder votre billet avant de choisir une pièce jointe. Consultez + l'aide du gestionnaire de media pour plus de détails.
    +
    + +

    Commentaires

    +
    +
    Liste les commentaires
    +
    Depuis l'onglets Commentaires vous pouvez lire et changer l'état + des commentaires de votre billet. Suivant vos permissions, vous pouvez modifier, + mettre en ligne ou hors ligne, supprimer ou classer comme commentaire + indésirable.
    + +
    Ajouter un commentaire
    +
    Depuis l'onglet Ajouter un commentaire vous pouvez répondre + directement à un commentaire sans passer par votre blog. Cette interface vous + permet également de saisir votre commentaire en HTML, sans limitation. Vous + devrez remplir les champs de la même manière qu'en modifiant un commentaire
    +
    + +

    Rétroliens

    +

    Pour faire un rétrolien cliquez sur le lien Faire des rétroliens. +Si vous ne voyez pas ce lien, vérifiez que votre billet est bien dans l'état +publié.

    + +
    +
    URLs à rétrolier
    +
    Indiquez ici la ou les URL que vous aurez relevé dans le billet vers lequel + vous souhaitez envoyer un rétrolien.
    + + +
    Envoyer l'extrait
    +
    Par défaut, ce champ comporte le début de votre billet. C'est ce qui sera + envoyé vers le blog que vous rétroliez avec un lien vers votre billet complet. + Vous pouvez modifier le contenu de cette "accroche" en saisissant directement le + texte de votre choix dans ce champ.
    + + +
    Découverte automatique des URLs à rétrolier
    +
    Si votre billet comporte des liens vers des billets précis et si la + plate-forme du blog destinataire est configurée pour le permettre, cette + fonction découvrira automatiquement les URLs spécifiques d'envoi de + rétrolien.
    +
    + + + diff --git a/locales/fr/help/core_posts.html b/locales/fr/help/core_posts.html new file mode 100644 index 0000000..69b8cf1 --- /dev/null +++ b/locales/fr/help/core_posts.html @@ -0,0 +1,65 @@ + + + Gestion des billets + + + + +

    Filtres de la liste des billets

    + +
    +
    Auteur
    +
    Permet de filtrer les billets par auteur.
    + +
    Catégorie
    +
    Filtrer les billets par catégorie.
    + +
    État
    +
      +
    • en attente : en attente de publication.
    • +
    • programmé : le billet sera mis en ligne aux date et heure + indiquées dans le champ Publié le.
    • +
    • non publié : billet hors ligne.
    • +
    • publié : billet en ligne.
    • +
    + +
    Sélectionné
    +
    Aucun, billet marqué comme sélectionné ou non sélectionné.
    + +
    Mois
    +
    Filtre les billets d'un mois d'une année donné.
    + +
    Langue
    +
    Filtre les billets selon la langue indiquée dans le champ langue du + billet.
    + +
    Trier par
    +
    Permet de trier les résultats de filtrage selon la date, le titre, + la catégorie, l'auteur, l'état de publication ou l'état de sélection.
    + +
    Trier
    +
    Indique l'ordre dans lequel on souhaite effectuer le tri.
    + +
    Billets par page
    +
    Nombre de billets à afficher par page de résultat.
    +
    + +

    Actions par lot sur les billets

    +

    Il est possible d'effectuer un ensemble d'actions sur plusieurs billets, d'un +seul coup. Les actions possibles dépendent des permissions de l'utilisateur.

    + +
      +
    • Publier : mettre le billet en ligne,
    • +
    • Hors ligne : mettre le billet hors ligne,
    • +
    • Programmer : programmer le billet pour mise en ligne à la date de + publication,
    • +
    • En attente : en attente de publication,
    • +
    • Changer de catégorie : envoie sur la liste des catégories pour + changer celle des billets sélectionnés,
    • +
    • Changer l'auteur : permet de changer l'auteur du billet en indiquant + l'identifiant de l'utilisateur qui deviendra le nouvel auteur,
    • +
    • Supprimer : supprime le billet (cette opération est irréversible).
    • +
    + + + \ No newline at end of file diff --git a/locales/fr/help/core_user_pref.html b/locales/fr/help/core_user_pref.html new file mode 100644 index 0000000..d3d935a --- /dev/null +++ b/locales/fr/help/core_user_pref.html @@ -0,0 +1,64 @@ + + + Préférences utilisateur + + + + +

    Informations utilisateurs

    +
    +
    Nom, Prénom
    +
    Si le pseudonyme n'est pas renseigné, le nom de l'auteur qui sera affiché + sera composé des noms et prénoms renseignés dans ces champs.
    + +
    Pseudonyme
    +
    Vous pouvez choisir ici le nom sous lequel vos billets seront signés.
    + +
    Email
    +
    Adresse à laquelle devront être envoyées les notifications de nouveaux + commentaires par email.
    + +
    URL
    +
    Indique le site web de l'utilisateur. S'il est indiqué, le nom du rédacteur + d'un billet sera présenté comme un lien vers le site donné.
    + +
    Format d'édition préféré
    +
    Choix de la syntaxe par défaut pour la saisie des billets. Le wiki est une + syntaxe simplifiée et sera converti en xhtml valide ; à moins que vous ne + maîtrisiez parfaitement le HTML nous vous conseillons le choix du wiki.
    + +
    État des billets par défaut
    +
    Le statut par défaut des billets peut être déterminé à : +
      +
    • en attente : le statut de publication n'a pas encore + été décidé.
    • +
    • programmé : le billet sera mis en ligne aux date et + heure indiquées dans le champ Publié le.
    • +
    • non publié : billet hors ligne.
    • +
    • publié : billet en ligne.
    • +
    +
    + +
    Taille de la zone d'édition
    +
    Fixe la hauteur de la zone d'édtion du billet. Par défaut ce paramètre est + réglé à la valeur 24.
    + +
    Langue de l'utilisateur
    +
    Indique la langue dans laquelle on souhaite publier ses billets. Si la + traduction existe, l'interface sera également traduite dans cette langue.
    + +
    Fuseau horaire de l'utilisateur
    +
    Ce choix déterminera l'affichage de l'heure de publication des billets.
    + +
    Activer l'éditeur visuel
    +
    Permet d'activer ou non l'éditeur visuel des billets et des catégories.
    +
    + +

    Changer le mot de passe

    +

    Pour changer votre mot de passe, indiquez deux fois le nouveau mot de passe +dans les champs Nouveau mot de passe et Confirmer le mot de +passe. Le mot de passe doit être long d'au moins 6 caractères.

    +

    Si aucun mot de passe n'est donné, celui-ci ne sera pas changé.

    + + + \ No newline at end of file diff --git a/locales/fr/help/core_wiki.html b/locales/fr/help/core_wiki.html new file mode 100644 index 0000000..1fb3b90 --- /dev/null +++ b/locales/fr/help/core_wiki.html @@ -0,0 +1,85 @@ + + + Référence de la syntaxe Wiki + + + + +

    Référence de la syntaxe Wiki

    + +

    La syntaxe Wiki est une manière d'écrire du texte avec un jeu de balises +réduit au minimum, permettant de couvrir les besoins les plus courants +(titres, paragraphes, citations, listes...).

    + +
    +
    Éléments de bloc
    +
    +
      +
    • Laissez une ligne vide entre chaque bloc de même nature.
    • +
    • Paragraphe : texte libre, terminé par une ligne + vide si suivi d'un second paragraphe.
    • +
    • Titre : !!! titre, !! titre + ou ! titre pour des titres plus ou moins importants.
    • +
    • Trait horizontal : ----
    • +
    • Listes : lignes débutant par * pour des + listes à puce ou # pour des listes numérotées. Vous pouvez faire + des listes imbriquées en mélangeant les codes de liste. Par exemple : +
      +* item 1
      +** item 1.1
      +* item 2
      +*# item 2.1
      +...
      +
      +
    • +
    • Texte préformaté : espace avant chaque ligne de texte.
    • +
    • Bloc de citation : > devant chaque + ligne de texte.
    • +
    +
    + +
    Éléments de formatage
    +
    +
      +
    • Emphase : deux apostrophes ''texte''
    • +
    • Forte emphase : deux soulignés __texte__
    • +
    • Retour forcé à la ligne : %%%
    • +
    • Insertion : deux plus ++texte++
    • +
    • Suppression : deux moins --texte--
    • +
    • Lien : [url], [nom|url], + [nom|url|langue] ou [nom|url|langue|titre]
    • +
    • Image : + ((url|texte alternatif)), + ((url|texte alternatif|position)) ou + ((url|texte alternatif|position|description longue)). +
      La position peut prendre les valeurs L ou G (gauche), R ou D (droite) ou C (centré).
    • +
    • Ancre : ~ancre~
    • +
    • Acronyme : ??acronyme|titre??
    • +
    • Code HTML en ligne: deux apostrophes inversées ``code html``
    • +
    • Citation en ligne : {{citation}}, + {{citation|langue}} ou {{citation|langue|url}}
    • +
    • Code : @@code ici@@
    • +
    • Note de bas de page : $$Corps de la note$$
    • +
    +
    + +
    Empêcher le formatage du texte
    +
    Pour insérer un caractère sans que celui-ci soit reconnu comme un caractère +de formatage, ajoutez le caractère \ avant celui-ci. Par exemple : +\[texte entre crochet qui n'est pas un lien\] +
    + +
    Insérer du code HTML
    +
    Vous pouvez ponctuellement avoir besoin d'insérer du code HTML dans votre +texte au format Wiki. Pour cela, utilisez le code suivant : +
    +///html
    +<p style="color:red">mon texte en rouge</p>
    +///
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/locales/fr/help/themeEditor.html b/locales/fr/help/themeEditor.html new file mode 100644 index 0000000..b79802b --- /dev/null +++ b/locales/fr/help/themeEditor.html @@ -0,0 +1,37 @@ + + + + Éditeur de thème + + + +

    L'éditeur de thème vous permet de modifier les fichiers template, les feuilles +de style et les fichiers JavaScript de votre thème en cours d'utilisation.

    + +

    La liste des fichiers est divisée en trois parties :

    +
      +
    • Fichiers template : les templates
    • +
    • Fichiers CSS : les feuilles de style
    • +
    • Fichiers JavaScript
    • +
    + +

    Une puce jaune contre le nom de chaque fichier indique que celui-ci fait partie +du thème. Une puce rouge indique qu'il se trouve dans le thème parent. +Une puce noire indique qu'il se trouve dans le thème "default".

    + +

    Si vous modifiez un fichier se trouvant dans le thème "default", celui-ci +sera copié dans votre thème en cours d'utilisation.

    + +

    Pour modifier un fichier, cliquez sur son nom, le contenu s'affichera alors +dans une zone d'édition. Si le fichier peut-être écrit vous pourrez sauvegarder +celui-ci en cliquant sur "enregistrer".

    + +

    Les modifications sont immédiatement appliquées lors de la sauvegarde, soyez +vigilants.

    + +

    Pour éditer vos templates, n'hésitez pas à consultez la +liste des marqueurs +de template.

    + + + \ No newline at end of file diff --git a/locales/fr/main.lang.php b/locales/fr/main.lang.php new file mode 100644 index 0000000..bee1ae2 --- /dev/null +++ b/locales/fr/main.lang.php @@ -0,0 +1,816 @@ +This is a comment.

    +

    To delete it, log in and view your blog\'s comments. Then you might remove or edit it.

    '] = '

    Ceci est un commentaire

    Pour le supprimer, connectez-vous et affichez les commentaires de votre blog. Vous pourrez alors le supprimer ou le modifier.

    '; +$GLOBALS['__l10n']['Dotclear installation'] = 'Installation de Dotclear'; +$GLOBALS['__l10n']['Cache directory %s is not writable.'] = 'Le répertoire de cache %s n\'est pas accessible en écriture.'; +$GLOBALS['__l10n']['Errors:'] = 'Erreurs :'; +$GLOBALS['__l10n']['Configuration file has been successfully created.'] = 'Le fichier de configuration a été créé avec succès.'; +$GLOBALS['__l10n']['User information'] = 'Informations utilisateur'; +$GLOBALS['__l10n']['Please provide the following information needed to create the first user.'] = 'Merci de fournir les informations suivantes pour créer le premier utilisateur.'; +$GLOBALS['__l10n']['First Name:'] = 'Prénom :'; +$GLOBALS['__l10n']['Last Name:'] = 'Nom'; +$GLOBALS['__l10n']['Username and password'] = 'Identifiant ou mot de passe incorrect'; +$GLOBALS['__l10n']['Confirm password:'] = 'Confirmez le mot de passe :'; +$GLOBALS['__l10n']['All done!'] = 'Terminé !'; +$GLOBALS['__l10n']['Dotclear has been successfully installed. Here is some useful information you should keep.'] = 'Dotclear a été installé avec succès. Conservez les informations suivantes précieusement.'; +$GLOBALS['__l10n']['Your account'] = 'Votre compte'; +$GLOBALS['__l10n']['Your blog'] = 'Votre blog'; +$GLOBALS['__l10n']['Blog address:'] = 'Adresse du blog :'; +$GLOBALS['__l10n']['Administration interface:'] = 'Interface d\'administration :'; +$GLOBALS['__l10n']['Manage your blog now'] = 'Gérez votre blog'; +$GLOBALS['__l10n']['The file %s already exists. If you need to reset any of the configuration items in this file, please delete it first or you may continue to install.'] = 'Le fichier %s existe déjà. Pour réinitialiser votre configuration, supprimez d\'abord ce fichier ou bien continuez l\'installation.'; +$GLOBALS['__l10n']['File %s does not exist.'] = 'Le fichier %s n\'existe pas.'; +$GLOBALS['__l10n']['Cannot write %s file.'] = 'Impossible d\'écrire le fichier %s.'; +$GLOBALS['__l10n']['Dotclear installation wizard'] = 'Assistant d\'installation de Dotclear'; +$GLOBALS['__l10n']['System information'] = 'Informations système'; +$GLOBALS['__l10n']['Please provide the following information needed to create your configuration file.'] = 'Merci de fournir les informations suivantes pour créer votre fichier de configuration.'; +$GLOBALS['__l10n']['Database type:'] = 'Type de base de données :'; +$GLOBALS['__l10n']['Database Host Name:'] = 'Nom d\'hôte de la base de données :'; +$GLOBALS['__l10n']['Database Name:'] = 'Nom de la base de données :'; +$GLOBALS['__l10n']['Database User Name:'] = 'Nom d\'utilisateur de la base de données :'; +$GLOBALS['__l10n']['Database Password:'] = 'Mot de passe de la base de données :'; +$GLOBALS['__l10n']['Database Tables Prefix:'] = 'Préfixe des tables de la base de données :'; +$GLOBALS['__l10n']['No such installed language'] = 'Cette langue n\'est pas installée'; +$GLOBALS['__l10n']['You can\'t remove English language.'] = 'Vous ne pouvez pas supprimer la langue anglaise.'; +$GLOBALS['__l10n']['Permissions to delete language denied.'] = 'Permission de supprimer la langue refusée.'; +$GLOBALS['__l10n']['Invalid language file URL.'] = 'URL de fichier de langue invalide.'; +$GLOBALS['__l10n']['Languages management'] = 'Gestion des langues'; +$GLOBALS['__l10n']['Language has been successfully deleted.'] = 'La langue a été supprimée avec succès.'; +$GLOBALS['__l10n']['Language has been successfully installed.'] = 'La langue a été installée avec succès.'; +$GLOBALS['__l10n']['Language has been successfully upgraded'] = 'La langue a été mise à jour avec succès.'; +$GLOBALS['__l10n']['Here you can install, upgrade or remove languages for your Dotclear installation.'] = 'Sur cette page, vous pouvez installer, mettre à jour ou supprimer des langues de votre installation de Dotclear.'; +$GLOBALS['__l10n']['You can change your user language in your preferences or change your blog\'s main language in your blog settings.'] = 'Vous pouvez changer votre langue d\'utilisateur dans vos préférences ou changer la langue principale de votre blog dans vos paramètres de blog.'; +$GLOBALS['__l10n']['Installed languages'] = 'Langues installées'; +$GLOBALS['__l10n']['No additional language is installed.'] = 'Aucune langue supplémentaire n\'est installée.'; +$GLOBALS['__l10n']['Language'] = 'Langue'; +$GLOBALS['__l10n']['Action'] = 'Action'; +$GLOBALS['__l10n']['Delete'] = 'Supprimer'; +$GLOBALS['__l10n']['Install or upgrade languages'] = 'Installer ou mettre à jour une langue'; +$GLOBALS['__l10n']['You can install or remove a language by adding or removing the relevant directory in your %s folder.'] = 'Vous pouvez installer ou supprimer une langue en ajoutant ou supprimant le répertoire correspondant dans votre répertoire %s.'; +$GLOBALS['__l10n']['Available languages'] = 'Langues disponibles'; +$GLOBALS['__l10n']['You can download and install a additional language directly from Dotclear.net. Proposed languages are based on your version: %s.'] = 'Vous pouvez télécharger et installer une langue supplémentaire directement depuis Dotclear.net. Les langues proposées sont basées sur votre version : %s.'; +$GLOBALS['__l10n']['Language:'] = 'Langue :'; +$GLOBALS['__l10n']['Install language'] = 'Installer la langue'; +$GLOBALS['__l10n']['You can install languages by uploading zip files.'] = 'Vous pouvez installer des langues en déposant des fichiers zip.'; +$GLOBALS['__l10n']['Language zip file:'] = 'Fichier zip de la langue :'; +$GLOBALS['__l10n']['Upload language'] = 'Déposer la langue'; +$GLOBALS['__l10n']['Invalid language zip file.'] = 'Fichier zip de langue invalide.'; +$GLOBALS['__l10n']['The zip file does not appear to be a valid Dotclear language pack.'] = 'Le fichier zip ne semble pas être un fichier valide de langue Dotclear.'; +$GLOBALS['__l10n']['An error occurred during language upgrade.'] = 'Une erreur est survenue durant la mise à jour de la langue.'; +$GLOBALS['__l10n']['Error:'] = 'Erreur :'; +$GLOBALS['__l10n']['By names, ascendant'] = 'Par noms, croissants'; +$GLOBALS['__l10n']['By names, descendant'] = 'Par noms, décroissants'; +$GLOBALS['__l10n']['By dates, ascendant'] = 'Par dates, croissantes'; +$GLOBALS['__l10n']['By dates, descendant'] = 'Par dates, décroissantes'; +$GLOBALS['__l10n']['Media manager'] = 'Gestionnaire de médias'; +$GLOBALS['__l10n']['confirm removal'] = 'Confirmer la suppression'; +$GLOBALS['__l10n']['Are you sure you want to remove %s?'] = 'Êtes-vous certain de vouloir supprimer %s ?'; +$GLOBALS['__l10n']['cancel'] = 'annuler'; +$GLOBALS['__l10n']['yes'] = 'oui'; +$GLOBALS['__l10n']['Directory has been successfully created.'] = 'Répertoire créé avec succès.'; +$GLOBALS['__l10n']['Files have been successfully uploaded.'] = 'Fichier chargé avec succès.'; +$GLOBALS['__l10n']['File has been successfully removed.'] = 'Fichier supprimé avec succès.'; +$GLOBALS['__l10n']['Directory has been successfully removed.'] = 'Répertoire supprimé avec succès.'; +$GLOBALS['__l10n']['Directory has been successfully rebuilt.'] = 'Répertoire reconstruit avec succès.'; +$GLOBALS['__l10n']['Zip file has been successfully extracted.'] = 'Le fichier zip a été extrait avec succès.'; +$GLOBALS['__l10n']['Choose a file to attach to entry %s by clicking on %s.'] = 'Choisissez un fichier à attacher au billet %s en cliquant sur %s.'; +$GLOBALS['__l10n']['Attach this file to entry'] = 'Attacher ce fichier au billet'; +$GLOBALS['__l10n']['Choose a file to insert into entry by clicking on %s.'] = 'Choisissez un fichier à insérer dans le billet en cliquant sur %s.'; +$GLOBALS['__l10n']['No file.'] = 'Aucun fichier.'; +$GLOBALS['__l10n']['Sort files:'] = 'Trier les fichiers :'; +$GLOBALS['__l10n']['Add files'] = 'Ajouter des fichiers'; +$GLOBALS['__l10n']['Choose a file:'] = 'Choisissez un fichier :'; +$GLOBALS['__l10n']['Maximum size %s'] = 'Taille maximale %s'; +$GLOBALS['__l10n']['Private'] = 'Privé'; +$GLOBALS['__l10n']['send'] = 'envoyer'; +$GLOBALS['__l10n']['Please take care to publish media that you own and that are not protected by copyright.'] = 'Veuillez prendre garde à ne publier que des médias que vous possédez ou qui ne sont pas protégés contre la copie.'; +$GLOBALS['__l10n']['New directory'] = 'Nouveau répertoire'; +$GLOBALS['__l10n']['Directory Name:'] = 'Nom du répertoire :'; +$GLOBALS['__l10n']['Download this directory as a zip file'] = 'Télécharger ce répertoire dans un fichier zip'; +$GLOBALS['__l10n']['open'] = 'ouvrir'; +$GLOBALS['__l10n']['Insert this file into entry'] = 'Insérer ce fichier dans le billet'; +$GLOBALS['__l10n']['Not a valid file'] = 'Fichier invalide'; +$GLOBALS['__l10n']['File has been successfully updated.'] = 'Fichier mis à jour avec succès.'; +$GLOBALS['__l10n']['Thumbnails have been successfully updated.'] = 'Les miniatures ont été mises à jour avec succès.'; +$GLOBALS['__l10n']['Insert media item'] = 'Insérer un média'; +$GLOBALS['__l10n']['Image size:'] = 'Taille de l\'image :'; +$GLOBALS['__l10n']['original'] = 'originale'; +$GLOBALS['__l10n']['Image alignment'] = 'Alignement de l\'image'; +$GLOBALS['__l10n']['None'] = 'Aucun'; +$GLOBALS['__l10n']['Left'] = 'Gauche'; +$GLOBALS['__l10n']['Right'] = 'Droite'; +$GLOBALS['__l10n']['Center'] = 'Centre'; +$GLOBALS['__l10n']['Image insertion'] = 'Insertion de l\'image'; +$GLOBALS['__l10n']['As a single image'] = 'En tant qu\'image uniquement'; +$GLOBALS['__l10n']['As a link to original image'] = 'En tant que lien vers l\'image originale'; +$GLOBALS['__l10n']['MP3 disposition'] = 'Disposition du MP3'; +$GLOBALS['__l10n']['Please note that you cannot insert mp3 files with visual editor.'] = 'Merci de noter que vous ne pouvez pas insérer de fichier mp3 avec l\'éditeur visuel.'; +$GLOBALS['__l10n']['Please note that you cannot insert video files with visual editor.'] = 'Merci de noter que vous ne pouvez pas insérer de fichier vidéo avec l\'éditeur visuel.'; +$GLOBALS['__l10n']['Video size'] = 'Taille de la vidéo'; +$GLOBALS['__l10n']['Width:'] = 'Largeur :'; +$GLOBALS['__l10n']['Height:'] = 'Hauteur :'; +$GLOBALS['__l10n']['Video disposition'] = 'Disposition de la vidéo'; +$GLOBALS['__l10n']['Media item will be inserted as a link.'] = 'Le média sera inséré en tant que lien.'; +$GLOBALS['__l10n']['Cancel'] = 'Annuler'; +$GLOBALS['__l10n']['Insert'] = 'Insérer'; +$GLOBALS['__l10n']['Media details'] = 'Détails du média'; +$GLOBALS['__l10n']['Available sizes:'] = 'Tailles disponibles :'; +$GLOBALS['__l10n']['File owner:'] = 'Propriétaire du fichier :'; +$GLOBALS['__l10n']['File type:'] = 'Type de fichier :'; +$GLOBALS['__l10n']['File size:'] = 'Taille du fichier :'; +$GLOBALS['__l10n']['File URL:'] = 'URL du fichier :'; +$GLOBALS['__l10n']['Show entries containing this media'] = 'Afficher les billets contenant ce média'; +$GLOBALS['__l10n']['Entries containing this media'] = 'Billets contenant ce média'; +$GLOBALS['__l10n']['No entry seems contain this media.'] = 'Aucun billet ne semble contenir ce média.'; +$GLOBALS['__l10n']['Image details'] = 'Détails de l\'image'; +$GLOBALS['__l10n']['No detail'] = 'Aucun détail'; +$GLOBALS['__l10n']['Update thumbnails'] = 'Mettre à jour les miniatures'; +$GLOBALS['__l10n']['This will create or update thumbnails for this image.'] = 'Ceci va créer ou mettre à jour les miniatures pour cette image.'; +$GLOBALS['__l10n']['update thumbnails'] = 'mettre à jour les miniatures'; +$GLOBALS['__l10n']['Extract in a new directory'] = 'Extraire dans un nouveau répertoire'; +$GLOBALS['__l10n']['Extract in current directory'] = 'Extraire dans le répertoire actuel'; +$GLOBALS['__l10n']['Extract archive'] = 'Extraire l\'archive'; +$GLOBALS['__l10n']['This will extract archive in a new directory that should not exists yet.'] = 'Ceci va extraire l\'archive dans un nouveau répertoire qui ne doit pas encore exister.'; +$GLOBALS['__l10n']['This will extract archive in current directory and will overwrite existing files or directory.'] = 'Ceci va extraire l\'archive dans le répertoire actuel et va écraser les fichiers ou répertoires existants.'; +$GLOBALS['__l10n']['Extract mode:'] = 'Mode d\'extraction :'; +$GLOBALS['__l10n']['extract'] = 'extraire'; +$GLOBALS['__l10n']['Change media properties'] = 'Changer les propriétés du média'; +$GLOBALS['__l10n']['File name:'] = 'Nom du fichier :'; +$GLOBALS['__l10n']['File title:'] = 'Titre du fichier :'; +$GLOBALS['__l10n']['File date:'] = 'Date du fichier :'; +$GLOBALS['__l10n']['New directory:'] = 'Nouveau répertoire :'; +$GLOBALS['__l10n']['Change file'] = 'Changer le fichier'; +$GLOBALS['__l10n']['No blog or user given.'] = 'Vous n\'avez pas indiqué de blog ou d\'utilisateur'; +$GLOBALS['__l10n']['permissions'] = 'permissions'; +$GLOBALS['__l10n']['Permissions'] = 'Permissions'; +$GLOBALS['__l10n']['The permissions have been successfully updated.'] = 'Permissions mises à jour avec succès.'; +$GLOBALS['__l10n']['You are about to change permissions on the following blogs for users %s.'] = 'Vous allez changer les permissions des utilisateurs %s pour ces blogs.'; +$GLOBALS['__l10n']['choose a blog'] = 'choisissez un blog'; +$GLOBALS['__l10n']['Choose a blog'] = 'Choisissez un blog'; +$GLOBALS['__l10n']['Entries per page'] = 'Billets par page'; +$GLOBALS['__l10n']['Choose one or more blogs to which you want to give permissions to users %s.'] = 'Choisissez un ou plusieurs blogs pour lesquels les utilisateurs suivants auront des permissions : %s.'; +$GLOBALS['__l10n']['set permissions'] = 'définir les permissions'; +$GLOBALS['__l10n']['No content found on this plugin.'] = 'Aucun contenu pour cette extension.'; +$GLOBALS['__l10n']['Plugin not found'] = 'Extension introuvable'; +$GLOBALS['__l10n']['The plugin you reached does not exist or does not have an admin page.'] = 'L\'extension que vous essayez d\'atteindre n\'existe pas ou n\'a pas de page d\'administration.'; +$GLOBALS['__l10n']['No such plugin.'] = 'Extension inexistante.'; +$GLOBALS['__l10n']['You don\'t have permissions to delete this plugin.'] = 'Vous n\'avez pas les permissions pour effacer cette extension'; +$GLOBALS['__l10n']['You don\'t have permissions to deactivate this plugin.'] = 'Vous n\'avez pas les permissions pour désactiver cette extension.'; +$GLOBALS['__l10n']['Plugins management'] = 'Gestion des extensions'; +$GLOBALS['__l10n']['Plugin has been successfully deleted.'] = 'L\'extension a été supprimée avec succès.'; +$GLOBALS['__l10n']['Plugin has been successfully installed.'] = 'L\'extension a été installée avec succès.'; +$GLOBALS['__l10n']['Plugin has been successfully upgraded'] = 'L\'extension a été mise à jour avec succès.'; +$GLOBALS['__l10n']['Plugins add new functionalities to Dotclear. Here you can activate or deactivate installed plugins.'] = 'Les extensions ajoutent de nouvelles fonctionnalités à Dotclear. Ici, vous pouvez activer ou désactiver les extensions installées.'; +$GLOBALS['__l10n']['You can find additional plugins for your blog on %s.'] = 'Vous pouvez trouver de nouvelles extensions pour votre blog sur %s.'; +$GLOBALS['__l10n']['To install or upgrade a plugin you generally just need to upload it in "Install or upgrade a plugin" section.'] = 'Tout ce que vous avez à faire pour installer ou mettre à jour une extension est généralement de la déposer dans la section "Installer ou mettre à jour une extension".'; +$GLOBALS['__l10n']['To install or upgrade a plugin you just need to extract it in your plugins directory.'] = 'Tout ce que vous avez à faire pour installer une extension est de l\'extraire dans votre répertoire d\'extensions.'; +$GLOBALS['__l10n']['Plugins'] = 'Extensions'; +$GLOBALS['__l10n']['Activated plugins'] = 'Extensions activées'; +$GLOBALS['__l10n']['Plugin'] = 'Extension'; +$GLOBALS['__l10n']['Version'] = 'Version'; +$GLOBALS['__l10n']['Details'] = 'Détails'; +$GLOBALS['__l10n']['Deactivate'] = 'Désactiver'; +$GLOBALS['__l10n']['Deactivated plugins'] = 'Extensions désactivées'; +$GLOBALS['__l10n']['Activate'] = 'Activer'; +$GLOBALS['__l10n']['Install or upgrade a plugin'] = 'Installer ou mettre à jour une extension'; +$GLOBALS['__l10n']['You can install plugins by uploading or downloading zip files.'] = 'Vous pouvez installer des extensions en déposant ou téléchargeant des fichiers zip.'; +$GLOBALS['__l10n']['Plugin zip file:'] = 'Fichier zip de l\'extension :'; +$GLOBALS['__l10n']['Upload plugin'] = 'Déposer l\'extension'; +$GLOBALS['__l10n']['Plugin zip file URL:'] = 'URL du fichier zip de l\'extension :'; +$GLOBALS['__l10n']['Download plugin'] = 'Télécharger l\'extension'; +$GLOBALS['__l10n']['To enable this function, please give write access to your plugins directory.'] = 'Pour activer cette fonction, donnez un accès en écriture à votre répertoire d\'extensions.'; +$GLOBALS['__l10n']['Add a link'] = 'Ajouter un lien'; +$GLOBALS['__l10n']['Available'] = 'Disponible'; +$GLOBALS['__l10n']['Most used'] = 'Plus utilisées'; +$GLOBALS['__l10n']['Link URL:'] = 'URL du lien :'; +$GLOBALS['__l10n']['Link language:'] = 'Langue du lien :'; +$GLOBALS['__l10n']['insert'] = 'insérer'; +$GLOBALS['__l10n']['Add a link to an entry'] = 'Ajouter un lien vers un billet'; +$GLOBALS['__l10n']['Search entry:'] = 'Rechercher un billet :'; +$GLOBALS['__l10n']['This entry does not exist.'] = 'Ce billet n\'existe pas.'; +$GLOBALS['__l10n']['Edit entry'] = 'Modifier le billet'; +$GLOBALS['__l10n']['next entry'] = 'billet suivant'; +$GLOBALS['__l10n']['previous entry'] = 'billet précédent'; +$GLOBALS['__l10n']['Entry has been successfully updated.'] = 'Billet mis à jour avec succès.'; +$GLOBALS['__l10n']['Entry has been successfully created.'] = 'Billet créé avec succès.'; +$GLOBALS['__l10n']['File has been successfully attached.'] = 'Fichier attaché avec succès.'; +$GLOBALS['__l10n']['Attachment has been successfully removed.'] = 'Pièce jointe retirée avec succès.'; +$GLOBALS['__l10n']['Comment has been successfully created.'] = 'Commentaire créé avec succès.'; +$GLOBALS['__l10n']['Don\'t forget to validate your XHTML conversion by saving your post.'] = 'Enregistrez votre billet pour valider la transformation en XHTML.'; +$GLOBALS['__l10n']['View entry'] = 'Voir le billet'; +$GLOBALS['__l10n']['Preview entry'] = 'Prévisualiser le billet'; +$GLOBALS['__l10n']['Entry status:'] = 'État du billet :'; +$GLOBALS['__l10n']['Published on:'] = 'Publié le :'; +$GLOBALS['__l10n']['Text formating:'] = 'Format du texte :'; +$GLOBALS['__l10n']['Convert to XHTML'] = 'Convertir en XHTML'; +$GLOBALS['__l10n']['Selected entry'] = 'Billet sélectionné'; +$GLOBALS['__l10n']['Entry lang:'] = 'Langue du billet :'; +$GLOBALS['__l10n']['Entry password:'] = 'Mot de passe du billet :'; +$GLOBALS['__l10n']['Basename:'] = 'URL spécifique :'; +$GLOBALS['__l10n']['Warning: If you set the URL manually, it may conflict with another entry.'] = 'Attention : si vous indiquez l\'URL manuellement, celle-ci peut entrer en conflit avec un autre billet.'; +$GLOBALS['__l10n']['Attachments'] = 'Pièces jointes'; +$GLOBALS['__l10n']['remove'] = 'supprimer'; +$GLOBALS['__l10n']['No attachment.'] = 'Aucune pièce jointe'; +$GLOBALS['__l10n']['Add files to this entry'] = 'Ajouter un fichier au billet'; +$GLOBALS['__l10n']['Excerpt:'] = 'Extrait :'; +$GLOBALS['__l10n']['Notes:'] = 'Notes :'; +$GLOBALS['__l10n']['Ping blogs'] = 'Faire des rétroliens'; +$GLOBALS['__l10n']['Trackbacks'] = 'Rétroliens'; +$GLOBALS['__l10n']['No trackback'] = 'Aucun rétrolien'; +$GLOBALS['__l10n']['Add a comment'] = 'Ajouter un commentaire'; +$GLOBALS['__l10n']['Name:'] = 'Nom :'; +$GLOBALS['__l10n']['IP address'] = 'Adresse IP'; +$GLOBALS['__l10n']['published'] = 'publié'; +$GLOBALS['__l10n']['unpublished'] = 'non publié'; +$GLOBALS['__l10n']['pending'] = 'en attente'; +$GLOBALS['__l10n']['junk'] = 'indésirable'; +$GLOBALS['__l10n']['Edit this comment'] = 'Modifier ce commentaire'; +$GLOBALS['__l10n']['This attachment does not exist'] = 'Cette pièce jointe n\'existe pas'; +$GLOBALS['__l10n']['Remove attachment'] = 'Supprimer la pièce jointe'; +$GLOBALS['__l10n']['Attachment'] = 'Pièce jointe'; +$GLOBALS['__l10n']['Are you sure you want to remove this attachment?'] = 'Êtes-vous certain de vouloir supprimer cette pièce jointe ?'; +$GLOBALS['__l10n']['selected'] = 'sélectionné'; +$GLOBALS['__l10n']['not selected'] = 'non sélectionné'; +$GLOBALS['__l10n']['Category'] = 'Catégorie'; +$GLOBALS['__l10n']['Selected'] = 'Sélectionné'; +$GLOBALS['__l10n']['schedule'] = 'programmer'; +$GLOBALS['__l10n']['mark as selected'] = 'marquer sélectionné'; +$GLOBALS['__l10n']['mark as unselected'] = 'marquer non sélectionné'; +$GLOBALS['__l10n']['change category'] = 'changer la catégorie'; +$GLOBALS['__l10n']['change author'] = 'changer l\'auteur'; +$GLOBALS['__l10n']['Selected:'] = 'Sélectionné :'; +$GLOBALS['__l10n']['Month:'] = 'Mois :'; +$GLOBALS['__l10n']['Lang:'] = 'Langue :'; +$GLOBALS['__l10n']['Selected entries action:'] = 'Action sur les billets sélectionnés :'; +$GLOBALS['__l10n']['This user does not exist'] = 'Cet utilisateur n\'existe pas'; +$GLOBALS['__l10n']['Change category for entries'] = 'Changer de catégorie pour les billets'; +$GLOBALS['__l10n']['Change author for entries'] = 'Changer l\'auteur des billets'; +$GLOBALS['__l10n']['Author ID:'] = 'Identifiant de l\'utilisateur'; +$GLOBALS['__l10n']['If you want to change your email or password you must provide your current password.'] = 'Si vous voulez changer votre adresse email ou votre mot de passe, vous devez indiquer votre mot de passe.'; +$GLOBALS['__l10n']['Personal information has been successfully updated.'] = 'Informations personnelles mises à jour avec succès.'; +$GLOBALS['__l10n']['Display name:'] = 'Pseudonyme :'; +$GLOBALS['__l10n']['Preferred format:'] = 'Format d\'édition préféré :'; +$GLOBALS['__l10n']['Default entry status:'] = 'État des billets par défaut :'; +$GLOBALS['__l10n']['Entry edit field height:'] = 'Taille de la zone d\'édition :'; +$GLOBALS['__l10n']['User language:'] = 'Langue de l\'utilisateur :'; +$GLOBALS['__l10n']['User timezone:'] = 'Fuseau horaire de l\'utilisateur :'; +$GLOBALS['__l10n']['Enable WYSIWYG mode'] = 'Activer l\'éditeur visuel'; +$GLOBALS['__l10n']['Change your password'] = 'Changer votre mot de passe'; +$GLOBALS['__l10n']['New password:'] = 'Nouveau mot de passe :'; +$GLOBALS['__l10n']['Search'] = 'Rechercher'; +$GLOBALS['__l10n']['Search options'] = 'Options de recherche'; +$GLOBALS['__l10n']['Query:'] = 'Requête :'; +$GLOBALS['__l10n']['search entries'] = 'rechercher des billets'; +$GLOBALS['__l10n']['search comments'] = 'recherche des commentaires'; +$GLOBALS['__l10n']['%d entries found'] = '%d billets trouvés'; +$GLOBALS['__l10n']['%d entry found'] = '%d billet trouvé'; +$GLOBALS['__l10n']['%d comment found'] = '%d commentaire trouvé'; +$GLOBALS['__l10n']['%d comments found'] = '%d commentaires trouvés'; +$GLOBALS['__l10n']['This entry does not exist or is not published'] = 'Ce billet n\'existe pas ou n\'est pas publié'; +$GLOBALS['__l10n']['All pings sent.'] = 'Tous les rétroliens ont été envoyés.'; +$GLOBALS['__l10n']['Auto discover ping URLs'] = 'Découverte automatique des URL à rétrolier'; +$GLOBALS['__l10n']['URLs to ping:'] = 'URLs à rétrolier :'; +$GLOBALS['__l10n']['Send excerpt:'] = 'Envoyer l\'extrait :'; +$GLOBALS['__l10n']['Previously sent pings'] = 'Rétroliens déjà envoyés'; +$GLOBALS['__l10n']['Dotclear update'] = 'Mise à jour de Dotclear'; +$GLOBALS['__l10n']['Unable to delete file %s'] = 'Impossible de supprimer le fichier %s'; +$GLOBALS['__l10n']['Downloaded Dotclear archive seems to be corrupted. Try download it again.'] = 'L\'archive téléchargée de Dotclear semble être corrompue. Essayer de la télécharger à nouveau.'; +$GLOBALS['__l10n']['The following files of your Dotclear installation have been modified so we won\'t try to update your installation. Please try to update manually.'] = 'Comme les fichiers suivants de votre installation de Dotclear ont été modifiés, votre installation ne peut être mise à jour. Merci de mettre à jour manuellement.'; +$GLOBALS['__l10n']['The following files of your Dotclear installation are not readable. Please fix this or try to make a backup file named %s manually.'] = 'Les fichiers suivants de votre installation de Dotclear ne peuvent pas être lus. Veuillez corriger ceci ou créer un fichier de backup nommé %s manuellement.'; +$GLOBALS['__l10n']['The following files of your Dotclear installation cannot be written. Please fix this or try to update manually.'] = 'Les fichiers suivants de votre installation de Dotclear ne peuvent pas être écrits. Veuillez corriger ceci ou mettre à jour manuellement.'; +$GLOBALS['__l10n']['No newer Dotclear version available.'] = 'Aucune nouvelle version de Dotclear n\'est disponible.'; +$GLOBALS['__l10n']['Dotclear %s is available.'] = 'Dotclear %s est disponible.'; +$GLOBALS['__l10n']['To upgrade your Dotclear installation simply click on the following button. A backup file of your current installation will be created in your root directory.'] = 'Pour mettre à jour votre installation de Dotclear, cliquez sur le bouton suivant. Un fichier de sauvegarde de votre installation actuelle sera créé dans votre répertoire principal.'; +$GLOBALS['__l10n']['Update Dotclear'] = 'Mettre à jour Dotclear'; +$GLOBALS['__l10n']['Update backup files'] = 'Sauvegardes des mises à jour'; +$GLOBALS['__l10n']['The following files are backups of previously updates. You can revert your previous installation or delete theses files.'] = 'Les fichiers suivants sont des sauvegardes de mises à jour précédentes. Vous pouvez rétablir votre installation précédente ou supprimer ces fichiers.'; +$GLOBALS['__l10n']['Please note that reverting your Dotclear version may have some unwanted side-effects. Consider reverting only if you experience strong issues with this new version.'] = 'Merci de noter que rétablir votre version de Dotclear peut avoir des effets non désirés. N\'envisagez ceci que si vous rencontrez d\'importantes difficultés avec cette nouvelle version.'; +$GLOBALS['__l10n']['You should not revert to version prior to last one (%s).'] = 'Vous ne devez pas rétablir une version précédant la dernière (%s).'; +$GLOBALS['__l10n']['Delete selected file'] = 'Supprimer le fichier sélectionné'; +$GLOBALS['__l10n']['Revert to selected file'] = 'Rétablir le fichier sélectionné'; +$GLOBALS['__l10n']['Congratulations, you\'re one click away from the end of the update.'] = 'Félicitations, vous êtes à un clic de la fin de la mise à jour.'; +$GLOBALS['__l10n']['Finish the update.'] = 'Finir la mise à jour.'; +$GLOBALS['__l10n']['new user'] = 'nouvel utilisateur'; +$GLOBALS['__l10n']['User "%s" already exists.'] = 'L\'utilisateur "%s" existe déjà.'; +$GLOBALS['__l10n']['User has been successfully updated.'] = 'Utilisateur mis à jour avec succès.'; +$GLOBALS['__l10n']['User has been successfully created.'] = 'Utilisateur créé avec succès.'; +$GLOBALS['__l10n']['Warning:'] = 'Attention :'; +$GLOBALS['__l10n']['If you change your username, you will have to log in again.'] = 'Si vous changez votre login, vous devrez vous identifier à nouveau.'; +$GLOBALS['__l10n']['No permissions.'] = 'Aucune permission.'; +$GLOBALS['__l10n']['Add new permissions'] = 'Ajouter de nouvelles permissions'; +$GLOBALS['__l10n']['Username'] = 'Identifiant :'; +$GLOBALS['__l10n']['Last Name'] = 'Nom'; +$GLOBALS['__l10n']['First Name'] = 'Prénom'; +$GLOBALS['__l10n']['Display name'] = 'Pseudonyme'; +$GLOBALS['__l10n']['Number of entries'] = 'Nombre de billets'; +$GLOBALS['__l10n']['users'] = 'utilisateurs'; +$GLOBALS['__l10n']['User has been successfully removed.'] = 'Utilisateur supprimé avec succès.'; +$GLOBALS['__l10n']['Create a new user'] = 'Créer un nouvel utilisateur'; +$GLOBALS['__l10n']['Users per page'] = 'Utilisateurs par page'; +$GLOBALS['__l10n']['Selected users action:'] = 'Action sur les utilisateurs sélectionnés :'; +$GLOBALS['__l10n']['Set permissions'] = 'Définir les permissions'; +$GLOBALS['__l10n']['Blog:'] = 'Blog :'; +$GLOBALS['__l10n']['Change blog'] = 'Changer de blog'; +$GLOBALS['__l10n']['Blogs:'] = 'Blogs :'; +$GLOBALS['__l10n']['View site'] = 'Voir le site'; +$GLOBALS['__l10n']['User:'] = 'Utilisateur :'; +$GLOBALS['__l10n']['Logout'] = 'Déconnexion'; +$GLOBALS['__l10n']['Thank you for using %s.'] = 'Merci d\'utiliser %s.'; +$GLOBALS['__l10n']['Help'] = 'Aide'; +$GLOBALS['__l10n']['uncover'] = 'dévoiler'; +$GLOBALS['__l10n']['hide'] = 'cacher'; +$GLOBALS['__l10n']['help'] = 'aide'; +$GLOBALS['__l10n']['No selection'] = 'Aucune sélection'; +$GLOBALS['__l10n']['select all'] = 'tout sélectionner'; +$GLOBALS['__l10n']['invert selection'] = 'inverser la sélection'; +$GLOBALS['__l10n']['view entry'] = 'voir le billet'; +$GLOBALS['__l10n']['Are you sure you want to delete selected entries?'] = 'Êtes-vous certain de vouloir supprimer les billets sélectionnés ?'; +$GLOBALS['__l10n']['Are you sure you want to delete this entry?'] = 'Êtes-vous certain de vouloir supprimer ce billet ?'; +$GLOBALS['__l10n']['Are you sure you want to delete selected comments?'] = 'Êtes-vous certain de vouloir supprimer les commentaires sélectionnés ?'; +$GLOBALS['__l10n']['Are you sure you want to delete this comment?'] = 'Êtes-vous certain de vouloir supprimer ce commentaire ?'; +$GLOBALS['__l10n']['Users with posts cannot be deleted.'] = 'Les utilisateurs ayant écrit des billets ne peuvent être effacées.'; +$GLOBALS['__l10n']['Are you sure you want to delete selected users?'] = 'Êtes-vous certain de vouloir supprimer les utilisateurs sélectionnés ?'; +$GLOBALS['__l10n']['Are you sure you want to delete category "%s"?'] = 'Êtes-vous certain de vouloir supprimer la catégorie "%s" ?'; +$GLOBALS['__l10n']['Are you sure you want to reorder all categories?'] = 'Êtes-vous certain de vouloir réinitialiser l\'ordre des catégories ?'; +$GLOBALS['__l10n']['Are you sure you want to remove media "%s"?'] = 'Êtes-vous certain de vouloir supprimer le média "%s" ?'; +$GLOBALS['__l10n']['Are you sure you want to extract archive in current directory?'] = 'Êtes-vous certain de vouloir extraire l\'archive dans le répertoire actuel ?'; +$GLOBALS['__l10n']['Are you sure you want to remove attachment "%s"?'] = 'Êtes-vous certain de vouloir supprimer la pièce jointe "%s" ?'; +$GLOBALS['__l10n']['Are you sure you want to delete "%s" language?'] = 'Êtes-vous certain de vouloir supprimer la langue "%s" ?'; +$GLOBALS['__l10n']['Are you sure you want to delete "%s" plugin?'] = 'Êtes-vous certain de vouloir supprimer l\'extension "%s" ?'; +$GLOBALS['__l10n']['Use this theme'] = 'Utiliser ce thème'; +$GLOBALS['__l10n']['Remove this theme'] = 'Supprimer ce thème'; +$GLOBALS['__l10n']['Are you sure you want to delete "%s" theme?'] = 'Êtes-vous certain de vouloir supprimer le thème "%s" ?'; +$GLOBALS['__l10n']['Zip file content'] = 'Contenu du fichier zip'; +$GLOBALS['__l10n']['XHTML markup validator'] = 'Validation XHTML'; +$GLOBALS['__l10n']['XHTML content is valid.'] = 'Le contenu XHTML est valide.'; +$GLOBALS['__l10n']['There are XHTML markup errors.'] = 'Il y a des erreurs XHTML.'; +$GLOBALS['__l10n']['You have unsaved changes.'] = 'Vous n\'avez pas enregistré vos modifications.'; +$GLOBALS['__l10n']['close'] = 'fermer'; +$GLOBALS['__l10n']['now'] = 'maintenant'; +$GLOBALS['__l10n']['visual'] = 'visuel'; +$GLOBALS['__l10n']['source'] = 'source'; +$GLOBALS['__l10n']['You can use the following shortcuts to format your text.'] = 'Vous pouvez utiliser les raccourcis suivants pour formater votre texte.'; +$GLOBALS['__l10n']['-- none --'] = '-- aucun --'; +$GLOBALS['__l10n']['-- block format --'] = '-- format bloc --'; +$GLOBALS['__l10n']['Paragraph'] = 'Paragraphe'; +$GLOBALS['__l10n']['Level 1 header'] = 'Titre de niveau 1'; +$GLOBALS['__l10n']['Level 2 header'] = 'Titre de niveau 2'; +$GLOBALS['__l10n']['Level 3 header'] = 'Titre de niveau 3'; +$GLOBALS['__l10n']['Level 4 header'] = 'Titre de niveau 4'; +$GLOBALS['__l10n']['Level 5 header'] = 'Titre de niveau 5'; +$GLOBALS['__l10n']['Level 6 header'] = 'Titre de niveau 6'; +$GLOBALS['__l10n']['Strong emphasis'] = 'Forte emphase'; +$GLOBALS['__l10n']['Emphasis'] = 'Emphase'; +$GLOBALS['__l10n']['Inserted'] = 'Insertion'; +$GLOBALS['__l10n']['Deleted'] = 'Suppression'; +$GLOBALS['__l10n']['Inline quote'] = 'Citation en ligne'; +$GLOBALS['__l10n']['Code'] = 'Code'; +$GLOBALS['__l10n']['Line break'] = 'Passage à la ligne'; +$GLOBALS['__l10n']['Blockquote'] = 'Bloc de citation'; +$GLOBALS['__l10n']['Preformated text'] = 'Texte préformaté'; +$GLOBALS['__l10n']['Unordered list'] = 'Liste à puces'; +$GLOBALS['__l10n']['Ordered list'] = 'Liste numérotée'; +$GLOBALS['__l10n']['Link'] = 'Lien'; +$GLOBALS['__l10n']['URL?'] = 'URL ?'; +$GLOBALS['__l10n']['Language?'] = 'Langue ?'; +$GLOBALS['__l10n']['External image'] = 'Image externe'; +$GLOBALS['__l10n']['Media chooser'] = 'Sélecteur de média'; +$GLOBALS['__l10n']['Link to an entry'] = 'Lien vers un billet'; +$GLOBALS['__l10n']['Activate enhanced uploader'] = 'Activer l\'interface avancée'; +$GLOBALS['__l10n']['Disable enhanced uploader'] = 'Désactiver l\'interface avancée'; +$GLOBALS['__l10n']['File successfully uploaded.'] = 'Fichier envoyé avec succès.'; +$GLOBALS['__l10n']['Maximum file size allowed:'] = 'Taille maximale de fichier autorisée :'; +$GLOBALS['__l10n']['Limit exceeded.'] = 'Limite dépassée.'; +$GLOBALS['__l10n']['File size exceeds allowed limit.'] = 'La taille du fichier dépasse la limite autorisée.'; +$GLOBALS['__l10n']['Canceled.'] = 'Annulé.'; +$GLOBALS['__l10n']['HTTP Error:'] = 'Erreur HTTP :'; +$GLOBALS['__l10n']['Choose file'] = 'Choisir un fichier'; +$GLOBALS['__l10n']['Choose files'] = 'Choisir des fichiers'; +$GLOBALS['__l10n']['Clean'] = 'Nettoyer'; +$GLOBALS['__l10n']['Upload'] = 'Envoyer'; +$GLOBALS['__l10n']['No file in queue.'] = 'Aucun fichier en file d\'attente.'; +$GLOBALS['__l10n']['1 file in queue.'] = '1 fichier en attente.'; +$GLOBALS['__l10n']['%d files in queue.'] = '%d fichiers en attente.'; +$GLOBALS['__l10n']['Queue error:'] = 'Erreur de file d\'attente :'; +$GLOBALS['__l10n']['«prev.'] = '«préc.'; +$GLOBALS['__l10n']['next»'] = 'suiv.»'; +$GLOBALS['__l10n']['No entry'] = 'Pas de billet'; +$GLOBALS['__l10n']['scheduled'] = 'programmé'; +$GLOBALS['__l10n']['protected'] = 'protégé'; +$GLOBALS['__l10n']['%d attachment'] = '%d annexe'; +$GLOBALS['__l10n']['%d attachments'] = '%d annexes'; +$GLOBALS['__l10n']['Type'] = 'Type'; +$GLOBALS['__l10n']['No user'] = 'Pas d\'utilisateur'; +$GLOBALS['__l10n']['System'] = 'Système'; +$GLOBALS['__l10n']['Blog'] = 'Blog'; +$GLOBALS['__l10n']['Updates'] = 'Mises à jour'; +$GLOBALS['__l10n']['Languages'] = 'Langues'; +$GLOBALS['__l10n']['Unable to open directory.'] = 'Impossible d\'ouvrir le répertoire.'; +$GLOBALS['__l10n']['Unable to create directory.'] = 'Impossible de créer le répertoire.'; +$GLOBALS['__l10n']['File is not writable.'] = 'Le fichier n\'est pas accessible en écriture.'; +$GLOBALS['__l10n']['Unable to open file.'] = 'Impossible d\'ouvrir le fichier.'; +$GLOBALS['__l10n']['Not an uploaded file.'] = 'Pas un fichier déposé.'; +$GLOBALS['__l10n']['The uploaded file exceeds the maximum file size allowed.'] = 'Le fichier déposé est plus grand que la taille maximale autorisée.'; +$GLOBALS['__l10n']['The uploaded file was only partially uploaded.'] = 'Le fichier n\'a été chargé qu\'en partie.'; +$GLOBALS['__l10n']['No file was uploaded.'] = 'Aucun fichier chargé.'; +$GLOBALS['__l10n']['Missing a temporary folder.'] = 'Il manque un répertoire temporaire.'; +$GLOBALS['__l10n']['Failed to write file to disk.'] = 'Impossible d\'écrire le fichier.'; +$GLOBALS['__l10n']['%s is not a directory.'] = '%s n\'est pas un répertoire.'; +$GLOBALS['__l10n']['Uploading this file is not allowed.'] = 'L\'envoi de ce fichier n\'est pas autorisé.'; +$GLOBALS['__l10n']['Destination directory is not in jail.'] = 'Le répertoire cible n\'est pas en jail.'; +$GLOBALS['__l10n']['File already exists.'] = 'Le nouveau fichier existe déjà.'; +$GLOBALS['__l10n']['Cannot write in this directory.'] = 'Impossible d\'écrire dans ce répertoire.'; +$GLOBALS['__l10n']['An error occurred while writing the file.'] = 'Une erreur est survenue pendant l\'écriture du fichier.'; +$GLOBALS['__l10n']['Source file does not exist.'] = 'Le fichier source n\'existe pas'; +$GLOBALS['__l10n']['File is not in jail.'] = 'Le fichier n\'est pas en jail.'; +$GLOBALS['__l10n']['Destination directory is not writable.'] = 'Le répertoire cible n\'est pas accessible en écriture.'; +$GLOBALS['__l10n']['Unable to rename file.'] = 'Impossible de renommer le fichier.'; +$GLOBALS['__l10n']['File cannot be removed.'] = 'Ce fichier ne peut pas être supprimé.'; +$GLOBALS['__l10n']['Directory is not in jail.'] = 'Le répertoire n\'est pas en jail.'; +$GLOBALS['__l10n']['Directory cannot be removed.'] = 'Ce répertoire ne peut pas être supprimé.'; +$GLOBALS['__l10n']['Not enough memory to open image.'] = 'Mémoire insuffisante pour ouvrir l\'image.'; +$GLOBALS['__l10n']['File %s is not compressed in the zip.'] = 'Le fichier %s n\'est pas compressé dans le zip.'; +$GLOBALS['__l10n']['Trying to unzip a folder name %s'] = 'Tentative de décompresser un répertoire %s'; +$GLOBALS['__l10n']['Unable to write destination file.'] = 'Impossible d\'écrire le fichier de destination'; +$GLOBALS['__l10n']['Unable to write in target directory, permission denied.'] = 'Impossible d\'écrire dans le répertoire cible, permission refusée.'; +$GLOBALS['__l10n']['Not enough memory to open file.'] = 'Mémoire insuffisante pour ouvrir le fichier.'; +$GLOBALS['__l10n']['File does not exist'] = 'Le fichier n\'existe pas'; +$GLOBALS['__l10n']['Cannot read file'] = 'Impossible de lire le fichier'; +$GLOBALS['__l10n']['Directory does not exist'] = 'Le répertoire n\'existe pas'; +$GLOBALS['__l10n']['Cannot read directory'] = 'Impossible de lire le répertoire'; +$GLOBALS['__l10n']['administrator'] = 'administrateur'; +$GLOBALS['__l10n']['manage their own entries and comments'] = 'gérer ses propres billets et commentaires'; +$GLOBALS['__l10n']['publish entries and comments'] = 'publier des billets et des commentaires'; +$GLOBALS['__l10n']['delete entries and comments'] = 'supprimer des billets et des commentaires'; +$GLOBALS['__l10n']['manage all entries and comments'] = 'gérer tous les billets et commentaires'; +$GLOBALS['__l10n']['manage categories'] = 'gérer les catégories'; +$GLOBALS['__l10n']['manage their own media items'] = 'gérer ses propres médias'; +$GLOBALS['__l10n']['manage all media items'] = 'gérer tous les médias'; +$GLOBALS['__l10n']['That user does not exist in the database.'] = 'Cet utilisateur n\'existe pas dans la base de données.'; +$GLOBALS['__l10n']['That key does not exist in the database.'] = 'Cette clé n\'existe pas dans la base de données.'; +$GLOBALS['__l10n']['You are not allowed to add categories'] = 'Vous n\'êtes pas autorisé à créer des catégories'; +$GLOBALS['__l10n']['You are not allowed to update categories'] = 'Vous n\'êtes pas autorisé à modifier des catégories'; +$GLOBALS['__l10n']['You are not allowed to delete categories'] = 'Vous n\'êtes pas autorisé à supprimer des catégories'; +$GLOBALS['__l10n']['This category is not empty.'] = 'Cette catégorie n\'est pas vide.'; +$GLOBALS['__l10n']['Category URL must be unique.'] = 'L\'URL de chaque catégorie doit être unique.'; +$GLOBALS['__l10n']['You must provide a category title'] = 'Vous devez indiquer un titre de catégorie'; +$GLOBALS['__l10n']['You must provide a category URL'] = 'Vous devez indiquer une URL de catégorie'; +$GLOBALS['__l10n']['You are not allowed to create an entry'] = 'Vous n\'êtes pas autorisé à créer des billets'; +$GLOBALS['__l10n']['You are not allowed to update entries'] = 'Vous n\'êtes pas autorisé à modifier les billets'; +$GLOBALS['__l10n']['No such entry ID'] = 'Identifiant du billet inconnu'; +$GLOBALS['__l10n']['You are not allowed to edit this entry'] = 'Vous n\'êtes pas autorisé à modifier ce billet'; +$GLOBALS['__l10n']['You are not allowed to change this entry status'] = 'Vous n\'êtes pas autorisé à modifier l\'état de ce billet'; +$GLOBALS['__l10n']['You are not allowed to change this entry category'] = 'Vous n\'êtes pas autorisé à modifier la catégorie de ce billet'; +$GLOBALS['__l10n']['You are not allowed to mark this entry as selected'] = 'Vous n\'êtes pas autorisé à marquer ce billet comme sélectionné'; +$GLOBALS['__l10n']['You are not allowed to delete entries'] = 'Vous n\'êtes pas autorisé à supprimer des billets'; +$GLOBALS['__l10n']['You are not allowed to delete this entry'] = 'Vous n\'êtes pas autorisé à supprimer ce billet'; +$GLOBALS['__l10n']['No entry title'] = 'Pas de titre de billet'; +$GLOBALS['__l10n']['No entry content'] = 'Pas de contenu de billet'; +$GLOBALS['__l10n']['Empty entry URL'] = 'URL du billet vide'; +$GLOBALS['__l10n']['You are not allowed to update comments'] = 'Vous n\'êtes pas autorisé à modifier des commentaires'; +$GLOBALS['__l10n']['No such comment ID'] = 'Identifiant du commentaire inconnu'; +$GLOBALS['__l10n']['You are not allowed to update this comment'] = 'Vous n\'êtes pas autorisé à modifier ce commentaire'; +$GLOBALS['__l10n']['You are not allowed to change this comment\'s status'] = 'Vous n\'êtes pas autorisé à changer l\'état de ce commentaire'; +$GLOBALS['__l10n']['You are not allowed to delete comments'] = 'Vous n\'êtes pas autorisé à supprimer des commentaires'; +$GLOBALS['__l10n']['You are not allowed to delete this comment'] = 'Vous n\'êtes pas autorisé à supprimer ce commentaire'; +$GLOBALS['__l10n']['You must provide a comment'] = 'Vous devez indiquer un commentaire'; +$GLOBALS['__l10n']['You must provide an author name'] = 'Vous devez indiquer un nom d\'auteur'; +$GLOBALS['__l10n']['Email address is not valid.'] = 'Adresse email invalide.'; +$GLOBALS['__l10n']['online'] = 'en ligne'; +$GLOBALS['__l10n']['offline'] = 'hors ligne'; +$GLOBALS['__l10n']['removed'] = 'supprimé'; +$GLOBALS['__l10n']['You are not an administrator'] = 'Vous n\'êtes pas administrateur'; +$GLOBALS['__l10n']['Invalid user language code'] = 'Code langue de l\'utilisateur invalide'; +$GLOBALS['__l10n']['Blog ID must contain at least 2 characters using letters, numbers or symbols.'] = 'L\'identifiant du blog doit contenir au moins 2 caractères composés de lettres, chiffres ou symboles.'; +$GLOBALS['__l10n']['No blog name'] = 'Pas de nom de blog'; +$GLOBALS['__l10n']['No blog URL'] = 'Pas d\'URL de blog'; +$GLOBALS['__l10n']['No blog defined.'] = 'Aucun blog défini.'; +$GLOBALS['__l10n']['Directory %s does not exist.'] = 'Le répertoire %s n\'existe pas.'; +$GLOBALS['__l10n']['You are not a super administrator.'] = 'Vous n\'êtes pas super administrateur.'; +$GLOBALS['__l10n']['Permission denied.'] = 'Permission refusée.'; +$GLOBALS['__l10n']['You are not the file owner.'] = 'Vous n\'êtes pas le propriétaire de ce fichier.'; +$GLOBALS['__l10n']['New file already exists.'] = 'Le nouveau fichier existe déjà.'; +$GLOBALS['__l10n']['File does not exist in the database.'] = 'Ce fichier n\'existe pas dans la base de données.'; +$GLOBALS['__l10n']['Extract destination directory %s already exists.'] = 'Le répertoire de destination d\'extraction %s existe déjà.'; +$GLOBALS['__l10n']['Empty module zip file.'] = 'Fichier zip de module vide.'; +$GLOBALS['__l10n']['The zip file does not appear to be a valid Dotclear module.'] = 'Le fichier zip ne semble pas être un fichier valide de module Dotclear.'; +$GLOBALS['__l10n']['An error occurred during module deletion.'] = 'Une erreur est survenue durant la suppression du module.'; +$GLOBALS['__l10n']['Unable to upgrade "%s". (same version)'] = 'Impossible de mettre à jour "%s" (même version).'; +$GLOBALS['__l10n']['Unable to read new _define.php file'] = 'Impossible de lire le nouveau fichier _define.php.'; +$GLOBALS['__l10n']['No such module.'] = 'Module inexistant.'; +$GLOBALS['__l10n']['Cannot remove module files'] = 'Impossible de supprimer les fichiers du module'; +$GLOBALS['__l10n']['Cannot deactivate plugin.'] = 'L\'extension ne peut pas être désactivée.'; +$GLOBALS['__l10n']['Cannot activate plugin.'] = 'L\'extension ne peut pas être activée.'; +$GLOBALS['__l10n']['Unable to retrieve settings:'] = 'Impossible d\'obtenir les paramètres :'; +$GLOBALS['__l10n']['Invalid setting namespace: %s'] = 'Espace de nommage du paramètre invalide : %s'; +$GLOBALS['__l10n']['No namespace specified'] = 'Aucun espace de nommage spécifié'; +$GLOBALS['__l10n']['%s is not a valid setting id'] = '%s n\'est pas un identifiant de paramètre valide'; +$GLOBALS['__l10n']['%s has still been pinged'] = 'Un rétrolien vers %s a déjà été fait'; +$GLOBALS['__l10n']['Unable to ping URL'] = 'Impossible de réaliser le rétrolien'; +$GLOBALS['__l10n']['%s is not a ping URL'] = '%s n\'est pas une URL de rétrolien'; +$GLOBALS['__l10n']['%s, ping error:'] = '%s, erreur de rétrolien :'; +$GLOBALS['__l10n']['Digests file not found.'] = 'Fichier de contrôle introuvable.'; +$GLOBALS['__l10n']['No file to download'] = 'Aucun fichier à télécharger.'; +$GLOBALS['__l10n']['Root directory is not writable.'] = 'Le répertoire principal n\'est pas accessible en écriture.'; +$GLOBALS['__l10n']['An error occurred while downloading archive.'] = 'Une erreur est survenue lors du téléchargement de l\'archive.'; +$GLOBALS['__l10n']['Archive not found.'] = 'L\'archive n\'a pas été trouvée.'; +$GLOBALS['__l10n']['Unable to read current digests file.'] = 'Impossible de lire le fichier de contrôle actuel.'; +$GLOBALS['__l10n']['Downloaded file seems not to be a valid archive.'] = 'Le fichier téléchargé ne semble pas être une archive valide.'; +$GLOBALS['__l10n']['Incomplete archive.'] = 'Archive incomplète.'; +$GLOBALS['__l10n']['Unable to read digests file.'] = 'Impossible de lire le fichier de contrôle.'; +$GLOBALS['__l10n']['Invalid digests file.'] = 'Fichier de contrôle invalide.'; +$GLOBALS['__l10n']['SQLite Database Schema cannot be upgraded.'] = 'Le schema de base de données SQLite ne peut pas être mis à jour.'; +$GLOBALS['__l10n']['Something went wrong with auto upgrade:'] = 'Une erreur est survenue durant la mise à jour automatique :'; +?> \ No newline at end of file diff --git a/locales/fr/main.po b/locales/fr/main.po new file mode 100644 index 0000000..dc99596 --- /dev/null +++ b/locales/fr/main.po @@ -0,0 +1,2485 @@ +# French translation of DotClear +# Copyright (C) 2006. +# Olivier Meunier , 2006. +msgid "" +msgstr "" +"Project-Id-Version: Dotclear 2\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2009-09-16 20:57+0200\n" +"PO-Revision-Date: 2009-09-16 21:11+0100\n" +"Last-Translator: xave \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: French\n" + +msgid "Dotclear has been upgraded." +msgstr "Dotclear a été mis à jour." + +msgid "Password reset" +msgstr "Réinitialisation du mot de passe" + +msgid "Someone has requested to reset the password for the following site and username." +msgstr "Quelqu'un a demandé la réinitialisation du mot de passe pour le site et l'utilisateur suivants." + +msgid "Username:" +msgstr "Nom d'utilisateur :" + +msgid "To reset your password visit the following address, otherwise just ignore this email and nothing will happen." +msgstr "Pour réinitialiser votre mot de passe, rendez-vous à l'adresse suivante. Sinon ignorez simplement ce message et rien ne se passera." + +#, php-format +msgid "The e-mail was sent successfully to %s." +msgstr "Le message a été envoyé avec succès à %s." + +msgid "Your new password" +msgstr "Votre nouveau mot de passe" + +msgid "Password:" +msgstr "Mot de passe :" + +msgid "Your new password is in your mailbox." +msgstr "Votre nouveau mot de passe est dans votre boîte à lettres." + +msgid "Wrong username or password" +msgstr "Nom d'utilisateur ou mot de passe incorrect" + +msgid "Back to login screen" +msgstr "Retour à l'écran de connexion" + +msgid "Request a new password" +msgstr "Demander un nouveau mot de passe" + +msgid "Email:" +msgstr "Email :" + +msgid "recover" +msgstr "récupérer" + +msgid "Remember my ID on this computer" +msgstr "Se souvenir de mon identifiant sur cet ordinateur" + +msgid "login" +msgstr "login" + +msgid "You must accept cookies in order to use the private area." +msgstr "Vous devez accepter les cookies pour utiliser l'interface privée." + +msgid "I forgot my password" +msgstr "J'ai oublié mon mot de passe" + +msgid "New blog" +msgstr "Nouveau blog" + +msgid "Blogs" +msgstr "Blogs" + +msgid "Blog details" +msgstr "Informations du blog" + +msgid "Blog ID:" +msgstr "Identifiant du blog :" + +msgid "Required field" +msgstr "Champ obligatoire" + +msgid "At least 2 characters using letters, numbers or symbols." +msgstr "Au moins 2 caractères, composés de lettres non accentuées, chiffres ou symboles." + +msgid "Please note that changing your blog ID may require changes in your public index.php file." +msgstr "Veuillez noter que changer l'identifiant de votre blog peut nécessiter des changements dans votre fichier index.php public." + +msgid "Blog name:" +msgstr "Nom du blog :" + +msgid "Blog URL:" +msgstr "URL du blog :" + +msgid "Blog description:" +msgstr "Description du blog :" + +msgid "save" +msgstr "enregistrer" + +msgid "No such blog ID" +msgstr "Identifiant de blog inconnu" + +msgid "Password verification failed" +msgstr "La vérification du mot de passe a échoué" + +msgid "Delete a blog" +msgstr "Supprimer un blog" + +msgid "Warning" +msgstr "Attention" + +#, php-format +msgid "You are about to delete the blog %s. Every entry, comment and category will be deleted." +msgstr "Vous êtes sur le point de supprimer le blog %s. Tous ses billets, commentaires et catégories seront supprimés." + +msgid "Please give your password to confirm the blog deletion." +msgstr "Veuillez indiquer votre mot de passe pour confirmer la suppression du blog." + +msgid "Your password:" +msgstr "Votre mot de passe :" + +msgid "Delete this blog" +msgstr "Supprimer ce blog" + +msgid "No given blog id." +msgstr "Pas d'identifiant de blog." + +msgid "No such blog." +msgstr "Blog inexistant." + +msgid "year/month/day/title" +msgstr "année/mois/jour/titre" + +msgid "year/month/title" +msgstr "année/mois/titre" + +msgid "year/title" +msgstr "année/titre" + +msgid "title" +msgstr "titre" + +msgid "Title" +msgstr "Titre" + +msgid "Title, Date" +msgstr "Titre, date" + +msgid "Title, Country, Date" +msgstr "Titre, pays, date" + +msgid "Title, City, Country, Date" +msgstr "Titre, ville, pays, date" + +msgid "I would like search engines and archivers to index and archive my blog's content." +msgstr "Je souhaite que mon blog soit indexé et archivé par les moteurs de recherche et archiveurs." + +msgid "I would like search engines and archivers to index but not archive my blog's content." +msgstr "Je souhaite que mon blog soit indexé mais pas archivé par les moteurs de recherche et archiveurs." + +msgid "I would like to prevent search engines and archivers from indexing or archiving my blog's content." +msgstr "Je souhaite que mon blog ne soit ni indexé ni archivé par les moteurs de recherche et archiveurs." + +msgid "Invalid language code" +msgstr "Code langue invalide" + +msgid "Blog settings" +msgstr "Paramètres du blog" + +msgid "Blog has been successfully created." +msgstr "Blog créé avec succès." + +msgid "Blog has been successfully updated." +msgstr "Blog mis à jour avec succès." + +msgid "Parameters" +msgstr "Paramètres" + +msgid "URL scan method:" +msgstr "Méthode de lecture de l'URL" + +msgid "Blog status:" +msgstr "État du blog" + +msgid "Blog configuration" +msgstr "Configuration du blog" + +msgid "Blog editor name:" +msgstr "Nom de l'éditeur du blog :" + +msgid "Default language:" +msgstr "Langue par défaut :" + +msgid "Blog timezone:" +msgstr "Fuseau horaire du blog :" + +msgid "Copyright notice:" +msgstr "Note de copyright :" + +msgid "New post URL format:" +msgstr "Format d'URL des nouveaux billets :" + +msgid "Enable XML/RPC interface" +msgstr "Activer l'interface XML/RPC" + +msgid "more information" +msgstr "plus d'informations" + +msgid "Comments and trackbacks" +msgstr "Commentaires et rétroliens" + +msgid "Accept comments" +msgstr "Accepter les commentaires" + +msgid "Moderate comments" +msgstr "Modérer les commentaires" + +#, php-format +msgid "Leave comments open for %s days" +msgstr "Laisser les commentaires ouverts durant %s jours" + +msgid "Leave blank to disable this feature." +msgstr "Laissez vide pour annuler ce comportement." + +msgid "Wiki syntax for comments" +msgstr "Syntaxe wiki pour les commentaires" + +msgid "Accept trackbacks" +msgstr "Accepter les rétroliens" + +msgid "Moderate trackbacks" +msgstr "Modérer les rétroliens" + +#, php-format +msgid "Leave trackbacks open for %s days" +msgstr "Laisser les rétroliens ouverts durant %s jours" + +msgid "Add \"nofollow\" relation on comments and trackbacks links" +msgstr "Ajouter la relation \"nofollow\" aux liens des commentaires et rétroliens" + +msgid "Blog presentation" +msgstr "Présentation du blog" + +msgid "Date format:" +msgstr "Format des dates :" + +msgid "Time format:" +msgstr "Format des heures :" + +msgid "Display smilies on entries and comments" +msgstr "Afficher des émoticones dans les billets et commentaires" + +#, php-format +msgid "Display %s entries per page" +msgstr "Afficher %s billets par page" + +#, php-format +msgid "Display %s entries per feed" +msgstr "Afficher %s billets par flux de syndication" + +#, php-format +msgid "Display %s comments per feed" +msgstr "Afficher %s commentaires par flux de syndication" + +msgid "Truncate feeds" +msgstr "Tronquer les flux de syndication" + +msgid "Media and images" +msgstr "Médias et images" + +msgid "Generated image sizes (in pixels)" +msgstr "Tailles des images générées (en pixels)" + +msgid "Thumbnails:" +msgstr "Miniatures :" + +msgid "Small:" +msgstr "Petites :" + +msgid "Medium:" +msgstr "Moyennes :" + +msgid "Inserted image title" +msgstr "Titres des images insérées" + +msgid "This defines image tag title when you insert it in a post from the media manager. It is retrieved from the picture's metadata." +msgstr "Ceci définit le titre de la balise d'une image insérée depuis le gestionnaire de media. Les informations sont obtenues depuis les métadonnées de l'image." + +msgid "Search engines robots policy" +msgstr "Paramètres d'indexation par les moteurs de recherche" + +msgid "XML/RPC interface" +msgstr "Interface XML/RPC" + +msgid "XML/RPC interface allows you to edit your blog with an external client." +msgstr "L'interface XML/RPC vous permet de publier sur votre blog avec un client externe." + +msgid "XML/RPC interface is not active. Change settings to enable it." +msgstr "L'interface XML/RPC n'est pas active. Changez vos paramètres pour l'activer." + +msgid "XML/RPC interface is active. You should set the following parameters on your XML/RPC client:" +msgstr "L'interface XML/RPC est active. Vous êtes invités à indiquer les paramètres suivants dans votre client XML/RPC :" + +msgid "Server URL:" +msgstr "URL du serveur :" + +msgid "Blogging system:" +msgstr "Système de blog :" + +msgid "User name:" +msgstr "Nom d'utilisateur :" + +msgid "your password" +msgstr "votre mot de passe" + +msgid "Users" +msgstr "Utilisateurs" + +msgid "Users on this blog" +msgstr "Utilisateurs de ce blog" + +msgid "No users" +msgstr "Aucun utilisateur" + +msgid "change permissions" +msgstr "changer les permissions" + +msgid "Super administrator" +msgstr "Super administrateur" + +msgid "You can't remove default theme." +msgstr "Vous ne pouvez pas supprimer le thème par défaut." + +msgid "Theme does not exist." +msgstr "Ce thème n'existe pas." + +msgid "Unable to move uploaded file." +msgstr "Impossible de déplacer le fichier téléchargé." + +msgid "An error occurred while downloading the file." +msgstr "Une erreur est survenue lors du téléchargement du fichier." + +#, php-format +msgid "by %s" +msgstr "par %s" + +#, php-format +msgid "version %s" +msgstr "version %s" + +#, php-format +msgid "(built on \"%s\")" +msgstr "(basé sur \"%s\")" + +#, php-format +msgid "(requires \"%s\")" +msgstr "(nécessite \"%s\")" + +msgid "Stylesheet" +msgstr "Feuille de style" + +msgid "Theme configuration" +msgstr "Configuration du thème" + +msgid "Blog themes" +msgstr "Thèmes du blog" + +msgid "Blog aspect" +msgstr "Apparence du blog" + +msgid "Theme has been successfully changed." +msgstr "Thème changé avec succès." + +msgid "Theme has been successfully installed." +msgstr "Le thème a été installé avec succès." + +msgid "Theme has been successfully upgraded" +msgstr "Le thème a été mis à jour avec succès." + +msgid "Theme has been successfully deleted." +msgstr "Le thème a été supprimé avec succès." + +#, php-format +msgid "You can find additional themes for your blog on %s." +msgstr "Vous pouvez trouver de nouveaux thèmes pour votre blog sur %s." + +msgid "To install or upgrade a theme you generally just need to upload it in \"Install or upgrade a theme\" section." +msgstr "Tout ce que vous avez à faire pour installer ou mettre à jour un thème est généralement de le déposer dans la section \"Installer ou mettre à jour un thème\"." + +msgid "Themes" +msgstr "Thèmes" + +#, php-format +msgid "You are currently using \"%s\"" +msgstr "Vous utilisez actuellement \"%s\"" + +msgid "use selected theme" +msgstr "utiliser le thème sélectionné" + +msgid "delete selected theme" +msgstr "Supprimer le thème sélectionné" + +msgid "Install or upgrade a theme" +msgstr "Installer ou mettre à jour un thème" + +msgid "You can install themes by uploading or downloading zip files." +msgstr "Vous pouvez installer des thèmes en déposant ou téléchargeant des fichiers zip." + +msgid "Upload a zip file" +msgstr "Déposer un fichier zip" + +msgid "Theme zip file:" +msgstr "Fichier zip du thème :" + +msgid "Upload theme" +msgstr "Déposer un thème" + +msgid "Download a zip file" +msgstr "Télécharger un fichier zip" + +msgid "Theme zip file URL:" +msgstr "URL du fichier zip du thème :" + +msgid "Download theme" +msgstr "Télécharger le thème" + +msgid "To enable this function, please give write access to your themes directory." +msgstr "Pour activer cette fonction, donnez un accès en écriture à votre répertoire de thèmes." + +msgid "back" +msgstr "retour" + +msgid "Last update" +msgstr "Dernière mise à jour" + +msgid "Blog name" +msgstr "Nom du blog" + +msgid "Blog ID" +msgstr "Identifiant du blog" + +msgid "Descending" +msgstr "Décroissant" + +msgid "Ascending" +msgstr "Croissant" + +msgid "List of blogs" +msgstr "Liste des blogs" + +msgid "Blog has been successfully deleted." +msgstr "Blog supprimé avec succès." + +msgid "Create a new blog" +msgstr "Créer un nouveau blog" + +msgid "Filters" +msgstr "Filtres" + +msgid "Order by:" +msgstr "Trier par :" + +msgid "Sort:" +msgstr "Trier :" + +msgid "Search:" +msgstr "Chercher :" + +msgid "Blogs per page" +msgstr "Blogs par page" + +msgid "filter" +msgstr "filtre" + +msgid "No blog" +msgstr "Pas de blog" + +msgid "Page(s)" +msgstr "Page(s)" + +msgid "Entries" +msgstr "Billets" + +msgid "Status" +msgstr "État" + +#, php-format +msgid "Edit blog %s" +msgstr "Modifier le blog %s" + +msgid "edit" +msgstr "modifier" + +#, php-format +msgid "Switch to blog %s" +msgstr "Passer au blog %s" + +msgid "This category does not exist." +msgstr "Cette catégorie n'existe pas." + +msgid "Categories" +msgstr "Catégories" + +msgid "The category has been successfully created." +msgstr "Catégorie créée avec succès." + +msgid "The category has been successfully removed." +msgstr "Catégorie supprimée avec succès." + +msgid "Categories have been successfully reordered." +msgstr "Catégories réordonnées avec succès." + +msgid "The category has been successfully moved." +msgstr "Catégorie déplacée avec succès." + +msgid "No category yet." +msgstr "Pas encore de catégorie." + +msgid "Categories list" +msgstr "Liste des catégories" + +#, php-format +msgid "%d entries" +msgstr "%d billets" + +#, php-format +msgid "%d entry" +msgstr "%d billet" + +msgid "total:" +msgstr "total :" + +msgid "URL:" +msgstr "URL :" + +msgid "Add a new category" +msgstr "Créer une nouvelle catégorie" + +msgid "Title:" +msgstr "Titre :" + +msgid "Parent:" +msgstr "Parent :" + +msgid "Top level" +msgstr "Premier niveau" + +msgid "Save" +msgstr "Enregistrer" + +msgid "Remove a category" +msgstr "Supprimer une catégorie" + +msgid "Choose a category to remove:" +msgstr "Choisissez une catégorie à supprimer :" + +msgid "ok" +msgstr "ok" + +msgid "Reorder categories" +msgstr "Réordonner les catégories" + +msgid "This will relocate all categories on the top level" +msgstr "Ceci va déplacer toutes les catégories au premier niveau" + +msgid "Reorder" +msgstr "Réordonner" + +msgid "New category" +msgstr "Nouvelle catégorie" + +msgid "Category has been successfully updated." +msgstr "Catégorie mise à jour avec succès." + +msgid "Category information" +msgstr "Détails de la catégorie" + +msgid "Warning: If you set the URL manually, it may conflict with another category." +msgstr "Attention : si vous indiquez l'URL manuellement, celle-ci peut entrer en conflit avec une autre catégorie." + +msgid "Description:" +msgstr "Description :" + +msgid "Move this category" +msgstr "Déplacer cette catégorie" + +msgid "Category parent" +msgstr "Catégorie parente" + +msgid "Category sibling" +msgstr "Catégorie voisine" + +msgid "Move current category" +msgstr "Déplacer la catégorie" + +msgid "after" +msgstr "après" + +msgid "before" +msgstr "avant" + +msgid "Entry does not exist." +msgstr "Ce billet n'existe pas." + +msgid "No comment" +msgstr "Aucun commentaire" + +msgid "You can't edit this comment." +msgstr "Vous ne pouvez pas modifier ce commentaire." + +msgid "Edit comment" +msgstr "Modifier le commentaire" + +msgid "Comment has been successfully updated." +msgstr "Commentaire mis à jour avec succès." + +#, php-format +msgid "Your comment on my blog %s" +msgstr "Votre commentaire sur mon blog %s" + +#, php-format +msgid "" +"Hi!\n" +"\n" +"You wrote a comment on:\n" +"%s\n" +"\n" +"\n" +msgstr "" +"Bonjour,\n" +"\n" +"Vous avez déposé un commentaire sur \n" +"%s\n" +"\n" +"\n" + +msgid "Send an e-mail" +msgstr "Envoyer un email" + +#, php-format +msgid "Back to \"%s\"" +msgstr "Retour à \"%s\"" + +msgid "IP address:" +msgstr "Adresse IP :" + +msgid "Date:" +msgstr "Date :" + +msgid "Author:" +msgstr "Auteur :" + +msgid "Web site:" +msgstr "Site web :" + +msgid "Status:" +msgstr "État :" + +msgid "Comment:" +msgstr "Commentaire :" + +msgid "delete" +msgstr "supprimer" + +msgid "comment" +msgstr "commentaire" + +msgid "trackback" +msgstr "rétrolien" + +msgid "Date" +msgstr "Date" + +msgid "Entry title" +msgstr "Titre du billet" + +msgid "Author" +msgstr "Auteur" + +msgid "publish" +msgstr "publier" + +msgid "unpublish" +msgstr "hors ligne" + +msgid "mark as pending" +msgstr "en attente" + +msgid "mark as junk" +msgstr "indésirable" + +msgid "Comments" +msgstr "Commentaires" + +msgid "Type:" +msgstr "Type :" + +msgid "Comments per page" +msgstr "Commentaires par page" + +msgid "Comment author:" +msgstr "Auteur du commentaire :" + +msgid "You have one spam comments." +msgstr "Vous avez un commentaire indésirable." + +msgid "Show it." +msgstr "L'afficher" + +#, php-format +msgid "You have %s spam comments." +msgstr "Vous avez %s commentaires indésirables." + +msgid "Show them." +msgstr "Les afficher." + +msgid "Selected comments action:" +msgstr "Action sur les commentaires sélectionnés :" + +#, php-format +msgid "%d comment" +msgstr "%d commentaire" + +#, php-format +msgid "%d comments" +msgstr "%d commentaires" + +msgid "New entry" +msgstr "Nouveau billet" + +msgid "User preferences" +msgstr "Préférences utilisateur" + +msgid "Documentation" +msgstr "Documentation" + +msgid "Latest news" +msgstr "Actualités" + +msgid "Dashboard" +msgstr "Tableau de bord" + +msgid "Make this blog my default blog" +msgstr "Définir comme blog par défaut" + +msgid "This blog is offline" +msgstr "Ce blog est hors ligne" + +msgid "This blog is removed" +msgstr "Ce blog est supprimé" + +msgid "DC_ADMIN_URL is not defined, you should edit your configuration file." +msgstr "DC_ADMIN_URL n'est pas défini, vous devriez corriger votre fichier de configuration." + +msgid "Following plugins have been installed:" +msgstr "Les extensions suivantes ont été installés :" + +msgid "Following plugins have not been installed:" +msgstr "Les extensions suivantes suivants n'ont pas été installés :" + +msgid "Quick entry" +msgstr "Billet rapide" + +msgid "Content:" +msgstr "Contenu :" + +msgid "Category:" +msgstr "Catégorie :" + +msgid "save and publish" +msgstr "enregister et publier" + +#, php-format +msgid "Dotclear %s is available!" +msgstr "Dotclear %s est disponible !" + +msgid "Upgrade now" +msgstr "Mettre à jour maintenant" + +msgid "Remind me later" +msgstr "Me le rappeler plus tard" + +#, php-format +msgid "PHP version is %s (5.0 or earlier needed)." +msgstr "La version de PHP est %s (5.0 ou plus récent nécessaire.)" + +msgid "Multibyte string module (mbstring) is not available." +msgstr "Le support des chaînes multi-octets (mbstring) n'est pas disponible." + +msgid "Iconv module is not available." +msgstr "Le module iconv n'est pas disponible." + +msgid "Output control functions are not available." +msgstr "Les fonctions de bufferisation de sortie ne sont pas disponibles." + +msgid "SimpleXML module is not available." +msgstr "Le module SimpleXML n'est pas disponible." + +msgid "DOM XML module is not available." +msgstr "Le module DOM XML n'est pas disponible." + +msgid "PCRE engine does not support UTF-8 strings." +msgstr "Le moteur d'expressions rationnelles PCRE ne gère pas les chaînes UTF-8." + +msgid "SPL module is not available." +msgstr "Le module SPL n'est pas disponible." + +#, php-format +msgid "MySQL version is %s (4.1 or earlier needed)." +msgstr "La version de MySQL est %s (4.1 ou plus récent nécessaire)." + +msgid "MySQL InnoDB engine is not available." +msgstr "Le gestionnaire de stockage InnoDB de MySQL n'est pas disponible." + +#, php-format +msgid "PostgreSQL version is %s (8.0 or earlier needed)." +msgstr "La version de PostgreSQL est %s (8.0 ou plus récent nécessaire)." + +msgid "Please set a master key (DC_MASTER_KEY) in configuration file." +msgstr "Veuillez indiquer une clé de référence (DC_MASTER_KEY) dans le fichier de configuration." + +msgid "Dotclear is already installed." +msgstr "Dotclear est déjà installé." + +msgid "Dotclear cannot be installed." +msgstr "Dotclear ne peut pas être installé." + +msgid "No user ID given" +msgstr "Aucun identifiant utilisateur spécifié" + +msgid "User ID must contain at least 2 characters using letters, numbers or symbols." +msgstr "L'identifiant utilisateur doit contenir au moins 2 caractères composés de lettres, chiffres ou symboles." + +msgid "Invalid email address" +msgstr "Adresse email incorrecte" + +msgid "No password given" +msgstr "Aucun mot de passe spécifié" + +msgid "Passwords don't match" +msgstr "Les mots de passe ne correspondent pas" + +msgid "Password must contain at least 6 characters." +msgstr "Le mot de passe doit contenir au moins 6 caractères." + +msgid "My first blog" +msgstr "Mon premier blog" + +msgid "Welcome to Dotclear!" +msgstr "Bienvenue sur Dotclear !" + +msgid "This is your first entry. When you're ready to blog, log in to edit or delete it." +msgstr "Ceci est votre premier billet. Quand vous serez prêt à bloguer, connectez-vous pour le modifier ou le supprimer." + +msgid "Dotclear Team" +msgstr "L'équipe Dotclear" + +msgid "" +"

    This is a comment.

    \n" +"

    To delete it, log in and view your blog's comments. Then you might remove or edit it.

    " +msgstr "

    Ceci est un commentaire

    Pour le supprimer, connectez-vous et affichez les commentaires de votre blog. Vous pourrez alors le supprimer ou le modifier.

    " + +msgid "Dotclear installation" +msgstr "Installation de Dotclear" + +#, php-format +msgid "Cache directory %s is not writable." +msgstr "Le répertoire de cache %s n'est pas accessible en écriture." + +msgid "Errors:" +msgstr "Erreurs :" + +msgid "Configuration file has been successfully created." +msgstr "Le fichier de configuration a été créé avec succès." + +msgid "User information" +msgstr "Informations utilisateur" + +msgid "Please provide the following information needed to create the first user." +msgstr "Merci de fournir les informations suivantes pour créer le premier utilisateur." + +msgid "First Name:" +msgstr "Prénom :" + +msgid "Last Name:" +msgstr "Nom" + +msgid "Username and password" +msgstr "Identifiant ou mot de passe incorrect" + +msgid "Confirm password:" +msgstr "Confirmez le mot de passe :" + +msgid "All done!" +msgstr "Terminé !" + +msgid "Dotclear has been successfully installed. Here is some useful information you should keep." +msgstr "Dotclear a été installé avec succès. Conservez les informations suivantes précieusement." + +msgid "Your account" +msgstr "Votre compte" + +msgid "Your blog" +msgstr "Votre blog" + +msgid "Blog address:" +msgstr "Adresse du blog :" + +msgid "Administration interface:" +msgstr "Interface d'administration :" + +msgid "Manage your blog now" +msgstr "Gérez votre blog" + +#, php-format +msgid "The file %s already exists. If you need to reset any of the configuration items in this file, please delete it first or you may continue to install." +msgstr "Le fichier %s existe déjà. Pour réinitialiser votre configuration, supprimez d'abord ce fichier ou bien continuez l'installation." + +#, php-format +msgid "File %s does not exist." +msgstr "Le fichier %s n'existe pas." + +#, php-format +msgid "Cannot write %s file." +msgstr "Impossible d'écrire le fichier %s." + +msgid "Dotclear installation wizard" +msgstr "Assistant d'installation de Dotclear" + +msgid "System information" +msgstr "Informations système" + +msgid "Please provide the following information needed to create your configuration file." +msgstr "Merci de fournir les informations suivantes pour créer votre fichier de configuration." + +msgid "Database type:" +msgstr "Type de base de données :" + +msgid "Database Host Name:" +msgstr "Nom d'hôte de la base de données :" + +msgid "Database Name:" +msgstr "Nom de la base de données :" + +msgid "Database User Name:" +msgstr "Nom d'utilisateur de la base de données :" + +msgid "Database Password:" +msgstr "Mot de passe de la base de données :" + +msgid "Database Tables Prefix:" +msgstr "Préfixe des tables de la base de données :" + +msgid "No such installed language" +msgstr "Cette langue n'est pas installée" + +msgid "You can't remove English language." +msgstr "Vous ne pouvez pas supprimer la langue anglaise." + +msgid "Permissions to delete language denied." +msgstr "Permission de supprimer la langue refusée." + +msgid "Invalid language file URL." +msgstr "URL de fichier de langue invalide." + +msgid "Languages management" +msgstr "Gestion des langues" + +msgid "Language has been successfully deleted." +msgstr "La langue a été supprimée avec succès." + +msgid "Language has been successfully installed." +msgstr "La langue a été installée avec succès." + +msgid "Language has been successfully upgraded" +msgstr "La langue a été mise à jour avec succès." + +msgid "Here you can install, upgrade or remove languages for your Dotclear installation." +msgstr "Sur cette page, vous pouvez installer, mettre à jour ou supprimer des langues de votre installation de Dotclear." + +#, php-format +msgid "You can change your user language in your preferences or change your blog's main language in your blog settings." +msgstr "Vous pouvez changer votre langue d'utilisateur dans vos préférences ou changer la langue principale de votre blog dans vos paramètres de blog." + +msgid "Installed languages" +msgstr "Langues installées" + +msgid "No additional language is installed." +msgstr "Aucune langue supplémentaire n'est installée." + +msgid "Language" +msgstr "Langue" + +msgid "Action" +msgstr "Action" + +msgid "Delete" +msgstr "Supprimer" + +msgid "Install or upgrade languages" +msgstr "Installer ou mettre à jour une langue" + +#, php-format +msgid "You can install or remove a language by adding or removing the relevant directory in your %s folder." +msgstr "Vous pouvez installer ou supprimer une langue en ajoutant ou supprimant le répertoire correspondant dans votre répertoire %s." + +msgid "Available languages" +msgstr "Langues disponibles" + +#, php-format +msgid "You can download and install a additional language directly from Dotclear.net. Proposed languages are based on your version: %s." +msgstr "Vous pouvez télécharger et installer une langue supplémentaire directement depuis Dotclear.net. Les langues proposées sont basées sur votre version : %s." + +msgid "Language:" +msgstr "Langue :" + +msgid "Install language" +msgstr "Installer la langue" + +msgid "You can install languages by uploading zip files." +msgstr "Vous pouvez installer des langues en déposant des fichiers zip." + +msgid "Language zip file:" +msgstr "Fichier zip de la langue :" + +msgid "Upload language" +msgstr "Déposer la langue" + +msgid "Invalid language zip file." +msgstr "Fichier zip de langue invalide." + +msgid "The zip file does not appear to be a valid Dotclear language pack." +msgstr "Le fichier zip ne semble pas être un fichier valide de langue Dotclear." + +msgid "An error occurred during language upgrade." +msgstr "Une erreur est survenue durant la mise à jour de la langue." + +msgid "Error:" +msgstr "Erreur :" + +msgid "By names, ascendant" +msgstr "Par noms, croissants" + +msgid "By names, descendant" +msgstr "Par noms, décroissants" + +msgid "By dates, ascendant" +msgstr "Par dates, croissantes" + +msgid "By dates, descendant" +msgstr "Par dates, décroissantes" + +msgid "Media manager" +msgstr "Gestionnaire de médias" + +msgid "confirm removal" +msgstr "Confirmer la suppression" + +#, php-format +msgid "Are you sure you want to remove %s?" +msgstr "Êtes-vous certain de vouloir supprimer %s ?" + +msgid "cancel" +msgstr "annuler" + +msgid "yes" +msgstr "oui" + +msgid "Directory has been successfully created." +msgstr "Répertoire créé avec succès." + +msgid "Files have been successfully uploaded." +msgstr "Fichier chargé avec succès." + +msgid "File has been successfully removed." +msgstr "Fichier supprimé avec succès." + +msgid "Directory has been successfully removed." +msgstr "Répertoire supprimé avec succès." + +msgid "Directory has been successfully rebuilt." +msgstr "Répertoire reconstruit avec succès." + +msgid "Zip file has been successfully extracted." +msgstr "Le fichier zip a été extrait avec succès." + +#, php-format +msgid "Choose a file to attach to entry %s by clicking on %s." +msgstr "Choisissez un fichier à attacher au billet %s en cliquant sur %s." + +msgid "Attach this file to entry" +msgstr "Attacher ce fichier au billet" + +#, php-format +msgid "Choose a file to insert into entry by clicking on %s." +msgstr "Choisissez un fichier à insérer dans le billet en cliquant sur %s." + +msgid "No file." +msgstr "Aucun fichier." + +msgid "Sort files:" +msgstr "Trier les fichiers :" + +msgid "Add files" +msgstr "Ajouter des fichiers" + +msgid "Choose a file:" +msgstr "Choisissez un fichier :" + +#, php-format +msgid "Maximum size %s" +msgstr "Taille maximale %s" + +msgid "Private" +msgstr "Privé" + +msgid "send" +msgstr "envoyer" + +msgid "Please take care to publish media that you own and that are not protected by copyright." +msgstr "Veuillez prendre garde à ne publier que des médias que vous possédez ou qui ne sont pas protégés contre la copie." + +msgid "New directory" +msgstr "Nouveau répertoire" + +msgid "Directory Name:" +msgstr "Nom du répertoire :" + +msgid "Download this directory as a zip file" +msgstr "Télécharger ce répertoire dans un fichier zip" + +msgid "open" +msgstr "ouvrir" + +msgid "Insert this file into entry" +msgstr "Insérer ce fichier dans le billet" + +msgid "Not a valid file" +msgstr "Fichier invalide" + +msgid "File has been successfully updated." +msgstr "Fichier mis à jour avec succès." + +msgid "Thumbnails have been successfully updated." +msgstr "Les miniatures ont été mises à jour avec succès." + +msgid "Insert media item" +msgstr "Insérer un média" + +msgid "Image size:" +msgstr "Taille de l'image :" + +msgid "original" +msgstr "originale" + +msgid "Image alignment" +msgstr "Alignement de l'image" + +msgid "None" +msgstr "Aucun" + +msgid "Left" +msgstr "Gauche" + +msgid "Right" +msgstr "Droite" + +msgid "Center" +msgstr "Centre" + +msgid "Image insertion" +msgstr "Insertion de l'image" + +msgid "As a single image" +msgstr "En tant qu'image uniquement" + +msgid "As a link to original image" +msgstr "En tant que lien vers l'image originale" + +msgid "MP3 disposition" +msgstr "Disposition du MP3" + +msgid "Please note that you cannot insert mp3 files with visual editor." +msgstr "Merci de noter que vous ne pouvez pas insérer de fichier mp3 avec l'éditeur visuel." + +msgid "Please note that you cannot insert video files with visual editor." +msgstr "Merci de noter que vous ne pouvez pas insérer de fichier vidéo avec l'éditeur visuel." + +msgid "Video size" +msgstr "Taille de la vidéo" + +msgid "Width:" +msgstr "Largeur :" + +msgid "Height:" +msgstr "Hauteur :" + +msgid "Video disposition" +msgstr "Disposition de la vidéo" + +msgid "Media item will be inserted as a link." +msgstr "Le média sera inséré en tant que lien." + +msgid "Cancel" +msgstr "Annuler" + +msgid "Insert" +msgstr "Insérer" + +msgid "Media details" +msgstr "Détails du média" + +msgid "Available sizes:" +msgstr "Tailles disponibles :" + +msgid "File owner:" +msgstr "Propriétaire du fichier :" + +msgid "File type:" +msgstr "Type de fichier :" + +msgid "File size:" +msgstr "Taille du fichier :" + +msgid "File URL:" +msgstr "URL du fichier :" + +msgid "Show entries containing this media" +msgstr "Afficher les billets contenant ce média" + +msgid "Entries containing this media" +msgstr "Billets contenant ce média" + +msgid "No entry seems contain this media." +msgstr "Aucun billet ne semble contenir ce média." + +msgid "Image details" +msgstr "Détails de l'image" + +msgid "No detail" +msgstr "Aucun détail" + +msgid "Update thumbnails" +msgstr "Mettre à jour les miniatures" + +msgid "This will create or update thumbnails for this image." +msgstr "Ceci va créer ou mettre à jour les miniatures pour cette image." + +msgid "update thumbnails" +msgstr "mettre à jour les miniatures" + +msgid "Extract in a new directory" +msgstr "Extraire dans un nouveau répertoire" + +msgid "Extract in current directory" +msgstr "Extraire dans le répertoire actuel" + +msgid "Extract archive" +msgstr "Extraire l'archive" + +msgid "This will extract archive in a new directory that should not exists yet." +msgstr "Ceci va extraire l'archive dans un nouveau répertoire qui ne doit pas encore exister." + +msgid "This will extract archive in current directory and will overwrite existing files or directory." +msgstr "Ceci va extraire l'archive dans le répertoire actuel et va écraser les fichiers ou répertoires existants." + +msgid "Extract mode:" +msgstr "Mode d'extraction :" + +msgid "extract" +msgstr "extraire" + +msgid "Change media properties" +msgstr "Changer les propriétés du média" + +msgid "File name:" +msgstr "Nom du fichier :" + +msgid "File title:" +msgstr "Titre du fichier :" + +msgid "File date:" +msgstr "Date du fichier :" + +msgid "New directory:" +msgstr "Nouveau répertoire :" + +msgid "Change file" +msgstr "Changer le fichier" + +msgid "No blog or user given." +msgstr "Vous n'avez pas indiqué de blog ou d'utilisateur" + +msgid "permissions" +msgstr "permissions" + +msgid "Permissions" +msgstr "Permissions" + +msgid "The permissions have been successfully updated." +msgstr "Permissions mises à jour avec succès." + +#, php-format +msgid "You are about to change permissions on the following blogs for users %s." +msgstr "Vous allez changer les permissions des utilisateurs %s pour ces blogs." + +msgid "choose a blog" +msgstr "choisissez un blog" + +msgid "Choose a blog" +msgstr "Choisissez un blog" + +msgid "Entries per page" +msgstr "Billets par page" + +#, php-format +msgid "Choose one or more blogs to which you want to give permissions to users %s." +msgstr "Choisissez un ou plusieurs blogs pour lesquels les utilisateurs suivants auront des permissions : %s." + +msgid "set permissions" +msgstr "définir les permissions" + +msgid "No content found on this plugin." +msgstr "Aucun contenu pour cette extension." + +msgid "Plugin not found" +msgstr "Extension introuvable" + +msgid "The plugin you reached does not exist or does not have an admin page." +msgstr "L'extension que vous essayez d'atteindre n'existe pas ou n'a pas de page d'administration." + +msgid "No such plugin." +msgstr "Extension inexistante." + +msgid "You don't have permissions to delete this plugin." +msgstr "Vous n'avez pas les permissions pour effacer cette extension" + +msgid "You don't have permissions to deactivate this plugin." +msgstr "Vous n'avez pas les permissions pour désactiver cette extension." + +msgid "Plugins management" +msgstr "Gestion des extensions" + +msgid "Plugin has been successfully deleted." +msgstr "L'extension a été supprimée avec succès." + +msgid "Plugin has been successfully installed." +msgstr "L'extension a été installée avec succès." + +msgid "Plugin has been successfully upgraded" +msgstr "L'extension a été mise à jour avec succès." + +msgid "Plugins add new functionalities to Dotclear. Here you can activate or deactivate installed plugins." +msgstr "Les extensions ajoutent de nouvelles fonctionnalités à Dotclear. Ici, vous pouvez activer ou désactiver les extensions installées." + +#, php-format +msgid "You can find additional plugins for your blog on %s." +msgstr "Vous pouvez trouver de nouvelles extensions pour votre blog sur %s." + +msgid "To install or upgrade a plugin you generally just need to upload it in \"Install or upgrade a plugin\" section." +msgstr "Tout ce que vous avez à faire pour installer ou mettre à jour une extension est généralement de la déposer dans la section \"Installer ou mettre à jour une extension\"." + +msgid "To install or upgrade a plugin you just need to extract it in your plugins directory." +msgstr "Tout ce que vous avez à faire pour installer une extension est de l'extraire dans votre répertoire d'extensions." + +msgid "Plugins" +msgstr "Extensions" + +msgid "Activated plugins" +msgstr "Extensions activées" + +msgid "Plugin" +msgstr "Extension" + +msgid "Version" +msgstr "Version" + +msgid "Details" +msgstr "Détails" + +msgid "Deactivate" +msgstr "Désactiver" + +msgid "Deactivated plugins" +msgstr "Extensions désactivées" + +msgid "Activate" +msgstr "Activer" + +msgid "Install or upgrade a plugin" +msgstr "Installer ou mettre à jour une extension" + +msgid "You can install plugins by uploading or downloading zip files." +msgstr "Vous pouvez installer des extensions en déposant ou téléchargeant des fichiers zip." + +msgid "Plugin zip file:" +msgstr "Fichier zip de l'extension :" + +msgid "Upload plugin" +msgstr "Déposer l'extension" + +msgid "Plugin zip file URL:" +msgstr "URL du fichier zip de l'extension :" + +msgid "Download plugin" +msgstr "Télécharger l'extension" + +msgid "To enable this function, please give write access to your plugins directory." +msgstr "Pour activer cette fonction, donnez un accès en écriture à votre répertoire d'extensions." + +msgid "Add a link" +msgstr "Ajouter un lien" + +msgid "Available" +msgstr "Disponible" + +msgid "Most used" +msgstr "Plus utilisées" + +msgid "Link URL:" +msgstr "URL du lien :" + +msgid "Link language:" +msgstr "Langue du lien :" + +msgid "insert" +msgstr "insérer" + +msgid "Add a link to an entry" +msgstr "Ajouter un lien vers un billet" + +msgid "Search entry:" +msgstr "Rechercher un billet :" + +msgid "This entry does not exist." +msgstr "Ce billet n'existe pas." + +msgid "Edit entry" +msgstr "Modifier le billet" + +msgid "next entry" +msgstr "billet suivant" + +msgid "previous entry" +msgstr "billet précédent" + +msgid "Entry has been successfully updated." +msgstr "Billet mis à jour avec succès." + +msgid "Entry has been successfully created." +msgstr "Billet créé avec succès." + +msgid "File has been successfully attached." +msgstr "Fichier attaché avec succès." + +msgid "Attachment has been successfully removed." +msgstr "Pièce jointe retirée avec succès." + +msgid "Comment has been successfully created." +msgstr "Commentaire créé avec succès." + +msgid "Don't forget to validate your XHTML conversion by saving your post." +msgstr "Enregistrez votre billet pour valider la transformation en XHTML." + +msgid "View entry" +msgstr "Voir le billet" + +msgid "Preview entry" +msgstr "Prévisualiser le billet" + +msgid "Entry status:" +msgstr "État du billet :" + +msgid "Published on:" +msgstr "Publié le :" + +msgid "Text formating:" +msgstr "Format du texte :" + +msgid "Convert to XHTML" +msgstr "Convertir en XHTML" + +msgid "Selected entry" +msgstr "Billet sélectionné" + +msgid "Entry lang:" +msgstr "Langue du billet :" + +msgid "Entry password:" +msgstr "Mot de passe du billet :" + +msgid "Basename:" +msgstr "URL spécifique :" + +msgid "Warning: If you set the URL manually, it may conflict with another entry." +msgstr "Attention : si vous indiquez l'URL manuellement, celle-ci peut entrer en conflit avec un autre billet." + +msgid "Attachments" +msgstr "Pièces jointes" + +msgid "remove" +msgstr "supprimer" + +msgid "No attachment." +msgstr "Aucune pièce jointe" + +msgid "Add files to this entry" +msgstr "Ajouter un fichier au billet" + +msgid "Excerpt:" +msgstr "Extrait :" + +msgid "Notes:" +msgstr "Notes :" + +msgid "Ping blogs" +msgstr "Faire des rétroliens" + +msgid "Trackbacks" +msgstr "Rétroliens" + +msgid "No trackback" +msgstr "Aucun rétrolien" + +msgid "Add a comment" +msgstr "Ajouter un commentaire" + +msgid "Name:" +msgstr "Nom :" + +msgid "IP address" +msgstr "Adresse IP" + +msgid "published" +msgstr "publié" + +msgid "unpublished" +msgstr "non publié" + +msgid "pending" +msgstr "en attente" + +msgid "junk" +msgstr "indésirable" + +msgid "Edit this comment" +msgstr "Modifier ce commentaire" + +msgid "This attachment does not exist" +msgstr "Cette pièce jointe n'existe pas" + +msgid "Remove attachment" +msgstr "Supprimer la pièce jointe" + +msgid "Attachment" +msgstr "Pièce jointe" + +msgid "Are you sure you want to remove this attachment?" +msgstr "Êtes-vous certain de vouloir supprimer cette pièce jointe ?" + +msgid "selected" +msgstr "sélectionné" + +msgid "not selected" +msgstr "non sélectionné" + +msgid "Category" +msgstr "Catégorie" + +msgid "Selected" +msgstr "Sélectionné" + +msgid "schedule" +msgstr "programmer" + +msgid "mark as selected" +msgstr "marquer sélectionné" + +msgid "mark as unselected" +msgstr "marquer non sélectionné" + +msgid "change category" +msgstr "changer la catégorie" + +msgid "change author" +msgstr "changer l'auteur" + +msgid "Selected:" +msgstr "Sélectionné :" + +msgid "Month:" +msgstr "Mois :" + +msgid "Lang:" +msgstr "Langue :" + +msgid "Selected entries action:" +msgstr "Action sur les billets sélectionnés :" + +msgid "This user does not exist" +msgstr "Cet utilisateur n'existe pas" + +msgid "Change category for entries" +msgstr "Changer de catégorie pour les billets" + +msgid "Change author for entries" +msgstr "Changer l'auteur des billets" + +msgid "Author ID:" +msgstr "Identifiant de l'utilisateur" + +msgid "If you want to change your email or password you must provide your current password." +msgstr "Si vous voulez changer votre adresse email ou votre mot de passe, vous devez indiquer votre mot de passe." + +msgid "Personal information has been successfully updated." +msgstr "Informations personnelles mises à jour avec succès." + +msgid "Display name:" +msgstr "Pseudonyme :" + +msgid "Preferred format:" +msgstr "Format d'édition préféré :" + +msgid "Default entry status:" +msgstr "État des billets par défaut :" + +msgid "Entry edit field height:" +msgstr "Taille de la zone d'édition :" + +msgid "User language:" +msgstr "Langue de l'utilisateur :" + +msgid "User timezone:" +msgstr "Fuseau horaire de l'utilisateur :" + +msgid "Enable WYSIWYG mode" +msgstr "Activer l'éditeur visuel" + +msgid "Change your password" +msgstr "Changer votre mot de passe" + +msgid "New password:" +msgstr "Nouveau mot de passe :" + +msgid "Search" +msgstr "Rechercher" + +msgid "Search options" +msgstr "Options de recherche" + +msgid "Query:" +msgstr "Requête :" + +msgid "search entries" +msgstr "rechercher des billets" + +msgid "search comments" +msgstr "recherche des commentaires" + +#, php-format +msgid "%d entries found" +msgstr "%d billets trouvés" + +#, php-format +msgid "%d entry found" +msgstr "%d billet trouvé" + +#, php-format +msgid "%d comment found" +msgstr "%d commentaire trouvé" + +#, php-format +msgid "%d comments found" +msgstr "%d commentaires trouvés" + +msgid "This entry does not exist or is not published" +msgstr "Ce billet n'existe pas ou n'est pas publié" + +msgid "All pings sent." +msgstr "Tous les rétroliens ont été envoyés." + +msgid "Auto discover ping URLs" +msgstr "Découverte automatique des URL à rétrolier" + +msgid "URLs to ping:" +msgstr "URLs à rétrolier :" + +msgid "Send excerpt:" +msgstr "Envoyer l'extrait :" + +msgid "Previously sent pings" +msgstr "Rétroliens déjà envoyés" + +msgid "Dotclear update" +msgstr "Mise à jour de Dotclear" + +#, php-format +msgid "Unable to delete file %s" +msgstr "Impossible de supprimer le fichier %s" + +#, php-format +msgid "Downloaded Dotclear archive seems to be corrupted. Try download it again." +msgstr "L'archive téléchargée de Dotclear semble être corrompue. Essayer de la télécharger à nouveau." + +msgid "The following files of your Dotclear installation have been modified so we won't try to update your installation. Please try to update manually." +msgstr "Comme les fichiers suivants de votre installation de Dotclear ont été modifiés, votre installation ne peut être mise à jour. Merci de mettre à jour manuellement." + +#, php-format +msgid "The following files of your Dotclear installation are not readable. Please fix this or try to make a backup file named %s manually." +msgstr "Les fichiers suivants de votre installation de Dotclear ne peuvent pas être lus. Veuillez corriger ceci ou créer un fichier de backup nommé %s manuellement." + +msgid "The following files of your Dotclear installation cannot be written. Please fix this or try to update manually." +msgstr "Les fichiers suivants de votre installation de Dotclear ne peuvent pas être écrits. Veuillez corriger ceci ou mettre à jour manuellement." + +msgid "No newer Dotclear version available." +msgstr "Aucune nouvelle version de Dotclear n'est disponible." + +#, php-format +msgid "Dotclear %s is available." +msgstr "Dotclear %s est disponible." + +msgid "To upgrade your Dotclear installation simply click on the following button. A backup file of your current installation will be created in your root directory." +msgstr "Pour mettre à jour votre installation de Dotclear, cliquez sur le bouton suivant. Un fichier de sauvegarde de votre installation actuelle sera créé dans votre répertoire principal." + +msgid "Update Dotclear" +msgstr "Mettre à jour Dotclear" + +msgid "Update backup files" +msgstr "Sauvegardes des mises à jour" + +msgid "The following files are backups of previously updates. You can revert your previous installation or delete theses files." +msgstr "Les fichiers suivants sont des sauvegardes de mises à jour précédentes. Vous pouvez rétablir votre installation précédente ou supprimer ces fichiers." + +msgid "Please note that reverting your Dotclear version may have some unwanted side-effects. Consider reverting only if you experience strong issues with this new version." +msgstr "Merci de noter que rétablir votre version de Dotclear peut avoir des effets non désirés. N'envisagez ceci que si vous rencontrez d'importantes difficultés avec cette nouvelle version." + +#, php-format +msgid "You should not revert to version prior to last one (%s)." +msgstr "Vous ne devez pas rétablir une version précédant la dernière (%s)." + +msgid "Delete selected file" +msgstr "Supprimer le fichier sélectionné" + +msgid "Revert to selected file" +msgstr "Rétablir le fichier sélectionné" + +msgid "Congratulations, you're one click away from the end of the update." +msgstr "Félicitations, vous êtes à un clic de la fin de la mise à jour." + +msgid "Finish the update." +msgstr "Finir la mise à jour." + +msgid "new user" +msgstr "nouvel utilisateur" + +#, php-format +msgid "User \"%s\" already exists." +msgstr "L'utilisateur \"%s\" existe déjà." + +msgid "User has been successfully updated." +msgstr "Utilisateur mis à jour avec succès." + +msgid "User has been successfully created." +msgstr "Utilisateur créé avec succès." + +msgid "Warning:" +msgstr "Attention :" + +msgid "If you change your username, you will have to log in again." +msgstr "Si vous changez votre login, vous devrez vous identifier à nouveau." + +msgid "No permissions." +msgstr "Aucune permission." + +msgid "Add new permissions" +msgstr "Ajouter de nouvelles permissions" + +msgid "Username" +msgstr "Identifiant :" + +msgid "Last Name" +msgstr "Nom" + +msgid "First Name" +msgstr "Prénom" + +msgid "Display name" +msgstr "Pseudonyme" + +msgid "Number of entries" +msgstr "Nombre de billets" + +msgid "users" +msgstr "utilisateurs" + +msgid "User has been successfully removed." +msgstr "Utilisateur supprimé avec succès." + +msgid "Create a new user" +msgstr "Créer un nouvel utilisateur" + +msgid "Users per page" +msgstr "Utilisateurs par page" + +msgid "Selected users action:" +msgstr "Action sur les utilisateurs sélectionnés :" + +msgid "Set permissions" +msgstr "Définir les permissions" + +msgid "Blog:" +msgstr "Blog :" + +msgid "Change blog" +msgstr "Changer de blog" + +msgid "Blogs:" +msgstr "Blogs :" + +msgid "View site" +msgstr "Voir le site" + +msgid "User:" +msgstr "Utilisateur :" + +msgid "Logout" +msgstr "Déconnexion" + +#, php-format +msgid "Thank you for using %s." +msgstr "Merci d'utiliser %s." + +msgid "Help" +msgstr "Aide" + +msgid "uncover" +msgstr "dévoiler" + +msgid "hide" +msgstr "cacher" + +msgid "help" +msgstr "aide" + +msgid "No selection" +msgstr "Aucune sélection" + +msgid "select all" +msgstr "tout sélectionner" + +msgid "invert selection" +msgstr "inverser la sélection" + +msgid "view entry" +msgstr "voir le billet" + +msgid "Are you sure you want to delete selected entries?" +msgstr "Êtes-vous certain de vouloir supprimer les billets sélectionnés ?" + +msgid "Are you sure you want to delete this entry?" +msgstr "Êtes-vous certain de vouloir supprimer ce billet ?" + +msgid "Are you sure you want to delete selected comments?" +msgstr "Êtes-vous certain de vouloir supprimer les commentaires sélectionnés ?" + +msgid "Are you sure you want to delete this comment?" +msgstr "Êtes-vous certain de vouloir supprimer ce commentaire ?" + +msgid "Users with posts cannot be deleted." +msgstr "Les utilisateurs ayant écrit des billets ne peuvent être effacées." + +msgid "Are you sure you want to delete selected users?" +msgstr "Êtes-vous certain de vouloir supprimer les utilisateurs sélectionnés ?" + +#, php-format +msgid "Are you sure you want to delete category \"%s\"?" +msgstr "Êtes-vous certain de vouloir supprimer la catégorie \"%s\" ?" + +msgid "Are you sure you want to reorder all categories?" +msgstr "Êtes-vous certain de vouloir réinitialiser l'ordre des catégories ?" + +#, php-format +msgid "Are you sure you want to remove media \"%s\"?" +msgstr "Êtes-vous certain de vouloir supprimer le média \"%s\" ?" + +msgid "Are you sure you want to extract archive in current directory?" +msgstr "Êtes-vous certain de vouloir extraire l'archive dans le répertoire actuel ?" + +#, php-format +msgid "Are you sure you want to remove attachment \"%s\"?" +msgstr "Êtes-vous certain de vouloir supprimer la pièce jointe \"%s\" ?" + +#, php-format +msgid "Are you sure you want to delete \"%s\" language?" +msgstr "Êtes-vous certain de vouloir supprimer la langue \"%s\" ?" + +#, php-format +msgid "Are you sure you want to delete \"%s\" plugin?" +msgstr "Êtes-vous certain de vouloir supprimer l'extension \"%s\" ?" + +msgid "Use this theme" +msgstr "Utiliser ce thème" + +msgid "Remove this theme" +msgstr "Supprimer ce thème" + +#, php-format +msgid "Are you sure you want to delete \"%s\" theme?" +msgstr "Êtes-vous certain de vouloir supprimer le thème \"%s\" ?" + +msgid "Zip file content" +msgstr "Contenu du fichier zip" + +msgid "XHTML markup validator" +msgstr "Validation XHTML" + +msgid "XHTML content is valid." +msgstr "Le contenu XHTML est valide." + +msgid "There are XHTML markup errors." +msgstr "Il y a des erreurs XHTML." + +msgid "You have unsaved changes." +msgstr "Vous n'avez pas enregistré vos modifications." + +msgid "close" +msgstr "fermer" + +msgid "now" +msgstr "maintenant" + +msgid "visual" +msgstr "visuel" + +msgid "source" +msgstr "source" + +msgid "You can use the following shortcuts to format your text." +msgstr "Vous pouvez utiliser les raccourcis suivants pour formater votre texte." + +msgid "-- none --" +msgstr "-- aucun --" + +msgid "-- block format --" +msgstr "-- format bloc --" + +msgid "Paragraph" +msgstr "Paragraphe" + +msgid "Level 1 header" +msgstr "Titre de niveau 1" + +msgid "Level 2 header" +msgstr "Titre de niveau 2" + +msgid "Level 3 header" +msgstr "Titre de niveau 3" + +msgid "Level 4 header" +msgstr "Titre de niveau 4" + +msgid "Level 5 header" +msgstr "Titre de niveau 5" + +msgid "Level 6 header" +msgstr "Titre de niveau 6" + +msgid "Strong emphasis" +msgstr "Forte emphase" + +msgid "Emphasis" +msgstr "Emphase" + +msgid "Inserted" +msgstr "Insertion" + +msgid "Deleted" +msgstr "Suppression" + +msgid "Inline quote" +msgstr "Citation en ligne" + +msgid "Code" +msgstr "Code" + +msgid "Line break" +msgstr "Passage à la ligne" + +msgid "Blockquote" +msgstr "Bloc de citation" + +msgid "Preformated text" +msgstr "Texte préformaté" + +msgid "Unordered list" +msgstr "Liste à puces" + +msgid "Ordered list" +msgstr "Liste numérotée" + +msgid "Link" +msgstr "Lien" + +msgid "URL?" +msgstr "URL ?" + +msgid "Language?" +msgstr "Langue ?" + +msgid "External image" +msgstr "Image externe" + +msgid "Media chooser" +msgstr "Sélecteur de média" + +msgid "Link to an entry" +msgstr "Lien vers un billet" + +msgid "Activate enhanced uploader" +msgstr "Activer l'interface avancée" + +msgid "Disable enhanced uploader" +msgstr "Désactiver l'interface avancée" + +msgid "File successfully uploaded." +msgstr "Fichier envoyé avec succès." + +msgid "Maximum file size allowed:" +msgstr "Taille maximale de fichier autorisée :" + +msgid "Limit exceeded." +msgstr "Limite dépassée." + +msgid "File size exceeds allowed limit." +msgstr "La taille du fichier dépasse la limite autorisée." + +msgid "Canceled." +msgstr "Annulé." + +msgid "HTTP Error:" +msgstr "Erreur HTTP :" + +msgid "Choose file" +msgstr "Choisir un fichier" + +msgid "Choose files" +msgstr "Choisir des fichiers" + +msgid "Clean" +msgstr "Nettoyer" + +msgid "Upload" +msgstr "Envoyer" + +msgid "No file in queue." +msgstr "Aucun fichier en file d'attente." + +msgid "1 file in queue." +msgstr "1 fichier en attente." + +#, php-format +msgid "%d files in queue." +msgstr "%d fichiers en attente." + +msgid "Queue error:" +msgstr "Erreur de file d'attente :" + +msgid "«prev." +msgstr "«préc." + +msgid "next»" +msgstr "suiv.»" + +msgid "No entry" +msgstr "Pas de billet" + +msgid "scheduled" +msgstr "programmé" + +msgid "protected" +msgstr "protégé" + +#, php-format +msgid "%d attachment" +msgstr "%d annexe" + +#, php-format +msgid "%d attachments" +msgstr "%d annexes" + +msgid "Type" +msgstr "Type" + +msgid "No user" +msgstr "Pas d'utilisateur" + +msgid "System" +msgstr "Système" + +msgid "Blog" +msgstr "Blog" + +msgid "Updates" +msgstr "Mises à jour" + +msgid "Languages" +msgstr "Langues" + +msgid "Unable to open directory." +msgstr "Impossible d'ouvrir le répertoire." + +msgid "Unable to create directory." +msgstr "Impossible de créer le répertoire." + +msgid "File is not writable." +msgstr "Le fichier n'est pas accessible en écriture." + +msgid "Unable to open file." +msgstr "Impossible d'ouvrir le fichier." + +# pas compris +msgid "Not an uploaded file." +msgstr "Pas un fichier déposé." + +msgid "The uploaded file exceeds the maximum file size allowed." +msgstr "Le fichier déposé est plus grand que la taille maximale autorisée." + +msgid "The uploaded file was only partially uploaded." +msgstr "Le fichier n'a été chargé qu'en partie." + +msgid "No file was uploaded." +msgstr "Aucun fichier chargé." + +msgid "Missing a temporary folder." +msgstr "Il manque un répertoire temporaire." + +msgid "Failed to write file to disk." +msgstr "Impossible d'écrire le fichier." + +#, php-format +msgid "%s is not a directory." +msgstr "%s n'est pas un répertoire." + +msgid "Uploading this file is not allowed." +msgstr "L'envoi de ce fichier n'est pas autorisé." + +# "en jail" ? c'est du geek ? +msgid "Destination directory is not in jail." +msgstr "Le répertoire cible n'est pas en jail." + +msgid "File already exists." +msgstr "Le nouveau fichier existe déjà." + +msgid "Cannot write in this directory." +msgstr "Impossible d'écrire dans ce répertoire." + +msgid "An error occurred while writing the file." +msgstr "Une erreur est survenue pendant l'écriture du fichier." + +msgid "Source file does not exist." +msgstr "Le fichier source n'existe pas" + +# geek ? +msgid "File is not in jail." +msgstr "Le fichier n'est pas en jail." + +msgid "Destination directory is not writable." +msgstr "Le répertoire cible n'est pas accessible en écriture." + +msgid "Unable to rename file." +msgstr "Impossible de renommer le fichier." + +msgid "File cannot be removed." +msgstr "Ce fichier ne peut pas être supprimé." + +# décidément ! mais que veut dire "jail" ? +msgid "Directory is not in jail." +msgstr "Le répertoire n'est pas en jail." + +msgid "Directory cannot be removed." +msgstr "Ce répertoire ne peut pas être supprimé." + +msgid "Not enough memory to open image." +msgstr "Mémoire insuffisante pour ouvrir l'image." + +#, php-format +msgid "File %s is not compressed in the zip." +msgstr "Le fichier %s n'est pas compressé dans le zip." + +#, php-format +msgid "Trying to unzip a folder name %s" +msgstr "Tentative de décompresser un répertoire %s" + +msgid "Unable to write destination file." +msgstr "Impossible d'écrire le fichier de destination" + +msgid "Unable to write in target directory, permission denied." +msgstr "Impossible d'écrire dans le répertoire cible, permission refusée." + +msgid "Not enough memory to open file." +msgstr "Mémoire insuffisante pour ouvrir le fichier." + +msgid "File does not exist" +msgstr "Le fichier n'existe pas" + +msgid "Cannot read file" +msgstr "Impossible de lire le fichier" + +msgid "Directory does not exist" +msgstr "Le répertoire n'existe pas" + +msgid "Cannot read directory" +msgstr "Impossible de lire le répertoire" + +msgid "administrator" +msgstr "administrateur" + +msgid "manage their own entries and comments" +msgstr "gérer ses propres billets et commentaires" + +msgid "publish entries and comments" +msgstr "publier des billets et des commentaires" + +msgid "delete entries and comments" +msgstr "supprimer des billets et des commentaires" + +msgid "manage all entries and comments" +msgstr "gérer tous les billets et commentaires" + +msgid "manage categories" +msgstr "gérer les catégories" + +msgid "manage their own media items" +msgstr "gérer ses propres médias" + +msgid "manage all media items" +msgstr "gérer tous les médias" + +msgid "That user does not exist in the database." +msgstr "Cet utilisateur n'existe pas dans la base de données." + +msgid "That key does not exist in the database." +msgstr "Cette clé n'existe pas dans la base de données." + +msgid "You are not allowed to add categories" +msgstr "Vous n'êtes pas autorisé à créer des catégories" + +msgid "You are not allowed to update categories" +msgstr "Vous n'êtes pas autorisé à modifier des catégories" + +msgid "You are not allowed to delete categories" +msgstr "Vous n'êtes pas autorisé à supprimer des catégories" + +msgid "This category is not empty." +msgstr "Cette catégorie n'est pas vide." + +msgid "Category URL must be unique." +msgstr "L'URL de chaque catégorie doit être unique." + +msgid "You must provide a category title" +msgstr "Vous devez indiquer un titre de catégorie" + +msgid "You must provide a category URL" +msgstr "Vous devez indiquer une URL de catégorie" + +msgid "You are not allowed to create an entry" +msgstr "Vous n'êtes pas autorisé à créer des billets" + +msgid "You are not allowed to update entries" +msgstr "Vous n'êtes pas autorisé à modifier les billets" + +msgid "No such entry ID" +msgstr "Identifiant du billet inconnu" + +msgid "You are not allowed to edit this entry" +msgstr "Vous n'êtes pas autorisé à modifier ce billet" + +msgid "You are not allowed to change this entry status" +msgstr "Vous n'êtes pas autorisé à modifier l'état de ce billet" + +msgid "You are not allowed to change this entry category" +msgstr "Vous n'êtes pas autorisé à modifier la catégorie de ce billet" + +msgid "You are not allowed to mark this entry as selected" +msgstr "Vous n'êtes pas autorisé à marquer ce billet comme sélectionné" + +msgid "You are not allowed to delete entries" +msgstr "Vous n'êtes pas autorisé à supprimer des billets" + +msgid "You are not allowed to delete this entry" +msgstr "Vous n'êtes pas autorisé à supprimer ce billet" + +msgid "No entry title" +msgstr "Pas de titre de billet" + +msgid "No entry content" +msgstr "Pas de contenu de billet" + +msgid "Empty entry URL" +msgstr "URL du billet vide" + +msgid "You are not allowed to update comments" +msgstr "Vous n'êtes pas autorisé à modifier des commentaires" + +msgid "No such comment ID" +msgstr "Identifiant du commentaire inconnu" + +msgid "You are not allowed to update this comment" +msgstr "Vous n'êtes pas autorisé à modifier ce commentaire" + +msgid "You are not allowed to change this comment's status" +msgstr "Vous n'êtes pas autorisé à changer l'état de ce commentaire" + +msgid "You are not allowed to delete comments" +msgstr "Vous n'êtes pas autorisé à supprimer des commentaires" + +msgid "You are not allowed to delete this comment" +msgstr "Vous n'êtes pas autorisé à supprimer ce commentaire" + +msgid "You must provide a comment" +msgstr "Vous devez indiquer un commentaire" + +msgid "You must provide an author name" +msgstr "Vous devez indiquer un nom d'auteur" + +msgid "Email address is not valid." +msgstr "Adresse email invalide." + +msgid "online" +msgstr "en ligne" + +msgid "offline" +msgstr "hors ligne" + +msgid "removed" +msgstr "supprimé" + +msgid "You are not an administrator" +msgstr "Vous n'êtes pas administrateur" + +msgid "Invalid user language code" +msgstr "Code langue de l'utilisateur invalide" + +msgid "Blog ID must contain at least 2 characters using letters, numbers or symbols." +msgstr "L'identifiant du blog doit contenir au moins 2 caractères composés de lettres, chiffres ou symboles." + +msgid "No blog name" +msgstr "Pas de nom de blog" + +msgid "No blog URL" +msgstr "Pas d'URL de blog" + +msgid "No blog defined." +msgstr "Aucun blog défini." + +#, php-format +msgid "Directory %s does not exist." +msgstr "Le répertoire %s n'existe pas." + +msgid "You are not a super administrator." +msgstr "Vous n'êtes pas super administrateur." + +msgid "Permission denied." +msgstr "Permission refusée." + +msgid "You are not the file owner." +msgstr "Vous n'êtes pas le propriétaire de ce fichier." + +msgid "New file already exists." +msgstr "Le nouveau fichier existe déjà." + +msgid "File does not exist in the database." +msgstr "Ce fichier n'existe pas dans la base de données." + +#, php-format +msgid "Extract destination directory %s already exists." +msgstr "Le répertoire de destination d'extraction %s existe déjà." + +msgid "Empty module zip file." +msgstr "Fichier zip de module vide." + +msgid "The zip file does not appear to be a valid Dotclear module." +msgstr "Le fichier zip ne semble pas être un fichier valide de module Dotclear." + +msgid "An error occurred during module deletion." +msgstr "Une erreur est survenue durant la suppression du module." + +#, php-format +msgid "Unable to upgrade \"%s\". (same version)" +msgstr "Impossible de mettre à jour \"%s\" (même version)." + +msgid "Unable to read new _define.php file" +msgstr "Impossible de lire le nouveau fichier _define.php." + +msgid "No such module." +msgstr "Module inexistant." + +msgid "Cannot remove module files" +msgstr "Impossible de supprimer les fichiers du module" + +msgid "Cannot deactivate plugin." +msgstr "L'extension ne peut pas être désactivée." + +msgid "Cannot activate plugin." +msgstr "L'extension ne peut pas être activée." + +msgid "Unable to retrieve settings:" +msgstr "Impossible d'obtenir les paramètres :" + +#, php-format +msgid "Invalid setting namespace: %s" +msgstr "Espace de nommage du paramètre invalide : %s" + +msgid "No namespace specified" +msgstr "Aucun espace de nommage spécifié" + +#, php-format +msgid "%s is not a valid setting id" +msgstr "%s n'est pas un identifiant de paramètre valide" + +#, php-format +msgid "%s has still been pinged" +msgstr "Un rétrolien vers %s a déjà été fait" + +msgid "Unable to ping URL" +msgstr "Impossible de réaliser le rétrolien" + +#, php-format +msgid "%s is not a ping URL" +msgstr "%s n'est pas une URL de rétrolien" + +#, php-format +msgid "%s, ping error:" +msgstr "%s, erreur de rétrolien :" + +msgid "Digests file not found." +msgstr "Fichier de contrôle introuvable." + +msgid "No file to download" +msgstr "Aucun fichier à télécharger." + +msgid "Root directory is not writable." +msgstr "Le répertoire principal n'est pas accessible en écriture." + +msgid "An error occurred while downloading archive." +msgstr "Une erreur est survenue lors du téléchargement de l'archive." + +msgid "Archive not found." +msgstr "L'archive n'a pas été trouvée." + +msgid "Unable to read current digests file." +msgstr "Impossible de lire le fichier de contrôle actuel." + +msgid "Downloaded file seems not to be a valid archive." +msgstr "Le fichier téléchargé ne semble pas être une archive valide." + +msgid "Incomplete archive." +msgstr "Archive incomplète." + +msgid "Unable to read digests file." +msgstr "Impossible de lire le fichier de contrôle." + +msgid "Invalid digests file." +msgstr "Fichier de contrôle invalide." + +msgid "SQLite Database Schema cannot be upgraded." +msgstr "Le schema de base de données SQLite ne peut pas être mis à jour." + +msgid "Something went wrong with auto upgrade:" +msgstr "Une erreur est survenue durant la mise à jour automatique :" + +#~ msgid "Login:" +#~ msgstr "Login :" +#~ msgid "Login and password" +#~ msgstr "Identifiant et mot de passe" +#~ msgid "User ID" +#~ msgstr "Identifiant utilisateur" +#~ msgid "Name" +#~ msgstr "Nom" + diff --git a/locales/fr/plugins.lang.php b/locales/fr/plugins.lang.php new file mode 100644 index 0000000..e84f570 --- /dev/null +++ b/locales/fr/plugins.lang.php @@ -0,0 +1,457 @@ +DC1 redirect plugin and activate it in your blog configuration.'] = 'Veuillez noter que Dotclear 2 a un nouveau format d\'URL. Vous pouvez éviter les liens morts en installant le plugin DC1 redirect et en l\'activant dans la configuration de votre blog.'; +$GLOBALS['__l10n']['next step'] = 'étape suivante'; +$GLOBALS['__l10n']['Dotclear tables not found'] = 'Tables Dotclear non trouvées'; +$GLOBALS['__l10n']['Feed import'] = 'Importer depuis un flux'; +$GLOBALS['__l10n']['Imports a feed as new entries.'] = 'Importe un flux comme nouveaux billets.'; +$GLOBALS['__l10n']['Cannot retrieve feed URL.'] = 'Impossible d\'atteindre l\'URL du fil.'; +$GLOBALS['__l10n']['No items in feed.'] = 'Aucun élément dans le feed.'; +$GLOBALS['__l10n']['Content successfully imported.'] = 'Contenu importé avec succès.'; +$GLOBALS['__l10n']['Import from a feed'] = 'Importer depuis un fil de nouvelles'; +$GLOBALS['__l10n']['This will import a feed (RSS or Atom) a as new content in the current blog: %s.'] = 'Ceci va importer un fil (RSS ou Atom) comme un nouveau contenu dans le blog en cours : %s.'; +$GLOBALS['__l10n']['Feed URL:'] = 'URL du fil'; +$GLOBALS['__l10n']['Send'] = 'Envoyer'; +$GLOBALS['__l10n']['Flat file import'] = 'Importer depuis un fichier texte'; +$GLOBALS['__l10n']['Imports a blog or a full Dotclear installation from flat file.'] = 'Importe un blog ou toutes les données depuis un fichier texte.'; +$GLOBALS['__l10n']['Single blog successfully imported.'] = 'Blog importé avec succès.'; +$GLOBALS['__l10n']['Are you sure you want to import a full backup file?'] = 'Êtes-vous certain de vouloir charger un fichier de sauvegarde complet ?'; +$GLOBALS['__l10n']['Import a single blog'] = 'Importer un blog'; +$GLOBALS['__l10n']['This will import a single blog backup as new content in the current blog: %s.'] = 'Ceci va charger une sauvegarde de blog comme un nouveau contenu dans le blog en cours : %s.'; +$GLOBALS['__l10n']['Upload a backup file'] = 'Charger un fichier de sauvegarde'; +$GLOBALS['__l10n']['or pick up a local file in your public directory'] = 'ou choisissez un fichier local dans votre répertoire public'; +$GLOBALS['__l10n']['Import a full backup file'] = 'Import d\'un fichier de sauvegarde complet'; +$GLOBALS['__l10n']['Warning: This will reset all the content of your database, except users.'] = 'Attention : Ceci va remettre à zéro tout le contenu, sauf les utilisateurs.'; +$GLOBALS['__l10n']['WordPress import'] = 'Importer depuis WordPress'; +$GLOBALS['__l10n']['Import a WordPress installation into your current blog.'] = 'Importe un blog WordPress dans votre blog en cours.'; +$GLOBALS['__l10n']['This will import your WordPress content as new content in the current blog: %s.'] = 'Ceci va importer votre blog WordPress comme un nouveau contenu dans le blog en cours : %s.'; +$GLOBALS['__l10n']['We first need some information about your old WordPress installation.'] = 'Nous avons d\'abord besoin de renseignements à propos de votre ancienne installation WordPress.'; +$GLOBALS['__l10n']['WordPress and Dotclear\'s handling of categories are quite different. You can assign several categories to a single post in WordPress. In the Dotclear world, we see it more like "One category, several tags." Therefore Dotclear can only import one category per post and will chose the lowest numbered one. If you want to keep a trace of every category, you can import them as tags, with an optional prefix.'] = 'WordPress et Dotclear gèrent les catégories différemment. Dans WordPress, un article peut être classé dans plusieurs catégories, alors que dans Dotclear, on voit ça plutôt comme "Une catégorie, plusieurs mots-clefs." Dotclear ne peut donc importer qu\'une seule catégorie par article et choisira dans ce cas la première créée. Si vous désirez garder une trace de chaque catégorie, vous pouvez les importer en tant que mots-clefs, avec un préfixe optionnel.'; +$GLOBALS['__l10n']['On the other hand, in WordPress, a post can not be uncategorized, and a default installation has a first category labelised "Uncategorized". If you did not change that category, you can just ignore it while importing your blog, as Dotclear allows you to actually keep your posts uncategorized.'] = 'Par contre, il est impossible dans WordPress de ne pas assigner une catégorie à un article, c\'est pourquoi lors de l\'installation est créée une première catégorie appelée "Non classée". Si vous n\'avez pas modifié cette catégorie, l\'importation peut simplement l\'ignorer. En effet, Dotclear vous permet d\'avoir des articles sans catégorie.'; +$GLOBALS['__l10n']['Ignore the first category:'] = 'Ignorer la première catégorie :'; +$GLOBALS['__l10n']['Import lowest numbered category on posts:'] = 'Importer la catégorie la plus ancienne sur les articles :'; +$GLOBALS['__l10n']['Import all categories as tags:'] = 'Importer les catégories comme des tags :'; +$GLOBALS['__l10n']['Prefix such tags with:'] = 'Préfixer ces tags avec :'; +$GLOBALS['__l10n']['Content filters'] = 'Filtres de contenu'; +$GLOBALS['__l10n']['You may want to process your post and/or comment content with the following filters.'] = 'Vous pouvez utiliser les filtres suivants sur vos articles et/ou commentaires.'; +$GLOBALS['__l10n']['Post content formatter:'] = 'Formatage des articles :'; +$GLOBALS['__l10n']['Comment content formatter:'] = 'Formatage des commentaires :'; +$GLOBALS['__l10n']['WordPress tables not found'] = 'Tables WordPress non trouvées'; +$GLOBALS['__l10n']['No file to read.'] = 'Aucun fichier lisible.'; +$GLOBALS['__l10n']['File is not a DotClear backup.'] = 'Le fichier n\'est pas une sauvegarde DotClear.'; +$GLOBALS['__l10n']['File is not a single blog export.'] = 'Le fichier n\'est pas un fichier d\'export simple.'; +$GLOBALS['__l10n']['File is not a full export.'] = 'Le fichier n\'est pas un fichier d\'export complet.'; +$GLOBALS['__l10n']['Please wait...'] = 'Veuillez patienter...'; +$GLOBALS['__l10n']['Import'] = 'Importer'; +$GLOBALS['__l10n']['Maintenance'] = 'Maintenance'; +$GLOBALS['__l10n']['Optimization successful.'] = 'Optimisation réalisée avec succès.'; +$GLOBALS['__l10n']['Comments and trackback counted.'] = 'Commentaires et rétroliens comptés.'; +$GLOBALS['__l10n']['Templates cache directory emptied.'] = 'Répertoire du cache des templates vidé.'; +$GLOBALS['__l10n']['Indexing entry %d to %d.'] = 'Index des billets %d à %d'; +$GLOBALS['__l10n']['next'] = 'suivant'; +$GLOBALS['__l10n']['Entries index done.'] = 'Index des billets complet.'; +$GLOBALS['__l10n']['Back'] = 'Retour'; +$GLOBALS['__l10n']['Indexing comment %d to %d.'] = 'Index des commentaires %d à %d'; +$GLOBALS['__l10n']['Comments index done.'] = 'Index des commentaires complet.'; +$GLOBALS['__l10n']['Optimize database room'] = 'Optimiser l\'espace de la base de donnée'; +$GLOBALS['__l10n']['Vacuum tables'] = 'Nettoyer les tables'; +$GLOBALS['__l10n']['Counters'] = 'Compteurs'; +$GLOBALS['__l10n']['Reset comments and ping counters'] = 'Réinitialiser les compteurs des commentaires et rétroliens'; +$GLOBALS['__l10n']['Search engine index'] = 'Index du moteur de recherche'; +$GLOBALS['__l10n']['This may take a very long time'] = 'Ceci peut prendre beaucoup de temps'; +$GLOBALS['__l10n']['Index all posts'] = 'Indexer tous les billets'; +$GLOBALS['__l10n']['Index all comments'] = 'Indexer tous les commentaires'; +$GLOBALS['__l10n']['Empty templates cache directory'] = 'Vider le répertoire du cache des templates'; +$GLOBALS['__l10n']['Empty directory'] = 'Vider le répertoire'; +$GLOBALS['__l10n']['Tags'] = 'Tags'; +$GLOBALS['__l10n']['Tags:'] = 'Tags :'; +$GLOBALS['__l10n']['Are you sure you want to remove this %s?'] = 'Êtes vous certain de vouloir supprimer ce %s ?'; +$GLOBALS['__l10n']['Add a %s to this entry'] = 'Ajouter un %s à ce billet'; +$GLOBALS['__l10n']['Choose from list'] = 'Choisir depuis la liste'; +$GLOBALS['__l10n']['all'] = 'tous'; +$GLOBALS['__l10n']['Tag'] = 'Tag'; +$GLOBALS['__l10n']['add tags'] = 'ajouter des tags'; +$GLOBALS['__l10n']['remove tags'] = 'supprimer des tags'; +$GLOBALS['__l10n']['Add tags to entries'] = 'Ajouter des tags aux billets'; +$GLOBALS['__l10n']['Tags to add:'] = 'Tags à ajouter :'; +$GLOBALS['__l10n']['Remove selected tags from entries'] = 'Supprimer les tags sélectionnés des billets'; +$GLOBALS['__l10n']['No tags for selected entries'] = 'Aucun tag pour les billets sélectionnés'; +$GLOBALS['__l10n']['Following tags have been found in selected entries:'] = 'Les tags suivants ont été trouvés dans les billets sélectionnés :'; +$GLOBALS['__l10n']['This tag\'s comments Atom feed'] = 'Fil Atom des commentaires de ce tag'; +$GLOBALS['__l10n']['This tag\'s entries Atom feed'] = 'Fil Atom des billets de ce tag'; +$GLOBALS['__l10n']['All tags'] = 'Tous les tags'; +$GLOBALS['__l10n']['Limit (empty means no limit):'] = 'Limite (laisser vide pour aucune limite)'; +$GLOBALS['__l10n']['Entries count'] = 'Nombre de billets'; +$GLOBALS['__l10n']['Tag name'] = 'Nom du tag'; +$GLOBALS['__l10n']['Edit tag'] = 'Modifier un tag'; +$GLOBALS['__l10n']['Tag has been successfully renamed'] = 'Tag renommé avec succès'; +$GLOBALS['__l10n']['Back to tags list'] = 'Retour à la liste des tags'; +$GLOBALS['__l10n']['Rename this tag:'] = 'Renommer ce tag :'; +$GLOBALS['__l10n']['Delete this tag'] = 'Supprimer ce tag'; +$GLOBALS['__l10n']['Tag has been successfully removed'] = 'Tag supprimé avec succès'; +$GLOBALS['__l10n']['entries'] = 'billets'; +$GLOBALS['__l10n']['No tags on this blog.'] = 'Aucun tag sur ce blog'; +$GLOBALS['__l10n']['Pages'] = 'Pages'; +$GLOBALS['__l10n']['manage pages'] = 'gérer les pages'; +$GLOBALS['__l10n']['Published on'] = 'Publié le'; +$GLOBALS['__l10n']['This page\'s comments feed'] = 'Fil des commentaires de cette page'; +$GLOBALS['__l10n']['You must provide a valid email address.'] = 'Vous devez indiquer une adresse email valide.'; +$GLOBALS['__l10n']['Page title'] = 'Titre de la page'; +$GLOBALS['__l10n']['Page position'] = 'Position de la page'; +$GLOBALS['__l10n']['Publication date'] = 'Date de publication'; +$GLOBALS['__l10n']['No page'] = 'Aucune page'; +$GLOBALS['__l10n']['Are you sure you want to delete selected pages?'] = 'Êtes-vous certain de vouloir supprimer les pages sélectionnées ?'; +$GLOBALS['__l10n']['New page'] = 'Nouvelle page'; +$GLOBALS['__l10n']['Selected pages action:'] = 'Action sur les pages sélectionnées :'; +$GLOBALS['__l10n']['This page does not exist.'] = 'Cette page n\'existe pas.'; +$GLOBALS['__l10n']['Edit page'] = 'Modifier la page'; +$GLOBALS['__l10n']['next page'] = 'page suivante'; +$GLOBALS['__l10n']['previous page'] = 'page précédente'; +$GLOBALS['__l10n']['Are you sure you want to delete this page?'] = 'Êtes-vous certain de vouloir supprimer cette pages ?'; +$GLOBALS['__l10n']['Page has been successfully updated.'] = 'La page a été mise à jour avec succès.'; +$GLOBALS['__l10n']['Page has been successfully created.'] = 'La page a été créée avec succès.'; +$GLOBALS['__l10n']['View page'] = 'Voir la page'; +$GLOBALS['__l10n']['Preview page'] = 'Prévisualiser la page'; +$GLOBALS['__l10n']['Page status:'] = 'État de la page :'; +$GLOBALS['__l10n']['Page position:'] = 'Position de la page :'; +$GLOBALS['__l10n']['Page lang:'] = 'Langue de la page :'; +$GLOBALS['__l10n']['Page password:'] = 'Mot de passe de la page :'; +$GLOBALS['__l10n']['Warning: If you set the URL manually, it may conflict with another page.'] = 'Attention : si vous indiquez l\'URL manuellement, celle-ci peut entrer en conflit avec une autre page.'; +$GLOBALS['__l10n']['Add files to this page'] = 'Ajouter un fichier à la page'; +$GLOBALS['__l10n']['Pings'] = 'Pings'; +$GLOBALS['__l10n']['Pings configuration'] = 'Configuration des pings'; +$GLOBALS['__l10n']['Settings have been successfully updated.'] = 'Paramètres enregistrés avec succès.'; +$GLOBALS['__l10n']['Activate pings extension'] = 'Activer le module de ping'; +$GLOBALS['__l10n']['Service name:'] = 'Nom du service :'; +$GLOBALS['__l10n']['Service URI:'] = 'URI du service :'; +$GLOBALS['__l10n']['error'] = 'erreur'; +$GLOBALS['__l10n']['Test ping services'] = 'Tester les services de ping'; +$GLOBALS['__l10n']['Pings:'] = 'Pings :'; +$GLOBALS['__l10n']['Theme Editor'] = 'Éditeur de thème'; +$GLOBALS['__l10n']['No file'] = 'Aucun fichier'; +$GLOBALS['__l10n']['File does not exist.'] = 'Le fichier n\'existe pas.'; +$GLOBALS['__l10n']['File %s is not readable'] = 'Le fichier %s n\'est pas lisible'; +$GLOBALS['__l10n']['Unable to write file %s. Please check your theme files and folders permissions.'] = 'Impossible d\'écrire le fichier %s. Veuillez vérifier les permissions des fichiers et répertoires de votre thème.'; +$GLOBALS['__l10n']['Saving document...'] = 'Sauvegarde du document...'; +$GLOBALS['__l10n']['Document saved'] = 'Document sauvegardé'; +$GLOBALS['__l10n']['An error occurred:'] = 'Une erreur s\'est produite :'; +$GLOBALS['__l10n']['Your current theme on this blog is "%s".'] = 'Le thème utilisé actuellement sur votre blog est "%s".'; +$GLOBALS['__l10n']['You can\'t edit default theme.'] = 'Vous ne pouvez pas modifier le thème par défaut.'; +$GLOBALS['__l10n']['Please select a file to edit.'] = 'Veuillez sélectionner un fichier à modifier.'; +$GLOBALS['__l10n']['File editor'] = 'Éditeur de fichier'; +$GLOBALS['__l10n']['Editing file %s'] = 'Modification du fichier %s'; +$GLOBALS['__l10n']['This file is not writable. Please check your theme files permissions.'] = 'Ce fichier ne peut pas être modifié. Veuillez vérifier les permissions des fichiers de votre thème.'; +$GLOBALS['__l10n']['Templates files'] = 'Fichiers template'; +$GLOBALS['__l10n']['CSS files'] = 'Fichiers CSS'; +$GLOBALS['__l10n']['JavaScript files'] = 'Fichiers JavaScript'; +$GLOBALS['__l10n']['Presentation widgets'] = 'Widgets de présentation'; +$GLOBALS['__l10n']['Search engine'] = 'Moteur de recherche'; +$GLOBALS['__l10n']['Navigation links'] = 'Liens de navigation'; +$GLOBALS['__l10n']['Selected entries'] = 'Billets sélectionnés'; +$GLOBALS['__l10n']['Best of me'] = 'À retenir'; +$GLOBALS['__l10n']['Blog languages'] = 'Langues du blog'; +$GLOBALS['__l10n']['With entries counts'] = 'Afficher le nombre de billets'; +$GLOBALS['__l10n']['Subscribe links'] = 'Liens d\'abonnement'; +$GLOBALS['__l10n']['Subscribe'] = 'S\'abonner'; +$GLOBALS['__l10n']['Feeds type:'] = 'Types de fil :'; +$GLOBALS['__l10n']['Feed reader'] = 'Lecteur de fils de nouvelles'; +$GLOBALS['__l10n']['Somewhere else'] = 'Ailleurs'; +$GLOBALS['__l10n']['Entries limit:'] = 'Nombre de billets maximum :'; +$GLOBALS['__l10n']['Text'] = 'Texte'; +$GLOBALS['__l10n']['Text:'] = 'Texte :'; +$GLOBALS['__l10n']['Last entries'] = 'Derniers billets'; +$GLOBALS['__l10n']['Uncategorized'] = 'Non catégorisé'; +$GLOBALS['__l10n']['Tag:'] = 'Tag :'; +$GLOBALS['__l10n']['Last comments'] = 'Derniers commentaires'; +$GLOBALS['__l10n']['Comments limit:'] = 'Nombre de commentaires maximum :'; +$GLOBALS['__l10n']['Home'] = 'Accueil'; +$GLOBALS['__l10n']['Archives'] = 'Archives'; +$GLOBALS['__l10n']['This blog\'s entries %s feed'] = 'Fil %s des billets de ce blog'; +$GLOBALS['__l10n']['This blog\'s comments %s feed'] = 'Fil %s des commentaires de ce blog'; +$GLOBALS['__l10n']['Entries feed'] = 'Fil des billets'; +$GLOBALS['__l10n']['Comments feed'] = 'Fil des commentaires'; +$GLOBALS['__l10n']['navigation'] = 'navigation'; +$GLOBALS['__l10n']['extra'] = 'extra'; +$GLOBALS['__l10n']['Widgets'] = 'Widgets'; +$GLOBALS['__l10n']['Are you sure you want to reset sidebars?'] = 'Êtes-vous certain de vouloir réinitialiser les bandeaux ?'; +$GLOBALS['__l10n']['Available widgets'] = 'Widgets disponibles'; +$GLOBALS['__l10n']['Append to:'] = 'Ajouter à :'; +$GLOBALS['__l10n']['add widgets to sidebars'] = 'ajouter les widgets aux bandeaux'; +$GLOBALS['__l10n']['Navigation sidebar'] = 'Bandeau de navigation'; +$GLOBALS['__l10n']['Extra sidebar'] = 'Bandeau d\'extra'; +$GLOBALS['__l10n']['update sidebars'] = 'Mettre à jour les bandeaux'; +$GLOBALS['__l10n']['reset sidebars'] = 'Réinitialiser les bandeaux'; +$GLOBALS['__l10n']['Widget templates tags'] = 'Marqueurs de template des widgets'; +$GLOBALS['__l10n']['If you are allowed to edit your theme templates, you can directly add widgets as templates tags, with their own configuration.'] = 'Si vous avez le droit de modifier les templates de votre thème, vous pouvez directement ajouter des widgets à l\'aide de marqueurs de template, avec leur propre configuration.'; +$GLOBALS['__l10n']['To add a widget in your template, you need to write code like this:'] = 'Pour ajouter un widget dans votre template, vous devez écrire un code comme ceci :'; +$GLOBALS['__l10n']['Widget ID'] = 'Identifiant du widget'; +$GLOBALS['__l10n']['Setting name'] = 'Nom du paramètre'; +$GLOBALS['__l10n']['Setting value'] = 'Valeur du paramètre'; +$GLOBALS['__l10n']['Here are the following available widgets for your blog:'] = 'Voici les widgets disponibles pour votre blog :'; +$GLOBALS['__l10n']['Widget ID:'] = 'Identifiant du widget :'; +$GLOBALS['__l10n']['No setting for this widget'] = 'Aucun paramètre pour ce widget'; +$GLOBALS['__l10n']['Setting name:'] = 'Nom du paramètre :'; +$GLOBALS['__l10n']['No widget.'] = 'Aucun widget.'; +$GLOBALS['__l10n']['order'] = 'ordre'; +$GLOBALS['__l10n']['Remove widget'] = 'Supprimer le widget'; +?> \ No newline at end of file diff --git a/locales/fr/plugins.po b/locales/fr/plugins.po new file mode 100644 index 0000000..3a65ac9 --- /dev/null +++ b/locales/fr/plugins.po @@ -0,0 +1,1358 @@ +# French translation of DotClear +# Copyright (C) 2006. +# Olivier Meunier , 2006. +msgid "" +msgstr "" +"Project-Id-Version: Dotclear 2\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2009-09-16 20:57+0200\n" +"PO-Revision-Date: \n" +"Last-Translator: xave \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: French\n" + +msgid "no" +msgstr "non" + +msgid "Configuration successfully updated" +msgstr "Configuration mise à jour avec succès" + +msgid "Settings definition successfully updated" +msgstr "Définition des paramètres mise à jour avec succès" + +msgid "blog settings" +msgstr "paramètres du blog" + +msgid "Value" +msgstr "Valeur" + +msgid "Description" +msgstr "Description" + +msgid "global settings" +msgstr "paramètres globaux" + +msgid "Akismet spam filter" +msgstr "Filtre de spam Akismet" + +#, php-format +msgid "Filtered by %s." +msgstr "Filtré par %s" + +msgid "Akismet API key:" +msgstr "Clé de l'interface Akismet :" + +msgid "API key verified" +msgstr "Clé vérifiée" + +msgid "API key not verified" +msgstr "Clé non vérifiée" + +msgid "Get your own API key" +msgstr "Obtenez votre clé Akismet" + +msgid "Antispam" +msgstr "Antispam" + +msgid "Delete junk comments older than" +msgstr "Supprimer les commentaires indésirables après" + +msgid "days" +msgstr "jours" + +msgid "IP Blacklist / Whitelist Filter" +msgstr "Liste noire / Liste blanche IP" + +#, php-format +msgid "Filtered by %1$s with rule %2$s." +msgstr "Filtré par %1$s avec la règle %2$s." + +msgid "IP address has been successfully added." +msgstr "L'adresse IP a été ajoutée avec succès." + +msgid "IP addresses have been successfully removed." +msgstr "L'adresse IP a été supprimée avec succès." + +msgid "Blacklist" +msgstr "Liste noire" + +msgid "Whitelist" +msgstr "Liste blanche" + +msgid "Add an IP address" +msgstr "Ajouter une adresse IP" + +msgid "Global IP" +msgstr "IP globale" + +msgid "Add" +msgstr "Ajouter" + +msgid "No IP address in list." +msgstr "Aucune adresse IP dans la liste." + +msgid "IP list" +msgstr "Liste d'IP" + +msgid "Checks sender IP address against DNSBL servers" +msgstr "Vérifie l'adresse IP de l'auteur sur des serveurs DNSBL" + +#, php-format +msgid "Filtered by %1$s with server %2$s." +msgstr "Filtré par %1$s avec le serveur %2$s." + +msgid "IP Lookup servers" +msgstr "Serveurs de résolution d'IP" + +msgid "Add here a coma separated list of servers." +msgstr "Ajoutez ici une liste de serveurs, séparés par des virgules." + +msgid "Checks links in comments against surbl.org" +msgstr "Vérifie les liens dans les commentaires sur surbl.org" + +msgid "Words Blacklist" +msgstr "Liste de termes interdits" + +#, php-format +msgid "Filtered by %1$s with word %2$s." +msgstr "Filtré par %1$s avec le terme %2$s." + +msgid "Words have been successfully added." +msgstr "Les mots ont été ajouté avec succès." + +msgid "Word has been successfully added." +msgstr "Le mot a été ajouté avec succès." + +msgid "Words have been successfully removed." +msgstr "Les mots ont été supprimés avec succès." + +msgid "Add a word" +msgstr "Ajouter un mot" + +msgid "Global word" +msgstr "Mot global" + +msgid "No word in list." +msgstr "Aucun mot dans la liste." + +msgid "List" +msgstr "Liste" + +msgid "Delete selected words" +msgstr "Supprimer les mots sélectionnés" + +msgid "Create default wordlist" +msgstr "Créer une liste par défaut" + +msgid "This word exists" +msgstr "Ce mot existe" + +msgid "No description" +msgstr "Aucune description" + +#, php-format +msgid "Filtered by %1$s (%2$s)" +msgstr "Filtré par %1$s (%2$s)" + +msgid "Unknown filter." +msgstr "Filtre inconnu" + +msgid "This comment is a spam:" +msgstr "Ce commentaire est un indésirable :" + +#, php-format +msgid "(including %d spam comment)" +msgstr "(dont %d commentaire indésirable)" + +#, php-format +msgid "(including %d spam comments)" +msgstr "(dont %d commentaires indésirables)" + +msgid "Spam moderation" +msgstr "Modération des indésirables" + +msgid "Spam" +msgstr "Spam" + +msgid "Ham" +msgstr "Non spam" + +msgid "Filter does not exist." +msgstr "Le filtre n'existe pas." + +msgid "Filter has no user interface." +msgstr "Le filtre n'a pas d'interface utilisateur." + +msgid "Return to filters" +msgstr "Retour aux filtres" + +#, php-format +msgid "%s configuration" +msgstr "%s configuration" + +msgid "Information" +msgstr "Informations" + +msgid "Spam comments have been successfully deleted." +msgstr "Les commentaires indésirables ont été supprimés avec succès." + +msgid "Junk comments:" +msgstr "Commentaires indésirables :" + +msgid "Published comments:" +msgstr "Commentaires publiés :" + +msgid "Delete all spams" +msgstr "Supprimer tous les indésirables" + +#, php-format +msgid "All spam comments older than %s day(s) will be automatically deleted." +msgstr "Tous les indésirables de plus de %s jour(s) seront automatiquement supprimés." + +msgid "Available spam filters" +msgstr "Filtres disponibles" + +msgid "Filters configuration has been successfully saved." +msgstr "La configuration des filtres a été enregistrée avec succès." + +msgid "Order" +msgstr "Ordre" + +msgid "Active" +msgstr "Actif" + +msgid "Auto Del." +msgstr "Suppr. Auto" + +msgid "Filter name" +msgstr "Nom du filtre" + +msgid "Filter configuration" +msgstr "Configuration du filtre" + +msgid "Syndication" +msgstr "Syndication" + +msgid "Junk comments RSS feed" +msgstr "Fil RSS des commentaires indésirables" + +msgid "Published comments RSS feed" +msgstr "Fil RSS des commentaires publiés" + +msgid "Blogroll" +msgstr "Liens" + +msgid "manage blogroll" +msgstr "gestion de la liste de liens" + +msgid "Links" +msgstr "Liens" + +msgid "All categories" +msgstr "Toutes les catégories" + +msgid "Home page only" +msgstr "Page d'accueil uniquement" + +msgid "You must provide a link title" +msgstr "Vous devez indiquer un titre de lien" + +msgid "You must provide a link URL" +msgstr "Vous devez indiquer une URL" + +msgid "You need to provide a XBEL or OPML file." +msgstr "Vous devez fournir un fichier XBEL ou OPML." + +msgid "File is not in XML format." +msgstr "Le fichier n'est pas au format XML." + +msgid "No such link or title" +msgstr "Lien ou catégorie inexistant" + +msgid "Return to blogroll" +msgstr "Retour à la liste des liens" + +msgid "Category has been successfully updated" +msgstr "Catégorie mise à jour avec succès" + +msgid "Edit category" +msgstr "Modifier une catégorie" + +msgid "Link has been successfully updated" +msgstr "Lien mis à jour avec succès" + +msgid "Edit link" +msgstr "Modifier le lien" + +msgid "XFN" +msgstr "XFN" + +msgid "_xfn_Me" +msgstr "Moi" + +msgid "_xfn_Another link for myself" +msgstr "Autre lien m'appartenant" + +msgid "_xfn_Friendship" +msgstr "Amitié" + +msgid "_xfn_Contact" +msgstr "Contact" + +msgid "_xfn_Acquaintance" +msgstr "Connaissance" + +msgid "_xfn_Friend" +msgstr "Ami(e)" + +msgid "_xfn_Physical" +msgstr "Physique" + +msgid "_xfn_Met" +msgstr "Rencontré(e)" + +msgid "_xfn_Professional" +msgstr "Professionnel" + +msgid "_xfn_Co-worker" +msgstr "Camarade de travail" + +msgid "_xfn_Colleague" +msgstr "Collègue" + +msgid "_xfn_Geographical" +msgstr "Géographique" + +msgid "_xfn_Co-resident" +msgstr "Colocataire" + +msgid "_xfn_Neighbor" +msgstr "Voisin(e)" + +msgid "_xfn_Family" +msgstr "Famille" + +msgid "_xfn_Child" +msgstr "Enfant" + +msgid "_xfn_Parent" +msgstr "Parent" + +msgid "_xfn_Sibling" +msgstr "Frère/Soeur" + +msgid "_xfn_Spouse" +msgstr "Époux/Épouse" + +msgid "_xfn_Kin" +msgstr "Famille" + +msgid "_xfn_Romantic" +msgstr "Romantique" + +msgid "_xfn_Muse" +msgstr "Muse" + +msgid "_xfn_Crush" +msgstr "Bluette" + +msgid "_xfn_Date" +msgstr "Petit(e) ami(e)" + +msgid "_xfn_Sweetheart" +msgstr "Ami(e)" + +msgid "Nothing to import" +msgstr "Rien à importer" + +msgid "Import operation cancelled." +msgstr "Importation annulée." + +msgid "Items order has been successfully updated" +msgstr "L'ordre des éléments a été mis à jour avec succès" + +msgid "Items have been successfully removed." +msgstr "Éléments supprimés avec succès." + +msgid "Link has been successfully created." +msgstr "Lien créé avec succès." + +msgid "category has been successfully created." +msgstr "Catégorie mise à jour avec succès." + +msgid "links have been successfully imported." +msgstr "Liens importés avec succès." + +msgid "URL" +msgstr "URL" + +msgid "Lang" +msgstr "Langue" + +msgid "Save order" +msgstr "Enregistrer l'ordre" + +msgid "Delete selected links" +msgstr "Supprimer les liens sélectionnés" + +msgid "Are you sure you you want to delete selected links?" +msgstr "Êtes-vous certain de vouloir supprimer les liens sélectionnés ?" + +msgid "Add a new link" +msgstr "Ajouter un nouveau lien" + +msgid "Add a category" +msgstr "Ajouter une catégorie" + +msgid "Import links" +msgstr "Importer des liens" + +msgid "OPML or XBEL File:" +msgstr "Fichier OPML ou XBEL :" + +msgid "import" +msgstr "importer" + +msgid "Light linear gradient" +msgstr "Dégradé linéaire clair" + +msgid "Medium linear gradient" +msgstr "Dégradé linéaire moyen" + +msgid "Dark linear gradient" +msgstr "Dégradé linéaire foncé" + +msgid "Solid color" +msgstr "Couleur unie" + +msgid "Custom..." +msgstr "Personnalisé..." + +msgid "Blowup configuration" +msgstr "Configuration Blowup" + +msgid "Predefined styles" +msgstr "Styles prédéfinis" + +msgid "Apply code" +msgstr "Appliquer le code" + +msgid "As images cannot be created, you won't be able to change some background properties." +msgstr "Les images ne pouvant être créées, vous ne pourrez pas changer certaines couleurs de fond." + +msgid "Theme configuration has been successfully updated." +msgstr "La configuration du thème a été mise à jour avec succès." + +msgid "General" +msgstr "Général" + +msgid "Background color:" +msgstr "Couleur de fond :" + +msgid "Background color fill:" +msgstr "Remplissage de la couleur de fond :" + +msgid "Main text font:" +msgstr "Police du texte principal :" + +msgid "Main text font size:" +msgstr "Taille du texte principal :" + +msgid "Main text color:" +msgstr "Couleur du texte principal :" + +msgid "Text line height:" +msgstr "Hauteur des lignes :" + +msgid "Links color:" +msgstr "Couleur des liens :" + +msgid "Visited links color:" +msgstr "Couleurs des liens visités :" + +msgid "Focus links color:" +msgstr "Couleur des liens survolés :" + +msgid "Page top" +msgstr "Haut de page" + +msgid "Prelude color:" +msgstr "Couleur du prélude :" + +msgid "Hide main title" +msgstr "Cacher le titre principal" + +msgid "Main title font:" +msgstr "Police du titre principal :" + +msgid "Main title font size:" +msgstr "Taille du titre principal :" + +msgid "Main title color:" +msgstr "Couleur du titre principal :" + +msgid "Main title alignment:" +msgstr "Alignement du titre principal :" + +msgid "center" +msgstr "centre" + +msgid "left" +msgstr "gauche" + +msgid "right" +msgstr "droite" + +msgid "Main title position (x:y)" +msgstr "Position du titre principal (x:y)" + +msgid "Top image" +msgstr "Image d'en-tête" + +msgid "Choose \"Custom...\" to upload your own image." +msgstr "Choisissez \"Personnalisé...\" pour déposer votre propre image." + +msgid "Add your image:" +msgstr "Ajouter votre image :" + +#, php-format +msgid "JPEG or PNG file, 800 pixels wide, maximum size %s" +msgstr "Fichier JPEG ou PNG, 800 pixels de large et de taille maximale %s" + +msgid "Preview" +msgstr "Prévisualisation" + +msgid "Sidebar" +msgstr "Bandeau" + +msgid "Sidebar position:" +msgstr "Position du bandeau" + +msgid "Sidebar text font:" +msgstr "Police du texte du bandeau :" + +msgid "Sidebar text font size:" +msgstr "Taille du texte du bandeau :" + +msgid "Sidebar text color:" +msgstr "Couleur du texte du bandeau :" + +msgid "Sidebar titles font:" +msgstr "Police des titres du bandeau :" + +msgid "Sidebar titles font size:" +msgstr "Taille des titres du bandeau :" + +msgid "Sidebar titles color:" +msgstr "Couleur des titres du bandeau :" + +msgid "Sidebar 2nd level titles font:" +msgstr "Police des titres de niveau 2 du bandeau :" + +msgid "Sidebar 2nd level titles font size:" +msgstr "Taille des titres de niveau 2 du bandeau :" + +msgid "Sidebar 2nd level titles color:" +msgstr "Couleur des titres de niveau 2 du bandeau :" + +msgid "Sidebar lines color:" +msgstr "Couleur des lignes du bandeau :" + +msgid "Sidebar links color:" +msgstr "Couleur des liens du bandeau :" + +msgid "Sidebar visited links color:" +msgstr "Couleurs des liens vistés du bandeau :" + +msgid "Sidebar focus links color:" +msgstr "Couleurs des liens survolés du bandeau :" + +msgid "Date title font:" +msgstr "Police des titres de dates :" + +msgid "Date title font size:" +msgstr "Taille des titres de dates :" + +msgid "Date title color:" +msgstr "Couleur des titres de date :" + +msgid "Entry title font:" +msgstr "Police des titres de billet :" + +msgid "Entry title font size:" +msgstr "Taille des titres des billets :" + +msgid "Entry title color:" +msgstr "Couleur des titres des billets :" + +msgid "Comment background color:" +msgstr "Couleur du fond des commentaires :" + +msgid "Comment text color:" +msgstr "Couleur du texte des commentaires :" + +msgid "My comment background color:" +msgstr "Couleur du fond de mes commentaires :" + +msgid "My comment text color:" +msgstr "Couleur du texte de mes commentaires :" + +msgid "Footer" +msgstr "Pied de page" + +msgid "Footer font:" +msgstr "Police du pied de page :" + +msgid "Footer font size:" +msgstr "Taille du texte du pied de page :" + +msgid "Footer color:" +msgstr "Couleur du texte du pied de page :" + +msgid "Footer links color:" +msgstr "Couleur des liens du pied de page :" + +msgid "Footer background color:" +msgstr "Couleur de fond du pied de page :" + +msgid "Configuration import / export" +msgstr "Import / export de configuration" + +msgid "You can share your configuration using the following code. To apply a configuration, paste the code, click on \"Apply code\" and save." +msgstr "Vous pouvez partager votre configuration en utilisant le code suivant. Pour appliquer une configuration, copiez le code, cliquez sur \"Appliquer le code\" et enregistrez." + +msgid "default" +msgstr "par défaut" + +msgid "Unable to create images." +msgstr "Impossible de créer les images." + +msgid "Invalid file type." +msgstr "Type de fichier non valide." + +msgid "Unable to open image." +msgstr "Impossible d'ouvrir l'image." + +msgid "External media" +msgstr "Média externe" + +msgid "Unsupported service" +msgstr "Service non pris en charge" + +msgid "Invalid page URL" +msgstr "URL de la page non valide" + +msgid "External media selector" +msgstr "Sélecteur de médias externes" + +msgid "Supported media services" +msgstr "Services de média supportés" + +msgid "Please enter the URL of the page containing the video you want to include in your post." +msgstr "Entrez l'URL de la page contenant la video que vous voulez intégrer à votre billet." + +msgid "Page URL:" +msgstr "URL de la page :" + +msgid "Media alignment" +msgstr "Alignement du média" + +msgid "Media title" +msgstr "Titre du média" + +msgid "Checks trackback source for a link to the post" +msgstr "Vérifie si la source du rétrolien possède un lien vers le billet" + +msgid "Import/Export" +msgstr "Import/Export" + +msgid "Flat file export" +msgstr "Exporter un fichier texte." + +msgid "Exports a blog or a full Dotclear installation to flat file." +msgstr "Exporte un blog ou toutes les données de Dotclear dans un fichier texte." + +msgid "Export file not found." +msgstr "Fichier d'export non trouvé." + +msgid "Export a blog" +msgstr "Exporter un blog" + +#, php-format +msgid "This will create an export of your current blog: %s" +msgstr "Ceci va exporter le contenu du blog en cours : %s." + +msgid "Export" +msgstr "Exporter" + +msgid "You may also want to download your media directory as a zip file" +msgstr "Vous pouvez également télécharger votre répertoire de médias au format zip." + +msgid "Export all content" +msgstr "Exporter tout le contenu" + +msgid "Congratulation!" +msgstr "Félicitations !" + +msgid "Your blog has been successfully imported. Welcome on Dotclear 2!" +msgstr "Votre blog a été importé avec succès. Bienvenue sur Dotclear 2 !" + +msgid "Why don't you blog this now?" +msgstr "Pourquoi ne pas le bloguer maintenant ?" + +msgid "or" +msgstr "ou" + +msgid "visit your dashboard" +msgstr "vous rendre sur votre tableau de bord" + +msgid "Dotclear 1.2 import" +msgstr "Importer depuis Dotclear 1.2" + +msgid "Import a Dotclear 1.2 installation into your current blog." +msgstr "Importe un blog Dotclear 1.2 dans votre blog en cours." + +#, php-format +msgid "This will import your Dotclear 1.2 content as new content in the current blog: %s." +msgstr "Ceci va importer votre blog Dotclear 1.2 comme un nouveau contenu dans le blog en cours : %s." + +msgid "Please note that this process will empty your categories, blogroll, entries and comments on the current blog." +msgstr "Veuillez noter que cette opération va vider vos catégories, liens, billets et commentaires sur le blog en cours." + +msgid "Depending on the size of your blog, it could take a few minutes." +msgstr "Selon la taille de votre blog, ceci peut prendre quelques minutes." + +msgid "General information" +msgstr "Informations générales" + +msgid "Import my blog now" +msgstr "Importer mon blog" + +msgid "We first need some information about your old Dotclear 1.2 installation." +msgstr "Nous avons d'abord besoin de renseignements à propos de votre ancienne installation Dotclear 1.2." + +msgid "Entries import options" +msgstr "Options d'importation des billets" + +msgid "Number of entries to import at once:" +msgstr "Nombre de billets à importer à chaque étape :" + +msgid "Importing users" +msgstr "Importe les utilisateurs" + +msgid "Importing categories" +msgstr "Importe les catégories" + +msgid "Importing blogroll" +msgstr "Importe les liens" + +#, php-format +msgid "Importing entries from %d to %d / %d" +msgstr "Importation des billets %d à %d" + +msgid "Please read carefully" +msgstr "Merci de lire attentivement" + +msgid "Every newly imported user has received a random password and will need to ask for a new one by following the \"I forgot my password\" link on the login page (Their registered email address has to be valid.)" +msgstr "Chaque utilisateur nouvellement importé a reçu un mot de passe aléatoire et devra en demander un nouveau en suivant le lien \"J'ai oublié mon mot de passe\" sur la page de connexion à l'interface d'aministration." + +#, php-format +msgid "Please note that Dotclear 2 has a new URL layout. You can avoid broken links by installing DC1 redirect plugin and activate it in your blog configuration." +msgstr "Veuillez noter que Dotclear 2 a un nouveau format d'URL. Vous pouvez éviter les liens morts en installant le plugin DC1 redirect et en l'activant dans la configuration de votre blog." + +msgid "next step" +msgstr "étape suivante" + +msgid "Dotclear tables not found" +msgstr "Tables Dotclear non trouvées" + +msgid "Feed import" +msgstr "Importer depuis un flux" + +msgid "Imports a feed as new entries." +msgstr "Importe un flux comme nouveaux billets." + +msgid "Cannot retrieve feed URL." +msgstr "Impossible d'atteindre l'URL du fil." + +msgid "No items in feed." +msgstr "Aucun élément dans le feed." + +msgid "Content successfully imported." +msgstr "Contenu importé avec succès." + +msgid "Import from a feed" +msgstr "Importer depuis un fil de nouvelles" + +#, php-format +msgid "This will import a feed (RSS or Atom) a as new content in the current blog: %s." +msgstr "Ceci va importer un fil (RSS ou Atom) comme un nouveau contenu dans le blog en cours : %s." + +msgid "Feed URL:" +msgstr "URL du fil" + +msgid "Send" +msgstr "Envoyer" + +msgid "Flat file import" +msgstr "Importer depuis un fichier texte" + +msgid "Imports a blog or a full Dotclear installation from flat file." +msgstr "Importe un blog ou toutes les données depuis un fichier texte." + +msgid "Single blog successfully imported." +msgstr "Blog importé avec succès." + +msgid "Are you sure you want to import a full backup file?" +msgstr "Êtes-vous certain de vouloir charger un fichier de sauvegarde complet ?" + +msgid "Import a single blog" +msgstr "Importer un blog" + +#, php-format +msgid "This will import a single blog backup as new content in the current blog: %s." +msgstr "Ceci va charger une sauvegarde de blog comme un nouveau contenu dans le blog en cours : %s." + +msgid "Upload a backup file" +msgstr "Charger un fichier de sauvegarde" + +msgid "or pick up a local file in your public directory" +msgstr "ou choisissez un fichier local dans votre répertoire public" + +msgid "Import a full backup file" +msgstr "Import d'un fichier de sauvegarde complet" + +msgid "Warning: This will reset all the content of your database, except users." +msgstr "Attention : Ceci va remettre à zéro tout le contenu, sauf les utilisateurs." + +msgid "WordPress import" +msgstr "Importer depuis WordPress" + +msgid "Import a WordPress installation into your current blog." +msgstr "Importe un blog WordPress dans votre blog en cours." + +#, php-format +msgid "This will import your WordPress content as new content in the current blog: %s." +msgstr "Ceci va importer votre blog WordPress comme un nouveau contenu dans le blog en cours : %s." + +msgid "We first need some information about your old WordPress installation." +msgstr "Nous avons d'abord besoin de renseignements à propos de votre ancienne installation WordPress." + +msgid "WordPress and Dotclear's handling of categories are quite different. You can assign several categories to a single post in WordPress. In the Dotclear world, we see it more like \"One category, several tags.\" Therefore Dotclear can only import one category per post and will chose the lowest numbered one. If you want to keep a trace of every category, you can import them as tags, with an optional prefix." +msgstr "WordPress et Dotclear gèrent les catégories différemment. Dans WordPress, un article peut être classé dans plusieurs catégories, alors que dans Dotclear, on voit ça plutôt comme \"Une catégorie, plusieurs mots-clefs.\" Dotclear ne peut donc importer qu'une seule catégorie par article et choisira dans ce cas la première créée. Si vous désirez garder une trace de chaque catégorie, vous pouvez les importer en tant que mots-clefs, avec un préfixe optionnel." + +msgid "On the other hand, in WordPress, a post can not be uncategorized, and a default installation has a first category labelised \"Uncategorized\". If you did not change that category, you can just ignore it while importing your blog, as Dotclear allows you to actually keep your posts uncategorized." +msgstr "Par contre, il est impossible dans WordPress de ne pas assigner une catégorie à un article, c'est pourquoi lors de l'installation est créée une première catégorie appelée \"Non classée\". Si vous n'avez pas modifié cette catégorie, l'importation peut simplement l'ignorer. En effet, Dotclear vous permet d'avoir des articles sans catégorie." + +msgid "Ignore the first category:" +msgstr "Ignorer la première catégorie :" + +msgid "Import lowest numbered category on posts:" +msgstr "Importer la catégorie la plus ancienne sur les articles :" + +msgid "Import all categories as tags:" +msgstr "Importer les catégories comme des tags :" + +msgid "Prefix such tags with:" +msgstr "Préfixer ces tags avec :" + +msgid "Content filters" +msgstr "Filtres de contenu" + +msgid "You may want to process your post and/or comment content with the following filters." +msgstr "Vous pouvez utiliser les filtres suivants sur vos articles et/ou commentaires." + +msgid "Post content formatter:" +msgstr "Formatage des articles :" + +msgid "Comment content formatter:" +msgstr "Formatage des commentaires :" + +msgid "WordPress tables not found" +msgstr "Tables WordPress non trouvées" + +msgid "No file to read." +msgstr "Aucun fichier lisible." + +msgid "File is not a DotClear backup." +msgstr "Le fichier n'est pas une sauvegarde DotClear." + +msgid "File is not a single blog export." +msgstr "Le fichier n'est pas un fichier d'export simple." + +msgid "File is not a full export." +msgstr "Le fichier n'est pas un fichier d'export complet." + +msgid "Please wait..." +msgstr "Veuillez patienter..." + +msgid "Import" +msgstr "Importer" + +# French translation of DotClea" +msgid "Maintenance" +msgstr "Maintenance" + +msgid "Optimization successful." +msgstr "Optimisation réalisée avec succès." + +msgid "Comments and trackback counted." +msgstr "Commentaires et rétroliens comptés." + +msgid "Templates cache directory emptied." +msgstr "Répertoire du cache des templates vidé." + +#, php-format +msgid "Indexing entry %d to %d." +msgstr "Index des billets %d à %d" + +msgid "next" +msgstr "suivant" + +msgid "Entries index done." +msgstr "Index des billets complet." + +msgid "Back" +msgstr "Retour" + +#, php-format +msgid "Indexing comment %d to %d." +msgstr "Index des commentaires %d à %d" + +msgid "Comments index done." +msgstr "Index des commentaires complet." + +msgid "Optimize database room" +msgstr "Optimiser l'espace de la base de donnée" + +msgid "Vacuum tables" +msgstr "Nettoyer les tables" + +msgid "Counters" +msgstr "Compteurs" + +msgid "Reset comments and ping counters" +msgstr "Réinitialiser les compteurs des commentaires et rétroliens" + +msgid "Search engine index" +msgstr "Index du moteur de recherche" + +msgid "This may take a very long time" +msgstr "Ceci peut prendre beaucoup de temps" + +msgid "Index all posts" +msgstr "Indexer tous les billets" + +msgid "Index all comments" +msgstr "Indexer tous les commentaires" + +msgid "Empty templates cache directory" +msgstr "Vider le répertoire du cache des templates" + +msgid "Empty directory" +msgstr "Vider le répertoire" + +msgid "Tags" +msgstr "Tags" + +msgid "Tags:" +msgstr "Tags :" + +#, php-format +msgid "Are you sure you want to remove this %s?" +msgstr "Êtes vous certain de vouloir supprimer ce %s ?" + +#, php-format +msgid "Add a %s to this entry" +msgstr "Ajouter un %s à ce billet" + +msgid "Choose from list" +msgstr "Choisir depuis la liste" + +msgid "all" +msgstr "tous" + +msgid "Tag" +msgstr "Tag" + +msgid "add tags" +msgstr "ajouter des tags" + +msgid "remove tags" +msgstr "supprimer des tags" + +msgid "Add tags to entries" +msgstr "Ajouter des tags aux billets" + +msgid "Tags to add:" +msgstr "Tags à ajouter :" + +msgid "Remove selected tags from entries" +msgstr "Supprimer les tags sélectionnés des billets" + +msgid "No tags for selected entries" +msgstr "Aucun tag pour les billets sélectionnés" + +msgid "Following tags have been found in selected entries:" +msgstr "Les tags suivants ont été trouvés dans les billets sélectionnés :" + +msgid "This tag's comments Atom feed" +msgstr "Fil Atom des commentaires de ce tag" + +msgid "This tag's entries Atom feed" +msgstr "Fil Atom des billets de ce tag" + +msgid "All tags" +msgstr "Tous les tags" + +msgid "Limit (empty means no limit):" +msgstr "Limite (laisser vide pour aucune limite)" + +msgid "Entries count" +msgstr "Nombre de billets" + +msgid "Tag name" +msgstr "Nom du tag" + +msgid "Edit tag" +msgstr "Modifier un tag" + +msgid "Tag has been successfully renamed" +msgstr "Tag renommé avec succès" + +msgid "Back to tags list" +msgstr "Retour à la liste des tags" + +msgid "Rename this tag:" +msgstr "Renommer ce tag :" + +msgid "Delete this tag" +msgstr "Supprimer ce tag" + +msgid "Tag has been successfully removed" +msgstr "Tag supprimé avec succès" + +msgid "entries" +msgstr "billets" + +msgid "No tags on this blog." +msgstr "Aucun tag sur ce blog" + +msgid "Pages" +msgstr "Pages" + +msgid "manage pages" +msgstr "gérer les pages" + +msgid "Published on" +msgstr "Publié le" + +msgid "This page's comments feed" +msgstr "Fil des commentaires de cette page" + +msgid "You must provide a valid email address." +msgstr "Vous devez indiquer une adresse email valide." + +msgid "Page title" +msgstr "Titre de la page" + +msgid "Page position" +msgstr "Position de la page" + +msgid "Publication date" +msgstr "Date de publication" + +msgid "No page" +msgstr "Aucune page" + +msgid "Are you sure you want to delete selected pages?" +msgstr "Êtes-vous certain de vouloir supprimer les pages sélectionnées ?" + +msgid "New page" +msgstr "Nouvelle page" + +msgid "Selected pages action:" +msgstr "Action sur les pages sélectionnées :" + +msgid "This page does not exist." +msgstr "Cette page n'existe pas." + +msgid "Edit page" +msgstr "Modifier la page" + +msgid "next page" +msgstr "page suivante" + +msgid "previous page" +msgstr "page précédente" + +msgid "Are you sure you want to delete this page?" +msgstr "Êtes-vous certain de vouloir supprimer cette pages ?" + +msgid "Page has been successfully updated." +msgstr "La page a été mise à jour avec succès." + +msgid "Page has been successfully created." +msgstr "La page a été créée avec succès." + +msgid "View page" +msgstr "Voir la page" + +msgid "Preview page" +msgstr "Prévisualiser la page" + +msgid "Page status:" +msgstr "État de la page :" + +msgid "Page position:" +msgstr "Position de la page :" + +msgid "Page lang:" +msgstr "Langue de la page :" + +msgid "Page password:" +msgstr "Mot de passe de la page :" + +msgid "Warning: If you set the URL manually, it may conflict with another page." +msgstr "Attention : si vous indiquez l'URL manuellement, celle-ci peut entrer en conflit avec une autre page." + +msgid "Add files to this page" +msgstr "Ajouter un fichier à la page" + +msgid "Pings" +msgstr "Pings" + +msgid "Pings configuration" +msgstr "Configuration des pings" + +msgid "Settings have been successfully updated." +msgstr "Paramètres enregistrés avec succès." + +msgid "Activate pings extension" +msgstr "Activer le module de ping" + +msgid "Service name:" +msgstr "Nom du service :" + +msgid "Service URI:" +msgstr "URI du service :" + +msgid "error" +msgstr "erreur" + +msgid "Test ping services" +msgstr "Tester les services de ping" + +msgid "Pings:" +msgstr "Pings :" + +msgid "Theme Editor" +msgstr "Éditeur de thème" + +msgid "No file" +msgstr "Aucun fichier" + +msgid "File does not exist." +msgstr "Le fichier n'existe pas." + +#, php-format +msgid "File %s is not readable" +msgstr "Le fichier %s n'est pas lisible" + +#, php-format +msgid "Unable to write file %s. Please check your theme files and folders permissions." +msgstr "Impossible d'écrire le fichier %s. Veuillez vérifier les permissions des fichiers et répertoires de votre thème." + +msgid "Saving document..." +msgstr "Sauvegarde du document..." + +msgid "Document saved" +msgstr "Document sauvegardé" + +msgid "An error occurred:" +msgstr "Une erreur s'est produite :" + +#, php-format +msgid "Your current theme on this blog is \"%s\"." +msgstr "Le thème utilisé actuellement sur votre blog est \"%s\"." + +msgid "You can't edit default theme." +msgstr "Vous ne pouvez pas modifier le thème par défaut." + +msgid "Please select a file to edit." +msgstr "Veuillez sélectionner un fichier à modifier." + +msgid "File editor" +msgstr "Éditeur de fichier" + +#, php-format +msgid "Editing file %s" +msgstr "Modification du fichier %s" + +msgid "This file is not writable. Please check your theme files permissions." +msgstr "Ce fichier ne peut pas être modifié. Veuillez vérifier les permissions des fichiers de votre thème." + +msgid "Templates files" +msgstr "Fichiers template" + +msgid "CSS files" +msgstr "Fichiers CSS" + +msgid "JavaScript files" +msgstr "Fichiers JavaScript" + +msgid "Presentation widgets" +msgstr "Widgets de présentation" + +msgid "Search engine" +msgstr "Moteur de recherche" + +msgid "Navigation links" +msgstr "Liens de navigation" + +msgid "Selected entries" +msgstr "Billets sélectionnés" + +msgid "Best of me" +msgstr "À retenir" + +msgid "Blog languages" +msgstr "Langues du blog" + +msgid "With entries counts" +msgstr "Afficher le nombre de billets" + +msgid "Subscribe links" +msgstr "Liens d'abonnement" + +msgid "Subscribe" +msgstr "S'abonner" + +msgid "Feeds type:" +msgstr "Types de fil :" + +msgid "Feed reader" +msgstr "Lecteur de fils de nouvelles" + +msgid "Somewhere else" +msgstr "Ailleurs" + +msgid "Entries limit:" +msgstr "Nombre de billets maximum :" + +msgid "Text" +msgstr "Texte" + +msgid "Text:" +msgstr "Texte :" + +msgid "Last entries" +msgstr "Derniers billets" + +msgid "Uncategorized" +msgstr "Non catégorisé" + +msgid "Tag:" +msgstr "Tag :" + +msgid "Last comments" +msgstr "Derniers commentaires" + +msgid "Comments limit:" +msgstr "Nombre de commentaires maximum :" + +msgid "Home" +msgstr "Accueil" + +msgid "Archives" +msgstr "Archives" + +#, php-format +msgid "This blog's entries %s feed" +msgstr "Fil %s des billets de ce blog" + +#, php-format +msgid "This blog's comments %s feed" +msgstr "Fil %s des commentaires de ce blog" + +msgid "Entries feed" +msgstr "Fil des billets" + +msgid "Comments feed" +msgstr "Fil des commentaires" + +msgid "navigation" +msgstr "navigation" + +msgid "extra" +msgstr "extra" + +msgid "Widgets" +msgstr "Widgets" + +msgid "Are you sure you want to reset sidebars?" +msgstr "Êtes-vous certain de vouloir réinitialiser les bandeaux ?" + +msgid "Available widgets" +msgstr "Widgets disponibles" + +msgid "Append to:" +msgstr "Ajouter à :" + +msgid "add widgets to sidebars" +msgstr "ajouter les widgets aux bandeaux" + +msgid "Navigation sidebar" +msgstr "Bandeau de navigation" + +msgid "Extra sidebar" +msgstr "Bandeau d'extra" + +msgid "update sidebars" +msgstr "Mettre à jour les bandeaux" + +msgid "reset sidebars" +msgstr "Réinitialiser les bandeaux" + +msgid "Widget templates tags" +msgstr "Marqueurs de template des widgets" + +msgid "If you are allowed to edit your theme templates, you can directly add widgets as templates tags, with their own configuration." +msgstr "Si vous avez le droit de modifier les templates de votre thème, vous pouvez directement ajouter des widgets à l'aide de marqueurs de template, avec leur propre configuration." + +msgid "To add a widget in your template, you need to write code like this:" +msgstr "Pour ajouter un widget dans votre template, vous devez écrire un code comme ceci :" + +msgid "Widget ID" +msgstr "Identifiant du widget" + +msgid "Setting name" +msgstr "Nom du paramètre" + +msgid "Setting value" +msgstr "Valeur du paramètre" + +msgid "Here are the following available widgets for your blog:" +msgstr "Voici les widgets disponibles pour votre blog :" + +msgid "Widget ID:" +msgstr "Identifiant du widget :" + +msgid "No setting for this widget" +msgstr "Aucun paramètre pour ce widget" + +msgid "Setting name:" +msgstr "Nom du paramètre :" + +msgid "No widget." +msgstr "Aucun widget." + +msgid "order" +msgstr "ordre" + +msgid "Remove widget" +msgstr "Supprimer le widget" + diff --git a/locales/fr/public.lang.php b/locales/fr/public.lang.php new file mode 100644 index 0000000..e26b166 --- /dev/null +++ b/locales/fr/public.lang.php @@ -0,0 +1,93 @@ +%1$s
    returned no result.'] = 'Votre recherche de %1$s n\'a donné aucun résultat.'; +$GLOBALS['__l10n']['Your search for %1$s returned %2$s result.'] = 'Votre recherche de %1$s a donné %2$s résultat.'; +$GLOBALS['__l10n']['Your search for %1$s returned %2$s results.'] = 'Votre recherche de %1$s a donné %2$s résultats.'; +$GLOBALS['__l10n']['Home'] = 'Accueil'; +$GLOBALS['__l10n']['All keywords'] = 'Tous les mots clés'; +$GLOBALS['__l10n']['Best of me'] = 'À retenir'; +$GLOBALS['__l10n']['Languages'] = 'Langues'; +$GLOBALS['__l10n']['Categories'] = 'Catégories'; +$GLOBALS['__l10n']['Subcategories'] = 'Sous-catégories'; +$GLOBALS['__l10n']['Archives'] = 'Archives'; +$GLOBALS['__l10n']['Links'] = 'Liens'; +$GLOBALS['__l10n']['Subscribe'] = 'S\'abonner'; +$GLOBALS['__l10n']['Entries feed'] = 'Fil des billets'; +$GLOBALS['__l10n']['Comments feed'] = 'Fil des commentaires'; +$GLOBALS['__l10n']['This blog\'s comments Atom feed'] = 'Fil Atom des commentaires de ce blog'; +$GLOBALS['__l10n']['This category\'s entries Atom feed'] = 'Fil Atom des billets de cette catégorie'; +$GLOBALS['__l10n']['This category\'s comments Atom feed'] = 'Fil Atom des commentaires de cette catégorie'; +$GLOBALS['__l10n']['This post\'s comments feed'] = 'Fil des commentaires de ce billet'; +$GLOBALS['__l10n']['This post\'s comments Atom feed'] = 'Fil Atom des commentaires de ce billet'; +$GLOBALS['__l10n']['Attachments'] = 'Annexes'; +$GLOBALS['__l10n']['Permalink'] = 'Lien permanent'; +$GLOBALS['__l10n']['Comments'] = 'Commentaires'; +$GLOBALS['__l10n']['Your comment'] = 'Votre commentaire'; +$GLOBALS['__l10n']['Your comment has been published.'] = 'Votre commentaire a été publié.'; +$GLOBALS['__l10n']['Your comment has been submitted and will be reviewed for publication.'] = 'Votre commentaire a été enregistré et sera publié après validation.'; +$GLOBALS['__l10n']['Add a comment'] = 'Ajouter un commentaire'; +$GLOBALS['__l10n']['Name or nickname'] = 'Nom ou pseudo'; +$GLOBALS['__l10n']['Email address'] = 'Adresse email'; +$GLOBALS['__l10n']['Website'] = 'Site web'; +$GLOBALS['__l10n']['optional'] = 'facultatif'; +$GLOBALS['__l10n']['Comment'] = 'Commentaire'; +$GLOBALS['__l10n']['HTML code is displayed as text and web addresses are automatically converted.'] = 'Le code HTML est affiché comme du texte et les adresses web sont automatiquement transformées.'; +$GLOBALS['__l10n']['Remember me on this blog'] = 'Se souvenir de moi sur ce blog'; +$GLOBALS['__l10n']['preview'] = 'prévisualiser'; +$GLOBALS['__l10n']['send'] = 'envoyer'; +$GLOBALS['__l10n']['They posted on the same topic'] = 'La discussion continue ailleurs'; +$GLOBALS['__l10n']['Trackback URL'] = 'URL de rétrolien'; +$GLOBALS['__l10n']['You must provide an author name'] = 'Vous devez indiquer un nom'; +$GLOBALS['__l10n']['You must provide a comment'] = 'Vous devez écrire un commentaire'; +$GLOBALS['__l10n']['Email address is not valid'] = 'Adresse email incorrecte'; +$GLOBALS['__l10n']['Document not found'] = 'Document non trouvé'; +$GLOBALS['__l10n']['The document you are looking for does not exist.'] = 'Le document que vous cherchez n\'existe pas.'; +$GLOBALS['__l10n']['Powered by %s'] = 'Propulsé par %s'; +$GLOBALS['__l10n']['Subscribe to'] = 'S\'abonner à'; +$GLOBALS['__l10n']['What is an RSS feed?'] = 'Qu\'est ce qu\'un fil RSS ?'; +$GLOBALS['__l10n']['RSS feed is a free blog summary. It provides content (either posts or comments) or summaries of content, together with links to the full versions, and other metadata. The last published items may then be read by your favorite RSS aggregator.'] = 'Un fil RSS recueille les informations de mise à jour d\'un site. Il fournit le contenu des billets ou des commentaires ou un extrait de ceux-ci, ainsi qu\'un lien vers les versions complètes et quelques autres informations. Ce fil a pour vocation d\'être lu par un agrégateur RSS.'; +$GLOBALS['__l10n']['Simply copy the following URL into your aggregator:'] = 'Copier simplement l\'adresse suivante dans votre agrégateur :'; +$GLOBALS['__l10n']['Password needed'] = 'Mot de passe nécessaire'; +$GLOBALS['__l10n']['You must give a password to access this area.'] = 'Vous devez indiquer un mot de passe pour accéder à cette partie.'; +$GLOBALS['__l10n']['Password:'] = 'Mot de passe :'; +$GLOBALS['__l10n']['You must provide a valid email address.'] = 'Vous devez indiquer une adresse e-mail valide.'; +$GLOBALS['__l10n']['Read'] = 'Lire'; +?> \ No newline at end of file diff --git a/locales/fr/public.po b/locales/fr/public.po new file mode 100644 index 0000000..464320f --- /dev/null +++ b/locales/fr/public.po @@ -0,0 +1,237 @@ +# French translation of DotClear +# Copyright (C) 2006. +# Olivier Meunier , 2006. +msgid "" +msgstr "" +"Project-Id-Version: Dotclear 2\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2008-10-13 05:22+0200\n" +"PO-Revision-Date: 2008-07-30 11:52+0100\n" +"Last-Translator: Olivier Meunier \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: French\n" + +msgid "To content" +msgstr "Aller au contenu" + +msgid "To menu" +msgstr "Aller au menu" + +msgid "To search" +msgstr "Aller à la recherche" + +msgid "By" +msgstr "Par" + +msgid "by" +msgstr "par" + +msgid "on" +msgstr "le" + +msgid "On" +msgstr "Le" + +msgid "Continue reading" +msgstr "Lire la suite" + +msgid "no comment" +msgstr "aucun commentaire" + +msgid "one comment" +msgstr "un commentaire" + +msgid "%d comments" +msgstr "%d commentaires" + +msgid "no trackback" +msgstr "aucun rétrolien" + +msgid "one trackback" +msgstr "un rétrolien" + +msgid "%d trackbacks" +msgstr "%d rétroliens" + +msgid "no attachment" +msgstr "aucune annexe" + +msgid "one attachment" +msgstr "une annexe" + +msgid "%d attachments" +msgstr "%d annexes" + +msgid "previous entries" +msgstr "billets précédents" + +msgid "page" +msgstr "page" + +msgid "of" +msgstr "de" + +msgid "next entries" +msgstr "billets suivants" + +msgid "Search" +msgstr "Recherche" + +msgid "Your search for %1$s returned no result." +msgstr "Votre recherche de %1$s n'a donné aucun résultat." + +msgid "Your search for %1$s returned %2$s result." +msgstr "Votre recherche de %1$s a donné %2$s résultat." + +msgid "Your search for %1$s returned %2$s results." +msgstr "Votre recherche de %1$s a donné %2$s résultats." + +msgid "Home" +msgstr "Accueil" + +msgid "All keywords" +msgstr "Tous les mots clés" + +msgid "Best of me" +msgstr "À retenir" + +msgid "Languages" +msgstr "Langues" + +msgid "Categories" +msgstr "Catégories" + +msgid "Subcategories" +msgstr "Sous-catégories" + +msgid "Archives" +msgstr "Archives" + +msgid "Links" +msgstr "Liens" + +msgid "Subscribe" +msgstr "S'abonner" + +msgid "Entries feed" +msgstr "Fil des billets" + +msgid "Comments feed" +msgstr "Fil des commentaires" + +msgid "This blog's comments Atom feed" +msgstr "Fil Atom des commentaires de ce blog" + +msgid "This category's entries Atom feed" +msgstr "Fil Atom des billets de cette catégorie" + +msgid "This category's comments Atom feed" +msgstr "Fil Atom des commentaires de cette catégorie" + +msgid "This post's comments feed" +msgstr "Fil des commentaires de ce billet" + +msgid "This post's comments Atom feed" +msgstr "Fil Atom des commentaires de ce billet" + +msgid "Attachments" +msgstr "Annexes" + +msgid "Permalink" +msgstr "Lien permanent" + +msgid "Comments" +msgstr "Commentaires" + +msgid "Your comment" +msgstr "Votre commentaire" + +msgid "Your comment has been published." +msgstr "Votre commentaire a été publié." + +msgid "Your comment has been submitted and will be reviewed for publication." +msgstr "Votre commentaire a été enregistré et sera publié après validation." + +msgid "Add a comment" +msgstr "Ajouter un commentaire" + +msgid "Name or nickname" +msgstr "Nom ou pseudo" + +msgid "Email address" +msgstr "Adresse email" + +msgid "Website" +msgstr "Site web" + +msgid "optional" +msgstr "facultatif" + +msgid "Comment" +msgstr "Commentaire" + +msgid "HTML code is displayed as text and web addresses are automatically converted." +msgstr "Le code HTML est affiché comme du texte et les adresses web sont automatiquement transformées." + +msgid "Remember me on this blog" +msgstr "Se souvenir de moi sur ce blog" + +msgid "preview" +msgstr "prévisualiser" + +msgid "send" +msgstr "envoyer" + +msgid "They posted on the same topic" +msgstr "La discussion continue ailleurs" + +msgid "Trackback URL" +msgstr "URL de rétrolien" + +msgid "You must provide an author name" +msgstr "Vous devez indiquer un nom" + +msgid "You must provide a comment" +msgstr "Vous devez écrire un commentaire" + +msgid "Email address is not valid" +msgstr "Adresse email incorrecte" + +msgid "Document not found" +msgstr "Document non trouvé" + +msgid "The document you are looking for does not exist." +msgstr "Le document que vous cherchez n'existe pas." + +msgid "Powered by %s" +msgstr "Propulsé par %s" + +msgid "Subscribe to" +msgstr "S'abonner à" + +msgid "What is an RSS feed?" +msgstr "Qu'est ce qu'un fil RSS ?" + +msgid "RSS feed is a free blog summary. It provides content (either posts or comments) or summaries of content, together with links to the full versions, and other metadata. The last published items may then be read by your favorite RSS aggregator." +msgstr "Un fil RSS recueille les informations de mise à jour d'un site. Il fournit le contenu des billets ou des commentaires ou un extrait de ceux-ci, ainsi qu'un lien vers les versions complètes et quelques autres informations. Ce fil a pour vocation d'être lu par un agrégateur RSS." + +msgid "Simply copy the following URL into your aggregator:" +msgstr "Copier simplement l'adresse suivante dans votre agrégateur :" + +msgid "Password needed" +msgstr "Mot de passe nécessaire" + +msgid "You must give a password to access this area." +msgstr "Vous devez indiquer un mot de passe pour accéder à cette partie." + +msgid "Password:" +msgstr "Mot de passe :" + +msgid "You must provide a valid email address." +msgstr "Vous devez indiquer une adresse e-mail valide." + +msgid "Read" +msgstr "Lire" diff --git a/locales/fr/resources.php b/locales/fr/resources.php new file mode 100644 index 0000000..ee941ea --- /dev/null +++ b/locales/fr/resources.php @@ -0,0 +1,22 @@ + 'http://doc.dotclear.net/2.0', + 'Présentation de Dotclear 2' => 'http://doc.dotclear.net/2.0/overview/tour', + "Manuel de l'utilisateur" => 'http://doc.dotclear.net/2.0/usage', + "Guide d'installation et d'administration" => 'http://doc.dotclear.net/2.0/admin' +); +?> \ No newline at end of file diff --git a/plugins/.htaccess b/plugins/.htaccess new file mode 100644 index 0000000..14249c5 --- /dev/null +++ b/plugins/.htaccess @@ -0,0 +1 @@ +Deny from all \ No newline at end of file diff --git a/plugins/aboutConfig/_admin.php b/plugins/aboutConfig/_admin.php new file mode 100644 index 0000000..39e987b --- /dev/null +++ b/plugins/aboutConfig/_admin.php @@ -0,0 +1,17 @@ +addItem('about:config','plugin.php?p=aboutConfig','index.php?pf=aboutConfig/icon.png', + preg_match('/plugin.php\?p=aboutConfig(&.*)?$/',$_SERVER['REQUEST_URI']), + $core->auth->isSuperAdmin()); +?> \ No newline at end of file diff --git a/plugins/aboutConfig/_define.php b/plugins/aboutConfig/_define.php new file mode 100644 index 0000000..c5c4019 --- /dev/null +++ b/plugins/aboutConfig/_define.php @@ -0,0 +1,21 @@ +registerModule( + /* Name */ "about:config", + /* Description*/ "Manage every blog configuration directive", + /* Author */ "Olivier Meunier", + /* Version */ '0.2', + /* Permissions */ null +); +?> \ No newline at end of file diff --git a/plugins/aboutConfig/icon.png b/plugins/aboutConfig/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..426cd27ed292a2edb316e29b25ed6f8f4c3630c0 GIT binary patch literal 776 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJbFq_W2nPqp?T7vk7#J9X1AIbU z|NsBLb?er(YuC=4In&Y65y%EILPJB1jg3#wM%cXv(QyLa#PowKj)oP2e6@|ErJKzkpot3J0W?#jjxps}Yn*qmElv}M(Tb4%lZ zR%~5XxN%YC-UTr`=9TZ6n|NqO&g$6}KzmnCFW%o{zpu*+=)x&ob=zBf_cvN^Z_zza zs|R$_o*Jz+^#(gCbXFD_ca}zM$kAAwZ!obyYkr#i(nLm}Uncr<0fQ^T-!02W2R`tjSRt@R_~*K|(4u>3mT_G`s0`yzx*1J>_7`}g)8 z{>8?{$7XFTd&}Bb7c+yYDmP>O_dN<1ekwMU=zM#1<~B#kzZF+lmpFf|Dy$QDV|U+k zqjbWCFB^;gfBkZE#}{iJhOJL?zP+uUxXOy5VgIM!e^R6w{xC}))^*)3vq}-@Sq4v6 KKbLh*2~7asM`s8C literal 0 HcmV?d00001 diff --git a/plugins/aboutConfig/index.php b/plugins/aboutConfig/index.php new file mode 100644 index 0000000..dfdc3cf --- /dev/null +++ b/plugins/aboutConfig/index.php @@ -0,0 +1,179 @@ + $s) + { + $core->blog->settings->setNameSpace($ns); + + foreach ($s as $k => $v) { + $core->blog->settings->put($k,$v); + } + + $core->blog->triggerBlog(); + } + + http::redirect($p_url.'&upd=1'); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} + +# Global settings update +if (!empty($_POST['gs']) && is_array($_POST['gs'])) +{ + try + { + foreach ($_POST['gs'] as $ns => $s) + { + $core->blog->settings->setNameSpace($ns); + + foreach ($s as $k => $v) { + $core->blog->settings->put($k,$v,null,null,true,true); + } + + $core->blog->triggerBlog(); + } + + http::redirect($p_url.'&upd=1&part=global'); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} + +$part = !empty($_GET['part']) && $_GET['part'] == 'global' ? 'global' : 'local'; + +function settingLine($id,$s,$ns,$field_name,$strong_label) +{ + if ($s['type'] == 'boolean') { + $field = form::combo(array($field_name.'['.$ns.']['.$id.']',$field_name.'_'.$id), + array(__('yes') => 1, __('no') => 0),$s['value']); + } else { + $field = form::field(array($field_name.'['.$ns.']['.$id.']',$field_name.'_'.$id),40,null, + html::escapeHTML($s['value'])); + } + + $slabel = $strong_label ? '%s' : '%s'; + + return + ''. + ''. + ''.$field.''. + ''.$s['type'].''. + ''.html::escapeHTML($s['label']).''. + ''; +} +?> + + + about:config + + + + + +'.__('Configuration successfully updated').'

    '; +} + +if (!empty($_GET['upda'])) { + echo '

    '.__('Settings definition successfully updated').'

    '; +} +?> +

    blog->name); ?> › about:config

    + +
    +
    + + + + + + + +blog->settings->dumpSettings() as $k => $v) { + $settings[$v['ns']][$k] = $v; +} + +ksort($settings); + +foreach ($settings as $ns => $s) +{ + ksort($s); + echo ''; + + foreach ($s as $k => $v) + { + echo settingLine($k,$v,$ns,'s',!$v['global']); + } +} +?> +
    Setting ID
    namespace: '.$ns.'
    +

    + +formNonce(); ?>

    +
    +
    + +
    +
    + + + + + + + +blog->settings->dumpGlobalSettings() as $k => $v) { + $settings[$v['ns']][$k] = $v; +} + +ksort($settings); + +foreach ($settings as $ns => $s) +{ + ksort($s); + echo ''; + + foreach ($s as $k => $v) + { + echo settingLine($k,$v,$ns,'gs',false); + } +} +?> +
    Setting ID
    namespace: '.$ns.'
    +

    + +formNonce(); ?>

    +
    +
    + + + \ No newline at end of file diff --git a/plugins/accessibleCaptcha/LICENSE b/plugins/accessibleCaptcha/LICENSE new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/plugins/accessibleCaptcha/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/plugins/accessibleCaptcha/_define.php b/plugins/accessibleCaptcha/_define.php new file mode 100644 index 0000000..9bafb48 --- /dev/null +++ b/plugins/accessibleCaptcha/_define.php @@ -0,0 +1,12 @@ +registerModule( + /* Name */ "Accessible Captcha", + /* Description*/ "This is an accessible captcha", + /* Author */ "Julien Wajsberg", + /* Version */ '1.2', + /* Permissions */ 'usage,contentadmin', + /* Priority */ 200 +); +?> diff --git a/plugins/accessibleCaptcha/_install.php b/plugins/accessibleCaptcha/_install.php new file mode 100644 index 0000000..f57f898 --- /dev/null +++ b/plugins/accessibleCaptcha/_install.php @@ -0,0 +1,67 @@ + + + This file is part of dotclear-accessible-captcha. + + dotclear-accessible-captcha is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, version 3 of the License. + + Foobar is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Foobar. If not, see . +*/ + +if (!defined('DC_CONTEXT_ADMIN')) { return; } + +// c'est le nom du répertoire +$moduleName = "accessibleCaptcha"; + +# On lit la version du plugin +$m_version = $core->plugins->moduleInfo($moduleName, 'version'); + +# On lit la version du plugin dans la table des versions +$i_version = $core->getVersion($moduleName); + +# La version dans la table est supérieure ou égale à +# celle du module, on ne fait rien puisque celui-ci +# est installé +//echo $i_version . '
    ' . $m_version . '
    '; + +if (version_compare($i_version, $m_version,'>=')) { + return; +} + +$s = new dbStruct($core->con,$core->prefix); +$s->captcha + ->id('bigint', 0, false) + ->question('varchar', 150, false) + ->answer('varchar', 150, false) + ->blog_id('varchar', 32, false) + + ->primary('pk_captcha', 'id') + ->index('idx_captcha_blog_btree', 'btree', 'blog_id') + ->reference('fk_captcha_blog', 'blog_id', 'blog', 'blog_id', 'cascade', 'cascade'); + +$s->captcha_hash + ->id('bigint', 0, false) + ->hash('varchar', 150, false) + ->captcha_id('bigint', 0, false) + ->timestamp('timestamp', 0, false) + + ->primary('pk_captcha_hash', 'id') + ->index('idx_captcha_hash_btree', 'btree', 'hash') + ->reference('fk_captcha_hash_captcha', 'captcha_id', 'captcha', 'id', 'cascade', 'cascade'); + +$si = new dbStruct($core->con,$core->prefix); +$changes = $si->synchronize($s); + +# La procédure d'installation commence vraiment là +$core->setVersion($moduleName, $m_version); +return true; + diff --git a/plugins/accessibleCaptcha/_prepend.php b/plugins/accessibleCaptcha/_prepend.php new file mode 100644 index 0000000..4c06b16 --- /dev/null +++ b/plugins/accessibleCaptcha/_prepend.php @@ -0,0 +1,34 @@ + + + This file is part of dotclear-accessible-captcha. + + dotclear-accessible-captcha is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, version 3 of the License. + + Foobar is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Foobar. If not, see . +*/ + +if (!defined('DC_RC_PATH')) { return; } + +global $__autoload, $core; +$__autoload['dcFilterAccessibleCaptcha'] = dirname(__FILE__).'/class.dc.filter.accessible.captcha.php'; +$__autoload['AccessibleCaptcha'] = dirname(__FILE__).'/class.accessible.captcha.php'; + + +$core->spamfilters[] = 'dcFilterAccessibleCaptcha'; + +$core->addBehavior('publicCommentFormAfterContent', + array('dcFilterAccessibleCaptcha','publicCommentFormAfterContent')); + +$core->addBehavior('exportFull',array('dcFilterAccessibleCaptcha','exportFull')); +$core->addBehavior('exportSingle',array('dcFilterAccessibleCaptcha','exportSingle')); +?> diff --git a/plugins/accessibleCaptcha/class.accessible.captcha.php b/plugins/accessibleCaptcha/class.accessible.captcha.php new file mode 100644 index 0000000..cff843c --- /dev/null +++ b/plugins/accessibleCaptcha/class.accessible.captcha.php @@ -0,0 +1,303 @@ + + + This file is part of dotclear-accessible-captcha. + + dotclear-accessible-captcha is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, version 3 of the License. + + Foobar is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Foobar. If not, see . +*/ + +class AccessibleCaptcha { + // nom des tables + public static $table = "captcha"; + private static $table_hash = "captcha_hash"; + + // ttl des hash en minutes + // devrait être en settings ? + private static $hash_ttl_min = 60; // 1h + + + // ----- méthodes publiques ----- + + /** + * retourne une question au pif et crée un hash dans la base de données. + * Ce hash fait l'association entre cette question et le formulaire, et sera supprimé + * lorsque la question sera répondue. + * @param $blog_id l'id du blog + * @return le hash créé et inséré dans la base + */ + public function getRandomQuestionAndHash($blog_id) { + $question = $this->getRandomQuestion($blog_id); + $question['hash'] = $this->setAndReturnHashForQuestion($question['id']); + return $question; + } + + /** + * vérifie une réponse par rapport à un hash + * si la réponse est correcte, on supprime le hash + * cette méthode supprime aussi les hash obsolètes + * @param $hash le hash correspondant à la question à vérifier + * @param $answer la réponse à vérifier + * @return true si la réponse est juste + */ + public function isAnswerCorrectForHash($hash, $answer) { + if ($this->checkAnswer($hash, $answer)) { + $this->removeHash($hash); + return true; + } + + // si non + return false; + } + + /** + * Retourne la question associée à un hash en particulier + * @param $hash le hash correspondant à la question à récupérer + * @return la question associée au hash + */ + public function getQuestionForHash($hash) { + global $core; + $con =& $core->con; + + $query = 'select c.id as id, c.question as question ' + . 'from ' . $core->prefix . self::$table . ' as c, ' . $core->prefix . self::$table_hash . ' as ch ' + . " where ch.hash = '" . $con->escape($hash) . "' and ch.captcha_id = c.id "; + + $question = $con->select($query); + + return array( + 'id' => $question->id, + 'question' => $question->question, + 'hash' => $hash + ); + } + + // ----- fin des méthodes publiques ----- + + + // ----- méthodes privées ----- + + /** + * retourne une question au pif + * cette méthode initialise une question pour ce blog s'il n'en existe pas encore + * @return une question au pif + */ + private function getRandomQuestion($blog_id) { + + $this->checkAndInitQuestions($blog_id); + // on récupère le nombre de questions + $count = $this->getCountQuestions($blog_id); + // on demande la nieme + $rand = rand(0, $count - 1); + // on va récupérer la nieme + $question = $this->getQuestionInOrder($blog_id, $rand); + return $question; + } + + + private function getQuestionInOrder($blog_id, $nb) { + global $core; + $con =& $core->con; + + $query = 'select id, question from ' . $core->prefix . self::$table . + " where blog_id = '" . $con->escape($blog_id) . "' order by id asc " + . $con->limit($nb, 1); + + $question = $con->select($query); + return array( + 'id' => $question->id, + 'question' => $question->question, + ); + } + + private function checkAnswer($hash, $answer) { + global $core; + $con =& $core->con; + + // vérifions que la réponse est correcte + $query = 'select count(c.id) from ' . $core->prefix . self::$table . ' as c, ' . $core->prefix . self::$table_hash . ' as ch ' + . " where ch.hash = '" . $con->escape($hash) . "' and ch.captcha_id = c.id " + . " and c.answer = '" . $con->escape($answer) . "'"; + $count = $con->select($query)->f(0); + + return ($count > 0); + } + + private function removeHash($hash) { + global $core; + $con =& $core->con; + + $query = 'delete from ' . $core->prefix . self::$table_hash . " where hash = '" . $con->escape($hash) . "'"; + + // et on en profite pour enlever les anciens + $expired_timestamp = gmmktime(gmdate('H'), gmdate('i') - self::$hash_ttl_min); + $expired_datetime = gmdate('Y-m-d H:i:s', $expired_timestamp); + $query .= " or timestamp < '" . $con->escape($expired_datetime) . "'"; + $con->execute($query); + } + + /** + * retourne une question en particulier + * @param $id id de la question à retourner + * @ return Question qui à l'$id passé en paramètre + */ + private function getQuestion($id) { + global $core; + $con =& $core->con; + + $query = 'select question, answer from ' . $core->prefix . self::$table . " where id = '" . $con->escape($id) ."'"; + $question = $con->select($query); + + return array( + 'id' => $id, + 'question' => $question->question, + 'answer' => $question->answer + ); + } + + private function setAndReturnHashForQuestion($id) { + global $core; + $con =& $core->con; + + $con->writeLock($core->prefix . self::$table_hash); + try { + $new_id = $con->select( + 'SELECT MAX(id) '. + 'FROM '. $core->prefix . self::$table_hash + )->f(0) + 1; + + $hash = $this->getHash(); + $cur = $con->openCursor($core->prefix . self::$table_hash); + $cur->captcha_id = $id; + $cur->id = $new_id; + $cur->timestamp = gmdate('Y-m-d H:i:s'); + $cur->hash = $hash; + + $cur->insert(); + + $con->unlock(); + } catch (Exception $e) { + $con->unlock(); + throw $e; + } + + return $hash; + } + + // on va supposer que c'est suffisamment random pour un captcha + private function getHash() { + $key = http::browserUID(crypt::hmac(DC_MASTER_KEY,crypt::createPassword())); + return $key; + } + + private function getCountQuestions($blog_id) { + global $core; + $con =& $core->con; + + $query = 'select count(id) from '. $core->prefix . self::$table . " where blog_id = '" . $con->escape($blog_id) . "'"; + $count = $con->select($query)->f(0); + return $count; + } + + private function checkAndInitQuestions($blog_id) { + global $core; + $con =& $core->con; + + $con->writeLock($core->prefix . self::$table); + + try { + $count = $this->getCountQuestions($blog_id); + if ($count == 0) { + $this->initQuestions($blog_id); + } + $con->unlock(); + } catch (Exception $e) { + $con->unlock(); + throw $e; + } + } + + public function initQuestions($blog_id) { + global $core; + $con =& $core->con; + + // on supprime tout + $delete_query = 'delete from ' . $core->prefix . self::$table . " where blog_id = '" . $con->escape($blog_id) . "'"; + $con->execute($delete_query); + + // et on ajoute la question par défaut + $this->addQuestion( + $blog_id, + __("What makes two plus two?"), + __("4") + ); + } + + public function addQuestion($blog_id, $question, $answer, $id = -1) { + global $core; + $con =& $core->con; + + // calculate new id + $new_id = $con->select( + 'SELECT MAX(id) '. + 'FROM '. $core->prefix . self::$table + )->f(0); + + if (is_numeric($new_id)) { + $new_id++; + } else { + // no id yet + $new_id = 0; + } + + $cur = $con->openCursor($core->prefix . self::$table); + $cur->id = $new_id; + $cur->question = $question; + $cur->answer = $answer; + $cur->blog_id = $blog_id; + $cur->insert(); + } + + public function getAllQuestions($blog_id) { + global $core; + $con =& $core->con; + + $query = "select id, question, answer from " . $core->prefix . self::$table . " where blog_id = '" . $con->escape($blog_id) . "'"; + $rs = $con->select($query); + + $result = array(); + while($rs->fetch()) { + $result[] = array( + "id" => $rs->id, + "question" => $rs->question, + "answer" => $rs->answer + ); + } + return $result; + } + + public function removeQuestions($blog_id, $arr_ids) { + global $core; + $con =& $core->con; + + $delete_query = 'delete from ' . $core->prefix . self::$table . " where blog_id = '" . $con->escape($blog_id) . "'" . + ' and (false'; + foreach($arr_ids as $id) { + $delete_query .= " or id = '" . $con->escape($id) . "'"; + } + $delete_query .= ')'; + + $con->execute($delete_query); + + } +} diff --git a/plugins/accessibleCaptcha/class.dc.filter.accessible.captcha.php b/plugins/accessibleCaptcha/class.dc.filter.accessible.captcha.php new file mode 100644 index 0000000..eb95c83 --- /dev/null +++ b/plugins/accessibleCaptcha/class.dc.filter.accessible.captcha.php @@ -0,0 +1,182 @@ + + + This file is part of dotclear-accessible-captcha. + + dotclear-accessible-captcha is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, version 3 of the License. + + Foobar is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Foobar. If not, see . +*/ + +class dcFilterAccessibleCaptcha extends dcSpamFilter +{ + public $name = 'Accessible Captcha'; + public $has_gui = true; + private $style_p = 'margin: .2em 0; padding: 0 0.5em; '; + private $style_answer = 'margin: 0 0 0 .5em; '; + + protected function setInfo() + { + $this->description = __('This is an accessible captcha.'); + } + + public function isSpam($type,$author,$email,$site,$ip,$content,$post_id,&$status) { + $accessibleCaptcha = new AccessibleCaptcha(); + + $question_hash = $_POST['c_question_hash']; + $answer = $_POST['c_answer']; + if (! $answer) { + $status = 'Filtered'; + return true; + } + + if (! $accessibleCaptcha->isAnswerCorrectForHash($question_hash, $answer)) { + $status = 'Filtered'; + return true; + } + } + + public function getStatusMessage($status, $comment_id) { + return sprintf(__('Filtered by %s.'),$this->guiLink()); + } + + public static function publicCommentFormAfterContent($core, $_ctx) { + $accessibleCaptcha = new AccessibleCaptcha(); + + if (($hash = $_POST['c_question_hash'])) { + $question = $accessibleCaptcha->getQuestionForHash($hash); + } else { + $question = $accessibleCaptcha->getRandomQuestionAndHash($core->blog->id); + } + + $escaped_value = htmlspecialchars($_POST['c_answer'], ENT_QUOTES); + $escaped_question = htmlspecialchars($question['question'], ENT_QUOTES); + $escaped_hash = htmlspecialchars($question['hash'], ENT_QUOTES); + + echo "

    + + +

    "; + } + + // plugin d'import export + public static function exportFull($core, $exp) { + $exp->exportTable(AccessibleCaptcha::$table); + } + + public static function exportSingle($core, $exp, $blog_id) { + $exp->export(AccessibleCaptcha::$table, + 'SELECT * '. + 'FROM '. $core->prefix . AccessibleCaptcha::$table . ' '. + "WHERE blog_id = '{$blog_id}'" + ); + } + // fin des méthodes pour le plugin d'import export + + // pour la gui + public function gui($url) { + global $core; + + $accessibleCaptcha = new AccessibleCaptcha(); + + // ajout de questions + if (! (empty($_POST['c_question']) || empty($_POST['c_answer']))) { + $accessibleCaptcha->addQuestion( + $core->blog->id, + $_POST['c_question'], + $_POST['c_answer'] + ); + + // redirection pour que l'user puisse faire "reload" + http::redirect($url.'&added=1'); + } + + // suppression de questions + if (! empty($_POST['c_d_questions']) && is_array($_POST['c_d_questions'])) { + $accessibleCaptcha->removeQuestions($core->blog->id, $_POST['c_d_questions']); + http::redirect($url.'&deleted=1'); + } + + // réinit + if (! empty($_POST['c_createlist'])) { + $accessibleCaptcha->initQuestions($core->blog->id); + http::redirect($url.'&reset=1'); + } + + // assez joué, maintenant on affiche + $res = ''; + + if (!empty($_GET['added'])) { + $res .= '

    '.__('Question has been successfully added.').'

    '; + } + if (!empty($_GET['deleted'])) { + $res .= '

    '.__('Questions have been successfully removed.').'

    '; + } + if (!empty($_GET['reset'])) { + $res .= '

    '.__('Questions list has been successfully reinitialized.').'

    '; + } + + $res .= + '
    '. + '
    '.__('Add a question').''. + '

    '. + '

    '; + $res .= + $core->formNonce(). + '

    '. + '
    '. + '
    '; + + $allquestions = $accessibleCaptcha->getAllQuestions($core->blog->id); + + + $res .= '
    '. + '
    ' . __('Question list') . ''; + + foreach($allquestions as $question) { + $res .= '

    '; + } + + $res .= '

    '. $core->formNonce() . + '

    '; + + $res .= "
    "; + + $res .= + '
    ' . + '

    ' . + form::hidden(array('c_createlist'), 1) . + $core->formNonce().'

    ' . + '
    '; + + $disableText = __('To disable this plugin, you need to disable it %sfrom the plugins page%s.'); + $disableText = sprintf($disableText, '', ''); + + $res .= + '

    '.$disableText.'

    '; + + return $res; + + } + +} + diff --git a/plugins/accessibleCaptcha/locales/fr/main.po b/plugins/accessibleCaptcha/locales/fr/main.po new file mode 100644 index 0000000..7eb9afc --- /dev/null +++ b/plugins/accessibleCaptcha/locales/fr/main.po @@ -0,0 +1,87 @@ +# French translations for dotclear-accessible-captcha package. +# Copyright (C) 2009 Julien Wajsberg +# This file is distributed under the same license as the dotclear-accessible-captcha package. +# Julien Wajsberg , 2009. +# +msgid "" +msgstr "" +"Project-Id-Version: dotclear-acessible-captcha 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-03-29 19:13+0100\n" +"PO-Revision-Date: 2009-11-22 15:22+0100\n" +"Last-Translator: Julien Wajsberg \n" +"Language-Team: French\n" +"Language: French\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#: class.accessible.captcha.php:241 +msgid "What makes two plus two?" +msgstr "Combien font deux plus deux ?" + +#: class.accessible.captcha.php:242 +msgid "4" +msgstr "4" + +#: class.dc.filter.accessible.captcha.php:29 +msgid "This is an accessible captcha." +msgstr "Ce plugin implémente un captcha accessible." + +#: class.dc.filter.accessible.captcha.php:49 +#, php-format +msgid "Filtered by %s." +msgstr "Filtré par %s" + +#: class.dc.filter.accessible.captcha.php:119 +msgid "Question has been successfully added." +msgstr "La question a été ajoutée." + +#: class.dc.filter.accessible.captcha.php:122 +msgid "Questions have been successfully removed." +msgstr "Les questions ont été supprimées." + +#: class.dc.filter.accessible.captcha.php:125 +msgid "Questions list has been successfully reinitialized." +msgstr "La liste des questions a été réinitialisée." + +#: class.dc.filter.accessible.captcha.php:130 +msgid "Add a question" +msgstr "Ajouter une question" + +#: class.dc.filter.accessible.captcha.php:131 +msgid "Question to add:" +msgstr "Question à ajouter :" + +#: class.dc.filter.accessible.captcha.php:134 +#: class.dc.filter.accessible.captcha.php:154 +msgid "Answer:" +msgstr "Réponse :" + +#: class.dc.filter.accessible.captcha.php:139 +msgid "Add" +msgstr "Ajouter" + +#: class.dc.filter.accessible.captcha.php:147 +msgid "Question list" +msgstr "Liste des questions" + +#: class.dc.filter.accessible.captcha.php:152 +msgid "Question:" +msgstr "Question :" + +#: class.dc.filter.accessible.captcha.php:160 +msgid "Delete selected questions" +msgstr "Supprimer les questions sélectionnées" + +#: class.dc.filter.accessible.captcha.php:166 +msgid "Reset the list" +msgstr "Réinitialiser la liste des questions" + +#: class.dc.filter.accessible.captcha.php:171 +#, php-format +msgid "" +"To disable this plugin, you need to disable it %sfrom the plugins page%s." +msgstr "" +"Pour désactiver ce plugin, vous devez le faire %sdepuis la page générale des plugins%s." diff --git a/plugins/akismet/_define.php b/plugins/akismet/_define.php new file mode 100644 index 0000000..fec101a --- /dev/null +++ b/plugins/akismet/_define.php @@ -0,0 +1,22 @@ +registerModule( + /* Name */ "Akismet", + /* Description*/ "Akismet interface for Dotclear", + /* Author */ "Olivier Meunier", + /* Version */ '1.0', + /* Permissions */ 'usage,contentadmin', + /* Priority */ 200 +); +?> \ No newline at end of file diff --git a/plugins/akismet/_prepend.php b/plugins/akismet/_prepend.php new file mode 100644 index 0000000..3d1fd40 --- /dev/null +++ b/plugins/akismet/_prepend.php @@ -0,0 +1,17 @@ +spamfilters[] = 'dcFilterAkismet'; +?> \ No newline at end of file diff --git a/plugins/akismet/class.dc.filter.akismet.php b/plugins/akismet/class.dc.filter.akismet.php new file mode 100644 index 0000000..88cb167 --- /dev/null +++ b/plugins/akismet/class.dc.filter.akismet.php @@ -0,0 +1,260 @@ +auth->isSuperAdmin()) { + $this->has_gui = false; + } + } + + protected function setInfo() + { + $this->description = __('Akismet spam filter'); + } + + public function getStatusMessage($status,$comment_id) + { + return sprintf(__('Filtered by %s.'),$this->guiLink()); + } + + private function akInit() + { + $blog =& $this->core->blog; + + if (!$blog->settings->ak_key) { + return false; + } + + return new akismet($blog->url,$blog->settings->ak_key); + } + + public function isSpam($type,$author,$email,$site,$ip,$content,$post_id,&$status) + { + if (($ak = $this->akInit()) === false) { + return; + } + + $blog =& $this->core->blog; + + try + { + if ($ak->verify()) + { + $post = $blog->getPosts(array('post_id' => $post_id)); + + $c = $ak->comment_check( + $post->getURL(), + $type, + $author, + $email, + $site, + $content + ); + + if ($c) { + $status = 'Filtered by Akismet'; + return true; + } + } + } catch (Exception $e) {} # If http or akismet is dead, we don't need to know it + } + + public function trainFilter($status,$filter,$type,$author,$email,$site,$ip,$content,$rs) + { + # We handle only false positive from akismet + if ($status == 'spam' && $filter != 'dcFilterAkismet') + { + return; + } + + $f = $status == 'spam' ? 'submit_spam' : 'submit_ham'; + + if (($ak = $this->akInit()) === false) { + return; + } + + try + { + if ($ak->verify()) { + $ak->{$f}($rs->getPostURL(),$type,$author,$email,$site,$content); + } + } catch (Exception $e) {} # If http or akismet is dead, we don't need to know it + } + + public function gui($url) + { + $blog =& $this->core->blog; + + $ak_key = $blog->settings->ak_key; + $ak_verified = null; + + if (isset($_POST['ak_key'])) + { + try + { + $ak_key = $_POST['ak_key']; + + $blog->settings->setNameSpace('akismet'); + $blog->settings->put('ak_key',$ak_key,'string'); + + http::redirect($url.'&up=1'); + } + catch (Exception $e) + { + $this->core->error->add($e->getMessage()); + } + } + + if ($blog->settings->ak_key) + { + try { + $ak = new akismet($blog->url,$blog->settings->ak_key); + $ak_verified = $ak->verify(); + } catch (Exception $e) { + $this->core->error->add($e->getMessage()); + } + } + + $res = + '
    '. + '

    '; + + if ($ak_verified !== null) { + if ($ak_verified) { + $res .= ' '.__('API key verified'); + } else { + $res .= ' '.__('API key not verified'); + } + } + + $res .= '

    '; + + $res .= + '

    '.__('Get your own API key').'

    '. + '

    '. + $this->core->formNonce().'

    '. + '
    '; + + return $res; + } +} + +class akismet extends netHttp +{ + protected $base_host = 'rest.akismet.com'; + protected $ak_host = ''; + protected $ak_version = '1.1'; + protected $ak_path = '/%s/%s'; + + protected $ak_key = null; + protected $blog_url; + + protected $timeout = 3; + + public function __construct($blog_url,$api_key) + { + $this->blog_url = $blog_url; + $this->ak_key = $api_key; + + $this->ak_path = sprintf($this->ak_path,$this->ak_version,'%s'); + $this->ak_host = $this->ak_key.'.'.$this->base_host; + + parent::__construct($this->ak_host,80); + } + + public function verify() + { + $this->host = $this->base_host; + $path = sprintf($this->ak_path,'verify-key'); + + $data = array( + 'key' => $this->ak_key, + 'blog' => $this->blog_url + ); + + if ($this->post($path,$data,'UTF-8')) + { + return $this->getContent() == 'valid'; + } + + return false; + } + + public function comment_check($permalink,$type,$author,$email,$url,$content) + { + $info_ignore = array('HTTP_COOKIE'); + $info = array(); + + foreach ($_SERVER as $k => $v) { + if (strpos($k,'HTTP_') === 0 && !in_array($k,$info_ignore)) { + $info[$k] = $v; + } + } + + return $this->callFunc('comment-check',$permalink,$type,$author,$email,$url,$content,$info); + } + + public function submit_spam($permalink,$type,$author,$email,$url,$content) + { + $this->callFunc('submit-spam',$permalink,$type,$author,$email,$url,$content); + return true; + } + + public function submit_ham($permalink,$type,$author,$email,$url,$content) + { + $this->callFunc('submit-ham',$permalink,$type,$author,$email,$url,$content); + return true; + } + + protected function callFunc($function,$permalink,$type,$author,$email,$url,$content,$info=array()) + { + $ua = isset($info['HTTP_USER_AGENT']) ? $info['HTTP_USER_AGENT'] : ''; + $referer = isset($info['HTTP_REFERER']) ? $info['HTTP_REFERER'] : ''; + + # Prepare comment data + $data = array( + 'blog' => $this->blog_url, + 'user_ip' => http::realIP(), + 'user_agent' => $ua, + 'referrer' => $referer, + 'permalink' => $permalink, + 'comment_type' => $type, + 'comment_author' => $author, + 'comment_author_email' => $email, + 'comment_author_url' => $url, + 'comment_content' => $content + ); + + $data = array_merge($data,$info); + + $this->host = $this->ak_host; + $path = sprintf($this->ak_path,$function); + + if (!$this->post($path,$data,'UTF-8')) { + throw new Exception('HTTP error: '.$this->getError()); + } + + return $this->getContent() == 'true'; + } +} +?> \ No newline at end of file diff --git a/plugins/antispam/_admin.php b/plugins/antispam/_admin.php new file mode 100644 index 0000000..758b0d9 --- /dev/null +++ b/plugins/antispam/_admin.php @@ -0,0 +1,51 @@ +addItem(__('Antispam'),'plugin.php?p=antispam','index.php?pf=antispam/icon.png', + preg_match('/plugin.php\?p=antispam(&.*)?$/',$_SERVER['REQUEST_URI']), + $core->auth->check('admin',$core->blog->id)); + +$core->addBehavior('coreAfterCommentUpdate',array('dcAntispam','trainFilters')); +$core->addBehavior('adminAfterCommentDesc',array('dcAntispam','statusMessage')); +$core->addBehavior('adminDashboardIcons',array('dcAntispam','dashboardIcon')); + +if (!DC_ANTISPAM_CONF_SUPER || $core->auth->isSuperAdmin()) { + $core->addBehavior('adminBlogPreferencesForm',array('antispamBehaviors','adminBlogPreferencesForm')); + $core->addBehavior('adminBeforeBlogSettingsUpdate',array('antispamBehaviors','adminBeforeBlogSettingsUpdate')); +} + +class antispamBehaviors +{ + public static function adminBlogPreferencesForm(&$core,&$settings) + { + echo + '
    Antispam'. + '

    '. + '
    '; + } + + public static function adminBeforeBlogSettingsUpdate(&$settings) + { + $settings->setNameSpace('antispam'); + $settings->put('antispam_moderation_ttl',(integer)$_POST['antispam_moderation_ttl']); + $settings->setNameSpace('system'); + } +} +?> \ No newline at end of file diff --git a/plugins/antispam/_define.php b/plugins/antispam/_define.php new file mode 100644 index 0000000..39d91f8 --- /dev/null +++ b/plugins/antispam/_define.php @@ -0,0 +1,22 @@ +registerModule( + /* Name */ "Antispam", + /* Description*/ "Generic antispam plugin for Dotclear", + /* Author */ "Alain Vagner", + /* Version */ '1.2', + /* Permissions */ 'usage,contentadmin', + /* Priority */ 10 +); +?> \ No newline at end of file diff --git a/plugins/antispam/_install.php b/plugins/antispam/_install.php new file mode 100644 index 0000000..6ffb734 --- /dev/null +++ b/plugins/antispam/_install.php @@ -0,0 +1,52 @@ +plugins->moduleInfo('antispam','version'); +if (version_compare($core->getVersion('antispam'),$version,'>=')) { + return; +} + +/* Database schema +-------------------------------------------------------- */ +$s = new dbStruct($core->con,$core->prefix); + +$s->spamrule + ->rule_id ('bigint', 0, false) + ->blog_id ('varchar', 32, true) + ->rule_type ('varchar', 16, false, "'word'") + ->rule_content ('varchar', 128, false) + + ->primary('pk_spamrule','rule_id') + ; + +$s->spamrule->index('idx_spamrule_blog_id','btree','blog_id'); +$s->spamrule->reference('fk_spamrule_blog','blog_id','blog','blog_id','cascade','cascade'); + +if ($s->driver() == 'pgsql') { + $s->spamrule->index('idx_spamrule_blog_id_null','btree','(blog_id IS NULL)'); +} + +# Schema installation +$si = new dbStruct($core->con,$core->prefix); +$changes = $si->synchronize($s); + +# Creating default wordslist +if ($core->getVersion('antispam') === null) { + $_o = new dcFilterWords($core); + $_o->defaultWordsList(); + unset($_o); +} + +$core->setVersion('antispam',$version); +return true; +?> \ No newline at end of file diff --git a/plugins/antispam/_prepend.php b/plugins/antispam/_prepend.php new file mode 100644 index 0000000..1f16bbd --- /dev/null +++ b/plugins/antispam/_prepend.php @@ -0,0 +1,30 @@ +spamfilters = array('dcFilterIP','dcFilterWords','dcFilterIpLookup','dcFilterLinksLookup'); + +$core->url->register('spamfeed','spamfeed','^spamfeed/(.+)$',array('dcAntispamURL','spamFeed')); +$core->url->register('hamfeed','hamfeed','^hamfeed/(.+)$',array('dcAntispamURL','hamFeed')); +?> \ No newline at end of file diff --git a/plugins/antispam/_public.php b/plugins/antispam/_public.php new file mode 100644 index 0000000..2d7cf87 --- /dev/null +++ b/plugins/antispam/_public.php @@ -0,0 +1,17 @@ +addBehavior('publicBeforeCommentCreate',array('dcAntispam','isSpam')); +$core->addBehavior('publicBeforeTrackbackCreate',array('dcAntispam','isSpam')); +$core->addBehavior('publicBeforeDocument',array('dcAntispam','purgeOldSpam')); +?> \ No newline at end of file diff --git a/plugins/antispam/antispam.js b/plugins/antispam/antispam.js new file mode 100644 index 0000000..8f243e9 --- /dev/null +++ b/plugins/antispam/antispam.js @@ -0,0 +1,3 @@ + +var dragsort=ToolMan.dragsort();$(function(){$("#filters-list").each(function(){dragsort.makeTableSortable(this,dotclear.sortable.setHandle,dotclear.sortable.saveOrder);});});dotclear.sortable={setHandle:function(item){var handle=$(item).find('td.handle').get(0);while(handle.firstChild){handle.removeChild(handle.firstChild);} +item.toolManDragGroup.setHandle(handle);$(handle).addClass('handler');},saveOrder:function(item){var group=item.toolManDragGroup;var order=$('#filters_order').get(0);group.register('dragend',function(){order.value='';items=item.parentNode.getElementsByTagName('tr');for(var i=0;i{dK;=FInHLH~Yy`f+UH-R#Ee1*%X0sR+(bD=AMbN@eg(OfJgLO-;#6RB+2IN-fVX$}U#$ zjo3X=O9iMl-_yl0ghN*K%tgKy0}hwKF0Z9q=dP7R7<-R53@b1ojd%BVXn{$lNC=ChHjIezxBZ)FW<@0E}|`sxY81i7u7 tIM>Dr9hR8+?B2cqCzV<&|Gt(!%&$Fzt=)8b_H>}t44$rjF6*2UngITyu7v;q literal 0 HcmV?d00001 diff --git a/plugins/antispam/filters/class.dc.filter.ip.php b/plugins/antispam/filters/class.dc.filter.ip.php new file mode 100644 index 0000000..9337555 --- /dev/null +++ b/plugins/antispam/filters/class.dc.filter.ip.php @@ -0,0 +1,311 @@ +con =& $core->con; + $this->table = $core->prefix.'spamrule'; + } + + protected function setInfo() + { + $this->description = __('IP Blacklist / Whitelist Filter'); + } + + public function getStatusMessage($status,$comment_id) + { + return sprintf(__('Filtered by %1$s with rule %2$s.'),$this->guiLink(),$status); + } + + public function isSpam($type,$author,$email,$site,$ip,$content,$post_id,&$status) + { + if (!$ip) { + return; + } + + # White list check + if ($this->checkIP($ip,'white') !== false) { + return false; + } + + # Black list check + if (($s = $this->checkIP($ip,'black')) !== false) { + $status = $s; + return true; + } + } + + public function gui($url) + { + global $default_tab; + $core =& $this->core; + + # Set current type and tab + $ip_type = 'black'; + if (!empty($_REQUEST['ip_type']) && $_REQUEST['ip_type'] == 'white') { + $ip_type = 'white'; + } + $default_tab = 'tab_'.$ip_type; + + # Add IP to list + if (!empty($_POST['addip'])) + { + try + { + $global = !empty($_POST['globalip']) && $core->auth->isSuperAdmin(); + + $this->addIP($ip_type,$_POST['addip'],$global); + http::redirect($url.'&added=1&ip_type='.$ip_type); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } + } + + # Remove IP from list + if (!empty($_POST['delip']) && is_array($_POST['delip'])) + { + try { + $this->removeRule($_POST['delip']); + http::redirect($url.'&removed=1&ip_type='.$ip_type); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } + } + + /* DISPLAY + ---------------------------------------------- */ + $res = ''; + + if (!empty($_GET['added'])) { + $res .= '

    '.__('IP address has been successfully added.').'

    '; + } + if (!empty($_GET['removed'])) { + $res .= '

    '.__('IP addresses have been successfully removed.').'

    '; + } + + $res .= + $this->displayForms($url,'black',__('Blacklist')). + $this->displayForms($url,'white',__('Whitelist')); + + return $res; + } + + private function displayForms($url,$type,$title) + { + $core =& $this->core; + + $res = + '
    '. + + '
    '. + '
    '.__('Add an IP address').'

    '. + form::hidden(array('ip_type'),$type). + form::field(array('addip'),18,255).' '; + + if ($core->auth->isSuperAdmin()) { + $res .= ' '; + } + + $res .= + $core->formNonce(). + '

    '. + '
    '; + + $rs = $this->getRules($type); + + if ($rs->isEmpty()) + { + $res .= '

    '.__('No IP address in list.').'

    '; + } + else + { + $res .= + '
    '. + '
    ' . __('IP list') . ''. + '
    '; + + while ($rs->fetch()) + { + $bits = explode(':',$rs->rule_content); + $pattern = $bits[0]; + $ip = $bits[1]; + $bitmask = $bits[2]; + + $disabled_ip = false; + $p_style = $this->style_p; + if (!$rs->blog_id) { + $disabled_ip = !$core->auth->isSuperAdmin(); + $p_style .= $this->style_global; + } + + $res .= + '

    '; + } + $res .= + '
    '. + '

    '. + $core->formNonce(). + form::hidden(array('ip_type'),$type). + '

    '. + '
    '; + } + + $res .= '
    '; + + return $res; + } + + private function ipmask($pattern,&$ip,&$mask) + { + $bits = explode('/',$pattern); + + # Set IP + $bits[0] .= str_repeat(".0", 3 - substr_count($bits[0], ".")); + $ip = ip2long($bits[0]); + + if (!$ip || $ip == -1) { + throw new Exception('Invalid IP address'); + } + + # Set mask + if (!isset($bits[1])) { + $mask = -1; + } elseif (strpos($bits[1],'.')) { + $mask = ip2long($bits[1]); + if (!$mask) { + $mask = -1; + } + } else { + $mask = ~((1 << (32 - $bits[1])) - 1); + } + } + + private function addIP($type,$pattern,$global) + { + $this->ipmask($pattern,$ip,$mask); + $pattern = long2ip($ip).($mask != -1 ? '/'.long2ip($mask) : ''); + $content = $pattern.':'.$ip.':'.$mask; + + $old = $this->getRuleCIDR($type,$global,$ip,$mask); + $cur = $this->con->openCursor($this->table); + + if ($old->isEmpty()) + { + $id = $this->con->select('SELECT MAX(rule_id) FROM '.$this->table)->f(0) + 1; + + $cur->rule_id = $id; + $cur->rule_type = (string) $type; + $cur->rule_content = (string) $content; + + if ($global && $this->core->auth->isSuperAdmin()) { + $cur->blog_id = null; + } else { + $cur->blog_id = $this->core->blog->id; + } + + $cur->insert(); + } + else + { + $cur->rule_type = (string) $type; + $cur->rule_content = (string) $content; + $cur->update('WHERE rule_id = '.(integer) $old->rule_id); + } + } + + private function getRules($type='all') + { + $strReq = + 'SELECT rule_id, rule_type, blog_id, rule_content '. + 'FROM '.$this->table.' '. + "WHERE rule_type = '".$this->con->escape($type)."' ". + "AND (blog_id = '".$this->core->blog->id."' OR blog_id IS NULL) ". + 'ORDER BY blog_id ASC, rule_content ASC '; + + return $this->con->select($strReq); + } + + private function getRuleCIDR($type,$global,$ip,$mask) + { + $strReq = + 'SELECT * FROM '.$this->table.' '. + "WHERE rule_type = '".$this->con->escape($type)."' ". + "AND rule_content LIKE '%:".(integer) $ip.":".(integer) $mask."' ". + 'AND blog_id '.($global ? 'IS NULL ' : "= '".$this->core->blog->id."' "); + + return $this->con->select($strReq); + } + + private function checkIP($cip,$type) + { + $core =& $this->core; + + $strReq = + 'SELECT DISTINCT(rule_content) '. + 'FROM '.$this->table.' '. + "WHERE rule_type = '".$this->con->escape($type)."' ". + "AND (blog_id = '".$this->core->blog->id."' OR blog_id IS NULL) ". + 'ORDER BY rule_content ASC '; + + $rs = $this->con->select($strReq); + while ($rs->fetch()) + { + list($pattern,$ip,$mask) = explode(':',$rs->rule_content); + if ((ip2long($cip) & (integer) $mask) == ((integer) $ip & (integer) $mask)) { + return $pattern; + } + } + return false; + } + + private function removeRule($ids) + { + $strReq = 'DELETE FROM '.$this->table.' '; + + if (is_array($ids)) { + foreach ($ids as $i => $v) { + $ids[$i] = (integer) $v; + } + $strReq .= 'WHERE rule_id IN ('.implode(',',$ids).') '; + } else { + $ids = (integer) $ids; + $strReq .= 'WHERE rule_id = '.$ids.' '; + } + + if (!$this->core->auth->isSuperAdmin()) { + $strReq .= "AND blog_id = '".$this->core->blog->id."' "; + } + + $this->con->execute($strReq); + } +} +?> \ No newline at end of file diff --git a/plugins/antispam/filters/class.dc.filter.iplookup.php b/plugins/antispam/filters/class.dc.filter.iplookup.php new file mode 100644 index 0000000..ed81be4 --- /dev/null +++ b/plugins/antispam/filters/class.dc.filter.iplookup.php @@ -0,0 +1,120 @@ +auth->isSuperAdmin()) { + $this->has_gui = false; + } + } + + protected function setInfo() + { + $this->description = __('Checks sender IP address against DNSBL servers'); + } + + public function getStatusMessage($status,$comment_id) + { + return sprintf(__('Filtered by %1$s with server %2$s.'),$this->guiLink(),$status); + } + + public function isSpam($type,$author,$email,$site,$ip,$content,$post_id,&$status) + { + if (!$ip || long2ip(ip2long($ip)) != $ip) { + return; + } + + $match = array(); + + $bls = $this->getServers(); + $bls = preg_split('/\s*,\s*/',$bls); + + foreach ($bls as $bl) + { + if ($this->dnsblLookup($ip,$bl)) { + $match[] = $bl; + } + } + + if (!empty($match)) { + $status = substr(implode(', ',$match),0,128); + return true; + } + } + + public function gui($url) + { + $bls = $this->getServers(); + + if (isset($_POST['bls'])) + { + try { + $this->core->blog->settings->setNameSpace('antispam'); + $this->core->blog->settings->put('antispam_dnsbls',$_POST['bls'],'string','Antispam DNSBL servers',true,false); + http::redirect($url.'&upd=1'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } + } + + /* DISPLAY + ---------------------------------------------- */ + $res = ''; + + $res .= + '
    '. + '
    ' . __('IP Lookup servers') . ''. + '

    '.__('Add here a coma separated list of servers.').'

    '. + '

    '.form::textarea('bls',40,3,html::escapeHTML($bls),'maximal').'

    '. + '

    '. + $this->core->formNonce().'

    '. + '
    '. + '
    '; + + return $res; + } + + private function getServers() + { + $bls = $this->core->blog->settings->antispam_dnsbls; + if ($bls === null) { + $this->core->blog->settings->setNameSpace('antispam'); + $this->core->blog->settings->put('antispam_dnsbls',$this->default_bls,'string','Antispam DNSBL servers',true,false); + return $this->default_bls; + } + + return $bls; + } + + private function dnsblLookup($ip,$bl) + { + $revIp = implode('.',array_reverse(explode('.',$ip))); + + $host = $revIp.'.'.$bl.'.'; + if (gethostbyname($host) != $host) { + return true; + } + + return false; + } +} +?> \ No newline at end of file diff --git a/plugins/antispam/filters/class.dc.filter.linkslookup.php b/plugins/antispam/filters/class.dc.filter.linkslookup.php new file mode 100644 index 0000000..d7e5b7e --- /dev/null +++ b/plugins/antispam/filters/class.dc.filter.linkslookup.php @@ -0,0 +1,74 @@ +description = __('Checks links in comments against surbl.org'); + } + + public function getStatusMessage($status,$comment_id) + { + return sprintf(__('Filtered by %1$s with server %2$s.'),$this->guiLink(),$status); + } + + public function isSpam($type,$author,$email,$site,$ip,$content,$post_id,&$status) + { + if (!$ip || long2ip(ip2long($ip)) != $ip) { + return; + } + + $urls = $this->getLinks($content); + array_unshift($urls,$site); + + foreach ($urls as $u) + { + $b = parse_url($u); + if (!isset($b['host']) || !$b['host']) { + continue; + } + + $domain = preg_replace('/^(.*\.)([^.]+\.[^.]+)$/','$2',$b['host']); + $host = $domain.'.'.$this->server; + + if (gethostbyname($host) != $host) { + $status = substr($domain,0,128); + return true; + } + } + } + + private function getLinks($text) + { + $res = array(); + + # href attribute on "a" tags + if (preg_match_all('/]+)>/ms', $text, $match, PREG_SET_ORDER)) + { + for ($i = 0; $i \ No newline at end of file diff --git a/plugins/antispam/filters/class.dc.filter.words.php b/plugins/antispam/filters/class.dc.filter.words.php new file mode 100644 index 0000000..ee53f84 --- /dev/null +++ b/plugins/antispam/filters/class.dc.filter.words.php @@ -0,0 +1,357 @@ +con =& $core->con; + $this->table = $core->prefix.'spamrule'; + } + + protected function setInfo() + { + $this->description = __('Words Blacklist'); + } + + public function getStatusMessage($status,$comment_id) + { + return sprintf(__('Filtered by %1$s with word %2$s.'),$this->guiLink(),''.$status.''); + } + + public function isSpam($type,$author,$email,$site,$ip,$content,$post_id,&$status) + { + $str = $author.' '.$email.' '.$site.' '.$content; + + $rs = $this->getRules(); + + while ($rs->fetch()) + { + $word = $rs->rule_content; + + if (substr($word,0,1) == '/' && substr($word,-1,1) == '/') { + $reg = substr(substr($word,1),0,-1); + } else { + $reg = preg_quote($word, '/'); + $reg = '(^|\s+|>|<)'.$reg.'(>|<|\s+|\.|$)'; + } + + if (preg_match('/'.$reg.'/msiu',$str)) { + $status = $word; + return true; + } + } + } + + public function gui($url) + { + $core =& $this->core; + + # Create list + if (!empty($_POST['createlist'])) + { + try { + $this->defaultWordsList(); + http::redirect($url.'&list=1'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } + } + + # Adding a word + if (!empty($_POST['swa'])) + { + $globalsw = !empty($_POST['globalsw']) && $core->auth->isSuperAdmin(); + + try { + $this->addRule($_POST['swa'],$globalsw); + http::redirect($url.'&added=1'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } + } + + # Removing spamwords + if (!empty($_POST['swd']) && is_array($_POST['swd'])) + { + try { + $this->removeRule($_POST['swd']); + http::redirect($url.'&removed=1'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } + } + + /* DISPLAY + ---------------------------------------------- */ + $res = ''; + + if (!empty($_GET['list'])) { + $res .= '

    '.__('Words have been successfully added.').'

    '; + } + if (!empty($_GET['added'])) { + $res .= '

    '.__('Word has been successfully added.').'

    '; + } + if (!empty($_GET['removed'])) { + $res .= '

    '.__('Words have been successfully removed.').'

    '; + } + + $res .= + '
    '. + '
    '.__('Add a word').''. + '

    '.form::field('swa',20,128).' '; + + if ($core->auth->isSuperAdmin()) { + $res .= ' '; + } + + $res .= + $core->formNonce(). + '

    '. + '
    '. + '
    '; + + $rs = $this->getRules(); + if ($rs->isEmpty()) + { + $res .= '

    '.__('No word in list.').'

    '; + } + else + { + $res .= + '
    '. + '
    ' . __('List') . ''. + '
    '; + + while ($rs->fetch()) + { + $disabled_word = false; + $p_style = $this->style_p; + if (!$rs->blog_id) { + $disabled_word = !$core->auth->isSuperAdmin(); + $p_style .= $this->style_global; + } + + $res .= + '

    '; + } + + $res .= + '
    '. + '

    '.form::hidden(array('spamwords'),1). + $core->formNonce(). + '

    '. + '
    '; + } + + if ($core->auth->isSuperAdmin()) + { + $res .= + '
    '. + '

    '. + form::hidden(array('spamwords'),1). + form::hidden(array('createlist'),1). + $core->formNonce().'

    '. + '
    '; + } + + return $res; + } + + private function getRules() + { + $strReq = 'SELECT rule_id, blog_id, rule_content '. + 'FROM '.$this->table.' '. + "WHERE rule_type = 'word' ". + "AND ( blog_id = '".$this->con->escape($this->core->blog->id)."' ". + "OR blog_id IS NULL ) ". + 'ORDER BY blog_id ASC, rule_content ASC '; + + return $this->con->select($strReq); + } + + private function addRule($content,$general=false) + { + $strReq = 'SELECT rule_id FROM '.$this->table.' '. + "WHERE rule_type = 'word' ". + "AND rule_content = '".$this->con->escape($content)."' "; + $rs = $this->con->select($strReq); + + if (!$rs->isEmpty()) { + throw new Exception(__('This word exists')); + } + + $rs = $this->con->select('SELECT MAX(rule_id) FROM '.$this->table); + $id = (integer) $rs->f(0) + 1; + + $cur = $this->con->openCursor($this->table); + $cur->rule_id = $id; + $cur->rule_type = 'word'; + $cur->rule_content = (string) $content; + + if ($general && $this->core->auth->isSuperAdmin()) { + $cur->blog_id = null; + } else { + $cur->blog_id = $this->core->blog->id; + } + + $cur->insert(); + } + + private function removeRule($ids) + { + $strReq = 'DELETE FROM '.$this->table.' '; + + if (is_array($ids)) { + foreach ($ids as &$v) { + $v = (integer) $v; + } + $strReq .= 'WHERE rule_id IN ('.implode(',',$ids).') '; + } else { + $ids = (integer) $ids; + $strReq .= 'WHERE rule_id = '.$ids.' '; + } + + if (!$this->core->auth->isSuperAdmin()) { + $strReq .= "AND blog_id = '".$this->con->escape($this->core->blog->id)."' "; + } + + $this->con->execute($strReq); + } + + public function defaultWordsList() + { + $words = array( + '/-credit(\s+|$)/', + '/-digest(\s+|$)/', + '/-loan(\s+|$)/', + '/-online(\s+|$)/', + '4u', + 'adipex', + 'advicer', + 'ambien', + 'baccarat', + 'baccarrat', + 'blackjack', + 'bllogspot', + 'bolobomb', + 'booker', + 'byob', + 'car-rental-e-site', + 'car-rentals-e-site', + 'carisoprodol', + 'cash', + 'casino', + 'casinos', + 'chatroom', + 'cialis', + 'craps', + 'credit-card', + 'credit-report-4u', + 'cwas', + 'cyclen', + 'cyclobenzaprine', + 'dating-e-site', + 'day-trading', + 'debt', + 'digest-', + 'discount', + 'discreetordering', + 'duty-free', + 'dutyfree', + 'estate', + 'favourits', + 'fioricet', + 'flowers-leading-site', + 'freenet', + 'freenet-shopping', + 'gambling', + 'gamias', + 'health-insurancedeals-4u', + 'holdem', + 'holdempoker', + 'holdemsoftware', + 'holdemtexasturbowilson', + 'hotel-dealse-site', + 'hotele-site', + 'hotelse-site', + 'incest', + 'insurance-quotesdeals-4u', + 'insurancedeals-4u', + 'jrcreations', + 'levitra', + 'macinstruct', + 'mortgage', + 'online-gambling', + 'onlinegambling-4u', + 'ottawavalleyag', + 'ownsthis', + 'palm-texas-holdem-game', + 'paxil', + 'pharmacy', + 'phentermine', + 'pills', + 'poker', + 'poker-chip', + 'poze', + 'prescription', + 'rarehomes', + 'refund', + 'rental-car-e-site', + 'roulette', + 'shemale', + 'slot', + 'slot-machine', + 'soma', + 'taboo', + 'tamiflu', + 'texas-holdem', + 'thorcarlson', + 'top-e-site', + 'top-site', + 'tramadol', + 'trim-spa', + 'ultram', + 'v1h', + 'vacuum', + 'valeofglamorganconservatives', + 'viagra', + 'vicodin', + 'vioxx', + 'xanax', + 'zolus' + ); + + foreach ($words as $w) { + try { + $this->addRule($w,true); + } catch (Exception $e) {} + } + } +} +?> \ No newline at end of file diff --git a/plugins/antispam/icon.png b/plugins/antispam/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..2011311b427a7cf470355475d5612a2cd1423135 GIT binary patch literal 674 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJbFq_W2nPqp?T7vk7#J9J0(?ST z|Ns9V8Xg=K<^d#uD9MHqh~g7si`=1%$msC!$WR~`sPg;w?;k$AfBx+0y$5%%-@1C{ z%B^D;?jAjM_}<>0`+HjM>}a^Ny?WK2E7!MFZ{NP<#-_4M8!9fYue`jj=)~&UGpmY^ zEiE{;G~?3Zh(n9=FD(ct}RwvSfV|@NOM)b;Obnisrg2;a}`%)bGnwSo0rPvkiRM|Ep18y z&!kum^Yo-|83`V|^AirP+W0$n@ z@|nBu-hBrIM;>3D1(e||@Q5sCVBq=y!i-L9OlAND6-rzqN`mv#O3D+9QW<;`lZ*0m zQ&Tb%72Gn5Qp@v;vWpdbBX&>JQUR(x?&;zfA|c6oaKD~&q71`@&$Zvn^KakY&#B}U zVbgpuMbMf3<)!1VAMm;)eNa(KOj4A(y5v^ebCm_=j7MW86p2j!z3%IL>7tVSu|c7{)mw2n>Kghgw`AVGAm^&OVwIJR=(a9v-aDpOHn^XPsv_aMwPf#K7lx$hZ4IFEMz!`njxgN@xNA%EvFV literal 0 HcmV?d00001 diff --git a/plugins/antispam/inc/class.dc.spamfilter.php b/plugins/antispam/inc/class.dc.spamfilter.php new file mode 100644 index 0000000..6e657d5 --- /dev/null +++ b/plugins/antispam/inc/class.dc.spamfilter.php @@ -0,0 +1,161 @@ +dcCore Dotclear core object + */ + public function __construct(&$core) + { + $this->core =& $core; + $this->setInfo(); + + if (!$this->name) { + $this->name = get_class($this); + } + + $this->gui_url = 'plugin.php?p=antispam&f='.get_class($this); + } + + /** + This method is called by the constructor and allows you to change some + object properties without overloading object constructor. + */ + protected function setInfo() + { + $this->description = __('No description'); + } + + /** + This method should return if a comment is a spam or not. If it returns true + or false, execution of next filters will be stoped. If should return nothing + to let next filters apply. + + Your filter should also fill $status variable with its own information if + comment is a spam. + + @param type string Comment type (comment or trackback) + @param author string Comment author + @param email string Comment author email + @param site string Comment author website + @param ip string Comment author IP address + @param content string Comment content + @param post_id integer Comment post_id + @param[out] status integer Comment status + @return boolean + */ + public function isSpam($type,$author,$email,$site,$ip,$content,$post_id,&$status) + { + } + + /** + This method is called when a non-spam (ham) comment becomes spam or when a + spam becomes a ham. + + @param type string Comment type (comment or trackback) + @param filter string Filter name + @param author string Comment author + @param email string Comment author email + @param site string Comment author website + @param ip string Comment author IP address + @param content string Comment content + @param post_url string Post URL + @param rs record Comment record + @return boolean + */ + public function trainFilter($status,$filter,$type,$author,$email,$site,$ip,$content,$rs) + { + } + + /** + This method returns filter status message. You can overload this method to + return a custom message. Message is shown in comment details and in + comments list. + + @param status string Filter status. + @param comment_id record Comment record + @return string + */ + public function getStatusMessage($status,$comment_id) + { + return sprintf(__('Filtered by %1$s (%2$s)'),$this->guiLink(),$status); + } + + /** + This method is called when you enter filter configuration. Your class should + have $has_gui property set to "true" to enable GUI. + + In this method you should put everything related to filter configuration. + $url variable is the URL of GUI unescaped. + + @param url string GUI URL. + */ + public function gui($url) + { + } + + public function hasGUI() + { + if (!$this->core->auth->check('admin',$this->core->blog->id)) { + return false; + } + + if (!$this->has_gui) { + return false; + } + + return true; + } + + public function guiURL() + { + if (!$this->hasGui()) { + return false; + } + + return $this->gui_url; + } + + /** + Returns a link to filter GUI if exists or only filter name if has_gui + property is false. + + @return string + */ + public function guiLink() + { + if (($url = $this->guiURL()) !== false) { + $url = html::escapeHTML($url); + $link = '
    %1$s'; + } else { + $link = '%1$s'; + } + + return sprintf($link,$this->name,$url); + } +} +?> \ No newline at end of file diff --git a/plugins/antispam/inc/class.dc.spamfilters.php b/plugins/antispam/inc/class.dc.spamfilters.php new file mode 100644 index 0000000..e921d7f --- /dev/null +++ b/plugins/antispam/inc/class.dc.spamfilters.php @@ -0,0 +1,164 @@ +core =& $core; + } + + public function init($filters) + { + foreach ($filters as $f) + { + if (!class_exists($f)) { + continue; + } + + $r = new ReflectionClass($f); + $p = $r->getParentClass(); + + if (!$p || $p->name != 'dcSpamFilter') { + continue; + } + + $this->filters[$f] = new $f($this->core); + } + + $this->setFilterOpts(); + if (!empty($this->filters_opt)) { + uasort($this->filters,array($this,'orderCallBack')); + } + } + + public function getFilters() + { + return $this->filters; + } + + public function isSpam(&$cur) + { + foreach ($this->filters as $fid => $f) + { + if (!$f->active) { + continue; + } + + $type = $cur->comment_trackback ? 'trackback' : 'comment'; + $author = $cur->comment_author; + $email = $cur->comment_email; + $site = $cur->comment_site; + $ip = $cur->comment_ip; + $content = $cur->comment_content; + $post_id = $cur->post_id; + + $is_spam = $f->isSpam($type,$author,$email,$site,$ip,$content,$post_id,$status); + + if ($is_spam === true) { + if ($f->auto_delete) { + $cur->clean(); + } else { + $cur->comment_status = -2; + $cur->comment_spam_status = $status; + $cur->comment_spam_filter = $fid; + } + return true; + } elseif ($is_spam === false) { + return false; + } + } + + return false; + } + + public function trainFilters(&$rs,$status,$filter_name) + { + foreach ($this->filters as $fid => $f) + { + if (!$f->active) { + continue; + } + + $type = $rs->comment_trackback ? 'trackback' : 'comment'; + $author = $rs->comment_author; + $email = $rs->comment_email; + $site = $rs->comment_site; + $ip = $rs->comment_ip; + $content = $rs->comment_content; + + $f->trainFilter($status,$filter_name,$type,$author,$email,$site,$ip,$content,$rs); + } + } + + public function statusMessage(&$rs,$filter_name) + { + $f = isset($this->filters[$filter_name]) ? $this->filters[$filter_name] : null; + + if ($f === null) + { + return __('Unknown filter.'); + } + else + { + $status = $rs->exists('comment_spam_status') ? $rs->comment_spam_status : null; + + return $f->getStatusMessage($status,$rs->comment_id); + } + } + + public function saveFilterOpts($opts,$global=false) + { + $this->core->blog->settings->setNameSpace('antispam'); + if ($global) { + $this->core->blog->settings->drop('antispam_filters'); + } + $this->core->blog->settings->put('antispam_filters',serialize($opts),'string','Antispam Filters',true,$global); + } + + private function setFilterOpts() + { + if ($this->core->blog->settings->antispam_filters !== null) { + $this->filters_opt = @unserialize($this->core->blog->settings->antispam_filters); + } + + # Create default options if needed + if (!is_array($this->filters_opt)) { + $this->saveFilterOpts(array(),true); + $this->filters_opt = array(); + } + + foreach ($this->filters_opt as $k => $o) + { + if (isset($this->filters[$k]) && is_array($o)) { + $this->filters[$k]->active = isset($o[0])?$o[0]:false; + $this->filters[$k]->order = isset($o[1])?$o[1]:0; + $this->filters[$k]->auto_delete = isset($o[2])?$o[2]:false; + } + } + } + + private function orderCallBack($a,$b) + { + if ($a->order == $b->order) { + return 0; + } + + return $a->order > $b->order ? 1 : -1; + } +} +?> \ No newline at end of file diff --git a/plugins/antispam/inc/lib.dc.antispam.php b/plugins/antispam/inc/lib.dc.antispam.php new file mode 100644 index 0000000..04adfb4 --- /dev/null +++ b/plugins/antispam/inc/lib.dc.antispam.php @@ -0,0 +1,195 @@ +spamfilters)) { + return; + } + + self::$filters = new dcSpamFilters($core); + self::$filters->init($core->spamfilters); + } + + public static function isSpam(&$cur) + { + self::initFilters(); + self::$filters->isSpam($cur); + } + + public static function trainFilters(&$blog,&$cur,&$rs) + { + $status = null; + # From ham to spam + if ($rs->comment_status != -2 && $cur->comment_status == -2) { + $status = 'spam'; + } + + # From spam to ham + if ($rs->comment_status == -2 && $cur->comment_status == 1) { + $status = 'ham'; + } + + # the status of this comment has changed + if ($status) + { + $filter_name = $rs->exists('comment_spam_filter') ? $rs->comment_spam_filter : null; + + self::initFilters(); + self::$filters->trainFilters($rs,$status,$filter_name); + } + } + + public static function statusMessage(&$rs) + { + if ($rs->exists('comment_status') && $rs->comment_status == -2) + { + $filter_name = $rs->exists('comment_spam_filter') ? $rs->comment_spam_filter : null; + + self::initFilters(); + + return + '

    '.__('This comment is a spam:').' '. + self::$filters->statusMessage($rs,$filter_name).'

    '; + } + } + + public static function dashboardIcon(&$core, &$icons) + { + if (($count = self::countSpam($core)) > 0) { + $str = ($count > 1) ? __('(including %d spam comments)') : __('(including %d spam comment)'); + $icons['comments'][0] .= '
    '.sprintf($str,$count); + } + } + + public static function countSpam(&$core) + { + return $core->blog->getComments(array('comment_status'=>-2),true)->f(0); + } + + public static function countPublishedComments(&$core) + { + return $core->blog->getComments(array('comment_status'=>1),true)->f(0); + } + + public static function delAllSpam(&$core, $beforeDate = null) + { + $strReq = + 'SELECT comment_id '. + 'FROM '.$core->prefix.'comment C '. + 'JOIN '.$core->prefix.'post P ON P.post_id = C.post_id '. + "WHERE blog_id = '".$core->con->escape($core->blog->id)."' ". + 'AND comment_status = -2 '; + if ($beforeDate) { + $strReq .= 'AND comment_dt < \''.$beforeDate.'\' '; + } + + $rs = $core->con->select($strReq); + $r = array(); + while ($rs->fetch()) { + $r[] = (integer) $rs->comment_id; + } + + if (empty($r)) { + return; + } + + $strReq = + 'DELETE FROM '.$core->prefix.'comment '. + 'WHERE comment_id '.$core->con->in($r).' '; + + $core->con->execute($strReq); + } + + public static function getUserCode($core) + { + $code = + pack('a32',$core->auth->userID()). + pack('H*',crypt::hmac(DC_MASTER_KEY,$core->auth->getInfo('user_pwd'))); + return bin2hex($code); + } + + public static function checkUserCode($core,$code) + { + $code = pack('H*',$code); + + $user_id = trim(@pack('a32',substr($code,0,32))); + $pwd = @unpack('H40hex',substr($code,32,40)); + + if ($user_id === false || $pwd === false) { + return false; + } + + $pwd = $pwd['hex']; + + $strReq = 'SELECT user_id, user_pwd '. + 'FROM '.$core->prefix.'user '. + "WHERE user_id = '".$core->con->escape($user_id)."' "; + + $rs = $core->con->select($strReq); + + if ($rs->isEmpty()) { + return false; + } + + if (crypt::hmac(DC_MASTER_KEY,$rs->user_pwd) != $pwd) { + return false; + } + + return $rs->user_id; + } + + public static function purgeOldSpam(&$core) + { + $defaultDateLastPurge = time(); + $defaultModerationTTL = '7'; + $init = false; + + // settings + $core->blog->settings->setNameSpace('antispam'); + + $dateLastPurge = $core->blog->settings->antispam_date_last_purge; + if ($dateLastPurge === null) { + $init = true; + $core->blog->settings->put('antispam_date_last_purge',$defaultDateLastPurge,'integer','Antispam Date Last Purge (unix timestamp)',true,false); + $dateLastPurge = $defaultDateLastPurge; + } + $moderationTTL = $core->blog->settings->antispam_moderation_ttl; + if ($moderationTTL === null) { + $core->blog->settings->put('antispam_moderation_ttl',$defaultModerationTTL,'integer','Antispam Moderation TTL (days)',true,false); + $moderationTTL = $defaultModerationTTL; + } + + if ($moderationTTL < 0) { + // disabled + return; + } + + // we call the purge every day + if ((time()-$dateLastPurge) > (86400)) { + // update dateLastPurge + if (!$init) { + $core->blog->settings->put('antispam_date_last_purge',time(),null,null,true,false); + } + $date = date('Y-m-d H:i:s', time() - $moderationTTL*86400); + dcAntispam::delAllSpam($core, $date); + } + } +} +?> \ No newline at end of file diff --git a/plugins/antispam/inc/lib.dc.antispam.url.php b/plugins/antispam/inc/lib.dc.antispam.url.php new file mode 100644 index 0000000..1c44e21 --- /dev/null +++ b/plugins/antispam/inc/lib.dc.antispam.url.php @@ -0,0 +1,99 @@ +auth->checkUser($user_id,null,null); + + header('Content-Type: application/xml; charset=UTF-8'); + + $title = $core->blog->name.' - '.__('Spam moderation'). ' - '; + $params = array(); + $end_url = ''; + if ($type == 'spam') { + $title .= __('Spam'); + $params['comment_status'] = -2; + $end_url = '?status=-2'; + } else { + $title .= __('Ham'); + $params['sql'] = ' AND comment_status IN (1,-1) '; + } + + echo + ''."\n". + ''."\n". + ''."\n". + ''.html::escapeHTML($title).''."\n". + ''.(DC_ADMIN_URL ? DC_ADMIN_URL.'comments.php'.$end_url : 'about:blank').''."\n". + ''."\n"; + + $rs = $core->blog->getComments($params); + $maxitems = 20; + $nbitems = 0; + + while ($rs->fetch() && ($nbitems < $maxitems)) + { + $nbitems++; + $uri = DC_ADMIN_URL ? DC_ADMIN_URL.'comment.php?id='.$rs->comment_id : 'about:blank'; + $author = $rs->comment_author; + $title = $rs->post_title.' - '.$author; + if ($type == 'spam') { + $title .= '('.$rs->comment_spam_filter.')'; + } + $id = $rs->getFeedID(); + + $content = '

    IP: '.$rs->comment_ip; + + if (trim($rs->comment_site)) { + $content .= '
    URL:
    '.$rs->comment_site.''; + } + $content .= "


    \n"; + $content .= $rs->comment_content; + + echo + ''."\n". + ' '.html::escapeHTML($title).''."\n". + ' '.$uri.''."\n". + ' '.$id.''."\n". + ' '.$rs->getRFC822Date().''."\n". + ' '.html::escapeHTML($author).''."\n". + ' '.html::escapeHTML($content).''."\n". + ''; + } + + echo "\n"; + } +} +?> \ No newline at end of file diff --git a/plugins/antispam/index.php b/plugins/antispam/index.php new file mode 100644 index 0000000..204ba5f --- /dev/null +++ b/plugins/antispam/index.php @@ -0,0 +1,222 @@ +getFilters(); + +$page_name = __('Antispam'); +$filter_gui = false; +$default_tab = null; + +try +{ + # Show filter configuration GUI + if (!empty($_GET['f'])) + { + if (!isset($filters[$_GET['f']])) { + throw new Exception(__('Filter does not exist.')); + } + + if (!$filters[$_GET['f']]->hasGUI()) { + throw new Exception(__('Filter has no user interface.')); + } + + $filter = $filters[$_GET['f']]; + $filter_gui = $filter->gui($filter->guiURL()); + } + + # Remove all spam + if (!empty($_POST['delete_all'])) + { + dcAntispam::delAllSpam($core); + http::redirect($p_url.'&del=1'); + } + + # Update filters + if (isset($_POST['filters_upd'])) + { + $filters_opt = array(); + $i = 0; + foreach ($filters as $fid => $f) { + $filters_opt[$fid] = array(false,$i); + $i++; + } + + # Enable active filters + if (isset($_POST['filters_active']) && is_array($_POST['filters_active'])) { + foreach ($_POST['filters_active'] as $v) { + $filters_opt[$v][0] = true; + } + } + + # Order filters + if (!empty($_POST['f_order']) && empty($_POST['filters_order'])) + { + $order = $_POST['f_order']; + asort($order); + $order = array_keys($order); + } + elseif (!empty($_POST['filters_order'])) + { + $order = explode(',',trim($_POST['filters_order'],',')); + } + + if (isset($order)) { + foreach ($order as $i => $f) { + $filters_opt[$f][1] = $i; + } + } + + # Set auto delete flag + if (isset($_POST['filters_auto_del']) && is_array($_POST['filters_auto_del'])) { + foreach ($_POST['filters_auto_del'] as $v) { + $filters_opt[$v][2] = true; + } + } + + dcAntispam::$filters->saveFilterOpts($filters_opt); + http::redirect($p_url.'&upd=1'); + } +} +catch (Exception $e) +{ + $core->error->add($e->getMessage()); +} +?> + + + <?php echo $page_name; ?> + + + + +'.html::escapeHTML($core->blog->name).' › '.$page_name.''; + +if ($filter_gui !== false) +{ + echo '

    '.__('Return to filters').'

    '; + printf('

    '.__('%s configuration').'

    ',$filter->name); + + echo $filter_gui; +} +else +{ + # Information + $spam_count = dcAntispam::countSpam($core); + $published_count = dcAntispam::countPublishedComments($core); + $moderationTTL = $core->blog->settings->antispam_moderation_ttl; + + echo + '
    '. + '
    '.__('Information').''; + + if (!empty($_GET['del'])) { + echo '

    '.__('Spam comments have been successfully deleted.').'

    '; + } + + echo + ''; + + if ($spam_count > 0) + { + echo + '

    '.$core->formNonce(). + '

    '; + } + if ($moderationTTL != null && $moderationTTL >=0) { + echo '

    '.sprintf(__('All spam comments older than %s day(s) will be automatically deleted.'), $moderationTTL).'

    '; + } + echo '
    '; + + + # Filters + echo + '
    '. + '
    '.__('Available spam filters').''; + + if (!empty($_GET['upd'])) { + echo '

    '.__('Filters configuration has been successfully saved.').'

    '; + } + + echo + ''. + ''. + ''. + ''. + ''. + ''. + ''. + ''. + ''; + + $i = 0; + foreach ($filters as $fid => $f) + { + $gui_link = ' '; + if ($f->hasGUI()) { + $gui_link = + ''. + ''.__('Filter configuration').''; + } + + echo + ''. + ''. + ''. + ''. + ''. + ''. + ''. + ''; + $i++; + } + echo + '
    '.__('Order').''.__('Active').''.__('Auto Del.').''.__('Filter name').''.__('Description').'
    '.form::field(array('f_order['.$fid.']'),2,5,(string) $i).''.form::checkbox(array('filters_active[]'),$fid,$f->active).''.form::checkbox(array('filters_auto_del[]'),$fid,$f->auto_delete).''.$f->name.''.$f->description.''.$gui_link.'
    '. + '

    '.form::hidden('filters_order',''). + $core->formNonce(). + '

    '. + '
    '; + + + # Syndication + if (DC_ADMIN_URL) + { + $ham_feed = $core->blog->url.$core->url->getBase('hamfeed').'/'.$code = dcAntispam::getUserCode($core); + $spam_feed = $core->blog->url.$core->url->getBase('spamfeed').'/'.$code = dcAntispam::getUserCode($core); + + echo + '
    '.__('Syndication').''. + ''. + '
    '; + } +} +?> + + + \ No newline at end of file diff --git a/plugins/antispam/style.css b/plugins/antispam/style.css new file mode 100644 index 0000000..c93cf1a --- /dev/null +++ b/plugins/antispam/style.css @@ -0,0 +1,23 @@ +ul.spaminfo { + display: block; + list-style: none; + margin: 1em 0; + padding: 0; +} +ul.spaminfo li { + margin: 0.5em 0; + padding-left: 16px; + /*background: url(index.php?pf=antispam/feed.png) no-repeat center left;*/ + background-color: transparent; + background-position: center left; + background-repeat: no-repeat; +} +ul.spaminfo .spamcount { + background-image: url(images/junk.png); +} +ul.spaminfo .hamcount { + background-image: url(images/check-on.png); +} +ul.spaminfo .feed { + background-image: url(index.php?pf=antispam/feed.png); +} \ No newline at end of file diff --git a/plugins/blogroll/_admin.php b/plugins/blogroll/_admin.php new file mode 100644 index 0000000..4919910 --- /dev/null +++ b/plugins/blogroll/_admin.php @@ -0,0 +1,27 @@ +addBehavior('adminDashboardIcons','blogroll_dashboard'); +function blogroll_dashboard(&$core,&$icons) +{ + $icons['blogroll'] = new ArrayObject(array(__('Blogroll'),'plugin.php?p=blogroll','index.php?pf=blogroll/icon.png')); +} + +$_menu['Plugins']->addItem(__('Blogroll'),'plugin.php?p=blogroll','index.php?pf=blogroll/icon-small.png', + preg_match('/plugin.php\?p=blogroll(&.*)?$/',$_SERVER['REQUEST_URI']), + $core->auth->check('usage,contentadmin',$core->blog->id)); + +$core->auth->setPermissionType('blogroll',__('manage blogroll')); + +require dirname(__FILE__).'/_widgets.php'; +?> \ No newline at end of file diff --git a/plugins/blogroll/_define.php b/plugins/blogroll/_define.php new file mode 100644 index 0000000..977ea67 --- /dev/null +++ b/plugins/blogroll/_define.php @@ -0,0 +1,21 @@ +registerModule( + /* Name */ "Blogroll", + /* Description*/ "Manage your blogroll", + /* Author */ "Olivier Meunier", + /* Version */ '1.1', + /* Permissions */ 'blogroll' +); +?> \ No newline at end of file diff --git a/plugins/blogroll/_install.php b/plugins/blogroll/_install.php new file mode 100644 index 0000000..c716698 --- /dev/null +++ b/plugins/blogroll/_install.php @@ -0,0 +1,46 @@ +plugins->moduleInfo('blogroll','version'); + +if (version_compare($core->getVersion('blogroll'),$version,'>=')) { + return; +} + +/* Database schema +-------------------------------------------------------- */ +$s = new dbStruct($core->con,$core->prefix); + +$s->link + ->link_id ('bigint', 0, false) + ->blog_id ('varchar', 32, false) + ->link_href ('varchar', 255, false) + ->link_title ('varchar', 255, false) + ->link_desc ('varchar', 255, true) + ->link_lang ('varchar', 5, true) + ->link_xfn ('varchar', 255, true) + ->link_position ('integer', 0, false, 0) + + ->primary('pk_link','link_id') + ; + +$s->link->index('idx_link_blog_id','btree','blog_id'); +$s->link->reference('fk_link_blog','blog_id','blog','blog_id','cascade','cascade'); + +# Schema installation +$si = new dbStruct($core->con,$core->prefix); +$changes = $si->synchronize($s); + +$core->setVersion('blogroll',$version); +return true; +?> \ No newline at end of file diff --git a/plugins/blogroll/_prepend.php b/plugins/blogroll/_prepend.php new file mode 100644 index 0000000..53e3785 --- /dev/null +++ b/plugins/blogroll/_prepend.php @@ -0,0 +1,15 @@ + \ No newline at end of file diff --git a/plugins/blogroll/_public.php b/plugins/blogroll/_public.php new file mode 100644 index 0000000..52c26ad --- /dev/null +++ b/plugins/blogroll/_public.php @@ -0,0 +1,229 @@ +tpl->addValue('Blogroll',array('tplBlogroll','blogroll')); +$core->tpl->addValue('BlogrollXbelLink',array('tplBlogroll','blogrollXbelLink')); + +$core->url->register('xbel','xbel','^xbel(?:/?)$',array('urlBlogroll','xbel')); + +class tplBlogroll +{ + public static function blogroll($attr) + { + $category='

    %s

    '; + $block='
      %s
    '; + $item='%1$s'; + + if (isset($attr['category'])) { + $category = addslashes($attr['category']); + } + + if (isset($attr['block'])) { + $block = addslashes($attr['block']); + } + + if (isset($attr['item'])) { + $item = addslashes($attr['item']); + } + + $only_cat = 'null'; + if (!empty($attr['only_category'])) { + $only_cat = "'".addslashes($attr['only_category'])."'"; + } + + return + ''; + } + + public static function blogrollXbelLink($attr) + { + $f = $GLOBALS['core']->tpl->getFilters($attr); + return 'blog->url.$core->url->getBase("xbel")').'; ?>'; + } + + public static function getList($cat_title='

    %s

    ',$block='
      %s
    ',$item='
  • %s
  • ',$category=null) + { + $blogroll = new dcBlogroll($GLOBALS['core']->blog); + + try { + $links = $blogroll->getLinks(); + } catch (Exception $e) { + return false; + } + + $res = ''; + + $hierarchy = $blogroll->getLinksHierarchy($links); + + if ($category) { + if (!isset($hierarchy[$category])) { + return ''; + } + $hierarchy = array($hierarchy[$category]); + } + + foreach ($hierarchy as $k => $v) + { + if ($k != '') { + $res .= sprintf($cat_title,html::escapeHTML($k))."\n"; + } + + $res .= self::getLinksList($v,$block,$item); + } + + return $res; + } + + private static function getLinksList($links,$block='
      %s
    ',$item='%1$s') + { + $list = ''; + + # Find current link item if any + $current = -1; + $current_size = 0; + $self_uri = http::getSelfURI(); + + foreach ($links as $k => $v) + { + if (!preg_match('$^([a-z][a-z0-9.+-]+://)$',$v['link_href'])) { + $url = http::concatURL($self_uri,$v['link_href']); + if (strlen($url) > $current_size && preg_match('/^'.preg_quote($url,'/').'/',$self_uri)) { + $current = $k; + $current_size = strlen($url); + } + } + } + + foreach ($links as $k => $v) + { + $title = $v['link_title']; + $href = $v['link_href']; + $desc = $v['link_desc']; + $lang = $v['link_lang']; + $xfn = $v['link_xfn']; + + $link = + ''. + html::escapeHTML($title). + ''; + + $current_class = $current == $k ? ' class="active"' : ''; + + $list .= sprintf($item,$link,$current_class)."\n"; + } + + return sprintf($block,$list)."\n"; + } + + # Widget function + public static function linksWidget(&$w) + { + global $core; + + if ($w->homeonly && $core->url->type != 'default') { + return; + } + + return + ''; + } +} + +class urlBlogroll extends dcUrlHandlers +{ + public static function xbel($args) + { + $blogroll = new dcBlogroll($GLOBALS['core']->blog); + + try { + $links = $blogroll->getLinks(); + } catch (Exception $e) { + self::p404(); + return; + } + + if ($args) { + self::p404(); + return; + } + + http::cache($GLOBALS['mod_files'],$GLOBALS['mod_ts']); + + header('Content-Type: text/xml; charset=UTF-8'); + + echo + ''."\n". + ''."\n". + ''."\n". + ''.html::escapeHTML($GLOBALS['core']->blog->name)." blogroll\n"; + + $i = 1; + foreach ($blogroll->getLinksHierarchy($links) as $cat_title => $links) + { + if ($cat_title != '') { + echo + ''."\n". + "".html::escapeHTML($cat_title)."\n"; + } + + foreach ($links as $k => $v) + { + $lang = $v['link_lang'] ? ' xml:lang="'.$v['link_lang'].'"' : ''; + + echo + ''."\n". + ''.html::escapeHTML($v['link_title'])."\n"; + + if ($v['link_desc']) { + echo ''.html::escapeHTML($v['link_desc'])."\n"; + } + + if ($v['link_xfn']) { + echo + "\n". + ''.$v['link_xfn']."\n". + "\n"; + } + + echo + "\n"; + } + + if ($cat_title != '') { + echo "\n"; + } + + $i++; + } + + echo + ''; + } +} +?> \ No newline at end of file diff --git a/plugins/blogroll/_widgets.php b/plugins/blogroll/_widgets.php new file mode 100644 index 0000000..f8b8686 --- /dev/null +++ b/plugins/blogroll/_widgets.php @@ -0,0 +1,44 @@ +addBehavior('initWidgets',array('blogrollWidgets','initWidgets')); +$core->addBehavior('initDefaultWidgets',array('blogrollWidgets','initDefaultWidgets')); + +class blogrollWidgets +{ + public static function initWidgets(&$w) + { + $w->create('links',__('Blogroll'),array('tplBlogroll','linksWidget')); + $w->links->setting('title',__('Title:'),__('Links')); + + $br = new dcBlogroll($GLOBALS['core']->blog); + $h = $br->getLinksHierarchy($br->getLinks()); + $h = array_keys($h); + $categories = array(__('All categories') => ''); + foreach ($h as $v) { + if ($v) { + $categories[$v] = $v; + } + } + unset($br,$h); + $w->links->setting('category',__('Category'),'','combo',$categories); + + $w->links->setting('homeonly',__('Home page only'),1,'check'); + } + + public static function initDefaultWidgets(&$w,&$d) + { + $d['extra']->append($w->links); + } +} +?> \ No newline at end of file diff --git a/plugins/blogroll/class.dc.blogroll.php b/plugins/blogroll/class.dc.blogroll.php new file mode 100644 index 0000000..c46ae9c --- /dev/null +++ b/plugins/blogroll/class.dc.blogroll.php @@ -0,0 +1,198 @@ +blog =& $blog; + $this->con =& $blog->con; + $this->table = $this->blog->prefix.'link'; + } + + public function getLinks($params=array()) + { + $strReq = 'SELECT link_id, link_title, link_desc, link_href, '. + 'link_lang, link_xfn, link_position '. + 'FROM '.$this->table.' '. + "WHERE blog_id = '".$this->con->escape($this->blog->id)."' "; + + if (isset($params['link_id'])) { + $strReq .= 'AND link_id = '.(integer) $params['link_id'].' '; + } + + $strReq .= 'ORDER BY link_position '; + + $rs = $this->con->select($strReq); + $rs = $rs->toStatic(); + + $this->setLinksData($rs); + + return $rs; + } + + public function getLink($id) + { + $params['link_id'] = $id; + + $rs = $this->getLinks($params); + + return $rs; + } + + public function addLink($title,$href,$desc='',$lang='', $xfn='') + { + $cur = $this->con->openCursor($this->table); + + $cur->blog_id = (string) $this->blog->id; + $cur->link_title = (string) $title; + $cur->link_href = (string) $href; + $cur->link_desc = (string) $desc; + $cur->link_lang = (string) $lang; + $cur->link_xfn = (string) $xfn; + + if ($cur->link_title == '') { + throw new Exception(__('You must provide a link title')); + } + + if ($cur->link_href == '') { + throw new Exception(__('You must provide a link URL')); + } + + $strReq = 'SELECT MAX(link_id) FROM '.$this->table; + $rs = $this->con->select($strReq); + $cur->link_id = (integer) $rs->f(0) + 1; + + $cur->insert(); + $this->blog->triggerBlog(); + } + + public function updateLink($id,$title,$href,$desc='',$lang='', $xfn='') + { + $cur = $this->con->openCursor($this->table); + + $cur->link_title = (string) $title; + $cur->link_href = (string) $href; + $cur->link_desc = (string) $desc; + $cur->link_lang = (string) $lang; + $cur->link_xfn = (string) $xfn; + + if ($cur->link_title == '') { + throw new Exception(__('You must provide a link title')); + } + + if ($cur->link_href == '') { + throw new Exception(__('You must provide a link URL')); + } + + $cur->update('WHERE link_id = '.(integer) $id. + " AND blog_id = '".$this->con->escape($this->blog->id)."'"); + $this->blog->triggerBlog(); + } + + public function updateCategory($id,$desc) + { + $cur = $this->con->openCursor($this->table); + + $cur->link_desc = (string) $desc; + + if ($cur->link_desc == '') { + throw new Exception(__('You must provide a category title')); + } + + $cur->update('WHERE link_id = '.(integer) $id. + " AND blog_id = '".$this->con->escape($this->blog->id)."'"); + $this->blog->triggerBlog(); + } + + public function addCategory($title) + { + $cur = $this->con->openCursor($this->table); + + $cur->blog_id = (string) $this->blog->id; + $cur->link_desc = (string) $title; + $cur->link_href = ''; + $cur->link_title = ''; + + if ($cur->link_desc == '') { + throw new Exception(__('You must provide a category title')); + } + + $strReq = 'SELECT MAX(link_id) FROM '.$this->table; + $rs = $this->con->select($strReq); + $cur->link_id = (integer) $rs->f(0) + 1; + + $cur->insert(); + $this->blog->triggerBlog(); + + return $cur->link_id; + } + + public function delItem($id) + { + $id = (integer) $id; + + $strReq = 'DELETE FROM '.$this->table.' '. + "WHERE blog_id = '".$this->con->escape($this->blog->id)."' ". + 'AND link_id = '.$id.' '; + + $this->con->execute($strReq); + $this->blog->triggerBlog(); + } + + public function updateOrder($id,$position) + { + $cur = $this->con->openCursor($this->table); + $cur->link_position = (integer) $position; + + $cur->update('WHERE link_id = '.(integer) $id. + " AND blog_id = '".$this->con->escape($this->blog->id)."'"); + $this->blog->triggerBlog(); + } + + + private function setLinksData(&$rs) + { + $cat_title = null; + while ($rs->fetch()) { + $rs->set('is_cat',!$rs->link_title && !$rs->link_href); + + if ($rs->is_cat) { + $cat_title = $rs->link_desc; + $rs->set('cat_title',null); + } else { + $rs->set('cat_title',$cat_title); + } + } + $rs->moveStart(); + } + + public function getLinksHierarchy($rs) + { + $res = array(); + + foreach ($rs->rows() as $k => $v) + { + if (!$v['is_cat']) { + $res[$v['cat_title']][] = $v; + } + } + + return $res; + } +} +?> \ No newline at end of file diff --git a/plugins/blogroll/class.dc.importblogroll.php b/plugins/blogroll/class.dc.importblogroll.php new file mode 100644 index 0000000..3b79a93 --- /dev/null +++ b/plugins/blogroll/class.dc.importblogroll.php @@ -0,0 +1,102 @@ +_parseXBEL($data); + } + elseif (preg_match('!_parseOPML($data); + } + else { + throw new Exception(__('You need to provide a XBEL or OPML file.')); + } + } + + + protected function _parseOPML($data) + { + $xml = @simplexml_load_string($data); + if (!$xml) throw new Exception(__('File is not in XML format.')); + + $outlines = $xml->xpath("//outline"); + + $this->entries = array(); + foreach ($outlines as $outline) { + if (isset($outline['htmlUrl'])) { + $link = $outline['htmlUrl']; + } + elseif (isset($outline['url'])) { + $link = $outline['url']; + } + else continue; + $entry = new StdClass(); + $entry->link = $link; + $entry->title = (!empty($outline['title']))?$outline['title']:''; + if (empty($entry->title)) { + $entry->title = (!empty($outline['text']))?$outline['text']:$entry->link; + } + $entry->desc = (!empty($outline['description']))?$outline['description']:''; + $this->entries[] = $entry; + } + } + + + protected function _parseXBEL($data) + { + $xml = @simplexml_load_string($data); + if (!$xml) throw new Exception(__('File is not in XML format.')); + + $outlines = $xml->xpath("//bookmark"); + + $this->entries = array(); + foreach ($outlines as $outline) { + if (!isset($outline['href'])) continue; + $entry = new StdClass(); + $entry->link = $outline['href']; + $entry->title = (!empty($outline->title))?$outline->title:''; + if (empty($entry->title)) { + $entry->title = $entry->link; + } + $entry->desc = (!empty($outline->desc))?$outline->desc:''; + $this->entries[] = $entry; + } + } + + + public function getAll() + { + if (!$this->entries) return null; + return $this->entries; + } + +} + +class dcImportBlogroll { + + public static function loadFile($file) + { + if (file_exists($file) && is_readable($file)) { + $importer = new linksImporter(); + $importer->parse(file_get_contents($file)); + return $importer->getAll(); + } + return false; + } +} +?> \ No newline at end of file diff --git a/plugins/blogroll/edit.php b/plugins/blogroll/edit.php new file mode 100644 index 0000000..d6b3976 --- /dev/null +++ b/plugins/blogroll/edit.php @@ -0,0 +1,241 @@ +getLink($id); +} catch (Exception $e) { + $core->error->add($e->getMessage()); +} + +if (!$core->error->flag() && $rs->isEmpty()) { + $core->error->add(__('No such link or title')); +} else { + $link_title = $rs->link_title; + $link_href = $rs->link_href; + $link_desc = $rs->link_desc; + $link_lang = $rs->link_lang; + $link_xfn = $rs->link_xfn; +} + +# Update a link +if (isset($rs) && !$rs->is_cat && !empty($_POST['edit_link'])) +{ + $link_title = $_POST['link_title']; + $link_href = $_POST['link_href']; + $link_desc = $_POST['link_desc']; + $link_lang = $_POST['link_lang']; + + $link_xfn = ''; + + if (!empty($_POST['identity'])) + { + $link_xfn .= $_POST['identity']; + } + else + { + if(!empty($_POST['friendship'])) { + $link_xfn .= ' '.$_POST['friendship']; + } + if(!empty($_POST['physical'])) { + $link_xfn .= ' met'; + } + if(!empty($_POST['professional'])) { + $link_xfn .= ' '.implode(' ',$_POST['professional']); + } + if(!empty($_POST['geographical'])) { + $link_xfn .= ' '.$_POST['geographical']; + } + if(!empty($_POST['family'])) { + $link_xfn .= ' '.$_POST['family']; + } + if(!empty($_POST['romantic'])) { + $link_xfn .= ' '.implode(' ',$_POST['romantic']); + } + } + + try { + $blogroll->updateLink($id,$link_title,$link_href,$link_desc,$link_lang,trim($link_xfn)); + http::redirect($p_url.'&edit=1&id='.$id.'&upd=1'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} + + +# Update a category +if (isset($rs) && $rs->is_cat && !empty($_POST['edit_cat'])) +{ + $link_desc = $_POST['link_desc']; + + try { + $blogroll->updateCategory($id,$link_desc); + http::redirect($p_url.'&edit=1&id='.$id.'&upd=1'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} + +?> + + + Blogroll + + + +'.__('Return to blogroll').'

    '; ?> + +is_cat) +{ + if (!empty($_GET['upd'])) { + echo '

    '.__('Category has been successfully updated').'

    '; + } + + echo + '
    '. + '
    '.__('Edit category').''. + + '

    '. + + form::hidden('edit',1). + form::hidden('id',$id). + $core->formNonce(). + '

    '. + '
    '. + '
    '; +} +if (isset($rs) && !$rs->is_cat) +{ + if (!empty($_GET['upd'])) { + echo '

    '.__('Link has been successfully updated').'

    '; + } + + echo + '
    '. + '
    '.__('Edit link').''. + + '

    '. + + '

    '. + + '

    '. + + '

    '. + + '

    '.form::hidden('p','blogroll'). + form::hidden('edit',1). + form::hidden('id',$id). + $core->formNonce(). + '

    '. + '
    '. + + + # XFN nightmare + '
    '.__('XFN').''. + ''. + + ''. + ''. + ''. + ''. + + ''. + ''. + ''. + ''. + + ''. + ''. + ''. + ''. + + ''. + ''. + ''. + ''. + + ''. + ''. + ''. + ''. + + ''. + ''. + ''. + ''. + + ''. + ''. + ''. + ''. + '
    '.__('_xfn_Me').'

    '.'

    '.__('_xfn_Friendship').'

    '. + ' '. + ' '. + ' '. + ''. + '

    '.__('_xfn_Physical').'

    '. + ''. + '

    '.__('_xfn_Professional').'

    '. + ' '. + ''. + '

    '.__('_xfn_Geographical').'

    '. + ' '. + ' '. + ''. + '

    '.__('_xfn_Family').'

    '. + ' '. + ' '. + ' '. + ' '. + ' '. + ''. + '

    '.__('_xfn_Romantic').'

    '. + ' '. + ' '. + ' '. + ' '. + '

    '. + + '
    '. + + '
    '; +} +?> + + \ No newline at end of file diff --git a/plugins/blogroll/icon-small.png b/plugins/blogroll/icon-small.png new file mode 100644 index 0000000000000000000000000000000000000000..890833937db1b4293a3c4c5194634cecbaaee398 GIT binary patch literal 848 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 + +if (!empty($_REQUEST['edit']) && !empty($_REQUEST['id'])) { + include dirname(__FILE__).'/edit.php'; + return; +} + +$default_tab = ''; +$link_title = $link_href = $link_desc = $link_lang = ''; +$cat_title = ''; + +# Import links +if (!empty($_POST['import_links']) && !empty($_FILES['links_file'])) +{ + $default_tab = 'import-links'; + + try + { + files::uploadStatus($_FILES['links_file']); + $ifile = DC_TPL_CACHE.'/'.md5(uniqid()); + if (!move_uploaded_file($_FILES['links_file']['tmp_name'],$ifile)) { + throw new Exception(__('Unable to move uploaded file.')); + } + + require_once dirname(__FILE__).'/class.dc.importblogroll.php'; + try { + $imported = dcImportBlogroll::loadFile($ifile); + @unlink($ifile); + } catch (Exception $e) { + @unlink($ifile); + throw $e; + } + + + if (empty($imported)) { + unset($imported); + throw new Exception(__('Nothing to import')); + } + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} + +if (!empty($_POST['import_links_do'])) { + foreach ($_POST['entries'] as $idx) { + $link_title = $_POST['title'][$idx]; + $link_href = $_POST['url'][$idx]; + $link_desc = $_POST['desc'][$idx]; + try { + $blogroll->addLink($link_title,$link_href,$link_desc,''); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + $default_tab = 'import-links'; + } + } + http::redirect($p_url.'&importlinks=1'); +} + +if (!empty($_POST['cancel_import'])) { + $core->error->add(__('Import operation cancelled.')); + $default_tab = 'import-links'; +} + +# Add link +if (!empty($_POST['add_link'])) +{ + $link_title = $_POST['link_title']; + $link_href = $_POST['link_href']; + $link_desc = $_POST['link_desc']; + $link_lang = $_POST['link_lang']; + + try { + $blogroll->addLink($link_title,$link_href,$link_desc,$link_lang); + http::redirect($p_url.'&addlink=1'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + $default_tab = 'add-link'; + } +} + +# Add category +if (!empty($_POST['add_cat'])) +{ + $cat_title = $_POST['cat_title']; + + try { + $blogroll->addCategory($cat_title); + http::redirect($p_url.'&addcat=1'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + $default_tab = 'add-cat'; + } +} + +# Delete link +if (!empty($_POST['removeaction']) && !empty($_POST['remove'])) { + foreach ($_POST['remove'] as $k => $v) + { + try { + $blogroll->delItem($v); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + break; + } + } + + if (!$core->error->flag()) { + http::redirect($p_url.'&removed=1'); + } +} + +# Order links +$order = array(); +if (empty($_POST['links_order']) && !empty($_POST['order'])) { + $order = $_POST['order']; + asort($order); + $order = array_keys($order); +} elseif (!empty($_POST['links_order'])) { + $order = explode(',',$_POST['links_order']); +} + +if (!empty($_POST['saveorder']) && !empty($order)) +{ + foreach ($order as $pos => $l) { + $pos = ((integer) $pos)+1; + + try { + $blogroll->updateOrder($l,$pos); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } + } + + if (!$core->error->flag()) { + http::redirect($p_url.'&neworder=1'); + } +} + + +# Get links +try { + $rs = $blogroll->getLinks(); +} catch (Exception $e) { + $core->error->add($e->getMessage()); +} + +?> + + + Blogroll + + + + + + + +

    blog->name); ?> › Blogroll

    + +'.__('Items order has been successfully updated').'

    '; +} + +if (!empty($_GET['removed'])) { + echo '

    '.__('Items have been successfully removed.').'

    '; +} + +if (!empty($_GET['addlink'])) { + echo '

    '.__('Link has been successfully created.').'

    '; +} + +if (!empty($_GET['addcat'])) { + echo '

    '.__('category has been successfully created.').'

    '; +} + +if (!empty($_GET['importlinks'])) { + echo '

    '.__('links have been successfully imported.').'

    '; +} +?> + +
    + +
    + +'. +''. +'
    '; + +echo +'
    '. +'
    '. +'
    '.__('Add a new category').''. +'

    '. +form::hidden(array('p'),'blogroll'). +$core->formNonce(). +'

    '. +'
    '. +'
    '. +'
    '; + +echo +''; +?> + + + \ No newline at end of file diff --git a/plugins/blogroll/locales/en/main.lang.php b/plugins/blogroll/locales/en/main.lang.php new file mode 100644 index 0000000..4f2b366 --- /dev/null +++ b/plugins/blogroll/locales/en/main.lang.php @@ -0,0 +1,44 @@ + \ No newline at end of file diff --git a/plugins/blogroll/locales/en/main.po b/plugins/blogroll/locales/en/main.po new file mode 100644 index 0000000..bfb0e25 --- /dev/null +++ b/plugins/blogroll/locales/en/main.po @@ -0,0 +1,74 @@ +msgid "_xfn_Me" +msgstr "Me" + +msgid "_xfn_Another link for myself" +msgstr "Another link for myself" + +msgid "_xfn_Friendship" +msgstr "Friendship" + +msgid "_xfn_Contact" +msgstr "Contact" + +msgid "_xfn_Acquaintance" +msgstr "Acquaintance" + +msgid "_xfn_Friend" +msgstr "Friend" + +msgid "_xfn_Physical" +msgstr "Physical" + +msgid "_xfn_Met" +msgstr "Met" + +msgid "_xfn_Professional" +msgstr "Professional" + +msgid "_xfn_Co-worker" +msgstr "Co-worker" + +msgid "_xfn_Colleague" +msgstr "Colleague" + +msgid "_xfn_Geographical" +msgstr "Geographical" + +msgid "_xfn_Co-resident" +msgstr "Co-resident" + +msgid "_xfn_Neighbor" +msgstr "Neighbor" + +msgid "_xfn_Family" +msgstr "Family" + +msgid "_xfn_Child" +msgstr "Child" + +msgid "_xfn_Parent" +msgstr "Parent" + +msgid "_xfn_Sibling" +msgstr "Sibling" + +msgid "_xfn_Spouse" +msgstr "Spouse" + +msgid "_xfn_Kin" +msgstr "Kin" + +msgid "_xfn_Romantic" +msgstr "Romantic" + +msgid "_xfn_Muse" +msgstr "Muse" + +msgid "_xfn_Crush" +msgstr "Crush" + +msgid "_xfn_Date" +msgstr "Date" + +msgid "_xfn_Sweetheart" +msgstr "Sweetheart" \ No newline at end of file diff --git a/plugins/blowupConfig/_admin.php b/plugins/blowupConfig/_admin.php new file mode 100644 index 0000000..f6546e2 --- /dev/null +++ b/plugins/blowupConfig/_admin.php @@ -0,0 +1,26 @@ +addBehavior('adminCurrentThemeDetails','blowup_config_details'); + +if (!isset($__resources['help']['blowupConfig'])) { + $__resources['help']['blowupConfig'] = dirname(__FILE__).'/help.html'; +} + +function blowup_config_details($core,$id) +{ + if ($id == 'default' && $core->auth->check('admin',$core->blog->id)) { + return '

    '.__('Theme configuration').'

    '; + } +} +?> \ No newline at end of file diff --git a/plugins/blowupConfig/_define.php b/plugins/blowupConfig/_define.php new file mode 100644 index 0000000..bf280bc --- /dev/null +++ b/plugins/blowupConfig/_define.php @@ -0,0 +1,21 @@ +registerModule( + /* Name */ "Blowup Config", + /* Description*/ "Configure your Blowup Theme", + /* Author */ "Olivier Meunier", + /* Version */ '1.0', + /* Permissions */ 'admin' +); +?> \ No newline at end of file diff --git a/plugins/blowupConfig/_public.php b/plugins/blowupConfig/_public.php new file mode 100644 index 0000000..4e3fed2 --- /dev/null +++ b/plugins/blowupConfig/_public.php @@ -0,0 +1,193 @@ +blog->settings->theme != 'default') { + return; +} + +require dirname(__FILE__).'/lib/class.blowup.config.php'; +$core->addBehavior('publicHeadContent',array('tplBlowupTheme','publicHeadContent')); + +class tplBlowUpTheme +{ + public static function publicHeadContent(&$core) + { + echo '\n"; + } + + public static function blowUpStyleHelper() + { + $s = $GLOBALS['core']->blog->settings->blowup_style; + + if ($s === null) { + return; + } + + $s = @unserialize($s); + if (!is_array($s)) { + return; + } + + $css = array(); + + /* Sidebar position + ---------------------------------------------- */ + if ($s['sidebar_position'] == 'left') { + $css['#wrapper']['background-position'] = '-300px 0'; + $css['#main']['float'] = 'right'; + $css['#sidebar']['float'] = 'left'; + } + + /* Properties + ---------------------------------------------- */ + self::prop($css,'body','background-color',$s['body_bg_c']); + + self::prop($css,'body','color',$s['body_txt_c']); + self::prop($css,'.post-tags li a:link, .post-tags li a:visited, .post-info-co a:link, .post-info-co a:visited','color',$s['body_txt_c']); + self::prop($css,'#page','font-size',$s['body_txt_s']); + self::prop($css,'body','font-family',blowupConfig::fontDef($s['body_txt_f'])); + + self::prop($css,'.post-content, .post-excerpt, #comments dd, #pings dd, dd.comment-preview','line-height',$s['body_line_height']); + + if (!$s['blog_title_hide']) + { + self::prop($css,'#top h1 a','color',$s['blog_title_c']); + self::prop($css,'#top h1','font-size',$s['blog_title_s']); + self::prop($css,'#top h1','font-family',blowupConfig::fontDef($s['blog_title_f'])); + + if ($s['blog_title_a'] == 'right' || $s['blog_title_a'] == 'left') { + $css['#top h1'][$s['blog_title_a']] = '0px'; + $css['#top h1']['width'] = 'auto'; + } + + if ($s['blog_title_p']) + { + $_p = explode(':',$s['blog_title_p']); + $css['#top h1']['top'] = $_p[1].'px'; + if ($s['blog_title_a'] != 'center') { + $_a = $s['blog_title_a'] == 'right' ? 'right' : 'left'; + $css['#top h1'][$_a] = $_p[0].'px'; + } + } + } + else + { + self::prop($css,'#top h1 span','text-indent','-5000px'); + self::prop($css,'#top h1','top','0px'); + $css['#top h1 a'] = array( + 'display' => 'block', + 'height' => $s['top_height'] ? ($s['top_height']-10).'px' : '120px', + 'width' => '800px' + ); + } + self::prop($css,'#top','height',$s['top_height']); + + self::prop($css,'.day-date','color',$s['date_title_c']); + self::prop($css,'.day-date','font-family',blowupConfig::fontDef($s['date_title_f'])); + self::prop($css,'.day-date','font-size',$s['date_title_s']); + + self::prop($css,'a','color',$s['body_link_c']); + self::prop($css,'a:visited','color',$s['body_link_v_c']); + self::prop($css,'a:hover, a:focus, a:active','color',$s['body_link_f_c']); + + self::prop($css,'#comment-form input, #comment-form textarea','color',$s['body_link_c']); + self::prop($css,'#comment-form input.preview','color',$s['body_link_c']); + self::prop($css,'#comment-form input.preview:hover','background',$s['body_link_f_c']); + self::prop($css,'#comment-form input.preview:hover','border-color',$s['body_link_f_c']); + self::prop($css,'#comment-form input.submit','color',$s['body_link_c']); + self::prop($css,'#comment-form input.submit:hover','background',$s['body_link_f_c']); + self::prop($css,'#comment-form input.submit:hover','border-color',$s['body_link_f_c']); + + self::prop($css,'#sidebar','font-family',blowupConfig::fontDef($s['sidebar_text_f'])); + self::prop($css,'#sidebar','font-size',$s['sidebar_text_s']); + self::prop($css,'#sidebar','color',$s['sidebar_text_c']); + + self::prop($css,'#sidebar h2','font-family',blowupConfig::fontDef($s['sidebar_title_f'])); + self::prop($css,'#sidebar h2','font-size',$s['sidebar_title_s']); + self::prop($css,'#sidebar h2','color',$s['sidebar_title_c']); + + self::prop($css,'#sidebar h3','font-family',blowupConfig::fontDef($s['sidebar_title2_f'])); + self::prop($css,'#sidebar h3','font-size',$s['sidebar_title2_s']); + self::prop($css,'#sidebar h3','color',$s['sidebar_title2_c']); + + self::prop($css,'#sidebar ul','border-top-color',$s['sidebar_line_c']); + self::prop($css,'#sidebar li','border-bottom-color',$s['sidebar_line_c']); + self::prop($css,'#topnav ul','border-bottom-color',$s['sidebar_line_c']); + + self::prop($css,'#sidebar li a','color',$s['sidebar_link_c']); + self::prop($css,'#sidebar li a:visited','color',$s['sidebar_link_v_c']); + self::prop($css,'#sidebar li a:hover, #sidebar li a:focus, #sidebar li a:active','color',$s['sidebar_link_f_c']); + self::prop($css,'#search input','color',$s['sidebar_link_c']); + self::prop($css,'#search .submit','color',$s['sidebar_link_c']); + self::prop($css,'#search .submit:hover','background',$s['sidebar_link_f_c']); + self::prop($css,'#search .submit:hover','border-color',$s['sidebar_link_f_c']); + + self::prop($css,'.post-title','color',$s['post_title_c']); + self::prop($css,'.post-title a, .post-title a:visited','color',$s['post_title_c']); + self::prop($css,'.post-title','font-family',blowupConfig::fontDef($s['post_title_f'])); + self::prop($css,'.post-title','font-size',$s['post_title_s']); + + self::prop($css,'#comments dd','background-color',$s['post_comment_bg_c']); + self::prop($css,'#comments dd','color',$s['post_comment_c']); + self::prop($css,'#comments dd.me','background-color',$s['post_commentmy_bg_c']); + self::prop($css,'#comments dd.me','color',$s['post_commentmy_c']); + + self::prop($css,'#prelude, #prelude a','color',$s['prelude_c']); + + self::prop($css,'#footer p','background-color',$s['footer_bg_c']); + self::prop($css,'#footer p','color',$s['footer_c']); + self::prop($css,'#footer p','font-size',$s['footer_s']); + self::prop($css,'#footer p','font-family',blowupConfig::fontDef($s['footer_f'])); + self::prop($css,'#footer p a','color',$s['footer_l_c']); + + /* Images + ------------------------------------------------------ */ + self::backgroundImg($css,'body',$s['body_bg_c'],'body-bg.png'); + self::backgroundImg($css,'body',$s['body_bg_g'] != 'light','body-bg.png'); + self::backgroundImg($css,'body',$s['prelude_c'],'body-bg.png'); + self::backgroundImg($css,'#top',$s['body_bg_c'],'page-t.png'); + self::backgroundImg($css,'#top',$s['body_bg_g'] != 'light','page-t.png'); + self::backgroundImg($css,'#top',$s['uploaded'] || $s['top_image'],'page-t.png'); + self::backgroundImg($css,'#footer',$s['body_bg_c'],'page-b.png'); + self::backgroundImg($css,'#comments dt',$s['post_comment_bg_c'],'comment-t.png'); + self::backgroundImg($css,'#comments dd',$s['post_comment_bg_c'],'comment-b.png'); + self::backgroundImg($css,'#comments dt.me',$s['post_commentmy_bg_c'],'commentmy-t.png'); + self::backgroundImg($css,'#comments dd.me',$s['post_commentmy_bg_c'],'commentmy-b.png'); + + $res = ''; + foreach ($css as $selector => $values) { + $res .= $selector." {\n"; + foreach ($values as $k => $v) { + $res .= $k.':'.$v.";\n"; + } + $res .= "}\n"; + } + return $res; + } + + protected static function prop(&$css,$selector,$prop,$value) + { + if ($value) { + $css[$selector][$prop] = $value; + } + } + + protected static function backgroundImg(&$css,$selector,$value,$image) + { + $file = blowupConfig::imagesPath().'/'.$image; + if ($value && file_exists($file)){ + $css[$selector]['background-image'] = 'url('.blowupConfig::imagesURL().'/'.$image.')'; + } + } +} +?> \ No newline at end of file diff --git a/plugins/blowupConfig/alpha-img/comment-b.png b/plugins/blowupConfig/alpha-img/comment-b.png new file mode 100644 index 0000000000000000000000000000000000000000..b1d37c6decab7eed6f600371942c8fb8e0088cfb GIT binary patch literal 1328 zcmcIkO=uHA7~N{EHCn_XA|f)Zd+^ZB>~7MgSvIL{(w|5ZN)s@8a6U+G~M)PpUZY46^rg_vxSVJ}xg92)%P)J*srYTtRER6sz$S62XX0MZG*vEIj)6#AH&6*f+bk)t9sFl~jjHLjpw|+% z?&VJDtyUh$rtSNI$Tvg}GRfBX;92_nD5sLcxtSxI8y)G+;nSDbA>y7rSPl1PKFgQ5 z`^;Tt?aRwMTxy%| qQ*MQpUa!xhbe;R<=3l*-z4@bS(|P=joH&%HX_?e$Ci#5i#_c~8c3(LF literal 0 HcmV?d00001 diff --git a/plugins/blowupConfig/alpha-img/comment-t.png b/plugins/blowupConfig/alpha-img/comment-t.png new file mode 100644 index 0000000000000000000000000000000000000000..b320da374aaa3d423feab93f4c1b137606e3b95a GIT binary patch literal 1549 zcmeAS@N?(olHy`uVBq!ia0y~yVEh7POLDLQ$>Y^`l7JLTv6E*A2N2Y7q;vrJoCO|{ z#S9GGLLkg|>2BR0prA~NYeY$Kep*R+Vo@rCV@iHfs)Ac)QEGX9QFgI{bFlG@Yi`Uy zbz&fO&PAz-C7Jno3L%-fsSF0D`UXb&1{N>OJL-V834&Ba`1)8S=jZArf(+8D$Sq*7 zv9BmdOwLX%QAkQn&&;z`QczG(QpilPRSGxtHSjHPPR+>ls47YguJQ{>uF6ifOi{A8 zg`H`7rFPApOIO3YI*GFLD%FaQ!pR)&UFCWb)AfPs=77m&6oN=dT{ za&d#&3FO%-Wt5Z@Sn2DRmzV368|&p4rRy77T3Uj9Ze*kjRH0j3nOBlnp_^B%3^4>| zj!SBBa#3ahIJ`jSCMM;Vme?vOfh>XpsOJ(3;1=Z-Ljw;OjQSOc1^R}12KsQ5ff{Xq zf>z*|$S(@X&(E>L5@|LdohXVBwj%VWx+IpQ+5yAELf61Z*T6Ky(A)}$Oe~|2^g|S( zY4^=f$xN$6*KTBJWn^MyUb)jCk(It(eyqz{=dq!{4;mK6qS>Hy|0Uo9slVX@j=IP(p;(Qk2%|a@>+OKN;!V4G~&7WLj|Cy z^z`lLxF4v1SzFI>Ka2z#XRen%SNu?~if2;HvCDgyWK=zc9>1MiI3v7aF;HyJUjNTt zK;u1owtqEQ&(RGO`g2{9f5%ZH&q+@nZFnHYZ}EHjM}O^Uo|9Cw_xKVF#ttuHS4bo4<_D$uph5)M`t%mPYATJZKwR`E3BJ`U7%`@6X1$F;AXu5Nz@ QERq>KUHx3vIVCg!0MY@?hX4Qo literal 0 HcmV?d00001 diff --git a/plugins/blowupConfig/alpha-img/gradient-d.png b/plugins/blowupConfig/alpha-img/gradient-d.png new file mode 100644 index 0000000000000000000000000000000000000000..74bf9cfbd6ccab96707908bb980714fb9389325d GIT binary patch literal 1432 zcmcIkO-vI(6ke5RsbC@p62-%0jq#xE{M`rLoaV z?e3Fqf*{&s!_jd(v$(%;9meC@+FgXF7IPq$bYZ*gl5D(h)rW7G1aY*(=?BW+XST4j z6AezFhyev8Ybr>}3MA-mie@RgcOziWV8kg0ki{>)mlWu18=-9xfU% zQ5;Q*#jF^V$iA?fw>V5zAQFJ3L^J~eznAfd zw9gOxJzh4z1_M3kK|(-aL{I@604z=8f#n#6^E0@ZijiSAo_Rw`apTdUT28zRkr{+^ zj-vAUyf^RjYDSu3g2AAp5X*Wn!ebUxBv>BRJY5a49VZG+(UA3uu1;KGN}EO@l5`T) zt#&v;uP0K?ns``7$`W*n@zPX1GA8oa$yIJlGm@H?3;*Lvc!#+I)X3W4!>E8@80*pN zp;-^zon!(WZvNoSCVmyPiyqe`IaSy}XM9P<&-ntl)#y#28l9&cA)17#sP3F;mmlmQ zm?YNq(x;7Ff;p%_6`5EwW~XM7$fYzx5l~oGgfygdHO*5E=YQ*~R*jzpewI}I zU2d0Nzsh}CG<4sW@YSIEndC=e#E(Cb&#`EK()#vm{dMai-PW>5@wa}THJ+Cjmdf&M z*ywX*g+py<8ZrGXoHP+UJt6w%(T?d=(ajv+T{RHkTzQxBQ NVuPd6R|As|{sQz3b~^w7 literal 0 HcmV?d00001 diff --git a/plugins/blowupConfig/alpha-img/gradient-l.png b/plugins/blowupConfig/alpha-img/gradient-l.png new file mode 100644 index 0000000000000000000000000000000000000000..c39567946ea756bcc4a7760c21489c6d251bb4be GIT binary patch literal 1443 zcmcIkOK1~O6dkpeHnj^~h!l~>v`druWZE=Cl75n=Nj0T3BgTT@bmk?QCiCgcluScy ztE+V3Mrx}IcY@eLLDapAf*`sn8iHUqx^ScJ{2}O@B+aLYy6NT3`&`bs_r7xMdJjf5uAN~7;_TPvE2#U&FhEyi$^YeTlsCKk}SU5i{YFs$Q*{T<6uI5B1Kb|&C zjU|X&F6YX*U8 zz01AQYppzxO-}Hr%bOdY(%M#9AN(&{3_4nB_MVC46A#vAUPgMjb59!i3jyoV=Gu)?A(XA5?ag-l zYe)O*N$1LoQeo!Wa+7^qICU!$*$(&6Lifhe!?x|T-n=s!EKU*P=c~-UjUSi0h8nXB Z;%9b+*;k?Ot4rvnSaf7Ov^9L?`fu~~fRg|K literal 0 HcmV?d00001 diff --git a/plugins/blowupConfig/alpha-img/gradient-m.png b/plugins/blowupConfig/alpha-img/gradient-m.png new file mode 100644 index 0000000000000000000000000000000000000000..b25c6bafd5a507ba4fa37b744097067b493d8d81 GIT binary patch literal 1446 zcmcIkOHUI~6dogDEolsx5MMDjW8%to9vvv1wB^yE4`LB$4amYc%-oi-org2Gb|3^3 zU5E=Y#tjQ&+?%i`a}ojvsHr#b=!t0I*Dpl zJ)CIN5@}XdJS-z+iw4E`XsQ+&6GPa^mv2lrGrC@g{NYMM4)YMGp0&=0f{0)Q>(S+< zSufp@VFEmETyVUBUjZGVr*v7#P935%{tUzM{s3-OdIP9R4^fT~4Z@UFcg}Rg5B?#T zEYjh_X6mQ?Ls z9+Y0Y%41p7bw8Hym7vF&=Yq7dw73-*zO{1Y*+ucdJCi`G_%WjKS zQG|Mx`l4XZO|_niAbRLg4?TG3K@>gJB9sbVdvG>MleQE+b=aN9&-Z=*Ki>@VXfWO1 z;yL310JJ0r5<>tqK{9u{kC5I~m|Y~pVWTIRb(416El!hlvo>(m0N~gu=XZVnHnl~9 zXU*ObGo$8Bi`Oye7S&M<`y?G(s$Mi;JmY`9+Sf#IryX2e$Gj=23d~9}26Pb7ETY@j zL(@|v+ers8lDfhPs_f$(A)hU4Akt}Tyimj@9K{7miBb?k3QA&>$^}z&N{iz$X<$;v znaOlkm@Eomk?M?jA~r|JGB$Z=%O%C&>?l>yyv!?*4MCQsNyl;w!vz>pOr=pV4;dr6nCFHPeYKoq6{W^Z zQ{xb_EX!y4eX3qSOgJ2NcFwY1g76v>ipkqv#kf!v+15#5L(nCy;+Lb#kE-Kll%kwO z^;X*)uhkPNM$J58BeHo7F+LjAl?gFIf?VY!R6VPzrPw})7IB!nK#i;oK2Go^juAiF zy)^5kgIOlTkuMOwwu4^mizjuAVIskrX!X-^#f$1qW- z`=yQRrOL600>ULMW5qOxXUuNTM1jkzy3Cs~N#+X}X-Xl28o__oSFM^{3vw+{{a$XD zUO&nMnKXPq5c#U;K_+?p>g^nPKCEP-J8Qc(mY3xRgD1L{H`bqZ&Cm2)oat&tpUw}p zJ}rIJW?#&&5a>%Qy>t|S-|z2~y#U<%DgRmE4gp}VFn7ztH(UUG-7K$eJ#c``%FwZf379IFJNFnNOWOiV+57EBu&~1!PL|Fems5Od+)w`zNgityW{Dr zX#l`@dA_s^Knn78dL+fiE&T2~pHlHm*&ZDo{jz`W8{eL*F50sP2M2q5d%MLggImVJ z`PCSJ^B2W8^6BftUjUrFz-Cw2N@dY>sIOp`t`jBkLtsrMA$D4X!FAH~g1iJFl%VJ4 zrTY^VwGtM|hBv(tNfe zw_z@q=K3-DE-!5`7McikIvu5xQE1denqe47)se2t93jWs0mF$L#5a0Q4*ir!>_lG3 zJQ_gZ7q8PzmX{ovBI(=}T)Ol^{j z+NU1@_30K8LL3pMtGYPT3H$#9bDe=+;bzqCUW@A>(k4C$Sj;ukj%(&RW`jmPW(Cj3 zO@hLpX`!LD9^IX%rFcRoJ;&0mab;&G_a2J7I6 zfWK7itIu=d1-dM7-QpI%jqUjaWK^W)cz>~9dCd`5%B5-h=5uH5&6%~gPpQ_ literal 0 HcmV?d00001 diff --git a/plugins/blowupConfig/alpha-img/page-t/animals.png b/plugins/blowupConfig/alpha-img/page-t/animals.png new file mode 100644 index 0000000000000000000000000000000000000000..4db1e880b28da32d9aa1204aaaa1973245713897 GIT binary patch literal 28044 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 X)1FU#uRCTg8bDoHN2yZLI`sbl`^Pc) literal 0 HcmV?d00001 diff --git a/plugins/blowupConfig/alpha-img/page-t/blank.png b/plugins/blowupConfig/alpha-img/page-t/blank.png new file mode 100644 index 0000000000000000000000000000000000000000..18ae6e8e9783b2ba9f724dce0cbe89b9df220e16 GIT binary patch literal 1892 zcmcIkOK1~87@j_mSgBYkiVtvDPol{_k~Ynn#A?&@K~riIwALQF-JP~;lHFx@HEF3* ztAh0+h@c>%;#Ix$;z7k;dh?*5hho8#52_#tMZtsrY|?F4ieB1*o&DyY|NH0r|9MRJ zbhp*k?5;rw)poQedJ(F^fTw($pnuWzXdC>htz#V-AG8Udauvp#jrLO(LR+@euj0+Z zh2LP@Yq$2piNzS>#1sKjGs|Gd#m>fQtK#+{Oe zg)kO44mv^Pc`?L;7^gAu8u&*|WmxP@B+F~UD8`K1wjr`?p->1Ef&tweVfjcT!g2yD z2!8PJTVt9n75$pEzZ7ISPJ&pnsT#JbYnaBBhV-*`jA7_PZYw7z8SX-wRW2Tsku6FF z%Lh2tjSR#n7{wNoNVaZfbUhbeV@slx>2X?Fb%jq7l1<`Jk0w7S`1xRlZxFeV$Z`Fv z_$8;m=qX)MhsRdYLw+Gd=|P}}%k))FWqOpQg;-S>r|LAPzwG}jm?FFNGR~SgXIm7R zB{`BOnr%VNcyG-VSsd2Qyky7Kyfi{sLmP>*E5?87E2)NK0mqVc&*idocPlpptkiu& z!k2<>*07dmV|Rnd1Dn_p`NA&GoIX z4@__WTz~jMedqnli*r||ld0+xpKg9X7ycELpB;bo_VIirLO&OlMyJOn(y6y+f(U&; z*@pAit}i4JdUr#P5Y*xY6`=I^_jasbleg zbz{z_Kpm~!i6_Sfr~Ux1 CnuJLJ literal 0 HcmV?d00001 diff --git a/plugins/blowupConfig/alpha-img/page-t/butterflies.png b/plugins/blowupConfig/alpha-img/page-t/butterflies.png new file mode 100644 index 0000000000000000000000000000000000000000..2a790c5df64dba45018fd7327cee1a0550ce60a9 GIT binary patch literal 6350 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 literal 0 HcmV?d00001 diff --git a/plugins/blowupConfig/alpha-img/page-t/default.png b/plugins/blowupConfig/alpha-img/page-t/default.png new file mode 100644 index 0000000000000000000000000000000000000000..1ea06207790cb086cab882a4f2e3ddc166f83f30 GIT binary patch literal 1926 zcmc&#S!feM7@oFKW2In46g-Emf}qJBiH%v3*dzAPrb-iN?UUQxNnD#f+})bAs1)^~ zeGwn5R7CJq6c3^(h(`qxL42rKP&^QQQUrYyRB&dKZo3*3gyIjG{pZ{7zrGnZqq{m= zYpPdN0|08;+u~gSR6*@P9FONrYUGsto|rf?5QWQ3pQ&8 zf+yxe(+S1}_}XvV4%m&Dci8s_`>oNNK(+-cqWG zcTsAuW$8Rk=W;oJF5uUU49$kaVWJSn`7pz04yu-r_o-%GG0AkEI5I^;)@@x$UZGDL zu%Z-23OQC9PSBk~s#y{b%Sh)1oo4+E?PSJ*5e)M7iD^bk)3UKLM-m~CF49cZnRpZz zEEL0fZ1FLij}4^Q%{&w28K!que3A4^ctVrp^q@ODm|{abLo$@YXOT+b5t;}wOBh>q zGSe?O{EJ|c=;);n7+L#RB#}m0q#)HYv1Y7WGfCvrnxP0*Ojd*pqIESBp=ZE9_E+p0 zUkiLKY3E)}x9%L}oH#SO&q?}X(zz^>oI1V%fXa#Xcw;L6;?v8kHTN5q&YRfyX#LIP z)6pIK7oNPb&eI0rz2)ZyCxf30V^7vR!yldTiCVl?R07~7pR(VahGC47S8k`$Q$k$M zVu;BEaXG`FqKLR1&q!T4wiEAWlZ-av@s@L71I|TWxg9c&jkuihlRC4zCv|3bO=@#~ zoAlp$AO3$jw3bzETF2qLH7B|+OnvBDecHA|ci+8U^6~4nediB^0>lbyvzJfhzU&{U zv$x;gUfNkp#U2yO_8xoxe9R6zd+W!Sqo&O$6mA^fXD+b)Ggp-N-M7-j>N5}Zsv>xO Z<;TdIb>ALv_|Fr7_HCWoN@pF literal 0 HcmV?d00001 diff --git a/plugins/blowupConfig/alpha-img/page-t/flamingo.png b/plugins/blowupConfig/alpha-img/page-t/flamingo.png new file mode 100644 index 0000000000000000000000000000000000000000..71388ee1432c56077f346b458a39df1e3851e966 GIT binary patch literal 12864 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 EUod-0?f?J) literal 0 HcmV?d00001 diff --git a/plugins/blowupConfig/alpha-img/page-t/flourish-1.png b/plugins/blowupConfig/alpha-img/page-t/flourish-1.png new file mode 100644 index 0000000000000000000000000000000000000000..48c01e3b2aa2fe8944b2263e2a346e4612b2de73 GIT binary patch literal 5045 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 EA5xVMK>z>% literal 0 HcmV?d00001 diff --git a/plugins/blowupConfig/alpha-img/page-t/flourish-2.png b/plugins/blowupConfig/alpha-img/page-t/flourish-2.png new file mode 100644 index 0000000000000000000000000000000000000000..2707e5a21c7c00130b3ba6285426c925bfaac252 GIT binary patch literal 12838 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 PallZ|RJRoA8u5Ps3?YkO literal 0 HcmV?d00001 diff --git a/plugins/blowupConfig/alpha-img/page-t/image-mask.png b/plugins/blowupConfig/alpha-img/page-t/image-mask.png new file mode 100644 index 0000000000000000000000000000000000000000..998613bcd9d98b2c37c322a7d7601df34b395eef GIT binary patch literal 1982 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 `#t2{BJ;Q@DS<3y;mE2X~ zqx2oO^L_xp>wo`qo&n@HE-QcxYt5ER9kgM|xGJ#WdeA|>E9p4z1!8~>ee7{vnN=5>QWHsTu4-krxamsuvQ_ct zj*xNwpwSIBoW2je1y{b2>sxEw{oDWkqDb5WKbr3Ouhdwu?3Ld6~%(beO?)#?Of6+ms?GOsU5hTdf z1`u`LChc*uS$;hxd|-Wq6pZg5B{)t@p{;K4q5d0iYXJL(Zvc7ezkTb<4T3OfhbMSp z$4C#Nao44VwQ`sHu<%*7c}BC02myFiF;;Zv{O*i%F4@i7Mvz}VDE z))q51f=%1R?yi8*2q4_U!4X1&N5T852IXHO4pgXE;bC5^eL; zX85RmZpi)60m$3GocITzZsmi! zyxT*}1*UwNh{`3FDPIV*5K>yq3{}RcKK#oI6X%t!%AipN4^xf@3=3D&f;NQW@9NEP zoe72jjQ|@#f&>7mekTl{6J@xpUXyk4v^6n zGy-e{2@(Lr1R!PLpjwd-n-?S&gq!1RecYK!%&MKrErmU7@BvMUbW`$q@y~a>dq94z zAArbE@hYrP;Z|JQConXa*ndNGRN|@EIh6oJ`nr~30K^I*4vhwzMu4rHZh0Z%TC$@{ zj)xDpXft1QnO6d61PKyk2msN|&o%(jC8&=C;l@~CcP5cY*47fz_E_o&AF#~p@BCTM z0CM-&-Z<9>b;xxYRK-t!G0&*T6i zS}d*dl1$4N6LbPtT)K1Oa2kEzspU2MqkiX!CB|Ag07w-=bimAwKZXFYiKeZ?}2XsdFoPoK(0y%)a6-LLljkjvSkmPA+MXREa?t2H}b$!RRD}2 zL4sVBHJVy@v%56xWrw-i7kmJ~gFp9d0Fa=J2h}!6crkpA;$HjG<#_~rP8xmyiy%RQ z1OVv{A% z210BgLJsq=3wYS}bD7^Cdk2vJI(R_354HdfK`yg4e)UyJIrtn903t|`AVGpO1BerZ z5Vcxg7D?pX3@Hup(Fh>_Kmd>+&LYAD@LppI8Pv-lL4pJc667N2AiA(Ba@x-hB5lCK z2Yd_yAUA#`07y{gg9HiScsV2hW{@C3f?TGxtSf}*U<5tEqbqy_0103aBuJ2e8bN{t z2@>Rz0Eh`f+JZ>iwZauXT-TeOf53AY-Wz{ActFDHAHedxETOb=kRU;V1PL-6fV72> zrti4r=Y8P=0Cod_1UX+Y3t$jnB1n)RL4pJc;tN8W_G?tlI)FzT_y_3D-W_X2~Zy-NRS{wf>;6Mmji$V2@)ho z1z1BJtsp^y1PK!4@&L%+2mlf!$W;*;tocEL1PKx(ND$9*@DDxf7eF=xfCLE=BuJ1T kL4pJc62u4~Zhb)h|CFu^@vH#ft^fc407*qoM6N<$g7D#;*8l(j literal 0 HcmV?d00001 diff --git a/plugins/blowupConfig/alpha-img/page-t/light-trails-3.png b/plugins/blowupConfig/alpha-img/page-t/light-trails-3.png new file mode 100644 index 0000000000000000000000000000000000000000..d1dacc23c59c622c9854094e56facd0a78bce4ff GIT binary patch literal 38308 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

    UVQ$3oVlO**JLXmyfJTxbYS0 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 Ue@Im32f)wv%sHzn3$OV90ps@!^8f$< literal 0 HcmV?d00001 diff --git a/plugins/blowupConfig/alpha-img/page-t/light-trails-4.png b/plugins/blowupConfig/alpha-img/page-t/light-trails-4.png new file mode 100644 index 0000000000000000000000000000000000000000..901b6e736949c701c6f7875392918de9ca33f339 GIT binary patch literal 32171 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

    ^_vOrcjvKKoBXHFAtkXs3L*w}ej@ovTfb_w# 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 UrOm%c|FCjO6QKhygWU=HFT|>S6aWAK literal 0 HcmV?d00001 diff --git a/plugins/blowupConfig/alpha-img/page-t/typo.png b/plugins/blowupConfig/alpha-img/page-t/typo.png new file mode 100644 index 0000000000000000000000000000000000000000..ef7689d1032fe5123e26c8eca5be51f3562e91e9 GIT binary patch literal 15365 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 ');$(styles_combo).append('');for(var style in dotclear.blowup_styles){styles_option=document.createElement('option');styles_option.value=dotclear.blowup_styles[style];$(styles_option).append(style);$(styles_combo).append(styles_option);} +$('#theme_config').prepend(styles_combo);$(styles_combo).wrap('

    ').before(''+dotclear.msg.predefined_styles+'').wrap('

    ');$(styles_combo).change(function(){if(this.value=='none'){$(this.form).find('input[type=text]').val('').css({backgroundColor:'#FFF',color:'#000'});$(this.form).find('select').not($(this)).val('');$('#top_image').val('default');}else{applyBlowupValues(this.value);}});var e=$('#bu_export ~ fieldset:first');e.toggle();var img=document.createElement('img');img.src=dotclear.img_plus_src;img.alt=dotclear.img_plus_alt;img.className='expand';$(img).css('cursor','pointer');$(document.createTextNode(' ')).prependTo('#bu_export');$(img).prependTo('#bu_export');$(img).click(function(){if(e.css('display')=='none'){this.src=dotclear.img_minus_src;this.alt=dotclear.img_minus_alt;}else{this.src=dotclear.img_plus_src;this.alt=dotclear.img_plus_alt;} +e.toggle();});var a=document.createElement('a');a.href='#';$(a).text(dotclear.msg.apply_code);e.append(a);$(a).click(function(){var code=e.find('#export_code');if(code.size()==0){return false;} +applyBlowupValues(code.val());return false;});function toggleDisable(e){if(e.attr('disabled')){e.removeAttr('disabled');}else{e.attr('disabled','disabled');}} +function applyBlowupValues(code){code=code.replace("\n","");var re=/(^| )([a-zA-Z0-9_]+):"(.*?)"(;|$)/g;var s=code.match(re);if(typeof(s)=='object'&&s.length>0){var member,target,value,t_e;var reg=new RegExp('^(.+):"(.*)"(;?)\s*$');for(var i=0;i0.5?'#000':'#fff'});}} +function getColorLum(color) +{var rgb=[parseInt('0x'+color.substring(1,3))/255,parseInt('0x'+color.substring(3,5))/255,parseInt('0x'+color.substring(5,7))/255];return(Math.min(rgb[0],Math.min(rgb[1],rgb[2]))+Math.max(rgb[0],Math.max(rgb[1],rgb[2])))/2;}});dotclear.blowup_styles={'Spring Time':'body_bg_c:"#E0E0E0"; body_bg_g:"light"; body_txt_f:"ss1"; body_txt_s:"1.2em"; body_txt_c:"#6B6B6B"; body_line_height:"1.4em"; top_image:"light-trails-1"; blog_title_hide:"0"; blog_title_f:""; blog_title_s:"3.5em"; blog_title_c:"#9AC528"; blog_title_a:"center"; blog_title_p:""; body_link_c:"#279AC4"; body_link_f_c:"#6D8824"; body_link_v_c:"#279AC4"; sidebar_position:""; sidebar_text_f:""; sidebar_text_s:""; sidebar_text_c:"#6B6B6B"; sidebar_title_f:""; sidebar_title_s:""; sidebar_title_c:"#8FB22F"; sidebar_title2_f:""; sidebar_title2_s:""; sidebar_title2_c:"#279AC4"; sidebar_line_c:"#FFD02C"; sidebar_link_c:"#6B6B6B"; sidebar_link_f_c:"#9AC528"; sidebar_link_v_c:"#6B6B6B"; date_title_f:""; date_title_s:"1em"; date_title_c:"#279AC4"; post_title_f:""; post_title_s:"1.7em"; post_title_c:"#9AC528"; post_comment_bg_c:"#FFFAD1"; post_comment_c:"#6B6B6B"; post_commentmy_bg_c:"#F5F9D9"; post_commentmy_c:"#6B6B6B"; prelude_c:"#EDEDED"; footer_f:""; footer_s:"1.2em"; footer_c:"#9AC528"; footer_l_c:"#6D8824"; footer_bg_c:"#E0E0E0"','Forest':'body_bg_c:"#80661A"; body_bg_g:"light"; body_txt_f:""; body_txt_s:""; body_txt_c:"#0A0A00"; body_line_height:"1.4em"; top_image:"default"; blog_title_hide:"0"; blog_title_f:"s3"; blog_title_s:"4em"; blog_title_c:"#D9D9BF"; blog_title_a:""; blog_title_p:""; body_link_c:"#666600"; body_link_f_c:"#CC9933"; body_link_v_c:"#8D8D40"; sidebar_position:""; sidebar_text_f:""; sidebar_text_s:""; sidebar_text_c:"#0A0A00"; sidebar_title_f:"s2"; sidebar_title_s:"1.6em"; sidebar_title_c:"#4D4D00"; sidebar_title2_f:"s2"; sidebar_title2_s:""; sidebar_title2_c:"#575700"; sidebar_line_c:"#D9D9BF"; sidebar_link_c:"#40330D"; sidebar_link_f_c:"#666600"; sidebar_link_v_c:"#40330D"; date_title_f:""; date_title_s:""; date_title_c:"#B3B380"; post_title_f:"s2"; post_title_s:"2em"; post_title_c:"#4D4D00"; post_comment_bg_c:"#F0F0E6"; post_comment_c:"#0A0A00"; prelude_c:"#140F05"; footer_f:""; footer_s:""; footer_c:"#FFFFFF"; footer_l_c:"#D9AD2B"; footer_bg_c:"#33260D"','Flamingo':'body_bg_c:"#CC9999"; body_bg_g:"light"; body_txt_f:"ss3"; body_txt_s:"1.2em"; body_txt_c:"#1A1A00"; body_line_height:"1.5em"; top_image:"flamingo"; blog_title_hide:"0"; blog_title_f:"ss1"; blog_title_s:"3.5em"; blog_title_c:"#FFFFFF"; blog_title_a:""; blog_title_p:""; body_link_c:"#AD8282"; body_link_f_c:"#8282D9"; body_link_v_c:"#997373"; sidebar_position:""; sidebar_text_f:""; sidebar_text_s:""; sidebar_text_c:""; sidebar_title_f:"ss4"; sidebar_title_s:"1.4em"; sidebar_title_c:"#8282D9"; sidebar_title2_f:"ss3"; sidebar_title2_s:"1.2em"; sidebar_title2_c:"#AD8282"; sidebar_line_c:"#CDCDFF"; sidebar_link_c:"#262640"; sidebar_link_f_c:"#AD8282"; sidebar_link_v_c:"#262640"; date_title_f:"ss4"; date_title_s:""; date_title_c:"#D9B3B3"; post_title_f:"ss4"; post_title_s:"1.8em"; post_title_c:"#8282D9"; post_comment_bg_c:"#F2E5E5"; post_comment_c:""; prelude_c:"#140F0F"; footer_f:""; footer_s:""; footer_c:"#FFFFFF"; footer_l_c:""; footer_bg_c:"#140F0F"','Iceberg':'body_bg_c:"#5280A3"; body_bg_g:"dark"; body_txt_f:"ss3"; body_txt_s:"1.1em"; body_txt_c:"#757575"; body_line_height:"1.5em"; top_image:"default"; blog_title_hide:"0"; blog_title_f:"s2"; blog_title_s:"3em"; blog_title_c:"#FFFFFF"; blog_title_a:""; blog_title_p:""; body_link_c:"#BDB000"; body_link_f_c:"#F3E66D"; body_link_v_c:"#BDB000"; sidebar_position:"left"; sidebar_text_f:""; sidebar_text_s:""; sidebar_text_c:""; sidebar_title_f:"ss3"; sidebar_title_s:"1.4em"; sidebar_title_c:"#689B9C"; sidebar_title2_f:"ss3"; sidebar_title2_s:"1.2em"; sidebar_title2_c:"#737300"; sidebar_line_c:"#E6E6CD"; sidebar_link_c:"#66664D"; sidebar_link_f_c:"#5280A3"; sidebar_link_v_c:"#66664D"; date_title_f:""; date_title_s:""; date_title_c:"#000000"; post_title_f:"s2"; post_title_s:"1.8em"; post_title_c:"#6F6800"; post_comment_bg_c:"#E4E4E2"; post_comment_c:""; prelude_c:"#0E2734"; footer_f:""; footer_s:""; footer_c:"#FFFFFF"; footer_l_c:""; footer_bg_c:"#0E2734"','Night':'body_bg_c:"#0D1A26"; body_bg_g:"dark"; body_txt_f:"ss3"; body_txt_s:"1.1em"; body_txt_c:"#050A0F"; body_line_height:"1.5em"; top_image:"default"; blog_title_hide:"0"; blog_title_f:"s2"; blog_title_s:"3.5em"; blog_title_c:"#F2F2E5"; blog_title_a:""; body_link_c:"#336699"; body_link_f_c:"#66664D"; body_link_v_c:"#2B5782"; sidebar_position:""; sidebar_text_f:""; sidebar_text_s:""; sidebar_text_c:""; sidebar_title_f:"ss3"; sidebar_title_s:"1.4em"; sidebar_title_c:"#336699"; sidebar_title2_f:"ss3"; sidebar_title2_s:"1.2em"; sidebar_title2_c:"#737300"; sidebar_line_c:"#E6E6CD"; sidebar_link_c:"#66664D"; sidebar_link_f_c:"#336699"; sidebar_link_v_c:"#66664D"; date_title_f:""; date_title_s:""; date_title_c:"#ADAD82"; post_title_f:"s2"; post_title_s:"1.8em"; post_title_c:"#737300"; post_comment_bg_c:"#E6E6CD"; post_comment_c:""; prelude_c:"#070E14"; footer_f:""; footer_s:""; footer_c:"#FFFFFF"; footer_l_c:""; footer_bg_c:"#14140F"; blog_title_p:""','Peas & Carrots':'body_bg_c:"#9DCA25"; body_bg_g:"light"; body_txt_f:"ss1"; body_txt_s:"1.2em"; body_txt_c:"#383839"; body_line_height:"1.5em"; top_image:"butterflies"; blog_title_hide:"0"; blog_title_f:"ss4"; blog_title_s:"3em"; blog_title_c:"#DBDB9D"; blog_title_a:"left"; blog_title_p:""; body_link_c:"#646B10"; body_link_f_c:"#DF6C01"; body_link_v_c:"#919924"; sidebar_position:"left"; sidebar_text_f:""; sidebar_text_s:""; sidebar_text_c:""; sidebar_title_f:"ss4"; sidebar_title_s:""; sidebar_title_c:"#FE9017"; sidebar_title2_f:"s2"; sidebar_title2_s:"1.2em"; sidebar_title2_c:"#826228"; sidebar_line_c:"#D3EB8B"; sidebar_link_c:"#858547"; sidebar_link_f_c:"#FE9017"; sidebar_link_v_c:"#8F9645"; date_title_f:""; date_title_s:""; date_title_c:"#826228"; post_title_f:"ss4"; post_title_s:"1.8em"; post_title_c:"#806432"; post_comment_bg_c:"#EFFDCC"; post_comment_c:"#826228"; prelude_c:"#C8E186"; footer_f:""; footer_s:"1em"; footer_c:"#FFFFFF"; footer_l_c:"#FFFFFF"; footer_bg_c:"#484432"','Rabbit':'body_bg_c:"#8F9645"; body_bg_g:"solid"; body_txt_f:"ss1"; body_txt_s:"1.2em"; body_txt_c:"#625D47"; body_line_height:"1.4em"; top_image:"rabbit"; blog_title_hide:"0"; blog_title_f:"ss1"; blog_title_s:"3.5em"; blog_title_c:"#DBDB9D"; blog_title_a:""; blog_title_p:"130:70"; body_link_c:"#646B10"; body_link_f_c:"#484C12"; body_link_v_c:"#919924"; sidebar_position:""; sidebar_text_f:""; sidebar_text_s:""; sidebar_text_c:"#858547"; sidebar_title_f:""; sidebar_title_s:""; sidebar_title_c:"#8F9645"; sidebar_title2_f:"s2"; sidebar_title2_s:""; sidebar_title2_c:"#826228"; sidebar_line_c:"#95956B"; sidebar_link_c:"#858547"; sidebar_link_f_c:"#826228"; sidebar_link_v_c:"#8F9645"; date_title_f:"s2"; date_title_s:"1em"; date_title_c:"#826228"; post_title_f:"s2"; post_title_s:"1.6em"; post_title_c:"#806432"; post_comment_bg_c:"#D6DE91"; post_comment_c:"#826228"; prelude_c:"#484432"; footer_f:""; footer_s:"1em"; footer_c:"#A6AF50"; footer_l_c:"#DBDB9D"; footer_bg_c:"#484432"','Rec Room':'body_bg_c:"#9B5E1C"; body_bg_g:"dark"; body_txt_f:"ss3"; body_txt_s:"1.1em"; body_txt_c:"#757575"; body_line_height:"1.5em"; top_image:"default"; blog_title_hide:"0"; blog_title_f:"s2"; blog_title_s:"3em"; blog_title_c:"#F9FAD6"; blog_title_a:""; blog_title_p:""; body_link_c:"#D1BF1D"; body_link_f_c:"#EEE168"; body_link_v_c:"#D1BF1D"; sidebar_position:"left"; sidebar_text_f:""; sidebar_text_s:""; sidebar_text_c:""; sidebar_title_f:"ss3"; sidebar_title_s:"1.2em"; sidebar_title_c:"#689B9C"; sidebar_title2_f:"ss3"; sidebar_title2_s:"1.2em"; sidebar_title2_c:"#737300"; sidebar_line_c:"#E6E6CD"; sidebar_link_c:"#66664D"; sidebar_link_f_c:"#689B9C"; sidebar_link_v_c:"#66664D"; date_title_f:""; date_title_s:""; date_title_c:"#000000"; post_title_f:"s2"; post_title_s:"1.8em"; post_title_c:"#689B9C"; post_comment_bg_c:"#E4E4E2"; post_comment_c:""; prelude_c:"#3B2C16"; footer_f:""; footer_s:""; footer_c:"#FFFFFF"; footer_l_c:""; footer_bg_c:"#3B2C16"','Seville':'body_bg_c:"#B51A0D"; body_bg_g:"dark"; body_txt_f:"ss3"; body_txt_s:"1.1em"; body_txt_c:"#383839"; body_line_height:"1.5em"; top_image:"default"; blog_title_hide:"0"; blog_title_f:"s2"; blog_title_s:"3em"; blog_title_c:"#FFFFFF"; blog_title_a:""; blog_title_p:""; body_link_c:"#F18A32"; body_link_f_c:"#F1B232"; body_link_v_c:"#F18A32"; sidebar_position:"left"; sidebar_text_f:""; sidebar_text_s:""; sidebar_text_c:""; sidebar_title_f:"ss3"; sidebar_title_s:"1.4em"; sidebar_title_c:"#97471C"; sidebar_title2_f:"ss3"; sidebar_title2_s:"1.2em"; sidebar_title2_c:"#737300"; sidebar_line_c:"#E6E6CD"; sidebar_link_c:"#6E6E72"; sidebar_link_f_c:"#F18A32"; sidebar_link_v_c:"#6E6E72"; date_title_f:""; date_title_s:""; date_title_c:"#97471C"; post_title_f:"s2"; post_title_s:"1.8em"; post_title_c:"#F18A32"; post_comment_bg_c:"#E4E4E2"; post_comment_c:""; prelude_c:"#381A1A"; footer_f:""; footer_s:""; footer_c:"#FFFFFF"; footer_l_c:""; footer_bg_c:"#381A1A"','Typo':'body_bg_c:"#FFFFFF"; body_bg_g:"solid"; body_txt_f:"ss1"; body_txt_s:"1.2em"; body_txt_c:"#000000"; body_line_height:"1.4em"; top_image:"typo"; blog_title_hide:"0"; blog_title_f:"s2"; blog_title_s:"3.5em"; blog_title_c:"#B11508"; blog_title_a:"left"; blog_title_p:"140:50"; body_link_c:"#B11508"; body_link_f_c:"#000000"; body_link_v_c:"#4D4D4D"; sidebar_position:""; sidebar_text_f:""; sidebar_text_s:""; sidebar_text_c:"#000000"; sidebar_title_f:"s2"; sidebar_title_s:""; sidebar_title_c:"#B11508"; sidebar_title2_f:"s2"; sidebar_title2_s:""; sidebar_title2_c:"#000000"; sidebar_line_c:"#000000"; sidebar_link_c:"#000000"; sidebar_link_f_c:"#B11508"; sidebar_link_v_c:"#000000"; date_title_f:"s2"; date_title_s:"1em"; date_title_c:"#000000"; post_title_f:"s2"; post_title_s:"1.6em"; post_title_c:"#B11508"; post_comment_bg_c:"#FFFFFF"; post_comment_c:"#000000"; prelude_c:"#FFFFFF"; footer_f:""; footer_s:"1em"; footer_c:"#000000"; footer_l_c:"#B11508"; footer_bg_c:"#FFFFFF"'}; \ No newline at end of file diff --git a/plugins/blowupConfig/help.html b/plugins/blowupConfig/help.html new file mode 100644 index 0000000..8442326 --- /dev/null +++ b/plugins/blowupConfig/help.html @@ -0,0 +1,55 @@ + + + + Blowup theme configuration + + + +

    Modifying Blowup theme configuration allows you to customize your theme very easily. To do so, simply fill in the configuration fields or choose a predefined style.

    + +

    Colors

    + +

    When you have to enter a color value, you should use the hexadecimal format. For example: "#FF0000" will give you red. You may also use the color picker located next to every color field.

    +

    If you lack inspiration, try and visit the following pages:

    +
    + +

    Measurement units

    + +

    When you have to indicate a size, it must be followed by a measurement unit. For example: "1em". If you do not include the unit, pixels will be used as default measurement unit.

    +

    The following measurement units are available:

    +
      +
    • px
    • +
    • em
    • +
    • ex
    • +
    • pt
    • +
    • %
    • +
    + +

    Header images

    + +

    You can choose a header image among the list to use in place of the default one.

    + +

    When you choose "Custom..." in the image list, you will be able to upload your own image. The image file must be in JPG or PNG format and must be precisely 800px wide. + +

    If you upload a JPG image, a border will be added to the image, which is not the case with PNG images (the transparency of which will also be kept).

    + +

    Predefined styles

    + +

    You can choose a predefined style in the "Predefinite styles" drop-down list. +Once you have chosen the style, you have to submit the form to apply the modifications.

    + +

    You may then modify the predefined style according to your taste and needs.

    + +

    Configuration import / export

    + +

    At the end of Blowup options, you can display an area names "Configuration import/export". This text area contains the configuration you are currently using. You can copy it to share it with others.

    + +

    To apply (import) a configuration, you simply need to replace the content of the text area with the configuration you want to use. Don't forget to click on "apply code".

    + + + diff --git a/plugins/blowupConfig/index.php b/plugins/blowupConfig/index.php new file mode 100644 index 0000000..0db37f6 --- /dev/null +++ b/plugins/blowupConfig/index.php @@ -0,0 +1,449 @@ + null, + 'body_bg_g' => 'light', + + 'body_txt_f' => null, + 'body_txt_s' => null, + 'body_txt_c' => null, + 'body_line_height' => null, + + 'top_image' => 'default', + 'top_height' => null, + 'uploaded' => null, + + 'blog_title_hide' => null, + 'blog_title_f' => null, + 'blog_title_s' => null, + 'blog_title_c' => null, + 'blog_title_a' => null, + 'blog_title_p' => null, + + 'body_link_c' => null, + 'body_link_f_c' => null, + 'body_link_v_c' => null, + + 'sidebar_position' => null, + 'sidebar_text_f' => null, + 'sidebar_text_s' => null, + 'sidebar_text_c' => null, + 'sidebar_title_f' => null, + 'sidebar_title_s' => null, + 'sidebar_title_c' => null, + 'sidebar_title2_f' => null, + 'sidebar_title2_s' => null, + 'sidebar_title2_c' => null, + 'sidebar_line_c' => null, + 'sidebar_link_c' => null, + 'sidebar_link_f_c' => null, + 'sidebar_link_v_c' => null, + + 'date_title_f' => null, + 'date_title_s' => null, + 'date_title_c' => null, + + 'post_title_f' => null, + 'post_title_s' => null, + 'post_title_c' => null, + 'post_comment_bg_c' => null, + 'post_comment_c' => null, + 'post_commentmy_bg_c' => null, + 'post_commentmy_c' => null, + + 'prelude_c' => null, + 'footer_f' => null, + 'footer_s' => null, + 'footer_c' => null, + 'footer_l_c' => null, + 'footer_bg_c' => null, +); + +$blowup_user = $core->blog->settings->blowup_style; + +if ($blowup_user === null) { + $core->blog->settings->setNamespace('themes'); + $core->blog->settings->put('blowup_style','','string','Blow Up custom style',true); +} + +$blowup_user = @unserialize($blowup_user); +if (!is_array($blowup_user)) { + $blowup_user = array(); +} + +$blowup_user = array_merge($blowup_base,$blowup_user); + +$gradient_types = array( + __('Light linear gradient') => 'light', + __('Medium linear gradient') => 'medium', + __('Dark linear gradient') => 'dark', + __('Solid color') => 'solid' +); + +$top_images = array(__('Custom...') => 'custom'); +$top_images = array_merge($top_images,array_flip(blowupConfig::$top_images)); + + +if (!empty($_POST)) +{ + try + { + $blowup_user['body_txt_f'] = $_POST['body_txt_f']; + $blowup_user['body_txt_s'] = blowupConfig::adjustFontSize($_POST['body_txt_s']); + $blowup_user['body_txt_c'] = blowupConfig::adjustColor($_POST['body_txt_c']); + $blowup_user['body_line_height'] = blowupConfig::adjustFontSize($_POST['body_line_height']); + + $blowup_user['blog_title_hide'] = (integer) !empty($_POST['blog_title_hide']); + $update_blog_title = !$blowup_user['blog_title_hide'] && ( + !empty($_POST['blog_title_f']) || !empty($_POST['blog_title_s']) || + !empty($_POST['blog_title_c']) || !empty($_POST['blog_title_a']) || + !empty($_POST['blog_title_p']) + ); + + if ($update_blog_title) + { + $blowup_user['blog_title_f'] = $_POST['blog_title_f']; + $blowup_user['blog_title_s'] = blowupConfig::adjustFontSize($_POST['blog_title_s']); + $blowup_user['blog_title_c'] = blowupConfig::adjustColor($_POST['blog_title_c']); + $blowup_user['blog_title_a'] = preg_match('/^(left|center|right)$/',$_POST['blog_title_a']) ? $_POST['blog_title_a'] : null; + $blowup_user['blog_title_p'] = blowupConfig::adjustPosition($_POST['blog_title_p']); + } + + $blowup_user['body_link_c'] = blowupConfig::adjustColor($_POST['body_link_c']); + $blowup_user['body_link_f_c'] = blowupConfig::adjustColor($_POST['body_link_f_c']); + $blowup_user['body_link_v_c'] = blowupConfig::adjustColor($_POST['body_link_v_c']); + + $blowup_user['sidebar_text_f'] = $_POST['sidebar_text_f']; + $blowup_user['sidebar_text_s'] = blowupConfig::adjustFontSize($_POST['sidebar_text_s']); + $blowup_user['sidebar_text_c'] = blowupConfig::adjustColor($_POST['sidebar_text_c']); + $blowup_user['sidebar_title_f'] = $_POST['sidebar_title_f']; + $blowup_user['sidebar_title_s'] = blowupConfig::adjustFontSize($_POST['sidebar_title_s']); + $blowup_user['sidebar_title_c'] = blowupConfig::adjustColor($_POST['sidebar_title_c']); + $blowup_user['sidebar_title2_f'] = $_POST['sidebar_title2_f']; + $blowup_user['sidebar_title2_s'] = blowupConfig::adjustFontSize($_POST['sidebar_title2_s']); + $blowup_user['sidebar_title2_c'] = blowupConfig::adjustColor($_POST['sidebar_title2_c']); + $blowup_user['sidebar_line_c'] = blowupConfig::adjustColor($_POST['sidebar_line_c']); + $blowup_user['sidebar_link_c'] = blowupConfig::adjustColor($_POST['sidebar_link_c']); + $blowup_user['sidebar_link_f_c'] = blowupConfig::adjustColor($_POST['sidebar_link_f_c']); + $blowup_user['sidebar_link_v_c'] = blowupConfig::adjustColor($_POST['sidebar_link_v_c']); + + $blowup_user['sidebar_position'] = ($_POST['sidebar_position'] == 'left') ? 'left' : null; + + $blowup_user['date_title_f'] = $_POST['date_title_f']; + $blowup_user['date_title_s'] = blowupConfig::adjustFontSize($_POST['date_title_s']); + $blowup_user['date_title_c'] = blowupConfig::adjustColor($_POST['date_title_c']); + + $blowup_user['post_title_f'] = $_POST['post_title_f']; + $blowup_user['post_title_s'] = blowupConfig::adjustFontSize($_POST['post_title_s']); + $blowup_user['post_title_c'] = blowupConfig::adjustColor($_POST['post_title_c']); + $blowup_user['post_comment_c'] = blowupConfig::adjustColor($_POST['post_comment_c']); + $blowup_user['post_commentmy_c'] = blowupConfig::adjustColor($_POST['post_commentmy_c']); + + + $blowup_user['footer_f'] = $_POST['footer_f']; + $blowup_user['footer_s'] = blowupConfig::adjustFontSize($_POST['footer_s']); + $blowup_user['footer_c'] = blowupConfig::adjustColor($_POST['footer_c']); + $blowup_user['footer_l_c'] = blowupConfig::adjustColor($_POST['footer_l_c']); + $blowup_user['footer_bg_c'] = blowupConfig::adjustColor($_POST['footer_bg_c']); + + if ($can_write_images) + { + $uploaded = null; + if ($blowup_user['uploaded'] && is_file(blowupConfig::imagesPath().'/'.$blowup_user['uploaded'])) { + $uploaded = blowupConfig::imagesPath().'/'.$blowup_user['uploaded']; + } + + if (!empty($_FILES['upfile']) && !empty($_FILES['upfile']['name'])) { + files::uploadStatus($_FILES['upfile']); + $uploaded = blowupConfig::uploadImage($_FILES['upfile']); + $blowup_user['uploaded'] = basename($uploaded); + } + + $blowup_user['top_image'] = in_array($_POST['top_image'],$top_images) ? $_POST['top_image'] : 'default'; + + $blowup_user['body_bg_c'] = blowupConfig::adjustColor($_POST['body_bg_c']); + $blowup_user['body_bg_g'] = in_array($_POST['body_bg_g'],$gradient_types) ? $_POST['body_bg_g'] : ''; + $blowup_user['post_comment_bg_c'] = blowupConfig::adjustColor($_POST['post_comment_bg_c']); + $blowup_user['post_commentmy_bg_c'] = blowupConfig::adjustColor($_POST['post_commentmy_bg_c']); + $blowup_user['prelude_c'] = blowupConfig::adjustColor($_POST['prelude_c']); + blowupConfig::createImages($blowup_user,$uploaded); + } + + $core->blog->settings->setNamespace('themes'); + $core->blog->settings->put('blowup_style',serialize($blowup_user)); + $core->blog->triggerBlog(); + + http::redirect($p_url.'&upd=1'); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} +?> + + + <?php echo __('Blowup configuration'); ?> + + + + + + +'.html::escapeHTML($core->blog->name). +' › '.__('Blog aspect').' › '.__('Blowup configuration').''. +'

    '.__('back').'

    '; + + +if (!$can_write_images) { + echo '

    '.__('As images cannot be created, you won\'t be able to change some background properties.').'

    '; +} + +if (!empty($_GET['upd'])) { + echo '

    '.__('Theme configuration has been successfully updated.').'

    '; +} + +echo '
    '; + +echo '
    '.__('General').''; + +if ($can_write_images) { + echo + '

    '. + + '

    '; +} + +echo +'

    '. + +'

    '. + +'

    '. + +'

    '. +'
    '. + +'
    '.__('Links').''. +'

    '. + +'

    '. + +'

    '. +'
    '. + +'
    '.__('Page top').''; + +if ($can_write_images) { + echo + '

    '; +} + +echo +'

    '. + +'

    '. + +'

    '. + +'

    '. + +'

    '. + +'

    '. +'
    '; + +if ($can_write_images) { + if ($blowup_user['top_image'] == 'custom' && $blowup_user['uploaded']) { + $preview_image = http::concatURL($core->blog->url,blowupConfig::imagesURL().'/page-t.png'); + } else { + $preview_image = 'index.php?pf=blowupConfig/alpha-img/page-t/'.$blowup_user['top_image'].'.png'; + } + + echo + '
    '.__('Top image').''. + '

    '. + '

    '.__('Choose "Custom..." to upload your own image.').'

    '. + + '

    '. + + '

    '.__('Preview').'

    '. + '
    '. + ''. + '
    '. + '
    '; +} + +echo +'
    '.__('Sidebar').''. +'

    '. + +'

    '. + +'

    '. + +'

    '. + +'

    '. + +'

    '. + +'

    '. + +'

    '. + +'

    '. + +'

    '. + +'

    '. + +'

    '. + +'

    '. + +'

    '. +'
    '. + +'
    '.__('Entries').''. +'

    '. + +'

    '. + +'

    '. + +'

    '. + +'

    '. + +'

    '; + +if ($can_write_images) { + echo + '

    '; +} + +echo +'

    '; + +if ($can_write_images) { + echo + '

    '; +} + +echo +'

    '. +'
    '. + +'
    '.__('Footer').''. +'

    '. + +'

    '. + +'

    '. + +'

    '. + +'

    '. +'
    '; + +// Import / Export configuration +$tmp_array = array(); +$tmp_exclude = array('uploaded','top_height'); +if ($blowup_user['top_image'] == 'custom') { + $tmp_exclude[] = 'top_image'; +} +foreach ($blowup_user as $k => $v) { + if (!in_array($k,$tmp_exclude)) { + $tmp_array[] = $k.':'.'"'.$v.'"'; + } +} +echo +'

    '.__('Configuration import / export').'

    '. +'

    '.__('You can share your configuration using the following code. To apply a configuration, paste the code, click on "Apply code" and save.').'

    '. +'

    '.form::textarea('export_code',72,5,implode('; ',$tmp_array),'maximal').'

    '. +'
    '; + +echo +'

    '. +$core->formNonce().'

    '. +'
    '; + +dcPage::helpBlock('blowupConfig'); +?> + + \ No newline at end of file diff --git a/plugins/blowupConfig/lib/class.blowup.config.php b/plugins/blowupConfig/lib/class.blowup.config.php new file mode 100644 index 0000000..6aa78d2 --- /dev/null +++ b/plugins/blowupConfig/lib/class.blowup.config.php @@ -0,0 +1,418 @@ + array( + 'ss1' => 'Arial, Helvetica, sans-serif', + 'ss2' => 'Verdana,Geneva, Arial, Helvetica, sans-serif', + 'ss3' => '"Lucida Grande", "Lucida Sans Unicode", sans-serif', + 'ss4' => '"Trebuchet MS", Helvetica, sans-serif', + 'ss5' => 'Impact, Charcoal, sans-serif' + ), + + 'serif' => array( + 's1' => 'Times, "Times New Roman", serif', + 's2' => 'Georgia, serif', + 's3' => 'Baskerville, "Palatino Linotype", serif' + ), + + 'monospace' => array( + 'm1' => '"Andale Mono", "Courier New", monospace', + 'm2' => '"Courier New", Courier, mono, monospace' + ) + ); + + protected static $fonts_combo = array(); + protected static $fonts_list = array(); + + public static $top_images = array( + 'default' => 'Default', + 'blank' => 'Blank', + 'light-trails-1' => 'Light Trails 1', + 'light-trails-2' => 'Light Trails 2', + 'light-trails-3' => 'Light Trails 3', + 'light-trails-4' => 'Light Trails 4', + 'butterflies' => 'Butterflies', + 'flourish-1' => 'Flourished 1', + 'flourish-2' => 'Flourished 2', + 'animals' => 'Animals', + 'flamingo' => 'Flamingo', + 'rabbit' => 'Rabbit', + 'roadrunner-1' => 'Road Runner 1', + 'roadrunner-2' => 'Road Runner 2', + 'typo' => 'Typo', + ); + + public static function fontsList() + { + if (empty(self::$fonts_combo)) + { + self::$fonts_combo[__('default')] = ''; + foreach (self::$fonts as $family => $g) + { + $fonts = array(); + foreach ($g as $code => $font) { + $fonts[str_replace('"','',$font)] = $code; + } + self::$fonts_combo[$family] = $fonts; + } + } + + return self::$fonts_combo; + } + + public static function fontDef($c) + { + if (empty(self::$fonts_list)) + { + foreach (self::$fonts as $family => $g) + { + foreach ($g as $code => $font) { + self::$fonts_list[$code] = $font; + } + } + } + + return isset(self::$fonts_list[$c]) ? self::$fonts_list[$c] : null; + } + + public static function adjustFontSize($s) + { + if (preg_match('/^([0-9.]+)\s*(%|pt|px|em|ex)?$/',$s,$m)) { + if (empty($m[2])) { + $m[2] = 'px'; + } + return $m[1].$m[2]; + } + + return null; + } + + public static function adjustPosition($p) + { + if (!preg_match('/^[0-9]+(:[0-9]+)?$/',$p)) { + return null; + } + + $p = explode(':',$p); + + return $p[0].(count($p) == 1 ? ':0' : ':'.$p[1]); + } + + public static function adjustColor($c) + { + if ($c === '') { + return ''; + } + + $c = strtoupper($c); + + if (preg_match('/^[A-F0-9]{3,6}$/',$c)) { + $c = '#'.$c; + } + + if (preg_match('/^#[A-F0-9]{6}$/',$c)) { + return $c; + } + + if (preg_match('/^#[A-F0-9]{3,}$/',$c)) { + return '#'.substr($c,1,1).substr($c,1,1).substr($c,2,1).substr($c,2,1).substr($c,3,1).substr($c,3,1); + } + + return ''; + } + + public static function imagesPath() + { + global $core; + return path::real($core->blog->public_path).'/blowup-images'; + } + + public static function imagesURL() + { + global $core; + return $core->blog->settings->public_url.'/blowup-images'; + } + + public static function canWriteImages($create=false) + { + global $core; + + $public = path::real($core->blog->public_path); + $imgs = self::imagesPath(); + + if (!function_exists('imagecreatetruecolor') || !function_exists('imagepng') || !function_exists('imagecreatefrompng')) { + return false; + } + + if (!is_dir($public)) { + return false; + } + + if (!is_dir($imgs)) { + if (!is_writable($public)) { + return false; + } + if ($create) { + files::makeDir($imgs); + } + return true; + } + + if (!is_writable($imgs)) { + return false; + } + + return true; + } + + public static function uploadImage($f) + { + if (!self::canWriteImages(true)) { + throw new Exception(__('Unable to create images.')); + } + + $name = $f['name']; + $type = files::getMimeType($name); + + if ($type != 'image/jpeg' && $type != 'image/png') { + throw new Exception(__('Invalid file type.')); + } + + $dest = self::imagesPath().'/uploaded'.($type == 'image/png' ? '.png' : '.jpg'); + + if (@move_uploaded_file($f['tmp_name'],$dest) === false) { + throw new Exception(__('An error occurred while writing the file.')); + } + + $s = getimagesize($dest); + if ($s[0] != 800) { + throw new Exception('Uploaded image is not 800 pixels wide.'); + } + + return $dest; + } + + public static function createImages(&$config,$uploaded) + { + $body_color = $config['body_bg_c']; + $prelude_color = $config['prelude_c']; + $gradient = $config['body_bg_g']; + $comment_color = $config['post_comment_bg_c']; + $comment_color_my = $config['post_commentmy_bg_c']; + $top_image = $config['top_image']; + + $config['top_height'] = null; + + if ($top_image != 'custom' && !isset(self::$top_images[$top_image])) { + $top_image = 'default'; + } + if ($uploaded && !is_file($uploaded)) { + $uploaded = null; + } + + if (!self::canWriteImages(true)) { + throw new Exception(__('Unable to create images.')); + } + + $body_fill = array( + 'light' => dirname(__FILE__).'/../alpha-img/gradient-l.png', + 'medium' => dirname(__FILE__).'/../alpha-img/gradient-m.png', + 'dark' => dirname(__FILE__).'/../alpha-img/gradient-d.png' + ); + + $body_g = isset($body_fill[$gradient]) ? $body_fill[$gradient] : false; + + if ($top_image == 'custom' && $uploaded) { + $page_t = $uploaded; + } else { + $page_t = dirname(__FILE__).'/../alpha-img/page-t/'.$top_image.'.png'; + } + + $body_bg = dirname(__FILE__).'/../alpha-img/body-bg.png'; + $page_t_mask = dirname(__FILE__).'/../alpha-img/page-t/image-mask.png'; + $page_b = dirname(__FILE__).'/../alpha-img/page-b.png'; + $comment_t = dirname(__FILE__).'/../alpha-img/comment-t.png'; + $comment_b = dirname(__FILE__).'/../alpha-img/comment-b.png'; + $default_bg = '#e0e0e0'; + $default_prelude = '#ededed'; + + self::dropImage(basename($body_bg)); + self::dropImage('page-t.png'); + self::dropImage(basename($page_b)); + self::dropImage(basename($comment_t)); + self::dropImage(basename($comment_b)); + + $body_color = self::adjustColor($body_color); + $prelude_color = self::adjustColor($prelude_color); + $comment_color = self::adjustColor($comment_color); + + if ($top_image || $body_color || $gradient != 'light' || $prelude_color || $uploaded) + { + if (!$body_color) { + $body_color = $default_bg; + } + $body_color = sscanf($body_color,'#%2X%2X%2X'); + + # Create body gradient with color + $d_body_bg = imagecreatetruecolor(50,180); + $fill = imagecolorallocate($d_body_bg,$body_color[0],$body_color[1],$body_color[2]); + imagefill($d_body_bg,0,0,$fill); + + # User choosed a gradient + if ($body_g) { + $s_body_bg = imagecreatefrompng($body_g); + imagealphablending($s_body_bg,true); + imagecopy($d_body_bg,$s_body_bg,0,0,0,0,50,180); + imagedestroy($s_body_bg); + } + + if (!$prelude_color) { + $prelude_color = $default_prelude; + } + $prelude_color = sscanf($prelude_color,'#%2X%2X%2X'); + + $s_prelude = imagecreatetruecolor(50,30); + $fill = imagecolorallocate($s_prelude,$prelude_color[0],$prelude_color[1],$prelude_color[2]); + imagefill($s_prelude,0,0,$fill); + imagecopy($d_body_bg,$s_prelude,0,0,0,0,50,30); + + imagepng($d_body_bg,self::imagesPath().'/'.basename($body_bg)); + } + + if ($top_image || $body_color || $gradient != 'light') + { + # Create top image from uploaded image + $size = getimagesize($page_t); + $size = $size[1]; + $type = files::getMimeType($page_t); + + $d_page_t = imagecreatetruecolor(800,$size); + + if ($type == 'image/png') { + $s_page_t = @imagecreatefrompng($page_t); + } else { + $s_page_t = @imagecreatefromjpeg($page_t); + } + + if (!$s_page_t) { + throw new exception(__('Unable to open image.')); + } + + $fill = imagecolorallocate($d_page_t,$body_color[0],$body_color[1],$body_color[2]); + imagefill($d_page_t,0,0,$fill); + + if ($type == 'image/png') + { + # PNG, we only add body gradient and image + imagealphablending($s_page_t,true); + imagecopyresized($d_page_t,$d_body_bg,0,0,0,50,800,130,50,130); + imagecopy($d_page_t,$s_page_t,0,0,0,0,800,$size); + } + else + { + # JPEG, we add image and a frame with rounded corners + imagecopy($d_page_t,$s_page_t,0,0,0,0,800,$size); + + imagecopy($d_page_t,$d_body_bg,0,0,0,50,8,4); + imagecopy($d_page_t,$d_body_bg,0,4,0,54,4,4); + imagecopy($d_page_t,$d_body_bg,792,0,0,50,8,4); + imagecopy($d_page_t,$d_body_bg,796,4,0,54,4,4); + + $mask = imagecreatefrompng($page_t_mask); + imagealphablending($mask,true); + imagecopy($d_page_t,$mask,0,0,0,0,800,11); + imagedestroy($mask); + + $fill = imagecolorallocate($d_page_t,255,255,255); + imagefilledrectangle($d_page_t,0,11,3,$size-1,$fill); + imagefilledrectangle($d_page_t,796,11,799,$size-1,$fill); + imagefilledrectangle($d_page_t,0,$size-9,799,$size-1,$fill); + } + + $config['top_height'] = ($size).'px'; + + imagepng($d_page_t,self::imagesPath().'/page-t.png'); + + imagedestroy($d_body_bg); + imagedestroy($d_page_t); + imagedestroy($s_page_t); + + # Create bottom image with color + $d_page_b = imagecreatetruecolor(800,8); + $fill = imagecolorallocate($d_page_b,$body_color[0],$body_color[1],$body_color[2]); + imagefill($d_page_b,0,0,$fill); + + $s_page_b = imagecreatefrompng($page_b); + imagealphablending($s_page_b,true); + imagecopy($d_page_b,$s_page_b,0,0,0,0,800,160); + + imagepng($d_page_b,self::imagesPath().'/'.basename($page_b)); + + imagedestroy($d_page_b); + imagedestroy($s_page_b); + } + + if ($comment_color) { + self::commentImages($comment_color,$comment_t,$comment_b,basename($comment_t),basename($comment_b)); + } + if ($comment_color_my) { + self::commentImages($comment_color_my,$comment_t,$comment_b,'commentmy-t.png','commentmy-b.png'); + } + } + + protected static function commentImages($comment_color,$comment_t,$comment_b,$dest_t,$dest_b) + { + $comment_color = sscanf($comment_color,'#%2X%2X%2X'); + + $d_comment_t = imagecreatetruecolor(500,25); + $fill = imagecolorallocate($d_comment_t,$comment_color[0],$comment_color[1],$comment_color[2]); + imagefill($d_comment_t,0,0,$fill); + + $s_comment_t = imagecreatefrompng($comment_t); + imagealphablending($s_comment_t,true); + imagecopy($d_comment_t,$s_comment_t,0,0,0,0,500,25); + + imagepng($d_comment_t,self::imagesPath().'/'.$dest_t); + imagedestroy($d_comment_t); + imagedestroy($s_comment_t); + + $d_comment_b = imagecreatetruecolor(500,7); + $fill = imagecolorallocate($d_comment_b,$comment_color[0],$comment_color[1],$comment_color[2]); + imagefill($d_comment_b,0,0,$fill); + + $s_comment_b = imagecreatefrompng($comment_b); + imagealphablending($s_comment_b,true); + imagecopy($d_comment_b,$s_comment_b,0,0,0,0,500,7); + + imagepng($d_comment_b,self::imagesPath().'/'.$dest_b); + imagedestroy($d_comment_b); + imagedestroy($s_comment_b); + } + + public static function dropImage($img) + { + $img = path::real(self::imagesPath().'/'.$img); + if (is_writable(dirname($img))) { + @unlink($img); + @unlink(dirname($img).'/.'.basename($img,'.png').'_sq.jpg'); + @unlink(dirname($img).'/.'.basename($img,'.png').'_m.jpg'); + @unlink(dirname($img).'/.'.basename($img,'.png').'_s.jpg'); + @unlink(dirname($img).'/.'.basename($img,'.png').'_sq.jpg'); + @unlink(dirname($img).'/.'.basename($img,'.png').'_t.jpg'); + } + } +} +?> \ No newline at end of file diff --git a/plugins/daInstaller/_admin.php b/plugins/daInstaller/_admin.php new file mode 100644 index 0000000..b63b72e --- /dev/null +++ b/plugins/daInstaller/_admin.php @@ -0,0 +1,58 @@ +auth->isSuperAdmin()) + { + $id = 'dainstaller'; + $title = __('DotAddict.org Installer'); + $link = 'plugin.php?p=daInstaller'; + $icon = 'index.php?pf=daInstaller/icon.png'; + $icon_big = 'index.php?pf=daInstaller/icon-big.png'; + $favs[$id] = new ArrayObject(array($id,$title,$link,$icon,$icon_big,null,null,null)); + } +} +function adminDashboardFavsIcon($core,$name,$icon) +{ + if ($name === 'dainstaller') { + $daInstaller = new daInstaller($core); + if ($daInstaller->check()) { + $upd_plugins = $daInstaller->getModules('plugins',true); + $upd_themes = $daInstaller->getModules('themes',true); + if ( + (is_array($upd_plugins) && count($upd_plugins)) || + (is_array($upd_themes) && count($upd_themes)) + ) { + $icon[0] .= '
    '.__('Updates are available'); + $icon[1] .= '&tab=update'; + $icon[2] = 'index.php?pf=daInstaller/icon-big-update.png'; + } + } + } +} + +$core->addBehavior('adminDashboardFavs','adminDashboardFavs'); +$core->addBehavior('adminDashboardFavsIcon','adminDashboardFavsIcon'); + +$_menu['System']->addItem( + __('DotAddict.org Installer'), + 'plugin.php?p=daInstaller', + 'index.php?pf=daInstaller/icon.png', + preg_match('/plugin.php\?p=daInstaller(&.*)?$/', + $_SERVER['REQUEST_URI']), + $core->auth->isSuperAdmin() +); + +?> \ No newline at end of file diff --git a/plugins/daInstaller/_define.php b/plugins/daInstaller/_define.php new file mode 100644 index 0000000..70ada7b --- /dev/null +++ b/plugins/daInstaller/_define.php @@ -0,0 +1,19 @@ +registerModule( + 'daInstaller', + 'Install and update your extensions live from DotAddict.org', + 'Tomtom / DotAddict.org', + '1.0.3', + null, + 10000 +); + +?> \ No newline at end of file diff --git a/plugins/daInstaller/_install.php b/plugins/daInstaller/_install.php new file mode 100644 index 0000000..ae6ea73 --- /dev/null +++ b/plugins/daInstaller/_install.php @@ -0,0 +1,50 @@ +plugins->moduleInfo('daInstaller','version'); +$i_version = $core->getVersion('daInstaller'); +if (version_compare($i_version,$m_version,'>=')) { + return; +} + +# Settings compatibility test +if (!version_compare(DC_VERSION,'2.2-x','<')) { + $core->blog->settings->addNamespace('dainstaller'); + $s = $core->blog->settings->dainstaller; +} +else { + $core->blog->settings->setNamespace('dainstaller'); + $s = $core->blog->settings; +} + +# Création du setting +$s->put( + 'dainstaller_plugins_xml', + 'http://update.dotaddict.org/dc2/plugins.xml', + 'string','Plugins XML feed location',true,true +); +$s->put( + 'dainstaller_themes_xml', + 'http://update.dotaddict.org/dc2/themes.xml', + 'string','Themes XML feed location',true,true +); +$s->put( + 'dainstaller_allow_multi_install', + false, + 'boolean','Allow the multi-installation',true,true +); + +$daInstaller = new daInstaller($core); +$daInstaller->check(true); +unset($daInstaller); + +$core->setVersion('daInstaller',$m_version); +return true; + +?> \ No newline at end of file diff --git a/plugins/daInstaller/_prepend.php b/plugins/daInstaller/_prepend.php new file mode 100644 index 0000000..31048e2 --- /dev/null +++ b/plugins/daInstaller/_prepend.php @@ -0,0 +1,15 @@ + \ No newline at end of file diff --git a/plugins/daInstaller/icon-big-update.png b/plugins/daInstaller/icon-big-update.png new file mode 100644 index 0000000000000000000000000000000000000000..463909c5ab3b6db1c69ccca719b24325cd99be01 GIT binary patch literal 5190 zcmV-M6uIk(P)(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRa4%t=H+RCwC#n|X{R*5%CWGh^*?W>dNfQw)xA1^pi3pGb7@C-}iTY-%H_~;|KYW{D2?-4!{pO0A9Bb z*5}XB*qEoexj@{i2y68_oYn8vQR9t(0QwFd&RM)vmWku{B9ww2aYssz#^w_1*Iq_Q zHQ;cZ6w<4CLHJ@{o6R_FvcJUj?V&2jM0_Q);ZR%fBU1(+4Ez^A9%HI0GgW%?|0TB zl#fam5z52HEo|JvS$*&7ICX~Pj%(ePXWK%Hvnm z`B`3k@l`(Xi$6iAb;2njutsA{jB|F-5P*r=h_Hd5DWOt%Ow`0#O}nvi-#{*4w4QJX zq?aaYRzNoiQXWDGtaY>_O|9Byb)&)RMuYW@2Gv?fvmN7mifr0rxSZqU>?ot<4C7bZG;wPS zY@8Vg0BfB^NH8(dwwPb3Grw46b)(68rAez5Bb6XXd5n~^OivUzb4QlpQiehZxzByw+fPqQLk_j^jtlj1;pJ3u%JDLrH;iV64TM?L2OGVw-gi8ylQ; z2zg^*VLM`Ka)er~L9O1z_dIahAb=Bm4~M|SQ6~h8u2}XggggmPeC}o9*z%#Ddw^6* zVJ%o|G1h?tYb;tjJeAZ5N8XyW^d#pNxoE>t;j zWSC3y8?;)Q`|h6R!j*M=Pm)f1Xl;?o+hKsUj!Y&XKa^u-d4uVxF|4*7|G!nm*xzBT zMf51zdNxB_wUA8U5u_BcHVG{|<|)C`&s^Y3U%NuB-sYv(mKiN)`Sy30NqGuwEcHgr z<2x4?xpHL@&r`eTEwI)yIXTMw^_5)! zxuk#CchB21db(400E{J{N#T2nO0|s?ou;N^);fwqDbj&rcBVu+@Ob;1kD;WX(TI>z z@XGmBCP(wU<%bS)|JkEVPmkgNDFvyNkCYODU}|!d&CMEdtao~c8zAgA*SY^-)(wCj zy@114l1$oTWxc_n@jSch60I%c!+C@dq&&slr^g9=kGa`l!q89{3h+Eh80sV`$$)e^ zVE)=N!@~vs;nQE>+WZpl`44YnYHExyjA=Alq%#?;P40hC7I4;}b%+qM??PE9uWMD= zGYvW%r9ztZN@M5T4FC*>CWbgXIYc|uOpOiUoFj@2L7=#JWrM}l8iytdEU(qMwzS3l zjRNayn@Zp0RHibXSnB{(~OK1Szg}Y`0*pj?C%3$yFfbg z=m!~|y`SafrA~X^s|$COM@Pt&USs*vHwJY9&{&2`8EUVD=-AR~YrgX0H46Cvtu2#d zc@|b`tW}yg2hDcO)M%coi&gTu6dTnxN2UrinlaW|e)z#R@Wn5Fop-$bel{vwT>sK4 zGc)6ON-;iOW`2GdAw-e|_Z31~N0g^dGI{a=R#sMd@rAD&#gs-7{+U zQrI~#hC(idHkL5fymo1o^RI6(cYK6g+UN7nUdB0?9L*u5K!$?F)jIEf_yo^=>pHX3 zMIL!@md`(XnN};}(Bv?`{-O8LYPEUv(Kqw@>kG^tox<}KLqj<(UAn%bAJ~0$fYpXn zFa$s*ljh{fxt{smIm^`aA&SK!uRQZy*EHDM1*{`Tc?7;#YAnZz!)4NeqS1^vb8?g*ljGQ#Q>4;qtg#qlICb(c##oe8 zT)KFj=|f|kh|K{mkofcVvxQ-Zl(I(wWKc?>lw*cSsj{Y-&2BZ?yKyZ-@Zj~&~&-hcpXx3ZS; zksL34YY}T5b4N!&KpdMyHSRQ;Qi`N|wt_H$HdwdL?+fiHh!o)=zP3qg<28Ms4r?r)C;73r9OtQLE^z63g;GAC(T=G%BaC$f zzM?pkraTmIVx~-KC?J;$@Ukg#msc2l?jnU4ypaNCtVpZb#x&d5b|Q!hPoXjavJ{X~ zlHlqRnQzuun;N3>&>V3ggKOW&3gz-J55M(CP*QdC0F2R$jgRk&X9EIYaY-ub(7luo zc;AoS$)#(XRO=zr<9W)3G())*>6DiQIp;9eVWhwrNB*DAF>z&s-0UQ=G1RZGqBk2j zleo_wCAc$lGL^y~E0H-q#o^5c*~gz}<*jp6XG_?Q4`eeLW{=MH&H~P2v?hvmBIDgo zFMxGB42xoe6oS*U!^qABx7*BEn%<#1gpvp;!S`_1 zVwz1b2IZ$v*$fu2#t_f1(p*?0dt{Q4*=fAbzlJ_LfjyPznyq$=tJkh{vOt$Y$iap0 zewVxNy$`RWG!3Q*xgF{5MqqIc6Pmr{*8cL#I)W=`;p`@D$F$*5w6S7$X_+Vf@d~I(3At$DgM8lON>Ji4(l< z{qOIz(+5A6F_u$vr}4amZQDiEVBKKfl9a>w9>L{RO6OORGh?h@xQ06R~pXgAtyE>#F}l1m@`Ez-aD2b_E99BMlaA8c zQnYm>%8#*o?w+J7(9WR`8kCY$S1JsZvb3N23?u*Z3}MROQ!MRKgN;psU&kkILlNq% z>G!b=?wliaehHOMQQNFzmF&8tVWmWeAuf&~2yRfeQAb#dLEOxMj=JGuL*yjk)r-9R z>3_hy@eDGG4qOz`v1V@WG?SB4Nm*@fvlPDdf~0^(h+1zD3rQHoJ3ak@*A;@O-A1=t zsC<6sd|0iboJ9k=$GsZ$CZ2!?iv>m>`$=r8b>Iq;wU(*r>06HFdv*aQBxecMChief`Lm*tzE`7}?y{4!FAo7`Z#UH+}# z`6v&+<*hf#dHt>p-Z~9-uvc3xOl;9kCj)T3zAwgFC0o9kedh8gZV`DwX(nAv4QwjG5z*=H!a8C3gRXeoN z=w@?|zv@~YUr8+P)&N+$Q|mixlZ>+OnUcj>w*#=fop#vugMf7yZ?H{Mu{FfI05EY( zRNo>k1iGI^apw@8N48kRWwVF_7!YfX=lOfbGN>Yys3^A>m=TzapHRQAx=9dgOYPd# z8v(FVp}n?7L3zY|T*DWVa$;^luq|Yf52$Nu}9v? zzWXdCy&c2Cr zfBgw^ySK}A%>V|!T;hSBc|YajCvUNlDp9X5h3(rDM67fDEkJ4uM@G=EEN!B^K!tNZTJUBH*W$9WX ztn^c@D=*plJK!FnsBZ=U#0GW8B+>jjw%SB^2g_AXDYjNuXsj%g8=u%YzjFRNU@b<_ zwGwcVCUy2OqMV0VBUJyp{hd3QS6#2*`RVi4?A;dA)3gO&k-F~~##3l}qp{g-*7vC{ zFY)Am`wf;}I!Cjz!Ph_ex4iIYe@Z5sB|hLc8i*r}m?`7kIgO2V|IcNU&Nh|KT^oo2 z>0IIe*EUw)E&cwttGY-d$A(BhaGb`o7n9iF-Hfr!WckkLKF8%}ze+GvU~6d+&+|}z z3bTLq9k^KIjTK1We|%e2q2GPPE)iyG!_%|>+?4^I5I5QJvk(7GkjX9RI8N3F`ZO16 zyu-s}-h2X^^3ajNIBqhT%@Rd1wbfNrkj8mF+POX7(Z-=8jhZTxedr{lJZx+_WqNr;RZ;7A!kL$-(B5I=!v&50%M3atCU% zNE{ntZP5-4H_R!8^L>mEJLfcsDilWsqXg+U&X9ZP1o$eUzPr^k*q!IpQAnmxe(~@f z_x^USIMO&+K6h>hjSjD5#{?k%;yq|YcoJtU@n(~7rAE9_ zM>ivEtVOaVS2-1UsG&5$*bu4FJYGJXbedhHEFo@I0|j6Z4JXuVwOD=j_y77cPsQ43 zAO<3!4TK${x!nMW&hG;t*Rf3Jz1K0diyhkx*>CK74Fmt{q37zu?j6+b0JFQy>`Edb z&;lAA3p)TfZ}(hveiU^EXgjZW4_=T z+TOmZKJI*>y=%at$ISQ3gzpuAerCQK6Wl&P_Wa++J7`sD7fJ_FnjUng%b>;giT>R{ z>gTh8OX0pR(xn^yw>ZA<|MV9B{_pW0@Z((_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRa2en~_@RCwC#n{8}lS9!;O=bU@*%y`CQkKgU}?t0(6A?a?CB`-h{l29UA3Pmjq zw51gwAq1`ZtyC1Lq97HuAKHGP{lXWdR+XBnRUy0xgi1+5OOk~RA&Ik1HkJ{a^ns?E z(G39Bm{{>GY5m_=YtdRGyN=HSbcl|MzoCQrqp9q`mxPet-j@XkA;Fr#a&hjT!`kM% zkrDwQ9E4CHL>C)lK)49y#Jk!C03jWObU>z{YYWg=qrn&z)XVn;_0l&p`O!ZXQvOYB zv|RvTjS=hD&VSjj6yGhCi$Ec~EK;RF$ZiY(YYj4$!AbSr5CEwZDwRiieaP-z0Bbci zs$#<$SVVRG+F$#F#S31#@A0kxSbF{JBc;{3--&nIL8ki=%1unzbmam9ixl8F3di%} z$SWXeUy&V6Ay|_~<<^cML#veg4DN z7=&_B={|&VFkuZ7*03hpdlyBlhY}K{1VRe15Cjp$@;V#Od(6+Tvaqm()`r_}pXSax zZ^8EijIoIYIQZ2fVP&;@3y>12JfxdJc{!}nSbvkSR=Q(j>Edq!f6*}jpu(n=hqf|#5LEqp7`up>Yj}3tk zJoeakICt)4KK9Y~;YU$yQ$k>Lgw`R}nr=e?I;bQ33T~z!<>k;p6>B2um9@LNaseGh zqZWa5(gf8aL{(CrgAf8^EcGCwv{7eyt-|tJh1InR8zrA=J;ZesJ!yx5LYCuGLktx% zj0_Jjede9GsT5#QQu6-yJ-`>g_!WNe#5o>*_%3Qyf7_I7S6;Tm42{+V!$>Dh zSla{>X1W5v7;6v`bci%H=9bFLEo`v7R%NwVrB(}(N|5p#1`9n*jOICYOAiD68S>dQ zt}78D_LL~nDAyqfLIQ0dG54Nqnh$*7A^zk0XL;zsw>DCsH8ydH{nsfLi(lQq@iJT9 zYP!n;)*_`K@GJb=w_adzrNYE$o{_;UM-LSk?CYT~pC*-ZP*PwmXk*ZNE03E-Y%|tk zLX9;RA-5It>jC3qgOo}YO64l9im&+(6C~nkwZFYqthsQW{TkJmD6{sek&mn+f zag))J!N%uX^2UZmhxN9+%V}36tQN~$x?1GpzjX#IRH{J}zJe&yEUi^>UB$xUCYR?o zICf}&i*sw#Y7uvxp5VglDy}0*ryZimAeGaw0AnnfOp07@mZiltCdP*`kxBgjMvSqu zVT?hvA#H7oq0N#{CgqUw6k()evrNQMf^R=@fgk>OmQuOS&(1G0ROsQwR~GRcMWhYo zO32u7j^cWql;<}gVq)S+<1sv#MM*(_K85Q@ESCSdu)yr>0*<4a%v)fLVQg%OxvNV} z0NJ>H*mckS32oh}H2~U>%XqksqPS5?bT%?o;1mj~vtgn{{!>Ca^Y=f{{Y;ynZq!j>d zY5|L@B$>3s(rSeRBRQIRNfa4I266}?@EpbIlOv>Dhv}&Sd|#9AP2o5a-;d&?BvYi* zDdw&$GBA+m-@o<)uFPHI{lE4gnvVb+3DDn|Pc1)Coa$2&= zwrS8}>CdNGEmj)uZ3Cb=Fxtz(v0mza#Q1P8)>?v4lS(OGn_XjJxx|6dJc}!3u3X#X z?n<83m35So_TE|2&HqpX=5IAi^-vpP@A46NQFaJ>tL5T_K-K5k-cv z;T-czC02@6tc7YlWPB*c<%JD$S&y}iI)}#dRH`Ay7~X#GtvvbUPk7hEce7U97#>W(=OkC`gN>@v7szN3ZySsST6IP`;PI<3s;$% z=;NV#r}+NUuT!f992gtm4?g`NYPC9#Jn}X!U7Ba=@HmdE=I7aojnM|JH7AZAL~DbR zii@vZW#Yha60zCC1!8~RTAT0tNGaP8AdONArBu?A+ea3#)}W+Aw#Q?+Sf$XH0YO4o zER$n-rY8Fl#5q5ma&cYBM%m}cfj+DSKZtM~iBdA=<;I|t#C27J5PkF8PjUIm0*^lW z2!1_??`sLBJA45d#B*^!4>M0PWHO;#_Zyq0pORd9BKs zTgNy!+DjN2PEHLrTBFlP3ed#vV(S5=1SzGk#vlaL>pt@ft1K?9aCLr}rKL5B#Z6q- z;gg^EAU&Bhk=DsPW=B6@i_`$D7mGam%rkNEw3i!LOArLyb@x3?9XZmNuS)>7N?F6m zV3xBlEMSaf`tTqK2tyrrjgvxCN)cDjM&Jh_rAo+psm|(pjn(xkRo@^p^9bQk=+7}c zT;SB{(~OM`acFWBfSMnn91mmFb)|r{rcu#NPEPXsAN^Qc7tq>p=>W4Nx{(glJb zq`$wPp`oFqjcNB|0T!bTjwAWi`;YRiCoXXDYLWh2ib_4CTn*61l5!P&y=e-)DUMAR z=aZ!nBEhyDAy8iw-vvp=>tG^z=z&!Y*5!Ymn>B?OenECjeH9SURwPtv2>n2Wa(?QK&H#%+0L%R=@AfJx5ug?NJi2rLGx!A1gWI{`o@%~y*RW_vwJ3@BI1ygW05 zauj<-0gELHBc`WMGB!3I1F82(g>Q}pB=x=SY|chMpvml;*E2FY#`}K#1M!(;n|Ap4 z#KaAC`9F*SG8WsxV@X0b0dRc`n0e_%KL5Et#r3>BdjebK@}K?r7r5{K2d-=9b$T{< z<22YI0D?FRpgTP76LGLK#$tA)!T9>FuH1!g?CPFvM2jaP` z5m+NTivf|q>RoGSx~`NKH5JXYP;Uh;F8Xj(|OPiM14krA@EWjrIuR9Ea zM#N{3*D*ocRP2~I0JdO)@!_m(?19-&Ic&Q|z$TPgVG>`r2$TV%1tiC6Hylc!wZzw| z5&6SNqLUP=lp>qW;y9}1GQudraonA{blVY%Z{D2^XshUT%Z&A`;D`u|KnjaXgo#u~ z^F`KSIJL&`@U~YpMGoC#I)4eE2YCS9j^> zmIk$z^txpp96L*|Q*9!Bg2*`NNOTlbwUvyfR+vaHZWmQOHKN`_08C6A;CDard#x=X z37X|niTQ;Elydgh5$e_jj1^>Lot&r>gx;P3zf(-LQRwYX2?|Sfeg?O=!sx_79(?HG zJ$Ju3kyI*``0!SU{kTB)JU|k$RO{nXX^g4tHGJc8Gls+>gv(E_7N~vouXyl-pWw`$ zcO(Ju2Bo#NT=eVvYls+YyNUn;i?)&`%d^pYgRX z{|UW?VdM?Y2De77yn*AUyFM8b-R40HNTCU}j8;nofV7rpH;yq=8c%k9t2w&AHH5y;$f4`W=5{u#wh!`@k}3lyoY_Sfq`JjNr-jCJ+p9f6&C-UmA-vmZvw4GE*MI zNtEBuJ-5CS1wNU4;oQMn&U`-GH(1%beQs?7jU-0NL|$>e?8NtC@ly-F-_GQG^n^de~y zidCJn&(|hc405sZ9n2(zuzRsTji^|m&X+>wRGEM&K^>l$uCMZLSbu6Oq1wD(I`>622>L969BB!G?_@g6eJ3o z@Gld{NBge>r|-;rM*m=Hs($XrNvD$|5hM%@>$nZxZ_D$RHHwSanpb4 iEq?Lq@i+PS-vIy!Vnl`V(ok3c0000(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ;o=HSORCwB?lg(}$Wf+B@_xr|n#&+tYZ5&%6X@yF=q2BPfV8y-??6?6Ius~wP znmgbY*l-2x5K@pp3Q~)zszUsz4Iw3V9JjSy&x~ijUlyr|#g-$T?Rg&^y+>k<{2wI% zm!%~y3^4@M)bq4FVte~4M6lMQ!ueH^cw>Bc_jqq`=d%Q0HaWdHI-6mQB}8b{ zgjPp$eRqq)qY+n|6=u0W>EvaCf*3CYD1a=loJ7xVzeAQ+j3*f{78O~x#2QCcIjnKm zsvLS2amb9)(>lzWkg*rQ(8LuSwadSvb59bFg77K>M zA*h7Qm*NV6^*HMQ0l)>Qaxe=`K;eoS)>_)_HvL|Y?QWM?%vK1j!x;x62vB*2DTRrfK)048yi6o2nmK^yWms~ z5kNu^H_Niq48!;!fP)0KXoY;CxW0D3p>%gujXIYWXGfz^uhnW@c>Q8b74UoCK$|6^ zsHg})#ZAB_5s0=mHlMz@Z>Oe2tH=`31dee?E|*dk6ezP*71Z3c4Ua~`OE?N6l|&*@ zRjW6YQ4*kZ9 z<+wgmTtqk;==R%>74Np~v*Qn%jxrfi0+HRa_Ib?lhd9ujHSHnD#$h_wW zD@>M^yi+$v1G8V9FC&r2Z%nV(!;q5el=1n3=B}-vXn}zv#&-+ib zyroH9IXLp=0t*ktbUGb6`JhUrY3S_i=`b3P^v}*Z2ce+7;PP7_FITu5>l8VQ0RV!D z|EVhY06c#%VJA@NJRZ-`*Eevry}fnF;jlf0ukj;V4}Z40{~1MT07}ri+TV6002ov JPDHLkV1jm!gnIx0 literal 0 HcmV?d00001 diff --git a/plugins/daInstaller/img/support.png b/plugins/daInstaller/img/support.png new file mode 100644 index 0000000000000000000000000000000000000000..2fb98bf57bfb7b8cb45b8d6a654c604e8d214189 GIT binary patch literal 902 zcmV;119|+3P)r* zg-R*PqZTod4OLTNrN)qAB!+}E3UOmJEc^iw-RQyvi3?poT#y)p0T#YC2pEKzpkk`L z5-pF~TBlN`52h_;#(U~>l5ghZe2<(v_g?a-5Ad;2oTd0qAy7mR`=?11$qlz+pdZt3 zm??@Wo=^nU|CxtK{-Gl4vqgtC3Y~>tpk!YXcnm0eOT=wEge3z^Z=P|?DalViXuBIj z)PK!Y{aMgCc-#BS-T5so4chi2`x%boFkmkpj~f>jHjLZ}ID2|}_+Ze@Figc% zYimg8=-3fsu>?-Q>-7cZkrCZ7hOxR_u4|&ja(Lq?42qQ?FdZjBXIda_#+nmuZgutG z49kYRUhnOpaQN0KS-v65^1VxvG&wOb5o~H|YOEd{EYC0uN&N7qqjm5Gmk`l@fzo{k z4p>vM7$m&jooqJylJ8z(zR)*4RT1HK;`odhunD zv=B=OLP9OeV6xi_-qqGNe4r+Vk_fD^ha759iyri1fJw9~q0q`ocsCx0(ibmuHk+-L z5Yq7H2VjjoNESXsf+_M_gY1wT*Rk1;(*4 zT_%$$TUuHQ#5|sliYs$R8@b%=%w1>7Js+8Z cuRjGC09Q<4qq^2i4FCWD07*qoM6N<$g2fb*-~a#s literal 0 HcmV?d00001 diff --git a/plugins/daInstaller/inc/class.da.installer.php b/plugins/daInstaller/inc/class.da.installer.php new file mode 100644 index 0000000..84a819b --- /dev/null +++ b/plugins/daInstaller/inc/class.da.installer.php @@ -0,0 +1,317 @@ +core = $core; + + # Settings compatibility test + $s = !version_compare(DC_VERSION,'2.2-x','<') ? $core->blog->settings->dainstaller : $core->blog->settings; + $this->themes_xml = $s->dainstaller_themes_xml; + $this->plugins_xml = $s->dainstaller_plugins_xml; + $this->modules = array( + 'plugins' => array( + 'new' => array(), + 'update' => array() + ), + 'themes' => array( + 'new' => array(), + 'update' => array() + ) + ); + } + + /** + * Check new/updated plugins availability + * Plugins already installed but marked as disabled will be ignored. + * Results of this method are stored as two subarrays 'new' and 'update' in $modules['plugins']. + * + * @param boolean $force Forces datas refresh if true (default to false) + * + * @return boolean Reports operatio status : + * - true if operation was successful, + * - false otherwise, you may check internal error trace. + * + */ + protected function checkPlugins($force = false) + { + if (!$this->plugins_xml) { + return false; + } + if (($parser = daModulesReader::quickParse($this->plugins_xml,DC_TPL_CACHE,$force)) === false) { + return false; + } + + $raw_datas = $parser->getModules(); + + uasort($raw_datas,array('self','sort')); + + # On se débarasse des plugins désactivés. + $skipped = array_keys($this->core->plugins->getDisabledModules()); + foreach ($skipped as $p_id) { + if (isset($raw_datas[$p_id])) { + unset($raw_datas[$p_id]); + } + } + + # On vérifie les mises à jour + $updates = array(); + $current = $this->core->plugins->getModules(); + foreach ($current as $p_id => $p_infos) { + if (isset($raw_datas[$p_id])) { + if (self::da_version_compare($raw_datas[$p_id]['version'],$p_infos['version'],'>')) { + $updates[$p_id] = $raw_datas[$p_id]; + $updates[$p_id]['root'] = $p_infos['root']; + $updates[$p_id]['root_writable'] = $p_infos['root_writable']; + $updates[$p_id]['current_version'] = $p_infos['version']; + } + unset($raw_datas[$p_id]); + } + } + + $this->modules['plugins'] = array( + 'new' => $raw_datas, + 'update' => $updates + ); + + return true; + } + + /** + * Check new/updated themes availability + * Results of this method are stored as two subarrays 'new' and 'update' in $modules['themes']. + * + * @param boolean $force Forces datas refresh if true (default to false) + * + * @return boolean Reports operatio status : + * - true if operation was successful, + * - false otherwise, you may check internal error trace. + * + */ + protected function checkThemes($force = false) + { + if (!$this->themes_xml) { + return false; + } + if (($parser = daModulesReader::quickParse($this->themes_xml,DC_TPL_CACHE,$force)) === false) { + return false; + } + + $raw_datas = $parser->getModules(); + + uasort($raw_datas,array('self','sort')); + + # On vérifie les mises à jour + $updates = array(); + $core_themes = new dcModules($this->core); + $core_themes->loadModules($this->core->blog->themes_path,null); + $current = $core_themes->getModules(); + foreach ($current as $p_id => $p_infos) { + if (isset($raw_datas[$p_id])) { + if (self::da_version_compare($raw_datas[$p_id]['version'],$p_infos['version'],'>')) { + $updates[$p_id] = $raw_datas[$p_id]; + $updates[$p_id]['root'] = $p_infos['root']; + $updates[$p_id]['root_writable'] = $p_infos['root_writable']; + $updates[$p_id]['current_version'] = $p_infos['version']; + } + unset($raw_datas[$p_id]); + } + } + + $this->modules['themes'] = array( + 'new' => $raw_datas, + 'update' => $updates + ); + + return true; + } + + /** + * Get informations about available new//updated themes/plugins. + * Probably the first method to invoke after instanciation. + * + * @param boolean $force Forces datas refresh if true (default to false) + * @param boolean $verbose Display exceptions when exists (default to false) + * + * @return boolean Returns if the check is completed or not + * + */ + public function check($force = false, $verbose = false) + { + $ret = true; + + try { + if (!$this->checkPlugins($force)) { + $ret = false; + } + if (!$this->checkThemes($force)) { + $ret = false; + } + } + catch (daModuleParserException $e) { + if ($verbose) { + $this->core->error->add(sprintf( + __('Oops, something went wrong with %s, we are working on it. %s'), + sprintf('%2$s','http://dotaddict.org',__('dotaddict.org website')), + sprintf('%2$s','http://dotclear.org/donate',__('Wanna help too?')) + )); + } + $ret = false; + } + catch (Exception $e) { + # Probablement à compléter. + $ret = false; + } + + return $ret; + } + + /** + * Retrieve a specific module list + * + * @param string $type The type of modules wanted ('plugins' or 'themes') + * @param boolean $update Flag to choose between new or updated modules (default to false - new modules list) + * + * @return mixed The matching modules entries as an array, if any. Or a boolean set to false. + * + */ + public function getModules($type, $update = false) + { + $type = ($type == 'themes') ? 'themes' : 'plugins'; + $what = ($update) ? 'update' : 'new'; + if (isset($this->modules[$type][$what])) { + return $this->modules[$type][$what]; + } + return false; + } + + /** + * Search a string in module id, label and description. + * Search is case-insensitive and can be apply to available themes or plugins + * + * @param string $search The search string + * @param string $type The type of targeted modules ('plugins' or 'themes') + * + * @return array An array of matching modules entries + * + */ + public function search($search,$type = 'plugins') + { + $type = ($type == 'themes') ? 'themes' : 'plugins'; + $result = array(); + + foreach ($this->modules[$type]['new'] as $module) + { + if ( preg_match('/'.$search.'/i',$module['id']) || + preg_match('/'.$search.'/i',$module['label']) || + preg_match('/'.$search.'/i',$module['desc'])) + { + $result[] = $module; + } + } + return $result; + } + + /** + * Helper method to fetch and install a ZIP package. + * + * @param string $url Source file URL + * @param string $dest Target file destination + * @param dcModules $coreModules Target modules stack + * + * @return integer Basic operation status code : + * - 1 : everything's all right, + * - 2 : tempfile couldn't be deleted. + * + */ + public function processPackage($url,$dest,dcModules $coreModules) + { + try { + $client = netHttp::initClient($url,$path); + $client->setUserAgent(self::getUserAgent()); + $client->useGzip(false); + $client->setPersistReferers(false); + $client->setOutput($dest); + $client->get($path); + } + catch (Exception $e) { + throw new Exception(__('An error occurred while downloading the file.')); + } + + unset($client); + $ret_code = dcModules::installPackage($dest,$coreModules); + + return $ret_code; + } + + /** + * Helper method to get user agent according to DC and daInstaller version + * + * @return string daInstaller user agent + * + */ + public static function getUserAgent() + { + $m_version = $GLOBALS['core']->plugins->moduleInfo('daInstaller','version'); + return sprintf('daInstaller/%s (Dotclear/%s)',$m_version,DC_VERSION); + } + + /** + * Helper method to compare correctly version. + * + * @param string $v1 Version of first module + * @param string $v2 Version of second module + * @param string $op Operator + * + * @return boolean True if test of version is correct according to operator + * + */ + private static function da_version_compare($v1,$v2,$op) + { + $v1 = preg_replace('!-r(\d+)$!','-p$1',$v1); + $v2 = preg_replace('!-r(\d+)$!','-p$1',$v2); + return version_compare($v1,$v2,$op); + } + + /** + * Helper method to sort module list. + * + * @param array $a First module + * @param array $b Second module + * + * @return integer + * + */ + private static function sort($a,$b) + { + $c = strtolower($a['id']); + $d = strtolower($b['id']); + if ($c == $d) { + return 0; + } + return ($c < $d) ? -1 : 1; + } +} + +?> \ No newline at end of file diff --git a/plugins/daInstaller/inc/class.da.modules.parser.php b/plugins/daInstaller/inc/class.da.modules.parser.php new file mode 100644 index 0000000..29c9e57 --- /dev/null +++ b/plugins/daInstaller/inc/class.da.modules.parser.php @@ -0,0 +1,81 @@ +xml = simplexml_load_string($data); + $this->items = array(); + + if ($this->xml === false) { + throw new daModuleParserException(__('Wrong data feed')); + } + + $this->_parse(); + + unset($data); + unset($this->xml); + } + + protected function _parse() + { + if (empty($this->xml->module)) { + return; + } + + foreach ($this->xml->module as $i) + { + $attrs = $i->attributes(); + + $item = array(); + + # DC/DA shared markers + $item['id'] = (string) $attrs['id']; + $item['file'] = (string) $i->file; + $item['label'] = (string) $i->name; + $item['version'] = (string) $i->version; + $item['author'] = (string) $i->author; + $item['desc'] = (string) $i->desc; + + # DA specific markers + $item['dc_min'] = (string) $i->children('http://dotaddict.org/da/')->dcmin; + $item['details'] = (string) $i->children('http://dotaddict.org/da/')->details; + /*$item['section'] = (string) $i->children('http://dotaddict.org/da/')->section;*/ + $item['support'] = (string) $i->children('http://dotaddict.org/da/')->support; + $item['sshot'] = (string) $i->children('http://dotaddict.org/da/')->sshot; + + # First filter right now + if (version_compare(DC_VERSION,$item['dc_min'],'>=')) { + $this->items[$item['id']] = $item; + } + } + } + + public function getModules() + { + return $this->items; + } +} + +?> \ No newline at end of file diff --git a/plugins/daInstaller/inc/class.da.modules.reader.php b/plugins/daInstaller/inc/class.da.modules.reader.php new file mode 100644 index 0000000..3a24dd1 --- /dev/null +++ b/plugins/daInstaller/inc/class.da.modules.reader.php @@ -0,0 +1,196 @@ +array
    HTTP Cache validators + protected $cache_dir = null; ///< string Cache temporary directory + protected $cache_file_prefix = 'daorg'; ///< string Cache file prefix + protected $cache_ttl = '-30 minutes'; ///< string Cache TTL + protected $force = false; + + public function __construct() + { + parent::__construct(''); + $this->setUserAgent(daInstaller::getUserAgent()); + } + + public function parse($url) + { + $this->validators = array(); + if ($this->cache_dir) + { + return $this->withCache($url); + } + else + { + if (!$this->getModulesXML($url)) { + return false; + } + + if ($this->getStatus() != '200') { + return false; + } + + return new daModulesParser($this->getContent()); + } + } + + public static function quickParse($url,$cache_dir = null,$force = false) + { + $parser = new self(); + if ($cache_dir) { + $parser->setCacheDir($cache_dir); + } + if ($force) { + $parser->setForce($force); + } + + return $parser->parse($url); + } + + public function setCacheDir($dir) + { + $this->cache_dir = null; + + if (!empty($dir) && is_dir($dir) && is_writeable($dir)) + { + $this->cache_dir = $dir; + return true; + } + + return false; + } + + public function setCacheTTL($str) + { + $str = trim($str); + if (!empty($str)) + { + if (substr($str,0,1) != '-') { + $str = '-'.$str; + } + $this->cache_ttl = $str; + } + } + + public function setForce($force) + { + $this->force = $force; + } + + protected function getModulesXML($url) + { + if (!self::readURL($url,$ssl,$host,$port,$path,$user,$pass)) { + return false; + } + $this->setHost($host,$port); + $this->useSSL($ssl); + $this->setAuthorization($user,$pass); + + return $this->get($path); + } + + protected function withCache($url) + { + $url_md5 = md5($url); + $cached_file = sprintf('%s/%s/%s/%s/%s.ser', + $this->cache_dir, + $this->cache_file_prefix, + substr($url_md5,0,2), + substr($url_md5,2,2), + $url_md5 + ); + + $may_use_cached = false; + + if (@file_exists($cached_file) && !$this->force) + { + $may_use_cached = true; + $ts = @filemtime($cached_file); + if ($ts > strtotime($this->cache_ttl)) + { + # Direct cache + return unserialize(file_get_contents($cached_file)); + } + $this->setValidator('IfModifiedSince', $ts); + } + + if (!$this->getModulesXML($url)) + { + if ($may_use_cached) + { + # connection failed - fetched from cache + return unserialize(file_get_contents($cached_file)); + } + return false; + } + + switch ($this->getStatus()) + { + case '304': + @files::touch($cached_file); + return unserialize(file_get_contents($cached_file)); + case '200': + if ($modules = new daModulesParser($this->getContent())) + { + try { + files::makeDir(dirname($cached_file),true); + } catch (Exception $e) { + return $modules; + } + + if (($fp = @fopen($cached_file, 'wb'))) + { + fwrite($fp, serialize($modules)); + fclose($fp); + files::inheritChmod($cached_file); + } + return $modules; + } + } + + return false; + } + + protected function buildRequest() + { + $headers = parent::buildRequest(); + + # Cache validators + if (!empty($this->validators)) + { + if (isset($this->validators['IfModifiedSince'])) { + $headers[] = 'If-Modified-Since: '.$this->validators['IfModifiedSince']; + } + if (isset($this->validators['IfNoneMatch'])) { + if (is_array($this->validators['IfNoneMatch'])) { + $etags = implode(',',$this->validators['IfNoneMatch']); + } else { + $etags = $this->validators['IfNoneMatch']; + } + $headers[] = ''; + } + } + + return $headers; + } + + private function setValidator($key,$value) + { + if ($key == 'IfModifiedSince') { + $value = gmdate('D, d M Y H:i:s',$value).' GMT'; + } + + $this->validators[$key] = $value; + } +} + +?> \ No newline at end of file diff --git a/plugins/daInstaller/inc/lib.da.installer.ui.php b/plugins/daInstaller/inc/lib.da.installer.ui.php new file mode 100644 index 0000000..aced565 --- /dev/null +++ b/plugins/daInstaller/inc/lib.da.installer.ui.php @@ -0,0 +1,310 @@ +rs->isEmpty()) { + echo '

    '.$msg_no_entry.'

    '; + } + else { + $pager = new pager($page,$this->rs_count,$nb_per_page,10); + if (!$search) { + $pager->base_url = $url.'&tab='.$type.'&page=%s'; + } + else { + $pager->var_pager = 'page'; + } + + $html_block = + ''. + ''. + ''. + ''. + ''. + ''. + ''. + ''. + ''. + '%s'. + '
    '.$msg_th_label.''.__('Lastest Version').''.__('Quick description').''.__('Actions').'
    '; + + echo '

    '.__('Page(s)').' : '.$pager->getLinks().'

    '; + $blocks = explode('%s',$html_block); + echo $blocks[0]; + + $this->rs->index(((integer)$page - 1) * $nb_per_page); + $iter = 0; + while ($iter < $nb_per_page) { + echo $this->{$lineMethod}($url); + if ($this->rs->isEnd()) { + break; + } + else { + $this->rs->moveNext(); + $iter++; + } + } + echo $blocks[1]; + echo '

    '.__('Page(s)').' : '.$pager->getLinks().'

    '; + } + } + + /** + * Return a generic plugin row + * + * @param string url + * + * @return string + */ + private function pluginLine($url) + { + return + ''."\n". + # Extension + ''. + ''.html::escapeHTML($this->rs->id).''. + "\n". + # Version + ''. + html::escapeHTML($this->rs->version). + "\n". + # Quick description + ''. + '

    '.html::escapeHTML($this->rs->label).'
    '. + ''.html::escapeHTML($this->rs->desc).'

    '. + __('by').' '.html::escapeHTML($this->rs->author).'
    '. + '( '.__('More details').' )'. + "\n". + # Action + ''. + '
    '. + '

    '. + $this->core->formNonce(). + '

    '. + '
    '. + "\n". + ''."\n"; + } + + /** + * Return a generic theme row + * + * @param string url + * + * @return string + */ + private function themeLine($url) + { + return + ''."\n". + # Extension + ''. + ''.html::escapeHTML($this->rs->id).''. + '

    '. + "\n". + # Version + ''. + html::escapeHTML($this->rs->version). + "\n". + # Quick description + ''. + '

    '.html::escapeHTML($this->rs->label).'
    '. + ''.html::escapeHTML($this->rs->desc).'

    '. + __('by').' '.html::escapeHTML($this->rs->author).'
    '. + '( '.__('More details').' )'. + "\n". + # Action + ''. + '
    '. + '

    '. + $this->core->formNonce(). + '

    '. + '
    '. + "\n". + ''."\n"; + } +} + +/** + * Class daModulesUpdateList + */ +class daModulesUpdateList +{ + protected $rs; + protected $nb; + + /** + * Class constructor + */ + public function __construct($core,$rs,$nb) + { + $this->core = $core; + $this->rs = $rs; + $this->nb = $nb; + $this->p_link = '%s'; + } + + /** + * Display data table for plugins and themes update lists + * + * @param string type + * @param string url + * + * @return string + */ + public function display($type,$url) + { + $type = ($type == 'themes') ? 'themes' : 'plugins'; + if ($type == 'themes') { + $msg_th_label = __('Theme'); + $lineMethod = 'themeLine'; + } + else { + $msg_th_label = __('Plugins'); + $lineMethod = 'pluginLine'; + } + + $iter = 0; + $items = ''; + $html_block = + '
    '. + ''. + ''. + ''. + ''. + ''. + ''. + ''. + ''. + '%2$s'. + '
    '.$msg_th_label.''.__('Lastest Version').''.__('Quick description').'
    '. + '
    '. + '

    '. + '

    '. + $this->core->formNonce(). + '

    '. + '
    '. + '
    '; + + while ($iter < $this->rs->count()) { + $items .= $this->{$lineMethod}($url); + $this->rs->moveNext(); + $iter++; + } + + echo $this->nb > 0 ? sprintf($html_block,$type,$items) : ''; + + } + + /** + * Return a update plugin row + * + * @param string url + * + * @return string + */ + private function pluginLine($url) + { + $support = + strlen($this->rs->support) > 0 ? + sprintf($this->p_link,$this->rs->support,'support modal',__('Support')) : + ''.__('No support available').''; + + return + ''."\n". + # Extension + ''. + form::checkbox(array('plugins_id[]'),$this->rs->id). + ''.html::escapeHTML($this->rs->id).''. + "\n". + # Version + ''. + html::escapeHTML($this->rs->version). + "\n". + # Quick description + ''. + '

    '.html::escapeHTML($this->rs->label).'
    '. + ''.html::escapeHTML($this->rs->desc).'

    '. + __('by').' '.html::escapeHTML($this->rs->author).'
    '. + '( '. + __('More details').' - '.$support.' )'. + "\n". + ''."\n"; + } + + /** + * Return a update theme row + * + * @param string url + * + * @return string + */ + private function themeLine($url) + { + $support = + strlen($this->rs->support) > 0 ? + sprintf($this->p_link,$this->rs->support,'support modal',__('Support')) : + ''.__('No support available').''; + + return + ''."\n". + # Themes + ''. + form::checkbox(array('themes_id[]'),$this->rs->id). + ''.html::escapeHTML($this->rs->id).''. + '

    '. + "\n". + # Version + ''. + html::escapeHTML($this->rs->version). + "\n". + # Quick description + ''. + '

    '.html::escapeHTML($this->rs->label).'
    '. + ''.html::escapeHTML($this->rs->desc).'

    '. + __('by').' '.html::escapeHTML($this->rs->author).'
    '. + '( '. + __('More details').' - '.$support.' )'. + "\n". + ''."\n"; + } +} + +?> \ No newline at end of file diff --git a/plugins/daInstaller/index.php b/plugins/daInstaller/index.php new file mode 100644 index 0000000..e10e391 --- /dev/null +++ b/plugins/daInstaller/index.php @@ -0,0 +1,321 @@ +blog->settings->addNamespace('dainstaller'); + $s = $core->blog->settings->dainstaller; +} +else { + $core->blog->settings->setNamespace('dainstaller'); + $s = $core->blog->settings; +} + +# Initialisation des variables +$p_url = 'plugin.php?p=daInstaller'; +$default_tab = !empty($_GET['tab']) ? html::escapeHTML($_GET['tab']) : 'plugins'; +$page = !empty($_GET['page']) ? (integer)$_GET['page'] : 1; +$nb_per_page = 10; +$q = !empty($_GET['q']) ? trim(html::escapeHTML($_GET['q'])) : ''; +$default_tab = !empty($q) ? 'search' : $default_tab; +$mode = isset($_GET['mode']) ? html::escapeHTML($_GET['mode']) : 'plugins'; +$ppaths = explode(PATH_SEPARATOR, DC_PLUGINS_ROOT); +$plugins_path = array_pop($ppaths); +$daInstaller = new daInstaller($core); +unset($ppaths); + +$pages['plugins'] = $pages['themes'] = $pages['search'] = 1; +$pages[$default_tab] = $page; + +# Ajout d'un plugin +if (!empty($_POST['add_plugin']) && !empty($_POST['package_url'])) { + try { + $url = html::escapeHTML($_POST['package_url']); + $dest = $plugins_path.'/'.basename($url); + + $ret_code = $daInstaller->processPackage($url,$dest,$core->plugins); + http::redirect($p_url.'&p_added='.$ret_code); + } + catch (Exception $e) { + $core->error->add($e->getMessage()); + $default_tab = 'plugins'; + } +} +# Mise à jour de plugins +elseif (!empty($_POST['upd_plugins']) && !empty($_POST['plugins_id'])) { + try { + $daInstaller->check(); + $ids = $_POST['plugins_id']; + $modules = $daInstaller->getModules('plugins',true); + + foreach ($modules as $module) { + if (in_array($module['id'],$ids)) { + if (!$s->dainstaller_allow_multi_install) { + $dest = $module['root'].'/../'.basename($module['file']); + } + else { + $dest = $plugins_path.'/'.basename($module['file']); + if ($module['root'] != $dest) @file_put_contents($module['root'].'/_disabled',''); + } + $ret_code[] = $daInstaller->processPackage($module['file'],$dest,$core->plugins); + } + } + + $arg = 'p_updated='.implode('|',$ids).'&p_status='.implode('|',$ret_code); + + http::redirect($p_url.'&tab=update&'.$arg); + + } + catch (Exception $e) { + $core->error->add($e->getMessage()); + $default_tab = 'update'; + } +} +# Ajout d'un thème +elseif (!empty($_POST['add_theme']) && !empty($_POST['package_url'])) { + try { + $url = html::escapeHTML($_POST['package_url']); + $dest = $core->blog->themes_path.'/'.basename($url); + + $core_themes = new dcModules($core); + $core_themes->loadModules($core->blog->themes_path,null); + $ret_code = $daInstaller->processPackage($url,$dest,$core_themes); + http::redirect($p_url.'&tab=themes&t_added='.$ret_code); + } + catch (Exception $e) { + unset($core_themes); + $core->error->add($e->getMessage()); + $default_tab = 'themes'; + } +} +# Mise à jour de thèmes +elseif (!empty($_POST['upd_themes']) && !empty($_POST['themes_id'])) { + try { + $daInstaller->check(); + $core_themes = new dcModules($core); + $core_themes->loadModules($core->blog->themes_path,null); + $ids = $_POST['themes_id']; + $modules = $daInstaller->getModules('themes',true); + + foreach ($modules as $module) { + if (in_array($module['id'],$ids)) { + $dest = $core->blog->themes_path.'/'.basename($module['file']); + $ret_code[] = $daInstaller->processPackage($module['file'],$dest,$core_themes); + } + } + + $arg = 't_updated='.implode('|',$ids).'&t_status='.implode('|',$ret_code); + + http::redirect($p_url.'&tab=update&'.$arg); + + } + catch (Exception $e) { + unset($core_themes); + $core->error->add($e->getMessage()); + $default_tab = 'update'; + } +} + +# Et c'est parti ! +$plugins_install = $core->plugins->installModules(); +$daInstaller->check(false,true); + +/** + * This function returns all error / success messages + * + * @return string + */ +function infoMessages() +{ + $res = ''; + $p_msg = '

    %s

    '; + $p_err = '

    %s

    '; + + # Plugins install message + if (!empty($_GET['p_added']) && $_GET['p_added'] != 2) { + $res .= sprintf($p_msg,__('The plugin has been successfully installed.')); + } + # Themes install message + if (!empty($_GET['t_added']) && $_GET['t_added'] != 2) { + $res .= sprintf($p_msg,__('The theme has been successfully installed.')); + } + # Plugins update message + if (!empty($_GET['p_updated'])) { + $err = $upd = ''; + $ids = explode('|',html::escapeHTML($_GET['p_updated'])); + $status = explode('|',html::escapeHTML($_GET['p_status'])); + foreach ($ids as $k => $v) { + if ($status[$k] != 2) { + $err .= '
  • '.$v.'
  • '; + } + else { + $upd .= '
  • '.$v.'
  • '; + } + } + if (!empty($err)) { + $res .= '
    '.__('Following plugins have not been updated:').'
      '.$err.'
    '; + } + else { + $res .= '
    '.__('Following plugins have been updated:').'
      '.$upd.'
    '; + } + } + # Themes update message + if (!empty($_GET['t_updated'])) { + $err = $upd = ''; + $ids = explode('|',html::escapeHTML($_GET['t_updated'])); + $status = explode('|',html::escapeHTML($_GET['t_status'])); + foreach ($ids as $k => $v) { + if ($status[$k] != 2) { + $err .= '
  • '.$v.'
  • '; + } + else { + $upd .= '
  • '.$v.'
  • '; + } + } + if (!empty($err)) { + $res .= '
    '.__('Following themes have not been updated:').'
      '.$err.'
    '; + } + else { + $res .= '
    '.__('Following themes have been updated:').'
      '.$upd.'
    '; + } + } + # Plugins install settings messages + if (!empty($plugins_install['success'])) { + $res .= '
    '.__('Following plugins have been installed:').'
      '; + foreach ($plugins_install['success'] as $k => $v) { + $res .= '
    • '.$k.'
    • '; + } + $res .= '
    '; + } + if (!empty($plugins_install['failure'])) { + $res .= '
    '.__('Following plugins have not been installed:').'
      '; + foreach ($plugins_install['failure'] as $k => $v) { + $res .= '
    • '.$k.' ('.$v.')
    • '; + } + $res .= '
    '; + } + + return $res; +} + +# Récupération de la liste des mises à jour des plugins +# et préparation de l'objet d'affichage +$u_p_rs = $daInstaller->getModules('plugins',true); +$u_p_nb = count($u_p_rs); +$u_p_rs = staticRecord::newFromArray($u_p_rs); +$u_p_list = new daModulesUpdateList($core,$u_p_rs,$u_p_nb); + +# Récupération de la liste des mises à jour des thèmes +# et préparation de l'objet d'affichage +$u_t_rs = $daInstaller->getModules('themes',true); +$u_t_nb = count($u_t_rs); +$u_t_rs = staticRecord::newFromArray($u_t_rs); +$u_t_list = new daModulesUpdateList($core,$u_t_rs,$u_t_nb); + +# Récupération de la liste des plugins disponibles +# et préparation de l'objet d'affichage +$avail_plugins = $daInstaller->getModules('plugins'); +$a_p_nb = count($avail_plugins); +$a_p_rs = staticRecord::newFromArray($avail_plugins); +$a_p_list = new daModulesList($core,$a_p_rs,$a_p_nb); + +# Récupération de la liste des thèmes disponibles +# et préparation de l'objet d'affichage +$avail_themes = $daInstaller->getModules('themes'); +$a_t_nb = count($avail_themes); +$a_t_rs = staticRecord::newFromArray($avail_themes); +$a_t_list = new daModulesList($core,$a_t_rs,$a_t_nb); + +# Récupération de la liste des plugins recherchés +if (!empty($q)) +{ + $default_tab = 'search'; + $search_modules = $daInstaller->search($q,$mode); + $s_m_nb = count($search_modules); + $s_m_rs = staticRecord::newFromArray($search_modules); + $s_m_list = new daModulesList($core,$s_m_rs,$s_m_nb); +} + +# DISPLAY +# ------- +echo +''. +''. + ''.__('DotAddict.org Installer').''. + dcPage::jsModal(). + dcPage::jsPageTabs($default_tab). + dcPage::jsLoad('index.php?pf=daInstaller/js/_dainstaller.js'). + ''. +''. +''. +infoMessages(). +'

    '.__('DotAddict.org Installer').'

    '. +'

    '.__('Install and update your extensions live from DotAddict.org').'

    '; + +echo +''. +'
    '; +if ($u_p_nb > 0 || $u_t_nb > 0) { + echo + '

    '.__('Detected updates for your system').'

    '. + '

    '. + __('Changes can be required after installation of updates. Click on a support link before to be aware about'). + '

    '; +} +else { + echo '

    '.__('No update available').'

    '; +} + $u_p_list->display('plugins',$p_url); + $u_t_list->display('themes',$p_url); +echo +'
    '. +''. +'
    '. + '

    '.($a_p_nb > 0 ? sprintf(__('Available plugins (%s)'),$a_p_nb) : '').'

    '; + $a_p_list->display($pages['plugins'],$nb_per_page,'plugins',$p_url); +echo +'
    '. +''. +'
    '. + '

    '.($a_t_nb > 0 ? sprintf(__('Available themes (%s)'),$a_t_nb) : '').'

    '; + $a_t_list->display($pages['themes'],5,'themes',$p_url); +echo +'
    '. +''. +''; + +dcPage::helpBlock('da_installer'); + +echo +''. +''; \ No newline at end of file diff --git a/plugins/daInstaller/js/_dainstaller.js b/plugins/daInstaller/js/_dainstaller.js new file mode 100644 index 0000000..1c9c878 --- /dev/null +++ b/plugins/daInstaller/js/_dainstaller.js @@ -0,0 +1,17 @@ +/* +# ***** BEGIN LICENSE BLOCK ***** +# This file is part of daInstaller, a plugin for DotClear2. +# Copyright (c) 2008-2011 Tomtom, Pep and contributors, for DotAddict.org. +# All rights reserved. +# +# ***** END LICENSE BLOCK ***** +*/ +$(function() { + $('a.modal').modalWeb($(window).width()-60,$(window).height()-60); +}); +$(function() { + $('.checkboxes-helpers').each(function() { + dotclear.checkboxesHelpers(this); + }); + dotclear.commentsActionsHelper(); +}); \ No newline at end of file diff --git a/plugins/daInstaller/locales/_pot/main.pot b/plugins/daInstaller/locales/_pot/main.pot new file mode 100644 index 0000000..9949e24 --- /dev/null +++ b/plugins/daInstaller/locales/_pot/main.pot @@ -0,0 +1,98 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# 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: \n" +"POT-Creation-Date: 2008-08-20 19:31+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" + +#: _admin.php:20 _admin.php:36 index.php:132 index.php:138 +msgid "DotAddict.org Installer" +msgstr "" + +#: _admin.php:26 +msgid "Updates are available" +msgstr "" + +#: index.php:57 +msgid "Following plugins have been installed:" +msgstr "" + +#: index.php:64 +msgid "Following plugins have not been installed:" +msgstr "" + +#: index.php:72 +msgid " has been successfully upgraded" +msgstr "" + +#: index.php:72 +msgid " has been successfully installed." +msgstr "" + +#: index.php:88 +msgid "Search options" +msgstr "" + +#: index.php:92 +msgid "Query:" +msgstr "" + +#: index.php:97 +msgid "Plugins" +msgstr "" + +#: index.php:100 +msgid "Themes" +msgstr "" + +#: index.php:101 +msgid "ok" +msgstr "" + +#: index.php:139 +msgid "Install and update your extensions live from DotAddict.org" +msgstr "" + +#: index.php:143 +msgid "Available updates" +msgstr "" + +#: index.php:144 +msgid "Detected updates for your system" +msgstr "" + +#: index.php:149 +msgid "Get more plugins" +msgstr "" + +#: index.php:150 +msgid "Available plugins" +msgstr "" + +#: index.php:155 +msgid "Get more themes" +msgstr "" + +#: index.php:156 +msgid "Available themes" +msgstr "" + +#: index.php:160 index.php:161 +msgid "Search" +msgstr "" + +#: index.php:164 +#, php-format +msgid "%u plugin(s) found" +msgstr "" diff --git a/plugins/daInstaller/locales/fr/help/da_installer.html b/plugins/daInstaller/locales/fr/help/da_installer.html new file mode 100644 index 0000000..62f958c --- /dev/null +++ b/plugins/daInstaller/locales/fr/help/da_installer.html @@ -0,0 +1,30 @@ + + + Mise à jour d'extension(s) + + + + +

    Mise à jour d'extension(s)

    + +
    +
    Il est possible dans Dotclear 2 de spécifier dans sa configuration (PATH) + plusieurs chemins de dossiers contenant des extensions. Or, les mises à jour des + extensions se font dans le dernier répertoire du PATH. + Il se peut, pour des raisons variées, que dans un des premiers, il existe une + extension avec une version inférieure à celle présente sur DotAddict. Dans + ce cas préçis, vous avez deux choix possibles :
      +
    • Autoriser la multi-installation : la nouvelle version de + l’extension sera téléchargée puis installée dans le dernier répertoire du PATH + et l’ancienne extension recevera un fichier _disabled afin de la désactiver. L’ancienne + version ne sera pas supprimée
    • +
    • Ne pas autoriser la multi-installation : la nouvelle version + ira écraser l’ancienne dans le bon répertoire.
    + + Par défaut, la multi-installation est désactivée mais vous pouvez + changer ce comportement en modifiant la variable dainstaller_allow_multi_install + dans about:config
    +
    + + + diff --git a/plugins/daInstaller/locales/fr/main.lang.php b/plugins/daInstaller/locales/fr/main.lang.php new file mode 100644 index 0000000..3924861 --- /dev/null +++ b/plugins/daInstaller/locales/fr/main.lang.php @@ -0,0 +1,120 @@ + \ No newline at end of file diff --git a/plugins/daInstaller/locales/fr/main.po b/plugins/daInstaller/locales/fr/main.po new file mode 100644 index 0000000..eafb5e4 --- /dev/null +++ b/plugins/daInstaller/locales/fr/main.po @@ -0,0 +1,163 @@ +# Language: Français +# Module: daInstaller - 1.0.3 +# Date: 2011-05-16 11:47:48 +# Translated with translater 1.5 + +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" +"Project-Id-Version: daInstaller 1.0.3\n" +"POT-Creation-Date: \n" +"PO-Revision-Date: 2011-05-16T11:47:48+00:00\n" +"Last-Translator: Thomas Bouron\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Transfer-Encoding: 8bit\n" + +#: _admin.php:20 +#: _admin.php:50 +#: index.php:250 +#: index.php:258 +msgid "DotAddict.org Installer" +msgstr "Installateur DotAddict.org" + +#: _admin.php:38 +msgid "Updates are available" +msgstr "Des mises à jour sont disponibles" + +#: inc/class.da.installer.php:175 +msgid "Oops, something went wrong with %s, we are working on it. %s" +msgstr "Oops, il semble y avoir un problème avec %s, nous travaillons actuellement à sa résolution. %s" + +#: inc/class.da.installer.php:176 +msgid "dotaddict.org website" +msgstr "le site dotaddict.org" + +#: inc/class.da.installer.php:177 +msgid "Wanna help too?" +msgstr "Vous voulez nous aider aussi?" + +#: inc/class.da.modules.parser.php:25 +msgid "Impossible to read data feed" +msgstr "Impossible de lire le flux de données" + +#: inc/class.da.modules.parser.php:32 +msgid "Wrong data feed" +msgstr "Flux de données incorrect" + +#: inc/lib.da.installer.ui.php:31 +msgid "No theme" +msgstr "Aucun thème disponible" + +#: inc/lib.da.installer.ui.php:36 +msgid "No extension" +msgstr "Aucune extension disponible" + +#: inc/lib.da.installer.ui.php:58 +#: inc/lib.da.installer.ui.php:212 +msgid "Lastest Version" +msgstr "Dernière version" + +#: inc/lib.da.installer.ui.php:59 +#: inc/lib.da.installer.ui.php:213 +msgid "Quick description" +msgstr "Description rapide" + +#: inc/lib.da.installer.ui.php:60 +msgid "Actions" +msgstr "Actions" + +#: inc/lib.da.installer.ui.php:111 +#: inc/lib.da.installer.ui.php:150 +#: inc/lib.da.installer.ui.php:267 +#: inc/lib.da.installer.ui.php:304 +msgid "More details" +msgstr "En savoir plus" + +#: inc/lib.da.installer.ui.php:119 +#: inc/lib.da.installer.ui.php:158 +msgid "Install" +msgstr "Installer" + +#: inc/lib.da.installer.ui.php:196 +msgid "Theme" +msgstr "Thèmes" + +#: inc/lib.da.installer.ui.php:222 +msgid "Update selected modules" +msgstr "Mettre à jour les modules sélectionnés" + +#: inc/lib.da.installer.ui.php:247 +#: inc/lib.da.installer.ui.php:283 +msgid "Support" +msgstr "Support" + +#: inc/lib.da.installer.ui.php:248 +#: inc/lib.da.installer.ui.php:284 +msgid "No support available" +msgstr "Aucun support disponible" + +#: index.php:142 +msgid "The plugin has been successfully installed." +msgstr "Le plugin a été installé avec succès" + +#: index.php:146 +msgid "The theme has been successfully installed." +msgstr "Le thème a été installé avec succès" + +#: index.php:162 +msgid "Following plugins have not been updated:" +msgstr "Les extensions suivantes n'ont pas été mises à jour :" + +#: index.php:165 +msgid "Following plugins have been updated:" +msgstr "Les extensions suivantes ont été mises à jour :" + +#: index.php:182 +msgid "Following themes have not been updated:" +msgstr "Les thèmes suivants n'ont pas été mis à jour :" + +#: index.php:185 +msgid "Following themes have been updated:" +msgstr "Les thèmes suivants ont été mis à jour :" + +#: index.php:259 +msgid "Install and update your extensions live from DotAddict.org" +msgstr "Installez et mettez à jour vos extensions en direct depuis DotAddict.org" + +#: index.php:263 +msgid "Available updates" +msgstr "Mises à jour disponibles" + +#: index.php:266 +msgid "Detected updates for your system" +msgstr "Mises à jour détectées pour votre système" + +#: index.php:268 +msgid "Changes can be required after installation of updates. Click on a support link before to be aware about" +msgstr "Des changements sont peut être nécessaires après la mise à jour. Pensez à vérifier en cliquant sur le lien de support" + +#: index.php:272 +msgid "No update available" +msgstr "Aucune mise à jour détectée pour votre système" + +#: index.php:279 +msgid "Get more plugins" +msgstr "Obtenir plus d'extensions" + +#: index.php:280 +msgid "Available plugins (%s)" +msgstr "Plugins disponibles (%s)" + +#: index.php:285 +msgid "Get more themes" +msgstr "Obtenir plus de thèmes" + +#: index.php:286 +msgid "Available themes (%s)" +msgstr "Thèmes disponibles (%s)" + +#: index.php:309 +msgid "%u %s found" +msgstr "%u %s trouvé(s)" + diff --git a/plugins/daInstaller/locales/fr/resources.php b/plugins/daInstaller/locales/fr/resources.php new file mode 100644 index 0000000..4ea1b39 --- /dev/null +++ b/plugins/daInstaller/locales/fr/resources.php @@ -0,0 +1,14 @@ + \ No newline at end of file diff --git a/plugins/daInstaller/locales/l10n-daInstaller-fr-1304423937.bck.zip b/plugins/daInstaller/locales/l10n-daInstaller-fr-1304423937.bck.zip new file mode 100644 index 0000000000000000000000000000000000000000..52d83c72f5fd94e2f25524ac08b28f792d09c08e GIT binary patch literal 1478 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 C<9^ow literal 0 HcmV?d00001 diff --git a/plugins/daInstaller/locales/l10n-daInstaller-fr-1304424006.bck.zip b/plugins/daInstaller/locales/l10n-daInstaller-fr-1304424006.bck.zip new file mode 100644 index 0000000000000000000000000000000000000000..f5774f9adbe674182393e11206dfd84d0b0d1ebc GIT binary patch literal 3007 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 literal 0 HcmV?d00001 diff --git a/plugins/daInstaller/locales/l10n-daInstaller-fr-1304424011.bck.zip b/plugins/daInstaller/locales/l10n-daInstaller-fr-1304424011.bck.zip new file mode 100644 index 0000000000000000000000000000000000000000..1a447bd27fa858fd19b0e8fde932683850e941c9 GIT binary patch literal 3011 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 literal 0 HcmV?d00001 diff --git a/plugins/daInstaller/locales/l10n-daInstaller-fr-1305546468.bck.zip b/plugins/daInstaller/locales/l10n-daInstaller-fr-1305546468.bck.zip new file mode 100644 index 0000000000000000000000000000000000000000..1e0721019836b4b1d5493c1f503c6f3bf6cd8947 GIT binary patch literal 3008 zcma*pc{CJU8vyW0$Qr{~8nVPpgt14;l%*KPHVq<-C0iIfAtBk9$T~t&LZ!&QjAdjW zBxJ&jeaSYK*ZNvMz286Y_nq@C&pqcp=iYPAbN~B2kD=~aS`YvLU;xltzkws7oV6L~ z0DvBL06_Hg_JIuo>+NIX>T2&L?doo4<7)3M?cgQtX5);7x!PbIVIEE%X{KXdV^`UO zcTHE2%SI}92lHp|55;vP%pe_BpgA?aG+u1n5*2+N383fc>Kpl^#3UsA<_|ix*nHZT zn{jt)Jo;PKrdOsH23=pQu25ScKs()b9{^8m^dW|zP_r+AGfylR50I!3&b~_*#I8jy zqNex9w6s|%CGOTm1(D%j@oLrAqi3dPToekfVG%ZcMB48UuFaJ26Z-o6l|*yofWpaY zpT~Fwrjue)Df?~PQ(b+#?y!j?KfnE{y9@J?9hL+8o5kL+UbCz(Uo}w)HeGdFbWg(c zuW8blsM$F#6hhOUkPcp%#R|Fz#nRw_?OjQC-T&k-EJV(@AF~}w0dMKr2-&NoJe|5~ zX)Tkyayi@SVu7eF7oJ8Q4rh7Vn1VY7mgp7ZWMm`DG?Qvy>{YKX!#?#nw>ZOwOU5qI z$#71^F3d~GoX^rvW*ip@=mOn4gL|QodlN|xa6*wdzCVi` z4#|+_n%?eTCVLrf>qkO|g6WWIUWFX7bQ~8=52K-IE78r~V~CX|8`7s;3>wbsHR11& z;%l(D=}CDrlm2#5fOg*sF^5f1^Sy#-;ub?hO;Wj=p^kg0PL!@GlgJ#V<;_+HdpIEENBUEpdb7>3I!d}p3iyxZU zZUWLD=s&FF<5h@0f{cZ={Lpu2<}r@8gwErQz`xe}5CHojfZaaq#RM*-@p zLw5|aDF42`}-;PRUCc?@FcSdLZWy8$2Ck)aSOT_J`oRLI8P}zr&_4bJjd5M4}(-FO>ZQCwV&+TXrW96$qBe$9y?&}!pRjs&< zcJ9oS3i?SkN^hu`8NqE2pBa6(J!n|>(+@ck{JWio|DtNnknkk-R8`8UssjH*RS)-5 zPqBPTzddDfq6i^a`q=&RKwaA#rR|Uo>5ELGhBMWh! zn%_Ct`H~-9u{kVL_1}2O+-v=XKte2~h-Y(P7JVh*~0*J^|K5-O^UeUu*LNhpK3qBoI~C`uzO zyCsjYj@t7>c*Asy;nz9ELvgUiV&wo(yV@Y=Li1UU3}hHrlK8c$4;@2o>NETX+8-?E z>PR&pUT0Uy+kWD?IdM9ih953V)%p(4Syo0WFbG4wCoQ4Vee!X|b8NqA>6|iGLqovp zC!*@?nRj!;k~b|Q4hPyQlSreO;P__{lKj_)y%e{Nq$8U-sk$ViUP~h*`^CKu}jHcr2JL@XVg1 zAD@e*6|BNW6KhhLNo#g=Cq8`e#|-u2xvFYZt$<9CxMFt(O`B*&e*9QYX7xMx`#+kJ zc3JWMB6(c%Zf12e4)XC^S4m;6O%v{YEUB18d~`;5K3?M6{f8`2v3QoX$mr@b_&~4v zdz8WY8da=n#&M}+|4r9)g#8uhoO=DMontUsGxKB>Z81R1 z482Ctf~Km3D!(%~kXm44CyA1~`}Jz0nwPph=04?u&u#S!e-zk$Hxa1#DBv+}O#KFC z(a$h42;#{tO@6$4#>uBCPq`z0!Fr2H_l|F29fygeNDsGWOu*~MCxe9fIyA`ZzNU2OU&KotQoB>&ezjsD$JaT`>AuD; z{M2*_4?5GG5jsUH5oU!6kY|4Z|#{t>;8ri0u2XJ^{5jN#|tlsmvOyyTI=UCQa zW12c@HFVzfh%WPd*92?nfAk8|E|g!dYKy$_1xS)BaF1>twtA5$glEuC^F$V_dQ ztXB-4YeVFs%9C52MQu#`{hoJn`~%gK=&Vrk5#507*1UV4Sue1&#TQo zKW*Fy-5%t$5zbssh#l>nkOo7fOj?&8pPc;NW<%XGGyuSVo`z59J`JJ2_Wy4-{`ZQ1 m|Lu1t_-6>6CX>_t@ZY9w4|hXdI{M%5X--$}X=Y*mefkGkDUHGa literal 0 HcmV?d00001 diff --git a/plugins/daInstaller/style.css b/plugins/daInstaller/style.css new file mode 100644 index 0000000..ed6af47 --- /dev/null +++ b/plugins/daInstaller/style.css @@ -0,0 +1,29 @@ +/* +# ***** BEGIN LICENSE BLOCK ***** +# This file is part of daInstaller, a plugin for DotClear2. +# Copyright (c) 2008-2011 Tomtom, Pep and contributors, for DotAddict.org. +# All rights reserved. +# +# ***** END LICENSE BLOCK ***** +*/ +#themes { + border: none; + margin: 0; +} +.learnmore { + background: transparent url(index.php?pf=daInstaller/img/help.png) no-repeat top right; + padding-right: 20px; +} +.support { + background: transparent url(index.php?pf=daInstaller/img/support.png) no-repeat top right; + padding-right: 20px; +} +.sshot img { + margin:4px 0; + width:160px; + height:140px; + border:1px solid #999; +} +form { + clear:both; +} \ No newline at end of file diff --git a/plugins/externalMedia/_admin.php b/plugins/externalMedia/_admin.php new file mode 100644 index 0000000..8b09054 --- /dev/null +++ b/plugins/externalMedia/_admin.php @@ -0,0 +1,32 @@ +addBehavior('adminPostHeaders',array('externalMediaBehaviors','jsLoad')); +$core->addBehavior('adminPageHeaders',array('externalMediaBehaviors','jsLoad')); +$core->addBehavior('adminRelatedHeaders',array('externalMediaBehaviors','jsLoad')); +$core->addBehavior('adminDashboardHeaders',array('externalMediaBehaviors','jsLoad')); + +class externalMediaBehaviors +{ + public static function jsLoad() + { + return + ''. + '\n"; + } +} +?> \ No newline at end of file diff --git a/plugins/externalMedia/_define.php b/plugins/externalMedia/_define.php new file mode 100644 index 0000000..4268ea2 --- /dev/null +++ b/plugins/externalMedia/_define.php @@ -0,0 +1,22 @@ +registerModule( + /* Name */ "External Media", + /* Description*/ "Insert external media from Internet", + /* Author */ "Olivier Meunier", + /* Version */ '0.6.1', + /* Permissions */ 'usage,contentadmin', + /* Priority */ 50 +); +?> \ No newline at end of file diff --git a/plugins/externalMedia/bt_video.png b/plugins/externalMedia/bt_video.png new file mode 100644 index 0000000000000000000000000000000000000000..3309386de1f7d7e59468badfc321552240347701 GIT binary patch literal 1932 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc3?z4jzqJQa%*9TgAsieWw;%dHU|?WO3h)VW z1q%Ds-znM~;Wbk^EiG;D-n|#zJa=$#2%EY_Ct>^JCwDT}?m2RO_ob`1y1ToVu3C5K z?1KXzOQ+3Qtf{Wv+S*#bcD0P}!WX|!uHUpJdQr!hAOEAHqvss?zjV!({7n;ApIZoC{2;J0?yY3H)j6BZtcZ#nqk`~Uy{KcBmNt*WMG#*T$g ze%#x3Vd{a4>y6XS0F5;^Hf}o`dHcb|xrc_nS;Ol4)|x1WFQd@u*-L2qxb zbJy-y7Z<;Ib+32g)K7o^1I@c}_ff-+MO(J-T)1$7L(LJF>Pu_ZtO;yApEmQ%z9Z+B zZ8^31;FX0-mz_R$8EAJ?TX$(`iK3+Bt1th90t2`0-G24%vjZRMoQe-`+OhB6y`#_H zea)P<%c=Oa> zQWe}Xi&D$;i?WLqoP&*LTyp~^Ar?W9x(Ht%tK|G#y+n{Qy^7od1{?c|g2d$P)DnfH z)bz|eTO|br1to>d6kDZmQ(pt$0_W6>OpmIf)Zi+=kmRcDWXlvKdpjz1+TBLf2M4Bo1&C7s~{IQsGUHbtx`rw zNr9EVetCJhUb(Seeo?xG?WUP)qwZeFo6#1NP{E~&-IMVSTQ za0Qv0n3P{yVymPCvIq{Ko=Yr%Ta;G}4Lo2l>Q^Kd=o{)8=)+A0YP10gT7hFMzbGU> zKgSMBl-PiDq9{VxiqN0xl30>z2MP~eATlxwF*LR^v9vNZk3!N9QG}-5H$NpatrA1K ziItI|m9Yg>JCY)(b{lhSYEEiyYFw zntKf8=X2!G*t)e;hub6Ix{_6#b(6mBCG)#xSFFw)HkH+wF=hF|43$MHf@!fQCJ8M& zny`XPFN2iO?C5*RZ8q0VICP7J2*mkBu~6t^}|_?VfCNffKW5*xxi3h@O1TaS?83{1OS3u+}{8I literal 0 HcmV?d00001 diff --git a/plugins/externalMedia/index.php b/plugins/externalMedia/index.php new file mode 100644 index 0000000..e85ae13 --- /dev/null +++ b/plugins/externalMedia/index.php @@ -0,0 +1,282 @@ + '#^(http(s?)://.+\.mp3)$#', + 'flv' => '#^(http(s?)://.+\.flv)$#', + 'dailymotion' => '#^http://(www.)?dailymotion.com/(.+)#', + 'googlevideo' => '#^http://video.google.([a-z]{2,})/videoplay\?docid=(.+?)(&|$)#', + 'vimeo' => '#^http://www.vimeo.com/([0-9]+?)#', + 'youtube' => '#^http://([a-z]{2,}.)?youtube.com/(.+)#', + 'jamendo' => '#^http://(www.)?jamendo.com/[a-z]{2}/(playlist|album|track)/([0-9]+)#', + 'deezer' => '#^http://(www.)?deezer.com/track/(.+)#' +); + +if ($media_page) +{ + try + { + $media_service = false; + foreach ($services_regs as $k => $v) { + if (preg_match($v,$media_page)) { + $media_service = $k; + break; + } + } + + if (!$media_service) { + throw new Exception(__('Unsupported service')); + } + + if ($media_service != 'mp3' && $media_service != 'flv' && $media_service != 'jamendo') + { + $http = netHttp::initClient($media_page,$media_path); + $http->setTimeout(5); + $http->setUserAgent($_SERVER['HTTP_USER_AGENT']); + $http->get($media_path); + + if ($http->getStatus() != 200) { + throw new Exception(__('Invalid page URL')); + } + + $content = $http->getContent(); + } + + switch ($media_service) + { + case 'mp3': + $m_url = $media_page; + $m_title = basename($media_page); + $m_object = dcMedia::mp3player($m_url,$core->blog->getQmarkURL().'pf=player_mp3.swf'); + break; + case 'flv': + $m_url = $media_page; + $m_title = basename($media_page); + $m_object = dcMedia::flvPlayer($m_url,$core->blog->getQmarkURL().'pf=player_flv.swf'); + break; + case 'dailymotion': + if (preg_match('##ms',$content,$m)) + { + $cap = html::decodeEntities($m[1]); + $movie; + + if (preg_match('#param\s+name="movie"\s+value="(.+?)"#s',$cap,$M)) { + $movie = html::escapeHTML($M[1]); + } + + if (preg_match('#
    (.+?)#s',$cap,$M)) { + $m_title = html::decodeEntities($M[2]); + $m_url = $M[1]; + } + + if ($movie) + { + $m_object = + ''."\n". + ' '."\n". + ' '."\n". + ' '."\n". + ''; + } + } + break; + case 'googlevideo': + if (preg_match('#docid=(.+?)(&|$)#',$media_path,$m)) + { + $movie = 'http://video.google.com/googleplayer.swf?docid='.$m[1]; + + if (preg_match('#(.+?)#si',$content,$M)) { + $m_title = $M[1]; + } + + $m_object = + ''."\n". + ' '."\n". + ' '."\n". + ''; + } + break; + case 'vimeo': + if (preg_match('#'."\n". + ' '."\n". + ' '."\n". + ' '."\n". + ''; + } + break; + case 'youtube': + if (preg_match('#Youtube\s+-\s+(.+?)#si',$content,$M)) { + $m_title = $M[1]; + } + + if ($movie) + { + $m_object = + ''."\n". + ' '."\n". + ' '."\n". + ''; + } + } + break; + case 'jamendo': + if (preg_match('#^http://(www.)?jamendo.com/[a-z]{2}/(playlist|album|track)/([0-9]+)#',$media_page,$m)) + { + $type = $m[2]; + $id = $m[3]; + + $req = 'name'; + if ($type == 'track') { + $req .= '+stream'; + } + + $http = netHttp::initClient('http://api.jamendo.com/get2/'.$req.'/'.$type.'/plain/?streamencoding=mp31&id='.$id,$media_path); + $http->setTimeout(5); + $http->setUserAgent($_SERVER['HTTP_USER_AGENT']); + $http->get($media_path); + + if ($http->getStatus() != 200) { + throw new Exception(__('Invalid page URL')); + } + + if ($type != 'track') { + $m_title = $http->getContent(); + $m_object = + ''."\n". + ''; + $m_url = $media_page; + } else { + $t = explode("\t", $http->getContent()); + $m_title = $t[0]; + $url = $t[1]; + $m_object = dcMedia::mp3player($url,$core->blog->getQmarkURL().'pf=player_mp3.swf'); + $m_url = $media_page; + } + } + break; + case 'deezer': + if (preg_match('#/track/(.+?)(&|$)#',$media_path,$m)) + { + $idSong = $m[1]; + + if (preg_match('#(.+?) \| Deezer#si',$content,$M)) { + $m_title = $M[1]; + } + + $m_object = + ''."\n". + ''; + } + break; + } + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} +?> + + + <?php echo __('External media selector') ?> + + + + +'.__('External media selector').''; + +if (!$m_object) +{ + echo + '
    '. + '

    '.__('Supported media services').'

    '. + '
    • '.implode('
    • ',array_keys($services_regs)).'
    '. + '

    '.__('Please enter the URL of the page containing the video you want to include in your post.').'

    '. + '

    '. + + '

    '. + $core->formNonce().'

    '. + '
    '; +} +else +{ + echo + '
    '.$m_object.'
    '. + '
    '; + + $i_align = array( + 'none' => array(__('None'),0), + 'left' => array(__('Left'),0), + 'right' => array(__('Right'),0), + 'center' => array(__('Center'),1) + ); + + echo '

    '.__('Media alignment').'

    '; + echo '

    '; + foreach ($i_align as $k => $v) { + echo '
    '; + } + echo '

    '; + + echo + '

    '.__('Media title').'

    '. + '

    '; + + echo + '

    '.__('Cancel').' - '. + ''.__('Insert').''. + form::hidden(array('m_object'),html::escapeHTML($m_object)). + form::hidden(array('m_url'),html::escapeHTML($m_url)). + '

    '; +} + +?> + + \ No newline at end of file diff --git a/plugins/externalMedia/popup.js b/plugins/externalMedia/popup.js new file mode 100644 index 0000000..cc8efca --- /dev/null +++ b/plugins/externalMedia/popup.js @@ -0,0 +1,3 @@ + +$(function(){$('#media-insert-cancel').click(function(){window.close();});$('#media-insert-ok').click(function(){sendClose();window.close();});$('#supported_media').prev().toggleWithLegend($('#supported_media'));function sendClose(){var insert_form=$('#media-insert-form').get(0);if(insert_form==undefined){return;} +var tb=window.opener.the_toolbar;var data=tb.elements.extmedia.data;data.alignment=$('input[name="alignment"]:checked',insert_form).val();data.title=insert_form.m_title.value;data.url=insert_form.m_url.value;data.m_object=insert_form.m_object.value;tb.elements.extmedia.fncall[tb.mode].call(tb);};}); \ No newline at end of file diff --git a/plugins/externalMedia/post.js b/plugins/externalMedia/post.js new file mode 100644 index 0000000..3b87ce0 --- /dev/null +++ b/plugins/externalMedia/post.js @@ -0,0 +1,6 @@ + +jsToolBar.prototype.elements.extmedia={type:'button',title:'External Media',icon:'index.php?pf=externalMedia/bt_video.png',fn:{},fncall:{},open_url:'plugin.php?p=externalMedia&popup=1',data:{},popup:function(){window.the_toolbar=this;this.elements.extmedia.data={};var p_win=window.open(this.elements.extmedia.open_url,'dc_popup','alwaysRaised=yes,dependent=yes,toolbar=yes,height=500,width=760,'+'menubar=no,resizable=yes,scrollbars=yes,status=no');},gethtml:function(){var d=this.data;if(d.m_object==''){return false;} +var res='
    '+d.title+'';} +res+='\n
    '+d.title;} +res+='\n
    ';return res;}};jsToolBar.prototype.elements.extmedia.fn.wiki=function(){this.elements.extmedia.popup.call(this);};jsToolBar.prototype.elements.extmedia.fn.xhtml=function(){this.elements.extmedia.popup.call(this);};jsToolBar.prototype.elements.extmedia.fncall.wiki=function(){var html=this.elements.extmedia.gethtml();this.encloseSelection('','',function(){return'\n///html\n'+html+'\n///\n';});};jsToolBar.prototype.elements.extmedia.fncall.xhtml=function(){var html=this.elements.extmedia.gethtml();this.encloseSelection('','',function(){return html;});}; \ No newline at end of file diff --git a/plugins/fairTrackbacks/_define.php b/plugins/fairTrackbacks/_define.php new file mode 100644 index 0000000..eedcd84 --- /dev/null +++ b/plugins/fairTrackbacks/_define.php @@ -0,0 +1,22 @@ +registerModule( + /* Name */ "Fair Trackbacks", + /* Description*/ "Trackback validity check", + /* Author */ "Olivier Meunier", + /* Version */ '1.0', + /* Permissions */ 'usage,contentadmin', + /* Priority */ 200 +); +?> \ No newline at end of file diff --git a/plugins/fairTrackbacks/_prepend.php b/plugins/fairTrackbacks/_prepend.php new file mode 100644 index 0000000..2ca33cd --- /dev/null +++ b/plugins/fairTrackbacks/_prepend.php @@ -0,0 +1,22 @@ +spamfilters[] = 'dcFilterFairTrackbacks'; +} +?> \ No newline at end of file diff --git a/plugins/fairTrackbacks/_public.php b/plugins/fairTrackbacks/_public.php new file mode 100644 index 0000000..82d8849 --- /dev/null +++ b/plugins/fairTrackbacks/_public.php @@ -0,0 +1,18 @@ +spamfilters[] = 'dcFilterFairTrackbacks'; +} +?> \ No newline at end of file diff --git a/plugins/fairTrackbacks/class.dc.filter.fairtrackbacks.php b/plugins/fairTrackbacks/class.dc.filter.fairtrackbacks.php new file mode 100644 index 0000000..fbc9793 --- /dev/null +++ b/plugins/fairTrackbacks/class.dc.filter.fairtrackbacks.php @@ -0,0 +1,85 @@ +description = __('Checks trackback source for a link to the post'); + } + + + public function isSpam($type,$author,$email,$site,$ip,$content,$post_id,&$status) + { + if ($type != 'trackback') { + return; + } + + try + { + $default_parse = array('scheme'=>'','host'=>'','path'=>'','query'=>''); + $S = array_merge($default_parse,parse_url($site)); + + if ($S['scheme'] != 'http' || !$S['host'] || !$S['path']) { + throw new Exception('Invalid URL'); + } + + # Check incomink link page + $post = $this->core->blog->getPosts(array('post_id' => $post_id)); + $post_url = $post->getURL(); + $P = array_merge($default_parse,parse_url($post_url)); + + if ($post_url == $site) { + throw new Exception('Same source and destination'); + } + + $o = netHttp::initClient($site,$path); + $o->setTimeout(3); + $o->get($path); + + # Trackback source does not return 200 status code + if ($o->getStatus() != 200) { + throw new Exception('Invalid Status Code'); + } + + $tb_page = $o->getContent(); + + # Do we find a link to post in trackback source? + if ($S['host'] == $P['host']) { + $pattern = $P['path'].($P['query'] ? '?'.$P['query'] : ''); + } else { + $pattern = $post_url; + } + $pattern = preg_quote($pattern,'/'); + + if (!preg_match('/'.$pattern.'/',$tb_page)) { + throw new Exception('Unfair'); + } + } + catch (Exception $e) + { + throw new Exception('Trackback not allowed for this URL.'); + } + } +} +?> \ No newline at end of file diff --git a/plugins/googleTools/_admin.php b/plugins/googleTools/_admin.php new file mode 100644 index 0000000..2581a43 --- /dev/null +++ b/plugins/googleTools/_admin.php @@ -0,0 +1,48 @@ +addBehavior('adminBlogPreferencesForm',array('googlestuffAdminBehaviours','adminBlogPreferencesForm')); +$core->addBehavior('adminBeforeBlogSettingsUpdate',array('googlestuffAdminBehaviours','adminBeforeBlogSettingsUpdate')); + +class googlestuffAdminBehaviours +{ + public static function adminBlogPreferencesForm(&$core,&$settings) + { + echo + '
    Google Stuff'. + '
    '. + '

    '. + '
    '. + '

    '. + '
    '. + '
    '; + } + public static function adminBeforeBlogSettingsUpdate(&$settings) + { + $settings->setNameSpace('googlestuff'); + $settings->put('googlestuff_uacct',empty($_POST['googlestuff_uacct'])?"":$_POST['googlestuff_uacct'],'string'); + $settings->put('googlestuff_verify',empty($_POST['googlestuff_verify'])?"":$_POST['googlestuff_verify'],'string'); + $settings->setNameSpace('system'); + } + +} +?> \ No newline at end of file diff --git a/plugins/googleTools/_define.php b/plugins/googleTools/_define.php new file mode 100644 index 0000000..ddd883a --- /dev/null +++ b/plugins/googleTools/_define.php @@ -0,0 +1,24 @@ +registerModule( + /* Name */ "Google Tools", + /* Description*/ "Handles Google tools (Analytics & Webmaster Tools)", + /* Author */ "xave", + /* Version */ '0.2.3', + /* Permissions */ 'contentadmin' +); +?> \ No newline at end of file diff --git a/plugins/googleTools/_install.php b/plugins/googleTools/_install.php new file mode 100644 index 0000000..04eae23 --- /dev/null +++ b/plugins/googleTools/_install.php @@ -0,0 +1,35 @@ +plugins->moduleInfo('googlestuff','version'); +$installed_version = $core->getVersion('googlestuff'); + +if (version_compare($installed_version,$this_version,'>=')) { + return; +} + +$core->blog->settings->setNamespace('googlestuff'); +$core->blog->settings->put('googlestuff_uacct','','string','Google Analytics PageTracker ID',true,true); +$core->blog->settings->put('googlestuff_verify','','string','Google Webmaster Tools Verify code',true,true); +$core->blog->settings->setNamespace('system'); + +$core->setVersion('googlestuff',$this_version); + +return true; +?> \ No newline at end of file diff --git a/plugins/googleTools/_public.php b/plugins/googleTools/_public.php new file mode 100644 index 0000000..caf4702 --- /dev/null +++ b/plugins/googleTools/_public.php @@ -0,0 +1,52 @@ +addBehavior('publicHeadContent',array('googlestuffPublicBehaviours','publicHeadContent')); + $core->addBehavior('publicFooterContent',array('googlestuffPublicBehaviours','publicFooterContent')); + + +class googlestuffPublicBehaviours +{ + public static function publicHeadContent(&$core) + { + if ($core->blog->settings->googlestuff_verify != "") { + $res = ''."\n"; + echo $res; + } + } + + public static function publicFooterContent(&$core) + { + if ($core->blog->settings->googlestuff_uacct != "") { + $res = ''."\n". + ''."\n"; + echo $res; + } + } + +} +?> \ No newline at end of file diff --git a/plugins/googleTools/locales/fr/main.lang.php b/plugins/googleTools/locales/fr/main.lang.php new file mode 100644 index 0000000..2986eca --- /dev/null +++ b/plugins/googleTools/locales/fr/main.lang.php @@ -0,0 +1,19 @@ + diff --git a/plugins/importExport/_admin.php b/plugins/importExport/_admin.php new file mode 100644 index 0000000..025193e --- /dev/null +++ b/plugins/importExport/_admin.php @@ -0,0 +1,22 @@ +addItem(__('Import/Export'),'plugin.php?p=importExport','index.php?pf=importExport/icon.png', + preg_match('/plugin.php\?p=importExport(&.*)?$/',$_SERVER['REQUEST_URI']), + $core->auth->check('admin',$core->blog->id)); + +# Files needed by flat files import / export +$__autoload['backupFile'] = dirname(__FILE__).'/inc/flat/class.backupFile.php'; +$__autoload['dcImport'] = dirname(__FILE__).'/inc/flat/class.dc.import.php'; +$__autoload['dbExport'] = dirname(__FILE__).'/inc/flat/class.db.export.php'; +?> \ No newline at end of file diff --git a/plugins/importExport/_define.php b/plugins/importExport/_define.php new file mode 100644 index 0000000..9c49a3e --- /dev/null +++ b/plugins/importExport/_define.php @@ -0,0 +1,22 @@ +registerModule( + /* Name */ "Import / Export", + /* Description*/ "Import and Export your blog", + /* Author */ "Olivier Meunier", + /* Version */ '2.1', + /* Permissions */ 'admin', + /* Priority */ 10 +); +?> \ No newline at end of file diff --git a/plugins/importExport/icon.png b/plugins/importExport/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..b0bc5e8a7cfd1ad1bb8b6d293a2f6019d37ed6a0 GIT binary patch literal 662 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJbFq_W2nPqp?T7vk7#JA21AIbU z|NsAAQ&XduExB~r(wQ@7_Vn}sxex}sD+^Gtt*wpAlN}-}7{~)*c+YZl=ruR0){;+> z6pIjqD-aD60J4GFlNLk)W#Q_9#sbX&np|95{OsAYd-v{LzkdD9nKSz??>>6;=-$11 zckbS?b?erd2Pe%qFmcNMp1wV8t5>g{yKz?Y&g!=94M0olwv?1@$*tI!SF%16XnxkJ z#Ke^msY_#kCI>BckDnJ7Jv-Qcz6;P6pxZpA*#%DUbedx2-{&6Q5#-bD64>tT-Q?!j zVC7Zg;#gyCn{Ns9GQ{yfHwy*v^7(Q(#^&D!hLT!IkY6x^prDeHlCg`6OX$p*t5&Vr z4Fy0qpScSJ@4z7KuiFfu4$cCP$YKTtt`8v0=(NTJB&bm08c`CQpH@>dp-(#e5&_G##+a;mX9)y4_8Ugt6#>+uyb2?=E0CXHUAmcWhHw}2-@+< z{eYf0Lqo-VhIM5-Th`Cs#5MbJ$LiQmKPx5u_9ydf|2(~2type = 'e'; + $this->name = __('Flat file export'); + $this->description = __('Exports a blog or a full Dotclear installation to flat file.'); + } + + public function process($do) + { + # Export a blog + if ($do == 'export_blog' && $this->core->auth->check('admin',$this->core->blog->id)) + { + $fullname = $this->core->blog->public_path.'/.backup_'.sha1(uniqid()); + $blog_id = $this->core->con->escape($this->core->blog->id); + + try + { + $exp = new dbExport($this->core->con,$fullname,$this->core->prefix); + fwrite($exp->fp,'///DOTCLEAR|'.DC_VERSION."|single\n"); + + $exp->export('category', + 'SELECT * FROM '.$this->core->prefix.'category '. + "WHERE blog_id = '".$blog_id."'" + ); + $exp->export('link', + 'SELECT * FROM '.$this->core->prefix.'link '. + "WHERE blog_id = '".$blog_id."'" + ); + $exp->export('setting', + 'SELECT * FROM '.$this->core->prefix.'setting '. + "WHERE blog_id = '".$blog_id."'" + ); + $exp->export('post', + 'SELECT * FROM '.$this->core->prefix.'post '. + "WHERE blog_id = '".$blog_id."'" + ); + $exp->export('media', + 'SELECT * FROM '.$this->core->prefix."media WHERE media_path = '". + $this->core->con->escape($this->core->blog->settings->public_path)."'" + ); + $exp->export('post_media', + 'SELECT media_id, M.post_id '. + 'FROM '.$this->core->prefix.'post_media M, '.$this->core->prefix.'post P '. + 'WHERE P.post_id = M.post_id '. + "AND P.blog_id = '".$blog_id."'" + ); + $exp->export('ping', + 'SELECT ping.post_id, ping_url, ping_dt '. + 'FROM '.$this->core->prefix.'ping ping, '.$this->core->prefix.'post P '. + 'WHERE P.post_id = ping.post_id '. + "AND P.blog_id = '".$blog_id."'" + ); + $exp->export('comment', + 'SELECT C.* '. + 'FROM '.$this->core->prefix.'comment C, '.$this->core->prefix.'post P '. + 'WHERE P.post_id = C.post_id '. + "AND P.blog_id = '".$blog_id."'" + ); + + # --BEHAVIOR-- exportSingle + $this->core->callBehavior('exportSingle',$this->core,$exp,$blog_id); + + $_SESSION['export_file'] = $fullname; + $_SESSION['export_filename'] = $_POST['file_name']; + http::redirect($this->getURL().'&do=ok'); + } + catch (Exception $e) + { + @unlink($fullname); + throw $e; + } + } + + # Export all content + if ($do == 'export_all' && $this->core->auth->isSuperAdmin()) + { + $fullname = $this->core->blog->public_path.'/.backup_'.sha1(uniqid()); + try + { + $exp = new dbExport($this->core->con,$fullname,$this->core->prefix); + fwrite($exp->fp,'///DOTCLEAR|'.DC_VERSION."|full\n"); + $exp->exportTable('blog'); + $exp->exportTable('category'); + $exp->exportTable('link'); + $exp->exportTable('setting'); + $exp->exportTable('user'); + $exp->exportTable('permissions'); + $exp->exportTable('post'); + $exp->exportTable('media'); + $exp->exportTable('post_media'); + $exp->exportTable('log'); + $exp->exportTable('ping'); + $exp->exportTable('comment'); + $exp->exportTable('spamrule'); + $exp->exportTable('version'); + + # --BEHAVIOR-- exportFull + $this->core->callBehavior('exportFull',$this->core,$exp); + + $_SESSION['export_file'] = $fullname; + $_SESSION['export_filename'] = $_POST['file_name']; + http::redirect($this->getURL().'&do=ok'); + } + catch (Exception $e) + { + @unlink($fullname); + throw $e; + } + } + + # Send file content + if ($do == 'ok') + { + if (!file_exists($_SESSION['export_file'])) { + throw new Exception(__('Export file not found.')); + } + + ob_end_clean(); + header('Content-Disposition: attachment;filename='.$_SESSION['export_filename']); + header('Content-Type: text/plain; charset=UTF-8'); + readfile($_SESSION['export_file']); + unlink($_SESSION['export_file']); + unset($_SESSION['export_file']); + unset($_SESSION['export_filename']); + exit; + } + } + + public function gui() + { + echo + '
    '. + '
    '.__('Export a blog').''. + '

    '.sprintf(__('This will create an export of your current blog: %s'), + ''.html::escapeHTML($this->core->blog->name).'').'

    '. + '

    '. + '

    '. + form::hidden(array('do'),'export_blog'). + $this->core->formNonce().'

    '. + '

    '. + __('You may also want to download your media directory as a zip file').'

    '. + '
    '; + + if ($this->core->auth->isSuperAdmin()) + { + echo + '
    '. + '
    '.__('Export all content').''. + '

    '. + ''. + form::hidden(array('do'),'export_all'). + $this->core->formNonce().'

    '. + '
    '; + } + } +} +?> \ No newline at end of file diff --git a/plugins/importExport/inc/class.dc.ieModule.php b/plugins/importExport/inc/class.dc.ieModule.php new file mode 100644 index 0000000..2e23c38 --- /dev/null +++ b/plugins/importExport/inc/class.dc.ieModule.php @@ -0,0 +1,89 @@ +core =& $core; + $this->setInfo(); + + $this->id = get_class($this); + if (!$this->type) { + throw new Exception('No type for module'.$this->id); + } + + $this->url = 'plugin.php?p=importExport&t='.$this->type.'&f='.$this->id; + + if (!$this->name) { + $this->name = get_class($this); + } + } + + public function init() + { + } + + protected function setInfo() + { + } + + final public function getURL($escape=false) + { + if ($escape) { + return html::escapeHTML($this->url); + } + return $this->url; + } + + public function process($do) + { + } + + public function gui() + { + } + + protected function progressBar($percent) + { + $percent = ceil($percent); + if ($percent > 100) { + $percent = 100; + } + return '
    '.$percent.' %
    '; + } + + protected function autoSubmit() + { + return form::hidden(array('autosubmit'),1); + } + + protected function congratMessage() + { + return + '

    '.__('Congratulation!').'

    '. + '

    '.__('Your blog has been successfully imported. Welcome on Dotclear 2!').'

    '. + ''; + } +} +?> \ No newline at end of file diff --git a/plugins/importExport/inc/class.dc.import.dc1.php b/plugins/importExport/inc/class.dc.import.dc1.php new file mode 100644 index 0000000..9944a6a --- /dev/null +++ b/plugins/importExport/inc/class.dc.import.dc1.php @@ -0,0 +1,627 @@ + '', + 'db_name' => '', + 'db_user' => '', + 'db_pwd' => '', + 'db_prefix' => 'dc_', + 'post_limit' => 20, + 'cat_ids' => array() + ); + + protected function setInfo() + { + $this->type = 'i'; + $this->name = __('Dotclear 1.2 import'); + $this->description = __('Import a Dotclear 1.2 installation into your current blog.'); + } + + public function init() + { + $this->con =& $this->core->con; + $this->prefix = $this->core->prefix; + $this->blog_id = $this->core->blog->id; + + if (!isset($_SESSION['dc1_import_vars'])) { + $_SESSION['dc1_import_vars'] = $this->base_vars; + } + $this->vars =& $_SESSION['dc1_import_vars']; + + if ($this->vars['post_limit'] > 0) { + $this->post_limit = $this->vars['post_limit']; + } + } + + public function resetVars() + { + $this->vars = $this->base_vars;; + unset($_SESSION['dc1_import_vars']); + } + + public function process($do) + { + $this->action = $do; + } + + # We handle process in another way to always display something to + # user + protected function guiprocess($do) + { + switch ($do) + { + case 'step1': + $this->vars['db_host'] = $_POST['db_host']; + $this->vars['db_name'] = $_POST['db_name']; + $this->vars['db_user'] = $_POST['db_user']; + $this->vars['db_pwd'] = $_POST['db_pwd']; + $this->vars['post_limit'] = abs((integer) $_POST['post_limit']) > 0 ? $_POST['post_limit'] : 0; + $this->vars['db_prefix'] = $_POST['db_prefix']; + $db = $this->db(); + $db->close(); + $this->step = 2; + echo $this->progressBar(1); + break; + case 'step2': + $this->step = 2; + $this->importUsers(); + $this->step = 3; + echo $this->progressBar(3); + break; + case 'step3': + $this->step = 3; + $this->importCategories(); + if ($this->core->plugins->moduleExists('blogroll')) { + $this->step = 4; + echo $this->progressBar(5); + } else { + $this->step = 5; + echo $this->progressBar(7); + } + break; + case 'step4': + $this->step = 4; + $this->importLinks(); + $this->step = 5; + echo $this->progressBar(7); + break; + case 'step5': + $this->step = 5; + $this->post_offset = !empty($_REQUEST['offset']) ? abs((integer) $_REQUEST['offset']) : 0; + if ($this->importPosts($percent) === -1) { + http::redirect($this->getURL().'&do=ok'); + } else { + echo $this->progressBar(ceil($percent*0.93)+7); + } + break; + case 'ok': + $this->resetVars(); + $this->core->blog->triggerBlog(); + $this->step = 6; + echo $this->progressBar(100); + break; + } + } + + public function gui() + { + try { + $this->guiprocess($this->action); + } catch (Exception $e) { + $this->error($e); + } + + switch ($this->step) + { + case 1: + echo + '

    '.sprintf(__('This will import your Dotclear 1.2 content as new content in the current blog: %s.'), + ''.html::escapeHTML($this->core->blog->name).'').'

    '. + '

    '.__('Please note that this process '. + 'will empty your categories, blogroll, entries and comments on the current blog.').'

    '. + '

    '.__('Depending on the size of your blog, it could take a few minutes.').'

    '; + + printf($this->imForm(1,__('General information'),__('Import my blog now')), + '

    '.__('We first need some information about your old Dotclear 1.2 installation.').'

    '. + '

    '. + '

    '. + '

    '. + '

    '. + '

    '. + '

    '.__('Entries import options').'

    '. + '

    ' + ); + break; + case 2: + printf($this->imForm(2,__('Importing users')), + $this->autoSubmit() + ); + break; + case 3: + printf($this->imForm(3,__('Importing categories')), + $this->autoSubmit() + ); + break; + case 4: + printf($this->imForm(4,__('Importing blogroll')), + $this->autoSubmit() + ); + break; + case 5: + $t = sprintf(__('Importing entries from %d to %d / %d'),$this->post_offset, + min(array($this->post_offset+$this->post_limit,$this->post_count)),$this->post_count); + printf($this->imForm(5,$t), + form::hidden(array('offset'),$this->post_offset). + $this->autoSubmit() + ); + break; + case 6: + echo + '

    '.__('Please read carefully').'

    '. + '
      '. + '
    • '.__('Every newly imported user has received a random password '. + 'and will need to ask for a new one by following the "I forgot my password" link on the login page '. + '(Their registered email address has to be valid.)').'
    • '. + + '
    • '.sprintf(__('Please note that Dotclear 2 has a new URL layout. You can avoid broken '. + 'links by installing DC1 redirect plugin and activate it in your blog configuration.'), + 'http://www.dotclear.org/extensions').'
    • '. + '
    '. + + $this->congratMessage(); + + break; + } + } + + # Simple form for step by step process + protected function imForm($step,$legend,$submit_value=null) + { + if (!$submit_value) { + $submit_value = __('next step').' >'; + } + + return + '
    '. + '
    '.$legend.''. + $this->core->formNonce(). + form::hidden(array('do'),'step'.$step). + '%s'. + '

    '. + '
    '. + '
    '; + } + + # Error display + protected function error($e) + { + echo '
    '.__('Errors:').''. + '

    '.$e->getMessage().'

    '; + } + + # Database init + protected function db() + { + $db = dbLayer::init('mysql',$this->vars['db_host'],$this->vars['db_name'],$this->vars['db_user'],$this->vars['db_pwd']); + + $rs = $db->select("SHOW TABLES LIKE '".$this->vars['db_prefix']."%'"); + if ($rs->isEmpty()) { + throw new Exception(__('Dotclear tables not found')); + } + + while ($rs->fetch()) { + $this->has_table[$rs->f(0)] = true; + } + + # Set this to read data as they were written in Dotclear 1 + try { + $db->execute('SET NAMES DEFAULT'); + } catch (Exception $e) {} + + $db->execute('SET CHARACTER SET DEFAULT'); + $db->execute("SET COLLATION_CONNECTION = DEFAULT"); + $db->execute("SET COLLATION_SERVER = DEFAULT"); + $db->execute("SET CHARACTER_SET_SERVER = DEFAULT"); + $db->execute("SET CHARACTER_SET_DATABASE = DEFAULT"); + + $this->post_count = $db->select( + 'SELECT COUNT(post_id) FROM '.$this->vars['db_prefix'].'post ' + )->f(0); + + return $db; + } + + protected function cleanStr($str) + { + return text::cleanUTF8(@text::toUTF8($str)); + } + + # Users import + protected function importUsers() + { + $db = $this->db(); + $prefix = $this->vars['db_prefix']; + $rs = $db->select('SELECT * FROM '.$prefix.'user'); + + try + { + $this->con->begin(); + + while ($rs->fetch()) + { + if (!$this->core->userExists($rs->user_id)) + { + $cur = $this->con->openCursor($this->prefix.'user'); + $cur->user_id = $rs->user_id; + $cur->user_name = $rs->user_nom; + $cur->user_firstname = $rs->user_prenom; + $cur->user_displayname = $rs->user_pseudo; + $cur->user_pwd = crypt::createPassword(); + $cur->user_email = $rs->user_email; + $cur->user_lang = $rs->user_lang; + $cur->user_tz = $this->core->blog->settings->blog_timezone; + $cur->user_post_status = $rs->user_post_pub ? 1 : -2; + $cur->user_options = new ArrayObject(array( + 'edit_size' => (integer) $rs->user_edit_size, + 'post_format' => $rs->user_post_format + )); + + $permissions = array(); + switch ($rs->user_level) + { + case '0': + $cur->user_status = 0; + break; + case '1': # editor + $permissions['usage'] = true; + break; + case '5': # advanced editor + $permissions['contentadmin'] = true; + $permissions['categories'] = true; + $permissions['media_admin'] = true; + break; + case '9': # admin + $permissions['admin'] = true; + break; + } + + $this->core->addUser($cur); + $this->core->setUserBlogPermissions( + $rs->user_id, + $this->blog_id, + $permissions + ); + } + } + + $this->con->commit(); + $db->close(); + } + catch (Exception $e) + { + $this->con->rollback(); + $db->close(); + throw $e; + } + } + + # Categories import + protected function importCategories() + { + $db = $this->db(); + $prefix = $this->vars['db_prefix']; + $rs = $db->select('SELECT * FROM '.$prefix.'categorie ORDER BY cat_ord ASC'); + + try + { + $this->con->execute( + 'DELETE FROM '.$this->prefix.'category '. + "WHERE blog_id = '".$this->con->escape($this->blog_id)."' " + ); + + $ord = 2; + while ($rs->fetch()) + { + $cur = $this->con->openCursor($this->prefix.'category'); + $cur->blog_id = $this->blog_id; + $cur->cat_title = $this->cleanStr($rs->cat_libelle); + $cur->cat_desc = $this->cleanStr($rs->cat_desc); + $cur->cat_url = $this->cleanStr($rs->cat_libelle_url); + $cur->cat_lft = $ord++; + $cur->cat_rgt = $ord++; + + $cur->cat_id = $this->con->select( + 'SELECT MAX(cat_id) FROM '.$this->prefix.'category' + )->f(0) + 1; + $this->vars['cat_ids'][$rs->cat_id] = $cur->cat_id; + $cur->insert(); + } + + $db->close(); + } + catch (Exception $e) + { + $db->close(); + throw $e; + } + } + + # Blogroll import + protected function importLinks() + { + $db = $this->db(); + $prefix = $this->vars['db_prefix']; + $rs = $db->select('SELECT * FROM '.$prefix.'link ORDER BY link_id ASC'); + + try + { + $this->con->execute( + 'DELETE FROM '.$this->prefix.'link '. + "WHERE blog_id = '".$this->con->escape($this->blog_id)."' " + ); + + while ($rs->fetch()) + { + $cur = $this->con->openCursor($this->prefix.'link'); + $cur->blog_id = $this->blog_id; + $cur->link_href = $this->cleanStr($rs->href); + $cur->link_title = $this->cleanStr($rs->label); + $cur->link_desc = $this->cleanStr($rs->title); + $cur->link_lang = $this->cleanStr($rs->lang); + $cur->link_xfn = $this->cleanStr($rs->rel); + $cur->link_position = (integer) $rs->position; + + $cur->link_id = $this->con->select( + 'SELECT MAX(link_id) FROM '.$this->prefix.'link' + )->f(0) + 1; + $cur->insert(); + } + + $db->close(); + } + catch (Exception $e) + { + $db->close(); + throw $e; + } + } + + # Entries import + protected function importPosts(&$percent) + { + $db = $this->db(); + $prefix = $this->vars['db_prefix']; + + $count = $db->select('SELECT COUNT(post_id) FROM '.$prefix.'post')->f(0); + + $rs = $db->select( + 'SELECT * FROM '.$prefix.'post ORDER BY post_id ASC '. + $db->limit($this->post_offset,$this->post_limit) + ); + + try + { + if ($this->post_offset == 0) + { + $this->con->execute( + 'DELETE FROM '.$this->prefix.'post '. + "WHERE blog_id = '".$this->con->escape($this->blog_id)."' " + ); + } + + while ($rs->fetch()) { + $this->importPost($rs,$db); + } + + $db->close(); + } + catch (Exception $e) + { + $db->close(); + throw $e; + } + + if ($rs->count() < $this->post_limit) { + return -1; + } else { + $this->post_offset += $this->post_limit; + } + + if ($this->post_offset > $this->post_count) { + $percent = 100; + } else { + $percent = $this->post_offset * 100 / $this->post_count; + } + } + + protected function importPost(&$rs,&$db) + { + $cur = $this->con->openCursor($this->prefix.'post'); + $cur->blog_id = $this->blog_id; + $cur->user_id = $rs->user_id; + $cur->cat_id = (integer) $this->vars['cat_ids'][$rs->cat_id]; + $cur->post_dt = $rs->post_dt; + $cur->post_creadt = $rs->post_creadt; + $cur->post_upddt = $rs->post_upddt; + $cur->post_title = html::decodeEntities($this->cleanStr($rs->post_titre)); + + $cur->post_url = date('Y/m/d/',strtotime($cur->post_dt)).$rs->post_id.'-'.$rs->post_titre_url; + $cur->post_url = substr($cur->post_url,0,255); + + $cur->post_format = $rs->post_content_wiki == '' ? 'xhtml' : 'wiki'; + $cur->post_content_xhtml = $this->cleanStr($rs->post_content); + $cur->post_excerpt_xhtml = $this->cleanStr($rs->post_chapo); + + if ($cur->post_format == 'wiki') { + $cur->post_content = $this->cleanStr($rs->post_content_wiki); + $cur->post_excerpt = $this->cleanStr($rs->post_chapo_wiki); + } else { + $cur->post_content = $this->cleanStr($rs->post_content); + $cur->post_excerpt = $this->cleanStr($rs->post_chapo); + } + + $cur->post_notes = $this->cleanStr($rs->post_notes); + $cur->post_status = (integer) $rs->post_pub; + $cur->post_selected = (integer) $rs->post_selected; + $cur->post_open_comment = (integer) $rs->post_open_comment; + $cur->post_open_tb = (integer) $rs->post_open_tb; + $cur->post_lang = $rs->post_lang; + + $cur->post_words = implode(' ',text::splitWords( + $cur->post_title.' '. + $cur->post_excerpt_xhtml.' '. + $cur->post_content_xhtml + )); + + $cur->post_id = $this->con->select( + 'SELECT MAX(post_id) FROM '.$this->prefix.'post' + )->f(0) + 1; + + $cur->insert(); + $this->importComments($rs->post_id,$cur->post_id,$db); + $this->importPings($rs->post_id,$cur->post_id,$db); + + # Load meta if we have some in DC1 and metadata plugin in DC2 + if (isset($this->has_table[$this->prefix.'post_meta']) && class_exists('dcMeta')) { + $this->importMeta($rs->post_id,$cur->post_id,$db); + } + } + + # Comments import + protected function importComments($post_id,$new_post_id,&$db) + { + $count_c = $count_t = 0; + + $rs = $db->select( + 'SELECT * FROM '.$this->vars['db_prefix'].'comment '. + 'WHERE post_id = '.(integer) $post_id.' ' + ); + + while ($rs->fetch()) + { + $cur = $this->con->openCursor($this->prefix.'comment'); + $cur->post_id = (integer) $new_post_id; + $cur->comment_author = $this->cleanStr($rs->comment_auteur); + $cur->comment_status = (integer) $rs->comment_pub; + $cur->comment_dt = $rs->comment_dt; + $cur->comment_upddt = $rs->comment_upddt; + $cur->comment_email = $this->cleanStr($rs->comment_email); + $cur->comment_content = $this->cleanStr($rs->comment_content); + $cur->comment_ip = $rs->comment_ip; + $cur->comment_trackback = (integer) $rs->comment_trackback; + + $cur->comment_site = $this->cleanStr($rs->comment_site); + if ($cur->comment_site != '' && !preg_match('!^http://.*$!',$cur->comment_site)) { + $cur->comment_site = substr('http://'.$cur->comment_site,0,255); + } + + if ($rs->exists('spam') && $rs->spam && $rs->comment_status = 0) { + $cur->comment_status = -2; + } + + $cur->comment_words = implode(' ',text::splitWords($cur->comment_content)); + + $cur->comment_id = $this->con->select( + 'SELECT MAX(comment_id) FROM '.$this->prefix.'comment' + )->f(0) + 1; + + $cur->insert(); + + if ($cur->comment_trackback && $cur->comment_status == 1) { + $count_t++; + } elseif ($cur->comment_status == 1) { + $count_c++; + } + } + + if ($count_t > 0 || $count_c > 0) + { + $this->con->execute( + 'UPDATE '.$this->prefix.'post SET '. + 'nb_comment = '.$count_c.', '. + 'nb_trackback = '.$count_t.' '. + 'WHERE post_id = '.(integer) $new_post_id.' ' + ); + } + } + + # Pings import + protected function importPings($post_id,$new_post_id,&$db) + { + $urls = array(); + + $rs = $db->select( + 'SELECT * FROM '.$this->vars['db_prefix'].'ping '. + 'WHERE post_id = '.(integer) $post_id + ); + + while ($rs->fetch()) + { + $url = $this->cleanStr($rs->ping_url); + if (isset($urls[$url])) { + continue; + } + + $cur = $this->con->openCursor($this->prefix.'ping'); + $cur->post_id = (integer) $new_post_id; + $cur->ping_url = $url; + $cur->ping_dt = $rs->ping_dt; + $cur->insert(); + + $urls[$url] = true; + } + } + + # Meta import + protected function importMeta($post_id,$new_post_id,&$db) + { + $rs = $db->select( + 'SELECT * FROM '.$this->vars['db_prefix'].'post_meta '. + 'WHERE post_id = '.(integer) $post_id.' '. + "AND meta_key = 'tag' " + ); + + if ($rs->isEmpty()) { + return; + } + + $meta = new dcMeta($this->core); + while ($rs->fetch()) { + $meta->setPostMeta($new_post_id,'tag',$this->cleanStr($rs->meta_value)); + } + } +} +?> \ No newline at end of file diff --git a/plugins/importExport/inc/class.dc.import.feed.php b/plugins/importExport/inc/class.dc.import.feed.php new file mode 100644 index 0000000..7042e38 --- /dev/null +++ b/plugins/importExport/inc/class.dc.import.feed.php @@ -0,0 +1,105 @@ +type = 'i'; + $this->name = __('Feed import'); + $this->description = __('Imports a feed as new entries.'); + } + + public function process($do) + { + if ($do == 'ok') { + $this->status = true; + return; + } + + if (empty($_POST['feed_url'])) { + return; + } + + $this->feed_url = $_POST['feed_url']; + + $feed = feedReader::quickParse($this->feed_url); + if ($feed === false) { + throw new Exception(__('Cannot retrieve feed URL.')); + } + if (count($feed->items) == 0) { + throw new Exception(__('No items in feed.')); + } + + if ($this->core->plugins->moduleExists('metadata')) { + $meta = new dcMeta($this->core); + } + + $cur = $this->core->con->openCursor($this->core->prefix.'post'); + $this->core->con->begin(); + foreach ($feed->items as $item) + { + $cur->clean(); + $cur->user_id = $this->core->auth->userID(); + $cur->post_content = $item->content ? $item->content : $item->description; + $cur->post_title = $item->title ? $item->title : text::cutString(html::clean($cur->post_content),60); + $cur->post_format = 'xhtml'; + $cur->post_status = -2; + $cur->post_dt = strftime('%Y-%m-%d %H:%M:%S',$item->TS); + + try { + $post_id = $this->core->blog->addPost($cur); + } catch (Exception $e) { + $this->core->con->rollback(); + throw $e; + } + + if (isset($meta)) + { + foreach ($item->subject as $subject) { + $meta->setPostMeta($post_id,'tag',dcMeta::sanitizeMetaID($subject)); + } + } + } + + $this->core->con->commit(); + http::redirect($this->getURL().'&do=ok'); + + } + + public function gui() + { + if ($this->status) { + echo '

    '.__('Content successfully imported.').'

    '; + } + + echo + '

    '.__('Import from a feed').'

    '. + '

    '.sprintf(__('This will import a feed (RSS or Atom) a as new content in the current blog: %s.'), + ''.html::escapeHTML($this->core->blog->name).'').'

    '. + '
    '. + + '
    '. + $this->core->formNonce(). + form::hidden(array('do'),1). + '

    '. + '

    '. + '
    '. + '
    '; + } +} +?> \ No newline at end of file diff --git a/plugins/importExport/inc/class.dc.import.flat.php b/plugins/importExport/inc/class.dc.import.flat.php new file mode 100644 index 0000000..d512345 --- /dev/null +++ b/plugins/importExport/inc/class.dc.import.flat.php @@ -0,0 +1,238 @@ +type = 'i'; + $this->name = __('Flat file import'); + $this->description = __('Imports a blog or a full Dotclear installation from flat file.'); + } + + public function process($do) + { + if ($do == 'single' || $do == 'full') { + $this->status = $do; + return; + } + + $to_unlink = false; + + # Single blog import + $files = $this->getPublicFiles(); + $single_upl = null; + if (!empty($_POST['public_single_file']) && in_array($_POST['public_single_file'],$files)) { + $single_upl = false; + } elseif (!empty($_FILES['up_single_file'])) { + $single_upl = true; + } + + if ($single_upl !== null) + { + if ($single_upl) { + files::uploadStatus($_FILES['up_single_file']); + $file = DC_TPL_CACHE.'/'.md5(uniqid()); + if (!move_uploaded_file($_FILES['up_single_file']['tmp_name'],$file)) { + throw new Exception(__('Unable to move uploaded file.')); + } + $to_unlink = true; + } else { + $file = $_POST['public_single_file']; + } + + try { + $bk = new dcImport($this->core,$file); + $bk->importSingle(); + } catch (Exception $e) { + if ($to_unlink) { + @unlink($file); + } + throw $e; + } + if ($to_unlink) { + @unlink($file); + } + http::redirect($this->getURL().'&do=single'); + } + + # Full import + $full_upl = null; + if (!empty($_POST['public_full_file']) && in_array($_POST['public_full_file'],$files)) { + $full_upl = false; + } elseif (!empty($_FILES['up_full_file'])) { + $full_upl = true; + } + + if ($full_upl !== null && $this->core->auth->isSuperAdmin()) + { + if (empty($_POST['your_pwd']) || !$this->core->auth->checkPassword(crypt::hmac(DC_MASTER_KEY,$_POST['your_pwd']))) { + throw new Exception(__('Password verification failed')); + } + + if ($full_upl) { + files::uploadStatus($_FILES['up_full_file']); + $file = DC_TPL_CACHE.'/'.md5(uniqid()); + if (!move_uploaded_file($_FILES['up_full_file']['tmp_name'],$file)) { + throw new Exception(__('Unable to move uploaded file.')); + } + $to_unlink = true; + } else { + $file = $_POST['public_full_file']; + } + + try { + $bk = new dcImport($this->core,$file); + $bk->importFull(); + } catch (Exception $e) { + if ($to_unlink) { + @unlink($file); + } + throw $e; + } + if ($to_unlink) { + @unlink($file); + } + http::redirect($this->getURL().'&do=full'); + } + + header('content-type:text/plain'); + var_dump($_POST); + exit; + + $this->status = true; + } + + public function gui() + { + if ($this->status == 'single') + { + echo '

    '.__('Single blog successfully imported.').'

    '; + return; + } + if ($this->status == 'full') + { + echo '

    '.__('Content successfully imported.').'

    '; + return; + } + + echo + '\n"; + + echo + '

    '.__('Import a single blog').'

    '. + '

    '.sprintf(__('This will import a single blog backup as new content in the current blog: %s.'), + ''.html::escapeHTML($this->core->blog->name).'').'

    '. + '
    '. + + '
    '. + $this->core->formNonce(). + form::hidden(array('do'),1). + form::hidden(array('MAX_FILE_SIZE'),DC_MAX_UPLOAD_SIZE). + '

    '; + + $public_files = $this->getPublicFiles(); + + $empty = empty($public_files); + $public_files = array_merge(array('-' => ''),$public_files); + echo + '

    '; + + echo + '

    '. + '
    '. + '
    '; + + if ($this->core->auth->isSuperAdmin()) + { + echo + '

    '.__('Import a full backup file').'

    '. + '
    '. + '
    '.form::hidden(array('MAX_FILE_SIZE'),DC_MAX_UPLOAD_SIZE).'
    '. + + '
    '. + $this->core->formNonce(). + form::hidden(array('do'),1). + form::hidden(array('MAX_FILE_SIZE'),DC_MAX_UPLOAD_SIZE). + '

    '; + + echo + '

    '; + + echo + '

    '.__('Warning: This will reset all the content of your database, except users.').'

    '. + + '

    '. + + '

    '. + '
    '. + '
    '; + } + } + + protected function getPublicFiles() + { + $public_files = array(); + $dir = @dir($this->core->blog->public_path); + if ($dir) + { + while (($entry = $dir->read()) !== false) { + $entry_path = $dir->path.'/'.$entry; + + if (is_file($entry_path) && is_readable($entry_path)) + { + $fp = fopen($entry_path,'rb'); + if (strpos(fgets($fp),'///DOTCLEAR|') === 0) { + $public_files[$entry] = $entry_path; + } + fclose($fp); + } + } + } + return $public_files; + } +} +?> \ No newline at end of file diff --git a/plugins/importExport/inc/class.dc.import.wp.php b/plugins/importExport/inc/class.dc.import.wp.php new file mode 100644 index 0000000..cca5408 --- /dev/null +++ b/plugins/importExport/inc/class.dc.import.wp.php @@ -0,0 +1,786 @@ + '', + 'db_name' => '', + 'db_user' => '', + 'db_pwd' => '', + 'db_prefix' => 'wp_', + 'ignore_first_cat' => 1, + 'cat_import' => 1, + 'cat_as_tags' => '', + 'cat_tags_prefix' => 'cat: ', + 'post_limit' => 20, + 'post_formater' => 'xhtml', + 'comment_formater' => 'xhtml', + 'user_ids' => array(), + 'cat_ids' => array(), + 'permalink_template' => 'p=%post_id%', + 'permalink_tags' => array( + '%year%', + '%monthnum%', + '%day%', + '%hour%', + '%minute%', + '%second%', + '%postname%', + '%post_id%', + '%category%', + '%author%' + ) + ); + protected $formaters; + + protected function setInfo() + { + $this->type = 'i'; + $this->name = __('WordPress import'); + $this->description = __('Import a WordPress installation into your current blog.'); + } + + public function init() + { + $this->con =& $this->core->con; + $this->prefix = $this->core->prefix; + $this->blog_id = $this->core->blog->id; + + if (!isset($_SESSION['wp_import_vars'])) { + $_SESSION['wp_import_vars'] = $this->base_vars; + } + $this->vars =& $_SESSION['wp_import_vars']; + + if ($this->vars['post_limit'] > 0) { + $this->post_limit = $this->vars['post_limit']; + } + + foreach ($this->core->getFormaters() as $v) { + $this->formaters[$v] = $v; + } + } + + public function resetVars() + { + $this->vars = $this->base_vars;; + unset($_SESSION['wp_import_vars']); + } + + public function process($do) + { + $this->action = $do; + } + + # We handle process in another way to always display something to + # user + protected function guiprocess($do) + { + switch ($do) + { + case 'step1': + $this->vars['db_host'] = $_POST['db_host']; + $this->vars['db_name'] = $_POST['db_name']; + $this->vars['db_user'] = $_POST['db_user']; + $this->vars['db_pwd'] = $_POST['db_pwd']; + $this->vars['db_prefix'] = $_POST['db_prefix']; + $this->vars['ignore_first_cat'] = isset($_POST['ignore_first_cat']); + $this->vars['cat_import'] = isset($_POST['cat_import']); + $this->vars['cat_as_tags'] = isset($_POST['cat_as_tags']); + $this->vars['cat_tags_prefix'] = $_POST['cat_tags_prefix']; + $this->vars['post_limit'] = abs((integer) $_POST['post_limit']) > 0 ? $_POST['post_limit'] : 0; + $this->vars['post_formater'] = isset($this->formaters[$_POST['post_formater']]) ? $_POST['post_formater'] : 'xhtml'; + $this->vars['comment_formater'] = isset($this->formaters[$_POST['comment_formater']]) ? $_POST['comment_formater'] : 'xhtml'; + $db = $this->db(); + $db->close(); + $this->step = 2; + echo $this->progressBar(1); + break; + case 'step2': + $this->step = 2; + $this->importUsers(); + $this->step = 3; + echo $this->progressBar(3); + break; + case 'step3': + $this->step = 3; + $this->importCategories(); + if ($this->core->plugins->moduleExists('blogroll')) { + $this->step = 4; + echo $this->progressBar(5); + } else { + $this->step = 5; + echo $this->progressBar(7); + } + break; + case 'step4': + $this->step = 4; + $this->importLinks(); + $this->step = 5; + echo $this->progressBar(7); + break; + case 'step5': + $this->step = 5; + $this->post_offset = !empty($_REQUEST['offset']) ? abs((integer) $_REQUEST['offset']) : 0; + if ($this->importPosts($percent) === -1) { + http::redirect($this->getURL().'&do=ok'); + } else { + echo $this->progressBar(ceil($percent*0.93)+7); + } + break; + case 'ok': + $this->resetVars(); + $this->core->blog->triggerBlog(); + $this->step = 6; + echo $this->progressBar(100); + break; + } + } + + public function gui() + { + try { + $this->guiprocess($this->action); + } catch (Exception $e) { + $this->error($e); + } + + switch ($this->step) + { + case 1: + echo + '

    '.sprintf(__('This will import your WordPress content as new content in the current blog: %s.'), + ''.html::escapeHTML($this->core->blog->name).'').'

    '. + '

    '.__('Please note that this process '. + 'will empty your categories, blogroll, entries and comments on the current blog.').'

    '. + '

    '.__('Depending on the size of your blog, it could take a few minutes.').'

    '; + + printf($this->imForm(1,__('General information'),__('Import my blog now')), + '

    '.__('We first need some information about your old WordPress installation.').'

    '. + '

    '. + '

    '. + '

    '. + '

    '. + '

    '. + '

    '.__('Entries import options').'

    '. + '

    '.__('WordPress and Dotclear\'s handling of categories are quite different. '. + 'You can assign several categories to a single post in WordPress. In the Dotclear world, '. + 'we see it more like "One category, several tags." Therefore Dotclear can only import one '. + 'category per post and will chose the lowest numbered one. If you want to keep a trace of '. + 'every category, you can import them as tags, with an optional prefix.').'

    '. + '

    '.__('On the other hand, in WordPress, a post can not be uncategorized, and a default '. + 'installation has a first category labelised "Uncategorized". If you did not change that '. + 'category, you can just ignore it while importing your blog, as Dotclear allows you to '. + 'actually keep your posts uncategorized.').'

    '. + '

    '. + '

    '. + '

    '. + '

    '. + '

    '. + + '

    '.__('Content filters').'

    '. + '

    '.__('You may want to process your post and/or comment content with the following filters.').'

    '. + '

    '. + '

    ' + ); + break; + case 2: + printf($this->imForm(2,__('Importing users')), + $this->autoSubmit() + ); + break; + case 3: + printf($this->imForm(3,__('Importing categories')), + $this->autoSubmit() + ); + break; + case 4: + printf($this->imForm(4,__('Importing blogroll')), + $this->autoSubmit() + ); + break; + case 5: + $t = sprintf(__('Importing entries from %d to %d / %d'),$this->post_offset, + min(array($this->post_offset+$this->post_limit,$this->post_count)),$this->post_count); + printf($this->imForm(5,$t), + form::hidden(array('offset'),$this->post_offset). + $this->autoSubmit() + ); + break; + case 6: + echo + '

    '.__('Every newly imported user has received a random password '. + 'and will need to ask for a new one by following the "I forgot my password" link on the login page '. + '(Their registered email address has to be valid.)').'

    '. + $this->congratMessage(); + break; + } + } + + # Simple form for step by step process + protected function imForm($step,$legend,$submit_value=null) + { + if (!$submit_value) { + $submit_value = __('next step').' >'; + } + + return + '
    '. + '
    '.$legend.''. + $this->core->formNonce(). + form::hidden(array('do'),'step'.$step). + '%s'. + '

    '. + '
    '. + '
    '; + } + + # Error display + protected function error($e) + { + echo '
    '.__('Errors:').''. + '

    '.$e->getMessage().'

    '; + } + + # Database init + protected function db() + { + $db = dbLayer::init('mysql',$this->vars['db_host'],$this->vars['db_name'],$this->vars['db_user'],$this->vars['db_pwd']); + + $rs = $db->select("SHOW TABLES LIKE '".$this->vars['db_prefix']."%'"); + if ($rs->isEmpty()) { + throw new Exception(__('WordPress tables not found')); + } + + while ($rs->fetch()) { + $this->has_table[$rs->f(0)] = true; + } + + # Set this to read data as they were written + try { + $db->execute('SET NAMES DEFAULT'); + } catch (Exception $e) {} + + $db->execute('SET CHARACTER SET DEFAULT'); + $db->execute("SET COLLATION_CONNECTION = DEFAULT"); + $db->execute("SET COLLATION_SERVER = DEFAULT"); + $db->execute("SET CHARACTER_SET_SERVER = DEFAULT"); + $db->execute("SET CHARACTER_SET_DATABASE = DEFAULT"); + + $this->post_count = $db->select( + 'SELECT COUNT(ID) FROM '.$this->vars['db_prefix'].'posts '. + 'WHERE post_type = \'post\' OR post_type = \'page\'' + )->f(0); + + return $db; + } + + protected function cleanStr($str) + { + return text::cleanUTF8(@text::toUTF8($str)); + } + + # Users import + protected function importUsers() + { + $db = $this->db(); + $prefix = $this->vars['db_prefix']; + $rs = $db->select('SELECT * FROM '.$prefix.'users'); + + try + { + $this->con->begin(); + + while ($rs->fetch()) + { + $user_login = preg_replace('/[^A-Za-z0-9@._-]/','-',$rs->user_login); + $this->vars['user_ids'][$rs->ID] = $user_login; + if (!$this->core->userExists($user_login)) + { + $cur = $this->con->openCursor($this->prefix.'user'); + $cur->user_id = $user_login; + $cur->user_pwd = crypt::createPassword(); + $cur->user_displayname = $rs->user_nicename; + $cur->user_email = $rs->user_email; + $cur->user_url = $rs->user_url; + $cur->user_creadt = $rs->user_registered; + $cur->user_lang = $this->core->blog->settings->lang; + $cur->user_tz = $this->core->blog->settings->blog_timezone; + $permissions = array(); + + $rs_meta = $db->select('SELECT * FROM '.$prefix.'usermeta WHERE user_id = '.$rs->ID); + while ($rs_meta->fetch()) + { + switch ($rs_meta->meta_key) + { + case 'first_name': + $cur->user_firstname = $this->cleanStr($rs_meta->meta_value); + break; + case 'last_name': + $cur->user_name = $this->cleanStr($rs_meta->meta_value); + break; + case 'description': + $cur->user_desc = $this->cleanStr($rs_meta->meta_value); + break; + case 'rich_editing': + $cur->user_options = new ArrayObject(array( + 'enable_wysiwyg' => $rs_meta->meta_value == 'true' ? true : false + )); + break; + case 'wp_user_level': + switch ($rs_meta->meta_value) + { + case '0': # Subscriber + $cur->user_status = 0; + break; + case '1': # Contributor + $permissions['usage'] = true; + $permissions['publish'] = true; + $permissions['delete'] = true; + break; + case '2': # Author + case '3': + case '4': + $permissions['contentadmin'] = true; + $permissions['media'] = true; + break; + case '5': # Editor + case '6': + case '7': + $permissions['contentadmin'] = true; + $permissions['categories'] = true; + $permissions['media_admin'] = true; + $permissions['pages'] = true; + $permissions['blogroll'] = true; + break; + case '8': # Administrator + case '9': + case '10': + $permissions['admin'] = true; + break; + } + break; + } + } + $this->core->addUser($cur); + $this->core->setUserBlogPermissions( + $cur->user_id, + $this->blog_id, + $permissions + ); + } + } + $this->con->commit(); + $db->close(); + } + catch (Exception $e) + { + $this->con->rollback(); + $db->close(); + throw $e; + } + } + + # Categories import + protected function importCategories() + { + $db = $this->db(); + $prefix = $this->vars['db_prefix']; + $rs = $db->select( + 'SELECT * FROM '.$prefix.'terms AS t, '.$prefix.'term_taxonomy AS x '. + 'WHERE x.taxonomy = \'category\' '. + 'AND t.term_id = x.term_id '. + ($this->vars['ignore_first_cat'] ? 'AND t.term_id <> 1 ' : ''). + 'ORDER BY t.term_id ASC' + ); + + try + { + $this->con->execute( + 'DELETE FROM '.$this->prefix.'category '. + "WHERE blog_id = '".$this->con->escape($this->blog_id)."' " + ); + + $ord = 2; + while ($rs->fetch()) + { + $cur = $this->con->openCursor($this->prefix.'category'); + $cur->blog_id = $this->blog_id; + $cur->cat_title = $this->cleanStr($rs->name); + $cur->cat_desc = $this->cleanStr($rs->description); + $cur->cat_url = $this->cleanStr($rs->slug); + $cur->cat_lft = $ord++; + $cur->cat_rgt = $ord++; + + $cur->cat_id = $this->con->select( + 'SELECT MAX(cat_id) FROM '.$this->prefix.'category' + )->f(0) + 1; + $this->vars['cat_ids'][$rs->term_id] = $cur->cat_id; + $cur->insert(); + } + + $db->close(); + } + catch (Exception $e) + { + $db->close(); + throw $e; + } + } + + # Blogroll import + protected function importLinks() + { + $db = $this->db(); + $prefix = $this->vars['db_prefix']; + $rs = $db->select('SELECT * FROM '.$prefix.'links ORDER BY link_id ASC'); + + try + { + $this->con->execute( + 'DELETE FROM '.$this->prefix.'link '. + "WHERE blog_id = '".$this->con->escape($this->blog_id)."' " + ); + + while ($rs->fetch()) + { + $cur = $this->con->openCursor($this->prefix.'link'); + $cur->blog_id = $this->blog_id; + $cur->link_href = $this->cleanStr($rs->link_url); + $cur->link_title = $this->cleanStr($rs->link_name); + $cur->link_desc = $this->cleanStr($rs->link_description); + $cur->link_xfn = $this->cleanStr($rs->link_rel); + + $cur->link_id = $this->con->select( + 'SELECT MAX(link_id) FROM '.$this->prefix.'link' + )->f(0) + 1; + $cur->insert(); + } + + $db->close(); + } + catch (Exception $e) + { + $db->close(); + throw $e; + } + } + + # Entries import + protected function importPosts(&$percent) + { + $db = $this->db(); + $prefix = $this->vars['db_prefix']; + + $plink = $db->select( + 'SELECT option_value FROM '.$prefix.'options '. + "WHERE option_name = 'permalink_structure'" + )->option_value; + if ($plink) { + $this->vars['permalink_template'] = substr($plink,1); + } + + $rs = $db->select( + 'SELECT * FROM '.$prefix.'posts '. + 'WHERE post_type = \'post\' OR post_type = \'page\' '. + 'ORDER BY ID ASC '. + $db->limit($this->post_offset,$this->post_limit) + ); + + try + { + if ($this->post_offset == 0) + { + $this->con->execute( + 'DELETE FROM '.$this->prefix.'post '. + "WHERE blog_id = '".$this->con->escape($this->blog_id)."' " + ); + } + + while ($rs->fetch()) { + $this->importPost($rs,$db); + } + + $db->close(); + } + catch (Exception $e) + { + $db->close(); + throw $e; + } + + if ($rs->count() < $this->post_limit) { + return -1; + } else { + $this->post_offset += $this->post_limit; + } + + if ($this->post_offset > $this->post_count) { + $percent = 100; + } else { + $percent = $this->post_offset * 100 / $this->post_count; + } + } + + protected function importPost(&$rs,&$db) + { + $post_date = !@strtotime($rs->post_date) ? '1970-01-01 00:00' : $rs->post_date; + if (!isset($this->vars['user_ids'][$rs->post_author])) { + $user_id = $this->core->auth->userID(); + } else { + $user_id = $this->vars['user_ids'][$rs->post_author]; + } + + $cur = $this->con->openCursor($this->prefix.'post'); + $cur->blog_id = $this->blog_id; + $cur->user_id = $user_id; + $cur->post_dt = $post_date; + $cur->post_creadt = $post_date; + $cur->post_upddt = $rs->post_modified; + $cur->post_title = $this->cleanStr($rs->post_title); + + if (!$cur->post_title) { + $cur->post_title = 'No title'; + } + + if ($this->vars['cat_import'] || $this->vars['cat_as_tags']) + { + $old_cat_ids = $db->select( + 'SELECT * FROM '.$this->vars['db_prefix'].'terms AS t, '. + $this->vars['db_prefix'].'term_taxonomy AS x, '. + $this->vars['db_prefix'].'term_relationships AS r '. + 'WHERE t.term_id = x.term_id '. + ($this->vars['ignore_first_cat'] ? 'AND t.term_id <> 1 ' : ''). + 'AND x.taxonomy = \'category\' '. + 'AND t.term_id = r.term_taxonomy_id '. + 'AND r.object_id ='.$rs->ID. + ' ORDER BY t.term_id ASC ' + ); + if (!$old_cat_ids->isEmpty() && $this->vars['cat_import']) + { + $cur->cat_id = $this->vars['cat_ids'][(integer) $old_cat_ids->term_id]; + } + } + + $permalink_infos = array( + date('Y',strtotime($cur->post_dt)), + date('m',strtotime($cur->post_dt)), + date('d',strtotime($cur->post_dt)), + date('H',strtotime($cur->post_dt)), + date('i',strtotime($cur->post_dt)), + date('s',strtotime($cur->post_dt)), + $rs->post_name, + $rs->ID, + $cur->cat_id, + $cur->user_id + ); + $cur->post_url = str_replace( + $this->vars['permalink_tags'], + $permalink_infos, + $rs->post_type== 'post' ? $this->vars['permalink_template'] : '%postname%' + ); + $cur->post_url = substr($cur->post_url,0,255); + + if (!$cur->post_url) { + $cur->post_url = $rs->ID; + } + + $cur->post_format = $this->vars['post_formater']; + $cur->post_content = $this->cleanStr($rs->post_content); + $cur->post_excerpt = $this->cleanStr($rs->post_excerpt); + + $cur->post_content_xhtml = $this->core->callFormater($this->vars['post_formater'],$cur->post_content); + $cur->post_excerpt_xhtml = $this->core->callFormater($this->vars['post_formater'],$cur->post_excerpt); + + switch ($rs->post_status) + { + case 'publish': + $cur->post_status = 1; + break; + case 'draft': + $cur->post_status = 0; + break; + case 'pending': + $cur->post_status = -2; + break; + default: + $cur->post_status = -2; + } + $cur->post_type = $rs->post_type; + $cur->post_password = $rs->post_password ? $rs->post_password : NULL; + $cur->post_open_comment = $rs->comment_status == 'open' ? 1 : 0; + $cur->post_open_tb = $rs->ping_status == 'open' ? 1 : 0; + + $cur->post_words = implode(' ',text::splitWords( + $cur->post_title.' '. + $cur->post_excerpt_xhtml.' '. + $cur->post_content_xhtml + )); + + $cur->post_id = $this->con->select( + 'SELECT MAX(post_id) FROM '.$this->prefix.'post' + )->f(0) + 1; + + $cur->post_url = $this->core->blog->getPostURL($cur->post_url,$cur->post_dt,$cur->post_title,$cur->post_id); + + $cur->insert(); + $this->importComments($rs->ID,$cur->post_id,$db); + $this->importPings($rs->ID,$cur->post_id,$db); + + # Create tags if we have metadata plugin in DC2 + if (class_exists('dcMeta')) { + $this->importTags($rs->ID,$cur->post_id,$db); + + if (!$old_cat_ids->isEmpty() && $this->vars['cat_as_tags']) + { + $old_cat_ids->moveStart(); + $meta = new dcMeta($this->core); + while ($old_cat_ids->fetch()) { + $meta->setPostMeta($cur->post_id,'tag',$this->cleanStr($this->vars['cat_tags_prefix'].$old_cat_ids->name)); + } + } + } + } + + # Comments import + protected function importComments($post_id,$new_post_id,&$db) + { + $count_c = $count_t = 0; + + $rs = $db->select( + 'SELECT * FROM '.$this->vars['db_prefix'].'comments '. + 'WHERE comment_post_ID = '.(integer) $post_id.' ' + ); + + while ($rs->fetch()) + { + $cur = $this->con->openCursor($this->prefix.'comment'); + $cur->post_id = (integer) $new_post_id; + $cur->comment_author = $this->cleanStr($rs->comment_author); + $cur->comment_status = (integer) $rs->comment_approved ; + $cur->comment_dt = $rs->comment_date; + $cur->comment_email = $this->cleanStr($rs->comment_author_email); + $cur->comment_content = $this->core->callFormater($this->vars['comment_formater'],$this->cleanStr($rs->comment_content)); + $cur->comment_ip = $rs->comment_author_IP; + $cur->comment_trackback = $rs->comment_type == 'trackback' ? 1 : 0; + $cur->comment_site = substr($this->cleanStr($rs->comment_author_url),0,255); + if (!isset($cur->comment_site)) $cur->comment_site = NULL; + + if ($rs->comment_approved == 'spam') { + $cur->comment_status = -2; + } + + $cur->comment_words = implode(' ',text::splitWords($cur->comment_content)); + + $cur->comment_id = $this->con->select( + 'SELECT MAX(comment_id) FROM '.$this->prefix.'comment' + )->f(0) + 1; + + $cur->insert(); + + if ($cur->comment_trackback && $cur->comment_status == 1) { + $count_t++; + } elseif ($cur->comment_status == 1) { + $count_c++; + } + } + + if ($count_t > 0 || $count_c > 0) + { + $this->con->execute( + 'UPDATE '.$this->prefix.'post SET '. + 'nb_comment = '.$count_c.', '. + 'nb_trackback = '.$count_t.' '. + 'WHERE post_id = '.(integer) $new_post_id.' ' + ); + } + } + + # Pings import + protected function importPings($post_id,$new_post_id,&$db) + { + $urls = array(); + $pings = array(); + + $rs = $db->select( + 'SELECT pinged FROM '.$this->vars['db_prefix'].'posts '. + 'WHERE ID = '.(integer) $post_id + ); + $pings = explode ("\n",$rs->pinged); + unset ($pings[0]); + + foreach($pings as $ping_url) + { + $url = $this->cleanStr($ping_url); + if (isset($urls[$url])) { + continue; + } + + $cur = $this->con->openCursor($this->prefix.'ping'); + $cur->post_id = (integer) $new_post_id; + $cur->ping_url = $url; + $cur->insert(); + + $urls[$url] = true; + } + } + + # Meta import + protected function importTags($post_id,$new_post_id,&$db) + { + $rs = $db->select( + 'SELECT * FROM '.$this->vars['db_prefix'].'terms AS t, '. + $this->vars['db_prefix'].'term_taxonomy AS x, '. + $this->vars['db_prefix'].'term_relationships AS r '. + 'WHERE t.term_id = x.term_id '. + 'AND x.taxonomy = \'post_tag\' '. + 'AND t.term_id = r.term_taxonomy_id '. + 'AND r.object_id ='.$post_id. + ' ORDER BY t.term_id ASC' + ); + + if ($rs->isEmpty()) { + return; + } + + $meta = new dcMeta($this->core); + while ($rs->fetch()) { + $meta->setPostMeta($new_post_id,'tag',$this->cleanStr($rs->name)); + } + } +} +?> \ No newline at end of file diff --git a/plugins/importExport/inc/flat/class.backupFile.php b/plugins/importExport/inc/flat/class.backupFile.php new file mode 100644 index 0000000..fdc97d4 --- /dev/null +++ b/plugins/importExport/inc/flat/class.backupFile.php @@ -0,0 +1,132 @@ + "\n", + '\r' => "\r", + '\"' => '"' + ); + + public function __construct($file) + { + if (file_exists($file) && is_readable($file)) { + $this->fp = fopen($file,'rb'); + } else { + throw new Exception(__('No file to read.')); + } + } + + public function __destruct() + { + if ($this->fp) { + fclose($this->fp); + } + } + + public function getLine() + { + if (feof($this->fp)) { + return false; + } + + $line = trim(fgets($this->fp)); + + if (substr($line,0,1) == '[') + { + $this->line_name = substr($line,1,strpos($line,' ')-1); + + $line = substr($line,strpos($line,' ')+1,-1); + $this->line_cols = explode(',',$line); + + return $this->getLine(); + } + elseif (substr($line,0,1) == '"') + { + $line = preg_replace('/^"|"$/','',$line); + $line = preg_split('/(^"|","|"$)/m',$line); + + if (count($this->line_cols) != count($line)) { + throw new Exception('Invalid row count'); + } + + $res = array(); + + for ($i=0; $iline_cols[$i]] = + str_replace(array_keys($this->replacement),array_values($this->replacement),$line[$i]); + } + + return new backupFileItem($this->line_name,$res); + } + else + { + return $this->getLine(); + } + } +} + +class backupFileItem +{ + public $__name; + private $__data = array(); + + public function __construct($name,$data) + { + $this->__name = $name; + $this->__data = $data; + } + + public function f($name) + { + return iconv('UTF-8','UTF-8//IGNORE',$this->__data[$name]); + } + + public function __get($name) + { + return $this->f($name); + } + + public function __set($n,$v) + { + $this->__data[$n] = $v; + } + + public function exists($n) + { + return isset($this->__data[$n]); + } + + public function drop() + { + foreach (func_get_args() as $n) { + if (isset($this->__data[$n])) { + unset($this->__data[$n]); + } + } + } + + public function substitute($old,$new) + { + if (isset($this->__data[$old])) { + $this->__data[$new] = $this->__data[$old]; + unset($this->__data[$old]); + } + } +} +?> \ No newline at end of file diff --git a/plugins/importExport/inc/flat/class.db.export.php b/plugins/importExport/inc/flat/class.db.export.php new file mode 100644 index 0000000..198eccd --- /dev/null +++ b/plugins/importExport/inc/flat/class.db.export.php @@ -0,0 +1,106 @@ +con =& $con; + $this->prefix = $prefix; + + if (($this->fp = fopen($out,'w')) === false) { + return false; + } + @set_time_limit(300); + } + + function __destruct() + { + if (is_resource($this->fp)) { + fclose($this->fp); + } + } + + function export($name,$sql) + { + $rs = $this->con->select($sql); + + if (!$rs->isEmpty()) + { + fwrite($this->fp,"\n[".$name.' '.implode(',',$rs->columns())."]\n"); + while ($rs->fetch()) { + fwrite($this->fp,$this->getLine($rs)); + } + fflush($this->fp); + } + } + + function exportAll() + { + $tables = $this->getTables(); + + foreach ($tables as $table) + { + $this->exportTable($table); + } + } + + function exportTable($table) + { + $req = 'SELECT * FROM '.$this->con->escapeSystem($this->prefix.$table); + + $this->export($table,$req); + } + + function getTables() + { + $schema = dbSchema::init($this->con); + $db_tables = $schema->getTables(); + + $tables = array(); + foreach ($db_tables as $t) + { + if ($this->prefix) { + if (strpos($t,$this->prefix) === 0) { + $tables[] = $t; + } + } else { + $tables[] = $t; + } + } + + return $tables; + } + + function getLine(&$rs) + { + $l = array(); + $cols = $rs->columns(); + foreach ($cols as $i => &$c) { + $s = $rs->f($c); + $s = preg_replace($this->line_reg,$this->line_rep,$s); + $s = '"'.$s.'"'; + $l[$i] = $s; + } + return implode(',',$l)."\n"; + } +} +?> \ No newline at end of file diff --git a/plugins/importExport/inc/flat/class.dc.import.php b/plugins/importExport/inc/flat/class.dc.import.php new file mode 100644 index 0000000..c3c925d --- /dev/null +++ b/plugins/importExport/inc/flat/class.dc.import.php @@ -0,0 +1,730 @@ + array(), + 'post' => array(), + 'media' => array() + ); + + public $stack = array( + 'categories'=>null, + 'cat_id'=>1, + 'cat_lft'=>array(), + 'post_id'=>1, + 'media_id'=>1, + 'comment_id'=>1, + 'link_id'=>1 + ); + + public $has_categories = false; + + public function __construct(&$core,$file) + { + parent::__construct($file); + + $first_line = fgets($this->fp); + if (strpos($first_line,'///DOTCLEAR|') !== 0) { + throw new Exception(__('File is not a DotClear backup.')); + } + + @set_time_limit(300); + + $l = explode('|',$first_line); + + if (isset($l[1])) { + $this->dc_version = $l[1]; + } + + $this->mode = isset($l[2]) ? strtolower(trim($l[2])) : 'single'; + if ($this->mode != 'full' && $this->mode != 'single') { + $this->mode = 'single'; + } + + if (version_compare('1.2',$this->dc_version,'<=') && + version_compare('1.3',$this->dc_version,'>')) { + $this->dc_major_version = '1.2'; + } else { + $this->dc_major_version = '2.0'; + } + + $this->core =& $core; + $this->con =& $core->con; + $this->prefix = $core->prefix; + + $this->cur_blog = $this->con->openCursor($this->prefix.'blog'); + $this->cur_category = $this->con->openCursor($this->prefix.'category'); + $this->cur_link = $this->con->openCursor($this->prefix.'link'); + $this->cur_setting = $this->con->openCursor($this->prefix.'setting'); + $this->cur_user = $this->con->openCursor($this->prefix.'user'); + $this->cur_permissions = $this->con->openCursor($this->prefix.'permissions'); + $this->cur_post = $this->con->openCursor($this->prefix.'post'); + $this->cur_media = $this->con->openCursor($this->prefix.'media'); + $this->cur_post_media = $this->con->openCursor($this->prefix.'post_media'); + $this->cur_log = $this->con->openCursor($this->prefix.'log'); + $this->cur_ping = $this->con->openCursor($this->prefix.'ping'); + $this->cur_comment = $this->con->openCursor($this->prefix.'comment'); + $this->cur_spamrule = $this->con->openCursor($this->prefix.'spamrule'); + $this->cur_version = $this->con->openCursor($this->prefix.'version'); + + # --BEHAVIOR-- importInit + $this->core->callBehavior('importInit',$this,$this->core); + } + + public function importSingle() + { + if ($this->mode != 'single') { + throw new Exception(__('File is not a single blog export.')); + } + + if (!$this->core->auth->check('admin',$this->core->blog->id)) { + throw new Exception(__('Permission denied.')); + } + + $this->blog_id = $this->core->blog->id; + + $this->stack['categories'] = $this->con->select( + 'SELECT cat_id, cat_title, cat_url '. + 'FROM '.$this->prefix.'category '. + "WHERE blog_id = '".$this->con->escape($this->blog_id)."' " + ); + + $rs = $this->con->select('SELECT MAX(cat_id) FROM '.$this->prefix.'category'); + $this->stack['cat_id'] = ((integer) $rs->f(0))+1; + + $rs = $this->con->select('SELECT MAX(link_id) FROM '.$this->prefix.'link'); + $this->stack['link_id'] = ((integer) $rs->f(0))+1; + + $rs = $this->con->select('SELECT MAX(post_id) FROM '.$this->prefix.'post'); + $this->stack['post_id'] = ((integer) $rs->f(0))+1; + + $rs = $this->con->select('SELECT MAX(media_id) FROM '.$this->prefix.'media'); + $this->stack['media_id'] = ((integer) $rs->f(0))+1; + + $rs = $this->con->select('SELECT MAX(comment_id) FROM '.$this->prefix.'comment'); + $this->stack['comment_id'] = ((integer) $rs->f(0))+1; + + $rs = $this->con->select( + 'SELECT MAX(cat_rgt) AS cat_rgt FROM '.$this->prefix.'category '. + "WHERE blog_id = '".$this->con->escape($this->core->blog->id)."'" + ); + + if ((integer) $rs->cat_rgt > 0) { + $this->has_categories = true; + $this->stack['cat_lft'][$this->core->blog->id] = (integer) $rs->cat_rgt + 1; + } + + $this->con->begin(); + + try + { + while (($line = $this->getLine()) !== false) + { + # import DC 1.2.x, we fix lines before insert + if ($this->dc_major_version == '1.2') { + $this->prepareDC12line($line); + } + + switch ($line->__name) + { + case 'category': + $this->insertCategorySingle($line); + break; + case 'link': + $this->insertLinkSingle($line); + break; + case 'post': + $this->insertPostSingle($line); + break; + case 'media': + $this->insertMediaSingle($line); + break; + case 'post_media': + $this->insertPostMediaSingle($line); + break; + case 'ping': + $this->insertPingSingle($line); + break; + case 'comment': + $this->insertCommentSingle($line); + break; + } + + # --BEHAVIOR-- importSingle + $this->core->callBehavior('importSingle',$line,$this,$this->core); + } + } + catch (Exception $e) + { + $this->con->rollback(); + throw $e; + } + + $this->con->commit(); + } + + public function importFull() + { + if ($this->mode != 'full') { + throw new Exception(__('File is not a full export.')); + } + + if (!$this->core->auth->isSuperAdmin()) { + throw new Exception(__('Permission denied.')); + } + + $this->con->begin(); + $this->con->execute('DELETE FROM '.$this->prefix.'blog'); + $this->con->execute('DELETE FROM '.$this->prefix.'media'); + $this->con->execute('DELETE FROM '.$this->prefix.'spamrule'); + $this->con->execute('DELETE FROM '.$this->prefix.'setting'); + + try + { + while (($line = $this->getLine()) !== false) + { + switch ($line->__name) + { + case 'blog': + $this->insertBlog($line); + break; + case 'category': + $this->insertCategory($line); + break; + case 'link': + $this->insertLink($line); + break; + case 'setting': + $this->insertSetting($line); + break; + case 'user': + $this->insertUser($line); + break; + case 'permissions': + $this->insertPermissions($line); + break; + case 'post': + $this->insertPost($line); + break; + case 'media': + $this->insertMedia($line); + break; + case 'post_media': + $this->insertPostMedia($line); + break; + case 'log'; + $this->insertLog($line); + break; + case 'ping': + $this->insertPing($line); + break; + case 'comment': + $this->insertComment($line); + break; + case 'spamrule': + $this->insertSpamRule($line); + break; + } + # --BEHAVIOR-- importFull + $this->core->callBehavior('importFull',$line,$this,$this->core); + } + } + catch (Exception $e) + { + $this->con->rollback(); + throw $e; + } + + $this->con->commit(); + } + + private function insertBlog($blog) + { + $this->cur_blog->clean(); + + $this->cur_blog->blog_id = (string) $blog->blog_id; + $this->cur_blog->blog_uid = (string) $blog->blog_uid; + $this->cur_blog->blog_creadt = (string) $blog->blog_creadt; + $this->cur_blog->blog_upddt = (string) $blog->blog_upddt; + $this->cur_blog->blog_url = (string) $blog->blog_url; + $this->cur_blog->blog_name = (string) $blog->blog_name; + $this->cur_blog->blog_desc = (string) $blog->blog_desc; + + $this->cur_blog->blog_status = $blog->exists('blog_status') ? (integer) $blog->blog_status : 1; + + $this->cur_blog->insert(); + } + + private function insertCategory($category) + { + $this->cur_category->clean(); + + $this->cur_category->cat_id = (string) $category->cat_id; + $this->cur_category->blog_id = (string) $category->blog_id; + $this->cur_category->cat_title = (string) $category->cat_title; + $this->cur_category->cat_url = (string) $category->cat_url; + $this->cur_category->cat_desc = (string) $category->cat_desc; + + if (!$this->has_categories && $category->exists('cat_lft') && $category->exists('cat_rgt')) { + $this->cur_category->cat_lft = (integer) $category->cat_lft; + $this->cur_category->cat_rgt = (integer) $category->cat_rgt; + } else { + if (!isset($this->stack['cat_lft'][$category->blog_id])) { + $this->stack['cat_lft'][$category->blog_id] = 2; + } + $this->cur_category->cat_lft = $this->stack['cat_lft'][$category->blog_id]++; + $this->cur_category->cat_rgt = $this->stack['cat_lft'][$category->blog_id]++; + } + + $this->cur_category->insert(); + } + + private function insertLink($link) + { + $this->cur_link->clean(); + + $this->cur_link->link_id = (integer) $link->link_id; + $this->cur_link->blog_id = (string) $link->blog_id; + $this->cur_link->link_href = (string) $link->link_href; + $this->cur_link->link_title = (string) $link->link_title; + $this->cur_link->link_desc = (string) $link->link_desc; + $this->cur_link->link_lang = (string) $link->link_lang; + $this->cur_link->link_xfn = (string) $link->link_xfn; + $this->cur_link->link_position = (integer) $link->link_position; + + $this->cur_link->insert(); + } + + private function insertSetting($setting) + { + $this->cur_setting->clean(); + + $this->cur_setting->setting_id = (string) $setting->setting_id; + $this->cur_setting->blog_id = !$setting->blog_id ? null : (string) $setting->blog_id; + $this->cur_setting->setting_ns = (string) $setting->setting_ns; + $this->cur_setting->setting_value = (string) $setting->setting_value; + $this->cur_setting->setting_type = (string) $setting->setting_type; + $this->cur_setting->setting_label = (string) $setting->setting_label; + + $this->cur_setting->insert(); + } + + private function insertUser($user) + { + if ($this->userExists($user->user_id)) { + return; + } + + $this->cur_user->clean(); + + $this->cur_user->user_id = (string) $user->user_id; + $this->cur_user->user_super = (integer) $user->user_super; + $this->cur_user->user_pwd = (string) $user->user_pwd; + $this->cur_user->user_recover_key = (string) $user->user_recover_key; + $this->cur_user->user_name = (string) $user->user_name; + $this->cur_user->user_firstname = (string) $user->user_firstname; + $this->cur_user->user_displayname = (string) $user->user_displayname; + $this->cur_user->user_email = (string) $user->user_email; + $this->cur_user->user_url = (string) $user->user_url; + $this->cur_user->user_default_blog = !$user->user_default_blog ? null : (string) $user->user_default_blog; + $this->cur_user->user_lang = (string) $user->user_lang; + $this->cur_user->user_tz = (string) $user->user_tz; + $this->cur_user->user_post_status = (integer) $user->user_post_status; + $this->cur_user->user_creadt = (string) $user->user_creadt; + $this->cur_user->user_upddt = (string) $user->user_upddt; + + $this->cur_user->user_desc = $user->exists('user_desc') ? (string) $user->user_desc : null; + $this->cur_user->user_options = $user->exists('user_options') ? (string) $user->user_options : null; + $this->cur_user->user_status = $user->exists('user_status') ? (integer) $user->user_status : 1; + + $this->cur_user->insert(); + + $this->stack['users'][$user->user_id] = true; + } + + private function insertPermissions($permissions) + { + $this->cur_permissions->clean(); + + $this->cur_permissions->user_id = (string) $permissions->user_id; + $this->cur_permissions->blog_id = (string) $permissions->blog_id; + $this->cur_permissions->permissions = (string) $permissions->permissions; + + $this->cur_permissions->insert(); + } + + private function insertPost($post) + { + $this->cur_post->clean(); + + $cat_id = (integer) $post->cat_id; + if (!$cat_id) { + $cat_id = null; + } + + $post_password = $post->post_password ? (string) $post->post_password : null; + + $this->cur_post->post_id = (integer) $post->post_id; + $this->cur_post->blog_id = (string) $post->blog_id; + $this->cur_post->user_id = (string) $this->getUserId($post->user_id); + $this->cur_post->cat_id = $cat_id; + $this->cur_post->post_dt = (string) $post->post_dt; + $this->cur_post->post_creadt = (string) $post->post_creadt; + $this->cur_post->post_upddt = (string) $post->post_upddt; + $this->cur_post->post_password = $post_password; + $this->cur_post->post_type = (string) $post->post_type; + $this->cur_post->post_format = (string) $post->post_format; + $this->cur_post->post_url = (string) $post->post_url; + $this->cur_post->post_lang = (string) $post->post_lang; + $this->cur_post->post_title = (string) $post->post_title; + $this->cur_post->post_excerpt = (string) $post->post_excerpt; + $this->cur_post->post_excerpt_xhtml = (string) $post->post_excerpt_xhtml; + $this->cur_post->post_content = (string) $post->post_content; + $this->cur_post->post_content_xhtml = (string) $post->post_content_xhtml; + $this->cur_post->post_notes = (string) $post->post_notes; + $this->cur_post->post_words = (string) $post->post_words; + $this->cur_post->post_meta = (string) $post->post_meta; + $this->cur_post->post_status = (integer) $post->post_status; + $this->cur_post->post_selected = (integer) $post->post_selected; + $this->cur_post->post_open_comment = (integer) $post->post_open_comment; + $this->cur_post->post_open_tb = (integer) $post->post_open_tb; + $this->cur_post->nb_comment = (integer) $post->nb_comment; + $this->cur_post->nb_trackback = (integer) $post->nb_trackback; + + $this->cur_post->post_tz = $post->exists('post_tz') ? (string) $post->post_tz : 'UTC'; + + $this->cur_post->insert(); + } + + private function insertMedia($media) + { + $this->cur_media->clean(); + + $this->cur_media->media_id = (integer) $media->media_id; + $this->cur_media->user_id = (string) $media->user_id; + $this->cur_media->media_path = (string) $media->media_path; + $this->cur_media->media_title = (string) $media->media_title; + $this->cur_media->media_file = (string) $media->media_file; + $this->cur_media->media_meta = (string) $media->media_meta; + $this->cur_media->media_dt = (string) $media->media_dt; + $this->cur_media->media_creadt = (string) $media->media_creadt; + $this->cur_media->media_upddt = (string) $media->media_upddt; + $this->cur_media->media_private = (integer) $media->media_private; + + $this->cur_media->media_dir = $media->exists('media_dir') ? (string) $media->media_dir : dirname($media->media_file); + + $this->cur_media->insert(); + } + + private function insertPostMedia($post_media) + { + $this->cur_post_media->clean(); + + $this->cur_post_media->media_id = (integer) $post_media->media_id; + $this->cur_post_media->post_id = (integer) $post_media->post_id; + + $this->cur_post_media->insert(); + } + + private function insertLog($log) + { + $this->cur_log->clean(); + + $this->cur_log->log_id = (integer) $log->log_id; + $this->cur_log->user_id = (string) $log->user_id; + $this->cur_log->log_table = (string) $log->log_table; + $this->cur_log->log_dt = (string) $log->log_dt; + $this->cur_log->log_ip = (string) $log->log_ip; + $this->cur_log->log_msg = (string) $log->log_msg; + + $this->cur_log->insert(); + } + + private function insertPing($ping) + { + $this->cur_ping->clean(); + + $this->cur_ping->post_id = (integer) $ping->post_id; + $this->cur_ping->ping_url = (string) $ping->ping_url; + $this->cur_ping->ping_dt = (string) $ping->ping_dt; + + $this->cur_ping->insert(); + } + + private function insertComment($comment) + { + $this->cur_comment->clean(); + + $this->cur_comment->comment_id = (integer) $comment->comment_id; + $this->cur_comment->post_id = (integer) $comment->post_id; + $this->cur_comment->comment_dt = (string) $comment->comment_dt; + $this->cur_comment->comment_upddt = (string) $comment->comment_upddt; + $this->cur_comment->comment_author = (string) $comment->comment_author; + $this->cur_comment->comment_email = (string) $comment->comment_email; + $this->cur_comment->comment_site = (string) $comment->comment_site; + $this->cur_comment->comment_content = (string) $comment->comment_content; + $this->cur_comment->comment_words = (string) $comment->comment_words; + $this->cur_comment->comment_ip = (string) $comment->comment_ip; + $this->cur_comment->comment_status = (integer) $comment->comment_status; + $this->cur_comment->comment_spam_status = (integer) $comment->comment_spam_status; + $this->cur_comment->comment_trackback = (integer) $comment->comment_trackback; + + $this->cur_comment->comment_tz = $comment->exists('comment_tz') ? (string) $comment->comment_tz : 'UTC'; + $this->cur_comment->comment_spam_filter = $comment->exists('comment_spam_filter') ? (integer) $comment->comment_spam_filter : null; + + $this->cur_comment->insert(); + } + + private function insertSpamRule($spamrule) + { + $this->cur_spamrule->clean(); + + $this->cur_spamrule->rule_id = (integer) $spamrule->rule_id; + $this->cur_spamrule->blog_id = !$spamrule->blog_id ? null : (string) $spamrule->blog_id; + $this->cur_spamrule->rule_type = (string) $spamrule->rule_type; + $this->cur_spamrule->rule_content = (string) $spamrule->rule_content; + + $this->cur_spamrule->insert(); + } + + private function insertCategorySingle($category) + { + $this->cur_category->clean(); + + $m = $this->searchCategory($this->stack['categories'],$category->cat_url); + + $old_id = $category->cat_id; + if ($m !== false) + { + $cat_id = $m; + } + else + { + $cat_id = $this->stack['cat_id']; + $category->cat_id = $cat_id; + $category->blog_id = $this->blog_id; + + $this->insertCategory($category); + $this->stack['cat_id']++; + } + + $this->old_ids['category'][(integer) $old_id] = $cat_id; + } + + private function insertLinkSingle($link) + { + $link->blog_id = $this->blog_id; + $link->link_id = $this->stack['link_id']; + + $this->insertLink($link); + $this->stack['link_id']++; + } + + private function insertPostSingle($post) + { + $post_id = $this->stack['post_id']; + $this->old_ids['post'][(integer) $post->post_id] = $post_id; + + $cat_id = $post->cat_id ? $this->old_ids['category'][(integer) $post->cat_id] : null; + + $post->post_id = $post_id; + $post->cat_id = $cat_id; + $post->blog_id = $this->blog_id; + + $post->post_url = $this->core->blog->getPostURL( + $post->post_url,$post->post_dt,$post->post_title,$post->post_id + ); + + $this->insertPost($post); + $this->stack['post_id']++; + } + + private function insertMediaSingle($media) + { + $media_id = $this->stack['media_id']; + $old_id = $media->media_id; + + $media->media_id = $media_id; + $media->media_path = $this->core->blog->settings->public_path; + $media->user_id = $this->getUserId($media->user_id); + + $this->insertMedia($media); + $this->stack['media_id']++; + $this->old_ids['media'][(integer) $old_id] = $media_id; + } + + private function insertPostMediaSingle($post_media) + { + $post_media->media_id = $this->old_ids['media'][(integer) $post_media->media_id]; + $post_media->post_id = $this->old_ids['post'][(integer) $post_media->post_id]; + + $this->insertPostMedia($post_media); + } + + private function insertPingSingle($ping) + { + $ping->post_id = $this->old_ids['post'][(integer) $ping->post_id]; + + $this->insertPing($ping); + } + + private function insertCommentSingle($comment) + { + $comment_id = $this->stack['comment_id']; + + $comment->comment_id = $comment_id; + $comment->post_id = $this->old_ids['post'][(integer) $comment->post_id]; + + $this->insertComment($comment); + $this->stack['comment_id']++; + } + + public function searchCategory(&$rs,$url) + { + while ($rs->fetch()) + { + if ($rs->cat_url == $url) { + return $rs->cat_id; + } + } + + return false; + } + + public function getUserId($user_id) + { + if (!$this->userExists($user_id)) + { + if ($this->core->auth->isSuperAdmin()) + { + # Sanitizes user_id and create a lambda user + $user_id = preg_replace('/[^A-Za-z0-9]$/','',$user_id); + $user_id .= strlen($user_id) < 2 ? '-a' : ''; + + # We change user_id, we need to check again + if (!$this->userExists($user_id)) + { + $this->cur_user->clean(); + $this->cur_user->user_id = (string) $user_id; + $this->cur_user->user_pwd = md5(uniqid()); + + $this->core->addUser($this->cur_user); + + $this->stack['users'][$user_id] = true; + } + } + else + { + # Returns current user id + $user_id = $this->core->auth->userID(); + } + } + + return $user_id; + } + + private function userExists($user_id) + { + if (isset($this->stack['users'][$user_id])) { + return $this->stack['users'][$user_id]; + } + + $strReq = 'SELECT user_id '. + 'FROM '.$this->prefix.'user '. + "WHERE user_id = '".$this->con->escape($user_id)."' "; + + $rs = $this->con->select($strReq); + + $this->stack['users'][$user_id] = !$rs->isEmpty(); + return $this->stack['users'][$user_id]; + } + + private function prepareDC12line(&$line) + { + $settings = array('dc_theme','dc_nb_post_per_page','dc_allow_comments', + 'dc_allow_trackbacks','dc_comment_pub','dc_comments_ttl', + 'dc_wiki_comments','dc_use_smilies','dc_date_format','dc_time_format', + 'dc_url_scan'); + + switch ($line->__name) + { + case 'categorie': + $line->substitute('cat_libelle','cat_title'); + $line->substitute('cat_libelle_url','cat_url'); + $line->__name = 'category'; + $line->blog_id = 'default'; + break; + case 'link': + $line->substitute('href','link_href'); + $line->substitute('label','link_title'); + $line->substitute('title','link_desc'); + $line->substitute('lang','link_lang'); + $line->substitute('rel','link_xfn'); + $line->substitute('position','link_position'); + $line->blog_id = 'default'; + break; + case 'post': + $line->substitute('post_titre','post_title'); + $line->post_title = html::decodeEntities($line->post_title); + $line->post_url = date('Y/m/d/',strtotime($line->post_dt)).$line->post_id.'-'.$line->post_titre_url; + $line->post_url = substr($line->post_url,0,255); + $line->post_format = $line->post_content_wiki == '' ? 'xhtml' : 'wiki'; + $line->post_content_xhtml = $line->post_content; + $line->post_excerpt_xhtml = $line->post_chapo; + + if ($line->post_format == 'wiki') { + $line->post_content = $line->post_content_wiki; + $line->post_excerpt = $line->post_chapo_wiki; + } else { + $line->post_content = $line->post_content; + $line->post_excerpt = $line->post_chapo; + } + + $line->post_status = (integer) $line->post_pub; + $line->post_type = 'post'; + $line->blog_id = 'default'; + + $line->drop('post_titre_url','post_content_wiki','post_chapo','post_chapo_wiki','post_pub'); + + break; + case 'comment': + $line->substitute('comment_auteur','comment_author'); + if ($line->comment_site != '' && !preg_match('!^http://.*$!', $line->comment_site,$m)) { + $line->comment_site = 'http://'.$line->comment_site; + } + $line->comment_status = (integer) $line->comment_pub; + $line->drop('comment_pub'); + break; + } + + # --BEHAVIOR-- importPrepareDC12 + $this->core->callBehavior('importPrepareDC12',$line,$this,$this->core); + } +} +?> \ No newline at end of file diff --git a/plugins/importExport/index.php b/plugins/importExport/index.php new file mode 100644 index 0000000..e0010b0 --- /dev/null +++ b/plugins/importExport/index.php @@ -0,0 +1,143 @@ + dirname(__FILE__).'/inc/class.dc.import.flat.php', + 'dcImportFeed' => dirname(__FILE__).'/inc/class.dc.import.feed.php', +)); +$modules['e'] = new ArrayObject(array( + 'dcExportFlat' => dirname(__FILE__).'/inc/class.dc.export.flat.php' +)); + +if ($core->auth->isSuperAdmin()) { + $modules['i']['dcImportDC1'] = dirname(__FILE__).'/inc/class.dc.import.dc1.php'; + $modules['i']['dcImportWP'] = dirname(__FILE__).'/inc/class.dc.import.wp.php'; +} + +# --BEHAVIOR-- importExportModules +$core->callBehavior('importExportModules',$modules); + +$type = null; +if (!empty($_REQUEST['t']) && ($_REQUEST['t'] == 'e' || $_REQUEST['t'] == 'i')) { + $type = $_REQUEST['t']; +} + +$current_module = null; +if ($type && !empty($_REQUEST['f'])) { + if (isset($modules[$type][$_REQUEST['f']])) { + require_once $modules[$type][$_REQUEST['f']]; + $current_module = new $_REQUEST['f']($core); + $current_module->init(); + } +} + +if ($type && $current_module !== null && !empty($_REQUEST['do'])) +{ + try { + $current_module->process($_REQUEST['do']); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} +?> + + + <?php echo __('Import/Export'); ?> + + + + + + +'.__('Import/Export').''. + ' › '.html::escapeHTML($current_module->name).''; + + echo '
    '; + $current_module->gui(); + echo '
    '; +} +else +{ + echo '

    '.__('Import/Export').'

    '; + echo '

    '.__('Import').'

    '; + + echo '
    '; + foreach ($modules['i'] as $k => $v) + { + require_once $v; + $o = new $k($core); + + echo + '
    '.html::escapeHTML($o->name).'
    '. + '
    '.html::escapeHTML($o->description).'
    '; + + unset($o); + } + echo '
    '; + + echo '

    '.__('Export').'

    '; + + echo '
    '; + foreach ($modules['e'] as $k => $v) + { + require_once $v; + $o = new $k($core); + + echo + '
    '.html::escapeHTML($o->name).'
    '. + '
    '.html::escapeHTML($o->description).'
    '; + + unset($o); + } + echo '
    '; +} +?> + + + \ No newline at end of file diff --git a/plugins/importExport/progress.png b/plugins/importExport/progress.png new file mode 100644 index 0000000000000000000000000000000000000000..267f54111eae4c93e3629b643bb5a61609e2769c GIT binary patch literal 858 zcmV-g1Eu_lP)RGReGUQd7@Bypi^|BM|q!9a-l6z7Pj;M8 zbDc_Yo<($OmUh?a+pkTnMiS$N^6@taF|GMmPl!uH*S?kZ|hkTqqGJ7$bPWsE*!jXGVBDq@Q|UXCtYk11Y@Fj|c#Uy3wgi8@(}CRmFl zU57MQi6d5sB~^$bRE8o|h9y&mAXJ4URD&f^gdS6YB~*bZQh_2?fGksgCr^SLPJbLt zfErAH8B2W`N_`hidLT=C8%TQMgsr<02XvbSad^jWnpw_ zZ*Cw|X>DZyGC40WH7_tY@MYc30003kNklUHWeNNLtF5Z;u+0Us$1 zKHu0jRryJ6@K@~7Vm4_S^0yA9ow6KB*D!TPJ$a;SxS-uas?#-GQbRHA>l&`50){return;} +$('#ie-gui form[method=post]:has(input[type=hidden][name=autosubmit])').each(function(){$('input[type=submit]',this).remove();$(this).after('

    '+dotclear.msg.please_wait+'

    ');$(this).submit();});}); \ No newline at end of file diff --git a/plugins/maintenance/_admin.php b/plugins/maintenance/_admin.php new file mode 100644 index 0000000..2c1e1f4 --- /dev/null +++ b/plugins/maintenance/_admin.php @@ -0,0 +1,17 @@ +addItem(__('Maintenance'),'plugin.php?p=maintenance','index.php?pf=maintenance/icon.png', + preg_match('/plugin.php\?p=maintenance(&.*)?$/',$_SERVER['REQUEST_URI']), + $core->auth->isSuperAdmin()); +?> \ No newline at end of file diff --git a/plugins/maintenance/_define.php b/plugins/maintenance/_define.php new file mode 100644 index 0000000..e64330c --- /dev/null +++ b/plugins/maintenance/_define.php @@ -0,0 +1,21 @@ +registerModule( + /* Name */ "Maintenance", + /* Description*/ "Maintain your database", + /* Author */ "Olivier Meunier", + /* Version */ '1.0', + /* Permissions */ null +); +?> \ No newline at end of file diff --git a/plugins/maintenance/icon.png b/plugins/maintenance/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..57bdcdd2e2f4075440483b38e97d582c7dd4ca07 GIT binary patch literal 411 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJbFq_W2nPqp?T7vkfZWUgpAgso z|Nkp^wF6OC4~PT`1IhRA-vPNm^!@vHAp6amS5F^5x^nsQnKNhhp15-C$f5oF_O9K1 zX4lSbJGO6KyLQ!*C5tC5-M3)jytX+zs-|wOowyvRx1x7RQTMu%u0^%Ytw1w7`<2px zrgN19`2{lw8oRi-gm!eCvAA_b7bwbE;1O92l>7j~j81DzW`G=0;u=vBoS#-wo>-L1 z;G39Sl%JcLl9{OBmRXcqo?nz*tl%55d!m*KP;I-Xi(`m{BRzt>5ySBpDb2G!r};-vk+?@J+CsV96{xRdYp(!?NsUf4}-Jbx57{{I2R$rjSW8 z`;C|y&c_5X%zpQ8x7>Nngv+NleVcLEl2!lj$BH{qsr9Ei;^g+fz7@i^e8KejUvEZ- q>}%e4_x)bh$Gq$>uJ!I*8CgIlF?hQAxvXcon); + $db_tables = $schema->getTables(); + + foreach ($db_tables as $t) { + if (strpos($t,$core->prefix) === 0) { + $core->con->vacuum($t); + } + } + http::redirect($p_url.'&vacuum=1'); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} +elseif ($action == 'commentscount') +{ + try { + $core->countAllComments(); + http::redirect($p_url.'&commentscount=1'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} +elseif ($action == 'empty_cache') +{ + try { + $core->emptyTemplatesCache(); + http::redirect($p_url.'&empty_cache=1'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} + +?> + + + <?php echo __('Maintenance'); ?> + + + +

    + +'.__('Optimization successful.').'

    '; +} +if (!empty($_GET['commentscount'])) { + echo '

    '.__('Comments and trackback counted.').'

    '; +} +if (!empty($_GET['empty_cache'])) { + echo '

    '.__('Templates cache directory emptied.').'

    '; +} + +if ($action == 'index' && !empty($_GET['indexposts'])) +{ + $limit = 1000; + echo '

    '.sprintf(__('Indexing entry %d to %d.'),$start,$start+$limit).'

    '; + + $new_start = $core->indexAllPosts($start,$limit); + + if ($new_start) + { + $new_url = $p_url.'&action=index&indexposts=1&start='.$new_start; + echo + ''. + ''; + } + else + { + echo '

    '.__('Entries index done.').'

    '; + echo '

    '.__('Back').'

    '; + } +} +elseif ($action == 'index' && !empty($_GET['indexcomments'])) +{ + $limit = 1000; + echo '

    '.sprintf(__('Indexing comment %d to %d.'),$start,$start+$limit).'

    '; + + $new_start = $core->indexAllComments($start,$limit); + + if ($new_start) + { + $new_url = $p_url.'&action=index&indexcomments=1&start='.$new_start; + echo + ''. + ''; + } + else + { + echo '

    '.__('Comments index done.').'

    '; + echo '

    '.__('Back').'

    '; + } +} +else +{ + echo + '

    '.__('Optimize database room').'

    '. + '
    '. + '

    '. + $core->formNonce(). + form::hidden(array('action'),'vacuum'). + form::hidden(array('p'),'maintenance').'

    '. + '
    '; + + echo + '

    '.__('Counters').'

    '. + '
    '. + '

    '. + $core->formNonce(). + form::hidden(array('action'),'commentscount'). + form::hidden(array('p'),'maintenance').'

    '. + '
    '; + + echo + '

    '.__('Search engine index').' ('.__('This may take a very long time').')

    '. + '
    '. + '

    '. + ' '. + form::hidden(array('action'),'index'). + form::hidden(array('p'),'maintenance').'

    '. + '
    '; + + echo + '

    '.__('Empty templates cache directory').'

    '. + '
    '. + '

    '. + $core->formNonce(). + form::hidden(array('action'),'empty_cache'). + form::hidden(array('p'),'maintenance').'

    '. + '
    '; +} +?> + + + \ No newline at end of file diff --git a/plugins/metadata/_admin.php b/plugins/metadata/_admin.php new file mode 100644 index 0000000..c2ca314 --- /dev/null +++ b/plugins/metadata/_admin.php @@ -0,0 +1,413 @@ +addItem(__('Tags'),'plugin.php?p=metadata&m=tags','index.php?pf=metadata/tags.png', + preg_match('/plugin.php\?p=metadata&m=tag(s|_posts)?(&.*)?$/',$_SERVER['REQUEST_URI']), + $core->auth->check('usage,contentadmin',$core->blog->id)); + +require dirname(__FILE__).'/_widgets.php'; + +$core->addBehavior('adminPostFormSidebar',array('metaBehaviors','tagsField')); + +$core->addBehavior('adminAfterPostCreate',array('metaBehaviors','setTags')); +$core->addBehavior('adminAfterPostUpdate',array('metaBehaviors','setTags')); + +$core->addBehavior('adminPostHeaders',array('metaBehaviors','postHeaders')); + +$core->addBehavior('adminPostsActionsCombo',array('metaBehaviors','adminPostsActionsCombo')); +$core->addBehavior('adminPostsActions',array('metaBehaviors','adminPostsActions')); +$core->addBehavior('adminPostsActionsContent',array('metaBehaviors','adminPostsActionsContent')); + +$core->addBehavior('coreInitWikiPost',array('metaBehaviors','coreInitWikiPost')); + +$core->addBehavior('exportFull',array('metaBehaviors','exportFull')); +$core->addBehavior('exportSingle',array('metaBehaviors','exportSingle')); +$core->addBehavior('importInit',array('metaBehaviors','importInit')); +$core->addBehavior('importSingle',array('metaBehaviors','importSingle')); +$core->addBehavior('importFull',array('metaBehaviors','importFull')); +$core->addBehavior('importPrepareDC12',array('metaBehaviors','importPrepareDC12')); + +$core->rest->addFunction('getMeta',array('metaRest','getMeta')); +$core->rest->addFunction('delMeta',array('metaRest','delMeta')); +$core->rest->addFunction('setPostMeta',array('metaRest','setPostMeta')); + +# BEHAVIORS +class metaBehaviors +{ + public static function coreInitWikiPost(&$wiki2xhtml) + { + $wiki2xhtml->registerFunction('url:tag',array('metaBehaviors','wiki2xhtmlTag')); + } + + public static function wiki2xhtmlTag($url,$content) + { + $url = substr($url,4); + if (strpos($content,'tag:') === 0) { + $content = substr($content,4); + } + + + $tag_url = html::stripHostURL($GLOBALS['core']->blog->url.$GLOBALS['core']->url->getBase('tag')); + $res['url'] = $tag_url.'/'.rawurlencode(dcMeta::sanitizeMetaID($url)); + $res['content'] = $content; + + return $res; + } + + public static function tagsField(&$post) + { + $meta = new dcMeta($GLOBALS['core']); + + if (!empty($_POST['post_tags'])) { + $value = $_POST['post_tags']; + } else { + $value = ($post) ? $meta->getMetaStr($post->post_meta,'tag') : ''; + } + + echo + '

    '. + '
    '.form::textarea('post_tags',20,3,$value,'maximal',3).'
    '; + } + + public static function setTags(&$cur,&$post_id) + { + $post_id = (integer) $post_id; + + if (isset($_POST['post_tags'])) { + $tags = $_POST['post_tags']; + + $meta = new dcMeta($GLOBALS['core']); + + $meta->delPostMeta($post_id,'tag'); + + foreach ($meta->splitMetaValues($tags) as $tag) { + $meta->setPostMeta($post_id,'tag',$tag); + } + } + } + + public static function postHeaders() + { + $tag_url = $GLOBALS['core']->blog->url.$GLOBALS['core']->url->getBase('tag'); + + return + ''. + '\n". + ''; + } + + public static function adminPostsActionsCombo(&$args) + { + $args[0][__('add tags')] = 'tags'; + + if ($GLOBALS['core']->auth->check('delete,contentadmin',$GLOBALS['core']->blog->id)) { + $args[0][__('remove tags')] = 'tags_remove'; + } + } + + public static function adminPostsActions(&$core,$posts,$action,$redir) + { + if ($action == 'tags' && !empty($_POST['new_tags'])) + { + try + { + $meta = new dcMeta($core); + $tags = $meta->splitMetaValues($_POST['new_tags']); + + while ($posts->fetch()) + { + # Get tags for post + $post_meta = $meta->getMeta('tag',null,null,$posts->post_id); + $pm = array(); + while ($post_meta->fetch()) { + $pm[] = $post_meta->meta_id; + } + + foreach ($tags as $t) { + if (!in_array($t,$pm)) { + $meta->setPostMeta($posts->post_id,'tag',$t); + } + } + } + + http::redirect($redir); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } + } + elseif ($action == 'tags_remove' && !empty($_POST['meta_id']) && $core->auth->check('delete,contentadmin',$core->blog->id)) + { + try + { + $meta = new dcMeta($core); + while ($posts->fetch()) + { + foreach ($_POST['meta_id'] as $v) + { + $meta->delPostMeta($posts->post_id,'tag',$v); + } + } + + http::redirect($redir); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } + } + } + + public static function adminPostsActionsContent($core,$action,$hidden_fields) + { + if ($action == 'tags') + { + echo + '

    '.__('Add tags to entries').'

    '. + '
    '. + '

    '. + + $hidden_fields. + $core->formNonce(). + form::hidden(array('action'),'tags'). + '

    '. + '
    '; + } + elseif ($action == 'tags_remove') + { + $meta = new dcMeta($core); + $tags = array(); + + foreach ($_POST['entries'] as $id) { + $post_tags = $meta->getMeta('tag',null,null,(integer) $id)->rows(); + foreach ($post_tags as $v) { + if (isset($tags[$v['meta_id']])) { + $tags[$v['meta_id']]++; + } else { + $tags[$v['meta_id']] = 1; + } + } + } + + echo '

    '.__('Remove selected tags from entries').'

    '; + + if (empty($tags)) { + echo '

    '.__('No tags for selected entries').'

    '; + return; + } + + $posts_count = count($_POST['entries']); + + echo + '
    '. + '
    '.__('Following tags have been found in selected entries:').''; + + foreach ($tags as $k => $n) { + $label = ''; + if ($posts_count == $n) { + $label = sprintf($label,'%s','%s'); + } + echo '

    '.sprintf($label, + form::checkbox(array('meta_id[]'),html::escapeHTML($k)), + html::escapeHTML($k)). + '

    '; + } + + echo + '

    '. + $hidden_fields. + $core->formNonce(). + form::hidden(array('action'),'tags_remove'). + '
    '; + } + } + + public static function exportFull(&$core,&$exp) + { + $exp->exportTable('meta'); + } + + public static function exportSingle(&$core,&$exp,$blog_id) + { + $exp->export('meta', + 'SELECT meta_id, meta_type, M.post_id '. + 'FROM '.$core->prefix.'meta M, '.$core->prefix.'post P '. + 'WHERE P.post_id = M.post_id '. + "AND P.blog_id = '".$blog_id."'" + ); + } + + public static function importInit(&$bk,&$core) + { + $bk->cur_meta = $core->con->openCursor($core->prefix.'meta'); + $bk->meta = new dcMeta($core); + } + + public static function importFull(&$line,&$bk,&$core) + { + if ($line->__name == 'meta') + { + $bk->cur_meta->clean(); + + $bk->cur_meta->meta_id = (string) $line->meta_id; + $bk->cur_meta->meta_type = (string) $line->meta_type; + $bk->cur_meta->post_id = (integer) $line->post_id; + + $bk->cur_meta->insert(); + } + } + + public static function importSingle(&$line,&$bk,&$core) + { + if ($line->__name == 'meta' && isset($bk->old_ids['post'][(integer) $line->post_id])) + { + $line->post_id = $bk->old_ids['post'][(integer) $line->post_id]; + $bk->meta->setPostMeta($line->post_id,$line->meta_type,$line->meta_id); + } + } + + public static function importPrepareDC12(&$line,&$bk,&$core) + { + if ($line->__name == 'post_meta') + { + $line->drop('meta_id'); + $line->substitute('meta_key','meta_type'); + $line->substitute('meta_value','meta_id'); + $line->__name = 'meta'; + $line->blog_id = 'default'; + } + } +} + +# REST +class metaRest +{ + public static function getMeta(&$core,$get) + { + $meta = new dcMeta($core); + + $postid = !empty($get['postId']) ? $get['postId'] : null; + $limit = !empty($get['limit']) ? $get['limit'] : null; + $metaId = !empty($get['metaId']) ? $get['metaId'] : null; + $metaType = !empty($get['metaType']) ? $get['metaType'] : null; + + $sortby = !empty($get['sortby']) ? $get['sortby'] : 'meta_type,asc'; + + $rs = $meta->getMeta($metaType,$limit,$metaId,$postid); + + $sortby = explode(',',$sortby); + $sort = $sortby[0]; + $order = isset($sortby[1]) ? $sortby[1] : 'asc'; + + switch ($sort) { + case 'metaId': + $sort = 'meta_id_lower'; + break; + case 'count': + $sort = 'count'; + break; + case 'metaType': + $sort = 'meta_type'; + break; + default: + $sort = 'meta_type'; + } + + $rs->sort($sort,$order); + + $rsp = new xmlTag(); + + while ($rs->fetch()) + { + $metaTag = new xmlTag('meta'); + $metaTag->type = $rs->meta_type; + $metaTag->uri = rawurlencode($rs->meta_id); + $metaTag->count = $rs->count; + $metaTag->percent = $rs->percent; + $metaTag->roundpercent = $rs->roundpercent; + $metaTag->CDATA($rs->meta_id); + + $rsp->insertNode($metaTag); + } + + return $rsp; + } + + public static function setPostMeta(&$core,$get,$post) + { + if (empty($post['postId'])) { + throw new Exception('No post ID'); + } + + if (empty($post['meta'])) { + throw new Exception('No meta'); + } + + if (empty($post['metaType'])) { + throw new Exception('No meta type'); + } + + $meta = new dcMeta($core); + + # Get previous meta for post + $post_meta = $meta->getMeta($post['metaType'],null,null,$post['postId']); + $pm = array(); + while ($post_meta->fetch()) { + $pm[] = $post_meta->meta_id; + } + + foreach ($meta->splitMetaValues($post['meta']) as $m) + { + if (!in_array($m,$pm)) { + $meta->setPostMeta($post['postId'],$post['metaType'],$m); + } + } + + return true; + } + + public static function delMeta(&$core,$get,$post) + { + if (empty($post['postId'])) { + throw new Exception('No post ID'); + } + + if (empty($post['metaId'])) { + throw new Exception('No meta ID'); + } + + if (empty($post['metaType'])) { + throw new Exception('No meta type'); + } + + $meta = new dcMeta($core); + + $meta->delPostMeta($post['postId'],$post['metaType'],$post['metaId']); + + return true; + } +} +?> \ No newline at end of file diff --git a/plugins/metadata/_define.php b/plugins/metadata/_define.php new file mode 100644 index 0000000..2ae7b58 --- /dev/null +++ b/plugins/metadata/_define.php @@ -0,0 +1,21 @@ +registerModule( + /* Name */ "Metadata", + /* Description*/ "Metadata for posts", + /* Author */ "Olivier Meunier", + /* Version */ '1.0.2', + /* Permissions */ 'usage,contentadmin' +); +?> \ No newline at end of file diff --git a/plugins/metadata/_install.php b/plugins/metadata/_install.php new file mode 100644 index 0000000..bb30a84 --- /dev/null +++ b/plugins/metadata/_install.php @@ -0,0 +1,47 @@ +plugins->moduleInfo('metadata','version'); + +if (version_compare($core->getVersion('metadata'),$version,'>=')) { + return; +} + +/* Database schema +-------------------------------------------------------- */ +$s = new dbStruct($core->con,$core->prefix); + +$s->meta + ->meta_id ('varchar', 255, false) + ->meta_type ('varchar', 64, false) + ->post_id ('bigint', 0, false) + + ->primary('pk_meta','meta_id','meta_type','post_id') + ; + +$s->post + ->post_meta ('text', 0, true, null) + ; + +$s->meta->index('idx_meta_post_id','btree','post_id'); +$s->meta->index('idx_meta_meta_type','btree','meta_type'); +$s->meta->reference('fk_meta_post','post_id','post','post_id','cascade','cascade'); + + +# Schema installation +$si = new dbStruct($core->con,$core->prefix); +$changes = $si->synchronize($s); + +$core->setVersion('metadata',$version); +return true; +?> \ No newline at end of file diff --git a/plugins/metadata/_prepend.php b/plugins/metadata/_prepend.php new file mode 100644 index 0000000..3269c4a --- /dev/null +++ b/plugins/metadata/_prepend.php @@ -0,0 +1,19 @@ +url->register('tag','tag','^tag/(.+)$',array('urlMetadata','tag')); +$GLOBALS['core']->url->register('tags','tags','^tags$',array('urlMetadata','tags')); +$GLOBALS['core']->url->register('tag_feed','feed/tag','^feed/tag/(.+)$',array('urlMetadata','tagFeed')); + +$GLOBALS['__autoload']['dcMeta'] = dirname(__FILE__).'/class.dc.meta.php'; +?> \ No newline at end of file diff --git a/plugins/metadata/_public.php b/plugins/metadata/_public.php new file mode 100644 index 0000000..635c1ef --- /dev/null +++ b/plugins/metadata/_public.php @@ -0,0 +1,345 @@ +tpl->addBlock('Tags',array('tplMetadata','Tags')); +$core->tpl->addBlock('TagsHeader',array('tplMetadata','TagsHeader')); +$core->tpl->addBlock('TagsFooter',array('tplMetadata','TagsFooter')); +$core->tpl->addBlock('EntryTags',array('tplMetadata','EntryTags')); +$core->tpl->addValue('TagID',array('tplMetadata','TagID')); +$core->tpl->addValue('TagPercent',array('tplMetadata','TagPercent')); +$core->tpl->addValue('TagRoundPercent',array('tplMetadata','TagRoundPercent')); +$core->tpl->addValue('TagURL',array('tplMetadata','TagURL')); +$core->tpl->addValue('TagCloudURL',array('tplMetadata','TagCloudURL')); +$core->tpl->addValue('TagFeedURL',array('tplMetadata','TagFeedURL')); + +# Kept for backward compatibility (for now) +$core->tpl->addBlock('MetaData',array('tplMetadata','Tags')); +$core->tpl->addBlock('MetaDataHeader',array('tplMetadata','TagsHeader')); +$core->tpl->addBlock('MetaDataFooter',array('tplMetadata','TagsFooter')); +$core->tpl->addValue('MetaID',array('tplMetadata','TagID')); +$core->tpl->addValue('MetaPercent',array('tplMetadata','TagPercent')); +$core->tpl->addValue('MetaRoundPercent',array('tplMetadata','TagRoundPercent')); +$core->tpl->addValue('MetaURL',array('tplMetadata','TagURL')); +$core->tpl->addValue('MetaAllURL',array('tplMetadata','TagCloudURL')); +$core->tpl->addBlock('EntryMetaData',array('tplMetadata','EntryTags')); + + + +$core->addBehavior('templateBeforeBlock',array('behaviorsMetadata','templateBeforeBlock')); + +class behaviorsMetadata +{ + public static function templateBeforeBlock(&$core,$b,$attr) + { + if (($b == 'Entries' || $b == 'Comments') && isset($attr['tag'])) + { + return + "prefix.'meta META ';\n". + "@\$params['sql'] .= 'AND META.post_id = P.post_id ';\n". + "\$params['sql'] .= \"AND META.meta_type = 'tag' \";\n". + "\$params['sql'] .= \"AND META.meta_id = '".$core->con->escape($attr['tag'])."' \";\n". + "?>\n"; + } + elseif (empty($attr['no_context']) && ($b == 'Entries' || $b == 'Comments')) + { + return + 'exists("meta")) { '. + "@\$params['from'] .= ', '.\$core->prefix.'meta META ';\n". + "@\$params['sql'] .= 'AND META.post_id = P.post_id ';\n". + "\$params['sql'] .= \"AND META.meta_type = 'tag' \";\n". + "\$params['sql'] .= \"AND META.meta_id = '\".\$core->con->escape(\$_ctx->meta->meta_id).\"' \";\n". + "} ?>\n"; + } + } +} + +class tplMetadata +{ + public static function Tags($attr,$content) + { + $type = isset($attr['type']) ? addslashes($attr['type']) : 'tag'; + + $limit = isset($attr['limit']) ? (integer) $attr['limit'] : 'null'; + + $sortby = 'meta_id_lower'; + if (isset($attr['sortby']) && $attr['sortby'] == 'count') { + $sortby = 'count'; + } + + $order = 'asc'; + if (isset($attr['order']) && $attr['order'] == 'desc') { + $order = 'desc'; + } + + $res = + "meta = \$objMeta->getMeta('".$type."',".$limit."); ". + "\$_ctx->meta->sort('".$sortby."','".$order."'); ". + '?>'; + + $res .= + 'meta->fetch()) : ?>'.$content.'meta = null; unset($objMeta); ?>'; + + return $res; + } + + public static function TagsHeader($attr,$content) + { + return + "meta->isStart()) : ?>". + $content. + ""; + } + + public static function TagsFooter($attr,$content) + { + return + "meta->isEnd()) : ?>". + $content. + ""; + } + + public static function EntryTags($attr,$content) + { + $type = isset($attr['type']) ? addslashes($attr['type']) : 'tag'; + + $sortby = 'meta_id_lower'; + if (isset($attr['sortby']) && $attr['sortby'] == 'count') { + $sortby = 'count'; + } + + $order = 'asc'; + if (isset($attr['order']) && $attr['order'] == 'desc') { + $order = 'desc'; + } + + $res = + "meta = \$objMeta->getMetaRecordset(\$_ctx->posts->post_meta,'".$type."'); ". + "\$_ctx->meta->sort('".$sortby."','".$order."'); ". + '?>'; + + $res .= + 'meta->fetch()) : ?>'.$content.'meta = null; unset($objMeta); ?>'; + + return $res; + } + + public static function TagID($attr) + { + $f = $GLOBALS['core']->tpl->getFilters($attr); + return 'meta->meta_id').'; ?>'; + } + + public static function TagPercent($attr) + { + return 'meta->percent; ?>'; + } + + public static function TagRoundPercent($attr) + { + return 'meta->roundpercent; ?>'; + } + + public static function TagURL($attr) + { + $f = $GLOBALS['core']->tpl->getFilters($attr); + return 'blog->url.$core->url->getBase("tag").'. + '"/".rawurlencode($_ctx->meta->meta_id)').'; ?>'; + } + + public static function TagCloudURL($attr) + { + $f = $GLOBALS['core']->tpl->getFilters($attr); + return 'blog->url.$core->url->getBase("tags")').'; ?>'; + } + + public static function TagFeedURL($attr) + { + $type = !empty($attr['type']) ? $attr['type'] : 'rss2'; + + if (!preg_match('#^(rss2|atom)$#',$type)) { + $type = 'rss2'; + } + + $f = $GLOBALS['core']->tpl->getFilters($attr); + return 'blog->url.$core->url->getBase("tag_feed")."/".'. + 'rawurlencode($_ctx->meta->meta_id)."/'.$type.'"').'; ?>'; + } + + # Widget function + public static function tagsWidget(&$w) + { + global $core; + + $limit = abs((integer) $w->limit); + + $objMeta = new dcMeta($core); + $rs = $objMeta->getMeta('tag',$limit); + + if ($rs->isEmpty()) { + return; + } + + $sort = $w->sortby; + if (!in_array($sort,array('meta_id_lower','count'))) { + $sort = 'meta_id_lower'; + } + + $order = $w->orderby; + if ($order != 'asc') { + $order = 'desc'; + } + + $rs->sort($sort,$order); + + $res = + '
    '. + ($w->title ? '

    '.html::escapeHTML($w->title).'

    ' : ''). + ''; + + if ($core->url->getBase('tags')) + { + $res .= + '

    '. + __('All tags').'

    '; + } + + $res .= '
    '; + + return $res; + } +} + +class urlMetadata extends dcUrlHandlers +{ + public static function tag($args) + { + $n = self::getPageNumber($args); + + if ($args == '' && !$n) + { + self::p404(); + } + elseif (preg_match('%(.*?)/feed/(rss2|atom)?$%u',$args,$m)) + { + $type = $m[2] == 'atom' ? 'atom' : 'rss2'; + $mime = 'application/xml'; + $comments = !empty($m[3]); + + $objMeta = new dcMeta($GLOBALS['core']); + $GLOBALS['_ctx']->meta = $objMeta->getMeta('tag',null,$m[1]); + + if ($GLOBALS['_ctx']->meta->isEmpty()) { + self::p404(); + } + else + { + $tpl = $type; + + if ($type == 'atom') { + $mime = 'application/atom+xml'; + } + + self::serveDocument($tpl.'.xml',$mime); + } + } + else + { + if ($n) { + $GLOBALS['_page_number'] = $n; + } + + $objMeta = new dcMeta($GLOBALS['core']); + $GLOBALS['_ctx']->meta = $objMeta->getMeta('tag',null,$args); + + if ($GLOBALS['_ctx']->meta->isEmpty()) { + self::p404(); + } else { + self::serveDocument('tag.html'); + } + } + } + + public static function tags($args) + { + self::serveDocument('tags.html'); + } + + public static function tagFeed($args) + { + if (!preg_match('#^(.+)/(atom|rss2)(/comments)?$#',$args,$m)) + { + self::p404(); + } + else + { + $tag = $m[1]; + $type = $m[2]; + $comments = !empty($m[3]); + + $objMeta = new dcMeta($GLOBALS['core']); + $GLOBALS['_ctx']->meta = $objMeta->getMeta('tag',null,$tag); + + if ($GLOBALS['_ctx']->meta->isEmpty()) { + # The specified tag does not exist. + self::p404(); + } + else + { + $GLOBALS['_ctx']->feed_subtitle = ' - '.__('Tag').' - '.$GLOBALS['_ctx']->meta->meta_id; + + if ($type == 'atom') { + $mime = 'application/atom+xml'; + } else { + $mime = 'application/xml'; + } + + $tpl = $type; + if ($comments) { + $tpl .= '-comments'; + $GLOBALS['_ctx']->nb_comment_per_page = $GLOBALS['core']->blog->settings->nb_comment_per_feed; + } else { + $GLOBALS['_ctx']->nb_entry_per_page = $GLOBALS['core']->blog->settings->nb_post_per_feed; + $GLOBALS['_ctx']->short_feed_items = $GLOBALS['core']->blog->settings->short_feed_items; + } + $tpl .= '.xml'; + + self::serveDocument($tpl,$mime); + } + } + } +} +?> \ No newline at end of file diff --git a/plugins/metadata/_widgets.php b/plugins/metadata/_widgets.php new file mode 100644 index 0000000..5aeb87b --- /dev/null +++ b/plugins/metadata/_widgets.php @@ -0,0 +1,37 @@ +addBehavior('initWidgets',array('metaWidgets','initWidgets')); +$core->addBehavior('initDefaultWidgets',array('metaWidgets','initDefaultWidgets')); + +class metaWidgets +{ + public static function initWidgets(&$w) + { + $w->create('tags',__('Tags'),array('tplMetadata','tagsWidget')); + $w->tags->setting('title',__('Title:'),__('Tags')); + $w->tags->setting('limit',__('Limit (empty means no limit):'),'20'); + $w->tags->setting('sortby',__('Order by:'),'meta_id_lower','combo', + array(__('Tag name') => 'meta_id_lower', __('Entries count') => 'count') + ); + $w->tags->setting('orderby',__('Sort:'),'asc','combo', + array(__('Ascending') => 'asc', __('Descending') => 'desc') + ); + } + + public static function initDefaultWidgets(&$w,&$d) + { + $d['nav']->append($w->tags); + } +} +?> \ No newline at end of file diff --git a/plugins/metadata/_xmlrpc.php b/plugins/metadata/_xmlrpc.php new file mode 100644 index 0000000..61d0d63 --- /dev/null +++ b/plugins/metadata/_xmlrpc.php @@ -0,0 +1,51 @@ +addBehavior('xmlrpcGetPostInfo',array('metaXMLRPCbehaviors','getPostInfo')); +$core->addBehavior('xmlrpcAfterNewPost',array('metaXMLRPCbehaviors','editPost')); +$core->addBehavior('xmlrpcAfterEditPost',array('metaXMLRPCbehaviors','editPost')); + +class metaXMLRPCbehaviors +{ + public static function getPostInfo(&$x,$type,&$res) + { + $res =& $res[0]; + + $meta = new dcMeta($x->core); + $rs = $meta->getMeta('tag',null,null,$res['postid']); + + $m = array(); + while($rs->fetch()) { + $m[] = $rs->meta_id; + } + + $res['mt_keywords'] = implode(', ',$m); + } + + # Same function for newPost and editPost + public static function editPost($x,$post_id,&$cur,$content,$struct,$publish) + { + # Check if we have mt_keywords in struct + if (isset($struct['mt_keywords'])) + { + $meta = new dcMeta($x->core); + + $meta->delPostMeta($post_id,'tag'); + + foreach ($meta->splitMetaValues($struct['mt_keywords']) as $m) { + $meta->setPostMeta($post_id,'tag',$m); + } + } + } +} +?> \ No newline at end of file diff --git a/plugins/metadata/class.dc.meta.php b/plugins/metadata/class.dc.meta.php new file mode 100644 index 0000000..aff5df1 --- /dev/null +++ b/plugins/metadata/class.dc.meta.php @@ -0,0 +1,422 @@ +core =& $core; + $this->con =& $this->core->con; + $this->table = $this->core->prefix.'meta'; + } + + public function splitMetaValues($str) + { + $res = array(); + foreach (explode(',',$str) as $i => $tag) + { + $tag = trim($tag); + $tag = self::sanitizeMetaID($tag); + + if ($tag) { + $res[$i] = $tag; + } + } + + return array_unique($res); + } + + public static function sanitizeMetaID($str) + { + return text::tidyURL($str,false,true); + } + + public function getMetaArray($str) + { + $meta = @unserialize($str); + + if (!is_array($meta)) { + return array(); + } + + return $meta; + } + + public function getMetaStr($str,$type) + { + $meta = $this->getMetaArray($str); + + if (!isset($meta[$type])) { + return ''; + } + + return implode(', ',$meta[$type]); + } + + public function getMetaRecordset($str,$type) + { + $meta = $this->getMetaArray($str); + $data = array(); + + if (isset($meta[$type])) + { + foreach ($meta[$type] as $v) + { + $data[] = array( + 'meta_id' => $v, + 'meta_type' => $type, + 'meta_id_lower' => mb_strtolower($v), + 'count' => 0, + 'percent' => 0, + 'roundpercent' => 0 + ); + } + } + + return staticRecord::newFromArray($data); + } + + public static function getMetaRecord(&$core,$str,$type) + { + $meta = new self($core); + return $meta->getMetaRecordset($str,$type); + } + + private function checkPermissionsOnPost($post_id) + { + $post_id = (integer) $post_id; + + if (!$this->core->auth->check('usage,contentadmin',$this->core->blog->id)) { + throw new Exception(__('You are not allowed to change this entry status')); + } + + #�If user can only publish, we need to check the post's owner + if (!$this->core->auth->check('contentadmin',$this->core->blog->id)) + { + $strReq = 'SELECT post_id '. + 'FROM '.$this->core->prefix.'post '. + 'WHERE post_id = '.$post_id.' '. + "AND user_id = '".$this->con->escape($this->core->auth->userID())."' "; + + $rs = $this->con->select($strReq); + + if ($rs->isEmpty()) { + throw new Exception(__('You are not allowed to change this entry status')); + } + } + } + + private function updatePostMeta($post_id) + { + $post_id = (integer) $post_id; + + $strReq = 'SELECT meta_id, meta_type '. + 'FROM '.$this->table.' '. + 'WHERE post_id = '.$post_id.' '; + + $rs = $this->con->select($strReq); + + $meta = array(); + while ($rs->fetch()) { + $meta[$rs->meta_type][] = $rs->meta_id; + } + + $post_meta = serialize($meta); + + $cur = $this->con->openCursor($this->core->prefix.'post'); + $cur->post_meta = $post_meta; + + $cur->update('WHERE post_id = '.$post_id); + $this->core->blog->triggerBlog(); + } + + public function getPostsByMeta($params=array(),$count_only=false) + { + if (!isset($params['meta_id'])) { + return null; + } + + $params['from'] = ', '.$this->table.' META '; + $params['sql'] = 'AND META.post_id = P.post_id '; + + $params['sql'] .= "AND META.meta_id = '".$this->con->escape($params['meta_id'])."' "; + + if (!empty($params['meta_type'])) { + $params['sql'] .= "AND META.meta_type = '".$this->con->escape($params['meta_type'])."' "; + unset($params['meta_type']); + } + + unset($params['meta_id']); + + return $this->core->blog->getPosts($params,$count_only); + } + + public function getCommentsByMeta($params=array(),$count_only=false) + { + if (!isset($params['meta_id'])) { + return null; + } + + $params['from'] = ', '.$this->table.' META '; + $params['sql'] = 'AND META.post_id = P.post_id '; + $params['sql'] .= "AND META.meta_id = '".$this->con->escape($params['meta_id'])."' "; + + if (!empty($params['meta_type'])) { + $params['sql'] .= "AND META.meta_type = '".$this->con->escape($params['meta_type'])."' "; + unset($params['meta_type']); + } + + return $this->core->blog->getComments($params,$count_only); + } + + public function getMeta($type=null,$limit=null,$meta_id=null,$post_id=null) + { + $strReq = 'SELECT meta_id, meta_type, COUNT(M.post_id) as count '. + 'FROM '.$this->table.' M LEFT JOIN '.$this->core->prefix.'post P '. + 'ON M.post_id = P.post_id '. + "WHERE P.blog_id = '".$this->con->escape($this->core->blog->id)."' "; + + if ($type !== null) { + $strReq .= " AND meta_type = '".$this->con->escape($type)."' "; + } + + if ($meta_id !== null) { + $strReq .= " AND meta_id = '".$this->con->escape($meta_id)."' "; + } + + if ($post_id !== null) { + $strReq .= ' AND P.post_id = '.(integer) $post_id.' '; + } + + if (!$this->core->auth->check('contentadmin',$this->core->blog->id)) { + $strReq .= 'AND ((post_status = 1 '; + + if ($this->core->blog->without_password) { + $strReq .= 'AND post_password IS NULL '; + } + $strReq .= ') '; + + if ($this->core->auth->userID()) { + $strReq .= "OR P.user_id = '".$this->con->escape($this->core->auth->userID())."')"; + } else { + $strReq .= ') '; + } + } + + $strReq .= + 'GROUP BY meta_id,meta_type,P.blog_id '. + 'ORDER BY count DESC'; + + if ($limit) { + $strReq .= $this->con->limit($limit); + } + + $rs = $this->con->select($strReq); + $rs = $rs->toStatic(); + + $max = array(); + while ($rs->fetch()) + { + $type = $rs->meta_type; + if (!isset($max[$type])) { + $max[$type] = $rs->count; + } else { + if ($rs->count > $max[$type]) { + $max[$type] = $rs->count; + } + } + } + + while ($rs->fetch()) + { + $rs->set('meta_id_lower',mb_strtolower($rs->meta_id)); + + $count = $rs->count; + $percent = ((integer) $rs->count) * 100 / $max[$rs->meta_type]; + + $rs->set('percent',(integer) round($percent)); + $rs->set('roundpercent',round($percent/10)*10); + } + + return $rs; + } + + public function setPostMeta($post_id,$type,$value) + { + $this->checkPermissionsOnPost($post_id); + + $value = trim($value); + if (!$value) { return; } + + $cur = $this->con->openCursor($this->table); + + $cur->post_id = (integer) $post_id; + $cur->meta_id = (string) $value; + $cur->meta_type = (string) $type; + + $cur->insert(); + $this->updatePostMeta((integer) $post_id); + } + + public function delPostMeta($post_id,$type=null,$meta_id=null) + { + $post_id = (integer) $post_id; + + $this->checkPermissionsOnPost($post_id); + + $strReq = 'DELETE FROM '.$this->table.' '. + 'WHERE post_id = '.$post_id; + + if ($type !== null) { + $strReq .= " AND meta_type = '".$this->con->escape($type)."' "; + } + + if ($meta_id !== null) { + $strReq .= " AND meta_id = '".$this->con->escape($meta_id)."' "; + } + + $this->con->execute($strReq); + $this->updatePostMeta((integer) $post_id); + } + + public function updateMeta($meta_id,$new_meta_id,$type=null,$post_type=null) + { + $new_meta_id = self::sanitizeMetaID($new_meta_id); + + if ($new_meta_id == $meta_id) { + return true; + } + + $getReq = 'SELECT M.post_id '. + 'FROM '.$this->table.' M, '.$this->core->prefix.'post P '. + 'WHERE P.post_id = M.post_id '. + "AND P.blog_id = '".$this->con->escape($this->core->blog->id)."' ". + "AND meta_id = '%s' "; + + if (!$this->core->auth->check('contentadmin',$this->core->blog->id)) { + $getReq .= "AND P.user_id = '".$this->con->escape($this->core->auth->userID())."' "; + } + if ($post_type !== null) { + $getReq .= "AND P.post_type = '".$this->con->escape($post_type)."' "; + } + + $delReq = 'DELETE FROM '.$this->table.' '. + 'WHERE post_id IN (%s) '. + "AND meta_id = '%s' "; + + $updReq = 'UPDATE '.$this->table.' '. + "SET meta_id = '%s' ". + 'WHERE post_id IN (%s) '. + "AND meta_id = '%s' "; + + if ($type !== null) { + $plus = " AND meta_type = '%s' "; + $getReq .= $plus; + $delReq .= $plus; + $updReq .= $plus; + } + + $to_update = $to_remove = array(); + + $rs = $this->con->select(sprintf($getReq,$this->con->escape($meta_id), + $this->con->escape($type))); + + while ($rs->fetch()) { + $to_update[] = $rs->post_id; + } + + if (empty($to_update)) { + return false; + } + + $rs = $this->con->select(sprintf($getReq,$new_meta_id,$type)); + while ($rs->fetch()) { + if (in_array($rs->post_id,$to_update)) { + $to_remove[] = $rs->post_id; + unset($to_update[array_search($rs->post_id,$to_update)]); + } + } + + # Delete duplicate meta + if (!empty($to_remove)) + { + $this->con->execute(sprintf($delReq,implode(',',$to_remove), + $this->con->escape($meta_id), + $this->con->escape($type))); + + foreach ($to_remove as $post_id) { + $this->updatePostMeta($post_id); + } + } + + # Update meta + if (!empty($to_update)) + { + $this->con->execute(sprintf($updReq,$this->con->escape($new_meta_id), + implode(',',$to_update), + $this->con->escape($meta_id), + $this->con->escape($type))); + + foreach ($to_update as $post_id) { + $this->updatePostMeta($post_id); + } + } + + return true; + } + + public function delMeta($meta_id,$type=null,$post_type=null) + { + $strReq = 'SELECT M.post_id '. + 'FROM '.$this->table.' M, '.$this->core->prefix.'post P '. + 'WHERE P.post_id = M.post_id '. + "AND P.blog_id = '".$this->con->escape($this->core->blog->id)."' ". + "AND meta_id = '".$this->con->escape($meta_id)."' "; + + if ($type !== null) { + $strReq .= " AND meta_type = '".$this->con->escape($type)."' "; + } + + if ($post_type !== null) { + $strReq .= " AND P.post_type = '".$this->con->escape($post_type)."' "; + } + + $rs = $this->con->select($strReq); + + $ids = array(); + while ($rs->fetch()) { + $ids[] = $rs->post_id; + } + + $strReq = 'DELETE FROM '.$this->table.' '. + 'WHERE post_id IN ('.implode(',',$ids).') '. + "AND meta_id = '".$this->con->escape($meta_id)."' "; + + if ($type !== null) { + $strReq .= " AND meta_type = '".$this->con->escape($type)."' "; + } + + $rs = $this->con->execute($strReq); + + foreach ($ids as $post_id) { + $this->updatePostMeta($post_id); + } + + return $ids; + } +} +?> diff --git a/plugins/metadata/index.php b/plugins/metadata/index.php new file mode 100644 index 0000000..501206d --- /dev/null +++ b/plugins/metadata/index.php @@ -0,0 +1,22 @@ + \ No newline at end of file diff --git a/plugins/metadata/post.js b/plugins/metadata/post.js new file mode 100644 index 0000000..6512830 --- /dev/null +++ b/plugins/metadata/post.js @@ -0,0 +1,17 @@ + +$(function(){$('#edit-entry').onetabload(function(){var meta_edit_tags=$('#meta-edit-tags');var post_id=$('#id');var meta_field=null;if(meta_edit_tags.length>0){post_id=(post_id.length>0)?post_id.get(0).value:false;if(post_id==false){meta_field=$('');meta_field.val($('#post_tags').val());} +var mEdit=new metaEditor(meta_edit_tags,meta_field);mEdit.displayMeta('tag',post_id);window.dc_tag_editor=mEdit;}});});function metaEditor(target,meta_field){this.target=target;this.meta_field=meta_field;};metaEditor.prototype={meta_ur:'',text_confirm_remove:'Are you sure you want to remove this %s?',text_add_meta:'Add a %s to this entry',text_choose:'Choose from list',text_all:'all',target:null,meta_type:null,meta_dialog:null,meta_field:null,post_id:false,service_uri:'services.php',displayMeta:function(type,post_id){this.meta_type=type;this.post_id=post_id;this.target.empty();this.meta_dialog=$('');this.meta_dialog.attr('title',this.text_add_meta.replace(/%s/,this.meta_type));var This=this;this.addMetaDialog();if(this.post_id==false){this.target.append(this.meta_field);} +this.displayMetaList();},displayMetaList:function(){var li;if(this.meta_list==undefined){this.meta_list=$('
      ');this.target.prepend(this.meta_list);} +if(this.post_id==false){var meta=this.splitMetaValues(this.meta_field.val());this.meta_list.empty();for(var i=0;i'+meta[i]+'');a_remove=$('[x]');a_remove.get(0).caller=this;a_remove.get(0).meta_id=meta[i];a_remove.click(function(){this.caller.removeMeta(this.meta_id);return false;});li.append(' ').append(a_remove);this.meta_list.append(li);}}else{var This=this;var params={f:'getMeta',metaType:this.meta_type,sortby:'metaId,asc',postId:this.post_id};$.get(this.service_uri,params,function(data){data=$(data);if(data.find('rsp').attr('status')!='ok'){return;} +This.meta_list.empty();data.find('meta').each(function(){var meta_id=$(this).text();li=$('
    • '+meta_id+'
    • ');a_remove=$('[x]');a_remove.get(0).caller=This;a_remove.get(0).meta_id=meta_id;a_remove.click(function(){this.caller.removeMeta(this.meta_id);return false;});li.append(' ').append(a_remove);This.meta_list.append(li);});});}},addMetaDialog:function(){var This=this;this.meta_dialog.keypress(function(evt){if(evt.keyCode==13){This.addMeta(this.value);return false;} +return true;});var S=$('');S.click(function(){var v=This.meta_dialog.val();This.addMeta(v);return false;});this.target.append($('

      ').append(this.meta_dialog).append(' ').append(S));var a=$(''+this.text_choose+'');a.click(function(){This.showMetaList('more',$(this).parent());return false;});this.target.append($('

      ').append(a));},showMetaList:function(type,target){target.empty();target.append('...');target.addClass('addMeta');var params={f:'getMeta',metaType:this.meta_type,sortby:'metaId,asc'};if(type=='more'){params.limit='30';} +var This=this;$.get(this.service_uri,params,function(data){if($(data).find('meta').length>0){target.empty();var meta_link;$(data).find('meta').each(function(i){meta_link=$(''+$(this).text()+'');meta_link.get(0).meta_id=$(this).text();meta_link.click(function(){var v=This.splitMetaValues(This.meta_dialog.val()+','+this.meta_id);This.meta_dialog.val(v.join(','));return false;});if(i>0){target.append(', ');} +target.append(meta_link);});if(type=='more'){var a_more=$('');a_more.append(This.text_all+String.fromCharCode(160)+String.fromCharCode(187));a_more.click(function(){This.showMetaList('all',target);return false;});target.append(', ').append(a_more);}}else{target.empty();}});},addMeta:function(str){str=this.splitMetaValues(str).join(',');if(this.post_id==false){str=this.splitMetaValues(this.meta_field.val()+','+str);this.meta_field.val(str);this.meta_dialog.val('');this.displayMetaList();}else{var params={xd_check:dotclear.nonce,f:'setPostMeta',postId:this.post_id,metaType:this.meta_type,meta:str};var This=this;$.post(this.service_uri,params,function(data){if($(data).find('rsp').attr('status')=='ok'){This.meta_dialog.val('');This.displayMetaList();}else{alert($(data).find('message').text());}});}},removeMeta:function(meta_id){if(this.post_id==false){var meta=this.splitMetaValues(this.meta_field.val());for(var i=0;i'+str+'';}});};jsToolBar.prototype.elements.tag.fn.wysiwyg=function(){var t=this.getSelectedText();if(t==''){window.alert(dotclear.msg.no_selection);return;} +if(t.indexOf(',')!=-1){return;} +var n=this.getSelectedNode();var a=document.createElement('a');a.href=this.stripBaseURL(this.elements.tag.url+'/'+t);a.appendChild(n);this.insertNode(a);window.dc_tag_editor.addMeta(t);}; \ No newline at end of file diff --git a/plugins/metadata/style.css b/plugins/metadata/style.css new file mode 100644 index 0000000..4e275bb --- /dev/null +++ b/plugins/metadata/style.css @@ -0,0 +1,56 @@ +.meta0 { } +.meta10 { font-size: 140%; } +.meta20 { font-size: 150%; } +.meta30 { font-size: 160%; } +.meta40 { font-size: 170%; } +.meta50 { font-size: 180%; } +.meta60 { font-size: 190%; } +.meta70 { font-size: 200%; } +.meta80 { font-size: 210%; } +.meta90 { font-size: 220%; } +.meta100 { font-size: 230%; } + +table.tags { + margin-left: 3em; +} + + +tr.tagLetter span { + font-size : 250%; + border: none; + display : block; + width: 1ex; + position: relative; + top: 0.80em; + left: -2ex; +} + +ul.metaList { + margin: 0 0 1em 0; + padding: 0; +} +ul.metaList li { + margin: 0; + padding: 0; + list-style: square; + list-style-position: inside; +} + +a.metaRemove { + color : #999 !important; + border: none; +} +a.metaRemove:hover, a.metaRemove:focus { + color : #06c !important; +} + +.addMeta a { + border: none; +} +.addMeta a:hover, .addMeta a:focus { + background: #fc0; + color: #000; +} +.addMeta a.metaGetMore { + font-weight: bold; +} \ No newline at end of file diff --git a/plugins/metadata/tag-add.png b/plugins/metadata/tag-add.png new file mode 100644 index 0000000000000000000000000000000000000000..d0facbedebdb4c78fe80660853089a1f832818db GIT binary patch literal 568 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJbFq_W2nPqp?T7vkfZR&~J|V9E z|Nq~+cki}s+t#dEvvldwnKNhh_V%{4v|trskYs=;#?%6o0vh%1|NrmbzrTC;?%db^ z&!0cPd-v|q*9(?D`+x1)wFQs?Y;L>sCF3@ctFnR60{Xj*W1s;*b z3=CW!K$y{KjmZq4phAgjL`iUdT1k0gQ7VIPVscS_ZfZ(qqJmpyQEGX9QFgI{Z^Z72 zS}H)bYdl>XLnOj|&psDwG7w;S5D}yd8zSxZ){;hwadg#T!-T7tTIyyJ% zOjGjo5x5xni+z{t|D#N9SvMAb_FKLZ;l=M^PDM;o%zJ9j*)pqTD_(sj z;HGUidDF?oB2gONBK2I$raTJ&@v*8tPQ-BWw$dq=Z%XDn`_=_nYw+K0yK6Sd!AnD* z{r_&m2}RTQeP_2&;Z@vjP|#fAykt?v-WAIy^52veU;FsLkJmtVGkCiCxvXupdateMeta($tag,$new_id,'tag')) { + http::redirect($p_url.'&m=tag_posts&tag='.$new_id.'&renamed=1'); + } + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} + +# Delete a tag +if (!empty($_POST['delete']) && $core->auth->check('publish,contentadmin',$core->blog->id)) +{ + try { + $meta->delMeta($tag,'tag'); + http::redirect($p_url.'&m=tags&del=1'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} + +$params = array(); +$params['limit'] = array((($page-1)*$nb_per_page),$nb_per_page); +$params['no_content'] = true; + +$params['meta_id'] = $tag; +$params['meta_type'] = 'tag'; +$params['post_type'] = ''; + +# Get posts +try { + $posts = $meta->getPostsByMeta($params); + $counter = $meta->getPostsByMeta($params,true); + $post_list = new adminPostList($core,$posts,$counter->f(0)); +} catch (Exception $e) { + $core->error->add($e->getMessage()); +} + +# Actions combo box +$combo_action = array(); +if ($core->auth->check('publish,contentadmin',$core->blog->id)) +{ + $combo_action[__('publish')] = 'publish'; + $combo_action[__('unpublish')] = 'unpublish'; + $combo_action[__('schedule')] = 'schedule'; + $combo_action[__('mark as pending')] = 'pending'; +} +$combo_action[__('mark as selected')] = 'selected'; +$combo_action[__('mark as unselected')] = 'unselected'; +$combo_action[__('change category')] = 'category'; +if ($core->auth->check('delete,contentadmin',$core->blog->id)) { + $combo_action[__('delete')] = 'delete'; +} +$combo_action[__('add tags')] = 'tags'; +if ($core->auth->check('delete,contentadmin',$core->blog->id)) { + $combo_action[__('remove tags')] = 'tags_remove'; +} + +?> + + + Tags + + + + + + +

      blog->name); ?> › +

      + +'.__('Tag has been successfully renamed').'

      '; +} + +echo '

      '.__('Back to tags list').'

      '; + +if (!$core->error->flag()) +{ + if (!$posts->isEmpty()) + { + echo + '
      '. + '

      '. + $core->formNonce().'

      '. + '
      '; + } + + # Show posts + $post_list->display($page,$nb_per_page, + '
      '. + + '%s'. + + '
      '. + '

      '. + + '

      '.__('Selected entries action:').' '. + form::combo('action',$combo_action). + '

      '. + form::hidden('post_type',''). + form::hidden('redir',$p_url.'&m=tag_posts&tag='. + str_replace('%','%%',rawurlencode($tag)).'&page='.$page). + $core->formNonce(). + '
      '. + '
      '); + + # Remove tag + if (!$posts->isEmpty() && $core->auth->check('contentadmin',$core->blog->id)) { + echo + '
      '. + '

      '. + $core->formNonce().'

      '. + '
      '; + } +} +?> + + diff --git a/plugins/metadata/tags.php b/plugins/metadata/tags.php new file mode 100644 index 0000000..677e6b0 --- /dev/null +++ b/plugins/metadata/tags.php @@ -0,0 +1,77 @@ + + + + Tags + + + + +

      blog->name); ?> › +

      + +'.__('Tag has been successfully removed').'

      '; +} + +$meta = new dcMeta($core); + +$tags = $meta->getMeta('tag'); +$tags->sort('meta_id_lower','asc'); + +$last_letter = null; +$cols = array('',''); +$col = 0; +while ($tags->fetch()) +{ + $letter = mb_strtoupper(mb_substr($tags->meta_id,0,1)); + + if ($last_letter != $letter) { + if ($tags->index() >= round($tags->count()/2)) { + $col = 1; + } + $cols[$col] .= ''.$letter.''; + } + + $cols[$col] .= + ''. + ''.$tags->meta_id.''. + ''.$tags->count.' '.__('entries').''. + ''; + + $last_letter = $letter; +} + +$table = '
      %s
      '; + +if ($cols[0]) +{ + echo '
      '; + printf($table,$cols[0]); + if ($cols[1]) { + printf($table,$cols[1]); + } + echo '
      '; +} +else +{ + echo '

      '.__('No tags on this blog.').'

      '; +} +?> + + + \ No newline at end of file diff --git a/plugins/metadata/tags.png b/plugins/metadata/tags.png new file mode 100644 index 0000000000000000000000000000000000000000..9db1d4ce4ba2938e48e12d41bc25dbaee16f174d GIT binary patch literal 477 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJbFq_W2nPqp?T7vkfZUk@J|V9E z|Nq~zWy{*NYnLrsHgo38o}QkTmX_-3YBVlT0Yn+5VxS2>fau4Mm%sl%{qg_koBvOr zK0WyA|Gj(nu3x`C=kEV$H~*hGbLQyLqkH!3Njn3wF5&3^n4|xr_x%SN>%Hec&@Pu< z{~fpg_uTs5V(Wj1GcMar{SS1cSV@pyFoPf%C>eu*%bC0Hz@R3gl>?}Pv%n*=n1O-o z0|+xZtudJa6jUg2jVKAuPb(=;EJ|hYO-wGz&rMCqOjK~oEJ`iUFUl@f@Qv6#QA-7= zw%60eF+?If^vq46CIbPNi-q^gGewh|1e7{7e*Kq!&LYhH>+QUiQeHx5jb%T1C#d^g zZ*IGC%IiIU+cbBFyK^%%Hakf;+WsDZmvzKk+Em?Ux2eDd5B%}>qQ>O1$}_Wdq&HjOi6b!VF6?#^fH_U9xCZgTdJ R7X&(t!PC{xWt~$(697Ce;H>}v literal 0 HcmV?d00001 diff --git a/plugins/pages/_admin.php b/plugins/pages/_admin.php new file mode 100644 index 0000000..e78a240 --- /dev/null +++ b/plugins/pages/_admin.php @@ -0,0 +1,27 @@ +addBehavior('adminDashboardIcons','pages_dashboard'); +function pages_dashboard(&$core,&$icons) +{ + $icons['pages'] = new ArrayObject(array(__('Pages'),'plugin.php?p=pages','index.php?pf=pages/icon-big.png')); +} + +$_menu['Blog']->addItem(__('Pages'),'plugin.php?p=pages','index.php?pf=pages/icon.png', + preg_match('/plugin.php\?p=pages(&.*)?$/',$_SERVER['REQUEST_URI']), + $core->auth->check('contentadmin,pages',$core->blog->id)); + +$core->auth->setPermissionType('pages',__('manage pages')); + +require dirname(__FILE__).'/_widgets.php'; +?> \ No newline at end of file diff --git a/plugins/pages/_define.php b/plugins/pages/_define.php new file mode 100644 index 0000000..94e919b --- /dev/null +++ b/plugins/pages/_define.php @@ -0,0 +1,22 @@ +registerModule( + /* Name */ "Pages", + /* Description*/ "Serve entries as simple web pages", + /* Author */ "Olivier Meunier", + /* Version */ '1.0', + /* Permissions */ 'contentadmin,pages', + 999 +); +?> \ No newline at end of file diff --git a/plugins/pages/_prepend.php b/plugins/pages/_prepend.php new file mode 100644 index 0000000..b4ae6f8 --- /dev/null +++ b/plugins/pages/_prepend.php @@ -0,0 +1,21 @@ +url->register('pages','pages','^pages/(.+)$',array('urlPages','pages')); +$core->url->register('pagespreview','pagespreview','^pagespreview/(.+)$',array('urlPages','pagespreview')); + +$core->setPostType('page','plugin.php?p=pages&act=page&id=%d',$core->url->getBase('pages').'/%s'); + +# We should put this as settings later +$GLOBALS['page_url_format'] = '{t}'; +?> \ No newline at end of file diff --git a/plugins/pages/_public.php b/plugins/pages/_public.php new file mode 100644 index 0000000..4fdf779 --- /dev/null +++ b/plugins/pages/_public.php @@ -0,0 +1,265 @@ +blog->withoutPassword(false); + + $params = new ArrayObject(); + $params['post_type'] = 'page'; + $params['post_url'] = $args; + + $_ctx->posts = $core->blog->getPosts($params); + + $_ctx->comment_preview = new ArrayObject(); + $_ctx->comment_preview['content'] = ''; + $_ctx->comment_preview['rawcontent'] = ''; + $_ctx->comment_preview['name'] = ''; + $_ctx->comment_preview['mail'] = ''; + $_ctx->comment_preview['site'] = ''; + $_ctx->comment_preview['preview'] = false; + $_ctx->comment_preview['remember'] = false; + + $core->blog->withoutPassword(true); + + + if ($_ctx->posts->isEmpty()) + { + # The specified page does not exist. + self::p404(); + } + else + { + $post_id = $_ctx->posts->post_id; + $post_password = $_ctx->posts->post_password; + + # Password protected entry + if ($post_password != '' && !$_ctx->preview) + { + # Get passwords cookie + if (isset($_COOKIE['dc_passwd'])) { + $pwd_cookie = unserialize($_COOKIE['dc_passwd']); + } else { + $pwd_cookie = array(); + } + + # Check for match + if ((!empty($_POST['password']) && $_POST['password'] == $post_password) + || (isset($pwd_cookie[$post_id]) && $pwd_cookie[$post_id] == $post_password)) + { + $pwd_cookie[$post_id] = $post_password; + setcookie('dc_passwd',serialize($pwd_cookie),0,'/'); + } + else + { + self::serveDocument('password-form.html','text/html',false); + return; + } + } + + $post_comment = + isset($_POST['c_name']) && isset($_POST['c_mail']) && + isset($_POST['c_site']) && isset($_POST['c_content']) && + $_ctx->posts->commentsActive(); + + # Posting a comment + if ($post_comment) + { + # Spam trap + if (!empty($_POST['f_mail'])) { + http::head(412,'Precondition Failed'); + header('Content-Type: text/plain'); + echo "So Long, and Thanks For All the Fish"; + # Exits immediately the application to preserve the server. + exit; + } + + $name = $_POST['c_name']; + $mail = $_POST['c_mail']; + $site = $_POST['c_site']; + $content = $_POST['c_content']; + $preview = !empty($_POST['preview']); + + if ($content != '') + { + if ($core->blog->settings->wiki_comments) { + $core->initWikiComment(); + } else { + $core->initWikiSimpleComment(); + } + $content = $core->wikiTransform($content); + $content = $core->HTMLfilter($content); + } + + $_ctx->comment_preview['content'] = $content; + $_ctx->comment_preview['rawcontent'] = $_POST['c_content']; + $_ctx->comment_preview['name'] = $name; + $_ctx->comment_preview['mail'] = $mail; + $_ctx->comment_preview['site'] = $site; + + if ($preview) + { + # --BEHAVIOR-- publicBeforeCommentPreview + $core->callBehavior('publicBeforeCommentPreview',$_ctx->comment_preview); + + $_ctx->comment_preview['preview'] = true; + } + else + { + # Post the comment + $cur = $core->con->openCursor($core->prefix.'comment'); + $cur->comment_author = $name; + $cur->comment_site = html::clean($site); + $cur->comment_email = html::clean($mail); + $cur->comment_content = $content; + $cur->post_id = $_ctx->posts->post_id; + $cur->comment_status = $core->blog->settings->comments_pub ? 1 : -1; + $cur->comment_ip = http::realIP(); + + $redir = $_ctx->posts->getURL(); + $redir .= strpos($redir,'?') !== false ? '&' : '?'; + + try + { + if (!text::isEmail($cur->comment_email)) { + throw new Exception(__('You must provide a valid email address.')); + } + + # --BEHAVIOR-- publicBeforeCommentCreate + $core->callBehavior('publicBeforeCommentCreate',$cur); + if ($cur->post_id) { + $comment_id = $core->blog->addComment($cur); + + # --BEHAVIOR-- publicAfterCommentCreate + $core->callBehavior('publicAfterCommentCreate',$cur,$comment_id); + } + + if ($cur->comment_status == 1) { + $redir_arg = 'pub=1'; + } else { + $redir_arg = 'pub=0'; + } + + header('Location: '.$redir.$redir_arg); + } + catch (Exception $e) + { + $_ctx->form_error = $e->getMessage(); + $_ctx->form_error; + } + } + } + + # The entry + $core->tpl->setPath($core->tpl->getPath(), dirname(__FILE__).'/default-templates'); + self::serveDocument('page.html'); + } + } + } + + public static function pagespreview($args) + { + $core = $GLOBALS['core']; + $_ctx = $GLOBALS['_ctx']; + + if (!preg_match('#^(.+?)/([0-9a-z]{40})/(.+?)$#',$args,$m)) { + # The specified Preview URL is malformed. + self::p404(); + } + else + { + $user_id = $m[1]; + $user_key = $m[2]; + $post_url = $m[3]; + if (!$core->auth->checkUser($user_id,null,$user_key)) { + # The user has no access to the entry. + self::p404(); + } + else + { + $_ctx->preview = true; + self::pages($post_url); + } + } + } +} + +class tplPages +{ + # Widget function + public static function pagesWidget(&$w) + { + global $core, $_ctx; + + if ($w->homeonly && $core->url->type != 'default') { + return; + } + + $params['post_type'] = 'page'; + $params['limit'] = abs((integer) $w->limit); + $params['no_content'] = true; + + $sort = $w->sortby; + if (!in_array($sort,array('post_title','post_position','post_dt'))) { + $sort = 'post_title'; + } + + $order = $w->orderby; + if ($order != 'asc') { + $order = 'desc'; + } + $params['order'] = $sort.' '.$order; + + $rs = $core->blog->getPosts($params); + + if ($rs->isEmpty()) { + return; + } + + $res = + '
      '. + ($w->title ? '

      '.html::escapeHTML($w->title).'

      ' : ''). + '
        '; + + while ($rs->fetch()) { + $class = ''; + if (($core->url->type == 'pages' && $_ctx->posts instanceof record && $_ctx->posts->post_id == $rs->post_id)) { + $class = ' class="page-current"'; + } + $res .= ''. + html::escapeHTML($rs->post_title).''; + } + + $res .= '
      '; + + return $res; + } +} +?> diff --git a/plugins/pages/_widgets.php b/plugins/pages/_widgets.php new file mode 100644 index 0000000..d89ef39 --- /dev/null +++ b/plugins/pages/_widgets.php @@ -0,0 +1,41 @@ +addBehavior('initWidgets',array('pagesWidgets','initWidgets')); +$core->addBehavior('initDefaultWidgets',array('pagesWidgets','initDefaultWidgets')); + +class pagesWidgets +{ + public static function initWidgets(&$w) + { + $w->create('pages',__('Pages'),array('tplPages','pagesWidget')); + $w->pages->setting('title',__('Title:'),__('Pages')); + $w->pages->setting('homeonly',__('Home page only'),1,'check'); + $w->pages->setting('sortby',__('Order by:'),'meta_id_lower','combo', + array( + __('Page title') => 'post_title', + __('Page position') => 'post_position', + __('Publication date') => 'post_dt' + ) + ); + $w->pages->setting('orderby',__('Sort:'),'asc','combo', + array(__('Ascending') => 'asc', __('Descending') => 'desc') + ); + } + + public static function initDefaultWidgets(&$w,&$d) + { + $d['extra']->append($w->pages); + } +} +?> \ No newline at end of file diff --git a/plugins/pages/default-templates/page.html b/plugins/pages/default-templates/page.html new file mode 100644 index 0000000..2aa53e0 --- /dev/null +++ b/plugins/pages/default-templates/page.html @@ -0,0 +1,250 @@ + + + + + + + + {{tpl:EntryTitle encode_html="1"}} - {{tpl:BlogName encode_html="1"}} + + + + + + + + + + + + + + + + + + + + + + {{tpl:include src="_head.html"}} + + + + + + +
      +{{tpl:EntryPingData}} + +{{tpl:include src="_top.html"}} + +
      + +
      +
      + +
      +

      {{tpl:EntryTitle encode_html="1"}}

      + + + {{tpl:SysBehavior behavior="publicEntryBeforeContent"}} + + +
      {{tpl:EntryExcerpt}}
      +
      +
      {{tpl:EntryContent}}
      + +

      {{tpl:lang Published on}} {{tpl:EntryDate}} + {{tpl:lang by}} {{tpl:EntryAuthorLink}}

      + + + {{tpl:SysBehavior behavior="publicEntryAfterContent"}} +
      + + + + +
      +

      {{tpl:lang Attachments}}

      +
        + +
      • + + {{tpl:include src="_mp3_player.html"/}} - + + + {{tpl:include src="_flv_player.html"/}} + + + {{tpl:AttachmentTitle}} + +
      • + +
      +
      + +
      + + + + + +
      +

      {{tpl:lang Comments}}

      +
      + +
      {{tpl:CommentOrderNumber}}. + {{tpl:lang On}} {{tpl:CommentDate}}, {{tpl:CommentTime}} + {{tpl:lang by}} {{tpl:CommentAuthorLink}}
      + +
      + + {{tpl:SysBehavior behavior="publicCommentBeforeContent"}} + + {{tpl:CommentContent}} + + + {{tpl:SysBehavior behavior="publicCommentAfterContent"}} +
      + +
      +
      + +
      +
      + + + +

      {{tpl:SysFormError}}

      +
      + + +

      {{tpl:lang Your comment has been published.}}

      +
      + + +

      {{tpl:lang Your comment has been submitted and + will be reviewed for publication.}}

      +
      + + +
      + +
      +

      {{tpl:lang Your comment}}

      +
      +
      {{tpl:CommentPreviewContent}}
      +
      +

      +
      +
      + +

      {{tpl:lang Add a comment}}

      +
      + + {{tpl:SysBehavior behavior="publicCommentFormBeforeContent"}} + +

      + +

      + +

      + +

      + +

      + +

      + +

      + +

      + +

      + +

      {{tpl:lang HTML code is displayed as text and web addresses are + automatically converted.}}

      + + + {{tpl:SysBehavior behavior="publicCommentFormAfterContent"}} +
      + +
      +

      +

      +
      +
      +
      + + + +
      +

      {{tpl:lang They posted on the same topic}}

      + + +
      + +
      {{tpl:PingOrderNumber}}. + {{tpl:lang On}} {{tpl:PingDate}}, {{tpl:PingTime}} + {{tpl:lang by}} {{tpl:PingBlogName encode_html="1"}}
      + +
      + + {{tpl:SysBehavior behavior="publicPingBeforeContent"}} + +

      {{tpl:PingTitle encode_html="1"}}

      + {{tpl:PingContent}} + + + {{tpl:SysBehavior behavior="publicPingAfterContent"}} +
      + +
      + +
      +
      +
      + + +

      {{tpl:lang Trackback URL}} : {{tpl:EntryPingLink}}

      +
      + + +

      {{tpl:lang This page's comments feed}}

      +
      +
      +
      + + + +
      + +{{tpl:include src="_footer.html"}} +
      + + \ No newline at end of file diff --git a/plugins/pages/icon-big.png b/plugins/pages/icon-big.png new file mode 100644 index 0000000000000000000000000000000000000000..4b466ded0e46177efe0e6f3450b799457a21e7cd GIT binary patch literal 2032 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 Q1MOt+boFyt=akR{0Nr7y%>V!Z literal 0 HcmV?d00001 diff --git a/plugins/pages/index.php b/plugins/pages/index.php new file mode 100644 index 0000000..3563cec --- /dev/null +++ b/plugins/pages/index.php @@ -0,0 +1,23 @@ + \ No newline at end of file diff --git a/plugins/pages/list.php b/plugins/pages/list.php new file mode 100644 index 0000000..a997d25 --- /dev/null +++ b/plugins/pages/list.php @@ -0,0 +1,203 @@ +rs->isEmpty()) + { + echo '

      '.__('No page').'

      '; + } + else + { + $pager = new pager($page,$this->rs_count,$nb_per_page,10); + $pager->html_prev = $this->html_prev; + $pager->html_next = $this->html_next; + $pager->var_page = 'page'; + + $html_block = + ''. + ''. + ''. + ''. + ''. + ''. + ''. + '%s
      '.__('Title').''.__('Date').''.__('Author').''.__('Comments').''.__('Trackbacks').''.__('Status').'
      '; + + if ($enclose_block) { + $html_block = sprintf($enclose_block,$html_block); + } + + echo '

      '.__('Page(s)').' : '.$pager->getLinks().'

      '; + + $blocks = explode('%s',$html_block); + + echo $blocks[0]; + + while ($this->rs->fetch()) + { + echo $this->postLine(); + } + + echo $blocks[1]; + + echo '

      '.__('Page(s)').' : '.$pager->getLinks().'

      '; + } + } + + private function postLine() + { + $img = '%1$s'; + switch ($this->rs->post_status) { + case 1: + $img_status = sprintf($img,__('published'),'check-on.png'); + break; + case 0: + $img_status = sprintf($img,__('unpublished'),'check-off.png'); + break; + case -1: + $img_status = sprintf($img,__('scheduled'),'scheduled.png'); + break; + case -2: + $img_status = sprintf($img,__('pending'),'check-wrn.png'); + break; + } + + $protected = ''; + if ($this->rs->post_password) { + $protected = sprintf($img,__('protected'),'locker.png'); + } + + $selected = ''; + if ($this->rs->post_selected) { + $selected = sprintf($img,__('selected'),'selected.png'); + } + + $attach = ''; + $nb_media = $this->rs->countMedia(); + if ($nb_media > 0) { + $attach_str = $nb_media == 1 ? __('%d attachment') : __('%d attachments'); + $attach = sprintf($img,sprintf($attach_str,$nb_media),'attach.png'); + } + + $res = ''; + + $res .= + ''. + form::checkbox(array('entries[]'),$this->rs->post_id,'','','',!$this->rs->isEditable()).''. + ''. + html::escapeHTML($this->rs->post_title).''. + ''.dt::dt2str(__('%Y-%m-%d %H:%M'),$this->rs->post_dt).''. + + ''.$this->rs->user_id.''. + ''.$this->rs->nb_comment.''. + ''.$this->rs->nb_trackback.''. + ''.$img_status.' '.$selected.' '.$protected.' '.$attach.''. + ''; + + return $res; + } +} + +/* Getting pages +-------------------------------------------------------- */ +$params = array( + 'post_type' => 'page' +); + +$page = !empty($_GET['page']) ? (integer) $_GET['page'] : 1; +$nb_per_page = 30; + +if (!empty($_GET['nb']) && (integer) $_GET['nb'] > 0) { + $nb_per_page = (integer) $_GET['nb']; +} + +$params['limit'] = array((($page-1)*$nb_per_page),$nb_per_page); +$params['no_content'] = true; +$params['order'] = 'post_position ASC, post_title ASC'; + +try { + $pages = $core->blog->getPosts($params); + $counter = $core->blog->getPosts($params,true); + $post_list = new adminPageList($core,$pages,$counter->f(0)); +} catch (Exception $e) { + $core->error->add($e->getMessage()); +} + +# Actions combo box +$combo_action = array(); +if ($core->auth->check('publish,contentadmin',$core->blog->id)) +{ + $combo_action[__('publish')] = 'publish'; + $combo_action[__('unpublish')] = 'unpublish'; + $combo_action[__('mark as pending')] = 'pending'; +} +if ($core->auth->check('admin',$core->blog->id)) { + $combo_action[__('change author')] = 'author'; +} +if ($core->auth->check('delete,contentadmin',$core->blog->id)) +{ + $combo_action[__('delete')] = 'delete'; +} + +# --BEHAVIOR-- adminPagesActionsCombo +$core->callBehavior('adminPagesActionsCombo',array(&$combo_action)); + +/* Display +-------------------------------------------------------- */ +?> + + + <?php echo __('Pages'); ?> + + + + + +'.html::escapeHTML($core->blog->name).' › '.__('Pages'). +' - '.__('New page').''; + +if (!$core->error->flag()) +{ + # Show pages + $post_list->display($page,$nb_per_page, + '
      '. + + '%s'. + + '
      '. + '

      '. + + '

      '.__('Selected pages action:').' '. + form::combo('action',$combo_action). + '

      '. + form::hidden(array('post_type'),'page'). + form::hidden(array('redir'),html::escapeHTML($_SERVER['REQUEST_URI'])). + $core->formNonce(). + '
      '. + '
      '); +} +?> + + \ No newline at end of file diff --git a/plugins/pages/page.php b/plugins/pages/page.php new file mode 100644 index 0000000..1bc0eda --- /dev/null +++ b/plugins/pages/page.php @@ -0,0 +1,638 @@ +auth->getOption('post_format'); +$post_password = ''; +$post_url = ''; +$post_lang = $core->auth->getInfo('user_lang'); +$post_title = ''; +$post_excerpt = ''; +$post_excerpt_xhtml = ''; +$post_content = ''; +$post_content_xhtml = ''; +$post_status = $core->auth->getInfo('user_post_status'); +$post_position = 0; +$post_open_comment = false; +$post_open_tb = false; + +$post_media = array(); + +$page_title = __('New page'); + +$can_view_page = true; +$can_edit_page = $core->auth->check('page,usage',$core->blog->id); +$can_publish = $core->auth->check('page,publish,contentadmin',$core->blog->id); +$can_delete = false; + +$post_headlink = ''; +$post_link = '%s'; + +$next_link = $prev_link = $next_headlink = $prev_headlink = null; + +# If user can't publish +if (!$can_publish) { + $post_status = -2; +} + +# Status combo +foreach ($core->blog->getAllPostStatus() as $k => $v) { + $status_combo[$v] = (string) $k; +} + +# Formaters combo +foreach ($core->getFormaters() as $v) { + $formaters_combo[$v] = $v; +} + +# Languages combo +$rs = $core->blog->getLangs(array('order'=>'asc')); +$all_langs = l10n::getISOcodes(0,1); +$lang_combo = array('' => '', __('Most used') => array(), __('Available') => l10n::getISOcodes(1,1)); +while ($rs->fetch()) { + if (isset($all_langs[$rs->post_lang])) { + $lang_combo[__('Most used')][$all_langs[$rs->post_lang]] = $rs->post_lang; + unset($lang_combo[__('Available')][$all_langs[$rs->post_lang]]); + } else { + $lang_combo[__('Most used')][$rs->post_lang] = $rs->post_lang; + } +} +unset($all_langs); +unset($rs); + + +# Get page informations +if (!empty($_REQUEST['id'])) +{ + $params['post_type'] = 'page'; + $params['post_id'] = $_REQUEST['id']; + + $post = $core->blog->getPosts($params); + + if ($post->isEmpty()) + { + $core->error->add(__('This page does not exist.')); + $can_view_page = false; + } + else + { + $post_id = $post->post_id; + $post_dt = date('Y-m-d H:i',strtotime($post->post_dt)); + $post_format = $post->post_format; + $post_password = $post->post_password; + $post_url = $post->post_url; + $post_lang = $post->post_lang; + $post_title = $post->post_title; + $post_excerpt = $post->post_excerpt; + $post_excerpt_xhtml = $post->post_excerpt_xhtml; + $post_content = $post->post_content; + $post_content_xhtml = $post->post_content_xhtml; + $post_status = $post->post_status; + $post_position = (integer) $post->post_position; + $post_open_comment = (boolean) $post->post_open_comment; + $post_open_tb = (boolean) $post->post_open_tb; + + $page_title = __('Edit page'); + + $can_edit_page = $post->isEditable(); + $can_delete= $post->isDeletable(); + + $next_rs = $core->blog->getNextPost($post,1); + $prev_rs = $core->blog->getNextPost($post,-1); + + if ($next_rs !== null) { + $next_link = sprintf($post_link,$next_rs->post_id, + html::escapeHTML($next_rs->post_title),__('next page').' »'); + $next_headlink = sprintf($post_headlink,'next', + html::escapeHTML($next_rs->post_title),$next_rs->post_id); + } + + if ($prev_rs !== null) { + $prev_link = sprintf($post_link,$prev_rs->post_id, + html::escapeHTML($prev_rs->post_title),'« '.__('previous page')); + $prev_headlink = sprintf($post_headlink,'previous', + html::escapeHTML($prev_rs->post_title),$prev_rs->post_id); + } + + try { + $core->media = new dcMedia($core); + $post_media = $core->media->getPostMedia($post_id); + } catch (Exception $e) {} + } +} + +# Format content +if (!empty($_POST) && $can_edit_page) +{ + $post_format = $_POST['post_format']; + $post_excerpt = $_POST['post_excerpt']; + $post_content = $_POST['post_content']; + + $post_title = $_POST['post_title']; + + if (isset($_POST['post_status'])) { + $post_status = (integer) $_POST['post_status']; + } + + if (empty($_POST['post_dt'])) { + $post_dt = ''; + } else { + $post_dt = strtotime($_POST['post_dt']); + $post_dt = date('Y-m-d H:i',$post_dt); + } + + $post_open_comment = !empty($_POST['post_open_comment']); + $post_open_tb = !empty($_POST['post_open_tb']); + $post_lang = $_POST['post_lang']; + $post_password = !empty($_POST['post_password']) ? $_POST['post_password'] : null; + $post_position = (integer) $_POST['post_position']; + + if (isset($_POST['post_url'])) { + $post_url = $_POST['post_url']; + } + + $core->blog->setPostContent( + $post_id,$post_format,$post_lang, + $post_excerpt,$post_excerpt_xhtml,$post_content,$post_content_xhtml + ); +} + +# Create or update post +if (!empty($_POST) && !empty($_POST['save']) && $can_edit_page) +{ + $cur = $core->con->openCursor($core->prefix.'post'); + + # Magic tweak :) + $core->blog->settings->post_url_format = $page_url_format; + + $cur->post_type = 'page'; + $cur->post_title = $post_title; + $cur->post_dt = $post_dt ? date('Y-m-d H:i:00',strtotime($post_dt)) : ''; + $cur->post_format = $post_format; + $cur->post_password = $post_password; + $cur->post_lang = $post_lang; + $cur->post_title = $post_title; + $cur->post_excerpt = $post_excerpt; + $cur->post_excerpt_xhtml = $post_excerpt_xhtml; + $cur->post_content = $post_content; + $cur->post_content_xhtml = $post_content_xhtml; + $cur->post_status = $post_status; + $cur->post_position = $post_position; + $cur->post_open_comment = (integer) $post_open_comment; + $cur->post_open_tb = (integer) $post_open_tb; + + if (isset($_POST['post_url'])) { + $cur->post_url = $post_url; + } + + # Update post + if ($post_id) + { + try + { + # --BEHAVIOR-- adminBeforePageUpdate + $core->callBehavior('adminBeforePageUpdate',$cur,$post_id); + + $core->blog->updPost($post_id,$cur); + + # --BEHAVIOR-- adminAfterPageUpdate + $core->callBehavior('adminAfterPageUpdate',$cur,$post_id); + + http::redirect($redir_url.'&id='.$post_id.'&upd=1'); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } + } + else + { + $cur->user_id = $core->auth->userID(); + + try + { + # --BEHAVIOR-- adminBeforePageCreate + $core->callBehavior('adminBeforePageCreate',$cur); + + $return_id = $core->blog->addPost($cur); + + # --BEHAVIOR-- adminAfterPageCreate + $core->callBehavior('adminAfterPageCreate',$cur,$return_id); + + http::redirect($redir_url.'&id='.$return_id.'&crea=1'); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } + } +} + +if (!empty($_POST['delete']) && $can_delete) +{ + try { + # --BEHAVIOR-- adminBeforePageDelete + $core->callBehavior('adminBeforePageDelete',$post_id); + $core->blog->delPost($post_id); + http::redirect($p_url); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} + +/* DISPLAY +-------------------------------------------------------- */ +$default_tab = 'edit-entry'; +if (!$can_edit_page) { + $default_tab = ''; +} +if (!empty($_GET['co'])) { + $default_tab = 'comments'; +} + +?> + + + <?php echo $page_title.' - '.__('Pages'); ?> + + callBehavior('adminPageHeaders'). + dcPage::jsPageTabs($default_tab). + $next_headlink."\n".$prev_headlink; + ?> + + + + +'.__('Page has been successfully updated.').'

      '; +} +elseif (!empty($_GET['crea'])) { + echo '

      '.__('Page has been successfully created.').'

      '; +} +elseif (!empty($_GET['attached'])) { + echo '

      '.__('File has been successfully attached.').'

      '; +} +elseif (!empty($_GET['rmattach'])) { + echo '

      '.__('Attachment has been successfully removed.').'

      '; +} + +# XHTML conversion +if (!empty($_GET['xconv'])) +{ + $post_excerpt = $post_excerpt_xhtml; + $post_content = $post_content_xhtml; + $post_format = 'xhtml'; + + echo '

      '.__('Don\'t forget to validate your XHTML conversion by saving your post.').'

      '; +} + +echo '

      '.html::escapeHTML($core->blog->name). +' › '.__('Pages').' › '.$page_title; + +if ($post_id && $post->post_status == 1) { + echo ' - '.__('View page').''; +} elseif ($post_id) { + $preview_url = + $core->blog->url.$core->url->getBase('pagespreview').'/'. + $core->auth->userID().'/'. + http::browserUID(DC_MASTER_KEY.$core->auth->userID().$core->auth->getInfo('user_pwd')). + '/'.$post->post_url; + echo ' - '.__('Preview page').''; +} + +echo '

      '; + +if ($post_id) +{ + echo '

      '; + if ($prev_link) { echo $prev_link; } + if ($next_link && $prev_link) { echo ' - '; } + if ($next_link) { echo $next_link; } + + # --BEHAVIOR-- adminPageNavLinks + $core->callBehavior('adminPageNavLinks',isset($post) ? $post : null); + + echo '

      '; +} + +# Exit if we cannot view page +if (!$can_view_page) { + echo ''; + return; +} + + +/* Post form if we can edit post +-------------------------------------------------------- */ +if ($can_edit_page) +{ + echo '
      '; + echo '
      '; + echo '
      '; + + echo + '

      '. + + '

      '. + + '

      '. + + '

      '. + '

      '. + + '

      '. + + '

      '. + + '

      '. + + '
      '. + '

      '. + '

      '. + __('Warning: If you set the URL manually, it may conflict with another page.'). + '

      '. + '
      '; + + if ($post_id) + { + echo + '

      '.__('Attachments').'

      '; + foreach ($post_media as $f) + { + $ftitle = $f->media_title; + if (strlen($ftitle) > 18) { + $ftitle = substr($ftitle,0,16).'...'; + } + echo + '
      '. + ''. + ''. + ''. + '
      '; + } + unset($f); + + if (empty($post_media)) { + echo '

      '.__('No attachment.').'

      '; + } + echo '

      '.__('Add files to this page').'

      '; + } + + # --BEHAVIOR-- adminPageFormSidebar + $core->callBehavior('adminPageFormSidebar',isset($post) ? $post : null); + + echo '
      '; // End #entry-sidebar + + echo '
      '; + + echo + '

      '. + + '

      '. + form::textarea('post_excerpt',50,5,html::escapeHTML($post_excerpt),'',2). + '

      '. + + '

      '. + form::textarea('post_content',50,$core->auth->getOption('edit_size'),html::escapeHTML($post_content),'',2). + '

      '. + + # --BEHAVIOR-- adminPageForm + $core->callBehavior('adminPageForm',isset($post) ? $post : null); + + echo + '

      '. + ($post_id ? form::hidden('id',$post_id) : ''). + ' '. + ($can_delete ? '' : ''). + $core->formNonce(). + '

      '; + + echo '
      '; // End #entry-content + echo '
      '; + echo '
      '; + + if ($post_id && !empty($post_media)) + { + echo + '
      '. + '
      '.form::hidden(array('post_id'),$post_id). + form::hidden(array('media_id'),''). + form::hidden(array('remove'),1). + $core->formNonce().'
      '; + } +} + + +/* Comments and trackbacks +-------------------------------------------------------- */ +if ($post_id) +{ + $params = array('post_id' => $post_id, 'order' => 'comment_dt ASC'); + + $comments = $core->blog->getComments(array_merge($params,array('comment_trackback'=>0))); + $trackbacks = $core->blog->getComments(array_merge($params,array('comment_trackback'=>1))); + + # Actions combo box + $combo_action = array(); + if ($can_edit_page && $core->auth->check('publish,contentadmin',$core->blog->id)) + { + $combo_action[__('publish')] = 'publish'; + $combo_action[__('unpublish')] = 'unpublish'; + $combo_action[__('mark as pending')] = 'pending'; + $combo_action[__('mark as junk')] = 'junk'; + } + + if ($can_edit_page && $core->auth->check('delete,contentadmin',$core->blog->id)) + { + $combo_action[__('delete')] = 'delete'; + } + + $has_action = !empty($combo_action) && (!$trackbacks->isEmpty() || !$comments->isEmpty()); + + echo + '
      '; + + if ($has_action) { + echo '
      '; + } + + echo '

      '.__('Trackbacks').'

      '; + + if (!$trackbacks->isEmpty()) { + showComments($trackbacks,$has_action); + } else { + echo '

      '.__('No trackback').'

      '; + } + + echo '

      '.__('Comments').'

      '; + if (!$comments->isEmpty()) { + showComments($comments,$has_action); + } else { + echo '

      '.__('No comment').'

      '; + } + + if ($has_action) { + echo + '
      '. + '

      '. + + '

      '.__('Selected comments action:').' '. + form::combo('action',$combo_action). + form::hidden('redir',html::escapeURL($redir_url).'&id='.$post_id.'&co=1'). + $core->formNonce(). + '

      '. + '
      '. + '
      '; + } + + echo '
      '; +} + +/* Add a comment +-------------------------------------------------------- */ +if ($post_id) +{ + echo + '
      '. + '

      '.__('Add a comment').'

      '. + + '
      '. + '
      '. + '

      '. + + '

      '. + + '

      '. + + '

      '. + form::textarea('comment_content',50,8,html::escapeHTML('')). + '

      '. + + '

      '.form::hidden('post_id',$post_id). + $core->formNonce(). + '

      '. + '
      '. + '
      '. + '
      '; +} + + +# Show comments or trackbacks +function showComments(&$rs,$has_action) +{ + echo + ''. + ''. + ''. + ''. + ''. + ''. + ''; + + while($rs->fetch()) + { + $comment_url = 'comment.php?id='.$rs->comment_id; + + $img = '%1$s'; + switch ($rs->comment_status) { + case 1: + $img_status = sprintf($img,__('published'),'check-on.png'); + break; + case 0: + $img_status = sprintf($img,__('unpublished'),'check-off.png'); + break; + case -1: + $img_status = sprintf($img,__('pending'),'check-wrn.png'); + break; + case -2: + $img_status = sprintf($img,__('junk'),'junk.png'); + break; + } + + echo + ''. + + ''. + ''. + ''. + ''. + ''. + ''. + + ''; + } + + echo '
      '.__('Author').''.__('Date').''.__('IP address').''.__('Status').' 
      '. + ($has_action ? form::checkbox(array('comments[]'),$rs->comment_id,'','','',0) : '').''.$rs->comment_author.''.dt::dt2str(__('%Y-%m-%d %H:%M'),$rs->comment_dt).''.$rs->comment_ip.''.$img_status.''. + '
      '; +} +dcPage::helpBlock('core_wiki'); +?> + + \ No newline at end of file diff --git a/plugins/pings/_admin.php b/plugins/pings/_admin.php new file mode 100644 index 0000000..be8e909 --- /dev/null +++ b/plugins/pings/_admin.php @@ -0,0 +1,25 @@ +addItem(__('Pings'),'plugin.php?p=pings','index.php?pf=pings/icon.png', + preg_match('/plugin.php\?p=pings/',$_SERVER['REQUEST_URI']), + $core->auth->isSuperAdmin()); + +$__autoload['pingsAPI'] = dirname(__FILE__).'/lib.pings.php'; +$__autoload['pingsBehaviors'] = dirname(__FILE__).'/lib.pings.php'; + +$core->addBehavior('adminPostHeaders',array('pingsBehaviors','pingJS')); +$core->addBehavior('adminPostFormSidebar',array('pingsBehaviors','pingsForm')); +$core->addBehavior('adminAfterPostCreate',array('pingsBehaviors','doPings')); +$core->addBehavior('adminAfterPostUpdate',array('pingsBehaviors','doPings')); +?> \ No newline at end of file diff --git a/plugins/pings/_define.php b/plugins/pings/_define.php new file mode 100644 index 0000000..27f0600 --- /dev/null +++ b/plugins/pings/_define.php @@ -0,0 +1,21 @@ +registerModule( + /* Name */ "Pings", + /* Description*/ "Ping services", + /* Author */ "Olivier Meunier", + /* Version */ '1.0', + /* Permissions */ 'usage,contentadmin' +); +?> \ No newline at end of file diff --git a/plugins/pings/icon.png b/plugins/pings/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..05bd28e3564788a94308cc7c9abf5e687700bfb6 GIT binary patch literal 878 zcmWkrc}$ZB6#oj5R0OtwCS_&|$w-D%VhAR>BMVk=R?ZYMV9XAtRPYGe*5H6$#cnve z0i|vP5f@q*DJ{}|9F zE$scU4Y*t`*ak7J#?%c=lTN1-Q@sv{1Cu?NP}=Qw+*ZQcWwY5}m1B%TCoJtS%V3tn zB!lrPjBVrNM{q)M_<;;ow>^+Bhne z3ay`XcXulk3N+_KnvJGRG^NXAGDujE97IDpF73zn@1SlEzI(5wr3J#>5blI9St^y{ zt3*^Mpenw;zFsUAi$tQNg_UUP`!oSNE0;)FbaJU-^O-}1e1ZsHeMuTqxu=<0#tG62 z1i2MlL1hWAl*lYO%BwhCdaS%8?qE5uw6cPCk{_2@plf_Pp1Sq0QupUE@{bl1A)L&j zYxLtsO2QIyqI#2)lFn`!pQiC+BVShqqhpeJB$NNR`RkC6qoR`9cSS_((j;#3J&cG5 zd6D(BX30Ol`J-0mtf(oTA$VVC`kc)^d@H?s<6hPMH)Cs#@C$C*m`}E`y&5NXCga!` zZwFVYki^8~EnmI0@7GiB9vH4ptj;IT3px+u)WnU2WQJzFsPHmFoY7y)kQcs{-DW6O zTJ9JOjU1Qjw@rfDA(~OOxJ@Fle-`^FMcz(!l|QW6p-m|$+8TPmE&PD-soM5N>cSn( ih4AwyQp&b(=Z1w50sG#a(Hv4wg(g^OS*bnDV&VUIM-3zZ literal 0 HcmV?d00001 diff --git a/plugins/pings/index.php b/plugins/pings/index.php new file mode 100644 index 0000000..895e5b8 --- /dev/null +++ b/plugins/pings/index.php @@ -0,0 +1,113 @@ +blog->settings->pings_active === null) + { + $default_pings_uris = array( + 'Ping-o-Matic!' => 'http://rpc.pingomatic.com/', + 'Google Blog Search' => 'http://blogsearch.google.com/ping/RPC2' + ); + + $core->blog->settings->setNameSpace('pings'); + $core->blog->settings->put('pings_active',1,'boolean','Activate pings plugin',true,true); + $core->blog->settings->put('pings_uris',serialize($default_pings_uris),'string','Pings services URIs',true,true); + http::redirect($p_url); + } + + $pings_uris = @unserialize($core->blog->settings->pings_uris); + if (!$pings_uris) { + $pings_uris = array(); + } + + if (isset($_POST['pings_srv_name'])) + { + $pings_srv_name = is_array($_POST['pings_srv_name']) ? $_POST['pings_srv_name'] : array(); + $pings_srv_uri = is_array($_POST['pings_srv_uri']) ? $_POST['pings_srv_uri'] : array(); + $pings_uris = array(); + + foreach ($pings_srv_name as $k => $v) { + if (trim($v) && trim($pings_srv_uri[$k])) { + $pings_uris[trim($v)] = trim($pings_srv_uri[$k]); + } + } + + $core->blog->settings->setNameSpace('pings'); + $core->blog->settings->put('pings_active',!empty($_POST['pings_active']),null,null,true,true); + $core->blog->settings->put('pings_uris',serialize($pings_uris),null,null,true,true); + http::redirect($p_url.'&up=1'); + } +} +catch (Exception $e) +{ + $core->error->add($e->getMessage()); +} +?> + + + <?php echo __('Pings'); ?> + + + +'.__('Pings configuration').''; + +if (!empty($_GET['up'])) { + echo '

      '.__('Settings have been successfully updated.').'

      '; +} + +echo +'
      '. +'

      '; + +foreach ($pings_uris as $n => $u) +{ + echo + '

      '. + ''; + + if (!empty($_GET['test'])) + { + try { + pingsAPI::doPings($u,'Example site','http://example.com'); + echo ' ok'; + } catch (Exception $e) { + echo ' '.__('error').' '.$e->getMessage(); + } + } + + echo '

      '; +} + +echo +'

      '. +''. +'

      '. + +'

      '. +$core->formNonce().'

      '. +'
      '; + +echo '

      '.__('Test ping services').'

      '; +?> + + \ No newline at end of file diff --git a/plugins/pings/lib.pings.php b/plugins/pings/lib.pings.php new file mode 100644 index 0000000..04a217d --- /dev/null +++ b/plugins/pings/lib.pings.php @@ -0,0 +1,92 @@ +timeout = 3; + + $rsp = $o->query('weblogUpdates.ping',$site_name,$site_url); + + if (isset($rsp['flerror']) && $rsp['flerror']) { + throw new Exception($rsp['message']); + } + + return true; + } +} + +class pingsBehaviors +{ + public static function pingJS() + { + return dcPage::jsLoad('index.php?pf=pings/post.js'); + } + + public static function pingsForm(&$post) + { + $core =& $GLOBALS['core']; + if (!$core->blog->settings->pings_active) { + return; + } + + $pings_uris = @unserialize($core->blog->settings->pings_uris); + if (empty($pings_uris) || !is_array($pings_uris)) { + return; + } + + if (!empty($_POST['pings_do']) && is_array($_POST['pings_do'])) { + $pings_do = $_POST['pings_do']; + } else { + $pings_do = array(); + } + + echo '

      '.__('Pings:').'

      '; + foreach ($pings_uris as $k => $v) + { + echo + '

      '; + } + } + + public static function doPings(&$cur,&$post_id) + { + if (empty($_POST['pings_do']) || !is_array($_POST['pings_do'])) { + return; + } + + $core =& $GLOBALS['core']; + if (!$core->blog->settings->pings_active) { + return; + } + + $pings_uris = @unserialize($core->blog->settings->pings_uris); + if (empty($pings_uris) || !is_array($pings_uris)) { + return; + } + + foreach ($_POST['pings_do'] as $uri) + { + if (in_array($uri,$pings_uris)) { + try { + pingsAPI::doPings($uri,$core->blog->name,$core->blog->url); + } catch (Exception $e) {} + } + } + } +} +?> \ No newline at end of file diff --git a/plugins/pings/post.js b/plugins/pings/post.js new file mode 100644 index 0000000..578f173 --- /dev/null +++ b/plugins/pings/post.js @@ -0,0 +1,2 @@ + +$(function(){$('#edit-entry').onetabload(function(){$('h3.ping-services').toggleWithLegend($('p.ping-services'),{cookie:'dcx_ping_services'});});}); \ No newline at end of file diff --git a/plugins/themeEditor/_admin.php b/plugins/themeEditor/_admin.php new file mode 100644 index 0000000..9ed790e --- /dev/null +++ b/plugins/themeEditor/_admin.php @@ -0,0 +1,26 @@ +addBehavior('adminCurrentThemeDetails','theme_editor_details'); + +function theme_editor_details($core,$id) +{ + if ($id != 'default' && $core->auth->isSuperAdmin()) { + return '

      '.__('Theme Editor').'

      '; + } +} +?> \ No newline at end of file diff --git a/plugins/themeEditor/_define.php b/plugins/themeEditor/_define.php new file mode 100644 index 0000000..1dead06 --- /dev/null +++ b/plugins/themeEditor/_define.php @@ -0,0 +1,21 @@ +registerModule( + /* Name */ "themeEditor", + /* Description*/ "Theme Editor", + /* Author */ "Olivier Meunier", + /* Version */ '0.6', + /* Permissions */ null +); +?> \ No newline at end of file diff --git a/plugins/themeEditor/class.themeEditor.php b/plugins/themeEditor/class.themeEditor.php new file mode 100644 index 0000000..7abfe70 --- /dev/null +++ b/plugins/themeEditor/class.themeEditor.php @@ -0,0 +1,252 @@ +core =& $core; + $this->default_theme = path::real($this->core->blog->themes_path.'/default'); + $this->user_theme = path::real($this->core->blog->themes_path.'/'.$this->core->blog->settings->theme); + if (null !== $this->core->themes) { + $parent_theme = $this->core->themes->moduleInfo($this->core->blog->settings->theme,'parent'); + if ($parent_theme) { + $this->parent_theme = path::real($this->core->blog->themes_path.'/'.$parent_theme); + } + } + $this->findTemplates(); + $this->findStyles(); + $this->findScripts(); + } + + public function filesList($type,$item='%1$s') + { + $files = $this->getFilesFromType($type); + + if (empty($files)) { + return '

      '.__('No file').'

      '; + } + + $list = ''; + foreach ($files as $k => $v) + { + if (strpos($v,$this->user_theme) === 0) { + $li = sprintf('
    • %s
    • ',$item); + } elseif ($this->parent_theme && strpos($v,$this->parent_theme) === 0) { + $li = sprintf('
    • %s
    • ',$item); + } else { + $li = sprintf('
    • %s
    • ',$item); + } + $list .= sprintf($li,$k,html::escapeHTML($k)); + } + + return sprintf('
        %s
      ',$list); + } + + public function getFileContent($type,$f) + { + $files = $this->getFilesFromType($type); + + if (!isset($files[$f])) { + throw new Exception(__('File does not exist.')); + } + + $F = $files[$f]; + if (!is_readable($F)) { + throw new Exception(sprintf(__('File %s is not readable'),$f)); + } + + return array( + 'c' => file_get_contents($F), + 'w' => $this->getDestinationFile($type,$f) !== false, + 'type' => $type, + 'f' => $f + ); + } + + public function writeFile($type,$f,$content) + { + $files = $this->getFilesFromType($type); + + if (!isset($files[$f])) { + throw new Exception(__('File does not exist.')); + } + + try + { + $dest = $this->getDestinationFile($type,$f); + + if ($dest == false) { + throw new Exception(); + } + + if ($type == 'tpl' && !is_dir(dirname($dest))) { + files::makeDir(dirname($dest)); + } + + $fp = @fopen($dest,'wb'); + if (!$fp) { + throw new Exception('tocatch'); + } + + $content = preg_replace('/(\r?\n)/m',"\n",$content); + $content = preg_replace('/\r/m',"\n",$content); + + fwrite($fp,$content); + fclose($fp); + + # Updating inner files list + $this->updateFileInList($type,$f,$dest); + } + catch (Exception $e) + { + throw new Exception(sprintf(__('Unable to write file %s. Please check your theme files and folders permissions.'),$f)); + } + } + + protected function getDestinationFile($type,$f) + { + if ($type == 'tpl') { + $dest = $this->user_theme.'/tpl/'.$f; + } else { + $dest = $this->user_theme.'/'.$f; + } + + if (file_exists($dest) && is_writable($dest)) { + return $dest; + } + + if ($type == 'tpl' && !is_dir(dirname($dest))) { + if (is_writable($this->user_theme)) { + return $dest; + } + } + + if (is_writable(dirname($dest))) { + return $dest; + } + + return false; + } + + protected function getFilesFromType($type) + { + switch ($type) + { + case 'tpl': + return $this->tpl; + case 'css': + return $this->css; + case 'js': + return $this->js; + default: + return array(); + } + } + + protected function updateFileInList($type,$f,$file) + { + switch ($type) + { + case 'tpl': + $list =& $this->tpl; + break; + case 'css': + $list =& $this->css; + break; + case 'js': + $list =& $this->js; + break; + default: + return; + } + + $list[$f] = $file; + } + + protected function findTemplates() + { + # First, we look in template paths + $this->default_tpl = $this->getFilesInDir($this->default_theme.'/tpl'); + + $this->tpl = array_merge( + $this->default_tpl, + $this->getFilesInDir($this->parent_theme.'/tpl'), + $this->getFilesInDir($this->user_theme.'/tpl') + ); + $this->tpl = array_merge($this->getFilesInDir(DC_ROOT.'/inc/public/default-templates'),$this->tpl); + + # Then we look in 'default-templates' plugins directory + $plugins = $this->core->plugins->getModules(); + foreach ($plugins as $p) { + $this->tpl = array_merge($this->getFilesInDir($p['root'].'/default-templates'),$this->tpl); + } + + uksort($this->tpl,array($this,'sortFilesHelper')); + } + + protected function findStyles() + { + $this->css = $this->getFilesInDir($this->user_theme,'css'); + $this->css= array_merge($this->css,$this->getFilesInDir($this->user_theme.'/style','css','style/')); + } + + protected function findScripts() + { + $this->js = $this->getFilesInDir($this->user_theme,'js'); + $this->js = array_merge($this->js,$this->getFilesInDir($this->user_theme.'/js','js','js/')); + } + + protected function getFilesInDir($dir,$ext=null,$prefix='') + { + $dir = path::real($dir); + if (!$dir || !is_dir($dir) || !is_readable($dir)) { + return array(); + } + + $d = dir($dir); + $res = array(); + while (($f = $d->read()) !== false) + { + if (is_file($dir.'/'.$f) && !preg_match('/^\./',$f) && (!$ext || preg_match('/\.'.preg_quote($ext).'$/i',$f))) { + $res[$prefix.$f] = $dir.'/'.$f; + } + } + + return $res; + } + + protected function sortFilesHelper($a,$b) + { + if ($a == $b) { + return 0; + } + + $ext_a = files::getExtension($a); + $ext_b = files::getExtension($b); + + return strcmp($ext_a.'.'.$a,$ext_b.'.'.$b); + } +} +?> \ No newline at end of file diff --git a/plugins/themeEditor/help.html b/plugins/themeEditor/help.html new file mode 100644 index 0000000..e190cb5 --- /dev/null +++ b/plugins/themeEditor/help.html @@ -0,0 +1,28 @@ + + + + Theme Editor + + + +

      The Theme Editor lets you modify the template files, the stylesheets and the JavaScript files of the theme you are currently using..

      + +

      The file list is divided in three sections :

      +
        +
      • Template files : the templates
      • +
      • CSS files : the stylesheets
      • +
      • JavaScript files
      • +
      + +

      The yellow bullet in front of the name of a file indicates that this file is part of the theme. The red bullet means it is a part of the parent theme. The black bullet means it is a part of the "default" theme.

      + +

      If you modify a file belonging to the "default" theme, it will be copied into the theme you are currently using.

      + +

      To edit a file, click on its name to display its content in the edition area. If the file can be written, you will be able to save your modifications by ckicking on "save".

      + +

      The modifications are applied immediately after saving, so be careful.

      + +

      To help modify your templates, you may consult the template tag list.

      + + + diff --git a/plugins/themeEditor/index.php b/plugins/themeEditor/index.php new file mode 100644 index 0000000..0999dc5 --- /dev/null +++ b/plugins/themeEditor/index.php @@ -0,0 +1,128 @@ +null, 'w'=>false, 'type'=>null, 'f'=>null, 'default_file'=>false); + +# Loading themes +$core->themes = new dcThemes($core); +$core->themes->loadModules($core->blog->themes_path,null); +$T = $core->themes->getModules($core->blog->settings->theme); +$o = new dcThemeEditor($core); + +try +{ + try + { + if (!empty($_REQUEST['tpl'])) { + $file = $o->getFileContent('tpl',$_REQUEST['tpl']); + } elseif (!empty($_REQUEST['css'])) { + $file = $o->getFileContent('css',$_REQUEST['css']); + } elseif (!empty($_REQUEST['js'])) { + $file = $o->getFileContent('js',$_REQUEST['js']); + } + } + catch (Exception $e) + { + $file = $file_default; + throw $e; + } + + # Write file + if (!empty($_POST['write'])) + { + $file['c'] = $_POST['file_content']; + $o->writeFile($file['type'],$file['f'],$file['c']); + } +} +catch (Exception $e) +{ + $core->error->add($e->getMessage()); +} +?> + + + + <?php echo __('Theme Editor'); ?> + + + + + + +'.html::escapeHTML($core->blog->name). +' › '.__('Blog aspect').' › '.__('Theme Editor').''; ?> + +

      + +blog->settings->theme == 'default') { ?> +

      + + + +
      +
      +'.__('Please select a file to edit.').'

      '; +} +else +{ + echo + '
      '. + '
      '.__('File editor').''. + '

      '.sprintf(__('Editing file %s'),''.$file['f']).'

      '. + '

      '.form::textarea('file_content',72,25,html::escapeHTML($file['c']),'maximal','',!$file['w']).'

      '; + + if ($file['w']) + { + echo + '

      '. + $core->formNonce(). + ($file['type'] ? form::hidden(array($file['type']),$file['f']) : ''). + '

      '; + } + else + { + echo '

      '.__('This file is not writable. Please check your theme files permissions.').'

      '; + } + + echo + '
      '; +} +?> +
      +
      + +
      +

      +filesList('tpl','%1$s'); ?> + +

      +filesList('css','%1$s'); ?> + +

      +filesList('js','%1$s'); ?> +
      + + + + \ No newline at end of file diff --git a/plugins/themeEditor/script.js b/plugins/themeEditor/script.js new file mode 100644 index 0000000..7b60c5f --- /dev/null +++ b/plugins/themeEditor/script.js @@ -0,0 +1,3 @@ + +$(function(){var msg=false;$('#file-form input[name="write"]').click(function(){var f=this.form;var data={file_content:$(f).find('#file_content').get(0).value,xd_check:$(f).find('input[name="xd_check"]').get(0).value,write:1};if(msg==false){msg=$('

      ');$('#file_content').parent().after(msg);} +msg.text(dotclear.msg.saving_document);$.post(document.location.href,data,function(res,status){var err=$(res).find('div.error li:first');if(err.length>0){msg.text(dotclear.msg.error_occurred+' '+err.text());return;}else{msg.text(dotclear.msg.document_saved);$('#file-chooser').empty();$(res).find('#file-chooser').children().appendTo('#file-chooser');}});return false;});}); \ No newline at end of file diff --git a/plugins/themeEditor/style.css b/plugins/themeEditor/style.css new file mode 100644 index 0000000..9fce472 --- /dev/null +++ b/plugins/themeEditor/style.css @@ -0,0 +1,29 @@ +#file-box { + width: 100%; + float: left; + margin-right: -180px; +} + +#file-editor { + margin-right: 180px; +} + +#file-chooser { + float: right; + width: 170px; +} +#file-chooser ul { + padding-left: 0; +} +#file-chooser li { + list-style: square inside; +} +#file-chooser li.default-file { + color: #f90; +} +#file-chooser li.parent-file { + color:#c00; +} +textarea { + font: 1em Monaco,"Courier New",Courier,monospace; +} \ No newline at end of file diff --git a/plugins/widgets/_admin.php b/plugins/widgets/_admin.php new file mode 100644 index 0000000..a162b3b --- /dev/null +++ b/plugins/widgets/_admin.php @@ -0,0 +1,17 @@ +addItem(__('Presentation widgets'),'plugin.php?p=widgets','index.php?pf=widgets/icon.png', + preg_match('/plugin.php\?p=widgets(&.*)?$/',$_SERVER['REQUEST_URI']), + $core->auth->check('admin',$core->blog->id)); +?> \ No newline at end of file diff --git a/plugins/widgets/_default_widgets.php b/plugins/widgets/_default_widgets.php new file mode 100644 index 0000000..0554e61 --- /dev/null +++ b/plugins/widgets/_default_widgets.php @@ -0,0 +1,90 @@ +create('search',__('Search engine'),array('defaultWidgets','search')); +$__widgets->search->setting('title',__('Title:'),__('Search')); + +$__widgets->create('navigation',__('Navigation links'),array('defaultWidgets','navigation')); +$__widgets->navigation->setting('title',__('Title:'),''); + +$__widgets->create('bestof',__('Selected entries'),array('defaultWidgets','bestof')); +$__widgets->bestof->setting('title',__('Title:'),__('Best of me')); +$__widgets->bestof->setting('homeonly',__('Home page only'),1,'check'); + +$__widgets->create('langs',__('Blog languages'),array('defaultWidgets','langs')); +$__widgets->langs->setting('title',__('Title:'),__('Languages')); +$__widgets->langs->setting('homeonly',__('Home page only'),1,'check'); + +$__widgets->create('categories',__('Categories list'),array('defaultWidgets','categories')); +$__widgets->categories->setting('title',__('Title:'),__('Categories')); +$__widgets->categories->setting('postcount',__('With entries counts'),0,'check'); + +$__widgets->create('subscribe',__('Subscribe links'),array('defaultWidgets','subscribe')); +$__widgets->subscribe->setting('title',__('Title:'),__('Subscribe')); +$__widgets->subscribe->setting('type',__('Feeds type:'),'atom','combo',array('Atom' => 'atom', 'RSS' => 'rss2')); +$__widgets->subscribe->setting('homeonly',__('Home page only'),0,'check'); + +$__widgets->create('feed',__('Feed reader'),array('defaultWidgets','feed')); +$__widgets->feed->setting('title',__('Title:'),__('Somewhere else')); +$__widgets->feed->setting('url',__('Feed URL:'),''); +$__widgets->feed->setting('limit',__('Entries limit:'),10); +$__widgets->feed->setting('homeonly',__('Home page only'),1,'check'); + +$__widgets->create('text',__('Text'),array('defaultWidgets','text')); +$__widgets->text->setting('title',__('Title:'),''); +$__widgets->text->setting('text',__('Text:'),'','textarea'); +$__widgets->text->setting('homeonly',__('Home page only'),0,'check'); + +$__widgets->create('lastposts',__('Last entries'),array('defaultWidgets','lastposts')); +$__widgets->lastposts->setting('title',__('Title:'),__('Last entries')); +$rs = $core->blog->getCategories(array('post_type'=>'post')); +$categories = array('' => '', __('Uncategorized') => 'null'); +while ($rs->fetch()) { + $categories[str_repeat('  ',$rs->level-1).'• '.html::escapeHTML($rs->cat_title)] = $rs->cat_id; +} +$__widgets->lastposts->setting('category',__('Category:'),'','combo',$categories); +unset($rs,$categories); +if ($core->plugins->moduleExists('metadata')) { + $__widgets->lastposts->setting('tag',__('Tag:'),''); +} +$__widgets->lastposts->setting('limit',__('Entries limit:'),10); +$__widgets->lastposts->setting('homeonly',__('Home page only'),1,'check'); + + +$__widgets->create('lastcomments',__('Last comments'),array('defaultWidgets','lastcomments')); +$__widgets->lastcomments->setting('title',__('Title:'),__('Last comments')); +$__widgets->lastcomments->setting('limit',__('Comments limit:'),10); +$__widgets->lastcomments->setting('homeonly',__('Home page only'),1,'check'); + +# --BEHAVIOR-- initWidgets +$core->callBehavior('initWidgets',$__widgets); + +# Default widgets +global $__default_widgets; +$__default_widgets = array('nav'=> new dcWidgets(), 'extra'=> new dcWidgets()); + +$__default_widgets['nav']->append($__widgets->search); +$__default_widgets['nav']->append($__widgets->navigation); +$__default_widgets['nav']->append($__widgets->bestof); +$__default_widgets['nav']->append($__widgets->categories); +$__default_widgets['extra']->append($__widgets->subscribe); + +# --BEHAVIOR-- initDefaultWidgets +$core->callBehavior('initDefaultWidgets',$__widgets,$__default_widgets); +?> \ No newline at end of file diff --git a/plugins/widgets/_define.php b/plugins/widgets/_define.php new file mode 100644 index 0000000..51a8a7b --- /dev/null +++ b/plugins/widgets/_define.php @@ -0,0 +1,22 @@ +registerModule( + /* Name */ "Widgets", + /* Description*/ "Widgets for your blog sidebars", + /* Author */ "Olivier Meunier", + /* Version */ '1.6', + /* Permissions */ 'admin', + /* Priority */ 1000000000 +); +?> \ No newline at end of file diff --git a/plugins/widgets/_public.php b/plugins/widgets/_public.php new file mode 100644 index 0000000..f38f843 --- /dev/null +++ b/plugins/widgets/_public.php @@ -0,0 +1,115 @@ +tpl->addValue('Widgets',array('publicWidgets','tplWidgets')); +$core->tpl->addBlock('Widget',array('publicWidgets','tplWidget')); + +class publicWidgets +{ + public static function tplWidgets($attr) + { + $type = isset($attr['type']) ? $attr['type'] : 'nav'; + + return + ''; + } + + public static function widgetsHandler($type) + { + $wtype = 'widgets_'.$type; + $widgets = $GLOBALS['core']->blog->settings->{$wtype}; + + if (!$widgets) { // If widgets value is empty, get defaults + $widgets = self::defaultWidgets($type); + } else { // Otherwise, load widgets + $widgets = dcWidgets::load($widgets); + } + + if ($widgets->isEmpty()) { // Widgets are empty, don't show anything + return; + } + + foreach ($widgets->elements() as $k => $w) { + echo $w->call($k); + } + } + + private static function defaultWidgets($type) + { + $widgets = new dcWidgets(); + $w = new dcWidgets(); + + if (isset($GLOBALS['__default_widgets'][$type])) { + $w = $GLOBALS['__default_widgets'][$type]; + } + + return $w; + } + + public static function tplWidget($attr,$content) + { + if (!isset($attr['id']) || !($GLOBALS['__widgets']->{$attr['id']} instanceof dcWidget)) { + return; + } + + # We change tpl:lang syntax, we need it + $content = preg_replace('/\{\{tpl:lang\s+(.*?)\}\}/msu','{tpl:lang $1}',$content); + + # We remove every {{tpl: + $content = preg_replace('/\{\{tpl:.*?\}\}/msu','',$content); + + return + ""; + } + + public static function widgetHandler($id,$xml) + { + $widgets =& $GLOBALS['__widgets']; + + if (!($widgets->{$id} instanceof dcWidget)) { + return; + } + + $xml = ''.$xml.''; + $xml = @simplexml_load_string($xml); + if (!($xml instanceof SimpleXMLElement)) { + echo "Invalid widget XML fragment"; + return; + } + + $w = clone $widgets->{$id}; + + foreach ($xml->setting as $e) + { + if (empty($e['name'])) { + continue; + } + + $setting = (string) $e['name']; + $w->{$setting} = preg_replace_callback('/\{tpl:lang (.*?)\}/msu',array('self','widgetL10nHandler'),(string) $e); + } + + echo $w->call(0); + } + + private static function widgetL10nHandler($m) + { + return __($m[1]); + } +} +?> \ No newline at end of file diff --git a/plugins/widgets/_widgets_functions.php b/plugins/widgets/_widgets_functions.php new file mode 100644 index 0000000..c855a7f --- /dev/null +++ b/plugins/widgets/_widgets_functions.php @@ -0,0 +1,368 @@ +'. + ($w->title ? '

      ' : ''). + '
      '. + '
      '. + '

      '. + '

      '. + '
      '. + '
      '. + '
      '; + } + + public static function navigation(&$w) + { + global $core; + + $res = + '
      '. + ($w->title ? '

      '.html::escapeHTML($w->title).'

      ' : ''). + ''. + '
      '; + + return $res; + } + + public static function categories(&$w) + { + global $core, $_ctx; + + $rs = $core->blog->getCategories(array('post_type'=>'post')); + if ($rs->isEmpty()) { + return; + } + + $res = + '
      '. + ($w->title ? '

      '.html::escapeHTML($w->title).'

      ' : ''); + + $ref_level = $level = $rs->level-1; + while ($rs->fetch()) + { + $class = ''; + if (($core->url->type == 'category' && $_ctx->categories instanceof record && $_ctx->categories->cat_id == $rs->cat_id) + || ($core->url->type == 'post' && $_ctx->posts instanceof record && $_ctx->posts->cat_id == $rs->cat_id)) { + $class = ' class="category-current"'; + } + + if ($rs->level > $level) { + $res .= str_repeat('
        ',$rs->level - $level); + } elseif ($rs->level < $level) { + $res .= str_repeat('
      ',-($rs->level - $level)); + } + + if ($rs->level <= $level) { + $res .= ''; + } + + $res .= + ''. + html::escapeHTML($rs->cat_title).''. + ($w->postcount ? ' ('.$rs->nb_post.')' : ''); + + + $level = $rs->level; + } + + if ($ref_level - $level < 0) { + $res .= str_repeat('',-($ref_level - $level)); + } + $res .= '
      '; + + return $res; + } + + public static function bestof(&$w) + { + global $core; + + if ($w->homeonly && $core->url->type != 'default') { + return; + } + + $params = array( + 'post_selected'=>true, + 'no_content'=>true, + 'order'=>'post_dt desc'); + + $rs = $core->blog->getPosts($params); + + if ($rs->isEmpty()) { + return; + } + + $res = + '
      '. + ($w->title ? '

      '.html::escapeHTML($w->title).'

      ' : ''). + '
      '; + + return $res; + } + + public static function langs(&$w) + { + global $core, $_ctx; + + if ($w->homeonly && $core->url->type != 'default' && $core->url->type != 'lang') { + return; + } + + $rs = $core->blog->getLangs(); + + if ($rs->count() <= 1) { + return; + } + + $langs = l10n::getISOcodes(); + $res = + '
      '. + ($w->title ? '

      '.html::escapeHTML($w->title).'

      ' : ''). + '
        '; + + while ($rs->fetch()) + { + $l = ($_ctx->cur_lang == $rs->post_lang) ? '%s' : '%s'; + + $lang_name = isset($langs[$rs->post_lang]) ? $langs[$rs->post_lang] : $rs->post_lang; + + $res .= + '
      • '. + sprintf($l, + ''. + $lang_name.''). + '
      • '; + } + + $res .= '
      '; + + return $res; + } + + public static function subscribe(&$w) + { + global $core; + + if ($w->homeonly && $core->url->type != 'default') { + return; + } + + $type = ($w->type == 'atom' || $w->type == 'rss2') ? $w->type : 'rss2'; + $mime = $type == 'rss2' ? 'application/rss+xml' : 'application/atom+xml'; + + $p_title = __('This blog\'s entries %s feed'); + $c_title = __('This blog\'s comments %s feed'); + + $res = + '
      '. + ($w->title ? '

      '.html::escapeHTML($w->title).'

      ' : ''). + '
      '; + + return $res; + } + + public static function feed(&$w) + { + if (!$w->url) { + return; + } + + global $core; + + if ($w->homeonly && $core->url->type != 'default') { + return; + } + + $limit = abs((integer) $w->limit); + + try { + $feed = feedReader::quickParse($w->url,DC_TPL_CACHE); + if ($feed == false || count($feed->items) == 0) { + return; + } + } catch (Exception $e) { + return; + } + + $res = + '
      '. + ($w->title ? '

      '.html::escapeHTML($w->title).'

      ' : ''). + '
        '; + + $i = 0; + foreach ($feed->items as $item) { + $li = isset($item->link) ? ''.$item->title.'' : $item->title; + $res .= '
      • '.$li.'
      • '; + $i++; + if ($i >= $limit) { + break; + } + } + + $res .= '
      '; + + return $res; + } + + public static function text(&$w) + { + global $core; + + if ($w->homeonly && $core->url->type != 'default') { + return; + } + + $res = + '
      '. + ($w->title ? '

      '.html::escapeHTML($w->title).'

      ' : ''). + $w->text. + '
      '; + + return $res; + } + + public static function lastposts(&$w) + { + global $core; + + if ($w->homeonly && $core->url->type != 'default') { + return; + } + + $params['limit'] = abs((integer) $w->limit); + $params['order'] = 'post_dt desc'; + $params['no_content'] = true; + + if ($w->category) + { + if ($w->category == 'null') { + $params['sql'] = ' AND p.cat_id IS NULL '; + } elseif (is_numeric($w->category)) { + $params['cat_id'] = (integer) $w->category; + } else { + $params['cat_url'] = $w->category; + } + } + + if ($core->plugins->moduleExists('metadata') && $w->tag) + { + $m = new dcMeta($core); + $params['meta_id'] = $w->tag; + $rs = $m->getPostsByMeta($params); + } + else + { + $rs = $core->blog->getPosts($params); + } + + if ($rs->isEmpty()) { + return; + } + + $res = + '
      '. + ($w->title ? '

      '.html::escapeHTML($w->title).'

      ' : ''). + '
      '; + + return $res; + } + + public static function lastcomments(&$w) + { + global $core; + + if ($w->homeonly && $core->url->type != 'default') { + return; + } + + $params['limit'] = abs((integer) $w->limit); + $params['order'] = 'comment_dt desc'; + $rs = $core->blog->getComments($params); + + if ($rs->isEmpty()) { + return; + } + + $res = '
      '. + ($w->title ? '

      '.html::escapeHTML($w->title).'

      ' : ''). + '
      '; + + return $res; + } +} +?> \ No newline at end of file diff --git a/plugins/widgets/class.widgets.php b/plugins/widgets/class.widgets.php new file mode 100644 index 0000000..ae7cf96 --- /dev/null +++ b/plugins/widgets/class.widgets.php @@ -0,0 +1,234 @@ +__widgets[$id] = new dcWidget($id,$name,$callback); + $this->__widgets[$id]->append_callback = $append_callback; + } + + public function append($widget) + { + if ($widget instanceof dcWidget) { + if (is_callable($widget->append_callback)) { + call_user_func($widget->append_callback,$widget); + } + $this->__widgets[] = $widget; + } + } + + public function isEmpty() + { + return count($this->__widgets) == 0; + } + + public function elements() + { + return $this->__widgets; + } + + public function __get($id) + { + if (!isset($this->__widgets[$id])) { + return null; + } + return $this->__widgets[$id]; + } + + public function __wakeup() + { + foreach ($this->__widgets as $i => $w) + { + if (!($w instanceof dcWidget)) { + unset($this->__widgets[$i]); + } + } + } + + public static function loadArray($A,&$widgets) + { + if (!($widgets instanceof self)) { + return false; + } + + uasort($A,array('self','arraySort')); + + $result = new self; + foreach ($A as $v) + { + if ($widgets->{$v['id']} != null) + { + $w = clone $widgets->{$v['id']}; + + # Settings + unset($v['id']); + unset($v['order']); + foreach ($v as $sid => $s) { + $w->{$sid} = $s; + } + + $result->append($w); + } + } + + return $result; + } + + private static function arraySort($a, $b) + { + if ($a['order'] == $b['order']) { + return 0; + } + return $a['order'] > $b['order'] ? 1 : -1; + } +} + +class dcWidget +{ + private $id; + private $name; + private $public_callback = null; + public $append_callback = null; + private $settings = array(); + + public function __construct($id,$name,$callback) + { + $this->public_callback = $callback; + $this->id = $id; + $this->name = $name; + } + + public function id() + { + return $this->id; + } + + public function name() + { + return $this->name; + } + + public function getCallback() + { + return $this->public_callback; + } + + public function call($i=0) + { + if (is_callable($this->public_callback)) { + return call_user_func($this->public_callback,$this,$i); + } + return '

      Callback not found for widget '.$this->id.'

      '; + } + + /* Widget settings + --------------------------------------------------- */ + public function __get($n) + { + if (isset($this->settings[$n])) { + return $this->settings[$n]['value']; + } + return null; + } + + public function __set($n,$v) + { + if (isset($this->settings[$n])) { + $this->settings[$n]['value'] = $v; + } + } + + public function setting($name,$title,$value,$type='text') + { + if ($type == 'combo') { + $options = @func_get_arg(4); + if (!is_array($options)) { + return false; + } + } + + $this->settings[$name] = array( + 'title' => $title, + 'type' => $type, + 'value' => $value + ); + + if (isset($options)) { + $this->settings[$name]['options'] = $options; + } + } + + public function settings() + { + return $this->settings; + } + + public function formSettings($pr='') + { + $res = ''; + foreach ($this->settings as $id => $s) + { + $iname = $pr ? $pr.'['.$id.']' : $id; + switch ($s['type']) + { + case 'text': + $res .= + '

      '; + break; + case 'textarea': + $res .= + '

      '; + break; + case 'check': + $res .= + '

      '.form::hidden(array($iname),'0'). + '

      '; + break; + case 'combo': + $res .= + '

      '; + break; + } + } + + return $res; + } +} +?> \ No newline at end of file diff --git a/plugins/widgets/dragdrop.js b/plugins/widgets/dragdrop.js new file mode 100644 index 0000000..ec01538 --- /dev/null +++ b/plugins/widgets/dragdrop.js @@ -0,0 +1,29 @@ + +ToolMan._coordinatesFactory.inside=function(item,container){var iTL=this.topLeftOffset(item);var iBR=this.bottomRightOffset(item);var cTL=this.topLeftOffset(container);var cBR=this.bottomRightOffset(container);return(iTL.x>=cTL.x&&iTL.x<=cBR.x&&iTL.y>=cTL.y&&iTL.y<=cBR.y)||(iBR.x>=cTL.x&&iBR.x<=cBR.x&&iBR.y>=cTL.y&&iBR.y<=cBR.y);} +ToolMan._dragdropFactory={firstContainer:null,lastContainer:null,makeDragable:function(item){var group=ToolMan.drag().createSimpleGroup(item);group.register('dragstart',this._onDragStart);group.register('dragmove',this._onDragMove);group.register('dragend',this._onDragEnd);item.isOutside=false;item.started=false;return group;},makeListContainer:function(list,name){if(this.firstContainer==null){this.firstContainer=this.lastContainer=list;list.previousContainer=null;list.nextContainer=null;}else{list.previousContainer=this.lastContainer;list.nextContainer=null;this.lastContainer.nextContainer=list;this.lastContainer=list;} +var helpers=ToolMan.helpers();var coordinates=ToolMan.coordinates();var items=new Array();for(var i=0;i)qCKiZ{9K>JG9{dNUHBNPzoplRQdY-w`Xs@-h2At(Cse=Z+)3_+jD!649rIzOxWfv>>M(m!br2gVIawnVm6% z%Fs8U>{RQLRjax()-X&l)7is*BV%Ij2j@;E$0iMDo(2t`UQ5BXCGAXtr}-E@U%mGJ h;WUpUwX6&e_=C5LmWVHU&kMAh!PC{xWt~$(696NJuetyL literal 0 HcmV?d00001 diff --git a/plugins/widgets/index.php b/plugins/widgets/index.php new file mode 100644 index 0000000..b085b06 --- /dev/null +++ b/plugins/widgets/index.php @@ -0,0 +1,300 @@ +blog->settings->widgets_nav) { + $widgets_nav = dcWidgets::load($core->blog->settings->widgets_nav); +} +$widgets_extra = null; +if ($core->blog->settings->widgets_extra) { + $widgets_extra = dcWidgets::load($core->blog->settings->widgets_extra); +} + +$append_combo = array( + '-' => 0, + __('navigation') => 'nav', + __('extra') => 'extra' +); + +# Adding widgets to sidebars +if (!empty($_POST['append']) && is_array($_POST['addw'])) +{ + # Filter selection + $addw = array(); + foreach ($_POST['addw'] as $k => $v) { + if (($v == 'extra' || $v == 'nav') && $__widgets->{$k} !== null ) { + $addw[$k] = $v; + } + } + + # Append widgets + if (!empty($addw)) + { + if (!($widgets_nav instanceof dcWidgets)) { + $widgets_nav = new dcWidgets; + } + if (!($widgets_extra instanceof dcWidgets)) { + $widgets_extra = new dcWidgets(); + } + + foreach ($addw as $k => $v) + { + switch ($v) { + case 'nav': + $widgets_nav->append($__widgets->{$k}); + break; + case 'extra': + $widgets_extra->append($__widgets->{$k}); + break; + + } + } + + try { + $core->blog->settings->setNameSpace('widgets'); + $core->blog->settings->put('widgets_nav',$widgets_nav->store()); + $core->blog->settings->put('widgets_extra',$widgets_extra->store()); + $core->blog->triggerBlog(); + http::redirect($p_url); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } + } +} + +# Update sidebars +if (!empty($_POST['wup'])) +{ + if (!isset($_POST['w']) || !is_array($_POST['w'])) { + $_POST['w'] = array(); + } + + try + { + # Removing mark as _rem widgets + foreach ($_POST['w'] as $nsid => $nsw) { + foreach ($nsw as $i => $v) { + if (!empty($v['_rem'])) { + unset($_POST['w'][$nsid][$i]); + continue; + } + } + } + + if (!isset($_POST['w']['nav'])) { + $_POST['w']['nav'] = array(); + } + if (!isset($_POST['w']['extra'])) { + $_POST['w']['extra'] = array(); + } + + $widgets_nav = dcWidgets::loadArray($_POST['w']['nav'],$__widgets); + $widgets_extra = dcWidgets::loadArray($_POST['w']['extra'],$__widgets); + + $core->blog->settings->setNameSpace('widgets'); + $core->blog->settings->put('widgets_nav',$widgets_nav->store()); + $core->blog->settings->put('widgets_extra',$widgets_extra->store()); + $core->blog->triggerBlog(); + + http::redirect($p_url); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} +elseif (!empty($_POST['wreset'])) +{ + try + { + $core->blog->settings->setNameSpace('widgets'); + $core->blog->settings->put('widgets_nav',''); + $core->blog->settings->put('widgets_extra',''); + $core->blog->triggerBlog(); + + http::redirect($p_url); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} +?> + + + <?php echo __('Widgets'); ?> + + + + + + + + + + + +'.html::escapeHTML($core->blog->name).' › '.__('Widgets').''; + +# All widgets +echo +'
      '. +'
      '.__('Available widgets').''. +'
      '; + +foreach ($__widgets->elements() as $w) { + echo + '
      '.form::hidden(array('w[void][0][id]'),html::escapeHTML($w->id())). + '

      '.form::field(array('w[void][0][order]'),2,3,0,'hideControl').' '. + $w->name().'

      '. + '

      '. + '
      '.$w->formSettings('w[void][0]').'
      '. + '
      '; +} + +echo +'
      '. +'
      '. +'

      '. +$core->formNonce().'

      '. +'
      '; + +echo '
      '; +# Nav sidebar +echo +'
      '. +sidebarWidgets('dndnav',__('Navigation sidebar'),$widgets_nav,'nav',$__default_widgets['nav']). +'
      '; + +# Extra sidebar +echo +'
      '. +sidebarWidgets('dndextra',__('Extra sidebar'),$widgets_extra,'extra',$__default_widgets['extra']). +'
      '; + +echo +'

      '. +$core->formNonce(). +' '. +'

      '. +'
      '; + +$widget_elements = new stdClass; +$widget_elements->content = +'

      '.__('Widget templates tags').'

      '. +'
      '. +'

      '.__('If you are allowed to edit your theme templates, you can directly add widgets as '. +'templates tags, with their own configuration.').'

      '. +'

      '.__('To add a widget in your template, you need to write code like this:').'

      '. +'
      <tpl:Widget id="'.__('Widget ID').'">
      +  <setting name="'.__('Setting name').'">'.__('Setting value').'</setting>
      +  ...
      +</tpl:Widget>
      '. +'

      '.__('Here are the following available widgets for your blog:').'

      '; + +$widget_elements->content .= '
      '; +foreach ($__widgets->elements() as $w) +{ + $widget_elements->content .= + '
      '.html::escapeHTML($w->name()).' ('. + __('Widget ID:').' '.html::escapeHTML($w->id()).')
      '. + '
      '; + + $w_settings = $w->settings(); + if (empty($w_settings)) + { + $widget_elements->content .= '

      '.__('No setting for this widget').'

      '; + } + else + { + $widget_elements->content .= '
        '; + foreach ($w->settings() as $n => $s) + { + switch ($s['type']) { + case 'check': + $s_type = '0|1'; + break; + case 'combo': + $s_type = implode('|',$s['options']); + break; + case 'text': + case 'textarea': + default: + $s_type = 'text'; + break; + } + + $widget_elements->content .= + '
      • '. + __('Setting name:').' '.html::escapeHTML($n).''. + ' ('.$s_type.')'. + '
      • '; + } + $widget_elements->content .= '
      '; + } + $widget_elements->content .= '
      '; +} +$widget_elements->content .= '
      '; + +dcPage::helpBlock($widget_elements); + +function sidebarWidgets($id,$title,&$widgets,$pr,$default_widgets) +{ + $res = '
      '.$title.'
      '; + + if (!($widgets instanceof dcWidgets)) + { + $widgets = $default_widgets; + } + + if ($widgets->isEmpty()) { + $res .= '

      '.__('No widget.').'

      '; + } + + $i = 0; + foreach ($widgets->elements() as $w) + { + $iname = 'w['.$pr.']['.$i.']'; + + $res .= + '
      '.form::hidden(array($iname.'[id]'),html::escapeHTML($w->id())). + '

      '.form::field(array($iname.'[order]'),2,3,(string) $i,'js-hide','',0,'title="'.__('order').'"').' '. + $w->name().'

      '. + '

      '. + '
      '.$w->formSettings($iname).'
      '. + '
      '; + + $i++; + } + + $res .= '
      '; + + return $res; +} +?> + + \ No newline at end of file diff --git a/plugins/widgets/style.css b/plugins/widgets/style.css new file mode 100644 index 0000000..9873027 --- /dev/null +++ b/plugins/widgets/style.css @@ -0,0 +1,76 @@ +#listWidgets { + float: left; + width: 33%; +} + +#sidebarsWidgets { + float: left; + width: 65%; + margin-left: 1%; +} +#sidebarNav { + float: left; + width: 50%; + margin-left: 0%; +} +#sidebarExtra { + float: left; + width: 49%; + margin-left: 1%; +} + +#sidebarsControl { + clear: left; +} + +#widgets, #dndnav, #dndextra { + padding: 1em 0; +} + +.widgets fieldset { + border: 1px solid #999; +} +.widgets legend { + border: 1px solid #999; +} + +.widgets p.widget-name { + background: #d4d0bc; + color: #000; + padding: 4px; + margin: 0.5em 0 0 0; + border-width: 1px 1px 1px 1px; + border-style: solid; + border-color: #666; + font-weight: bold; +} +.widgets p.widget-name img { + cursor: pointer; + margin-bottom: -1px; +} + +.widgetSettings { + border-width: 0 1px 1px 1px; + border-style: solid; + border-color: #666; + padding: 4px; + background: #eceade; +} + +#widgets .widgetSettings { + display: none; +} + +.hideControls .widgetSettings { + display: none; +} +.hideControl { + display: none; +} + +#widgets-tpl dt { + margin: 1em 0 0 0; +} +#widgets-tpl dd { + margin: 0.2em 0 1em 0; +} \ No newline at end of file diff --git a/plugins/widgets/widgets.js b/plugins/widgets/widgets.js new file mode 100644 index 0000000..b61f6d6 --- /dev/null +++ b/plugins/widgets/widgets.js @@ -0,0 +1,21 @@ + +var dragdrop=ToolMan.dragdrop();$(function(){$('input[name="wreset"]').click(function(){return window.confirm(dotclear.msg.confirm_widgets_reset);});});$(function(){var widgets=document.getElementById('widgets');var w_nav=document.getElementById('dndnav');var w_ext=document.getElementById('dndextra');w_nav.className='hideControls';w_ext.className='hideControls';removeElements(document.getElementById('listWidgets'),'input');removeElements(widgets,'p');removeElements(w_nav,'p');removeElements(w_ext,'p');hideElements(w_nav,'input');hideElements(w_ext,'input');configControls(w_nav);configControls(w_ext);dragdrop.makeListContainer(widgets,'div',setHandle);if(!document.all){widgets.factory=true;} +dragdrop.makeListContainer(w_nav,'div',setHandle);w_nav.onDragEnd=navDragEnd;dragdrop.makeListContainer(w_ext,'div',setHandle);w_ext.onDragEnd=extraDragEnd;function removeElements(p,name){name=name||'div';$(p).find(name+'.js-remove').each(function(){this.parentNode.removeChild(this);});} +function hideElements(p,name){name=name||'div';$(p).find(name+'.js-hide').each(function(){$(this).toggle();});} +function removeEmptyMsg(p){$(p).find('p.empty-widgets').each(function(){this.parentNode.removeChild(this);});} +function navDragEnd(){formControls(this.parentNode,'nav');configControls(this.parentNode);removeEmptyMsg(this.parentNode);} +function extraDragEnd(){formControls(this.parentNode,'extra');configControls(this.parentNode);removeEmptyMsg(this.parentNode);} +function formControls(e,pr){var items=new Array();for(var i=0;i');f.submit();return false;});});} \ No newline at end of file diff --git a/public/.IMG4_m.jpg b/public/.IMG4_m.jpg new file mode 100644 index 0000000000000000000000000000000000000000..47d6d8e7b26aaf78278d7a3b773e5387e19dd01e GIT binary patch literal 27064 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 literal 0 HcmV?d00001 diff --git a/public/.IMG4_s.jpg b/public/.IMG4_s.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7c161c0bfe4b694de8609ad0862d517d50f01378 GIT binary patch literal 7121 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 HVdlR9Rd;5i literal 0 HcmV?d00001 diff --git a/public/.IMG4_sq.jpg b/public/.IMG4_sq.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7b7c6b5b840db5e1f6160a02e4e20cdad0006f3b GIT binary patch literal 1143 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 Avj6}9 literal 0 HcmV?d00001 diff --git a/public/.La_fracture_52_sq.jpg b/public/.La_fracture_52_sq.jpg new file mode 100644 index 0000000000000000000000000000000000000000..011ae0fedccf020a9d58b328b13d873350443ea4 GIT binary patch literal 1240 zcmex=_1P|rX?qqI0P zFI~aY%U!`Mz|~!$%*;qrN1?DZF(+nejWjF5eW%#5iv0-Syg!{X=NEPF$En3Wi@q8Elo*zT?1VW162)8 z4Uj>M?Ck8kTtEYaK?VqGNQp^lkPQAGU=ZYBFkmoXW>jKe5@ci+Wc+`GK_2K^Rz@&j zfC5G)W}v&-Ie_lu2CCR9z`(@F%*@2X%*x8b0#sfLRKUO@$SS00=*T7bFC}Pw& zaUqAY)5e3MK^H%$7$+4q0da^)IX3ko)c*)Xb%U7&iwQ2K~t=qQm z*tzS_;UhlG{sQ@ok%1ZF zF(3)?8oJK}fj(nmVPR%r2lxl7mfC}~?)Ea<4`$q=b?+GtaIzNOUv*Mt8Ir#7$57WaPS>Z`k{;_<8(Z_hJ? z8!zcG{Bc;t4G4 z9&Grkyf^aS>8o9=zpK(^%k6)D`I~*&g0KDB2Aksl3`*;k)xT`6*J?GXjYyGo5IFqI z`o8kKJJ-tgFTWS{qd5F`?1i~|iW9 zc;LzV*C&{Nth)U%x5UqYSBay4`RBuz)2}S+cw>G*-)D32_3QOf-RF6B{tjTD^Y)L$e}>4fOMW}>g>L0IchA6G z;roAvX?wFT?mU`w;!0|ubnRw!iDU2f)L-}i+_ip%uj=*o($wlHGhNraS{^ID^3KHe u@CxhoWg6=2_qW^SZ(Q!LK6i1}ZatP0x*aDhW$o|hKMl0)Uj9+}|4jfK`|oT3 literal 0 HcmV?d00001 diff --git a/public/.La_fracture_52_t.jpg b/public/.La_fracture_52_t.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0593446d9fb087508ed096337cb93cc09c50e64f GIT binary patch literal 2391 zcmbW#c{tST9suy)m|@~%8T*zQ#xjz!$Ak${q*Rl=XvWrR9m`;>9Tiz-P_jls-6K?% z7D_Z(3Nx0mr5MJR>_YgR>74uA`#krrd++ys-tS-E_xpT5@B4!N;8#Gz#>(0XfIt8M z!d(Ek101qAV`+BQ?hF>?B7y>f0{r}f0^&l#yG5kLrKP3B zB_(C|s32wK(DIU!sC_83s+#&p(9j5Lam3Q<=rL;>{8@VkM<-_&4^J;|pNp3+2a$q9Lc_@6@z;M(xN-AVA}u{5 z^UmF@d)Y+~iXWDgmOXm>^x5<3n%cS-FW)sazo&m_X>DV6_w@F$`UeI_$JpZ&oXM%_ znZ>2$mDRN$>l>TDWDo%QH;kMArv0Z3!IkmAU{DzRmkh!a%H2=|j8{>cPt@!*oDd+U zq!YVK+?-li)yR+5J+mM|3}kR!%6g+Ji@$Jx+5S6P-2Y|!7wzA&L0~r&!hJv}0>A-l zNfF0}j4ZdxkltvdSAj|AK+e|Q-aAoOgDY};BhN4PoVTsnJXu5(YCOg~yO@tlXz<~` zvDUIyCGpvSB1EjdAl%Qvt$q74YVI1s0MmoY&bC->Xucsq1pej5(HZU{I=C{~z;n1%rr}&NJwp(KQg* zvQ)cUyO!3c|6s~{VJ;Q~?#lW7TzNC<#=Gch6(=m!Mtys;!6kPufX&vcw`0%Fgby7hauE?gIuK8Rd;ADwe{+n!158Y(Yi4+vB7B zft}6IOvW@>YkDEhO&_yUIOFmJgYeY(5S-1_-2Q9xO3T+&Q!XwiGiodYneLaI`WLQj zoRU)-`AVf5q9UTPtS*+8KP#oMSD&Qx#KgTwHhKC%p_<_$DlX<0 zf|w!^`yPH9ckq6^`R;Y}fXMWcs?c()Wnr+5R3>CQ@C(TZ&B@S$TQ=#sSI;@gG z!wqh;kmc6A4Vm=~C%h7=s>)YrI)>jVn+|u^h7l7{t!0F;F{Z_~2FqIEimrR}v&VUr zuE>mFa-FYk!Do`(4cz_4vImPNIu^X*T0O2c9-{>whr9&=d^gp#;veRPsp(-MX<9WM zLG-Y(?BFna`{eRPm=Djut=VCZM55N4QPp~}BTvn|%O>+mMpF#ccASNpqx2`fNTJEb z1jTdgR(H;op)dHPkEA8v2K?;}&G?q-S=I(Camyj2BB>Z+z0Cvxmp0ctL(0H(Uz_nH z2!vO$lQ_9_5lLm_N#kIX|{b$I+ab7EI2((Ile2#i1T_& z6sv7pr3{JcBHS`~Ch@k$A`Khp#VL?@?c_i^6gcFHdy%SU1dINI-L*VY=p|Ams(0}^ z8#ndZa6En~Sf&*Dv=wt;;`d<-!raM@P@nI?jm8mC`ZMw{yeldLH=yWu*I#K+-lMC) zphT;bN`=8<#F0w7h3!GWnUxCyt23CA>hYwOB`Ynj>hXXNh?Ut5d@-hhKu)vbCz>++ zYAZn?-+k@?2lGmLyry=U)lpOHy`26d!4QB>a}*vdj@5lh)Si65pF-qbS5<;5v0b9R zS@Y+|3wFT#2L;DcT!DVumYsRziM0OhHtrvD?j-r$_?#ch4+7TFdx$Vcc7mMR~Y9ds>GqT}eY7l!SlEQaBl5LhiT5d?yh-A`s`!w;~b41^3K2 z9QTY|bZZa1S?`qKE)u~vd{^Viti{9)3g?&G;u_QgpYTQN=txx>md3M(jZ_2v1- z%)I?dFt%K_M~YVTL}`7vX`h-DTH{py2*mH_3mNGpjohvrD(fITm7MmgBKIO zWGe5rHTr;D>XiQEm}8UIMW;1BuU#Y;&&dpJQOL$jQ>q5p^8`=ksZs?$->mJ)lD#Iy zHshYRD%|!wM8&r@<3V8YO}Rf(Tp9%4oeIb$YixZAO)WjCoJ_ky$+4H0NTb0Ezs!Na z>=XEyUfT#7x7r$guPj(%1&hIlVq+=ld7bTj6-{L)Qb&stm+y!6*fbXmisf#PG-UL> z$@2NW^Zc~S1Ie_4K|H%C>gd*GgI={2yA}{g7RP%QJEl9-?MYw4vCrM9RdREGUMq5B UK1Mgbd$}l)w1d7lT?G#O2~|s3>Hq)$ literal 0 HcmV?d00001 diff --git a/public/.La_fracture_53_m.jpg b/public/.La_fracture_53_m.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e2faccd2b3e4f978f1517d9427a5295a5349272c GIT binary patch literal 42793 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 literal 0 HcmV?d00001 diff --git a/public/.La_fracture_53_s.jpg b/public/.La_fracture_53_s.jpg new file mode 100644 index 0000000000000000000000000000000000000000..12a8d202afbc572484d530155f5fe3b1438d97ab GIT binary patch literal 11803 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 nokdDf^YSBOg literal 0 HcmV?d00001 diff --git a/public/.La_fracture_53_sq.jpg b/public/.La_fracture_53_sq.jpg new file mode 100644 index 0000000000000000000000000000000000000000..cf32ce84bccdc38b6738b90f78965b81024a8bef GIT binary patch literal 1282 zcmex=_1P|rX?qqI0P zFI~aY%U!`Mz|~!$%*;qrN1?DZF(+nejWjF5eW%#5iv0-Syg!{X=NEPF$En3Wi@q8Elo*zT?1VW162)8 z4Uj>M?Ck8kTtEYaK?VqGNQp^lkPQAGU=ZYBFkmoXW>jKe5@ci+Wc+`GK_2K^Rz@&j zfC5G)W}v&-Ie_lu2CCR9z`(@F%*@2X%*x8b0#sfLRKUO@$SS00=*T7bFC}Pw& zaUqAY)5e3MK^H%$7$+4q0da^)IX3ko)c*)Xb%U7&iwQ2K~t=qQm z*tzS_;UhlG{sQ@ok%1ZF zF(3)?8oJK}fj(nmVPR%r2lBPa+SQ+y|`xX zfds?L``Nn=7-}f25&Xa)uW|fe^ZQt_?Fznn7mSV_Y+%{&gs1HLx|01)$3$+KC!RR? zH@o$VsY7zm?wN`&&oi%o`gO?-qXTX;PoC7WWWU}uahmOk#zp*F3JS0MD!#Ya?a0r7 zhSCGdll#{{_DIPQ(7dCpWf3>G@O;*mQ>Pa_=@IHF41KnvJMl<|$aft}n=c0GcIk`=2*8H5zw?xnQPvpzq zzZEZo4vG}HO#aW16?MG%GkfyED#r`Ga*T+4Qg zi{5Wt>x;y?H_|MQD{O8q!%j*Tq ozD(U@zrUyc@w0^)OWOT34HQ3A&HuM^olN|p(ueVT>i^#a00)EyNB{r; literal 0 HcmV?d00001 diff --git a/public/.La_fracture_53_t.jpg b/public/.La_fracture_53_t.jpg new file mode 100644 index 0000000000000000000000000000000000000000..06505f5d6a24f51683f6fd36a3cdeb0760610e0b GIT binary patch literal 2591 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 C0}Ukr literal 0 HcmV?d00001 diff --git a/public/.La_fracture_54_sq.jpg b/public/.La_fracture_54_sq.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6bf1cfce5f001dea6783bb79843517d9628e9733 GIT binary patch literal 1303 zcmex=_1P|rX?qqI0P zFI~aY%U!`Mz|~!$%*;qrN1?DZF(+nejWjF5eW%#5iv0-Syg!{X=NEPF$En3Wi@q8Elo*zT?1VW162)8 z4Uj>M?Ck8kTtEYaK?VqGNQp^lkPQAGU=ZYBFkmoXW>jKe5@ci+Wc+`GK_2K^Rz@&j zfC5G)W}v&-Ie_lu2CCR9z`(@F%*@2X%*x8b0#sfLRKUO@$SS00=*T7bFC}Pw& zaUqAY)5e3MK^H%$7$+4q0da^)IX3ko)c*)Xb%U7&iwQ2K~t=qQm z*tzS_;UhlG{sQ@ok%1ZF zF(3)?8oJK}fj(nmVPR%r2lx z@s16%9=MC{TkuI;B6{h0xqGQqnKHUlf-?6s#GaOs6M69K`QP-c{*ba<^}vpu3As0q zRrU189{(Bcobv2;m0JIbsjp|Ixc}MoTr~WM@ZMvcD;8c}zFp3_?&G(FkC)rj7A-q^ zsqT~3LBl@HB@(Bed=8u&vFUw;jz{vz6n6E0zn1iOSN?o+=W2yohs!FJREyhhD*rQ7 z?Rmp?Jk7BBSjSZcr<%1kGDT%P!pG&SmbQm!J)IKq&X$);LsItqy;a&;JM-@w$Tc_E zfBfaBKD$%u;T8FJGK?qAfBb!YWpcyb{|uZwPjWx6`M$y8fZUwIeXC<%m5Xl^-{`Hn zdHIC5zqcM#maY5w_`}l7sqtriJEuIDz|Zjb@4uO=&Kg#%U-&sS^^^S5BL4jE=Rd7^ zzS(5?N2Su(jdytFF_)||w0>AuE^GMv;Pv(2SG$T>?r?HoS5|qz%e7>g?W=_g3OH_w zo>$@jzEl2h)#ne=vK4zzN`;l^Y?68Y?C%SS^MCl}KQo+=qq}9B+0VuE{xjVFwk%qA z!AzmDK*`seV$$!wue#Q=>1B>5Q~cg@Hye&seSaG__nfqd+t0#BayeP#c8sX@)5 zmqo?j%1;=*v*piy{xhs4ICHW`L*;Id1Nk-yk3aqj()ng=@-j#IjKLgv3xi{}#)0M~ LAtsaT|K9`v@vRz@ literal 0 HcmV?d00001 diff --git a/public/.La_fracture_54_t.jpg b/public/.La_fracture_54_t.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f754f057cb3226492b030db6e60db681094ca794 GIT binary patch literal 2695 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 literal 0 HcmV?d00001 diff --git a/public/.La_fracture_56_m.jpg b/public/.La_fracture_56_m.jpg new file mode 100644 index 0000000000000000000000000000000000000000..52107e97e87e0f5f64cb8ae1d1c507d24d54f1ab GIT binary patch literal 40747 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 bavbM>zt|wu3a`g;7SAP%JHf=d4|D$mVGDrQ literal 0 HcmV?d00001 diff --git a/public/.La_fracture_56_sq.jpg b/public/.La_fracture_56_sq.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6bd7acaf61545b6d671c341a97ecd2bcd4656320 GIT binary patch literal 1298 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 literal 0 HcmV?d00001 diff --git a/public/.La_fracture_57_s.jpg b/public/.La_fracture_57_s.jpg new file mode 100644 index 0000000000000000000000000000000000000000..cabd646dd917b9fbe31da568721539c7c3b08b77 GIT binary patch literal 10944 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 literal 0 HcmV?d00001 diff --git a/public/.La_fracture_57_sq.jpg b/public/.La_fracture_57_sq.jpg new file mode 100644 index 0000000000000000000000000000000000000000..91ada6e779395216b697adf077d755cb8c16a178 GIT binary patch literal 1304 zcmex=_1P|rX?qqI0P zFI~aY%U!`Mz|~!$%*;qrN1?DZF(+nejWjF5eW%#5iv0-Syg!{X=NEPF$En3Wi@q8Elo*zT?1VW162)8 z4Uj>M?Ck8kTtEYaK?VqGNQp^lkPQAGU=ZYBFkmoXW>jKe5@ci+Wc+`GK_2K^Rz@&j zfC5G)W}v&-Ie_lu2CCR9z`(@F%*@2X%*x8b0#sfLRKUO@$SS00=*T7bFC}Pw& zaUqAY)5e3MK^H%$7$+4q0da^)IX3ko)c*)Xb%U7&iwQ2K~t=qQm z*tzS_;UhlG{sQ@ok%1ZF zF(3)?8oJK}fj(nmVPR%r2lp4U7td+|pFb=PJ_|1*2twt9#C6?N*UYQ1_D@nGfo{FUqNB|prq$nSVrdZTBSigVuE z9m&W2tDY$xpRSO*$W5W?#_Q(u@k>jkp7hG~a&xlOtn;*B?`xkJb7@C(^D|!w9gZ`- z$G6$#udR~Z=dPG_?WStLF4h^PR`7LvPC%44e!5fB$^%nRIk*9<%TB+zAc$+kYS1^C$Vc z-yQuUrEy9s85Vo^O z29`t@@W0RF^Q)Y4eaWwyKIK`z9ctI;UFO+4d*bzfvr1ok=q={orTwDe;PeMo^{4$T z*Uhs~+kB>M+e?*N=aZIqzx-adgunVfgWa^l|8C3wQ(M}4POtKgt77&B!=9%4z~8sZ z=Bv-mwftOj#>|MXx_-~q8y??h^CfIQzkF8xk6B0deD0Y1mQ(8Ur#DGOwx6`mAFEMM K6a9Vs|4jffoDS>& literal 0 HcmV?d00001 diff --git a/public/.La_fracture_57_t.jpg b/public/.La_fracture_57_t.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c772c4132d128e04b499b4e7c356e3f23b59c68f GIT binary patch literal 2510 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

      CB5y1}SLniyt<6X|7 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%0Dh>_CzD@W*ndm+vQJ}ObMU*yf@Y3K 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 z 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 literal 0 HcmV?d00001 diff --git a/public/IMG4.jpg b/public/IMG4.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c7729218b6ab3e77138e53eb326ca8aa45a74d97 GIT binary patch literal 302521 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�{7{$lf+cL4*+NooYxI#F1 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

      _v)=S=#KqE}Cc8hE$uyhg#L^lj80% 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 z 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�jhDAgO$S4pS7OB6FPI8e~Jj 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 literal 0 HcmV?d00001 diff --git a/public/La_fracture_52.jpg b/public/La_fracture_52.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d32b04e6f651df65010985742779136aaa6c3fd0 GIT binary patch literal 139982 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

      FcuK6b{=L8mae+8 ztwLnHE?}^=L2NZORRW|IZOakjeYEziZ(DBc3#dC~)?`;?T2<(4u|9a)8!+5}G}p>{ zDc)_wO82M@UIQ^nQC*C;xRaw(D+o`%Qjl0NG0Fiy;JpJ=sbm9@^d0(0y?g6{EEz9J zL#e;f*nvI`JKbVw;nXm9sx|9of6dp-#BF7AwsECBW5;Rhr1)t{M%(kw4Vt?9%a!JF zRdJK_ti&5^R;U*(4VT`SlI=1<6`UXHjKvR<0;k!DmRaF4lb`I(y(yud6-?+)n9`m~ zbm2Wxx1uuwO}`-`A?Jw=J_>W=MyA)MTRGtbD5=Ic{5WJzxx-Qmw8iE_m~dQp51q1pf6(=@=vf4W98htt4Ne z*$2`oR@9j>N@8gWDl8CyomB|Vz+y@e^w#c*#o9UbNFYn~Bg1b3WWDe&q^#UVCe+ zXDRV1X=A78qBcX{T(lLwz3Imnm6Y*{er3Y77uoljFB%U8^2mv}d4ll-cG+EwSf8DX zQ5PqqkK%0!fly=RH5UbDuE!2*?W^!Dt=HT(h2Hu$yX>xEFSegnlBsp+>QZ=+R-9r1 zzu5gQ52nULGgjq$)~qsTT=FN!NbjbC?`?&1X>M&>#C@<+xd123-YjmU*$Kw*qc4~@ z!89ZnL3`q*Rbr2x##Q`8QYeDSnD#gGwBoL8>%wroHgy=}ib@Pc{_6hPsk7*8`-?}j zv`r1la7ZXoS${}MaE!WQTIoFQ>oL;{H7Vz9)b14sUG7w9=Enl*TpV;UUKBd?{OkK? zTLrUnIHYT)t1JkQz`QY{Y}uc>6**3S^VtRtX>$PDG5Fm~+{ekCnBDe3j=%?5J&OrX zZ~)cZ(FTHl-dgB?eT=Zh4+y@TShrvhnIfd#p69dZKNNrQAwd@ zT^de;nWEThn^Laz{e-Fd$rhKKQpSIEXJUq{r+NH~@Z$Xe9q=SQ7I>3I^bP*>WQEmp zMGgyGRD2BNkYh_PK~aQO-94#Y=#LRtrxd99)e=8FWE&r(foY#hL09xC#f55@DjyBS zAM4ybDOqSt_E`7yoaw25MY&6vpBHM$eSCnpbsV5Q<$T1-{0`2>KO<$1G=DN{csM!za=NxFW9%0Pl=DBhmH#1ufkkkAL~}^&NU0uLxUnSRPZts zkpel0r@UK^cMt+LTLqvbV561#bG3_-FVw7Yba|4FpB3x1ykx<35Cxx0rk{ zB~viC2f<+qiX;Ws&XBkJHKsVOps{T~9<(i@XP**9YPhvh z@&4-WT8N41RmMrCLG-IRXbU8O|Cm^<9a5N(3_EiTJ6fp z{9^PHu|ZsmmdWt8G{mE%1)JNcmS6!mrsUEKlbU^E2wzGm4+cBna(7i`@sy#SJ4sD@ zuFb`-h-`h5oDx%U%)Xv-6r+x2M}0Y^Jf=hSG#GqNg?&hz5U-|1C&tSkA#)yKfu_)s zm+M!YTDHZZ1<^RO6-;!eL~2=WC$g;~t*m!6<<*+9A8vvS(bJ8X?5||l+rlb~Dc^MuRY_P258L3?pi7#J%D=fu7A8aahfR?V%})uQfCr|Cf^O5{pLOA z3#K7qM`wH&NSYY>If(_fl}*CBl}q`Qi$Zf&PzBpc)fC4k((})C-0xZJCmNB8@tWTl zA7v%fS;~VbUnp<$p`*}hxH-mM#yG5k1wMzET^kFX?KFPka7gosr!0$M?T1j%P7!?> z?PxynW?dKiRbpM*+j9b6<>UQutsLLA5VJgo<*q@u!zF8(L}z4l3*D-1B@ZLxH)UrKyEowoV>%^@jOJYQP)vhjXvrbk~S z1T>fY_W9o3nP!u`B5I=B4=zucrnw;cmJ=F|OJ(A2jC z`N+$WKyB$k@o8en0Avj7H;EoR1@uXDZHQ?=MabCImRFjH@e-bFhID8XU$Yx*GJzbW zk3yilgEEo~-Tf*?Jr_Z);H(Pbw~!azJd|0LUred_3wv4mA?aCBF{06>sVYl&B;`jx zr-oP4uZ*rWL%uX-ZIe{@jWTS=%$6EWUN))Nr@t0_90~4{zOR;=c<`>HEs>S`c=T(li5Sd<;;Hq*$(1uJ3!*@`Z!@Q3Cm zoKbg&M=)qv*15b~=hV^FA=M`1h}gt@wd|KsyZbm?y0=?(lxP5?!yK{NV;S}Kb3;Zh zZ%EfHjq7%CxUKp-qI`Mh#mCl*CXPlZA3#t)ty%f~yOsJE=_(ziI`*RP6bEQ1+j}G{ zGk#XQc&VPZ1NK=;eznE^$;8DJSk+_)8IfK}^l{UbKiPjFVV|K%3r#o6$*Yt@95mD+ zry`L#u>_4J^$2}ZODH6wfiRR?%UF=8aIZZ;KmQ&c-Zn^Iwa}P=Ce(NGju-r;r8maAF^oP#l&MgZ zchbV|qZ%|^+BB@6Al4{`uaSajZDtDt>uSQ%g4Zc_tHi)nOeLNPZW&0)1)0$0KN69ejp?zLYXO%4}qXX#cmnpcGD z6O9W1nZa^N_rJ+iIN7xBIA`=cXV3V%?@J4kiGgWhXBUW+E|{Ew{=CBj zv^WN)B^5VEA*;Ofc@iRQS$oz?QaO*w^8)T5&8f=IWAF!?>1qSn<(x>~KG71`PJ#*; zQK^2XeDT!>*}*5MRc2y3#M?N^YT|J#PCa}^NAkDXk3#A~L5&}V(0BHNo*7_@sEE2v z7f*c#pS!n7c_hjq(1ro782EWy(Nctdhm*tTtFb%wl-h*)N$q@ff<>xoCAQfq$*BW3 zU5w6ntRI=GC31qpjFDjCxp|bi(ve)+Wc~VY7C-7wpwEL;5v6{%m6ioxaSZ?_AhDp#q4( z4Vj>f>s&i~5d+QeaOQ)_g5`Qt;3Lg%#}KhG>=Y`q79aHqT#nKuRTMUvv(10f-8;kn zth_OYEL6~Ijpk!@4FYHc3U{yoxryrQ)@tW5=bphspm^;YxAU%USE@*us~8S_Q_%ETcnU$kDl;0@c`Cxm z7ZryGD_Ww=ljxK7NzZ%Da(BdfI=wLMQsS%>1V3a(HFhx0-%)XDt|F;6(gib==D0ag z>eE_@KKy~|WAt^;_dSg(dTOjPX*ApIGexb4y1qs(l2=tW8}4(tI9+hsEmsr|p&?<8 zvrF+(AM*AApk=&KR4wnMYoUgxBgrdCR*C7NVwobP8Ha?<&=sjczOA7uPBe+W zYIqi9=eR9pzj@@K=efuUR*KF*nA_P5F8WNtgof3P?iQi%bjW622$5MjzuU371-II< zYo@2p81V2|sicQRY=2jnFz9%6-B|9$aFu_}tG&jAx9RYxJ2RP} zOR?_d2WLy_UsH1S1Pus+a@xo7B1+S50`EeYObi%UzO4mR#7f8%K%l8E>2j<`g$>Ul zU8C5XtsIIHZK?^oY2NtJNijc437Gk? z1XWT0Z-~oJe)w>tpArZ8?RXtu{Qcg5L7B=};8cKAhagA5D6gmF{y>sP)04FXsv_EMX_4B?cyI;(kUP?Wpy)0-b8iDsB zJoF2QMvc$yIfqvyGEPk|(H@ZFnVg(7M>oH;YIpi_psmB(EMvw*rj}k{>ZBQXzONu$ z$fck08W?{qBS?XsLFw7@D<-c;#1`qG&TKt z>M|W66i-d?JY_-$p`YKR+c89g5>5XG0!vDg{zSDzBshIRHtCX#%c$rQWnR;ztGmd# z1R-VNLLba|Z9WZ>fCy zQOXws#;+)dEqDP;?_(9$r7>3! z8wrH~vRyjqW8tw%_|}?#Io$1KzT{qQGf%B1ozi;)p+%SAE&sVEWa3Y4%hl<7*0C!_hIqoamu{mKNCOsA*--uxn7 zovOxsGR+VxUb{!|hru=7ZyzOW(gc-RIdD2qP(xgrDUB+?p6jc{oMwU!;^VZY66KLr z6%q<6E2A*^GY`Siv8-1@q@?Cl=~gTPu?%IIf$1bV9A<^?mPfNNCRFs-qM*b?Jt19P zzJmUGm2~14?`iPFK*9snRSMRm_^XJd5xE8HqWmoF6JzMxbfQ(!L1T$dbBtvL8=~ZmVBO;OPyRo`ek;U)k*D?$UXl>9;QNJc{*V2-{mm_#b1A#`3 zhx5RHvjdviS#gOE8xWx+wDgi<^i+r2ph~dwn(}g?#Ew<5@6%6T$QVxnwHg#D7~#(z zF2^MnT|T3a7_)9;(C3o;sK>4qDm<^8i#IfUT_0;Br8ewH+F>EzQmlGRZAqhx3@0-g(&5<1 zynd)n4kUQ{Z|yfvgysW-^|n zbk}!youP7EGG*euQV^~4UkFQvUns>G`&GI8mT4St9e0G_9&R4Iz3%cg?fFq z#F%Qp*YOj9(v;OBLCJMPx5CK`FgxpUW1GYK1|R6a^Fv;qR1&cqDp-C~eSSDxWQX;B zN!<2EGoVvg^qrJVey%PVs#K_{C)T24TbN!C@vAD+l*=L8B1w&ZC8d3m8ZFwV_%VQ~ zy28C9xTYjCs_0evto~JT(=T!?a2>F!Ka28Yt(2N}@V)mXDS%g(x+jOdFO&`;6ttgQE9jd`XyK- zS~y1KxVd9zo4DRG00)xG8ChkCmmq8-?hhVv@Y0nD`O~p+>t-edpGV%fNx`Wp_$}kS z?MQ-t_V&~0Cj%Un;bb#(bb@Lfl+@r*CUqhxQ{`%O8xoRP2KJmTP4%xT11^0uSU8@j z)(P?si4?)7IB1$u=<%G=rYk%;h-6L3@AV7i?ZwnKWx`_0_*0FD-c$p4J@C?zwazBK z+l@0~YyB3<+snc9!#=$EKHp(2WREvFGC9zE zq>~h?OB%kFTeCHAbVe_-^f*(3&V>ZXhpi*d-EI6F8h^+oUlW8jM!a|B72s%r0L1;X zFqHoBB-d^0a!0zomh?s_9V;n^%oJw!t7DnOVPal2B#o}|K40i zLn}dn#+)33&3aRXv2UIiWzDA*iecV) zrLl2XKtU)3_4)p&*9)=XAx|Oo&+m{A(iBTcte2w4T*$0TBZrAE^^doPj;^fFZ{pr! z#XZOU$T#LYB391xq~@uTg7m_ZQ*mYE2_ykTBHU^>L9Hg!KLkmS=Isx=gz^N@}H`7v)1E`{sqsIb0L*wAeGa)X5K5F{itZpNB0-Wv)MhKj5ZwadV%y)Q)C4YYGPqZ<@sGVi$g zBXgQcMKby1W24F>N#uoM-8FoE5AyD9$IPD1MVbw)b4zP@oObmb z`aGUaSMc@J_dI2yEmmx!s7AxvX7y6sRmDsZ~135zZ{Kl zPb-*bD)7;JGIwLgN;p86Q~=@(cPKoVq?@aR=VzM>%IeDp(_u9q zVq==S_>0Zyhn=yJ`Zfs)!7a1x777blZ~Vl+f?2YkM#jkVF)^FcA2g*x%QH2@DJyi( zZM1l64_m#Um;E66jwJt1n-=F>@wuEu?&5Rms*~f&_8}BY5Nb+rz3-)XYZs~4KB>@A zjJegXj6r72|DkjZ0xr|>4`Q48eee9 z%^NCvP5+W1DE+m8s>@eoD@tW_Q9pJ6UK;qyA!Ki5J{r0HRcy)1!?vs^%-5W_e%dR| z&QD{zM*1)4pkMO16&NvHMUrdhMcPEAwpM!I4h zJ?f(Axl~PO8m(LQQ`_mXAxA-SO}C&80-5bBSQ!B!JynjmyT;bYFlhM9M!{E;RXQmH zX`W@+mzy^s80-4@w-l+vcKP*Kvro5(Wr(^AB$_5gs;lIkt{4Zo?2X{Pc2%S%jsus* zMH>vv-MS(DdvjS1-=9}MY)`kayl-;I+}70kxa#|K6-5!RuH?_zeAq{V$my1oj>$Lo z-N*q1@@8zlkzYnB|?P-$<{PRuQKfr z65k5QPMogVBxNO&(VXtN;=OYM>y`GrO9n-a`!qpvCSv=c( zi@}Sz@Ai6EJa>4?uiav>5C*4bwyPA=4}LIJr$`P=^Ll*$zURZ!`^SK8TOgr9+9@-# zP29Vse5oGy%MIwFTHD`ZloV2acX%D$7U~Y*ThJK5MR4w6V1V=eYmf6w zWqSkMT2Lk~gu&IR#evWFR3|aZ_*72sUMH#1^$UqGjaQ9Zx1Fvb4^==CZsIW6_jfx4p%U~)l z7q?UakNlvi)5@JI1O1*Rzmqg2_d>Hz_ea_Q7-A+w%+9?I4&5XDc&$8otQ0o(CLLz1 z>*-S_S!HO;&V=HnK}CNur>kg0s(UbuwzIE^P;gZQ?sfUijt)EWek$~37TE3PXE2w^R8j((M(hL%cv|nh?tDP#4@weMy30SWBc>3*Rt$bJNg=~hxRTd zuJL>id24!dPu`(=vXWf8fNW7nvH4q!HM_g!fqOKkXstDITb=qsib;j2s_bwERo^{Q z-Y@!^G3~q7;#0ET;Wsn%ZZFu~3pRruq_}z;?1i*FS*~c}8?hU0yyqv`BK*ix+Bu20 zS-cU+LM}Slr`QN%cgrz>Z%m-Wj9DoPU2br&p<@i{HMX5!y$pKT9J@=oyVB0?dV_6K zccQ*+`P+{)_j^`34LyPzl1BzQCNb+=5)bjBM#_ZO>kej>jo~}jH9(9uD?y%1?Hz16 zHVOuh_h*+dHTLeTF(Lbxr}7;Z!A^JGWeHw_J!mSWWotht@-sO&31_pCI>Zn&bgR(( z=*yRXW?1EZ)46}1%Ka>H3L@tzNE=@fCE|K(&r@)?(C+8H|Cpb2>YBPt+hf_`R`n^ZU1(8&bC zY?|{*t4rQ&iyM>Ti8ehPyYFSbix7!JLK8HeaL1kB%z4k~O?_M|>fVxN-v463B(e$- zYg#U`Q9e+*AC_~-O(x9*TQSfISYiLQCi}BcKMdvatX*-PPs`GaHf#AA@$WIkvVo3) zFE!s?Us~CWD6P9^)!oi1*sFDBu~t)q8WOO|?yLb%f5_g?OLI)YQ!l-2ud!6=p^f`G zGO*cT)8Bn!$hc?ni7G;w>?Ta!Ko@j=_~tb+W4p$i>b6DDyt2`&_!9SQ8JXgDt7{;p z5Q8`Tg2Y^E=AHw?mnM1!5YRr!#$vnWujGjz=9f2G?_b>A+grN5wEQw()#k^(*^$in zsEHTcp9H$0q>*Nxpltv{G##%p-b>WEUAP?cu2C*k9JH@UmJ@~CE%N_5Vq5pV_L`wb z?c5fl#*?`_8(&Ok<*DteT1#U@H>BcFr`EwSG9ge_iHw=(rcEl!4wdB1V*`TdUKvXD zpGG&v2RB+DY&*(ETYbNob^Vy(6~vNuzxG}d8F{s7oiSR9?6K1CI9Qo@s|%A6xUx9M zwOCQZjzlwYDE3h1>sSFQJ8MMwc5eT!n0=5*)X6j|c!(f>x-nkwx9V)#Ll<&dJ0rkv#v7 zC+2bByiEH!mb&eY+!f~?(E+nIzcGy(=6wqN;rJt+08delw#Irxc7yESk?cP5AO<9U zx5q6v1|~7UuRY{N*3Vs3?A4tOZr0(3le_Z}<0X$}WKhtOYyTESh+0kyslL#9fS}Njlbw8Dg5z1qVUO!y9&=UK!SuA0hEiiS`;)H^ZK|j_orhAsGUf zleJ8xL>3qhimeW9{pN&(v#Q%R$A?-coN?bU z``=@AMlF&j19~#)>-jGnJMHI&#P&B@D%NY-=3btgy_Q17l(qUcgeD$Q$TF?7PVE(G zu6PkjN*Gc}Pdgt!BpMCfRfqq~4vbcckE4J8+hXs7#}zI4pc~hon=~_Lv$Xhz_)^uK zWtVG7H=^!jbJUjAwv1X?=2_;NGKBPz2me&zNmaQuK4D0mynz^3H-+wBwSHdNj~Q!g z`|-%V@x9-m=qp60Tc=*e1NTbW?_aFGyuJ5`(1TP+h0HB_Qg{Y#MjPD}tt0U)q&C(Y zJg5=n_x3H zLY3)`@_OR}LrzcxqrY+Dp05n5={@ic!shY<%M<);X!HVe=u!^~+Chu;{pp32L$+(sp4$XQiIEYrd1`G+U@G5>MM5 zRfj+qW58Y%ZjIs92$!8cuTeV{UHTR`Sz{8^t8C;%e_$7M@3fIxT)rTP$ELpinq%Od zoA=8`3H%_jk6LLYhRco=%nF-p?~+v-2|(nwzuL5Zf)b3Tq-a}Rf49P@=at#P0?FF8<`FJ(Klw(yphSGUe|PWzSVYMBv6(+pV4l; zzOTECyOXR<_M#8vm5m!?FUZ-8pQ`T=*Ly#?sb^4m;mjd21*M1RNL&)X$Uwz?t9dhQ zOHlnd(^wGHcmt)&{)*c6ML1k#yXC0L8El~jE6*xYAs0sdmK!A8(P$5+^j(7qryKNg zK-t-;P2Tp6;i>5@=oPs@0(cU*(~}pUCy+Pw7)rt&@7N2vb3%m_KC-2gazwztOAxq4 zr0s(*_@5wI0`m0;ppzb(r|5_q;~ej`mpkA6We6inQha=#e3qJ;UOH=vGu%ehNHNpmfo%E<8em~B>1^L zJ(w;=Ad|b+$i=x!!B-y?DwN}}nh?qi(q15S2J&^8DR@HJlRKH3jKs@apwXTVLKfv8 z!xt2VuL>zYmDl1^**x2R!l^?SYjcE#CdC^Z6F`lUb3V8@wXX;mrdvYpgVVtR-L}h> zWzL&(<^&AJVx$IYkn(K?tBrnG0yIS#_j1pOMX-~#@=KE%j4WP9l_j&a#>FT};UQ!c zdZ0H1fJV4q8IjWet~L2R!=V6i@zy)!i!TP>fOMM*U4A79_JeQqa<3(4O;e?*ks0zJ zyycm&z=IY`aUu;EOI!QrRKpF_w=migbBj0PMx_LtR=-STX#6XArgJ?gDt+eVj9fCn zMo}XVIrStV5ro7E+K87WQgz-0og5dH!0RU|(3?~9P^h+-gDrC@ zO%<+}dIX2P~dy&&?;6OoL~lQhRPRd2nW;p*1YWmA*+m7%s?{VDSAp zYjVTOa1AOH7m{>MEeizt7#vLBx?c6&@Ks4Pub@}HQX{DwZo^2#x3JX;Do4_L@ph4N z>GLdaNbfHN13TRfiO@pQUP2m(KgdNXvP2agg3ly!tiw^(A6?a097#s1R2|^rRZGvS zu9l3{OU6sJ0_%b#>J6!FBvkq0?eCjanKn_6;GTwsnt+6orL$^vmbj07t44Uff~G)y zJRSYi=u?%^W_=wWc>|6ZvpBQGq&Gsm|sSsgY0O+zTcyu{+s&kk9I)qjXI^Ss+1Gca1Df)0_Q5nF*znii{IW z6M$r8%aoSVsC~RF+?D>t*P%u#xCD$WxRZU$40M7;YJZ%o--o{<;mU*n#$}+d z`OK^-FXEFYVXQGcO>||t>zarBQ|o7}O|kc)*9?s4IAYS31pyGMk}GPx%f}#(^$}N^ z7u#ZTzCyeXelmidDECtG?)B1+=OZ6AA*@!;rjYQ3np~5IN_3Y*$!hAwB!n$R>QFE< z_uNDHReDxu8SxEbf%P zOIH%rs@e^6{x-59*SSDuS2K$os{O5!F1%e;Smswo6g$mLmYG~wbdx*lQ&a>C#E?q2 z@*F-irqMfKMB`HO6HMpif}GZL@|(w7aoUuSyS-dfUe?xo6s zF_Htyyad^WT)(2++B$OUv9sHfFR598jB`Z|UkT&Fxy|xwbdPn&2yAVuttG+qnum_SpX6H*V=$N#R+uO}u-%yCnDK229#q1OI%Lz68}rSkV>g;}(hF)Sy3 zM|Z7)8sYUFD!o|uRnd0}VAaz6DE#rzKPkXe!z|Yb8gYjD_;}2kD`*^#+_1_)$jz*( zkS7yVL6K}!%01OxQ>Gs*m$XfK=^G;BX@saF^#Fa3;WPzz0L4Ob$uLEV7H!?v*@^nR zyiNHO$`jkX@iAhq-b7!_W;FYT0To^hvqC(w zBrsL(IVG9%i`OQ+b=jokO>0XFq{L~J>!uX^CoWO<-Z#D$Q|Fn6wY)$yRfdN+dKU@- zbe9tC;!FI&{f*Y_Ud>d+*B+Ob=a%QXgv*qZ+22`9E@OyL2q;slB;_i^@PvNBr=Ne}s&79ZJw@P<9+V{|R4Ob07`CDLY_=JROr@IFRb1SmkGMRL5EsSkg_ zN!spDHo6q9wO6@R(tj&WF%)a&uGhc!F}3ohg;1om7eP*RX>=+1%wW`NLwTYsSe4pmw7 z+(ozcH{uDEewZ|0zn38I<7%ZG+Q|bj<&f^tNp<8FLn$nJf2B?O>D;u7)<-7Pcv>Sc z7b#mLXaj+n@my_Q`ijGf!oPbJXs(tx%a%FSi# zhX%f{uRd;m^|km(!;Gm{51RJAQ@^`pUlXU<11J2hH4LCbmro1gLC!7{*gh`Ju)vd!UgU>!cl!;~lSy!fX=%jRHx;^~uQ}f3Vg=%m zEUPkznvSt{Jge^%O|P1Vy_x(0|I&+Hy9lz!<^lQR?0_q}&Rss0m-!E-f)dWW z%QxdWp1Zb|OkEB(`Sdy}m@9QxOvCSTE_ijV9H(|y3L|$V7)IlFQsrtt5Mwl+AJn6; zz&UOUamB5iUqd_GXR?>+{8#qkPnDzQbM0J=KrYgoDMA5QU?gR^f*n22eoPtrMeqvu z6)CZDIyI*8wKu82uHq{yf$*B|QEI_qze=Dfm>%l0iP$d&w$(IB2g>OJSimB9wW&HU zVF&@OPOs^2l!L&or%Ed&zdWG1>^RWF1axw3TF6n;1iQV zl0A=NeislBZ+nAs3r6@h(Zl|%{ery<3Uo)Coom*Fn!_*=!9eb(KZ(guq zba`+)Z&RK@Vv6!VKX!jcoPBwOrU{PGDmZaU=?|vCtaHbD5^jXOE%1TGa9`&1_o+%6 z&Q1vOugQAC-D%MhlxqT%2;K%Rj6XnzecBr*N$Uc+d=ETA$@tX$ zW5K6fIq^`R71xJhn?t(Q$Ij5%3(C@VcEeLcOi|ms6Xr`<)2}1-Q^s9V9oy}dQ(d31 zg{G4WqC8H4!Y7i|+vw?hjTEpL&#nOslT>`|HQR%@nEJ41U)svETNRj z`I{`dbOPrNF(c9PP*+D%fWcXUAGaA%vE)K28S@}MOi^*^%GeOyaW#`(e}4VCcLgU} z_yYd<$~{=Z5GBX&>G3~k`s%nQzc=hrQqm=*G>jAkq&v1D3`R+}Gze1CoidRWklyI- z1_h+0MyJG=?oQwR-p~8~x6j$Lv*+G(cFrBwb=_NClITmcJ%h@kmVHx(=YHW{!+0yl zNunNBnhxoRFHeomr<~B=GW}GM;|0+dcv7QBeVw419s4Zts%}Sew$Js?p3C-L=BrEV z`+9Cz?+>jTg>^d_h(6H)}t{H4Ra zaQSg~`rh*{%vM$>v}@Y-Xc-KA)TaVTgKA!bA4?@xYcK8}v>to(>+bTa9`yo`DFN!& zv`$3Dna^GK(U0{}<{yBvD;ot4x}BCe1}bg7n3R_Cs#e;)i6^_0)xZ)&8?ex(jRuLA z+Ag1=*W0KbnHdkI00xxOk!0e|E#y@FKC*H%@gHFN)iDla^Nl381RX~YX39&+df%I! zr>Uv7CSh6GvU(2mXLVk+i^MVqU>or7zE;*--%OX5}uiYf8?$Py-t;JTMFB;U9J2Dn_-~ZibzY>})=n-VU zJ70Sa43aHtN_6PDzbxv*3hD=H| z0yp#J_O%=~*P&_A)vgs?mG-;I{gl;@WXV0{^+al4OTfC0wPj{9xsHoFXtGL@?!WOp z>F>FHU@Z(D5jV-1hQ&M2+oQO>WpnWn_0c6{%Z(% zgvSzThPK1hou^#`C1DgS#`>H9GD#}oPoj9^Sgcan@?~eFVfJV>EXPUqBPc(VEY$S# zodadyk79ouB9Xnoum1pd^*5EWC}18x;U<&ME3zttz-GdfZ&oQ!d90B4VhT`!TO{@; z1`{f4sMN9gRkb5;T+QxQhyR79g6;spB`7x+%h@I^0*qC;XvZ6l34=z-1zD0f zW|91NT9jHlAn}UNCM|fY2}W(@FVGvhK3>nHs`%ygT}R)i zO$-nvcojA?En(67u9@53e!G{LhwpJZpu;e5;kfxF&cim=>pyH8F|F6n7a3veJ!$-E zWzjt#x5g#NJE5VynnB|hHweTdi@#+C?q#kn##)80DWs7F@)+=Wl_AeI2*zw0huTe! zpe)j@v-l|k-Dm>V;kfQ~SDH->g)3`j{l7xv{{96?3bz1zK_ZC8_6BbafgS28Gt zWuKpMwn;xvyzSntqL@TIfERCNd~Ly4*eEmtn+M)}2QS~1tv7Ms~Z9{f%V}5_Qp!zanW|H zP&4j1KTDm>@4@@+uIjdZHgiBjBly0K%q1zYkf#vq6N9`VYb6NU$N-aPX4hr)b!b_? zHEkoe;XPEw|62$NGq5?dNoz<|ko{0QAd-q+0)GE*M6o>fsuoYia9F^RH|lr&1NzMy zN8V0k*W?6`+5F54e2kg|vrrsw^hu3&c1*isAI)El47Uvk_!T73X|4GWtvZ$kqLEE7 zdQj<*Zi}=W=<)81lWOnc?DRdMu)<0_a|7L@JRU6gX`GET5Swlm7JJDgXIyk2!Tbhu zCU?T(vXKlz$_1=>Y`togR~|#rnEjjB<4e!qd>#AhFKJc!w$=?%pfB@IXVnb2@IHW2 z2T8T$K#mBG_;^C~EPU!p``RIcW4{O_nvoH^tM)Vi!+-^t*lC||{%Jjm;U7-Y6QI#n zCr2bRGmnF$z^6s(*ZY;xY0qgWduW7V#V_+7_z9Tkkdh?xj}ki!G=dFNl|-d^LFwRP zsCLbCZB%K}H=B^o13Ik3u&!NI#M_WnMThfebfZCxzW)G-$i4c1fOW#LeT2rBrijzS zsse$ngxDioIBML0-u#=Q_Bu&qEl(di+u1^7xFc^&ekg@{V=h)ucIbfInY2Ip$IdHy zT((L7%ni(=CzYogs0x(EHL*zuQmG{zS_iTAx=6um`)HK0Edd*fL-|F2PiBWboQ6H&m+q{h^qfZU5}fVWvi*@TzR{(MSX(mTZRgXVT(%Q?;fY&a#kGl!<7|Q z6+rS$f+GUidY>^X!+Vk==ch+Z8L_xdBa1qltg)8YOL3Q@ZVLQ$d@tIS+2tFWRMH`+ zb%mDZ^Ci;YczZ_eDoAy1x6E>zKjvtm@b3|?9QCmFVjfwSz-dmZ> z-M9XwKpHujZ&f#_0a%|*#_t!62fm1P<=cE>cNYD!@SjRs!TyN>Ay%(j<j-3TV*!J#6=aRNJ}glhbQR##Ug#`*Ap1D9n`^$iWqN) z7Ww^*Qc)HR!CSTgjf_>JR?vof|L~>2ef?N#QPUmop~FR9_(s~b@u-VP$BqT5KBF23H4T>Y;s~Kdga7B^ZVsR@UF2nBuQks)wqzP1#eijNo&K!4(FAYs|A_Um;tY8rK2mJb^bdM6rZ?&36f-3K(OfdR1&p^BlLzysTW_99nH;f4Hr!>v~My zIqp1r+)!@Y@qPIFjEtY7b9DB+Wvxz{puRg!CG4n$sOQGDvoT?VM@{aN!SzeC+`J|V z#r*(r2vrHcD?eiswx>$=M|Oxef!8^I3+! z2jDJQ%Ovv$CuU5BhidDL=NPj0)CovMa;Fr^`x#h^EM%KX3=3#GpgfUM=z|bL5<|PZ z_NsQkH%9<{NTUCNw~o9W{~H-z_}?CgetDPn4*=<<3dpwfn|L)Mj-#4>S9LGpcyl}* zb}4jpM!2-AX0M74UA~zBnwc3W6Xs#vBA#YskGivoa@2%V6PylcU%mq4q$!ke*X$Vz z6O8oAdqkm}^ec)qTV$`L2i|?{x9DGnCGyl7cn-yXyrfMF}q@0th4yf;lz5Q*llD z6lCF2Ch2M(qs3y>y$Ja2X?Tk^%J2Dk?;u_{B6ILI$3pBHo-mlq8f6?Y7as_X$-_#R z%OF$lKb*c8ez`R!HgR2q2X+&|3KrRdVQd(B-0am57i#E+%j_-cKMFo}Q-+^vU<6Ddqiyb)YAQqZ z7}jH8vjKr;y`3?@K$46ZV1`DfoSaV>Jgdc%X9^|46T$YR8|L|-p0oWq--=UkRG`I> zd1`0Mr+M%PUA}^9Bb!)t4hYMYh|S_fz&NJ82CT&sduw6muvR2x@kf)>NsgC}BxJ>~ zK=^)F!Nju>yp~eIhXBgy1oMpBf0xV!*D5d!>fO58{!Ba&ug+3D`R{du=)Oi{EK1(1kLxQ*TX~lEPvhGTgV;M9ZfzM%oQ$` z>LBlin%J`TXIgnU$%_6&F8$6M4dl^(7MSh#uDNjXUMjK6c{~wwY7nSPJPo+96Z(^3 zmy2GJZXEB@zj7V1}| zdGDVMIgeB2b*zuV@ln-V(8sB#LtKM|=-RKKKRJ(mL2U*z)*e59c)xo)HrViLZ{}ki zrN_b%WLb2V`=v!n&i@@Kt~143n0_5Q^??B$EzQr2P+P)z-}Y&8jEW_V;~gFU1MKX7 zz}w>5U>Ja^5%ta@S=!K)_VE$XisSDT-7`;)7jJylOH8+{H5 zZ6wKKx<4VOB54Bk`IDO<=so|^_Z3W1VV=0}689-hG%l;`kdQL$b0fH3&6TOEY8P4C z$e52rapiR$jg))qR(%5JERFJ z{Kn=#7^#s@zLd-FV493!I`BnPFWn_Gs%#;t#ufKJ{F2-YYGH+0+91dd<_=sZzrDlg zD`Ufx7`~0u+m=AJXUgg%OoeZJgY>XnM@2rl9&^^od|v5 ztY0d(a08(>s%@%)!^7o+w>Kn<$6ozI9qC%u1&g1N$;sK=3ej`3fvrd5-=@ANtC8sr zmSXqNQ1Y>05>4d@-at~Cm?&szGy$OmRA+XKZze25eLm(@=V zj(S-=Z9~SUpyH@FDRjN_vH8T_~@sO^QAn4RF7@^crD<3Yf3L_ zk5MsT9VwGR;sU-8vP9R!z-zeXfX{RP*6rWwF@f-vla%MbsHH`?LE(V8!UcDNf zi7E`)YsfjKRQUlQmP(8dND3(C!hY3M&dXk_+kdfnlndB{re#;}c|zA^xW3DoOJVws z&D$vwst=$i^$q#{L}=z|_*`;GP-q{m|a(8@v=S1mVK!=zJw(&e|X!o{5zLQ`bV z9zEfR-|QAl5KsDA#*B+^3(wgBIul}#^#m7aEi7kbBm&M(8_b*LTDP1p0K`93c_H0O z+0ILS=P!FAD!iy7G3n)A6O1vHx4@6WY3Xki3#IHBud!-603n0A_lw{q97twL4Xp+E z9Kv1ISx^H!Paq1y%+K<&RnK;aX%ZEdxPbC6a|0|bUhSC;d!_n%?Ss zP4#D1`UdQoSj^{cQzcadyBMkXy^+A6t&z_F4D-fN3OQ^&Urn@pvn2ZCgx zVi)V&Eq46$A7E~rMO|lIek#PV=?o+~Q2#0cncAm%Fy~rM?Q24^d-4+&7%9;ldqR{a zq9460KWo@%FgX}PIsQm5152I{4^WPhUX!d^_Gog8E#FoJ@@yxAYg(l} z5r=0hAIk)oqA9l6z{ZA&S6tQayK9Xnsv;DtZqH*t$mYo|WA-XL#4?(fE4VSAXE*_b zP0=DN%@!&iT0W*s-sQ#&rXtvsx^skEIb3*X^o7*U%tUKH9*-$R6n$IA%DnM$5&45f zS7r1rbfksn`enGRuh$A@(3Uh0mo&FmRg}8#GCK@qkCMpb?H z&nI~H9zoYFTF^(i%!53cgi&KX)W)A+a(NNqX<^3VR&%Rwe^x_Nz9dG5xZxYc%&P%z zCNuSWOllfjS{ev5=zw;mp83=bc@4Z;L<#aNnP)N*J0XIlTho|2RNC*vyO|FXg!PzF1xvu(2 zc{GatbF9oF$SB?;qj4aiVvEH5MQKNnqLknHtp1gd=&TN!JNL$c)A)yBe^D_uESMnB zVWz_o`h9wNC<#E(ysJzuUuJ8K*}E+49EbzAHyc4LiL`JM=0S}pOwww`?&7z#k-N4L>EIg3bGD|4pCIk{M7RRKt>0j zWQsjyL1@coM7K>-{ZW=l8V*Rnh4Njn?et}l)nkuyWeZnvU&^qAZRG(5hBT7bL+cE4 znE%KAFZ}Ta=|13~S`@M_+h9mB)dM9RVC9Sv(f9{gki79II+_ygCE$h?3@VG<-t#=x4&lH0C1S zf=d##YnBMKtA;@qO22f$Q}F)82N2fj*9VW1IkF)a0@XtrpSeDWZDpGn~ z(m>Din_abQ7V&~pP%damfBJk%3zv%&7sd_!PgCEs*Arsc%)Il z#A11TNm$nct~sK%X}U>j3YCg|TX^iu# z2*=9e-wno-nFb*Cx>;Wd(RE+CSduxO%4mYhPyFC1PpN%PNZB|!Ouq2RbDC)n2BpNR zI9t-5RQZ*AiL1}Yw5PaW076p973T*7g1v4$ZufI>34dfDt%?$$Y>64p4Mez)8RZzv z9C_APh};W6eD`V9z2~fABBh($g6^Sc3Oi7EC+p6GN_h8d0`p6a2s>|5?|4Rus_z9Q zmJYnPuowc<)~E*r^JuT*7a8shF{cC6szk#E@wXu^l_u)GjtV@WBM2!h#7wIMz~=EX zC^B0Q!mX9*#9WV*B#NR-l#`W(e}9GtYLUz9;36U^`_<_&IkXe8sjIA#0?_4_CE+7w zv{GUhhJlfI75?oF=?T7UJC$&jkk-j8l6xW`i9dzRh*mHj4v5v|V&Vfl+(cHIrgtS@?>joj2EMH@buf@Wbl+Bop}79=03EGhGtEt-%^ zk>YTKa@T88ar|h^UCo^g{(h(+?k3F6t;sIK(jgLTO(>xqgBcv(v|3?bB#0#S&|nMH z{Onl;IUL``n~SR=InMY>N^*d8Izd&s_|50(BXS!1PD>*P1Ig+ju-={=fz@x-s`A9z z{ZNmsLP$QV1T^5mm%?}$!W{gN=hGjmIgsf?vP-~e}Kk2+89C+m>Ne^JRXpHUx7For6sK3Qm>`VhK*$HK5VJH z`;ykLulS@n#=giAJV|8n6X<#hw;Qt;g@zbDoCY2GA0lU?e%P(*q)rCqp zX65W*x=ylu(a-zvNK>+#EM;rIq<2QrLS6>tMTYxljZ?00GN zajYb<87r5oNZtp-C@Ci)Gucd-@_YWi9B2a*C?f8RsH-TmLZ-65{C2X9r2}ttXV2#UV zX_aN3%Hn3`Pl;#)_hj;(@VgrMZ!~*zq1+7zls3*$O z?bPKSMCj7T^0DdYTS5~i2NJx>$$U^}>p1@0UYv@4EIR=;&GacQj$7w5mRyn6pA@yW zZ)wt)we`bwK9pDa(+Ws8Ayf$+xBTCW|ZWxV+pWsLn>Dc-$yCsvE;Yg>!O+3 z>DH?rK)GO8g5%%n9f>UE0p1c1Wr7q}4fCwAs4O5NWrCp03pPxUA0FTTO_93o6Pki+TkYBtsSuOi$jEipxuXFxk) z?p5&lY}J$j)N~&WpovGky@-C5MU^Lida0?sQ8i|fhVrfbbgX$z5MbC`7>o6l8^z^* z^0>B_p;o7O1QaDub50{KCCHA9dlrTEKr3d2kBkmrU-(3vxy%SkyMillG%7H!jO(5u zB8118ar&sr;>Fn&Qn0FqO*C`eo437S%=XvxK-{lPD)-sB#~Yok7{x5ZKVoU1!4GZ8 z>>u)UR8Rcv|U9N2(;g7^+OvIAY&6G`bpF z>)F<$U+9%;31o9~L503S^-zobz4|6vsJWJRJUWLNyi^rZskr4A*u)v_a&KW-Tok>D z%H*YpU|6n%j&rG%8duhCH*P$rgc8f8>u{qiAz_&T2_S%XfL2;92jzJdBX5vKIYSzE z;w61f4)9nMu}p?<)wlx8t1U zRGv6fbEA9vg>n+6wyV4K(UO=%2vl4G9Hz;vD4KH--oJM@TXvQ1@KcZ zVzYCEK$t@CE+!MaF_y!YlLo`1yLpxAAC+92X*@gE`5uRUoxK}t5EFHCt$SZ*gwyy& zvu4=2CrJyPX7qG$?$e7^M|x-NZPcM|`n~e?XOH8cWdX$?S?TbWJU;2NWCBPbJ7zXj!wO(}4(rp((%UELf{o>aspwRxqfx|EKvSO# zx1W{GPt|TzEs=uSYljp8~dP&F-GLE z_2Dx1E(dm-r849cGYr#tOQm2Jh|TtSR&U&d&i!c)c2N8EFLL4ZVen*`^&@dx0Zr@H zk5L0@o1k7McWhpOeM>GIto~%$!V^E%8|XHc^r2l|D<3Q@=@N)dg!z$02*aP^8|UqUVxka%YDf>@WIH=6Mkt%N~#6x(=Ip+P7t=uZT=B zP#ktSBx*`*uoR9=?f*Qzt|pXFMRGxrj&X?@*?l)*k&fZOXbh?dwRfJF6y)bY&>oQrTGnKi)zUWJLF`O*+|H;pMDQCjj@CNL&kNLid=}CCw@p&z+ZLg}!uW1Lf+OOh{H1-z; z3@QcVtV~u!7hzOxIS)0o(G|n>BiFyy`2L&E!%BMzS(ZCR^~0Xa3A!`3U9-pwN#c9H zNe>8l-b8W#<2S{!s%6m;D}Rj*-;!Aa%}PUH?3wA6F?VWCnKnx5N0|plyT*4Wz<8EcK7TG0*Nr_*>|Bqqy_K z8+~qc?&@U)S)W(vIZpLB@MGurT`kYg%s#dSboL&I6trAfZxRfBKa%nE8#TRV!7KS9 zz+P?f@!Is7e9k4plcDTZrAXX1+fmb9MRkFtL51_q&nA^)+iUT~ecC`xRij$Ak~@&` zM}(_ITb!fzFNIvyPUQHxTk^WHf+i0N2`P;)LWQ0Uy)BC8Rpy=8`a(jLOzK3bQ0OsUk};tXH_S8e+@R}pF`&Flk>sP)>i|U zIaUQSVR})^o-?Zkn-RRHXi-cCi66a_Tc@qRF%g5FaG5LUmSO^%P|8$%pOla^L55X*xpRHI@Tp_!V zL94cgTIvAjm`VvAgj#MM-?`+v7ZI{jUcUqdi z=&(6|*H=E71bwJi(Tqvw`H4qQ2>{`%OW~#syGlFJTDr+0itZI%k3H#~r$7o!2nHK$ zI%W}R??=QX%9d37w++nIxU?G0CWLWT1w^tndwW#jBmc?}#19d#XvGijB3 zI>v_gy^YhfAn9TRo#`KpK4o11aX37AwR`Wx_>3A#ul>_uV_#z}L2NQIobKjk?}U8^ z$xIDR&}l@8>T?SOM)hK?iT4w_L?>}x6O%C~GcFS=yxO%YRaj4k4@^cTjx z&y^|-YQ;@011M~xDliQi#MZVofLfbmj|FCEs!Rw+Gg|^?%vg&Kk^q~EF>(#%G5tv^ z`D}VB)&)exK)@-JPa*LP_#3@hyIbWPe&b9TYhTFG^<^340lwA_^wNHh zH!MtNO&0^AcMsP+JKZn+z`V?U5DPMZg{<2*<@6}NLGg~{*77C}$GoqcSJC#0G4C&T zOW{8B&RBDh^3vo+Ha9rSkAKdJ08hX_C(x4rv@#AldR3RsAQ|4~;>L(rU|VD{wlcO- zYaFuoPUnhnf#r`{q;<3iG^Z|pWDQNWAFj;MO6bJ6|26>5Z5@f*)FH2dA$`d)idlyr z@4)1CfsQIDUE4QKHeVLry6C#W&cz!&SCzAx&lre|60WCWNIFwd!^|$zc*K0{);!Tt z>iA#MuOps zF1%zI!**)&)p+k?4?j>OYy1{yQcH3_7!LnZdQ3j%o^D^u zztO)-;nmU)-+XT~USD=oNeqPPbOM=ndx`oPpYZTHs9h9(mTY%|MR6E}Zf|8;@SUt-8k@BN;)o_`HsRo*4eu_w4%u&4ZQ z{U(=+U8;qT>3d6Dxw2ol>?hLMAP;C64^ms6mwd!45m_;P%f`+&lOgy_NyNl~t%4>~_iWT@fOl%X zd0v2wu6f}op1Zt@TG8TnwnA4cg0%G35&Y9UhF-@7oN6_f`o?GY_*%t$qwxhC+Pchb z0(oKQUaDvTG0;~+GLgo`OQAv$F&Y z(JY@QPgS8TlKZ|{K}(dIIPmjVqjNP9*X87mbW?ekbnh5P8)VC2cPN5+SBN?RHbe+# zuTLQxRf(w}dXX;rA)keR&whA1Jyn-OeTMLz&>5|EY2us$<44Q|g4kdJO{Ngko`xHt zD2B3Oof^(L_i*(NIitxr4)sPtbzySqB8`eJ%UhhRv_U+!sUmefrASFlOnAkQVDQ{w z%}b>lJ6rkE;1uGR-HnsUbgD2WSZXU90HcUKhoncrJvmH>36MgyBTBjYr$C27jGe1= zTf3SmM1JE`!hl@s`4=hT%Q+X{2M#WP58It715lt*I`cu94M}~A!^?P!DTQ(J*s86xCILPklCMHcWa}AF zC)Nh|#Udz9p5Pgq)6eyhlZp1Bv*lYv9E8Id4)R*pl%WdA_Hz&yF~1RNbI_1y+Ll@9p#b{&z{pRDyPLUNp}`eq*y>%@~xH^INi5SwP^hK-p#6^}>BmR%GiEydD@+LEG- z)k#6}VF%Z9$6{4(^q2rTFhj6)CBOzS?;;rlI=6oRaA|&oF#0L`CD!+Iw$TKeUK_y^ zUFQ$)Vh8YEb{<1XFCbSok|esqixEd;f(p}c4Zyk>jb~`hUCzcA z2nU^9YUd#GY*^EUa?eEBv>PvS??XflZ?7@jLRJsl&ncP$+6MVgH->sxmi)?>TeobR z^9V-#}_+`FyVY}HV z!T+j3-ru3hz=V0xpX5?Xi5sdng9(&>p;wom$r2UfQ?p;b^=MT_z6@xmRynB8-fl^K ztp7W^q%R!7)2L^>fa@iY_Fg-qf%YqPW@9eY=h=s}#Lx{F(IRpjX?Z1t>U%#m5gQFE zjrF3Br$wVYD?EYv_QP#m0!`n)eso*e+$0D+675SR5R!T&Wyt)x2ht(PFSIVFi6_Wb zqETHvW#`5(Uj2*=`}s7Hzw*OpB=&j#v}IY4ljMKLegfk36P2lzJ1se;HjA|bSA=2J zzh7_K1A~9navpQcIS<;azrBbFJ4Q|nM=_a9h`)ETIPnz`^qnSSS}Z%;h{D9 zkQX^C`Wf1TuI5K(b$I1pzpY8%^?c-?-*C&(ZkVH@o4-8S;A$bVoy%d(V5KZ+Wp?162#*oZu}za$tB)qL zsJ=bRPp!S8ZxyF;m5fW-Y$n=$+8aEKaujSg4VVl2^lsmhUIi3Muv}`)V@LC&_!>r` z%*FUK^#z7NoV)64Y*H7+vzu0x!v*+`>HSZRgUX5Jbyl8^YvTDFAayuj40YLZ_v z`YmN<*x1sB)b*5DWWwZ&Xf82PO>r?{oC8b0;)l24h}igkPuIntwhTpdV%u}qc7kn{ zTt%+wIa@VHdR!NXU)u;_1+$zR>r*?9Jgpd!&*}pL&f~O?eFUrCOtD zR)-nK&nVi)SDwXa*SMZ<^)O>pJ{Ln|Ru;Ym`=ZkZciRQ|I}8i8}d= zyxN6Oao?WnYTO9Yq0Xqu4or%Xp0+ORoTz@wS-Ke1AjR3-yx^+uf7dV3FM1m3b+&ZV zA~8H^((=AMF3jVaP@@^Fw)+xE$4i=r+E3F$bX)8N;%}1oj?6?y056wcPr5usU^cEXX0qOcb0|KPaP!Ap8RoC=!FN1NS)|a}BQeBL; z&O7-b3ZR!FoLh)KTlwFirBpEa#qKb52JSe-5Ty=OQS5_}PRc=>apqL!=>k7GOSf2joi(k5#d0 zf%&P;#s9eM-mKL86e{!onOW+~{^Y zj3N^R#h`|%3j$^(j?#J7>0ZXMgvW(?eeqUZ9sn0*XmzQ`_}Lj&75wg_H#_T3u!>O} z4iA()&_;}Sk#W~7N8Q7IAcJbG7*Ol;^Wg?K zfEMo1DEZ#{u4GPF-RBIe+sXTE`lmw)nGRnBDSidUGMi7Jw8se!K4~f&WdvfTFtSVb z#$lE?rF59`TD3i^<6t@T&}UT0&$Cm#aZKhCm(JZukKdc?>MHrXIE?n%NPC!BN{-%r z?pr|-QmFfV^6FJb&qqjH+ROfyBpAZ8 zGIVu#x7*-W;+_Rf?+YnBjx+*3HM9l!{&Wds8{(zR+#t-@CXC~G!v8@95iz@4M%j*bj}*!$}LIBd8k6i?=#daf_FGiVIk zI4UH<5XDGEwF?A(Upoca2fabG&{Mf_HU|}J^ZO;I-=797Uvg~CaPwZAa50HOHBgX=3tVP~(JjfoedtHgf0G_I^|fTMy^FNPTxC}Ow1E;6=&;KPm| z`L>f&o0CQH<(M5Y=ywYcU@LE|z7J=fA3LtiFndqGd;*RNwVBdl0WFGn6^?<8RLrvl zkDBlSj>=a0lC@wRJ3HZT;YjOV3>Hf1*{+V%TEo+}<>6MbB_loaUr4JoEOF!;zQ`Fm zw~J&dt<)JGvGw9`p2-HR#?0NpcxsGcE_&M~4P5^}weXeqHcg_J5t~=-RvcdMice{Y zmn)8p>AdKE7zp{W)V|CmoCT5x*`%(UXYktja>U_o6hQ))h+mfop!kfH7)iQ|iCLu4XRz`f~oi_iUgPUybbNxjZ z)yTGVBcXw>xGXJm?Fq$m6NKW(++D()1R7UKQWg7a;N`5 zy?n;^4+Bo)Yh7CMv#pITR#BfOTbfhC8T2-j=qcjGFm4;mOQ z=KS>ziwjIk{MpR#H^#l@mCYZsVi5q_pb@=qn7mxsP-`}fXR(3wJ(TyzR6S#*Ehof0 z08w+T%6Qmc<9LMinH{BIx$!ZO-kWN{`SczB=zts9id_k`r0}+!r40yfj?}vrL9sUE5*A4wXJmc%A^ros&85F8qp?BT=YBjQy;h;d*tO_5ui6I7FAoj_p0b+c|1xE5b@OmlS>e*(L|_*Loc&8tYMrp;;kz6HUzX_VC@NVE4; zu7dx0CSfR)LKg>Eb3}b-Gw{OezwjuLSVX|t+Ux53e}IphisNuA9!>(0m?;mx<)xsYhP z-J$p9+%q_NWJL&XL|F5rJ|WIeY38LZ}zm}VTo}03OjE9KtrLn zTrw)d^O7nB;zX^od{F_SGWn-RiWY022!nTtu<*%D_zzwMNP`*Co}?j zEle=mfq&yTzaBpO86#l5GFe!psvl(eo#O}#mYk5Kn?IF;ypK(Nn*Tdce?8 zvo)!4y0Arr*4N}sh56BEx9_zRN8!N7DZ_(rIwed~mMY!*$pk5fyHq0r&0^oCT!f2I zpTN#cbOcY9jwceA63YC@AT(f8JuI=}@GCZ|$jZ=N^5J@RJC^}1X>}k1;WAH;%fCrZ ztaPA6iay1Acucg4qaian_3OzwuzsY!1BM8e)pl3RtP@x>Sx%Thi(rkwP)o|uRCf+T z(J=nWa3{u*-vGDOlm0u~C9F7~cv^Fz;o(^Yt~Sc%^$;YgSqDP}MbFqRayqM|7=?~# zi;#>qa)(HR$m=yOF#BHH>y#q`nL)a-kR)Nt8Uz@*KgI6tMrd}r}R?0cDutduB+e+lix83mV$22 zi^xnSGNpF*n$(kIp6^VuGds10UAl+&7th z6j;$;lKhV_{92NCv^ow>>)mU!^b|?_x_ADJy>?OPW#sj2&4JY78%okecnP8e2xJDj zamD9iZlp;np+c_ZHk3>5<&tv0>-*d9 zFW5Od=kxiz-tX7r`FP&B7QvFV8gINAy^>jcug}r0TS;b0vaH!^Yd6v?_-)5;VvN2U z3c@99p*Zs5=CJ=@cBRO&lqC>kw)U-sOM zHfi>AU(>^1*MGNv zJUJ1%0xdH-%i7ODUA-La3>7#^skY!V)Rq1AL0>|8%Tu?*Rd?%!yNR@Yed2*$!^-ho zkw7iCs+s2(k6N4fz-CKR;85OwfM>1pf<6nM?&stP#3huj4Stb{VS9IutgA%3cN-pc z@+-Z~-rz;nG_LbB^bizub($Fh!dA&nspV#%@immk@?a?U5-RkpO__fVpVN-#!2FgBJ zQg39KaWd{P;+=f)b#UH`&+Bfc+uup|&nCg|=Cq1<`z0Rl|0-2&ng|)->9g@|k+}+w zRJOK|=WKvK6SEM~+t4+fao?p~$kvL95jB}IZp!GW}tBG3#?CV_`nLdO<^|) zML&e=<~zT)tOhYsM~uZr_cO*uta%SVY3MzkS>7D|D%q8KN_@1~e6GT&nto`TcmK(A zloU@_&3}M9&gQ>cq|`X)1+oyiDXWd=C3JH4FdU-dHuQOs-BB4c`b#dD6x~7aGB|64=Kh?9^GnwN1kboiU-vuGlN}El`f=8-pP%k$nV-#E z#m;(yKvdX1PHhr9hLluXnp2;T#!(mqMSDNJ&-gk#oqk|$wBevK@pXsd`1;1A=a(Z! z*&6_(%NY*A)SM z4Wg3)LU8Mrxp;5># zEej(e6@+kKtR7C5xwK*X^r%{Oi}OT3&IFJ~!IYrBg~*N*U94QR!{Z*^J$qOz7DMp9 zSLp_vSqS=DMbwwpd)Km1jBbGOr+|)@d;MT6M-xj{&$3!mAG$!H%B+1t)qEW7jDr@h zaQDX<+x4ZF*utxjuh+$|jMmWj7^HF69)I+TBhy*-&Kt3q z-*&FG^0Bckr6iT*T_j-{%YCm>J48$CruX8nv_W-Ei}Cp>95Q zVqcpe6ilx`{;Q!@q^lqKK~VBTAQ6_o#XhxY%WRNMb$n^*S;5k>#h(_2nyEszXSDg3 z;+)0Mdi?Mx@!g_<@Xm1(k`Z}jRb0Ke{xElkTY~9ldK1}qU z9@bn}KqG-Jcv~mlFlN#25mV>!ZjQIB89>0E2@yhznlV|xQLfxsUOaxG*fYtbqR9rB z89s7nv;y)Mv$=QdZyM)iEZ#8LVE93Y&zF>2xmsZx1=v=U2;bFSIpAVS1IfyOesmCx z4Pg~JmUOZ*^WK!i23o6liT5DPT@F+>$0F%6&F6{{7qlw0$F*0WZ@Ig~Pk@PB=;Cgh6gQ;+wfmZUzw0k}WO|VC z*fX-yh)5Zs9G@$?kFAfn-=xyn{;I%O0+SuflEZ@(2y zZP_9B-^muHcsNtiU;qH?$jG0N_W?5&VdcNlu=T!$QLt>5NmZ4ge_Wg6K%Wf`-yOK> zyi8?rYkjz!zV+6cw# zZ(y-SWpo6Bo0)Cw`bCh9-mN;$nZj~&V-#hdE=BI#cNEABUE-iNw!pY3iN)uBahGUZ z(hkS45aU&)yzINcvU_(J^hMHT)^rxjf!HYSu1diA@medh>W%X9DpES&@3AX44N|ic<3JslXa@zO^cow;h+HjcK=M}+Q z9bpcPVUV3&>SOt&eymRADqR`lD0_s0Xy+xZsxyhVx^6u^XBBap z#KOvqRe#4=KlyxnFa$&3AzKLguUA#-K8)0#V*>J1gPcl^|B7sj+Wd2%f35~U*4Z-q zCEdKj{`MM0TS`8u?9r!FOFzRZ39USol;{YNS#;c_l(PQ#&1YG_IXf6YTOVS+;@G~p zMGBbFy_oNj{`Tzb$wh}*zZGU6%aJ@1pN}maJ4H9f3pYHwq$`*!JLD)J(fpmG{w;IT z#d&C@bH?R)!KMJJ3UF-ul8wdNbd1E2?q8Abf~MYFnb%{SO8Obt{NsfC`h`Q zzSc(N{|&g*|6w*6tHF&%e{2_p7Z!9&a@yXo4j(tM(On;EeOC)0 z)#n?-)pvTIeq_4+!k(`dTQ$F-J~JEN)}Fp~^my`3Mpw>is>E}WX<(C46w58aMjDd! zqnp#N3z>JHVZw2=yEyfUhvQkuzFAp?lCU95r}GT+UNwr)R=)V_;3T(xugguYbw8xJ zJwEwmJ1aC*gvK@THn+GuUlEp$hr7Bh!He#x*N)^xe&il}Dy~i3_OpC^p>uXA*>bmc zJMctnS+Kz|Q=;=~y>X3E^xS&RGdI(?=%p0>f`;O=a%$ITCWM(u(Q%xBRLD?Y3t+T( zF@G^)7aVu!l^oh{vvbFxe@nsR&uKjUR~gdQX1-hO=DGyp(@ct>q#^ExM$An#9kui9 z_JNPmL~<@bsm=deO)r)9wt@WNbCL3*0|L<_Ac7YBdties1|ywR)@t!{}aul^Xtp7E%s7pq#l$b62?lq5KX4btaZ?@IFzFN3+-95|y z&piYnHO!pylAPp_-Tmx$#|g)s?%A!@O8YNawx^#~F8%iRG8T@-jI#8Me!efJS8jo3 zf(50T?2EpRy07pp3J{9VbfJa?U;%ux@10Fc9Op7WpP9c}m2*E-6Jgc3As;zo6I9__ z;*!}f5FM_O{sly)+vGv$0;Ke~Q?p|6e=wsjDP1*R)dx#vckGrPTv<3CdQx@d)^5oG zGG5;+)eO7tA-9sh6kMJ?Hln^{W5HjJce!95&1&04P0bF9J?;#)P2Or4RB2rGvMW%U z8A1(b+3{+^D#3#Dwyv@4P9`IzFi9_d2&6=?L5yfZ!-dJfs6o+$fn~>skAGjCWAysB zm^-+2JXbBy?ems>?aLztDJy!pvwFHOs7&Z;eT<#@y)r!n!b+$cgzq(HG%|W(8ap07 z?zw)^d$Hi(_CD}c@LUnoqmQ$^%c9_|BZnoqif9wR&l<7M1n)ShE;z#gSWaqd*{Cj2 z)D|-q7RLY0{zZ4qTb#n~kJeT&rZU~s@Sm#A{RxIRp3wwxBsHo+kRKHP;~b#?>(XwCoX2@s@)1x6BaBEj@BY@=r#(e}<>|8HBdU{wVUR zBBMAeXbGJ$6vXLOWI{?r-n4QoAQsDVq#eGlilAD-GyrAS#im3;$Fzt;iggMaUL{~t zVki2!RWElPCsjVB`cMoN_iZH1NIOnxGYOr(zW=-7S4%w2<+P_u*F8{AvRU=#dqan} zC{k8Ir!x2B|5Cmi?L6GGJ-PWsC!NK$wm>BNK+#c0uga~Hiqd;35`~0t^@V+ z_Ib+>57a1(E!zDoXeF^HV5e`QyK;vPONrpaein!mMS=VaC+DWU7QMu~m?j-ls3zjpGo= z?^77gxbhZgZ(k?>g}#3RfK2Kkr9dnuz>9e@yqcAzX(`jAMKlhZSMh^ej`^XJK)oXf@r5n)R5c6X$-4t?gMjgS4ug-S(N55b?)i!7{v zrMW}GEY@o3_RK)zmADT@Xa9YBX#Y4feqx}@|G~RIk1bSxmBnOg|6G+AyCZivIkl5A zT8Mqu^;DNfw!!aR++sHJh+!Z5D$?euP|stjo{OdJOu~9F5aLDBq?pr%gYSIgTYd1S%pVu6QJW1j?>d+U%JyDAXr@e5%uP zn^pKdOPhJ$k^b+1Rx9dOs+GfI>XqA+*OxX%$E}9u=6#$=XuW+=^YgedxTeGLU!KbGKppdm%>3@srg+P@pLbpUTozAQhCPBN z+D1hS1aB|TOhM)4W}OsopoCxO7#9Qb9=jggiUd5{@^7#oY`Gp>>>}RVg#U7F_&ZhL zA@6<`mT9GAk?XJ>EHwMJVbs89h1wSa|6YF&%~VQy^#04Is!&o`+I=7R_j@T`!w(rG=B6X# zgNg;ebye<5V?ar!eL;R6Mm4B{*=;XOY3b#r8oxVn7ZDfTI{yI#&t7IcK4uxLn~UuH zVc+X)W0lV>ko%-Vcs|sJX4;hbx#}u7vLf*SGofDSw=i~_enq`%MT{u~cq2Wy=|8}F z%&f9^S>Qi)!r{T0x!S9Ta`)xMqbGLGDC_cTK83w6+%fsL`3sWD=$*u%Ul0W#lV2pt zMzq85Q{#Xq=$JY3$F`7+=MjgZuVr4$z0S<}o|80fG_o?+*q`fIcIp0W`ETHYCJ{kw zWcZ9*a=-dRG5#m=-&va-xOdc~&5Kgci9WzbUnefwkN7yx)Z0TFezu6nsvdgV{NPDg z;q(_K@rSA2dD|W2v*yjG#RpqFr6+&- z#;LG?w%)YOD_nO9%((r-3!yvK0NUS;r7dtVJoTq1I+`6@t={XYL3q!We%Qsc2VA|l zbC#cObLQpQ_^X+#*vV2`C9X*PwR>}SyOr~I8`M>~3F*oGho~baVR%j-KbYe)E;_n7 zwzh=?y;;ETSJH{ zvf?$r%*o8OQ)BX3curyY8^1`+8%x(aWXq$W?^`?{w*1-{nlv7s+R4^VcxctgtU{T;6US#%3Xnb%6QD?M6~&a z#-~^lYRN{qz8#m-b+_*E=7dx-csG_{DneW&g`U8$<6nno3(az%A0I84<-?Z z`rOG`4FjK7YJLkh5BvZgrj66HzAytX#g+iZ5=lbhAVwZ?m`Jsc`ksy2VccQP(=-2^ zy!lvR|*r0UEtLm$8dc1DvAS9|7DEHfAz z#T_t_Mc!!j`PJ1jrq~G@J(M?u+w@awNQ9GxCI(5zUip$DfWVUb8>wX$`i!-|GXW*^*QRPMJ3=L$ZRY}- z2o+A}cDM_}neUVqhMy|NGorQ-RA^^%eA}l2TMT*GrB9Hk2SKB z2O3tC<>yJUuo&cTz4Evc-ETg0TPVLVu!bYn%Y^ap%BJGeRnScc=}pLCY2JnZ2*1Rt z(3;)?M~_X~`RTt4{t}v?Y@)tnNGk=Kd&--`+bVcBL)y8>RiJpM5`oO;I-WA-YmH36 zER%P3Amgps2avm<{{X+whZAd_Hh|-xhH7VaivGULdL^pF>_nkT<-RqY=xKF`p7wkJ zmAcn4ylMpy!A*weOf8o9m}?}$%JF6Y*7lBFK9|s}?USjK-nq<|2Koh#d+KN=+JV-~ z4VVz76>(FFXz9M|Wz=I7-NjE{)43P>mFS zasiKanr;qJgKH`?Dar^ZZ^f|upgqVXH(oGR>q?AiadNp}zbvm32P*g6c(DX_i3A*T z;3^)$C0n0V{3^hH4f~{#tPvn9Gs{L@Tfii_1mDMJf9-Ey zD87oH9(b!X;dz+Scp~^FwlD^jG((kPRBEmHK8%OH%^h$q<3PzTP2kW+;+f!JV zmILPGA8*-5Y|+9nMqR*@ygZupDXh~k{N90Z+EY`55>`3t;xBcbjwh{P@pzNO!r%N; zSJnuJAfujFI)$h0Y_{x9loz{yRDD?7)}3~y4=rc3ZG`Mi>@R2iM!$I#PPhI1PbMnzZmrdA}4dq zm)G`yOG?_kArM68bKV_6dh&LYqgH|jYuZbhhQCmJdvCh`QX-;{8J23KOG9LB_j^J- zLbT{GGZ*4^W?f=&JdD0iixc|RDI4J$2wmZ8=ER7GfOFq%pD;Vw^__VGbt{qji0-X* znR6Lff1wGxVWWUZ12^bAI@0=^AbQ&vmXJWj_~p6o7fkvL_NW%`eq$~AnlJf)i@F5I z0pRZFbZ|b^m_ic|jz^WicgVn4s=PQF(^@PfqTk>xcxRu94@5|YkCZ{nozZlQ`DEa!+SOys%(SI7}~-0 zh!+19O)Al3uUR*g&>y9Be%7LN{`n0thV;vgWgpd7#y>K(2TJPg)uXxCWNW`S@|*eO z-yB1UiMC+Q)U(F8SoIM=ZkW6!nctxgQaK`ouBY>{N&gOuR#mB9it(`aHk+55*?~3x54pVBP zX~Tp?ZjV0==T@{X(y;w4`OL5XI-6Vj7ChqNfa*mfW?yGol-CM&L8C2T)%s8=? z7FT#LZLz`3uG)mS64IaxHpH%QM24pW00sX6qGVl~#U7P8_CDy1E8&If$fnrl!HZ-|NiOM&uy5TO~&t7wkUdAh4aEi@fFdBo!xv`$XDNIH1ynQIYb3H;DWaLN2#ZEYT<{k^h%_<7>RMq_LuR zxnbyoi}$|QZ-9$Ocx@sUN&cvQYG{A zH9YVTW$g^jcYmf?FS?D;TmEDUQ1 z#wCgI+(O~9@drCqwLa_*7k|E#kBP2K{zNH* zm{-#M%)4HYT30B7gPkO(-`mhHXpfXjJ)fpCqLYox^tMHZ?|+I4&X&Dja2BI?=@mQ; zqQFU%Kkq8+5V9*Zaw)C!qk?HFQOMpEqXl6&z@k8AlWK1XwW;D=W#&h;jk{T=5SBP? z%F9tL`vo%F+-}nh6(r~wiDiZK-R~EY@3r~|0vx1X^|OI$D|(YHW%XI;qv5R*SP8Lw zS5=iJhm3dI78y)&+#p#iPaq2y5kMpeG*z9^>SXIZB)2N~2@(Z^$J{8fwfd2hukufE z4d*GI=geM%U`TqO9>a{eU#dbjMRAx`WnC@kc{cR0k$KajtmhOIu41hlh+|;MsVw z2APr@ zao>cMvNx{=d}MbngxcY9D~{a@>Bk7sB{$Mr^s3n@C+GWGV&<&|WCDvi<8Bh4*cv!q zP_FtbXEs~;(@MA8dfb-wJtsP!0@FyC$ES2rrLFt`C}m~G^=?n31x#EsrasLrK=*(Ov(`-#9z_+^h<5>&j^$% zX?0BlS(&1O^8Q?diEj1pCLG;Gx&JbzP6PQo?5EH9 z;`qwJtS>7UgaxXb#E4!!&kf~Evl^doUKtO!Jkc&+)9Bk#Zkzh~*x^MHWgNl1hRd5#*^wFB4v;`8{|71E@~scDW0&j_n@bnM_8)P?(~DV(gQGrY_Sob;L&j zzCwAWL{i#})> z;Wbib{%eU6skN9OfV|NC*4l?_zGFTOFI(ulMNDIQ_AtaT$F`H!V6S4PXfQ+kO%sp=n9lID?@B6KV zZInSt;g#l?yFhe0fobN0U$vpH_D#RuyVo*7ZsHz|=xH?eTbZyO-TqGLpe>gJh`zT% z@cvRs=+CsVk-}mE7}QCHa2P&#RJ~t_u3PQrS4TCWBP;S5^$L5$Qh?NSUt%8b4}`F3 z3#x7dTcZUg=&rV3iT)1&tXThAfB#(=P)~jc4uw^CtfR!cugp<3Xsy3e5&Tt1;Dlhs zF_*8}J6ny4tY~9!5M(kAf>wo0+?&&ld|DM=B1AO#S6fayo1XH~2^XmX|)fgyy6 znW_Et>O0<~F&7BTmsZALmFsOC*cypRMKEKd;)R)Ip_Q(kI8hL z2}lo?&oWl@?}7o|%Dy;QwST-dbq_zwZmW*bVo^v~3-J|UX6mlh4X-EDh44WxCRvGM()Qf}%!hFvWSf>WYtV zi{Gi#vHzC&{S;Cnd$=P3D?Y_k^vy{~I>L$MLKSYE#d<%7dR2(eBC_`t0quqHJ5M(WkyH))Mo5WymsV@rmN7luv183Jd=+6Z!0 zQ5&(EFi(hBL8tMR-hphrA58`{<+g(r8eI?d5UT0P7@au9Ws211_&V~c_4=%~xkF!C zA;HSSIWn=rI3Xlxe~$w67Y^pa7Ov>Lyn=Y5xHML`SMe<6rMx7Lao8g$S2pdS$AXI5 znB|`{swlr%)*y)at7vzs-lWd8fltg@yjs14i+2SKo|#4_{lx-TmyK0a<2#`>kT>&B)v z`rj8jVC)qw=Bq(wy0^QF0k|ct=WK3rWv~#VO8Q~>;JP$tg?s8K0VQwD%ld%L##SP8 z&ocvj-Af*zkQ3Ov+LC+fLqf%BRl+Te=mOtWqnke8d1-MaI-grfJ`yCs+uE1R(4g>& z7Boa@qtM*<$mzJ-`ktAPqO>apS-!3TT>p1*Yc@=Wh8RRHANNvGC}&!$ zRObgSG3Fau7{xiK8}(+QEC@;mRDb6iu2xK#-p?plN}?V=!9~lTJSyN|SttyEkW<$U z;X$rG6XW1S{|n+d)w~4c2;wb)JwbHTu;TB9M}&Dm!u3Eu6{iLVQ9Wz9YdsRCy}J~G z7{`M07lwoJIvw9~mvXd;5LwB>m=j^hMg~*~h>(gsYW7A2-qvWMp=iFWe?eS+V_Ai4 z^rNzZ=@%=1iOg2L%H!?3R?~uS zf2hYyG1o9ubmT5z#FO!CAN4hUEF4S+gMy55P@uh%y17T+-WQbf@^*y3F zlc5;%<^|zpg-uXj#S+IriC}T+j^g;cLZ0u}WdNc+u2Ytrg^X^yDJryOGcUz>V9O7~ zw3O5QtCp*i{*GnB@vwfu$ba?%%f(V0{NDR=;qO`*R-Ix_mG>W(WmIT0XeC1y{+}+u z<3W=}x)0wxF%U|>nms_!Kx%)W{I!*OfD-(ef+I^5r?@w;?w11C4-Le@@TP*x5(!n2jbUJmZ}YOBUF(>b!PH}gRRd7 zfP!8MiAn?t z{OdSktR!JWC-IlXIN?&BL#nZRlSvY{oa$SDpYW+sI|#xSA4D0IQp zC;aBllzt9$z==LJvrHPEz<(@eLZxEuExFr%!l zRh->(L}RNn;uInQsKU5a6YGQB`Nh&WXHvy%EH~&1-SJjYcA8aksHPch%KKr|e}I{y zD5)e!*b@Y{(zP`y##Zl5DcB*y(8Ya11oy<9#Egc)^nUWzA!{6XSqaGznr_%7!7nfa$P@s|ci-VDTRUqO;4g zKl}s#k1*^BsgnmZ=h1)lZjvz@M+2kv)aUH9AN@=HYy^Or97B8wT=q6{z5gSR@|sJi zO2B3*Yg!!?f!g0+5w{19pZW?5ngi%CX*g^)1w?B&)?x;(sxYV9&2pw%t^0c6$F!1=o3`jzDky!=;Q zpSWk;bl3AS{lkX1(?OJA)r<UO8F;E z+50>IUCr1z{#D96-)|0(!aAXeIvN(LFY>cjfAvP z`uR(jQRwsi5ukuJ8Bs95^s?Iga)iK&LZT31_t>T8VKy0PCI+U7g>Iirq2%ea1heyG zDxp(eEHwCS6cQG;qiVK036NL~#(#tmMMKZEa}bvlv^O+xqC-=T7uNhv;ky_Gi`{)# zNYFa6uzMn?{v^eP(PVG(l7M;v^9J1I<;-Fs>s4eyrRhl0pL0Y(_)scbIXrqMJ4ta} zQ=jxjvk>EMf4d>XDDO53CEa3LwZ6U}iw6RCl*ZCUEeqcplW9+4iF-3z8;wkOq>Rai zvMQJ94HJ51$hWav(?SiVyTH$p#k40OvSAQstLvKS^jClviXtU|I3tuUU67&fu`82L ze4TmRbRPHfzlHaN%W1%YDdNqfIho>1h4?E}OUesH^zqw1wYDbfDfPy}Fg-fc#HDh` zx?T3zB^tasky%CUp$zMaI#Nqb*1cAh`#Gi+iwP#@nekIX)T`1cq&k|saw7lVK5FgT zZL9IerZweB{O~H9#188`qMv0tqYv~+2`ub$$vqGR%E^{YiBD)c?0u%ISBn&!csh zN;nqem9Xx6voxpG8}!8xp^B$-polPiQvp`Fe8Eokk~sJXCVQqr`Q=!fa&r|tNhKGWsl zt66h@jDD^769Mww5*7MUt0HuL1mO2{O8j*^=SO8cw+18<-fXcUd%%^QozPgowKnGX zkjFx#Yz?FC@%2R%nmqMjo9gH&i*Jo%C`j!tW2$6cDs*A|30-5F=%NQRW0)`$e0dx8 zEs$dB=C&gRVFHwT5cKq5`zyJ__Cm*QBVrh1%Q6cXZ0bxiA*sujO=N@P9b_Y2BQUYZ zkKOdwz4ANX^)}5mgdK(N?f%oC4lKWYKNWBbr`0!xVe`#Dhu5F1@7-D=(4e%+DQt4g zB`@1oJ2IrQ^~T)Lc^WytQx~hUxXcXZxQaonW!vX6U(wDEFKHN2$Hy++#1uU!n%mSf z*Eru^gDax0aK*h?pFu?iSZCi99e$QZL+4XQHW&k-^{bz`4sU;m&*ak}lwxyFyZQ;yuC=NpkJP71V?L$MS(uB8T z%PG8R+g$gXN$`%PCZK4#_~#CtVbh@}gAcXEWK{F@&ac?>aQ!X>2qoQVPOcG z_pHY{_!2V}=oR88faL_YloWq{u76aq*QZZWB1;+x3KPh{aSd-n@Bq!?hKB>qCFk+w zpK6a<9<|len|J&Y&5^c7*i`PK5?HDGC~|4W>8ig(`xgQH>aQ0gnYPb+02!0I7*zqA zmo-zRV zS~RvQ4`#IcVdV{#%2+q`(!@#{$fH#;9X7zh)9q^eq%JJvkM5sv#rwLLJan1WVQ&hf z`W~q<2cO=+B!}Wf{aPTnrPh*!EvXO=k$H@KR-kcQgti7;LE z@Um@Ms+V?Lkxmeg5Q)V9xiTDjsmK{r;lREP=+XcwOv8aJRO1eQBv z*L)p0%g0iSMqpfA&t2c9&q0wQcqr_z`Z!7-EBJpiZ?6|ixjSiyx;ZkEEs)_Rzzt<% zoq47bAYmK)l`<+XXL>E)NjjwpBheN4$?McJg30w(+!bC~YUrSF%npN5XCRe!yQ{F# zUqe%-e5X!*)#+(oB`?~(zcQ>X6{g+~r?&YmUO-2roh{Q|bMLCAMNl{9CiNubQWO{y zSe%RsJYM^11FzSnFzIQ$5l~geRn7CjVPF&C4_bicTGU8*d43GaRdWb062>DYtPu%z zW8OaZeb$1~z=F0qjXGZPuz}O)|G%zLno#9lyY_YsKt~=a&ITK!66#fV<+S#v!m7gx zb`_EIc-dC4zlF7F**MienT|!1&G>^-tv56m-q68d{{enLN&f+wtir!07hu9$ajeNI zDdGa$_%Z<*wVQbv5Alv>mz1NYy-^}WGf~fWLsc2dL#^*cn1(+t<*hG9cgHA# zsuAckHL3dcT*@_?rNIzJW=mOsGmHPSOFwyjuvrmdQ>8J(u~H`RkXd~xVCHP*kN3UJTw)zI z2V{KnsTqpfcV_6=ZGuk9jm?JckMzJBM8RxO<8X#gJAn2MvY4SqdOBtQCdq4>a7C~Ya#Ocz1b9d?h!f}SorMT+E`QN_#C?2R75TUFv z<(X&C*M;Qd)WnyJp< z3r|5?0{FwV&y!*@2tS#_t`%jP(=hUVnKJOZL?<0dTsLi;c1RZ;N{2xX*3ZNXvVI$; zL#F(MH9@-qg2f5W8kWxr-Iq_2j9CS}5%H~I=A$)%x_+8cbGdUpGIOzypLuwrvkezVuFLfD`!Gxq^> zvonrIMz0*mnMMZ>v*zi15mv$;8g~mTCkx@m;<-Y6tGo>&Sw#!@Q@^$fMqMH@#8s-J z8X0?kZI28AG^@ormf&*y|K?!1T@n(Qe$lcUy1Yb1^E@txMFFH9T^=bXB(c^Hr$vWn zC3+SRdm!Au-3*oe$&AA&buCa@<%U~o%?bNkJthDKpT>LCBQ#ZS)EmmV-EOsf!J{<8{{YJ4lmZCcpg z@LzUa_d;|^vCk1WJCdptV%X<>{Ge*>j+CK=a6(#}&3m?Vx_V4DkyZjv>VO&vY(Q=eu5WNa3q;9^J#!Eg!(?q}W}qsqy23s%)@SH|&kepJMQI3Qz-* z=vK~nfN7}u$JNY8|J9jg;I%%iFt&Vy25XF?<2Z|MT?UzWzpgD0=r)1VMft42{khTU zfPi@mT6)o*=aErnuCu$c)=`X~vt2wc88mRD3zkU2V}OO95_>&!&JXm=qYQ3nfwz3D z=*kOJd3A#R?v7K-4zoo0MMu%;2&H14b+pdG#*PFe){bA;ra01fNztN9qh~aLSu@4h zNL6P1(>h98+^&NGcbsbuhZF#Ed(7;zefaPec1wn#Hn4wGFe(~rE27b;tCW0F);Mi0 zrxUbuL($i+tIyQt&ry-DER)f%*lLrO>cr{C4p9S!^%Y|&sOE&(^|Sg~-!TD%1{-5i z){Fr?cgb6hg>Dl1OJWis`0qsB~S;7VN?H9d@IBIu1F??xass71V~)J z0sM8ZU3{@47D?1a@B@2PA;<2F4DnpmkWsT0y$x#Lk+da*8%_vH_#XhKKv}=~ZC{>* zNJhy03P2U{u9@l?1eij{BR~l~N0xyIxLycQ1P-+Pz7_fDLx7H8ya40y*(7LYqR5Fs ztrfozeIR^x{lh_>5>luD*VDv;M*3)wl%gn_YzZQy3evRr=}f4I3A&dco+yv`{{TNF zBmfUnQB$^%PEBP%BZ*3?spazM4*O`zR7fhkM^nnFs37SGMc0aHl&~B)#+`g+;yN5pa&oc@%*E2-LKAW>+D@qMAbpvk_GLe;>%0+lvJ&T+<-fP z4&sKI>Cy}eu7UpD6`~PXY#?rg0qvv`3VeP(9vwB?6R~mXfc#XncDV$VDMczfIbEtx zXBU9l4W6Jp$xZFa3EDglU`s0LVU^a*JKE7i_e%Ol(JVq>c2X8sn)T7^x36~7`!nFG(~s(?sKVu*?!L2C5!1QLAdwy>?ymgKrt z6rvKI8}Xs&N%A93B=(|0895X+>NX&n{{2uDG(VLEM|99obrtdJqhN*0B-19Nm3W{l zii)ZjATkOgI!1^JeA`>M;&!U0-{SLjW^X8Bt;(`2Nje5kwWQt9tKG z4YY%LD6Ut5B_yB6Hv%PmP%>5e`myK zKZ3*rV4=ip2|hIFbVPwl%hcPLRS!aX=radLaxfL+`+j3g5Gcy(dF|vhO>UHKMFXFb zfUflM{B#>KCWu0a9z`_YuU%mx2L+jXmxtx9n%8WjQnr4Q}vu328I-Ra8Ze|zPj6C|Ntk-AW6 z=_(+f-LFfhvR!Mh|JLc{UD)4RD9?)`Pw0Z`sZ09WEEcMrJKlq>D1_Lm9_yi zNC{WwHLsrAZ>wmU5xsS2!`RPtISDCzg(32QR7+_hgs-mSr3XrDssYqBPFxjrs~-Q>ARdQfj7}DXAsIB`s7TG~zgcw*FrVYpOT8;+G4lNau@Af|`&A5lT|O z(gv#oLhGASvI<2i2uKHT2Oa6LKOZf%&(fL6JJzA1kwTKHg>*Xs=Uw&D84OoB1TPeV3Pl1%4<9=3O%MU5 z2s$%$0RX9dt=$nJ#*PUkZVx#bxeBy(%^eKRserWK|$g z9~AFRA&MZPAo3LldK!6cw&!hVhfHXM^6C^qb}3Q)l+iqpUQt&O{jX53%gVot@c$Y4}~<&l%OeCr>l_MgrD7@01f z^ZDv*1zj4NB)M)>Ql#?nG&BdxQzsP6j-MY*KmaGt{@pM@qNzzjQVnW)k+`X+T>`)& z0VyrOsZ~Mfq1Q_qxkH|** z{PoU2cV6dDWy%iy#!F!Y} z*XLXp*1D2RfmI8tR&Ok_D@8X@#b|<*uc7g%{fAf3w|ec-BO|L7vEOJUtSu=|q$xxw zbOaIm2D@Nca_h%6l=DmXi(cXsv@W%EMEXevn|0rPSQovQ9EMk9>4KoYWezNYrTd=c zNb{gR9}%j@VwCLc6wF4~&9x~(Wx5U^>;d`fq5*Ph$T4hG^k&KpHwYA>j^u)Bd^(P_ z*H)NfxOF7zQ;0}BPxgO?MR{+xT59%O&i784DFUh>tcn#VZ&T+@wOA0XC{_( zl)cl@Rcrtyq|%-rAx(5fr-GHc(%~snC;>ZED5UItU2DGDp%i5|X(fPHB>HNa^{qho z(@Y)0S|t*%QqT`t{{Y6d(*o29NTa2IAxFS%zn-a3lLVq2Nh(hN0K+?i4LSqY$F8d# zO{oY+3*6M2S8tKi35Ti-gOJ+4fa~K;5jVOljHT{HO?DOjoiUwC03?B5L$KTuIvpfr zY*Q9Wih)kQ9Z)(_kZo$`MG7HD@UM`e>8VCUN}`G6D1fNAwIM+N01ZQpb_Z?9^QCl2 zb5vP_j8T-L0ifoS)DFM9OiBPC<`Pts)|;P>h%8xVdZL#SlSK-V(LP_dNg~LIx?B4s zZfbvK+gD5t5~HuB2aiv~!&M{%p%a&@eYU9|yHm^^7NQWoRNG~4f2%}E*2>G(J|HNP zIGy&ci}$RIRFJTML0v1y;a<8p(FNtynhz7O{+$_AtrUSsIw!~qy>}WLU!>wW+JFF(FiI~1Z_h?50;dYLxdOvQs~eIfr~tBjxeerPD30zyHwb-K?Y_)QXN3HK8@H?$_r`SJyhHe-%l&xS!@lBp=Me z)bk({M0V*a5Q~N9>rJFy%2kGfUa3iOwA3i5)D;f^cCC7yS^nFh0fRU$( zC6dX5r%k0zr`td^sN9l3A3q&hC8!jnT)9iSqO#=$1vrFID!(02$=#AfGbB)zcoL9J z5}yS4P?M#L@J}KXgJhKwqB$dV5wPMnr8RiSo342ciNk3nDpv{v>PW43I-s+%oQ+vJ z98U!W_!3d@{{XjFa9Dz;WN=E5q7_o3bdo|w^xmeLaX_YSm+%x7G~E6g zqwEP1B%16hkSR`|9Vp56H1htf(H7` z)eAaI*NNN%Ur9cFH6qNIA|*iVssaTHMJrD|XviC~Bp?b+MLLbT6HrFlA)V16qa_JR zQmaKM*UW1Ofm8{4BLq}}unKy4SLdQb-pD@0U4)5`&;q%tJLD(yE|Et!%+rBcZgf(tW-KL?K7= z9}+yl^3~(HaB31p)aeOv(NuyQCzFJV9lCMyuBZXQOpzPeN=FWb*HsJ!RAd~m zqLLseHl9^+V1*s_uTA_0tCz)dyFSG23*b@2tJ)y)S5vmbZR@_R63S8!d#98o26{=D}JTY13)poVttyatJu6q|dJ<=;v?Kc>U z4zVGJ(i~~#);%gpl0gJ*L#Q*~1jGvNGNJFyVVd;B4Ax0R{% zpanS{NpVT)kfidZMz1X?K(vM5k#B;WquayPWid7z3Soz4GKXhWLqTyNPZWxuY!g*& zzTO&?2mi4C@t@>19700HVGnrsJ-nljB~l8aELZryE7#BSo{+ACK1 zJQE&qeYCK$;($O)rCd)Vu%X{n%FYlEu@T$FqBO|X*;i?lt}V8r z6r;y_0n=I$ak&!rQ23{CF%0Ru+t`KrJ^id^^D`d3zZ;Q57bpq{lN^!&B?=%_H3al0 zR@L?vH%cH#dnIpbgIebg`K=V%u<3F=ax;yXo6p%GTxO zjDjta3Cb@Rg{j-)@!%Vk!pkjiWqk;B+Ps456cNYNNA^aosRI(n4@7`-S4HP|GBOsi zM>8uDGMC&_QSqa3j4lgXXbW0X6WsSnN>m9PY6T9YVjD3OSORRN=Upwfzoa)SoM=C( zOGGPTB|O_-Q6bPuBeTqoZYU&>l+>CUX;{>Xgx8|4UOSQ7+;Nvzkmp$KiL_jQNK=#U zu_Gj0IH7+=ORl5`xUDMo&#HtPP>ozbwUV=trDSBd7 zAEry?OCH&Ons^0JtB~Vb>2jNnDYq!=ZhM4ZFSndl$(Gq}`BpkPWH{U@@uXZ}(1f3; ziqh2UbTl5cjq2vOJ34isP63rtY;fXvOW5F4tE@Dwy!uTkenv0--29 zPPUusNJJ%*0P2H>ch|QWd=B3wIYqM_$~%)_x8zv&Z?5+UY+scU;~g@a1_*ghDM1R~ zfKb@bnrWmY)}Y4)j4D;L8}1eZm`=RfF)Zf8lwGmMJ*wH_Nn04?dR{?IBIKA=D{JQvD!} ztG2dT7`O#s9IC!&-+tcWFG{k<$t;;3aUNy568nD+^=oGB%Hu9HR4B75OI&z~NOFoi zmM9Pur6nXsPDDA`u`q*{Q#M}q_HQJ(UM)E9c5w^k#~y^`#`_Kp>I?2ehRLI{Uk$vk zZMNy_QnpX_siJh|3lM6NsOq0T?nAUDE+u)eX4uwWjbEjOAR(TrJ$vyD+?eZs?rT2 zl4LROFxM6f&i?>}+wTWTP^W*eKehdu={|(>GZ*HIuvO&+doSS6)k&C2vBDFO`k|Px*Wc#X5sVJupL3CPPEhMZqQWQl92BM^COqOboC9<-RvVFn! zM^*$wH_txV2ulTqU&E=tPP#Ru3)tDq~Bf7=Pt$`Xq>zi+V|rn{Cf z$$s^|-0YTXUE0&!3w~~!#$9Q{7=>Vv+?Ufj?%)kNQl+A-A+o27i6tsRPYy?IH|69( zaLgX4h>}3sSxQFxtnF0J<7Zf0Ji8uUleT!|oAz&&uI|uF3yANxC799Bh5N~fky%cM z0BK4?d{m;YB6<>t6fSV>kHKI81nlkLn8o|O?3~HD1lF^g6SxJ6+iZ}$*@^0TaxNDs z653`17Q`}SxK`Xnx`!JI4ko-u6qRd!UUV4xZ|_FI`)yE}H{OS8AmmBJF*}?*!u2x` zftOfrNtoPAG{jx5G40m)f2b5W!TBaYT0e$G0ZF2^&>b}L=9MqVBNipNb6a$Q(^MWSt`W`6wG2sq#Z5c zJhmF>fh&(t0c9?Lf{FzNxRnKRJr98EPc3xB23(SN+@Gu;W8CDFtPoHK#)JKax&@tc zgYIk-q$^~(=TNcnsn~h`%{bbpA%Zwjd?X^NQ>r{wxS~eG=69}`9M;7t8E=B5X0~4I zTxDC2Z?o$T8wG~kMELhSb<5L_I8;5gA!)cm4W%NWr;4g~uZFucX9&_^_*39lG{$Ro z=B}889JbqKi4Ql(E%{CPFF0i0E!M+oj<&fH+7lI0Wl*IX6?>bV=sIeoW;6^GDOOy~ zjhA=3vc074XKOA00B!khUEHjzCCnsc+2nXmKV+1~Mbdn{C4;%?T@pa(!?0b{@*QFR%vpz-+O`E z>r36meZCeZa7;!8yqOJ24(zFKMR^W1gnD_NeLyQcNRggIebY>HNSE++Sde5c1M&bj zlEpU9x9_;zj?b81rs7#+9p9af<*_rYid~_bd$&u5QdMe2tv6-dnI!v&)-C%290E;#I4{r7`p$#V|SD-p-B{F?n2 zAidj}%2kO7Pu!u~S#Zfy=Gi!VSXM^P1%Oz7l0G|R&F^w9{V)TQ5l<-XN`=rxly~L+sjq6xYq|`Jw6^6 zghIEXP0A#NxLsgPdLzJupLJ<*Jk!@xJw*&f237+HCZoCeDu&Dp;z{^;wRo+A`y_zx zZR}^WSANq^!LyaYxM#h{ycVG%5x8D2)0vA2PD6FhZV1gKOw{bcQ?Tiz>V|n4ySb+T z-MG4t`=AQ|JWcy>O+NQKW8BW@+^`6EZ*DGGoNQ{@c$s6Gl~`_8HQ%No5n6|kSug8p z3W}yV5iy0An5x5R;3A5X=>{8zq*f#4l`Tqb_ev0STM^hn$du^#J_Z@e264IE+BKHlA&C6Lx;|jAR|P%6m<0%xCu(2(el0UCg*ow!a4enR0$j!z+2X?zpKRP$tS-=v*`_ z-%?uz#Ds&RE}#i#2F_b=@b@zyKq0tSfc06s4EsjRnYnh;CdzS(e2mfV{am|=+-&Yc zv0uC~VYNq@A0LP%q?a5IB{7QIZA2%MiiK;Wo~SV(J1~eI4t&;sbMZap{!3`S?K^Ya z9PhQ3aoRg{8?SP(T+bWKFvvF-(;715+9x4y2VGf63HB7{AP6c=Qa3tX5eR}MVi`|4 zG6iXlNA`=|9BSd1V|KpZT6^UmxLvzeKWpwjNjeK`*fOi+nNQ_6`LN}sPc3sCeWy^U zs9T&FZHlES6u9aE0z}jjSYu}J6h?)`g*+<$yit*nQ+4?s~U3+k2626wzb;kV4E%~#k-^zsS+0A_n> z-rm9Fr#`s$aoNpJTwHd`h)=oNF4uN1d1djpuX8PTyL2-pHkMlE`qOb+j;N(IQYfVz zuOT}dImM0wn|M)eG6>3dcMM$iD|>$CaE!;ey@>8tZtyVC$g_J_=rP}Y^st8F&wZvR zxK_QrF&62kQhg(?p`#(EAa;4+l9IhPu5d&9Ebou`kC4le0K09qXS1`cZzG$1wx-o` zX4M%?;NN(T40gW9JG|Buk83PF+Ag#V(h|urF@jjXBUcMi>3BN zI7?~AWi7#RqCKT1k0Bh@#8h;NjX1!)Kqa@Ec~wjYcdLIwaiY2vjT`Dvqtru)Pqq>jdRK(Tzp7Q=w zRZQ>fW4LI>yIE(#toZ!vZ)=UM3V9vP)l=Jg~!}-sabG^ z3KDcay(>aYi8~xq!Tb>hAe>p4ZXT=^SMHCp9n{F|*4&m?Y%ttMDeg3hILvG_8j!M; z-SUf-s^1wGNr`MB!o`Z-`W}|sXhKVz5`q)SQ_|LeCZ&a6V+IZWDL4thr7C>t^5g(l z?91)1?h`G@Aa^D<5sqS$@(bmStKV#K>-=a>SuD7vzDpJr$GT< z{PNB6UDGvtBEO-_f}*IhCBY+ja;mDGFO1E78 z&pY;*4COZaOi8)r{`(^KncvUT;^bJo$ad6PtTGzDCIN{sHyuwRQ$h#|LXd{PDN=+w zh#C_>0A>tD`>SfLBK&sOwXV8FiFWfO#`_a&?SgU`Q8PFgYOJfvt&p056&H6RDYegH z9CWsZ$J8vlM5I@)#Os<80(p&{`Pn9^%}}%j{{Xe`xe0xh!0<-1{6~xsehS?(iQ! zwOG4D_J!Tddpxmanf=2bmb`yA&2z%zw|j;{{JXu@)dtgzt=Ff=Y3GH#q(8|{C@Ys0 zAPUhbtJGtiMw|JY{{T%E7$0Kaa#;0U`b;T2gG z_GD=i=CcK>bV!!?w+5Seg*O?#ZKcAe6za6{>NLT}?>&W>f#JWBVJdewF#bKAY+d*5 z@4h+J&$l^M^2^(766t5il_FiM9#iUe)oF!}O|#g_Ze}BExIY3+_hdHOkke?WLu7iC zd1I*vM2eeV8oanYHmYZHFj%ha)DM%Mw^&h$3`2r3j4MOCI9Nl^R997JL`Wv{BbNlcKmxGD)MqS6UN)Ww=E?IHa{A1YNaYLm73Fy~q=-R;+H@$T1I zr&uwW7l{#O&0P0nUvC#182PBS5RRU36>N?iHlnQw2@nyv*n92xRih>d_ep*r8Q9^qGAen9S#JcPVfq774bmnUV^aa4E2FE-$p_aSwR>Z54lmbXvRmDo{>Kh)PEnzZJkik*l_ZtnlXV=cyz`H7T zV~blOUNSp-F`rW~BF!|5@5}c7oenxGq_kZ33P&zHchyW~7=mnFkOkjzy}cqVNbXF1 z*4T?3CCLx0grNvPsaYqW1A6NNu_1LAi{&;f*B-Rx*tOO@>l(krZhfBf8+K&HbaHLf zDL@`78}FyhJk5wpA(rZsaqmxU?a1zmoxUyAc409;%m$;yknxJ_=!lsahJ$UZ>Kt*W z5JDN`YNV(08fvFXRNft6d6w=>GSY2-Q89*upM24uXPU>k?h)wY zUS1l(jfD})Qb#StMV@v2Sxuof8)DpQ<9+(*{{TlF#*Y^g?2dlg6q0B{l~8)saFWhwIvUbmX^ZS;0^_n0!nHWdT3>HL|K$oi@Eq7 zNt|YVxUpohu34XNqrj7w*;(XO3A>1KQG%6DDp3s{Nl7Iho>b&2C#GP;;ugP(uH>Ea z?WQ%F;k~+hA&+;=^K09-2zdRe)+Nb>C73T^|U_ISUx$ ze{fx`$Sv;ORg*%-V>y)GaVsdlONVZ9>u|D6UA{@Tq33~p3V8)6Dcty^Xi5@^G`FMt zRRmqP`uvl=^LM`t?0t^Mb;^C|mn^RH4z>p|m#7)xRC2r4{7j*07W( zsi{aW2xkO~0OcSKK-y94UG(j(<`z8V+bOl-SA4DYGhxK?8>O~A&O(dtFu`et~1wh`L2LDAC(bCmnhxx$dDT zNUDiQpxo`GlqMO4(%s6Af!(gt-k{`nD@StiJFUMCX)fiL2$zU2$F?-I^GfErhl*KB zlejA&XiG{!wpynJtAdT0-+szl@jEtiJG;1aJU1bds8$TE+uRgerbt04Q&Hrp?`_4T zf)o;Vru5eOQ?nNvkZP-)>oCP}TLkQ{C&{gt{xNT0N}rJ2Wi=WTEGnE_T!$1J2~|Z6 zcdpgc^ud{7QgBC7Ep>w|Uw0jgx~D$6NY89|_7#HPVPlc|iE_F?X3Kb;F5bn(NVZ82 zC_U_=LQ=ntdRi1*^^gxO^#GXy+vR%u)eVwsitoYUEx_F(pBgsCI7Aq91 zyf)@c6Mk+mcGaG8#(`6}MhV30EK}X|j@8jvVZUQWiPGe&c&rm8$@>-16HVC)^(5+L*go zJ8v@cZj*IW5|CYwz{7p!o%dQ#G#1vNwC^@NVPa zUD3yw%X@Q|TQf{;$J}6EZ4wb7pM8pZjVVd|icLXMRYC<1h}3lfjF^h20j{uezVN#b zC%9JJ4;#;HnK616L37RWh&MQ<*^R}pHoI#A=SK=+fY173f$9IJuaY&vpJyK z*^-Gr06TfA8ov6wKE^MEXIDv(py2uDadyP5c{l2@o)sP+qnl}$~04}ttO z$vIKiXHOFBwX-@ZTz6b04!Tx-VDX?S*pEM#UG>Z^z0D=e-u%XCk;xoN(;)KVC=F@2 zC&OW{Q>U_)vj5cS)C29dhUiL76r~QMp#%1vesd

      zef>s&&~&R#O>j^sCrd_bXaa zW{2@LuGR9_PJuPzy7WV7D=Z?m(p*QWBD;Y?X-c2QwAV~`E`2}^3Y&#-tKD zblX-67*Rc~%#o{OmMAR$0GL@dzU`0QuXEsP>xi2(T+lHCfdEkKO9Pf9W9NFd-qS@FfWHKC} z3Rt#cdAf{2p%(z2`nSPshuU3-xVIeFv`=JsmT!tB;<6SwCw%*tvH1xUjp4+xxapE4Ce+ofEQ{laij6!&weXak<>v zix-2TGaa)`ob_JTf35kI_qFkUs^!~B z*gg@EttJBEu~X!G~d41gC@Z+KTjr9hA#FR8KwTC8k7WwZYs8bI7n-T9rGk z#ejZJu!b4-wci`gHz3aK_C;&IU#u{&zUEzS_Pbr8ZR%D@kXz(rQl`He;W7K85Th{j zjmmXM{J||YK_FLCPy=1$ZlebA$g;bB1NC_ZL3NtjGZh)arG{B)Pe=|r zfTE(FNE#o6)}R{J@^1V)yOGT2p8z>xvR+O0$==5982(Ld?K|+hf0AW+W@L`Q$EFpZ98>=U*}7MF;>ieJ;gVSvVFbN?3RO0N_H{|8*S2t{{V)H z9oO>>?uo)hznV|vnB{OVap50YsZ9R>?K`?~vq^WnTeVK3woZ38{dt4i996twY$d36 zOJ$!KxVvh-tXme-g_&+S%_?=ZEiM#uu87r(UkHl5gOkt6C?b!)#P-2@H`vc{7{GhC zZ@Xaj?58PXwN~sGvypCcZSx~RpO9Q8-Et`ql%z*yI$%3+4X~uN(Ftme3URKFQSKZ} zsY>CgD%Ia+iun#an!n$sI5g*QQuKA0Kw`2A3od=)Rtgcj!E?8@md>l`$6x{RfA*JyH{kRcF!#B z*K6*W<_}?k3d7FPQK~ zjCX)MpUaxw54C>D<{hbx-K^f>jLpYynS484w-Lea57-d;Vq?(WL?bP%avVErFFNb$ zM#ki%iAo^YaqqoTPC<)eU1-(g?Fa65;euPRIi0;?OX$b3dwi?yvg3}S zsS%&K{RZ=dAD(u9pEH?i|rCm zO2#_TFcFb1#=FT6;s-Rs*u3kp3O?d{^Wzq=ig z%Hv{xZ1!9S9Ese_cd*yEGA~`ayj+`tFAQ7l58I$W^-@sdN?bV(CPx<&>ZM1h4RUny zh!O;`IQO|7>9sW;d7I@$r6~I?`-g>ghn7XNS>fclbZpJ*t)CvqA=@q3_3J9VIQrdR z)mrBnP|dwD+E9#yJyyy#3fEk^y)t{p62JkD*YQdm05E3VQc3N(I_)Rh{%PC<_fG+` z;MSCOx@L1=#2@cf;%ZlQXB+K@(Li$FZi2QH`j;kD7Yk2&iEIZJqv}dQ+M0qica~Oc z0hLeu+>tVccx#qyA{rG<^?IMkhJLQW0j4{#J7AbF({&41x;bv}MeAolz1N4l7geXQ5$_WLd~ z+q*sTG|YueT?N+JkX!7Q!ELZO#fEGb9k<;WZMK85T9kwiD)!Ps=sERg1Ev9~VP0e% zq3oP$xg>9<^G8bk&3&o&bGzNk%e#YRoe9fRFJN%->}jj1wamF$ap&jUu8awbizTS8 zs^KY@S}SeDE86t|wyUSqLNO8Cd`TYx%}zAp{#NFBER%qJwr5!9+wXmFxw$h?d#~S9 zklZHUl|Dty5N6#V3v?8_HB84_%W0O|4?5c|g(|8-1qQk0t`4+hMIzjlC0MZRPhho^ zIQus5cXH!Fx?M3mCk8l1F@<7yh6Rt`o^4a@mK%w<-I{jlEu3R5_gZC9&$8lE#B=p> zCXnhO5F!abdZ%e&XV~w>F*P#UM{un>i+C#?hwW$X8wAdAUg%k^ScY?yQz*DzB4v3k z##y&s@9e|3TjrT-wNMmSyEw2F5eApqUlvUhgWz`D zkzP%LMIU9o;m2TKyJd~f#cut&&Mlq1vE=!!!gRRTR;;+Q=2hwhYin@bZAzUX=iNe! z$w)%|wGLEJ((0ivaeU1xVVX}}zhYS3umpGp?cTRH?en(zXKgXe>IP<;O7HnsaB_U9 z>xG^7UTRc(#O29~Tn{kHnp3Xw9s!kNXddaBgs9sDa!y5yaNbKTgVl2i8Ujp)Y`g@7qg=4n_cQ{4n}>~Nm7zZ zP?9J?CZN;EYtiY-8q5FH>FvBEvdWeT_Zq6e-kuu#=tY;-_1`gVs+V+ZFD8t&vRwWG z$W!LO|w(sY*dWbdm`g))~LN>f9?B{bv@nCMRW=>!GF zVo6eQ`EXHH7KNk|L8rr}+USF>ZANsB;>~Ettrwhj^#QA`n<0kvzVB#!b81vs2razJ zi5*h3D5Q@gu8lcllY+%ULB&)i9e=~`(XO_vD&Z324+Xe6i`?K_(nEInmiEwv!cZUp zSxSn&Kb0t(Y^bt6?eyZUVHV0)>ys@H8Lp(F|^qPAEQU%O_({N)xz9 z2V>WN_iDOjf}GGRm?3KlDODy09Kkj5~@FPJEwv6lOAs;?iNJOJ86DXaA2uTKPF76ZiOifMT-@; zUwy)qsazXEjR8FYI=-AGscaHa*<$PO-Iv>*H)FywTgP+s%qHdf z&M}flGHo-xr&uK^TAFbVH1bg6ZXv`e3qsNql>!LcQ;-5iCgCvzD;2`oZN0?$OUDriQ<;_~-_8s+36-Na|EKr-qy|Qi{4)bH;~qbdwcCFDL`o%7FZJi(;@T5;%@2 z6)E*lpC1h&vT$7-CV(1JyNxq4S3&?q2owZUr%hl0ve!aLsWb&by$0vRXs{&)NGZN9 zt#lrdPM#k>hNN`PXH*h+vP~zFeIv-E)6DPJZ2!O12dEpXt+mA_bCyCJ0kQNeFoNsZZ>R z@2bSTlw}YqRMSlrH_VWtq7tN%HY30d`d3|X4jpmIOj$XrfGth`0EJI6y-xI}^lFvC zPL?-XVfRez_cH#_+OmsQYjo_?_}K)U<}L{q>n3H&?+um}Vzx>)VkNZ8t6R$iEiI|U zpe;ZRdc6SlNW{cVz^i@Qxvz8L%bQkJW+V?fY~1YYn%4f%eZa)U?06N@)0@HmWyQal zu&YvSxg?ni%rdKtsWT_ZxZ9>dVXK9)pQj2{)$eU71zdR*a`w))o0-v^y}s-~5sMH@ zOZitmOfg~NYD>NZ;5#j}LhaG~d6;&Tc3a9dYaB`WXWX1{5z>f8vQ2J8Y>2%w@;BcEhx6x`zA4xA$+k zJ;lr{)(jspguFFay|1^oyIrRvxFhMNN@h*dA-2o6NR4lXXyl>M z(&dhrs5B&sZ2P2N$S8g;@m}9FH%{Gmi}ed1ej{R8%&zBLd%v1wze*jsdyp{e4YK0h zs@3{%a5CC%j>e1<6xCf)(@zah7?*(~C=mmV9$nQz$YZ#lHjk2`-}?>s58E7K$o~Lp z;O2~FmmbVnqW7mOizef9nKJQwzeZi$MP+h9a!s}y4}`TCp~RujK}x7~NNdJzDK+Fq z7*Kclgr+Rv>Fpk;wgp$@_Jh6Fdu^`SZ^m+%zi*kgXEx`2!Qx^!x0rD@yHgC?%#3Vg z3%oTJ=`C+9#Je%NxY}KL92HGts~V7f%mcp{t6W;vvT+-C{3(9>(5aEwzV)Hr&*E3S zA2!Rbc%%zVJ0>rDx5*X=5pK7I+~v%+{T6kdhZ7i=*C9(oNkTa!(?(MU5-!f> zo(w@4-v)G`fibz9_VC`zaDMV^y~oHqk=iq8vG)c(HHX=9E7mui_QDb--&2=MkNRvo zbIv@MT89j2?ghR$k&Ica48`|yH)UMhaeQB9REch_uu7kKX;WaPgivY#MxZX)sf&}3 zB}p{BwhkY-3v+HOsJ-mPuQPEhFB-vEodY0#^KQo>=hmnZ=3McMM6?!emk6&&alfQm zp|-X?^m8au(tWklT>2q_H*0Z7OP4l3Yb>pUVEDgn@jDg^g3 zRHZG)3YOyBQUJg}Kfjc1Od1Qz#Yk^unZV1OP487nh{e{N8zf7 zkWv!7kW@`QCwl(?RWu?AD;gkDK_Dmso~j4ozJX^%7D>8=DMF%wBhRgT^*M)?lSHsy z0YH;Lr5&nv>88rFgk#HYL=r1chTb}9Z$W#PTJ_qbbfMCMvm?-T8&_aF_VLq{sWqem zI;iwWC#lq>?V@l{6as6+f;TAeH5#FU&VV+8cmB-^f8nIbirI=fkV-(<&;mgp9lGg= zC<9d9tt6|1dxONOJDT|&N`nOTIHkgOPRHlhYIWbHjfzJ`a22EuRM>DMea8I`w9a4$ zf)Sz~6abp~L85EsG(=ccXGp4*Ac`uqMLe}R0GuMJ1v~Unt$(LUD6$~BO-kaFfJg{C z8uj0y(z^t}IY^Y%MGK)xQS{ceq14E&Q@tD@Eu~6Y!8JafD&Cv;Yh-e^W&kfPspLo- zY@mF6^kx}hRRwn0g{V*vD4vwxYJ4a)8QP1trn=Vd;iXD#Xak#QNd)ad%9K}MhPm#& zy&5iccVa_D$;e*Kulz0|pb&mv4R+`TO{-P^*Xh-{(io1|At@|^vV01NPxWi_siOMl zQ6F(T)pBq_y|#{pY&q%`^&VX-UA0XbuB|uvZ^2mDMI30QuWdqs#FJ4<{{U9IMeMmI zXlkYaF0BPVq6HQ@gTz!-<@=(lSp+hagap+Dl_VO_kUV_#()nz;CGNU(*j)%p z$0eGTDAtr4^`YBTh$?byRGTSUHUtWaslNpeF}ICttH2Psra@9{g(KWa9@$x`Ki^M@ zBdG{M+J(IX+wg2l0^Xt+J|HLPk}n= zfTa{9D^y^$FJ&b~NFbCZn{CwZrw(p`izBA0;8w7)$SELHaX%Bd)5m&KODS+vTu7xs z6(Ku-Y3Ju%b%I@Tuw)G&pz?FlN>3$qG!*OCPo_vUT1Ds*r259-@c^WG*QevBGD<9r zRqHEO)!8ff*G-zJH5n?M#~z%H^yo!@uT*q}EQ(i`hf0s@8fcMI@Bw0HBdt( zbWce=cOC$F`DjK#GABKNru*%_)bY~ibXj<+goPS!L-HfXOlAcN%!ai)5&-H5^50uB z%#u=+m2wm*BBG~%_BxS~OaLi*g;an7{70Y9RgF?v4$(`1I+gq;WyBB-XN( zR1%?4K#*%s!&8wU?o0!ODj*(3L?rn6Q{|QKujZ$h`}I1qqXbo{G_5EJsqo+Dr6mvwDfazI zKbZP~H1yNNXcnh$i=VjN^P_1n4LV<|uEuL;Y$hfgWC^p`nYS%cr_VlW`yWNu8AxQvK@+zjl z6rTa{*KUAKs=xox>BI(VhSUuJ*!Ycz>*cS`WG}Ak&ZR(1QB~>ilAc8hPzfY*Jgd3i zsjj*-D(k0CnqgWP4VBQf%+rdMS{hgO>#$zShGezWqhhV82^kW!!mwsk|>@T!RGTKqL=*6W@?ju%gmfZB*rDpLJHXVfZoHK`kIwyhA|>JpQL z@+eJIlV5!!m;}>mfGJ-+TSyM|9ap{zK=M&bd`UZ~)Q+dG?bYjL0K%$agsf3SRB=3s z*ps(_BzWtx0IoTZo|=G?2|@|{+x}v9r|s3kh)!AxE;v?45T9(M3i3WX{Cex6F*vEn zh7H9W8a9*df$9lDtFq5Q@U3*gz_-mQz0=m#Q|&iGkP3az1M=IcuB`{4QIK~j(Bz^B z0YG?>Ku5z}5s6cvM^CHJMGy8!9X}m7fl6sr=F$NNl|blE^=m>K){#r0Gzbf&L8(9O zT~;uqQWLQ#grqE_3fI&=8`Dh)2V}A(lC()6bsBL1N?M{Cf@?y20R8$IYgAGT3FlBf zUMK!KNkgtWc2wE6pjI2RoK_zq>*5{v;)a&c7CYtLAWWkwxzX1yx>qJBBW4I_?`9454n4K zVu5oTx|4pb#~V=eB`YdfM-x>msQ6c1`XQFpU;okS6}%^dTvm29QKr-#2k+PCLd)wN zL%CIn{@Zu7RH?^3X=rgNK>i@5PW2+RKf6}Yy6n;<>1?-eMPrY_)V8#fLJENu{M~4x>ms4AR8C~YbwqOr!RT@}ipn)UOptEEg7^?^97 z72E#exILZlrQ^lG_K=eIv_Wp1zbJqop>i zgrB&#lI7C|MnUXHkUnc>7+a2}fdwD{IR#W2cn_bBk_43r#6;anwz2K-LP2zK3N_lb z*oy7(*IZ30b;}`FHb>naqM9XZ=4rVhTY845Bu4} zM_DopE>#8j_8W^=Sdpg9w#bmrE-006khrp%AwU|o^GZS6sMVwmu~QUNX+M-IwWsC- z`t%}f=oBJ@U_NKW?eNoyJ&-7>1Z_fV;iV*sCJ6KP?6M*go@~dg_J%! zlh|^*JS>YFy2ia(E{Q6)-6F4>FL7F$CAD~tNKpBW5kf(@K#C^TjK?0mUUJNO-88*; z!DPjWlSWb;K#c6zsF=X_7Lb*NGU8QKk_BjY+fG9c-LOHGm)~e{s**`OQBnm|drpJ2e7>(-@QjN?w6cAFb2Z<>l?mCZw8hVg`qKLU)B3hxL8 z=W+?EgALe`UXarcB0I8q%5kKrEH+ZfNLz&|D=AHRCCPQwaDsALC3PQq?K?Mrvphto5I%6a<)i)EO2`P#7O#NGpm)VFM zPr9bTHE<%eDX!I}E1{a5=#Zjqc{Qr-YqMQk_pIXlkZrcxyJiH!wN(2`j`tOZ03Vi> z){&{)ix62qUCskf2+E%wGSt(L80FLj`)wavoC&WK_?m60XC~O9+i+1heqD`cnAMvv z#O~~0am(y+GS7656qLNmx)7BFs8EBlfIkgs7NNu7jDZR!(cJ77`EI@5ExBE_%T7Og zmycd{3X)4v&RKfrPh3JMx4`y}f~>HkoqIFZ?;h z(dw@n)ivam0n{9OTHzrS1x?Dz@wj5l^sI{05uAm@HDYn;j37>1iROevDp>cFq>w;G zYBe%sOMyXj!Z=mb(IBp;pgSkXQ*o(%TGbpB71t-m?C->hddRJInRf?UjSe))j7N3n z-sSBy+Fe>ol)fj38=4wuxgpw%4a&KX_Zu0=@{HpWgzJpnusf`4HQF?Qmc!CyTVvf4 zBKnDRCOnjtZBRk*71X3Mu{hVy(5K2saoe+}^Yctb1j{TLnPr+S!yt9mEEead#%<~D zvZ9AujM|(Ec}P&=LIEJ`chX7{XKN>ba>~Ht%{1GNy0kRQNmGuk#e}5@NaUp`t6%^X zCsSvjTFS9z&oHc-1Z$o1DT6 zR^rNm0;r*-Xhyv~J0Ux-|I+G3v6Op7Mu`b2QcqDtqyw+cU{!rvshM_FDT#5*yQ=k- zwv~g#lny0he?7YDy*rXup{Bz~cPkViq3yJ<;kQrEQ?~TuzWeLCH)Y4GiBi#sTZKt; zm$>4J4}yWMX;bH_#{KJ;Qi9eBL?up<)`(B#sHq@qN%Hd5K+K>{RQfm$D`8pyN=D{@ zl9Q{$+`08Vsp=Q(s*5E)-~nzZdTOIV({F~Y8D%Om8HF%f6>jdn584m9{{Xoe9mTlF z#^dF-oEhwXSLxRYtxGWA%R}5;i5c-$%F$k(eg|In<+XMCZ5)hSGt^SFy5aiJ)1II^ zMh9h7e|r1UbNl`qI}FZe*}E|1n)W1R3_p?MiFYiB^g|jel5Mv2%uLb7M!Nb=pCm|>L7R$uPq)0c6LGn6YRtRf)Z^O&%|}|Z4(UMdmu{ryIaXPH$>g(x z#+8UNF1YN3qHJb`&RknLk0#Y~it5~2=Y2=BA|jHog{Oi6pwofTCLjPaR)y+Xw*{yL zLGM_f?ls-JspROa;&$glWCPlR_;T<<=5tA7XK33Es z@_}UvaWpDy6@-mTp@d~HWY#Um3#jWB4ZUd|ChgACj9V=;GYpZBwuW<<@o#gnmE~Xh zWxw=E4kkQ%#I!efRk?RC*S@yMOG`fAxxlO^zFz4P8$MBXyVSLvu#mx-YbsX4id>c(~u%yGu)JnC+z^Th5qbH|eOJD(hsa#I3@u zHk=;WZ|<`*3qBXNJDDuYJ6(fq$DO{{PAz!nd#2<0XL55(rh6Z{_O7rYl6p^2M6l*jG5FP+PB z%=nL%yzsrJDSz~S0~&dmV5Z(sZQk)QkEkcr$5w%c>>k$2J}&KwSq+zJc%OqSovtTy z?cMF|)$1i|KFc!iZwQ5PjV3kb((HB@Y>d_3Y-ivhVJ$zlS_MjU!?%cLA+>g1)IR($Q&|_Me$YtZ_D6y-#aB*L$7l|0h)g)Zoh#`?E z)g>j=uzkfe97;DjT@ov`so3JA!!TNF{JOu?AVbP=e&tL1Ku%GS3{M)58z*||$xWu# zn|sqD$0qPCs+yaLiiZUfwKSrXqub+SU%Jmnw)glye)Qn&yL?AGr?-nN$v1m!?&5aa zyqED40>=m2)wUFyl#8{t?9`b;V^>R*1${J2n$Oay*%Q41fyHW34y98WS)$EX?S2~* zV))ayuGDMxDUeFf=1K2X37qELoEdj<9k*DlajtWe-PT+7)mY`b8s44&;ykaq$%Y%7c^&+*8R<0$${B+kCxvxv(UQ_nEs

      Em3>X!m`z+uvo!z0@H*6}hEAA_8E=pYX-FhUS(< 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%0DbLuakEbDWC^!7_bHOuEew53I97NzsEp(m`#eUH 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 Se&6_Wb6ooW0H1GuRsY!?n}W&! literal 0 HcmV?d00001 diff --git a/public/La_fracture_53.jpg b/public/La_fracture_53.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e7b06ffef56a229961febe78ce329f658a575016 GIT binary patch literal 193597 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 literal 0 HcmV?d00001 diff --git a/public/La_fracture_54.jpg b/public/La_fracture_54.jpg new file mode 100644 index 0000000000000000000000000000000000000000..fafc34ed59a740150bf7ecb3459503f80743d6a9 GIT binary patch literal 191124 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 z zj?^hHWZhQv2(EJ3RGDV(EQ`GqmPMsZc~Rj@vxOdXrIzBs zb@tHns!Bb=gds}uQ3&~n1Jl2!P$1nfEQg)1RgX~S!2ZWp#=L?8_6H`%Oc1X>YsASe zdtpIi#~xn2y?O#QWMr0^vuic3!Trl%tAOpQ*>1Q>n!`p)-}3en$Xda0xIyvp&zF33 z!+Sanf)lLoT5j8Qxof)R{A){&KC(qV;at%^NaPt2UB%PG&2Q~{I# zXQS0@)O4QbziZl5{SL0-xkg7LY;Ee=>5kZOB6E=CO-Xo_C&9mJ8vbFE<&NJTmne`V zVe-gCkWov`t60@Va`t_mt6W92w8E)Xq}CycQk?w}*)Odgmc2l(1m>N+!*mj*?P^?wv-?7$e)ah{y zs^02jFk+>}tHrb__tu03D4Zl`zr&^xCeBhCD*mUP_@c{RV`;G6Dm6-3+a0E_Q8N0% z928HTQ#sfUh-+Kk4<*MLDsRO^sU;+VoOMZQmm_mOh;^zPkLaVfUvxYbuI*QPRnH++ z*X-Kn!%?f;S3e=9%T_mS`>_y8mH|i|oL8e~vaovJf?0C`gZMhYxu)N$u;KD&9N1s% zdZaD)U6-_J%&K0~ueE0pb1NA~b-68sxK_$iKT%i#KOA)<6GsNNqI@3&uBFHvf4$O3 z*tBidmu{eG=NOlDPd$mTTXnp7wzpYY(v<+9NGH&P@#<5E(@qNur}Rw!?AX30N+cF1+FAX4mYlGm8Z!3-UsaeNIj>+XN7L^t(q1JBA^D|J3zjdVpgt ze8EUjDH!x1d=K#N*XP57?_W;PA9WNtDMQZ6Kw46eN>rB804g2u2j)F<(?mM;i7^A+ z5{Qz{8zdDciu-2jT}-jFDAHX@z-Xx}Nba-T(%LN}!O6?{Z2b zFwu=DJo~bdCD%`zJ|F^&C(HVN%ScKPXvD_|15IEEoJ(R#pNQzbsoz@yN)4KXpR}5f;6%`-M_W%n&NsjNZIAgy(r_$<}HVMOkyMp)1Pm$}GNJmUaHev^< zRGmq^GkOKtUvJTNn(iEpQ*!N-*L0TKHAN!t)bp~;C^s{r)G9-gGV7p5ZHz5sm8S~H z&U%ifPsn#a!b0Q??6?<>wOH2tnf9VAweCf^`h;fSB116Vi83_<5zmaI%|yicft&^Z07P}AD4jYpW#M}G-)pS_{_XYYw!v6j zGsfF)rLlduZh{uz-ov)qZ&CT4Wu)6lEv^dFJ^GgC$CBdNVYc0Ekr?Y8#!UR`5QS7%UFNK zwfCiG9&WA1IFi?O5>l{_9%hfdPrJeg@(zza|kmjO9$u=@pETXGh zjU{e8wc)l}#6UkvG82rPx8;eEaxYFyQn7CV>N?#>ZMfT*Q?he=e0QeoaQOpmhrazL z;b#f@+Zalm*;R5|*;tq$+(wb&8-l{wL(s`aR*!8&n92mj$Y9*9<~Z*tllGml>(6pw ztZ*LDu_gs7bZf|*VQIW^^ZQn!=CxfYd6jma<%hr5Q-@ zVTM++2l`Xnu6-E*@3{IbLy^zjaj)A~6LPM(%sSP+<*(hq+Uex&E9DKt`*tJkXDu>;z!@UOp=5?j|G)S?SBlh(OV}bzL3H{6%}b^NnWLT}IpP zYg|LLSLoX`pA#CdZksMJu6Y2Tk@nHp9t7%yUo0qyfW_Bz;wKoU$Lu*wfL}A5@Qc)LJ6N5na5d-@*`Q{ z#~C0MEc>ZSl$`W}MnZ+8KXG5@B|adnILtpd%owm~Q<*L7 z+moBqc=r0K4=8=P?^WB*!8cLR9~?bj$ZlNLXnNH?yJ*pBZlzlVHc;s9TxtTtQkC zlSqQ?y!{lz?naApmaY%kbloPyetV92E*{N!L00@2(+zrR?BTfMCc;EkR#Lf0`AdM{ z^fZ_W2@o6(gcP?g;n8y6J@Lmba~8{8zK$Z?qtn=FHhN5L0p)1&XII!iDNg-tlWw~> z%toBsh(e@9S&-ke^EOA1RMM1m;?5{v8u~wqC5b#jcd76%De2tXrA>vQIb#Yf&c8o! z-7Y3mT~tVBx`CR>7Ez}>h}Y3A5?c0srqHOb59$=4EkI+aKN}N<9PPWt=*WUe=hbw7 zKIxk^p5?;)g;B@p<=SpLm3o`bHZmZwA=O*LM0mDQ5oWexI_ytvXz_8xkcU>J9E=(1 zY5@}xS^c)?kcT^M`mQ2Z+XpjO)X`WgjHNdo&aZf;R~Kq_+Nh5}HXW8_tX9c+aZ(%bF9#h$66$>jS@G(BnmHNpBdfC4lfFL8>H)8PqjH;) zoY(d(QbpZ%w;y{cy}H=zV^H6#WMXV)+F_ci=I&ei&#DGVl<^G|`JlW)F{iEx%nLaN z)^2;P$uwvf?rpt!?_Fi~!J=|5p$m3a{ja}EUuwFRHMp0usjT(_)EJ76^K@oscYOZ&oU0b z#|YDDqUhRI&&YS|avJWNQ?_kwmAeZyjk8{sLyVT4xk_IyD+9;L9%&~F9cT}^%bdLk zbi@-*1bV2X-?vV6-T2R1(C#?vQ{#DDTf>*!e@|&ycHG2lRyQ@VV77pkqO_>6+f;J; z{oOMR!Y5l{zQ)5P!0>!CGq5lu$7^(vX;=2enLqk5=IBZB=tzU zE_skkRTxT;kWhSxaUnqmCjk0jkHfBzS0Mz|5M$ZOygV8z!BW5;Lmh^HfjzU;;zKj8 zd4qFQ=g1XgEkGl=8OBd>`h9*F>Y+`jj737qfCIP~E+_-pN47pW^gVQGz6+C7hE;~c zz?^BgZHn8kDksRWkv0W|r8`#^O;gxQuJ+Rn`Snc6OgRf@+HVSRqxw_jpApxmr`_tt zIR&ij90PFo>bPa45mT}BSF0&;B|kTr&PgXdy-qv!&#z6U2veB_KF$H};yV=_`e0{0 zzm9sdl?HU_f>uET2>_9f-xJvX0H0ThB~Elskn=AsQIPT$`$oiW6;&$%hoFv2{Ra0`yOgn{u<1J|dBGD{Tw#FYQVCiihE-}$EBQI z7?xWEkT9TB8_5X-_XE?{^6Ln-5GSh2QalzEa29grJv;aR0Dpd-B8Q5^)iAK1TU8E4 zwVe3%RngFsDs;C~9hQ=!5|ZPtDJf5Lj_20{tr)qY&eSN9TSt+?0UsOz`3~TGdO1eq zrbU#0WZCuYGO63mqS8GzTXGnRW=K&9REcjPi0vUM1g&nmw4o_TB$I$TF$B;AZo_&w zgp~!jaTrYaempl)gf^yF@K9s4Utl^=MgV=;e5O zE(E0ocvrZbe7W!6ri=-tU1CGGf|(&DO@dF5z$j4}{X?<v_+ns8V;>tvs(A6ePWXxewVtA@#WVn*! zX;{h&sLoOd?lL-Dq%ClQZ2N|>r$d7~X1R?|4$8_6Oc&o#30&JJ(;g!|vyXArgo1m1 zBn8DvP4Rz3H;5+MgZUC}~U5>(J|JeWu+10G74351LZ1fg=YUX+(vROSh_O z#x+CsaM-u7LfwH@zeMugjV;llt_f4bSQp=3=*taldLjcA=IlqRrB5dYlG~+BSztkLBR8pLL zK|Q(>iyENlC8q7I!y7XZt)kuCYETztbE;Ozj{T!;B?ZK#QA?>(3xIf|-0=kCzgWPQ zdlX`;+J1V`ZZ~M$c^*BaU4~WE`Xn~=bcS1(T}ul7KvRLkg#9e`@NwN?N%R>c=@A#g zonPTG-tYANRPGNT=oS^07uDOoxju@%O5#}CMzn_HMkO{0TMs^mN)X`3bg1VYA=8+l z6eOZ2x?-T46LZ6fC96T`E&-9jQ}pO zHDs-}`=ZcTYxNgfr5!z{+^~&OzHN+VBw4LkAVO`|5~uUzG2jocOOUgGSum+aB{Y@A!Wc*F4A-T{=-FiVbrdNegtVC}`mTpA@Jc%p9KG{V|c(B*VJ&^iEa_ zop%^-<^KS14>hQk0P;D;e;(tYjTm#P@UqD+@N>~9(N|KxcKR?en&t8vb zbuQ-1|JLI3u_N_-CrbfyHx>P3Va>{{WKGN_|t}vH$>Q(IB7C zJ#-1Kc|n38kd&*ys3agC1PEP#7m2)G^=l>biGP z)UzY7+sX-8B=$ZZfd}#UckS0^lQmZkw3yL(x%Uammm1B_I?u4@yPhlD^hq@FI9rV& zI~levt0l&U>yp(8)*W(rl_ALtt<)v^6SUOGr_yRS5jUAt&DQl#ao?I3Im!mpVp>sTWI^V_j$1`O0v;n+i$jR z>@%-i*KXdmg2Ic)i$fdxWeRE8G2UnwRKip5rLq`W)!jW936HYGwHd>1bDIu!Q3vg~ z!)Iz^$#-Yk&ni}4X?1j#n?%bSdAIkKddt?9?d&PBk5q=F$W>kYEHW))M@z#Gy4oE5 zO{>Valh3WCmPCNTgRo|O;{(A7Nx0Jv^!u#dfM8og%SAB+z9XJ0k& z?OvYbn@HCdHON91rcld`u)^PL6CE$Ouv6vaJG982oJ#^glW{IRtQRl@IOF6T4zr!rW9{{27|}TgW!V$9YI1j3d&MrrOQCFOVe7lCok+TkxYnY?nU*l2 zvebsyc`B0{6KP?um*q}6Gk^^vN=R9-r99OjY5>5EpUEXJe&?mlCr4Pj4uUv~v4);=8T zx0<&1o<83-3cg>oq~xwxpJAf$cBQ-N&C1y=rRi1w>F&DGN~z z4L&To3n4W+g9=#H%*a=`fDz2E|2X7;>`WM zv{!o~iI|0e!_7=W{oiqZQ;aB1kN<5*CE~&8WAYn@(WKz!xJ6G52J$ z4?}}{F7)NSd3&mU+4ZU`U7?)<^J*X5QfX}L;J+%78pV`|&Dc$8#^rlXyoP-J#{!hB z1uM;6b7{O`BGsp=GCySw)ls0AmKaH2YI6hj&;dz4{{YqJx4G1gT(xYB z8++0C?{!A0ZRPs6voefFk2!ozwnXFFj%!CY4FxT86@`$yY7(|}S=TB2qJBg3O4A^) zy2I_JH<(%W%Xn!Ko9=8{)??Dmk5q$&oNe>^Aa+giRgWy*&Q7zq#JJclISz|&t6e_P zIccn&Pj1B%Gp-$2r(9R0A~K>i3MorT@$-MkD6OI*8lr|RZV$0U)DSTR2&L5I-SJa& z+)bi#d{;*fe&5b@TRnZ_NwC=2exvsG+C{I+B4bKwSt^KSw$Sx?+UxwBc0 z>>ZhGZAv!WuY#QGT6Z!#%{H^Gk+w$Ub#6OUo9jx-8-|3PP39*ewksPP+hIlY#f8QZ znQkw<)8QnbDK0p1oLDn88oZvD-srFZ`0eSls~7ER-cJytVjCv0v({;I2AxG0XRxHZ zq+HF0(sJv4xs=w@C3#H?d800TH%xbOlZ>Qhda=x3a3tf@Uxq6dG}_%Z+@}8kc{;7t z-Oib52V2;-WK~h#Fr->sbqoW1+;-%8fd*c?kairLiGwvI@e$C%rTX%UV{y zrXzxsOC7ycWj9IQ-`b}tZyIiB`;NEdDhrJ(la#4a>FPB$mtMIM9=dI5ik2h7ZcKSG zl#rN?xCaCZdOrv-)>t{cxOUwo;TjlCI611bBjS!&DiQfR#B`+!7L5xDPsgS3~kOVC%E_YwhD;-gHK^yQ*F~BBt?h8@Tw=Ol=G;Ozg-uV(|8QLRouTyg>nN36* z7`MxpJiea?S#r7Jq+`kNAf$N(D5L=f&4V9$c@UaX1cu-7^;Q=FarWV;bIr`d#+H?p z)1KPi+cxXCO+=d8lk5bTDE;;npw`CBjFQjPMGnM32`&TVl`gwTKGx`jWkybKe&6TK z+WEtgna~@N$WwWzO1tCjyTz~E5l3F$xYYNdNGHjby|(5h&l;1%=Vlo&Knlfb@UuxWvpH8wH%*8y3LPUUlzDX*{kNJpWeT6bc-v7R{sFD zqVvbwV3Z{&YXK?fo~E5EVh@G33q+Ri>a6|WN8}D&*~a5}_WQ6aSJUda$~o6|D7CLx zSv{|8&P%*Z7@t<^Kc^Ap0Hu-dAgCj;@68Zn5fLm4`34GtQK`kld7G!aKf#=vMb4Vt z=Etwzv2#JU?N>XGAh%yb2ENw1(9ZfqF5Wwi+1a7s^l&0Pmcs=Al91D3bk>w*3RcbG z>A56n<+sbJzbJ8L>o4w3KK(()QZ^SXC+X{JVVxeT!lUVGqys8KXE^*jYB>=bQq&P0 zPcta^`80goPf4HtRZbXt{LvUNlUr;z^7^W8bm6XX+W7NR;#gc!Y}=f3pmJujVYEu0 zTFfgs_pyX}q*ouSQ>$)5dzH9^2FVFl4slVb5hr`dA77M!JMwQu&^vG2_1qorN7cC7 zOsc8i&H6PIZg7JYQQ|iN8eD@q0$PZlAA9#OL^u2a`49@b9QDr)U|{lm!k!1-{v|md zaq}B_c`j?M`(EZFBJRFMr*5s96mCaVmg-lk!LGbk#|F`eNksUK8;QnalG!dbIZdIG zk0P_}whuwqi7w%s9BJ{ohyVca+vQEA{k!voby!%`YBhEii+f{w92;5e{Tz?nIM$b4 zWw*mGp=AzFi2ElB2e45oK?~|I)zb_K{{U}8FO>5x{ykga0MtI(`671I`xpFWJ&gj& z`;9DR!`VNyW3=Nsl*<)ZAuJK$+H8I+b&c|O!nAZ^^&s$K^p!^w3I)xOi zDS1vMD)LZJJ;0d#%zo1Cz=EbAzyo$ZuB&bP?TeT1pPpOLTxJIIpzHeF9a~hh*I1_2 z9bR}VP(ef5n@k@ojwvO= zfN)fM9Grjv_3zsqdGa`~N*k38xv42>%qc)AAqZ9qh)S@o-yXnc_@}5k^t8jTHNN0v zVg$!6#L01GUsKvPzbPxC&BA4pW5!0QtLP7&tu`mF!B?2+UMvOI|&p5FnEs3MS;c12r2klMrP^jGP?2O$3d!vm{|imq7` z1NNfLrL?2Proz^LLVXA35A(?Dq5w4)EQuzjh>K$iAxZs1=I`7N{qlbg_;t}570)7r z?K*u1{XuW7Y?c22Q(1Ej>iI4 zc=-<_-vEsD(;Amt@(dR0p`(6nMWfYmU9i`hkeW#PvE3CgRz5*j6T$r%K&ovSVb;LB4zOsF$ zTJj?+I6f&I&%kwIQOQW(ns%QYqz>UKIUk07Pp53>tm_bzDPOo!2n8tx0AQRC#GimC zry^cR0vXm@2>>h0DnZYZvz+{WdxMU!d!Z+?R5+oQ!1#Ql{l}-yY{_zqtfhV>00m`3 z$bc{j^zYFU%Sxa_q1G1_H0X$Jtm4-q!doyPDqF~F-LDNK( zS;~FpLxZ}4LO)-8dir+$9Sqf>qAf*6?)*W*8$Rt*d%SD4lXmO(*+dA^WxpM}mue7X zup~f3$d5g78$nuq=A0->dteTjPf@9FoDq)&d8Di-2{;S>NB;o20QU6hMqre)tyH8W zB>51OD+&1Ep4bE9_;jufQ2>;(Nm7;MNB{wkUtjjmR1QfAG@{rnO#zX08#5~`;fZ#)okfbd+1O+7b1bTcrB4`+~ zP7~svET4(Se-r70{5oJjK-CMcys5c%*_zp?nDqqJR@@;TS&uC(Hu9QYK>55LLc4qq zLUs?iU~t`2plGq~#~zPeu4FMq8%vwi>DTcY50|xVvp}xK7-%wjOP^(>W_!1rIF=ZQO>* zKH8Pydn*KvmO#ay6x>2Mly+B$AfG|%KlpUHNkGeb)FZjZGLT27e%`j;!xY6wWk z$BHsZ^u|4U!0tq$4c$Op+^uw`NV00Zt0j{i(HzHl)wG`(J|5DSE(p}N1-Qbq88sNB;=%nl0eBl z3KHv8HB*e0r6t6NRD2NGAQEtLkTa9<>P+eC6JM-^hK!%7Wf7Xlc2Qb=v4ew^X9EZG z_32%x6R{~*Wkrsp2cKz`I-uJj#}bmIs1TH-D2$We81?Hp1ufJ^bmR?Rj;JSWyG-E< zzO(6mr41+Ek%_XJgwoQ=Pnl1;@cFNe>a`hgQ*BN+0tOLX+6^B^IUeMGS+u(O>KvhN%TlD&sHllufwy~Ug9+y*1q6x;Tx+b(u?3@Wht5Ot_v|&FsPs^WQPvhJ0>w{1LU3!{B z1<(7+-*zjjWT1s)A!=4Ud`H0c^(PVwtGHa;0Gp!5Cvs?4|Iqc0Rs?U*6re&?-@1p7ar}p0pHI5_PM7Xb_p%*PN<6%NVw91U{J#VI zJ$v*)t(UDI+f?P15R~{8Ei3MEoQ}ui@anNFr!iWmVZyYjO3%99J+y&?g#0s%j{gAf z>Y%!bi*iMxBgH|#1vpfD`5xoqFg-nUp1L3#isjXlhq5NyYw>6W<2Wk?Ao$>XNbl%+ zxCL`cLCq27P`?$22h2uEKY%&)>#_i~R}ADHiOVSnP$VZ9^-v=t7$25?9dts9b1oCs zO1!cCKO|&$sNfQD*#7`Nx*%)GLSQy4&t6vN%|_>I)43x=+ECN_UmS8n_JtAJn?8~8 zGNQ4SPpx(4LrN0cC`x2F+6f*?SAbVu-j8h|6A8xh7~O=855nU*fR_gkaI38snmLbc z-WlOXd3MIN#qw6aQ#WakH(I{f8mhO}uB_%o`pU>Zw*?6>8z@p4TA9y*TKzidpKlEz zoJ11Oi#}i?U!SBIJ|wa2(z`~cZ(6n)eOYY zVNQzi`#t4dt8LmZs5bsem&kTDTH-cCEt$2pl;uWe)2aB0iyjo(Vy|#EYo{^hpAu5x zQ*P#6-jEEzg?4Xsqi-#r6fND8mKfMJo=%0y+a<%)y!S7UXn4IwAlIIycqThhU12fO z@|^cv3ros-C?Emy=QaFLVj6%%`Ld9cFe2dl{3=FYH*#Hmg0ZWl#L$7tr4DD<3MUKa;(Rar=k5br2DA^;H@5gQ}F_87OM_4KT7vWS@qvGo`xqY=eh4|0CfKkQR>JPQuL3y5@XSmkZ| zkw3QdeqOQ{yqTtL7Zr80c4gbkhqKd2i(^d=#<>;oVNyJ%n|X(;<2vc~eb09#A!_N= zj6*o4X5B_R1By{W;qEp&m91&Z-0!{X)V#%_*W6W4-t6|KxWA93Mk@9jpwlcHWlu$M zIrk)7HuHch^@K7#JyH9Q{{SfMHM)+M$aj%7r0iP;!B{L~Ij_`MM2_y=0jZLZ^l4JxavM@m<4>O^ z)_)?4^QAmm%LyCv;kSzG9%9d_kMvMF68gg+i5j5?OV3-R%D#XxjE(FL`1>})@EoU1sV-1nFs z$&eJb6Dh?0l_?(Y&D1p_2>WWz{(CnBN7%1^wEEedlzP(}}f4BoWp zjY;x7D!ZeeIN^Mmxc#`(+)zx|v}ju`w4OkQg*uo@j+zOAFt80NK1`}lwgMOOsaOOb zLmfGRrdsq%{<67>yNmg9rnYp7&1&>X;@Sxoyk$`9@AycQuJ3m8pj0-e7xS4^%1m?x z6PBGv;5wwG0!(Pd$0u)e?#y{Vk#z&)9xLRFPwZ`*-3A;z9gtw;Iu2`U4!2*8BG3p-j*>7)au+w|kk$8*I4FH%s)EF|E^9SejNu#J}|j zDe=f}0W0uc2T|5+vLM`sOA(I-^hkZfeY{!nCdc<5v!g+KVA!mvbO;<*bO;hzF=slf zgIM>NRCfbP!>d6`ihE>^-BKEWMj#qxK6oXK{CX(<&%v%~ytO`Cye}td`(>ot+_W4~ zuh+3Q6VhgC_3-1_w@4gAa+_vjFQLTvD5b|e?*rXIOvHr?N|oeIAIUUHYVq*5)kbN) z+4jAUPvuwlE;3z(;y8X)R}5F%shLu#B|UYsPpqtp@||!sE(}-e+YTjpK?zD+!cS8C z<2cG`n7=B0Xsa;Lt?BRdstL)wGre3_@-0301zqwVFzvgJpRs9twvV{)VLgIw~098vX9${rb!&CwLsg;|H95|d%EKNV%@9?zbei7x{WM5QG;(1q5 zY^8FVwF`LF^>?rRUdgjenE|&EZ8b2e+IljYbWIV~@_$E~JbV=TTG4P_t>^|9#33O@ z7y6%~>0TTgpB+k>z+Wx$i?^9&ylJiDJSO#c9fUR1+}UapB{M(*+6`e%Kh zksPEUXdo!8r9LVE<0G&hpApw7d>5ypMk~w@xmg9cE|(ewDKC5Px7e@8xCH+IFZ1iv z?Cz7fvj5TbdRjfmoxGAr87c4RN2WiIe!o4CZ#GifAmV(pd60`Bh0AmN@ zdvw9x%hZYcMN_ElDKB`bK?OqvwEAT}q@Ut{9<2~TQk>i(OsTZ5+;x8`0HBlWp54=r zQQNCWiszUlFi+vMk&h$fgy$_0tgHanJ2FPdhB9us!}&dSssGKf~9qfE`B3;|V9# zpp}9FP{)zM?eXiQOr6R)gl|n4)pcehTFZ^C)iEn!2m6X^Fr%T_{{SHbOj=MB_#pZ@ zp1U*1wM{xMR%ha#RO=eWC)0k>tkqN^I1R)4I5FcEfGZ&=4Iw@tDQooq0MvgI)yA=v z%8`mF^A#X8r7;Z&@N_hXkk|=BzbncCLl{|D^89my>(z6UP?4I2X$xGSt!_GM=&I{l zVIVRi#9@Hi0?UCY_K=W~=1Q*N{aA3bCZu=h;mRgTd@io z4$7Gx9A+Jv^UadmNK20t_62GH6%qOMqbVBTfu#}*Q`WS@u~7yyQ5{N>^h7Y)T2cy$ zDewvLIVa20*F6vmlIf)?G9VDr2eR8~N)v#FvJ!v?V340cJ{aju{;36)-bw5SW8ytM zai2{801lk$H5SUX5u=hqSwIU`RpO8eltu|B9=ONn)+0X^gosRF&#ktKB~?z3XB93w zgh`0vU1+U`7SoOSppZ*$AxKcpLV*XrSjDM`O3N><-wjFNGm)zcTaKpYCtxE*oQhY}oMr3*?`l7c`W zCPRGaab~p-)`D=s_L8BHj1hT{*2B`b`qM7 zqY)BWh^PK_59x>GwBCIJoJjQ}rXZStfDc4vcl7AHZ&_8eL9smvc1_Ti&}FIC#c~`f~Lyo%SyBWnL`3|`9)}mG5 zkOpv+fRuoc2Td(UJZy!+l?5qBu{by+e1D%?IW$3lQOoUDUfJEIcKWdvpWC((t?Ao& zOD)Eo5ngfRr2#=c<7Xu#j@|lKV&Ux9Exz6f#EUgNgZbS^MtoKC5DLGJGw|=$EzHG)j2-u;l_2gU3hl=C|k%${M0&7?a?zLk40hs0A(-6ZSftz z^C8p)lsb<`6Xl#JXR#gnA?%gXq!3OLR6=`W)4xlX#b;OpDIk(O2XaqX2MCi?K79K6 zwwje^J~eb%53vb{WjK~lxe}gB5!nS~0;gSCP=xxaN(mj$LJ%alOz36))355Qp&JF8 zb;{YUBhb+o619CrjKJcUj-Lda6$X{-f!o)o5GD8^=;x24fjBGmBzy<>e0qxkP?_*m z?dK}#8s^-cBFcQC+lwHKg%d2~r=9!;LfV$?`%1)Co!!ztDxKP{gz0 z@U&uQWnm=&Bsdd~KIER+ACGUx*Q6h9Rwd|^K1D?-9sU7dk@#cb+oC}xiD=0pjO3rv zGJNxaf<1qSNMfHd2+hTNw>Fe*{X*MN3&#zRIB@U}yw~@7t zO2R#D@}|RfY`SO>W_=Uth~%sJZbF2@WF;lCvh#n`NI7jPN|XXr4@z{&1n_?)eKSy$ zwpm(;9wi`PcO;Sl$6@?G#C7Lt5=!;7BEeDHXS{}8U^sl7Ds2f_0EH9f^5hJ6Bjf0L zdXJq^?C0B9kQ2vRpbk3 zKk7a5I{f!aHudzlK4RfU7Vo(sO`$4KLF~1I{-1_VeB;-u3YF;y<%^Wzuz;+1mlQh$ zAJ4z2AAstB1d=C`epxOhe=mj=@gK|b>#{7k zq%mBVymQU=pue~{{{UZE5=R~E`b9>J%$C4$Z0v}w_foViS$Rua?}pFAAN-wr8a=Ef zkcTe`ANX^81;af_RsR6o2b(I!UpwUKyZCJ93pC&f1ew zNpB^$ew|+5kji{=QYjb+62l)@OKwS+Gwu6=xwNi# z<}HJnYZ;rc!)A`xlrOY<4m+DJg$zcjta58@7_lRjU4436jEM_d=h#{luaPM&sHUcb z1Pu)U--}-gy%{7+TJ`9<51TiedhSr-zCIkL-wNt`Jx0NGXS^jf!TEMH%7gT^OuuZ) z@monmhh#dEk2SX0N=iqO>u5qI1c3E!R6Tbom#I6Kn^kvp`E zr|nNzQPWpm>K9&WeABhw?zfhk_cgJ{8$P?bYnt5`1i^l#~> z6&6z(emq8)OqhzSmmP?!`n9;1%b7jOPgWWcl-Py={(hM08`8!aVGtg@{5sOKFS>AK;RSP zFCM~H`Wp%I!dK;Ep$E(bOK&%RJQBpX54+!YEv}?a^RF*Tt>PmmkzQwB*tObu-*FqA zJOJ}rrBk-9Myk7oE!Lxkow;o#xAPrHZLG{~2yH(yekh0%1w*jmzyAO)RDacN-efy+ zJrJn8w_@75k0k6|%KE8N^L6+-+ z{EPlz+bdYnxOUTO)931z4##TNbPL;tYNyMR<$P67DvcGSsX>%ABw^2NrD^M+EK2{RiNG<22EkZzH5&rLVTY2nTfvufqDzp+DO{v?3*P8%uFk)ZeXFzvqId3%)4Y(1?iw)MLNJ>V!Zc>0`GA*BkDw zS+#x5aotA6Rr|K9JBs$m_RTz%eKU$h_PF~ky0L+hw!DITyZHJMo{`&3Id8k61t52m z1;ScRJg$ zkqPN6nJ_H9g*+UK6+SGol{%Ktv>=dRE1TeGk1>|fnAD$+E4Ww{d}IdWWXbI@9`KhbedWUtM(+$l~v5@_Hao3VH3 z&V#UXdiyuJt^WYJHs&?;#^#;Zlj)T~r`*E(cYdBl(=zS$n$3pl3Ix^Hq^flB9g5_# z+|MT6ZEJJEeoiPpKrZy{9CywlU>*f&WZXxEmNM3E&D~;8=I|I-evkRX5Zx3(kfJ%p&T$w{hyUTr=LjtGD%E`_`Ycb%?X=Ecw6w-`NdneWX(g z(aR$p@7q-Tc?(*RASc`Z0GzKftQRn%uDSH`jY^6?MYU^X=j}F?HuH|Qm#kacHcby* zv*U}+o|Y|M?G486Vr;B_^DzGRG3oEkO>&(w(G9<75Zi$JsYwZB2Q%$G~0_uxTSUg_v(GI07=b0p&^gl zACJ1_AF|pmN3Y}I-4eWfx_ zl9HckJs#nj*qzq!!*(gdH8^ea`YS({c)HYcKP2)#wX0g2t2&+}i4SCf^+VnfcNf=k z+6oomLvUJQPY)a=zUKi-B?%vl1Av#CQD`_c#Dz<_#QcY(X}S*WrRh72-cG%Z$#FR` zn3LzRV>T?PcCOS#eb*M?jFi5J{{To*jG$g<>dCD$BjQW6S-ekm(B>IjF$ zi`dqUZxqBooji}gRt>ipOw=~ZT7Bb;_U*6jc87i1S3}2C5U1NV+m=-HZq&*Z(Nd`MJbI619r!x3%Nc2(WBA1L1j@OH;D zf8krr%U-;lpy{dK?zHGPb*rahq1iL34I^o&T*;0_Kq-{;He@(f(Ek8RJW>*MClM2s zszdpFr7z?4_+9YiO27M?3c*_4vzKF6n8RC(Wy4h5BQ=){2NGWh`j;HTiT;T`3052f z)&^O(WnQQh6S}O}3b%Vw)t@g+f(&aAMGHrsqN`@4~M-t-uev&iR_x=a3OR`Jc*?<4j^>Si> zX$J!-hEg?pSkQOwkolSJ2B+-B*|O3i|~S+de&q#~o3amFd8lKm@xg zT9g1z0ti=*JK$#|W78+&`Sjt^O@biLh*Ev!DX_IEK`J=_5!iPfRyocU)b10B6bRs=3-J^>nJw5<6QrAZm=KcD6C>#t13am~e%hQV46P%sWKRi5YZ zBk~<~Mxk;@u~AEoJL8>->JH1Y=(HEx92OA78~ZBA(q%M+s4XaM_ghlZl&j_d5rgTD zy0rVb!Z}2U2MiP?qztn)RL(ZPtumVCkx5>J*GYb5Y7rTrBT1AUOYb-0k>IyO&IPD< zSCX=RW7kYIcbn~1%`i%7tnuc7rmDqycA-hB{^q}^vJ`M*!TOg@aO1yDgn5zhD$YCp zeO_`pm60Wsqcae}KDN=c%ctz$yVR-eBws{svtW8q%|OuJW2~>0t!ldV5b=Pbf)Rz zND0@2DN%7~N4hbUgp8bL$0T>{{{SAG$*xjY1d>~5AAj3Ob;JOrfC9XKGCSaPB6p@c zleB<*yMCkP-~2O*J=_xx1gWuT%8)!>B?k>3d? z9l9}>MTjZ>0*ER6e;jwlGux&l66jelX4a+qIh1T!MRw*4c=G4eHtH26i1HNTSarrh z^Fka`P9+K>1f^K?Ju$C}*g7VxfN*={c^u&X0FPMnN)~{2D9OnkmxKNtX9Ad}JJS`} z)-z=Wq514JabX?#b@gg-DUkaSOG$mk+9%0LXuN=;I}ar1)O4aRR0&bKc)C@t$9KBX zt`(lhhSRIwT*Q1lv?j6V9r_o1RHUU$J0WUNz)&h7UY$IN0gcl(8)NlG?r*8J=&a1W zwvSC3M3x}6GFzdh)h1JcnC*G2f#lKsyDz_%2ge^D!?#O9 zi_vZKe1NAa10ee2zew~HL4D(ec_;yue7_&a{{WXnEc9CZg(yJsNyb_PABV>WrV;=( zQLDOQ{f%^akt-z3Wr_A7_1D)r;u7?PM+q+$n^E#wTMHgo9kMghZ$u}F1h_&|f|1;T z+pz=>=j+n3b%~`{!2HMLK3<^*;0}BL0K9Z)vn@&yj}S1B3QuqSUccqglt+Rfl}7C! za-1`#ZFf3N?#(y*qJ?pqx~s0ExU?}9EtE)M4!Hso?FB8j61;h53K{CZhD19GtN}Jw z-BsN+-`A>^!X=t3B|QSm>6}ZYiHrpM(cTHqgQ)TzNmp@^o}v3qlVNqLZRt(gwXtOz z`++b;qNu}&5`+~xSrSV>tJ^LDpDbg@W37<3W}?~B@{pGS$nLBZ<0B_IAMWZCAzw(4 zqE_qvo2&2&7$`$tM>s#0KM%{UO<5J`cJWk};@i?%dA|>s1uYLK;|Dk=BzD0d_x$?i za!r?~ronkV_eR5R6%e&LxX4lz=_CwxJ%^#jG28I#)9ldhZ0rBj^?GVSWRv7bcOE~$ zf4e8I&$9PlOVK}ff`rLRjF%L=e@)c*Am=__o&Nxbr$p41>_M`QNQ7k{6?nF(znWp*W)v*vo!iXUQt@z!>!Z0L!k3LYJ!J)SXdSp*bl)3Gq1#J;$yS z+tl~RT^f8BE~z-KKi>JHkabRRG(Wo5LgQF>dd)h^HLTjQ+t+0czSY#GCJEKDU2)_H zWW-Yo1s-d{lvD2LcA9e01-|Ac`;EXMjCa-7pDD{bn>%!%raaYgyz}PqweUuf6*u*i z`$sDAA0u9Duft(KQyJa;eh5sgEyMktMSUrk@E)Sz6RXO3DE};}!HSLY$ zddQKDdv}|3Dq96SxR0rj!s0%+7*eoOK4len`5wWe89+&hKXpI+L#Z`L<<$+|zUVm$ zS1#Uho{MW0&2>BEt#T&aQi^5DVVd1qzR~y$zjZD(dgM7WQ<*L)N)5EMp#@3GYWT*4?5gcs?jM(KIT27=vw>erSIHIn7}F)aM#~P> zDV9>VOG}aa(&oIE43?DJe#t-y@G0_eKjM$$asJSJelS%aXD@du)BBU#tu%gP;C-Q6 zq|IKEvs&bdw^gk&+?aC>Z8H;E_ak90NLVf9Ew;3*fS`hvD66BT4DcY2^$&F?%1cx? zxb$54tbNn+WIHLfmm8E@2rAd~O|oT`w4HVL;zhdJp;gJkBUF@?bXTx)*=st*27^QJu;f zUfCOZ*x1%9r^Vja1br*1mgICxw=fzBNJMtsaq`I@C`W?*71C(wwCl#5Th54TF)d-Y zwO1AI9Itz$a)%{Zakn?8mHzSKp4wcMEY&ud_c_tlLJP63OSIHwr7> z#LF7!u^~x$mz`P*k(=@H!dLxNudYpKMmm5B3O?Oaknw(NiZ{MdpT2#%Y-yR#GIriT z-}EWg+qW0DSrPVit2kCLK?(Y1ntHJ?UQ(lbQwxSlfFlYDQR;+DW?n2Dj$x1L;Vw{F zxL3<&_*Q2t+TAs>-*9In@=b-03)pO0d)v1nYz$tjA|MwyXkSsApc z)|8g~%Vgn6@kkJ3nj)?4$BmI~`^fhS0juvkla&e_hmLm(-XgcDi(lh@ z-nD9|wDP37>_l(HQ}Mzx0FT^jRo+tIqQj@+~x|$z8484ZA6+fiBKndtu^g z-4C{pre$+KUxEE4{{R?_j!^X;0EhL)sZB%h^en2jKIA#x=T_tEn?6xizhpS-pJUPI z&9hZ6_dV3flUkJGs-n@^e)6w2*=WLP#!3=$5(>kK#sV%Fv&#+KUX)BC4QT8=H!|-} zym@TI)p#P#?`5;mYvS^yDz-hsjTw_!8T#8MWIo!~)Bef_yW(9^54Mt5+Zht=EO)oK zDsrKw)GL~Hj$XZ9s|#47<^6(h94mFVgP`**p1{3zt9rW1h%c>)n-prPvZSrM885RG zM_?*gX-O^+-dEBf44tqXS>KlqR#~ZA)k9!&KQC^4aanb3$rE)e3l2Tdj^(u`JgW8) zJ-wS?gJ#WzoEVNvs`{3rFo&e2r4|%HQ)mlO=>9MX#j|nT#j)6Wr8uOig0F2v|*0k$GdipY}ElH!k=l&+M(F%-T0 zF~oCNGucT$?msq3`;uID_X(7{Dmf}0MPC@nn{cmlOOfm!HEXO@s<+!zH7(W8Gd!Aj z5#~I7qO*j58{omY^XG7yAUkm{j@%bQecH?9T6>CpkBVbUcWkNSJ@pmSqO`Zy8B3L~ zDc2hCL!`Wx5aQZMN|aQel?pw&T?Q;SOQ?zWQxtc^dxgk)F2%P|X!kW#TlLdFZqauw zU5&$K)TLk8O{%Z5O_TQ~zUs~dS>-NC`bEtQHlrLk>XNj1Ehw>wGIsl$-*)zN#M%5j zy&aTWWZm{%zO!xDYdH^R+5X!bf518^fA|zXIh@Z7F_c^`3?+U@q!6LH;cw;e}=-n8Qy@%xMjR(DTZ zUdDwoU3`?ZW=jwokKma|@>%xXTR~+woJ0u&49BB4h0{ooEmj>})E`4{lXkUIYjoU+ zyIXP2!Mo{D_PLc4HwL7z?37uXmd(BJW^-QaXlv@(V+}H|0+QO*jlr#F-Xu zCinjUt~(5aHKn-_gv~^678^b)1qvi}IS>mFGcn!4tw-IxRL2o#>0cJ~R+hD-S!I!OCbpZPBAc$ z4P2+!>18~{fjf_=_FH}QD}SA_E*_x=X^Cl1qR6r1s~T9lMVHm=pHle^R}4$~LWxS611F`(8R$OHFt}6$?i+zVSSuIp>K7rk%2VvO z>iyM?I?AHKKW}VZJt5>)P^NdBmNo|b5?Zl)0MbA$zb!5?l%=di32VqYhk}>5%0SD$ zy#6Z0>)th67vK7X>dv*rzQuVvVEn>seMjXmq?i#AxGff?nwDHOH` zA;uKS(ua|NpFn%{Nqx|ZHMiQQiqIRtzCH?w+4%a#j#naTsN-#+twUnx9fx7rtX-qo zZ=gK_bwp>W)~c$>Fy63B?>OpEp&=~BbtCErmw*o~L0LW#YJtxFms$}tem-yUiUCu` z`^BX$y?453e4qXAWx=+ZRLz36zGHWcN~hUQV>*}L4Ee69L&XbwGMn;kmz3cP=p8^P z2w@}CQ*0IyCC>r%>biUF$6n@GdaTGAs;c$q5i`E6bQ;{K;O*K8Gs%6ro zIG2#5IJcWyxpknF{HKe!5GJ)P!u7o?%r~0oi6o7-@pag?t~ivb#Ec{y`KaU2=LCNq zyj@aPsh|aw9k|IVk1ezzX;}yO2GkA)PmT!mJ-!33e8tzNr5Z0Ve&S#$=1af_7J^cg zqzovKRHb-#^z#1zKD|!a((AJS)%Av3UQxg~0F<8~I}m^4+po{E9;@kEQfVk;w5-Z` zC~Ucfc2LJ|-k&J=@i7Lkxot~=+e#eiJWa#Tup7;(+c*;UAQ8Z8Z$=T4L+ zuWpqAmCujtlkJw|DJ5XH=1M!|J^XQ=yR^0ElP+VIbCu61M=_;R75p#6mG>80Bwi`j zAz$oimfpi?nwWw_)L0;*QXX_SESYY-v){E!SklZIB&tYDbAH$noutyMK`)1Dh9juH^(Jq{@gA?h3J+Q~JQcxNQ9zFng2+>(-mm74IEG@Rs5}=|8GoXDL{HH;>4_|jT*kX3|h#j z0jN+THijAr8CQcXpd}*!6NHb?sb(YS{zOf%CN4=9-{~G>O_~N69Y~QX5%oA zZ^4$@X)Sw5Z74_yYGbs_ z4m{8$=oG_K*L6)gf}2Rx;6<*a)1pSMtEFi{W(;ej8{6B`qKXc0jp~g1rdoNirz@)cAl1N=J%ul%x!I2drepVZ}msy%SF4`d2l5x*4*C7F25p$&E4i zQ(;VCmBy7CR5w|X8PptL0IW2Uw<=>-HHDIZ&A|5 zV2hw!EGVpzf(awCv7X4hU+xd@&_;oOGD-y*FtGKDXk0wn$s}|9t z%#~jy_^zeYw<;5=k0pf^6XLd=LXfojg#r&vCloG?uu!|+UE?iI!s@4C-Ri0Bb;fJl zysmxk>cvI7{{T%~9ZGUSq`UIAkJPVFG2fg-vf)<5lVxKim=*9DQ}ZXuaV;{-O(dyqIO51kQk0C6P5|gLkw;4D zZ*{+EE}_Bgx@MDl_IP6_O?WoeLAZ{KU4KU<30hQ=jrG=ISy>Ca><+o)}L$FcA;tg zy=dK^?T<3Wi;bmWEv`&fXEWVt0Qs>Yw*gK@73-YipHyY0_0b1StpkhlK3*v)!doCH z6yWwDU5-H`t~t40j)MTG4aKiH%OJ zO!t(Od3iaMf!oC6Az4mwob<9MF<$P29Wlv0h*TR&Bsb_Ve1A|${IGNUM^=GrsOsI~ zQCQ$S;(g+>5S)ozunM< z!KW|Y=O0kG^NIPhoLJ&n@^y>q1<`Ro7supV2R0ZI?JTd%%PZym8f6Kr1{!iTazY*O zaY-dVDwEf%t=s7xRxkHV#*D$6hZP9ULNB@?^VyX9XXh?ZrI)ozg zje#Q^4K}LkUSj1t{bz(|H~kLRU1IBMv(w<$Y&L0jT_a5FwoswFFS6q}w$j|6G!jrq z#(aB@w{4{v6POafpD#5Tlb8%0QE&54G(zNI_Ux_eT9>y>*&#q2;+jCzSg>W%OSn`u z)EP>SY`miTZI64vw6v_F$YAu1EioU+)FR$3%d6Qmi?hkaG&&Pq}Hl<>dLK|kKHE0n&;k| zB1^8J=G6ZH*QpT_(tLlV^9AJi^=ausk!t04^Y~KScb|nXwfm3R>8PtExh}fG{oZfb z^l$C95Z~5JrKeS+&BkSrqOkF1BPZO!>_V~g49+?Llgd3?>Zu?DaRRsD{qW}C*e5EW?>BlX&}YsF7$O`~Xc0Zab?rS?!= zKH8mm9_N>W2UUigOd?3IJ~eNun5gmk^+xn=dfj1jbypbeJcm`c=(QL7JtXc*ax5zJ z**gl3rs6br-i}ilG9j*8?YZpurC~oZ0+Oz_rifr${j}Wg^guRJabxN}s-So7hm+;e z>KufgMu`_tYNkD%+G(Ov%pMXpTL=i5X<0FG=g5NmMjCCGDxEGR#JIJgU4h3!BQ#qR z({>ca)5HQn-rH|oVfQC>W35f#t&*k!?&neN7glg;QJl(hCXcc_(*O^fE-fH-@A!A> zS{hl-%+@g>iKU+&4c;)+Wh+lqngNwCS|_3>(Y2`o=2kCtSdW<8|t&YEv;7 zlGLYTux(JkY4o;SQBS$!U&9Q*w*BpFai%STr5U+%+j8xW1>}4EyNY)!J4=bTTLzhN zc~rS}%vFhustZVUrliQFb?WJBKyYRF-Y8hcTSCH<)PEQg5pCS7)h?qmu1Sr&eZww+ zi)a4e?aYTh-j~eM64f0OVBWHRNGKmbd|({m#?D<)84jb6Z${qgzV4b<^J2eEkv2EX{q1KzXcCifWkZV_G6vA#b}Xh7ysgFZoQ~rf+zPF7V&X|eHW@?J<%uX}GF0Nf>O;Oq z%=oA@;xk!}YI(W&OkOwgLfL>YrAhD&f-2QnZLuS**A*Q8lC9vx5ujAKC|Ycgt8n+Aw5q{EFGM%_x%&<0DRB4)mBz~`?T6<(cv}CSCivMvE;dW zp8o(k?X69#mMHC!3YE0Whgm7>2~D8oxGXS)zLV}atazuYWEri9vxl{oQum%vwhaJ#8{2qct!ie&Ecet|d7s$nT=EGjbVJcciq^*BMR}p&@D* zUBRpmL)7A_ka$0}7FEtXr!$YXL#}T!tn74%{KE>0`V6P8oqrEX27-fy)oW!9xLx8K8$Uq@E%zoJ!HSkz0KJ=<4NB1Jn4#+6-q`kM%C z=u?6NXz^MWpKz!M2ZfsZZyxJF2j2T_xktY7?`CN>EbE#zm9~uYx~{{v(;^ME)l6$W znryP-ewB(CkI1yK4&`4>A>^cU(bTUb$?a!$U|=e*ld-EFqRFDR!e1KI9`_zvAQ2Ac!^mg-Ue09COkr4t>J z_iDM*c1nu$iNuIlj8K&t#oTyhPk+plUk0UD_6xG=HUs=9a3NZ8T2A zb~nDaOp7-F%yFL)tERe}uUK-cql$ zx45767PZxkO{PGMJm105MJm|eA;myZT zy4GqnoleGN&+PqkT~yOKGZyHNWnPI8)Tt9ky7HFNPmxlJf`%9KcI$$1ltbAWikIHF zjw_oIIaIRro$cSb8Jx2%y9OQoL(AGLPp6kvEuG}wx|ZKx2H%P#5;!pPrreicaV&m(k27(LuL_7%(XI7F$cwu* zX_QtcOxM#Px@0hgMXvaV%NSvg;d^p|rc^N|H_i z^f(>!{{V+xPN3esKHQQO5x2IdBRbef!BUill9Sy*C)A(BWFO!^F1ZL^wvk?M{lTq)S2q7Gb0E5IcL_>YgL!?t>Jb?rbO#tL%S2};~r*N{Oy{6Y`&_^2=Pyl^Ct_(rU$R$G25%fg#zQ7nxidv{J#8ic-(@)dHZS+U3Q)t3N4W>h>LO=io5IPan zkR$FiFXFVAy)J`nd=bL?lQH9Myk|#t%T_WiSrTIBGbOgmG9FTf3HMuJv^bJ{R+Ips zao1jtb2v3f!){6wgSp#cq+FH7ddDbfku)o)tRq*8ZB1hBPt!K^S6HT;#I!^pVSp{!tBaqwK`rO)b{HNZSA7f74OO!02GbP4l6aj?}D0i{G--pA_J zl>((aJX41=<}d(OI@QjvWyr zw-JwUG?e)km}Rz;pF|}o9f0Yg_cbbWo2ti{{@%E^nP6G}0Cnn>irMB@rUWhR74coV zg3E6u)QGa3ZA(cCPs`u7PBD|$Om*d_yo%8zJ=D28Q^pC~o#Ye8TH)Uv_TG1JHIa>? zoMAozHoi+;+9FtgF zFMSiraSAJA-TD2se7Wz8^@QXZiUgr6;=VF-SAnEC$C}f+U2DmeU#Kps8mnWxg%zd7 z;wisrDg{dUf^(jLoSod)ZxqD3bmtrKTBMgM;we?d)q9KjJhzr| zznl7a@88#>oSF+PWwwUGUn&Q`m{xkB)RB|b!a!)) zBUIE>RJF0`sHtGnQ^X2tB}^FYMvT%)IZ7F6DL@3C_#Ymyo@=clLRmExNkC<~xQK7* zzKJL?&=d5Z7BP%_WPhXd=i$+O1rQ|Mp^j?0lC0NdCtas<-eXLm+3SZK%5j)#3S=q5 zk2023;!p{~PBDXyj7f;9&P|i)I{hVt2CHmpAXwK%Q*J|pE;BC2X-yxHp{1myDo4Wu zx5J|nV^^vYE{O zN8!->mUO5EC%>k0G5C*hW80Jb9`CnvD{e-8QU zJB6Jl6s!zq<_7?rd_lqK439TOlUB@^R_Y{1ODqwTtuFbgL@4|K80<5g^(dK=(hNDO z%Pc@KE_oqV)*8;L#OwQ+b@VZ%zY&W&scLRAU3u3L5+Yu8UOq}v+(T%|^&umsE=yfZ zIxwf3VW%8@XlYA+RuQHv>6x08GWs1q zPbbURcmyc?j)W`0eu}}t?0PzmjA$0BNJ^BF-T@;c2OY^h$L4zHD&V-fjM}fkwUvb^ zlYpPgxW-8SU31Lu3((LHWkqdid1zYJucu+exB%~uAN^?nen9uY`1QzS@?O4>V7%D- zgG*4|eYdgf1ZDJ&-!e**gsb>>?fG@+cE#4!vj5QamPu2Pn<+^n^JL2=~1 zkERrWIb`AVtC^z)DJR=a0>mtmo8r82(@G z>ai*leaM>tFT{j}fULT|F5Ue|9-}_Ky;d=Lu33^1hP!y7A1j0ow4T5pWn;6^v8^iCHNC`5{33px}CA{CeusdWFlV z1qfWP%N)Zx~O4?nTnKsIs7F@>TK`|7BM?-B!R$X_@DZ}6b zKq~9k?R#B02nmw&EE@{7d`k1@tbXDw6?G5p(~zxqG@5NBNzf`U=ylDGIwfdOtF$NfxT%V%$?;+Asl=d?v?*vEbVsv*(;s)-L6yfEW&PM)G^BGHP!`(+9$(%+ zC00AOSpLCBds8b>*>)~AlOC$(6=8Q>l^vuuZY8O+cxt=Sr5h ze5%$c6S5kw+P*R(0=xV?<7aeh*+z%~re-3bd#mIY>nYC+Ni^a3;b+(s5wVaqwKzd8BsNKf>ntqdi^K2nq=URdh-ngT?C8Km9??YhY3iGA$;h=#xS9rqOS zuJnnjfe&_F_JJCb`)JjbOZ4z}IdkGkF4M7ZDbkhfNG1I6 zYf(}$`>SVVbZ~b#@>a*p()Aud*rGpCv#V!1g?w7LrlsUi&-PF$Z!6`=FR7LeCNn*@ zUP}9*U=;KbtdK3MVSfr}0|>$epn<$g)z7I_1a>vi5+)wqja;mvNFVUrtXu4-c! z;?Z)PdC707)IP*E(;X}YMM-nrDmgex4jMs#zGvIzBu*q_x6xCTe{#Izb;|ZLBSrQ! zMtLI7k66^@Gq1*mh|rsT4a`KhZ3WAd)V9Qs*U@`RVOR;r^?IbVq5$3-eO=xPkYhN4HC zDpN9NJsKa?$w_b}Qk)UmMo)^?Ql6LbL^lY7=gBNX;d8KD`zP*OlLdW$DwpBj@A^Kq z%36e5Res*{YHk+Ss={u@ScK|p)VR^4`>qzRM1?|xyT7b%B{+(9DB9cXzlGY;LWI)HTu}jHn|$;l80Dr_R{j2ameLq7+4BY z4LG~-;@9)~tYSS^R916bi63aL^IO{@Bv`YgO0r(ms$$v<=;(2ueN{q1M`zRXAV2LA z2}_>Q3h6ZT{`{?D=%+9qoE1~{O}p3|{#@ayHll4e9Wh05u0oYQihSr}U=tsm9IIW# z7T9g}!kT5UeT1wx z-82d=Rjt&ogo?{0J03E1=Mepa)hTMZ=b(kSUMwUwpx4Y2e86AD7h}AC?KIk|lw#PA zaHV>u+!rcp(YC$H^L&rK@sAbF)@}I)NS{Tp+9HnWxv=dNxq942A_PTW)7UhG4|q10 zQoknD-$VHElz_yKe}#zvaCHvd{^0)L8gi9;2IM%kyM8@?lJ#QsjSUlPk!fc+aBHQT zcyd)as>le6+wr4>zNNZUr4pv_@zaZawj}um^{GLIHx1{t7h?Uq?L3vfZrs6ty>1S_ zTdqx|q@vIwL}7}^E=<;`t>-=*Ty#uzW%+9jhnyY=$WlCy%g-iZ$@!xwW%E53De}J| z?|M%+a=i|@eyulH-MKocthTW{ z*J0{VjX-->&?A+fbGweO$NQb%Bl3+@bSsALt$5RA^NObKF6%AsqA?;9zfBbrr7Aih zd8LN^rxk}AN4Bs?j+A8~N`zGgB`9 z_GE`#zt_LGNkJr(o2C zhfvz7LMEWxGdQ!~mt>Fl|_&ysdMw!co{ zX_uQ!o%&wc$<lyEULz|qsPl^RlUZnZ=1E|gR850+h=h@oQX6wGhe&e)XT7AYYxkD z5!fwTi(xJw*P#dIJ}F<5DR7R$8ip|vEFFgJ=MG8Y9FG<0m6JZ>YhU`76_M}-KOFop zdhzBStGhx>SyEd|c#iXLE5U>y1mp~nk_aT{7(PkHKMuIq;=O${xp{f_KOz)JYHcgZ z-*A?c-~^wSKA#Ns>(T8I*EC=M(e;)>f?*(lJc`>MnMfEQ=daJij-h=cOg^WYf}xZN z5)|URlw41Ov-5fZ=rBDq(EvSHv}AIC5f-qg3RCm9-}3B8@A1cesuU$;LNOTxp+I_i zcPAttPT%e6)5NZQL}`qVB&1~t!a&FRao^Vm@cw;uM6Nla%%ue?$;od8SV`^NC}8*X zKjGIzYPn`h^F`QFLRLU2?b`rIQPx&$I`dl9 z`*Z7NxjBfadBvnzk(ufRP7Zt~gg5UW_b;qfs zOTCWUJFA_aw=N$$9ZuUPN@`8*Fs)k?9FZh4?23j_8opeJNOVPhLkMjl4!F{kFfe{m zfv4PRh~;`$cb4`-c}aX-(lI{NKHi#=<%4`{3^-Yr5h+x;>TRfV(nOeyGN}a&$8*T2 zvV^6-FPq260y_tHt07a4#d4VCpxmtM{vzXz!bIuY7O4`_!qHU@*v(R%ZPhtK`?4z3 zml|3WlNr~XQVK{vI)TVI>biQ8V8+0YH8~b1nwec{ddANtqF%#A3gSf)r7ob$Y&sY- zqd5vl306`=(cN2W3Ir6B)uXCFV7bUuHFw(g+x;HBufHc4587XoXldL6;!=_K8ow3mw6+n~9c<2G zDEfl9kBJeMw^mfOsh0pKDkP(@P6uw7>P|)El+3dudoK#{F6#!~t8U|}Er!1G)fd+B z=0k1Isk20O;-+hg$CthAG={vv1fY1H-MVc(QVuj75GIPh*M8J^O0!U^({>#bU*4*9 z%ggJHRg0>)jF+;9uL1*?2?6H%#0IU}{TZklV zy5{F2j5VjW-9jvQI=;fX$mV1i@j*mpqqpljP*?yl##t=!vI#+N1v{QbaVy6b9FcvuPm9C>&3>4c;MU{C~t>+kzr#;e^N zGgN9ys=7DDXSG#Y*z|qAVq4WG5(PiNM!;t zWB7P`L6AH>zaHK=#yfOlEy-j_x)ZMG`c|S_I9aU^~F;@}{c3X_g4**n#P|`vWg^Uss06!kEAe6+Aldsja zU4F6ps=5lQN;zwBQtIMFj}{|~k@C6jG};o{iO)zPHgr1JCC4EwJaM! zSo&mEePm{&eLKh)ORamUSAvE+DL6e&P75L>ihhXfHn&}El%a2{&O(ro3yZ){l8F6B z2?M`;0n%p07bty%8fl4g4V+j~S+@Befhne(Otl~dVMtm?aG@#Bp}-%PLos)DL|JV0 zU0jc%Zbe*K2(CVG1I!_5j;|jav*ZXy5^?h5w{C#cB8-m|uhK$smt!s~PDXST$YE`y zp-3t4@lr^_hls~<`E&%4ldT+GeR~nxTdY?`Dnw{WB`lyVWF@wn2gGGZ0Vy87gROfY zfEPfC)7lqbNW<|*z$$HUk7_0KRsUWS2lRZ8utX>2WM^YH;#Qc`kKQ~3If z`u_kfxg{V?7q6rUUQGScw8QPkX&zx{aZ4dY`4p%W_<(%~@9X(>==O9?+}VHs()Ee_ zJ6hQtocVmQ`hWmrkUx)KpDsABq{HpiJC$yQA9-LUXz(8*^MF7~aDOi3di8-Wz49oe zFvE)={GmhulmbR@52?m6{5rfH*A}Y;akPY#C;)_@50s4L`VvR;_;t_%vW zD+=zUfrR;d1`kz<4!PzEFv1grxS!BZcK$yvY#+q+(Fo!fB;;&SRtdmLN0=!EZjXT& z?nmH9e!8^I3zmEODg$ffZberiZJKu)>U0+IIKHl~+jf<(SiM@QpSp<-GY+|FZA`SZ zvmI+w(nxPAN)A3{k5f-V86sv#%CTGgcKb=0va$GK4td(Po7EoAopDJSQWA12r`tvEXo74m)UT;he9X^N^Sc#d(EY+~6Mo&f zbCzv26hYfKmLA3(uayqQt{tP)aZIKqH4@3Tr$=H+RGhZze9(N8m3C2aqZ6x;aO#$S zXy%dSKe$cHR@kX^9ZG_RZPv#RM^qU$?no@ge{Z#yUgDl^ISVbYh~8)e1xFy9cLz^M zWX&za`8Ucr9F{gM>+qzSmn8BA)y5p|&8O_OT$9CCTL!d?iq<54)goPeb2DPkYAdd( z=F(Fozb4D7AxSt<9W-=f9YGs{#Y%FZA#u%5+^;2Y*9>uA(z#i=F{|hrrpw6frn3I- zY{hKL4=mVRE>Vw8veUle7a_;g^2&-CZJ?3WhKQMwv$^u&`X?;);1@zh=T2#vvbkgi zn-`DX<=Z|asizR9yKU|^x8uXMkt^#E$?$o!mm{U2=8TZ)6@Ulgi4?#Nt@D0~SPP1f zdOye2bKM5X_XW!OA05V5ELLmV7Zzw~V3r) z!B=zCw4x;D;6Dso^+Hf-W!lcUBFC8d(?R4eRMAiGYK-9^mH1%KOG-bLjcSC;Gb-j^+;2SB zax3+bYn{E+^c|;K(Kc`?AVY(4{hWH^I?dZ@Ht2c_sx!Re$8IyJSV~jmwKA>=x#-Lk1LSCAkecgYQF9+)DmMg{i^w1ClM7urwSS z=Dx@XyN0*d;UT#5SKJj0dD?_M@rzr&KHBzr-J4{lrlxaYw5zGCtg(kIQCLfh9o85& z1rxrFVgCRC+L}P}Q5G6e9xZ-2d^(t7AA-NRpOGAMj(*>FnxERQSF>&U#f3}g#c4O7DXZ?LW)pUrB%~|Eb-(~Y8_4Kc0}u%tnM-YU-Ls6X zH;yyWHtBl(y^kYHWpXI%_2|#8x{pcMR^zQM`PlUJ>^8ShrxFmgc#wu$04YhHP!9S5 z>$x%egPtdY)dciYJax8;AhokvpCU3-}Z!+Xm- zd#P=4t|n1cvds;Rmdis|EihxS%V}|i#kN<;Ah@8k1tn?Eh@az$0$lnECk$LRAr;#> z3z4+$MgGaW-XQJs_}6)#A6w*os-6*<8a4aec5vbziv-f4021yqmjKYj0l1-`TL$ zFDxl$Le@nLS$Wtm?QP&-*O=KjcVQusz zG6TeI$z~1@HR_Ul{MVC&=j0&doOT6xj4!A z_UVWW8Exxf`iJ7K{+);8-=e|!rNMkuLa~8?oU8d~x8v3zJ0b-VA;h|d+(AAIPH;g7 zx%>zOALG=+NIGK^5+|4WOAcnBanuwe`GqMe2vXfn z08vsw#!qrOXs>EdUFt&8vVeQGoPm&_KfwM2t3<9Titj{P^9pH1s0=5`)pzqL$iejN z2|t%s1clEgAfpT%RAI@rKcah!Qz5)Mco6V+e|kWrHem0NCH6UID+bgh?WsFfzdTo$VD zj0-u{@$KM8aZfW6);verYHJ8u$q0Qa9n_!FR1c}6+)qv|6H4GH_=AGuoIy1SxchkG zhxT{(DH_y?HV;@kYN!Unf9)x>eU(Rc!8HN@0HQ>a(u#fLG8dEOpCg{B4(C%VJp&5| zrGYmfC6J5#ckX@aQ#XV-uHRgNsL$2JstTQ1{W7i~l_|ByqmW{$$jNmMrNBvq!47$Q zfS?qp9OtGT#G+_%e-+KB3A%f4!klSytXgW8dg`Q9UEH&=O?T@iB5&_3hJ$u3PfN*^ z)P(yeA=Ee(ocHc?Pt7o0@M~eYNC!NTy<3emZCg;EqEqYaqg1mKP2FU-9h|EbS$T=B zO@30{c0-T(pK)%jN>`?RIp>YCe8T};$wH+j-+Hs(@R ze{h#7J8@oh%#uM0|V2o`6T&)vXchOuvJdO_N(^$w;~gJ7a7;sF#?(vzRV!} z#+Y4oV}8^IpJk`e+r}ym8F9p^ZTg`=j;jrMj8G+65O}vjtb+=&9<2?SRrmh@-BB3% z*Wq*&SM}vLu`bP-eR=eb|)kb z!N%KZ2}uLc0n(j9ZAvoPjypZnH*ouR;T`5XakmaKq`YYs^REZG!ApXDr-`t8+-*o% z`kw^*$CsS7%*Cvq zbjUza0q-w79_l?bb#*F9+r>19aLT}gp=mWba(M2)R;`Jm3fHQCw3>{80Kj!BZRp;> z9tAEXXUJpb$Ju!)(M-&eq{of)Bvw|_CrhSXJtR4>YARO&mB)`3#RaLc z+G$DgOL7pRmlKRAb~)%7NLZczC<6CF^-dk)-5R12kCXKF>m0=9kw-lkEj6AP;q5*%(Dg1Z)pe+{Y~$R$61Ju!WGcoP zCN!@W+aJ_q{{YKS?vM22r#gm32av@)*|?L7cWCR2xN*j}v_^i>H%~{ltBWlQvJEAV ztRdFaJ<`$=g1^*K0!hHfS~HM0H9`6*WX*n_&4_WWDPT{FTI*6O;mBdPTa5E5C~d}) zw2*}%Dk(~m0RZ52hGG`Yxi@o9)ZT>}wf$nD>ew}_rh@^~1s;A5uFKv~mvxZ93cF%=g<*CVP5B(()i)k9CR+}G18QX9ixD0$=u90RhJ0*}ly z(q}tu;FuBBpx`<%iY@)g_u$dJ}2~!dz`+n<>XK?~ zlsFVc9oDti(-F6*E1gUj=!pd@h{}U8+FNe6%V4ABLRQig5<3Evk=-MuVnV`1C6`4? zdDlV`aZu3 zn#xjUS=2|Xh}2mU5Tv-5on;M#Eoo9hf|Lo*eD$R{g6~ya)jXX?DX z{r>=Mq$NJ*kP7q0bI>v}L>5v2l%(JSJ%54d1{4T6D`GxUkUuPE{yjM-DW9A-; z#!pHwy=S7sozvWU_a6`Ub*CyV8?T8u^!R%Ebf!e2$-0|99wkKNliZJ&@)!ft(>+Lu z0d(S3Ulb)tDGK~TiTrw2rPj>F)}GpbR&qe>bKAFWfQu%~v?xAanDHIb3Ge*JQy_wi z(Km1uKyqo*0_Z6-!)T=2}l%Zp}9tl#24W7#9% zI=IZaW&kM5YjG$}6Z0(m$F^~d3<7^1{d7h}mmGj45oiP?K_OlHdVD&dfJr2_Fp>s;06)*FeljAF>b?pH9wRyJ=rT|H4xcC#1!i^d9mpy2 z^zu>lJs=y_Sr1nN=L8d z)nXX1stn<52*|<5{{S|B$EO!cx5z!SkVrZFz8w(AGbGi3PkaD7{{TMSDF770t8#t- ze96WKr%cI0!BHqzj&cD5BmDXYf-O~)ESv&6D$D1IQ)NyRA55PSI6Q)Nyl)WkO8@6vTz4(;CAaU7C@{iNkGb#;sEk0J%9t$lhG?I zcI;Du@yFxRnBt1neeyDWFh}v}CLIv9?3ADZgZO9DKf|GvFh=EMD3kaB=zjs$S(XEU zdEO;$Hr^mXN_yONP4~KrZwFV2j zx4P&3?Mjf`k7dPxf>aQkDJmn^Iqlr~W8i!B#$@H4dzvAF^C#|7JZn8_-Ima#wGE); zWP{u(I8u%QBhX{{b=}$0Oq;k575~-sjzeWonr$lb^7j0(+u$%s>+}8|OX)gtZ9-2K z25l;FNIm`1fR%jNBMJ36#($4)j6o%PB#4A&H;_l_@>j|{ut`1ptJgoDR)rTPqdG9j z!dnPA`Mi8F;oI~0k4~-^B<@`qY>&kGE5FN}b^w#x@yAz!vrNgsg}%;`<}XDhI!Rhr|8-bjNb%oJG^t+f$w?Q3)Uu=lBd{etmR6I*g51H)U1ZRQd{QOB3Wem=gPK6XPZtlzlME!aUv>(=)NI2B}4Kl>0f#k z!D;~WE@wTv5C{35fF<1$Xv=h=BPSiyM}Ln_;Q~rfBr7@WuY$3Ik6x%N%`39pq$puS z<@kjRj;WRJWF42wAwDX|9r5^j^kp1Y8j*soK$U_*%8+n|0RyejlECB)g!#$KmVn z1L4+nl4|*Ie0@$o4(F-Jk%C~gBLL&zG70$Op;kp>Azv;&Y<4mNv%Fv@jdg~@WIA$(nvj%M6%U6?~MNd zQ@4lV_zts@5htmUc$zO>LCQ57I6~L*sRzX5=Q#fW%;T#^isaPX z5r)Eig8V{)ls&*P<>}mmj;;U&*CdH%MLfI-B}+>DKq>8v{1kp4pH~zsnVmju)f6Sf zw}OG6ERR5NGx>GV8Bx?F0PIR~%8HegE9YJZkxny#+>zB_T+vQpg;7RU3QKGGh);=g z9gckm<=?KDoC@WbtAzEE5JEDfxRnn?A3^vN>yUcrfNFav&b7mu54>_FiN(}O*trL1 zfv3?I+JuXHCj(K$hqLXq=0W+Df z+MV~ln8@??z084vzXfCQ$6ZH2!jcB6B*@is?#XY+T=C8PnZ$Z`C|vOFhr!Tl2Hml0 z?L$@7#r5oUO=>bE&SFX<#)lXoO9*et#V;N~BOP`PIOxDghm@m0E}N)s+O64-qOpqBV@8yTmXAem$;2bUkfHkiafgp+CQPdr zCAc>8&WMuq+|TqKP+PyeU%03FCe|GmxvkgnwEkLSQlhh+I}+HY*6IHMeA$-kUqZ5= z>@noGeDfW7X$e{R#XpY>n7&cxBTRO>05q7j3Gy3zE4%I2?|5_HCs*n5bjTI@?%PLc zeWqF0*}Xo>9D3*4Z4KYWR7P2d?53U$HX41bPq{{YvYYhRk|t%kxqNQ$=1MMtZc!c<=OJ9+rvj;*KL zftU)&4zjg;cO?WkdtbmJ`$yka`=wJw+IIdHfdZ3|^lMGugzF++J0{j!P~|{k9BZ}& zG`A6RlVZZr?5*DwA8h4W#{Mj4P-x^ISHA=WDUQ_Uo!9-}bF4kd?SFCMeMYvQUF4l# zj&|wwTQs?{6E|vNG^W^q+N+vF&et^~%2`^_j>I>dd33VSj#m#zy}Dl%zyewBTkB<8 zRDI|2#ZH&I?HZ1g3v!{>^?P1i+V3|#iT2eFrpo%xJvBveiCl7I!-5=)g@BX=0Hv$3 zRfd2v%6E}Y3?BQ^&6)TPz6#S{-wovMW72dQEjo&Ry|V3e`fSF;+43!0ojw9)&VTA7 zLUOTzUcWZnj`WcsUfR{|pkt^V05sng2h66(0rTjnJtyw_ni`*`-EOtY+;29eY!@77 ztI^t+6_Zi3Y^`fLwOyNPgr6o`QxaclK`K&NL0W>`SBSLqVjZXful`Y9r~u=M9;N*i z`hM$q$ZsF^DZW0@Y`M)l*Y?7tMz^pU!fOV)je+|T;-h_7R8+d#PP9>yr3?||I!Si% z6(*GGTYm>YR8x;n)xFh&NB2>++AAsI*#;6Jy$6396Xh+Lx2-XAyXJeSG3?c91>E$-iFdsVE9 z4mQPksL@wxRqU?X*_btPq*$#}CE2veNJ>IfgYGyy2bJfh4R`@gJotW#L;@S1vaw+O z@bbOvo**NRXmon*=DvW>nYA@?h!&SNvmA{gqQ2HU1~qf-u#~>aYyeZi*3uF(6sZ`{ zv37ozqvD)E16LO7;rgpD?rZLgllZS}+^9I$S=KHqxVw&{@&@&1v8s2Hl{(4D74=k$}OrX&NKzkmq_Dj8?@am~8y&D)RmEoVz_l&SVAO4@kz5wCBW zL|YnVU08ut3AIh0^;>FT4ym;=(f5+I7J$J|#~Kl09j%VvRQVJxtMAj4?sRQKZ;hzx zkYd*HrPnEPyvc%pdTQI(sw*0)jvfkbMY3ZpO(pfIEfbX~K^R>JZXKN6yoFCzN?Q9@ z1-~(Jx7~%4dT$d?m7&n@+?%-R3fElI?I$rRjSjgc;=-!&k9|`V(2HG_No_49+@Z_+yW%_Z`Y*>=|?AO}4tTb{$yB)f4Zjh|h1t(QWH#GHF0vk5fUGtWM?mSuG0bek*OG7nw-p z=nxs(4ZRc_k$&WU;JJ^4_S*^z9b=2(&zGq2O@^)PN`Cs!X5C>`uF1;jh?dEN^a->j zg!^u(VYe2g3=C~C81Z2Ktd2%LETVV6cf5h4alYlSaa4u_(4W~i8~2;2u-VEWF=VR7IND|ttuO-nxBxV z$3{|=sErtdnAkTW{CM5(ywB25!OPhY-4v~$3rTJHH z#G;X~RwB`IYvS6ng8Q-~s!OYNYw#z>y8bAQ$S(tg(VUUw-TUJ*&wg|JxfncGLCa# zYsre34oq>w&2!~{+@C*2c8_Ge-*q=!)_GDl66~By2BE*M*xj#E8`&;IlKFZfV*vDq z5Zh$|hJxKH_d8SY!mJpuK6W0+wYL}Pv!?St^SMe+k;4*o+s!Uk@waj2(a0NBb)&JO z!e~p9%ndrZ_e-cmRlg#8NXpiaacz{9Bq)%_MiqNzZvgI;0`{v9GRl9%e{!3{A8$W$ zJe9~hJiUu!;fCyx<$cv08d>%B(CU#TRqu+)5@5<~$Z@}A#+T*bpqB@iQ5q3Cv55>1 z9g1y21Y9an{{Xr!dD9B0WOD^iEnjZ>MyVpM#-m=V_NX^4hEXY}i|opc73D6uiBbpF zzLcc4mluZB;9TiKg_`)`hZ~kmBXP&|`C4&r+|S$xBvWddbbe2ZuH4`9PVE8CNwTP> zvayY&>2$2focqyh6sp%>GbJUoILRpNpZST;lOEqrB$j&y;$8Y6W#wL$>Y+5BcwD7( zwBNb3?b0?5EWP55=XIAyDm@)yS4~|FLYhPt>ZLtv73oS+L!VaTYG08pw17TbJ7`43 zub2m~j=^b4^uhf;aZ@k1=zNvN9EZ6|&^77&kN*H|G%XT}-|hbZT$NKt0gH{Yyx-l= zXis&v*ln2}DoAeyN_j}fiaSeJCZuDSv$=b|181yXwJ@@fR?%8JD5tn29AtJqc-oa++A;vqQrn}8ZI@a0@D_V05`0NN4(HU2`uFRG zW~I83 zI4bU*{lA}IpQUB=tugnN5MkuK8M1(*@1PeB0PFz+KMbDzQYMSllv-Sq=GrZ#3rd1Q zGm>zxPUPet&pw?v4OJOU=#9s3&n>BH!TFPe;7RD6CyWOVa)1EH3hmn;01xNY z;Obh9y%K50+byLk^hhJ+^zG}D*G`t$huuEC9{Um27COVAQC?uWAM*ai9FISWZ!<(^j+t7 zzTTSK_l**6?G7vsOQzIr*HZ&#jR~^DD6&c$Q=Um_MV~fYZDk)RJ#|OBlwt)bXSiD> zQd54<_=VkyJ>@XiG|Hc&r>?xvb<1aKwfmUb@CmDK#uGy>C4_*V6s;j?7;rDYTlo{q zl<}@Ly;cQ_?YBg$zi3=TBJgYySFuWa`=@8yT&;H1-=kEm#wXET#ZxIr{{W?u-g4e@ z2{={`I;igE1vr1{vP{1HRKJJ5-Ly^^l4k36yFL8G)yJTzm$ThSwpC>`RRytGUYD?j z7(od*N_>^#pCum=fjwWy*f#Cw-2zAiC~QBn&Jc~Xqhod^!D$K&h2^Cti(_>%PPbhn zWM)G)#vM}C?6f5PQ>st^;HdbN`gL>M$k?%`OC$xZl-GXD_)lMm#1~_1TR?*CGj#Iy zE7{hMz^|a3)s1~jHzX{UV7DQL)}|Bkx!{j;%f&bn*OBXPH%uf{@=x1`6-!*lq|?h& z)3=%2kuA|WLRP(sbO$RJD5xtwD2(TeNc}C4l8_2VNAt?B!=jt+K_h*s@RS`dYS5e3 z-x|K>Tdvb=Fqb}0llA(mO*2&+-S<4whSJFM0Q}`kD#=;te>AT9`oGF|b7VTR?GJ=1 zHoEP`1x@o76uUItw_dOQ;k8v|ZJnZC6WoVhWc@oylwVnODMl23A&#`Wf=4##Wq~8X zBNOc7fgz zyPiF6w2hk&YblPQ_SwVwEvCPFu4@i4eXYm2Y6in9e93d3cVYGoq`7h*d25p@Pt!J) zKIv0|DG5q~dvt#!_whifu4v_G$L%`z=Pi#*Z!pI%!t2qf3Q(a~5;IzNsp- zVpR5KqD+QmsR=H$>xx3KK3$<0=Cbs=xC z(H6E^sgUr1xe-}y2x-+YR)CR(WDbFuBP-yDnH5s~lZCj)aDQ==vg(Z6KfQ`H?do~i z3Hs#gk_@_}FTuosnC}w56ksTyoG2cN)IL=6N((ZGZC`Ah8@k&~y4iGwX4_cX$h@Cq z)Y;J=kuqdR@T7;FjUlxym!rgG4lqx&poHZeFXxv1f}o(FPIdnPwyqJ?>8^F!PCKoM zMSnonr*&5#zcr~ej5{IZSExyK&lZxoPN)D!b$&wt>P_61ss=%uZV6p8?azg{_4-+w zmW39&%Uqu(-lE~@5~j{X=}^skkGU#a&ph&kQdmd0r3548M~LX1VnN!=Iu&j9o%ZXn zMxljk#dQ+l>#3TW$o^6r1*{HeoKmZY`#|6StO^Y8q#~-sU4JopSNBR zjmQl0d~PAxxUM7cM zXHgT6DB#uH>rCmkb+O{1mK~sD-Yr&^n+Zr^CQH8{0DR>9dNI`^rsLfLRDOTkUjtZf zjB+gQDA#1}@ZNAkZiv;CNiKmTvLQe1 z{{Vw+Z?$cncM|H7_8l5DNLrPnl`*~85n!CeYCrVAN*F)#hA@Nran%0+B#6ohWbQ$I z>cP0w^}T}ATerT~>+UVJ8BR~ttmVgT=c{Ep*=5I~xZowFsR}72I5<5F^Ay1V*HM^! zMa7l-#iu3L@y@v$knT{XE%$coVRoTv;Q-2qM5Z9QoT zJT>jqo*0PLWY`Des+IZjf= zIFTHXI2;keRVZ<~t{~Ft*^-%PlGJJ%_JfJADKgT(76*`j!9L(Um4Tm5vDBHlK5Gdw zoJQ8Q>icVLhPsZv1^w$$qu$;|h|_ZAwG|~X(;@UEEx^iDLIQ~i8OKvHEW*fxy=x(` zrqps!qml_ZS8m>3r`P^Ha>zTC+ovWw)hD~OR>GX~1(hrnx11jU08&&2eN&%Li0h7G ztJ%Ag{622FyJ{|tTQC36^<~8$+nQ}fN5ufE;BtL> z{P^@=O^E*hno5r{-*gn=M*x(h6p@32`C~o(I;2;jDJSirAt_K;Lh<4TJAzMd$Jf)V zLGW<+BIqy>@yP6|OC`yWC-9<2b?T>6BXB8(|(D;@>UA>G1pjQWxM`sjgm%PHlV)v|rHE82 za7>ugb;v>_I>TWNoZzd)Skvt2Wf}^QICHmxBBhTn71Lbr_aSG*SM{2Hv&EKtpR&o- zE_Z8YVcA2hja5xX<4BVxWQm8w1s4>Q1cFqds-BY4MR=p!=ZY#0jHwDsNp8RA@Wl~bth)0kKDppb+J)veN z?qXYb5Aj6AfhNJ*#-Awt_ugG)MwL&uRq^GP!y{y+DcU?dGNPYs2p)+LUJeHp6#{iG&>g> zG{&8GM_S2-?O-k>KsB7wL!l=12x$#<+@#(=^A8>zkyFVAqF!qrRzfoI?wExAG()0q5kjj*gdZ2@j8=LTFC!RYP&#-wwr3vhcqQ?Ul8AuFY<( zS6k#AnRhLw@!PxV_U6i%#Z)M6$4qESaHY`nhF$qp;@8XEOF$TzVScmm3s?)VByG~LHh+&2z2c8=%wTdQbVlZ~g`cDLx+`gZ1_zwKT0Q+FOL@2uT-y(3ETKyj+>2fyiC$Fi!{l?zOM$R2o zWNC~p9CqUV#+_50)9!=rDO*;%!;rLnTTA8i zaz3wDv92}CmX!+EZ0luTNC=Sqau%0FTKC$JeXO<$9Bix1VE!NhCF&{6mfo~LaMpUL zyzlv9V2UM3clg0v+}qCkz2DjXlgM0mRXC^*qleEfZ~{{Y7kEyR5LbxaF~y$XieedqG_)vM?> z+SIKQkstRJakmSqxwbB{t#@6db7Q`XA`P8$Q=&T5b{50F>nKrCZA_djsW@nW;;zBD zlH2N;fG=@ZBoZdQDQn-PesPb(q|(#*?ZaG#S21krqK0G0 zkh^A9+l&RJ4g!oQjPyp3BuX{}yYK|>;FL8%y*id#U;XOxR-W6;Rq^#buCph3vEt4% z*=%RqSXo)k)`3N()s#xu5?)kT;yb}!!dC09V+le$mC+gi2RH!#02ku1VtK!o_0{|b z%KNuF@Rgp@^awgu@~M~971nJ;n7YR$KzZ1)ZDYi-ZY-l6#RR$nZDuS#)sM%9^i8;Jervqc;7J1q1mny6dv(t#0Dz0F(yWl9k50$^{Y)1wfeQ=r zBzWMC`5EelB$b0Nlk41^`u_kg&#e)?Vzhh6cTN?NfP>f*p2wus6{2V|)O^SuLmpl8 z`SdclSkSG~F`qA7cRvo_9*Bz|QVJjHPoW1R*Zew}ja(-imcX2OWO*F+^}*=nss(DI z0VmKUKQZ{{rI2Jmbefgn*c0=13jBXQmdSv1g(!LaLXTp7agR~bmUKX((U20K09Hy# zA=R9y`5favkm+D3jEk3BxTJ)u=KWaie=eF#ak>!+C1=5BxX1cc>D$w!F`{8~0%C|t z^W>lb&OHeHG1nxEF8v^>t;{$hODzN;K&8bcUpJNqrU*Fi`FGD;lDhTuaCPUeGndmE zdyb?bhFeHroF8nfJ;(|)ihUhgXD3=bX4z6pTOspoBIuJNjedeSac4>W>A> zsmAD=NGU-nNcRC9v4Qw!{{V+qh}^lPT<}C0@*Zc*E5`%{WDfm^2k`3f=DFs`yiku4 zzYs7yNC&?e zE_548>zDzRzY@Z(N+ra2H6^!Mbt!SM6x)bWR5A$buea_Fl!*c8N1rOFPfsxgP_F%s zarKo0)i+yy!9K=ycFhj!Vr>=C7cK3rm~p1bZZue}#*OVpiS+C=(`iBww+x7Lvc4#P%H@=19jO7y$eN1Y$V#R;KUv{{X6T4X-9$+gw~moyq)so;I~|8_c8V zY0I+Rc~HFCUxUvoSu0ZfhscZ$-CsvuQ30@jZ-vhwF;&bzvko?{++Dtjvh7UilCG;Z ziTpO1tc_w_^*a&c#ITUSU`TVsMQLTC_q0}osH5crtb2)N0fVzY1lgKo{Watre5v!a?8+MgbA?(pX2O?|e{Vm*z$wy&hv+qmro zEZf&ycE$KG(1d)>sny`Vr#w8B;o?qu64o=oe6k`$1cxnspYfM6Y9zlD3e zLuNM5VYgE2jNiDLn%hfupK5!NVg~#{c`_C}m*lkmlqo67O8$9`*m$+Q6#;&|e^n#9 z`#|B_`h7~GLs!-9=(=1@6HuL9YWyj6)zGEHoXm*tv*NVM4?<-{-}L}eQ-XRy+{kir zYsTvv@l!o7?e{~`bY0&_s*`zUj!sZ+FYl=l`~ zk>?R!&`H8lkP?uTHq^$Qj@7(lZtYQf9;^!5KtE+zZjC9S3zC4d(Py{Y6w~KkDz>ebB zj}BxQuS1HW(_|%SX{Xc@l?(%ejDgZdW+IzngWQ!(TK$`F72383taVwh%Gk}Lvn&&B zJ-IDOxw&foRH*K@@>I+J09_rY5aI|a2ucUYG1LBelK6ca(PwKXaDLMGKE1tv&Wg&; zZog%5ZuQlzy!q4ZCEr37)^1!$ef7CGNQ{)Wq`p+26r=zE$4f5Y*9&+xlLB_)nCkxk zXFLb1SGQjaShBV)%cYYVZQa$CoVe_3lMz0q12QE@ac#nk`)OKZB!-kg^GdKfC%BZY zv)yMR=>4DC*9+Qdy4H|rY-=iX+lveRV#ccG%D&bWg|m;lVEa~aWVbIeOs74-Tp>YN z#sI^9c~^>DLbi168&u={Ub9Kl>6zEHib%?hSydFP#k4r3EyWiWr8u>?rKw6 zqDqN9N;7#mx-u>j+HRk(Xd2BnpR2}x9R|G=MyX;5`0EG{{Y9O zs4R(-tQ7vQn1kEP9-}|c;yMJZ3c|<3IYN72cR$Sk0H0b&#bJ5IKLqDL59iX#MPQKj z#u7rZNc~=;{jvV;l!13t%z@b94X?!>P9IVE=dthb`1Q%C-Yd7asZ{Rd(p4G%01^v} zN}NerNh$yy-aj74)2>N??!AoySDw7d0rOX8m;V5ywSts9q2v^@axzD3c0c3Q`%*J5 zy<_&T|I+n+?54UifeHEhc@jGl{{V>{etkc+eJ&N%A=FYjiT;<5%syh^B!3?N00V=b znhVpI#TRKPZM7*a{P^<(5=V3Y00Y(Hz&kEk5=#=Fq0&?02g>dOLVJwF-}sYBn2rxAz+ses2}b4^=LYg0HF~tBKD3XGom}fnc_;hFmQjkGd^GE~(^CaLXf(L(y z{$2W{ZA4h5G6}{!K_4OfdNsu>E&l-06jg!o`1*7}Ca#whlZp-u6X2ujek1TW>k#2Q zLo6wHIXFrP?Vpe2J$l3!SOvOQ-1#JcpHu2RJ{bJEA_b~}2~;cmGmL(D^y$P%NJ2=d zDpG*-LBfu4l1HagYO-((Ey>9${Ul?z@$~74JdkDZC%TANkUhJ4=c2_0wtP-8l6#E) zBdv=p&b7yve2f5dp519ct!03Ger2d0C6;(8K_AQYie zRF5F8*v@~K;ru#jMu}O9&#o{*01q;MJai-(mS1)$?~#n05062dEVlh1t2sFD-|*`g zwNSdyEh`yUd>`=XWA{{|#4Uq~DGCZ6BzpeD|LuvvdVw;pW~1GI%5#9 zbc&VT9zFAbk)K@rPe@Y$zEbc?Rq~vJkBP^`j!-yM&CQQxjzU$u7j;may}YC_hBo+HQPaVlBwkHmwM_=DFR;%>d264YEB z&JD0?7F8gr4V9q?Awe!H#Hi%sxlS?Pt9HP;>(n$~|I_tyQq;QSqr^DsLP8Vh2W%ew zetRY3RrJj$fvWZj9~of*Y^fetAT7@2UYH;JdT1OMt1$Hi7HLkU9%xs%qCr{-#z(`~ zwsGI9!N6S70Ggugkm{DB=oCEF>4WQ>A5Qo^bV93=e`RuzsUBdS$|JD#{Qm&q z)ky@Y09k50z&HT_9>5;wANlk_V2u{T<~{ufY?G6ZkEc%=Iu=Tg1s?tL*ncmNM=+8? z;eCQWIU~Lgr|`#42@5Ur`f?9{OmuUU8DygbA1{tok(~bk@aq7`W?5MWAdoP7f0+LO zKAu{bEE0Yg@;M17Dhl=Pem|E>63LxxuIk63IKl7m{D0lk859MQ>GB=V!CA}$M6ySIy z=f~o%=ko8-cUkdCC8p7U7D*~9$v+>6{Q3ZZn8=m(918~lNbn=u$D*_N=b$Ag;EfxK z&Iw*Y7(w(O!1Muf`;c}EBpjsq1a>`>>HY`s>E$xvWU@d$p!f98$N2TGkgSk9lk+6^ zANh5OYM>HCk&uuFkDxvK=hLLjotBvL@$pbn72g=|<@o;qyP)(%*=$HCIXF@552y3b zM=&C{L8`Y;#VNoF?mjsFJyG6)1HF6*K3-jj$C1aUZrv-r)+sd*G8;w#J;@*K+qX+8 z?o2qX6rwYe`IQgD(<9UJ=zc;G0cA_aj#PUb0G~wx{C~r&bsQ`LOr(?KqmUDYW41x~ zf5)WEQEo?kPpfa!#VHN$tmJcdlh)JuOgrjL2+nL zZ{#u5H4gRFpd8Uu+fi7K=?Fbts{* zGVyW3tf^|klt4-GZA4(>@xbcPUY@N0+UTQ7aStT{Uj0+`>>oLC8J}{1ey#`3wwoc+SOh$}YJ}lpRxFcb{oa z{E7!&C<-3I{eVjmc_> z^--Zjgy9k=qz~ev03=IGOzM^#@V7Ol(e_XH>wcl+S|8uF z@2!r@6J*udR@%jK4TLH29QNczml^CSw;MPldJsVbf)7_Za?_I?opZ>E2UOyI@3^T` znXRs>-Y;fYPPVPq#cr=sAmF`l1vmOHnCDh(0PfBd+n;%v_2y*L|IH z8G~LMV2dyA&xi8`+V}6TC{-ZcR~~2 zst(d^_XhQ)>9+)?PIko>gZDqh(>7IWu73XjR|s8QYpm|JbuuE*J#nulO6(yuV&}-E zwunzGD;^36SBlDqk5oOhvc2ur-f01UFH5R>V*Ad7?VV#<)dilptlDwr)4fF7cKRu- zu`V4jfVfj2G}GvEM0Zgo!n9#7ajm;4vX<4y{2AtNMYjXs8s23c8#$OI5J&1!)SnRVIP= zdm3h!t!$g5ac8jYw7NT#+AgsHXqLN;t{llCG9*u!h|5C$iNzqT#{IOX#cNuWp00a# zCbSRGvQrl!h5j8`J6GL4k*e#kwrTo~?CnXZm3y@lgXr%8yrMGLWJy{nf^IYue#k);Xr>`fngX*3q?CMKV~ntCy=UVETrX z%#^A!fFAdnkfH394-aw02Iw?sGS$F7Wsnh}dxz)|3BP$feNRCC$+YRazO4dHBO4~3 z#QL@jjf$c~*pL$@v6dw|uQa(mf~Ft#p9pa(_WDo2WNtC#O6`K#cPp2T`A!ca%G+vH zt6u3_HjgGOeS=!qS&ZDqTb{?%!;qE3ktv0t=DUv0pX#E zr3vVaYTUq6O>geMj`n^+V?}{oXo~wChR0IZ_h*-1`*i!dp!d|pZaO9^dJ~xLp|{+O zmYh-wQnQr#6Qp7smv3}3mPI+Af8=T{%a1gEI~9WCkZ8AM*M8*JxR2ebt67s(l@*{R zviqOZ&#He8wwMGNO3ppffW^2f+E3lRG+t_nrq7cS4<6Odb4%E^w7UsQcXv<<`av0U zQ#q(?B`R#l5mbdddq| zLN+$%OpO8q3??*}3`sK{n9s7zzi6on^T-HrB7cavsN=zr%VCeoR!`joh&C1aY~CE& zTjjeecBzxbP0Fct)EPChts_iTh?pUmt}zYdmjj+iS_)K*<1REwsUf%YO2F8maQ^P= zZ==N;R~2oWZOvUg&4ZF?T5`TC+SEGh8I@9y>#`*wnNmKgzCv1RI@Rtavap~Ee3*9a zN3ZG9p<+CfDPMT??@SKryi2w1`oz7K4xK}{Lw>S6Yb)z$EKjbE!xE*m@MYGYNOAS0 zDQNakI5-1Fj!zxF5ix2M%FFK;SfF8hX4wkgS&3Igc+K}8yxn_?XJDwp#xd{nu zsd6PHC|8hU+fj9EM~*sw!bxGUXY@lQHs$KB9t`KIPHT_0M~Pn^pJ&nKMv1gj!?uHc z6$zTp)J1kZookLqeJ&>;fI^U@sVYe9OsA$`TX?Q7*myCDrRKkK-Q?43 z(U8JkdQ3L8+lv&iz);9=zYV;2kWM^(6nYVeAe?E`fQwX)9?Av5pLKNn&Ai@d3)bW7 zxApXB*&#CvV64~(fMljB*|0UMT479WYe8IfDR|FioF1BbMgiXb8*f03w(?V*^PlNB z^4or;y`q{dH7#zpW7gSeXg}O3vzV&JqQn0H(CTNFqo^z5^J?@xG<1xBBacg@1Jzd1 z{^2(F>?P^?A0E%;P3A4W*Cy(!b)*VJK&Ya(Rd+z6};kqQD4ID zNo#ro?x`RHa`!(97{9u{LaXFHM%Cu=JCC-z4I-O|^_OQe2Fgvg)mZ%H#JEvQ$ch<6 zXPtGy=k12d5*$*8NBGeoF={#UZ&jWA{;6%7?$TDUx$?G6Le`&X6BH~RM<7$LAb^GQ|9c-*>yIzA? zPj#QkaWL88Hv;(ix7B^T|nN10fBq#dS#b<(=T@9p))jgai0pDZK z#~&}3j!rYzG_>+fpLb9Xx-zrvwHKc-x%-zFsd0RoD+&8n?`;178~))}GHhs7_G13) zX0DLRoJ=*YFj%i`Pq;ktlq4YuP(FQ=(U08ahuzSR(Ex2t-ilYs{{VN}cC$fq#dE7^ zxZ~~yRpZ*iZ4Bv_I_+Z%t8UpBjLK@Y*-oWV-bxy1!}3e#=N{T}q|(p;=D4`=emE>f zYi!>tQ=xs=?Au#(j8k#DMvGtLc{`UN>^lwj&`NDpvaBlA8Y-m2VYkeu>;2S8eNo%? zlw4Rz!g`JtfWAlN3~nK z3Ft-JO85(PNHNrhTwyC^VL+jI@<^}Yj6dNm%roP~E?U0UES^z))@`)w;mWx>>@@28 zWGJRy&A3|1Ze^UQcXI0-i2~6OQCMWeLkV=ZG1e6DT3cvm<}%dKA9ZR8>Eiy$q8#&Y zO|4Wyv+i5&6KlBB>-F9)(3pkE`v%#r=#%X4>_X$6LHP-lI?bkFAL+<$GQGB%QCe5y z9;lLQ<9S^BzXw;5Ztz#d8XVR zE&$-jO45Hx!NDH`*O4*;?9mlfe#qK=w^!r}9P-MRMlf;n4#U0xKjYUV#w*v-D}lMp zI;yGdl$SM8rN>zid?|JC(DY4VBPL@NCQK zK(y3Kovg6td{N}JtH>Yqd#WcMgChs4#9ewC(q`rCio*AcNpJ^100YxFOq7j0i z4oY#6k6xZ6sA{vYx4tOi5>k&PXZ2wy1Gq^e{vC7*1;--gF51an0>M(S6@mDA41XW@ z^zo5&l8q6_<8)pTn-W6N=*0Yp3kEmwt2-vy_aU*-^*hKc82O!KhH2 zOlVg=b3YL8yTo%Xh6IoY(+>UaTHwof@b&IiB`|s z=Mr1+#=EmnPqd@3i+i+7*x*K?t6fAmBE>BiqBj|GB;g2g1R(i&6r8In$?1EYajhXB z;(%1Wk_Z3@=eMfUPvA4HSn)Lf0Pdfw9Aja+%?*g2+NKS`=biBK_f_rvKf8?l-gy52 zPhDrZ%w)pkbfSc#PA%^0sigZn*md1L>y7pPREo}x$hB2fT(cTYA$oj~TOANxdZs{_ zltfgxjiHwV&At_bblyHd77cxyU8`=>SO>I;q>@cg`e9sHRhi|q}psxJxxu& zZ2OeIW;jEVV{D@74%dYj54KuG%90)LpKKoy<=LU#Ws#5@zx21l1V54L{{SkswEIZi zw&)d=JMT0^wXN1T>i+vI`#ffsQ)^wU-x!wL6grJ0s8{;@YkGSq`mA}; zlHHYS&m=t5l+E`%P~&T9#?Z7c;nROAu6Ww@F0qraZQTPXwddH27aH7cZT?P7xGrk* z^+}H0Yte1hTN-@XlN7yZOpviuP$qpkaqf`IY@{eDu&$hUARNt$@bTaJq$S*N@l)gW zkzZt~@b-<_+wFeV){5@pl@-X1?@FuHSE$QKcs{iyxp90P3BfHbCkj|sWQTK>!oj?Y zgwihjU#LwV`$3Kmd#ArkASX!KZ=JI?zmDv4Xbt1;nzcww{74UXWWlD@9Hwl zg9Vj5&9xVG9-vJZ$-)|4eZEVc8+nzT;ruN&?@fwAvgcfZM;`xYE- zo21skY#_5E_o&Urcik!;L%}WOJ}1}LsmD|8F+k9&Nw2jnZa*T~?ab`bW9xUDG>yX3 zNKIW~TlSLDex(NE*!tlO=TEx0{&*_L@(3jzRQDu?YWyrIZJjWU_LSU;5vc7P%em~j zy#+%xJZ(;Xh8OG~M=m_r6TIWFKDJypAu^U-k`xkzk>X0$NIJD(8QuI{@v=G1`E*k~ zW9{BOUgurO8&3Oey>b*Qq+86`<;8^!x7uQ+RXkWJixH$Y(=4?$*GG@cr&Ls>5O4&i zfU;34TY85(_K8ykHg9QMpS5VSwm7%7Tb$bD*Sx!GtJ{g!ON!!U#dR#X73&w!!|ed# zP_hY8!4LV~x82ZtEcju!%A3~xxMLo(`MwOqt7R)R|& z(<#nRnK}8oly!`Q@NXp2HLo73F|mE0@y^fv#rvhb=bpgzEDg4tv&DJ3~eiC8^b^O1(k$Qiih^6E*haHh|w8mSb#t#N5_J8*%0$Tt=-;INA- zm{4AbDr3N}iy9<$)KuEZZM3MY6{$)+xUS)YKH8b++DVsR&L+9cc>BY#epYn95BG5f4zH zm)~r9-HgXA_0B-t`14_tKVX$%vFlSJGcHU`np$ShfZ>x8LOqcBLfKGAb)|PhfRmSw zyK(&)VoCB$Cw-=I!>-D9y60xsimP>))eEkkk9w|lpodwhwTU729(U@|9p$p&acgbV z5*%$sMD(LvfY-lL>7D%ko=XmWqj9v_S#@{T`zFa}bk4?|r){4#qi1UV&mJsE(j_gp z=x8YnLSeR2(`Z9!KuAV9-ylvv1p5pCDSBD`9OdO`mN_Decx8g@kt?B-Po~m&jayL&>_N{Xbz;xX@*; zJc!mckE$g2GT}UlFy=#&j_ti2=91zSj>LBaWE6zVWZ{;wp_%(Y(HM<=DO;BFGj`Z6 z>vmaOqW#iUu(fSd5$F-*$A8!iv!sCYqG56xi(X;N_XdRPCV+?O1~bt=QAl88XmOb~Z?DW8oTMJf>YvGz@4r@mL9|M$py-)cvuNSX7r?s$F4L=X)G%|F@>S`Aq{Q}1J+gBz-%1n7% z8GUw3P*Sk4;-oJLRzh>~;~h#`=1w=?!7~e;%&X~NY1}6|Jsd$tZ3eoQwG^`ItM4r# z#I~$zOS2h+aKjQ%-1b{}_Y{=A71>Hp=p`nDx|tqzYS)ScG1~=u%LxbwZ9WLVN(cY| z0QhU79MZ+KG=H$H@v>P(oAapDd7le*@}2KDj5odio{kxCffo?^a7n5*$h# z3rmM77$5?iA6$?R@;y_vz1L=-qW{+QCoe7{(o#Z4V0-5z5uV+Cb|BS#RiY*egIAZ3 zr$S0pmflcW5JLTXoM-U-`sj#Wl-T%%C64mceN*2HN|JJ};~4;)etl9amT?H%X(>XK zuv8YW5LN0v9r5Yu->!(oamcx%B-iOkD)CFF2MO*l3D5Hb{CccK7d)@Y7Gw;MAbfyH zPk+zwKaNLTFbkGx!dzKUPk#51bne&-H3<2#z|Z)&o$I|aRK zw(uz`DlDz#xnCK;+=*VzbZH6=vaETi;~jch9iFDFa|=5=fnC*HQ`L-1W8#sq`;Xzu zS7;lRv^!$O(w3swgz?B8 zD)ISA$jx-LXDMX@tPh(vs9f_50e$@+;H>PN^~L(IN7vsyG4<5e+(Cg=5>1SW%w0)T zTEs+VD{d+GWxACHnm{X1N|%oWk}s#BIn)Lf#jSq|sY;G9+u=s#ebwkwj~Z{@^t} zSKc<=J5#Q+kqcd;*Y*e-o3SJ_S!oYoVR9HTopq!R$w(j*^L*I-3d2uC#vtNfm}|Pk zGw@MZzjRvdb9+KIsylaWX!h-{h7~5SS2pfS>a}N?YE7h+M?$@p(3jEXR7cF9lm#B$ zTlmG;ZXH9U!SMR0l78qkdi!e>iEeE*_KDU998~KS^JiRJD`KpXYStsE4Yr_T##_lL zSIUH+a|*yLJ9#i8c0AcH$wj7p)A4j!8vJxKvd?PjsvXsoxRg^|O%w_99e~5vNiC(w zV98~`>`t=ta$Z?gn$;qt(L(_b$)Ks_O2(L&9UL$Q)m$CWnZFI zy?c=5NUMt<>WtPRsFxJmjRL000H}O1jNzyM05d2rR`FQSRYReD+i^mwY;Nx3?7CfS zeRUgUBfAAGm~LIuE!HEVO?!3QEdKRfRe)$({Mp5firr z#C_axvV<0((C!yDuEe&VuxoHBi`G=J=&TK8lIO(^g_9miN(y89${-aaDL5nz0~@!^ z9X408JbvXk>-*5^C}!!%jOozr0R4fXfoE^-bSdiDRrgxzNkBsBO0FX&RFbAdwumCCn*H zoY4(C;NVJuQd5zd4FhmNt9b|ZS+G;h@9rN&(QoXvTL{*+n@lSTnz)oT?6L06m2(zU z))K?ApN_ywap5}St98UB0Y14PbUzW5WoC3B9?9)TJ?NJlOSN-65kLE5N{Mvt(Ok9@ z`;51LsiO&>`Zlpc`75`=#cA0kcAflM@R7D4)f{bh)s~GZl%w9uGzFh z(akO9wYx0cBGXv4j>;acc7-+0$! zivvNn*sH^tIbtUe&{y2ZrTyI5&H5G>CdvgZbY%vdc)L2z$>vy&f|L}e^(jgrDM`t~ zLr*c_k|EU)KJ>NQ3PkMs*B;(%I_w@ZnaW!wvL!)f5Gx@)J}RRmDb;;L>ycixx9w#L zN%Qjq){*VWEcJHV%@P2{i2Y~WOxAZAnA=XLd9Os-VdTU}6g#fZey#}`^G?rb&+-O~Q*X}7*u{{XhM zdYi4+DG=X@Z8FL%J7<`iT-}ovEm27=%5uD+z|oS?UL49)*hnfI^3gc~+s}p}F^fBz zjlV>v+)v#dH{0X2>bIhaYYlZ$F6`ZvdkU^f;l^K!tkuGI+>t(3GOukYLttac)RG5B zM?>-p?ZqoMf{`=#4@EAYVY!P#FvX$dYJNLX6yg$Je(lQCGc_X}ke}R;RD<(;svRNG zJsmKOKsi6Uip`5E$K>nPHTG<&m!E{o(h~Dinhc-lduvjIiC7&{J)_VYw~+^I zP4=mKHn+ zQ)^am6Zmlj$)i2JpNey~+jy?(ZBo?|A+lwd(^kS2If&|0jUoR45$++isVOQ*RzgWg zBx4|T=1TQl5a6o~$=A$R1W;U3v)yE4ZMJ_B9 ztxE_Q%E1}PJ@foJxT##S1O#QQA22~fm;npzjE~{z->!(4T$AXDHhU$+6%yy^O1qxm z;CIi!WB7H^6S;Fsalt)AaD1Fgr{n`906!rrw8z2iforhRB-gV|M8oiDHQ9-V`!W>7Xi{BAxYLPHabD&R z={;lngUc}t2x@O9F+L?g>5u>wApI4y!=G)7<9j;G=jYKeVk)+Hmi3za7vn(^b{Tb# zq{mc;-jL!WqPZw5d1`UOuOdJ z&$hPQMl!b4Q`3JWJGT65QvU!&v(s(NoLv2&ZFY5hb5@R2fhJaySsDlToa$)~Y;`Wj zoaE5{y=>isa$}`Qa53!7a#MZ{p-Ku@pPCNhHKpE|SBDM^iuWF1k5Hl$0vOtmeC?%a~5)WmmYDQ&5^&Ad_)*>}VesvhezP`xpw8r<0^ zEE}IyeQn%jI=k&}Y2rO}FJrie#q%{9V3eXelccpyxGa>VOYm(^EDpt31p4;q=opPb zE-s@v5~#^PXS)w2Y4tU{*U4zuY&HERCbOcmUqr+v>R0s@v)z?q!;)q-VDWygJ8Mt$ z*;8p!eXv|A6&m?y1u@@dzXWptTwV6_Q_em6UT09XpxA7#wbm}E_O>=-4^7o#Yc)asHi`q&ifu+}wF?IP%Ys2trVvqp7Okis6gcx_tY%^$IPzeVo0t$FhMFkfO$| zy1Lmeq&01>##ht<(c5+lfgHb0qdFQvsLKqRTGq;%uBYLW3^DlxKL%-lBc zL~4G{=_t7k-MR+DTPBWH(03`Zr|VU+wpT3_0^La2UCZJ-k_Wz|27SOuN*zjj1)jMu zqq{efXibf_D*ph~II^Eu;wpY0lO@~AD!p&}Vob+CW$95B9Z{W83CKd0g{#o^=>*80 zY+cewy5y_xwLSY~+jVVwa^%|$*N-9bzRRRXwqm{wWQsuSif5|bS`xPm$xbQ{lH4f` zkkAFRd7mziUF1>d5McF3ve`i=*xg~A&z3rf6^CNA4wbqe!f zj|v;eb~^Vw%m45*mn&yl#rCAAe9`GC~D=NcEvp9=!WtK+l@}~w*LTs#M~{l zZO*p4Ux%w)LS{S3u9dD!pDHwv!{|~T4yM7@o@sw7n>~tE^L0pS#(qB4UCbA7d1_4SnOjFB{@q^ctQozJ1|+!1uTnjT>1mqCsg6^U-?#I7o=VGq zBBq<0!}VG0Fj0oS%4ry@&|y%;i&;7qY>B9MUvaltlUruC44TEsEu={i zm4`dyz^O#zu2|CV)i9k$4~2L0KMo_9pw>fkZk4V^h|I{gRf?~#xUHWSdRq<$>+IQm zk9nflEIt5RWTIc?oY*JHzt z8Rw@x9a5Px8-T!+8(0qb{{W-OSp!+Ht26M}rZRt3V(Q!#s_H7^C!ko`JgzH|vC7xO z>u85pv$*q;#E^!QklA>K{Csdde7Z8%Bon-(Y!nuU?K6&b%|mF@VA@|hRk%jiVc0z5 z@yqB&u`N>JmXsJs1#4IJGLw<|e0o`HN=Gwq>YpB80XWZ@1)lTQ%0Tz1dxh z)-R&BT`{=pH8H85iXm9Ul^w<&Vk=8hTtbu_0Z3YXIwM@=t#&8fU|6u*W^L5Qiw7X(x=AyX&!7@#G4&Nw~rN;{Lp))Lnk^q z*+xQo@ydAQ84lEK! zkB}r}zw${UL9YIv2r#zWRZX_e1JO4)8{K`&mT5;JYBgGAyYb|P-DV9dvgARL6@CP_ zC8uUBz~_INC?P*DbdIrs4TrzzjH~AAEqV68rP#HvHLmS@R~ao}2 z6?-vdDnwZdN}E%T6h6sq9Sn}&fT!Fr>=Z(>GUMYCrZ905y+Lv!m!?ZtLuiUe; zQE1YqwG?>+@QM)wM%zzUxt>DRJI)0SlDwODk-xD=A-^dvvkxj+-zPvSAku zy$M&^cORSTdv)zQn&DR7Qf(4-blRa6Q?K>*BQX}zTMfrbmh#aNzi}yAT2hCfwiVx} zmvTU0E*rrpChEoHejeBPCdXgcp4c`$Cu-IinGUaN)T}>ko?uv({;nIVC~*!l>X~hL zQgW3fEd?qW>0z$XA%YA+Rbqb5c)A5OEe!?s@2S?+QaP+yB9mZ|5!hUM;%xdCk^ON9x!uVIMM z){Oc#mgAs%euR(DsQyFIyaFaq*QybD_SeLF1-1RP*1q+d+f=LBm(e6jbjN+oj;jh+Jq*1o)6ppjMI(RQ^nZG2PSkN(B=QbM4bdqA_2Wb++!-aP8^s;NER_lC5RO zT>_q6e0G-ah)XRg_Y_f#txEE6sQ2nq?qp3VM%&3$2ENX&i9s#4r2?e^pO_3_XYu^U zez+w?*QDgC>uhNymv9y2kTS9Ol@8s$KcDB+bp=TS@1HbU@I;a8Ht0w}8t0AX-q^BwYK(-bLC-Bev{XKfDKsHdBF?UA-REI!I zW7-%BQb%A<`n!BH)xax_!569^!bmDkLcgdAPJ7^d6aX0Pan+(4iW4~SMbc0lT1tx4 zPC-EcfsFU>_;q_0T!q*tjE5UaND3)G=^mNS$}!d8Bot=EsD9(i+;PV?l$ATK*u@ov z+DnzuUuox6?4@aGQe>@`)|kvCZUh%zC~PR>%RPEp9k!;RGKeG%wq?VqsSt9}%7)i{ z)A05;W!PQGr#d#+_LU+dkS0ixKFx-`;wz&^VaKG85VMBRqLiSiUMayn@$5BXMK2I< zy>gvc%y_ajwSCR-zN4&DY}2<$@?dQ=(r-1TMUO68UxOJqT&K)N9x+%-@YG_)Bo+jZw&ZeN`T%FKX9=Zj{EbX_$(X$V-U?gscn`jDhgaNu#BnVkdhgn}KBk z-oD{&c>e%b*r#3TG9TL~Ud*iG9X`F8_EPp5=N^Q$~k1-d>E<3Pq+>!m9A`iOB;JrX|*cqdn>t-BS}~+UZE~mE;D}E zaq%HX+d@zjuP~;_3rdm~`15uS{b%oU&4TW0Ogvz@Jv^Q3o zW1u0MxrMizlX*axl#_MT3z*T$t z-A>sNi1Hl}uC_R}k|M)w1Qj@y8(82eIRneN?5ty_ATSC8qV%?#0Sh3KdJ-bz_b(GQH?-;b@Z6&8f1F ziS#58dSAsX>{7~sawivk=6>O&Q*Rux2~`d3RF&5db!v@%%vzy$m(nTg8EKV0C+d*m zlG*~%;-#-E@Ja{*)9udYyi&nY1$a<~0k-*dk1= zjMT|rQxvQ;+ik~vr+vcriqf=r6)5=hqe4PN8huij(FL{p#NtRk)TmJQt%8ZVDqW)U zYO1DsMP)@b_n*S7d-l3ZzM!&$7iyT%KMDc-PtcS zI=an;p3=6 zt6z52(6%l;Zd7+J^m|=ml2<40_0>{Yg|6G|jm3JMavpK_JQ$Lf{&u_;rUKe=$9zfX zjUTn~_8WX6VC3$4DN|o|nmoGqtm*Xq-sNuX6ZH*lqAhG>$-S|uRD@Z%UGK|jDq~tio2lD#f9d&gy*IO3buh%ys9V9#c@J!a-eVHn7rz>^1?7Fs*^EeaIof6eGuR3f(AZ@pT zobxXK0C%9o;}@xw44t=;war@F>RVHQz_od8zFP58d|bjuijF}1IvQGF!bIEzt@kkF z=%f5|_amzEPU@`^CbN64S<0%Nd#^6&KxuQJSITBAhgA)UkIaUk38#f1hN(Piw=ZKedtn)Jk=fGXA=DgZK5@)rV*G_+c#j4S5LWv1Jm650Om zXtixlCec4Yx@pL&zeeF-GQyg<6%Olij5`>@T-mI#GC^@AOfwlvQ>gjAUXW-R9Is!R zqGHv-L)Z6fDeaqcHn5%4_~TdG^mtSoTMWjQt2&LIm|8eywB!Ec3GhDQS`p@iVLl~( zT|eMCe%g{f*#-jluc9|Q?>4%VS#N9Ec$;aWt=XuC&Be?q>gT0wb&8b+DG6n{7>6W& z;=`er)H2$$=j4?oDl|6`MPI@G6A10MRd(^GDa_t(cb#8h(x+&9mmf)j)%6sKQLI`q zts|LGq%$rmi)#x&P+CX@3rQWu6nV9D@-ccE_#y}*g;9II+|JOaqPe5!7LDl<`BIaP z=JJ!y!g4#ZKYe1dI7hY*vOIrKJTIeaK5T^00y-Yeu%(150BLaru*{ItkrJw zI;5K#wNc*Q=_sYOt+uzdW`(6b^HSV$*m3z ziQwzDPq6G)2|g^eQ{nwjC3vJqv?Q3~`JE>P?C28_Pfgc3}k@+6EWo1}Us=seSKAuc;jF)^$Qk7%z1f2FH;EuU9121E@ zB(n4Cnx2fwn9@SgY5cRy#Cey(e)|yV!XNE-0)AfNIxFq z$ovOioe%BsUsQnq0Gil3gTq_prxa8NkD742XUEN1I42#wdv(wpuTDS)+XWzx*(o6) zx`4k2fAt*au=K$7>XBU2x-!E2Ln%opNf_}Yl@Opv8Nlk%kqo(K7j!^1?x`UM#3e`F zRx#zAcl^Ew_;q0%)?DUUMNu{zDfbpKN`^e~k?|jnah~0DKrU@bI|NOTq$DrMCkYBt zek76U@c4dRbifd~ra_|S9(m#ZMc(#$i_Hc_Ep*nXq|zs4de+LC%CX1f2ffw(3o;nC zhyMVs1f&MkpbwbxS6rX9R#6Wfi z&%b!b1qo@8X}scb4 z*rqXJ;?6z3FY3D^m$Xg4Xn&3O4FYXEUE7Q=-nyr)*nR&1+Giqk85Ppw$aX4J^Gf!l zmA3K_uN4mIDN*WOwya|l8CdS&RVl&EIe0EhoA!6f((Fe2KI2W;clo2=4x5D?-%WfNrW{1OPU>uB?BAWI6W1W%mC7 z7TOFc_8L5`QM=Y6xYRUBmlQk4 zLOEo3tvP+f??S46(~V8913MpVixQ8GE2G2Yt!@o@j}v8GRF^Gj6ojeQ3kZc|>yLn? zElLW)luk)=+=)g&ij&aa(E{${chL(UYrKyts-KPRIRb!j4u-vgZyzEpWR%{!D&7^0 z7)Z5watjJ>3T)j`Qz=THAthcPHqk1os_OZ!zjmFh=?nT$3 z@#U_?qiwr`a;l{}ZuN$q#WZ(gM0e_gEytKCnsdo%D{Pe~=1IsWQYI~l1bMxBtR~U~ z;9WA4_HVG=LWu_3kl@5Ro7-F5ePaT(#kj-QTSacyS1NN)zwNxJl3*6yZ5}Cg3K%FL zp0U=6d_g{-f{2?AKLuHoJPo|saupve@_z44XS~&4SI#hX%E=JwkyTSsb6p-2Ns}q} zi;8~f=__?=KL*l}2bV&6pp2s5P*0*zKolD@D~pUc@BZA??bYA9e(W}_zhT;o<)37; z`|Q^xi1;gCm$Vn*<&ou#;CghD)N<{!0qm65!{u|`XWB5VYmOTm>2&B6x`j`eukrf7 z?M;DqrQiPm7(O3U=j~&^hw93`I%(?W1%>l}>TiWu>H&uCfs$OE_Md6J>~@s>|t@*J6w0{QpN?7$(TR&oyu=W}YD0>dOD!G^%yj`X1jXJj0_4l=iQ6MGCt66R< z=o2l7O(nz@p71_OXrXE+pgV^RTt)ZrO`VU6sdm%$i&=H0Xqx0J>Zv!}d$H`B1r+_K zT#K;OJe{6onR8-GsgUv#u%D?&ZN$2jq@XAs>Q6v-CCT5p1{YT*sl-tAo*G{dN4zb@Baw84Lk|jd3Wig(0N|w{bPOZmOvbFe-P!JM&f09c9f%6!p zlN#(1Ymc)Ei4?qU#RlC8y^oJ6r_s5xZ93I{(2HN*BnkGDWW%1IgiCsEWF^+f@hVzW z973=F?u#C8x1t3|qW!R0>rbVgJLX&cA6>Yuq^{%&$dDkaZJMarOms_!IkYlso{++Q zw~H;5<|d#UZb7 z_efWt>QBrt2=CU?)iDHb9*JaX4%JjY4t=CY;tkJK+ahur?by?)?Dg8(RO|IM#!YRJ zjqE+c7?DsQ_HwXREw%J8p|C2CQwr*b4Mi~9Va9ZvZ}fvmTUg70F~xjx&Brf%Bf zdY2*o*#->X-D;RJjBjksZGTAnA6oKK>v_so-6W+X2zMD9g_5v0P+I>0v`X4~*xH3R zCEwQZwTm=A_Y*-(Xf8E=^$bW*T6gOlXvl~pwE=|5Ln^|;eqREm5`$HP<8K4{su?+b zompDH0&6;?&NH7~Z({nmzGl}pl`i{5FRN~O$EAq@C>@$Ekl0Q=K5X^BJ@}VEhrZ@e z?O*LfN7Sx#+lX5Y+__pq+WW8)`lA-zUcCz56mN7TkZ`ozx~2G$^CcL-&R17l&Bp%# zoXO&8w&qdov+W01*zE1CA@0|@^ScXM99@x2#;cU;&~|z5PnyIxX2X3@mKNzsUSkXJ z04S)XDhnR!QL9_oz7wz^xBY%m8sD^iJ}7OAO|tIxxpFlLb`@`;8%;=;r`MXO&bV4( zEAf*T#Sb=>c=qx~fhVKnqN`0Gt+P1oFYNd^Tk0DN6 z1S?;vVr)64I}S4y213?rr^o84U5^9rn+p7hHe$5?mqx%U71vyKEt0d(5W2HLAKyXQr3I$C}`&`#7Z&M_1 zdyGvrozbpBV~k@w>Vh1_EiweEWIEp#m6uEeri(E60BmMoRC9QhC9)GtamKb z{i^D95Z|Rv`Mk)~;#OGIY1+GXt-)%EiyRf0QXt2VDaEi76CF~Xd)Y|BI%BU_VZWK% zsu{~NvN+3%D!9r0uGOuA*K64Kc~NFCHRiH>mZcnF zH8qI?a6pIKZOJNL7t^R$sK~8M(Ds+JY&&fcb^ib%_4_jBu6TFk9!--y-vsvY`Fosn zCEQLx@otL-2D_P5mmg;wU1?W)Lmy(?D5!SYg;8#l^;U>!yJ$vS$;d>97aeaPHuU#M z_Ey+hPm6(L)yH=%*{JXOt(D@)3w*{D)E0ET2xQuG#~xCB&!A z1z-l;NFH9lnFId-F1a->y`J5GUTJgVuflEj*WcR;NkB#vlBE;#VPKm4HJeqNaBf{ThoxldazEH;ET55Q#OJ-d;P z{ZKhlkOADHj5eHM#Ngxvf-*dQAIIa>;T6j=a756gsW?K?+B@K9<<1AtK8f`tb=%wMYHI%2yKY?ivWyMtqLrU<9Ay6evvJL)&sVQ(^tX^`sv%C8$W_C$ zt72KO>@)+P1*TYS1z7V~Atd^B-7eEqKuiY&J*`qbmmt)Pi*as<&2K*O&5tJTTx!+z zb2eHHK(*QIo}C@0n^F{|Nnr>l$wnJsE=s!weA1P7&N>HgsTf90`;Y18xj@Jl4`pCz zoSUHXZCtC318uI`DN%Swu1I;$?e z;&uA2Ub^B4aiGYy)@o=h_6rI2LciN{VYEei5!r2V)|V99Y7VO|4<#+8kP4PcIzNm? zn4kNfpjsz1h}_*&;+vniR{LPE)hYQhhJE#G6D3cAi9rFjtBDh^^MNfB8^D*67F5^- ztR!^*0LRpb4h>3+y>}#QKIOO`%U-_QVsecs*7cb%;$B-mrxJ-r&i%>od~GTxATN+%J*>{Nc9t8=u`St-SuhIThAWW5rhCmG z6|El6l2P-J5#Oecgx@Pw0u%Xs@5b<=&e-N{^l0Pw`o(t78*E}~pHuOyWj_(3h|RR6 zDJyZLp|1rgZa7O}u%!IdIz_~HzeJ!Gd{YSj0CL9{=_wXWwgZj)6> zPh$?Idv+Ao(I<&^X)A!*E1rmnZV6x?VMu7D&qR`X!$xG;6BcE?hus$mRcy@aRvUZK zt(~#0rSnxynTFlHx3%<@Z%s^78L5j8psG6D4kJH0Q-jbtGiPic!5qH}=RW9oL91<= zq5a8mzqKJ;PO`arvc(loH$a6sY={;rj3Ui)5>TS^ahzJyg?9N>hWr|o8`6PCQMiA2 z{0Ct&JO;K)guL_cn~-E{SCN~G8p&vC1%%fhf`rC}DQ+b!$#kWs6n<4490S|UoZD|s z3506csd|3oxRF~e?yPR7wIf~@h>?1#s{u_SO%qN(YYrWukMy!+!)>Lh)>?5(9xLoh z781ikVvSyDTNPVuKYDyiS*c3eC~Nj@nNcKbi(;qt8(1=?Rcy8mz>9AUxiHeV;&~}R zIE0X;gtQNvh{^l}`4i=WY^B#rZabd4p=w(e^|j1hX0xkTKWlk7vg@j1EOh&hFWGGh zaFCIo6r`WascFE0DYo3XqA|Ye_e?W!s#mi@VIMneuLr5)A~vfr3Wh;QRaQy1!mZjp=kU&InAwyU{MY;;ZP@T)A- zRdGRM2FB7A+vX)yil}e0m!+m`kLa`zpCZ1>3F&3q$eLK!%Ze;VqJnDw0Cp+bxhmsR zcAd>4qMK=<*ItFSR!@U+r!6(>JBbn8VrRl z)7$U6tzrFJX0g=u>*!kzOd6Y=dKTGHDyBWvC5^;NrP)C9DRIVuk_ht%R#bvf;;i(i zw|sCm-U87Dz~U5!f87SBt-5NiEAF=Ip=q^=adirL63ulsvvB2PiSt@@z`q6$f*dV* zscZ66O_X{Apie3@<3~ZPLT`KbJw;v1lv+F}QytNmn#CUR$;z&f?MzLA*|rr;P9>zF z4Y>EzAx=6{v>>UrmEyNDk@${R#{64)VH>}PJXGt7e&BTeV4Es7wMntp*Qz{;n(oJK zU-b32aN)`@q(5IFE;*3f*hxddw{Sv&3VZdnbn+Uc%30L^0FpL2T7Mqzn`{P|etxa3 z+T1~9;7dz-1UFk_nXV79`ji$&J}3r136ZJQ`u3z;5KE^c0Y2uygl{q zK6hN%YTubY%8Os!rov%06K<;^JvHczHe{w_fhb|jJM1NusRamhoMtiY<#Km;IxOKv zc>e(IqJwX+(>1u-_QA1CwWHQ0Z2Q$+b1hU?&Dr3$G6;Se<~cd0-U|e+EjZI9VJ!M@mG~<- z3ILFOI#@tRo&fX+L{us~ed%#(UDza8Q*1Sw+zPwY#phV@Uh=SD{3SE!V(>A7zud8t@_Znq#63>8jX$1QC(^t1^ z90BlP_;~VI4?6kRZfJxry!|3hvAS+nI&Q^NscNk}y353_wpuJ6YRMHSfV4-LvtKd! zE}%BV?`1_KudqV=bo*&OR}b;F)L0C6`|Y(>A${T0Pmd0+7a3mKas<7;4w{V)s?Ltc zrcI@6t5~x?bBj4}Ok%_*eZ_meO{pphN2WpTn-BmF{w?Z;-c|Hd5%)2u{@bt3kFMWO zytj94k2^|)%W`b1+|pZn_hdZM9Pug+p|)EIKRTXhj3rs>f5nz;C_wZ2RW@g*2YtAv zd};Sfqwh}cQFb#|$8)r%>f~B3cEwLV53zD2eIPavq^>$2CL^hFg{Ung0z8tSdOE$d zqC-{vuC#dXT@I&NakgA(#JJ3c((HHJP$*g!K?*?`1Q0<4d^`2$PVBm2TB`GEX|k25 zWgWgm4(iW*fsf`o=F|Wc>h|Qa^JnfMrMAt8b&^40)j070WqHC*N8{N3U0=4k?w{>n z|I_sW9xc_n7L?&0NbWn4+^sgX?69I=U6vBiW3#i&xq?#S{-pJ3d+1v9Z>)S zliSzx>!>@gNZ3B_Wh{)PI+T0aLIBEKNC2NB-?w}cKk9G6?m?I;eHcHpGNMg%A&QDL{~=5PJ-NpKh-jC`=+KT05*ZN^p=z>cP%?08ehO z84I%KluexwWkE?=@BtX{Li-$JI3FL&u87DRE_sG5s9r?Vcl7c-cO+=qy%zFUrP=AT zb<5imTHIAlnAF5gLjImYTxmrf+=j3gqx2?uDq02Q6Gpsj%zFz4zbkZwYR4Vq-tiz;b^dXOJW;1AVz5f8GY!!H< zqqxb(VD8{$5+0F|uM;nj>T`jsoI&*XP*@*n{E8oUU$bVm{(^<=)@HwVu?%uu_s*9%~9mXY-;?Ue18!B0Ge?^#BLePc>hNK1v;T_SwiXc=wNW-G296tJ(C6ZSKTc$zf8W z1#M7nW5ilmb%iC;muy>8$#Fg;1%A8$uBdkrGLay$Bcg$$Hs(;xZ|#4V7q));ut=wi zSmXK|@*~aKZnl}BdVSjLol%iv4U{D^8hw7#Orf^hQULKjMM-IEMVo;Z1NS$=Y``B7 zeP7jB)*KbdR6M539VN*L}L0sjvCc!@4 zahs7`5iT@!Gc>Z7+CKNVkm{4%g3#6*s9%lQuga*tTX6J0G(~u)?U!oRxeHL_Yxy-% zENiwMmhSGct81NxNJXV2N@zp(Yo#suPazSCoN;MsAu0`_7*0!mc*tet(f4ynJ5y_X zDK`V~ZzA!Q^*++x-i`*B`&8IT)u|_0%!M|5nW&K6lxq7RTciQBs5urBie<&G%dkQR zTUK$MM*X?-OPlR&w&0}v`NI3RC)w0o=)06{GTxU^+V$v`Pqep`i8toBvf@&ZKuAm_ zp-LY*Jc7}cC#?yALNR`Xd!ZR+em@~nnlIXh{{T<7zp`D<)@$I*+4Q}c%Gj2d*Rs;) zsJY?R-LShZJt1$VU|L*00R=uG7#?KLP&b2hbjD!5*9@v{;**x$-|cueQP-xssb2HF zKK}IkJ$~Ej8m|`c?`&Uc;iN90!%M8VrrcbF$o~NRb05nJ>V(HBlin?QJ2uop7#+%0 zTlO!qM1insM*Cg<+>KqiMANocU%r=c;n|_jhY>QNNtCMSpG=wS_g#wFQ=vVQ-;(k_ zlMLCof`go`!E_eu_TzK4!R8pTc4$!5$y$z`u2-$b7JiZaUPPzdb%U!*Bt9SMQ{?8tJZAXyPvsGTwVlKsG zyu(4qQk18~9!n}|Yldk9ECHwNoOzLj3$(PoKZxgy4@H{CaVyz!tD?R79BgzoM)peW`BNdenX~w&YrcaZZy1Wn+uu zu~PDGn|}7XeOyCrAj&MfiuNpBN`02lUp^{diBEm`q6@W2bLQ>lupi-|AN>&x)iRtPH!zts{ zz7ywj;{LxX9>?0}Al_~_T#LQ(wQ{!G?V6)uE^747z-GBM6gIR>$An}|kmr(rau21~ z2|h_9#{_u1wZLW+X8!=x>qUSgYcj8Oud!{0rbMYW8|JGR*y_ycwz6pTi4msQh?dp% z?b}&Rm1!mEGhT8D4*960dH(=R4*43L$ZHdPcZN+8AD6LH{zv;mv)!Pswg&A;(-Srg zw)5V**M7Q1Q~N!d>|38nGBnsy;ZBBE;Fkl%rv?hy%12rn!lka*(try2C3XXXZhp)w z)5+`I+t_u>8k;SGt82TNcd5d%+TF0OYC0W6d*_|;X{l~TON%BdoNTFn($SDor@1l= zUD>ZsB*3;9sYZkL(YA5!-?;8ooS9P=?_sK!Sq8?pS8Ba;ACoN-TeH}hVql47GCCVA zw(D%iBrU}+$g8%Vyk&8=?p|p@aJp-A)>FCZdv=`cvjM%bj>4781fV)t77?6`rvfsN zqMvii85#U~o|d76f!vm1*Cx&TE7s+sV@TZRG>wNsuhbikVJNjL$&)O^*|2EBt@Z*rVUr=H%(bf2?hBa~Cf1CU@O!`{c=MhUhiS?B{Q3qO$ zRHx`+{`lF~7-gSkzU{T9L^zYfKlM?Fbt>|3B&W>vGu${Ji@z$?+xVt-s_C9W(qeD) zarOC=ms-;ol$U=}ga;I-DD5L!G~av=7ZnsCN7n@7zg*GP$V*}f^9hCq?74?j`!uQ4 ztn7_e_PRPa(5>QW4AIb3*4@@B;4LM|S7>F)6Uo)wiD} z@qm?&KB*4iFq2dYa6>Iv*#f8gQB6&x_-yj6>)c&!yswaLIHho_#8uget=LD7iQ%uR zZYxi+($vsb&ZKuxN|ck1xM~Wp9v1Xj*zL_n?7qtNJ&w<6u-!Myy`lTM*DC2|m^G0s zBB0NWXBtI>=3{x=y%I!5iwc?+5|E&ztgUJ|_o9FekFp{sZVJKDzT7MIX}a~*zUez; z*fsr`J3BI(t*obnr&_6tnLZP5V|3IHf1&TbL?WhzSy(a0`J-H<5I}(`-U* zd-kWs`v%L+do<^+8UF)5h_ZuCL21_8MAz$+;C-iNdkiW603f8eT2GM2kR*3f zj#_@yGKOvIZ6EEfi&4G2zt}cMc^%z?mb#kCite6~ii9^#{D*7Zi2@WBT47CnTfpN! zMP*06F+EP@*{B2c{S(Hw#dHJlSrOVxZF^{G2t!RaJW`Ya;*_N$0027<-MaJjA)2eB zN_k5t2F|225&r;i;k2aXeydJ>4nM&4%{nhrLCW)c?iFZ}O+E71!0|~>aJ3bA9D0vJ zNbT^(dbez9y$ON?75~)rCFa7Qg zQ?I843=)TypDg|v{C^(0V|D6G&~IVrrIG&t^#B`7Wgg>d2Ol4eN~>okHDYH2d;xe{z-B~BkONhnDG5#RLo?~<(d{0~(D*F3ik zwh7!~Tlul$l1e`x5<7nbgVmr2Dq5d%CX&AdlAj^p1`#oISdWwk-wj6pa1+*SeC3(;FGLes%CBx{0j>vZMmY?JTfU)Lw^jzmq zW+CfzYhUEPH`yXdpRe);yRcV5n$29<)wYqOvfRllOH44g8gWTWjx2zL9_mrTbJt+f zoC``McpGnAhC)H&j#}~$AL~wgSNpvMGp2HCLsP7yFyXLT8*wngTyZ44Q1fc`$IMc+ zoM4W+VW%sAXdl6I6PdWDG(3x*0u@*w_8?7)3l~F$F>Q(m9wn1Ul}Y}O08UHUdTvyF}=axx>N_R zT}MVykd4hkQ@@hiQ~QhJ{fCR8^6iev16b7`l&CHyY_^?~9#L?mm~tA9R;0^Yek(D+ zE+@+bc0CWmbC`@ae}vKmb31;jMRU*GFR#$+yG^$xP(`BK+jZ?~)JjXu%w{^U`_21a zYWCPC4y=Hd&u0oxPaQcIV5gR>wzB7b9H-df>XsarK_6k9s40zHWg$xc0PB(vNhv>JiXdy9mU^jWNvU=emt5qx^kH@n=d~U zJ>%@ELrsr0vXz$-kV=vOJw8cNO@DL*Tqs%lxBG1RM<%D3s2z;j5b|7M$6farSSm7D z4Ys26cKlWDJlIoh;D;2G)kcK&^h(7^tvSm>)>_)Q5jp_^4oZ+4K^GqX+G|JPs*{yd^ z`UOr6n1WZdJpP=!?&H6QRmmt}bgbdfnqRoS6u+6WL9FB&2qdGhc-lX#G2DiM)sUj4=E@r$yaO_{4X_Zzf0j42Ttkib)ELX++xK1g4>oVJCi1EfGF za0tc)*&}QBL&pzmyo*0imn&hn()CNdqMeC#)-~0)k?7EVrB!xPBO*M;n|sB#9E`UD ze1Yx=JuuNEfh%3*CkX`LbRh{yun0(QVt`p&k+Nu57%wM7d8yjYkKW8WlgiSvXGT6sIa3Tr_E&z zsbrNUDN0nOC?sd3hMAeAg~|It#!K^se0wi&Ch4obsCv)pNlBP)+0cA zSMCiwNoGP-GsKV5aq{-=TUSKH($wl7*)stbCue1S>3eM+{{XI3ZQAS3y+?2!R2dJp zTUquVTMH!$&OUa?9ZGs;GHu9aqNXhV=QP^pc5=OX@=W~_y28Ve>Y8njc7(x{h>S;> z(8BeeZo{{U_40{IK>x1zGs>TQ*W3xmfCZ{m{^{^u>k z3+;+}0(Wh<1$kBT{XN$ABUGf)w!5ur7QpVMGnApkVcG`oqoAqiYblUr_%^ZaE=SY* z33uc!4x#uZ97YAPW4AON#^pm(ee6(C=-hv2yiv}++HAE1Zd`)8C04|XPgc27BMC*T z8S&hFuj!mpW5o`-QiUid^n+vBlOo&51AA@39Mtd~M%&kLH8Lfn7`8AUOYkgNZcHgi z8AGhRfa7i?oOV)F6f!#VXHu=ESyx+BL@6ux72}Yv466etAY>EYzizp8BUS8n^P=EB zZ;M{Ic1dvoMYg}Dpp%snkWxS(9^em7si8wf-b==-|JC&^YeM0?l0j%T60afg2R+B( z@ayxTG+$H^B4c}~omk9g08&V9On{JpI~6*!j@`~j=kV*Q1$S!DjziOLG;yq?mek@@ z6iS1GCj%XZJ#(BMs4ThVTC#T9lG+?)EAnwaI+fx;13!T5FnzKk-ncfKS+w@iznZmr4bIdfHr@QJEn*1htCjS6%MJtoz*-C{DZlhmC0ZLOt+fCt8Lu{M zTgCTnEE|~9n&@&eY@jglLY$PunF~jmNNG4oS5Mq)LSlrH{IF_^KM;}tfJPf)t)5xa zw+Y*i5^_$Ju0h@<@w~gkH&3vbn$u$PK)}Sk zNH*Pql*tA7GUS*)Z2Zqm-oLUlM_!v!-uD92MAbHvK^6-;R>Z5Q<*ClsJRXi4A(;(^ zkgNo$0e_>e-{nA(`@tLk0B9TUM5ZhN;o)*upgc{fFORtAk92nu%2lXPz^Zu>mh;So zL}3jSvgCqZQW8N4E*~!tGuJ4PGkxThwFL_2%YFgfrTww%{7%g1ZEiZn+&k#Zvtax< zlNDXCD%}xG_E}r3d#!kY;AvhCVECvGy1y)cB#sh(Dnj7yP-+jizEYyRtmT-LHPW|= zo#*?R{SxzNooe-rMQhGbdCI(cI+{$@lJA>d+;43yj|C}8K4Oy81m!1pLjFj&0C?=) z3UMEeIm&|aA0kxh9C2^9-fOqI_Qj?%GDSsYV6?b$)+^Daw_f_CpX&I|QrT%z76XaF z`Fg`r4%NS%2Ob_&N^O0%Dmhj5skc<|FDCKiTdH}sdtG*e0U{{U>a#@hEKTJkJi z)v1!de3qHBCs{LG{eRM>q&@W$OK!;$NLwlFk0lTsP9%~sZwo#=JQBT*CaO;yDd8?amoJx zyc)3?EPXlu0Im5%pQz8V@_Sxg`nSWMvn$7fT4RN^+w3swa%}li_!bEmtI`pN?%WbJ4wo-rsik7t* z#E6CtY3}Ie0MlwJ#s}KpE>EQ69xmDTeL^=C@hv{Xuhd%8u`xRhlq-5U)KMOJ4kSm6 z>kP^YbT+l6)q<}i3@567Pyt|F->a@VE|*mcvu8v#g7%)>O-@mw#%h zOi=7q*K*%^%b5?Df!WY<5U#X}f6#bcb1tv^vTPqQ^jKAxrRIWF%Tzv7=x? z_4!9N-w@u4RcrQZZ!eRl>!^}z8HAY;VMIj4Ryc>;f`vBg z%=xkutR=#f6v*lU47jsos+l;meUOGxEAVvv={`?uPsD|0OU=Vay0>rqwR-mybVtkY|ib`91+ zm9Ad?`yJ^@eqv-vYD=TV>$#*nzv6JnI9EiEJ#$CsK(Pg)wn00KAl zZ-zu2%2D>+!xuaqu5McGwXVHl#>=zH*^> z>Cuj>05}onid%W6`sV^Jfbf7u$cZj+y`Ifr+4^4rJYTgju%G#-+V*~|9Q@v1Kk3g~ zS6@D01o8(rDxw-dYRXFfCa6$9ju4} z_SDUuu&fVr!~iOLk(HZayK=xXu4a9WYobQJYWCQ0A~UaRn)cwi zy1h-UjO1%kkqwCz))SKI>m7ZD($l`$Tuwe@1h3}n9_fQ)UbXj32i*88W{ZI?wXN1o zmcPqaG`wLqX_dLm;<%9Gx94p%m!voQvIvp%FGx{+af(lpiAi6!d^(J^Vq;PFFb~NZ zx~eSx$Y@=StF=qMxlr{+u*RdXSW4Hat|U&ci6%^#??iURhs+60{ac6+HIPz9P*jAF zf0uGbB#$3Zh>d)@F4K(>m=I#Xj*?k|!%RjBIZ#7M2u@FIoD3ek?h4?!bphNDgm)ZQ z&V;2$#aIAf4*4MZU?1h4x%IfOPqkisb4dEA7A>^DX~LJ4?ckpjjOPRboF3!XtARq`UbJMX31Mvqv{{SqGzd8XzzN+u20*Y3lX>LM%)#hY6m8Td4mzRQm z1o|K0*F;HO+JsY=vO3&!l2(-DwxQxO0akK*cle&K7_Mn*Z%-Lgm+ddaAoob|{{T{d z6Os9J)}p!E?^0>GMTiC`K@H2vNc9jP@VH zx35(aHc^lc=%i;>lj60P7we4p`us=u=N(=%!E4(8{Y7&~v-*jr2_VR5vItu8T`rA$8vaI4X+!eZ_+engD=nVO( z3JD7!k`G;)aGe7h*e+QRv;FZx)cFj(Eruze(6g|)xIHE+YJQ2=9Bh=xFJyRz{K|?# zJV?UH$QAr@VAU=|a!5!3lAXEAJZ%n+4$(7^b(nh1s#f)G#O<^sL6C;j5VbQUPKMSJ zwFI9P921VM0U}w8s7@)Zevw9fECB54P&fb&{P-cbh0t@(K-P z!nRUA zC13&Z=!nb!;^|9WF^kKbQ!DMJM7Q>ziD)B1L zJN0PkN$g!rtjp!@D66NS*zEa3Re`VVt`_xcsW%Xsi(=wV6qv86(1%Dph(S0$y)<;B z=KN4222zciZ`CxKXSPkpWUJMvBdN4KcWo`0aT2Fbi)k;sq$4XN1dQbTI(Wd7K_PZ_Wi&WPucDp@Jw({E66EQ7hR(N}l!FW1Q>q<)U2t9{&W2#F+Q8d}Y zBCHj#=IyAr0^Wc3Z95PtW5<l-;psN=H>^ zP2DvJ8l#)s-JY&KlGG7qcD2i7R+vrzq`&oEUeQ8=fl9ovdt=wBktr4q>oY1wv+j$I zZ|yb|Yu2^bdd90ZzCG6B&8#%ULMK$twoz>hSX+*;m_-X=Kh+*yem*EyRF;ICWBRf= zY3I>M8T)|KtoX}~d0$s){exKK`+atzn4w5*))lZ!Y7!Lq%D_~0xI>5poTPwyOtKlc zEs*A8ikRyBzs4J`$8D)0 z2vhz7K`&*5Ni3$9pK=@%t6ke`SKOmRS$jzGqubZI`72^lP?rQ%l%%KX7KH^iz&`7P zx)83EXvhZ`?CUWrHXm|48Bsy3?DP39rK(-Ex80za3$7Phi088@=NfIbILmR|`5s%T zN?KRS;Ysb&M@+E*S!|`$-*x1zACD+wZ2N}C8lIYa?8U2+0^}}ai3uuYn2g3tuE<)_ z3W8cniAXB+1obf!BSadksLLO_?i{Jys;MXJkpBR*?)1^O)NgUt{HX4sHcr<_VQj}? z#j+zQqNkj2q&3|x1Q2?0p&}ohJd-i9vZwRc5ms&Rv}v2n6zp~@g40a4hnVq0B0JEt-9rCV=%26z)X%}u-if3D9 z;<{uhRkNb0-{zlvw-zs>sjJ3*(&9+S= zyDq_Pu+4fMWle9?2$71@6^Gw_=}!j|+7c21TUwN{fR!=R8FNW!T|;TU=Jgua9oBhO zDAIW@4%F_MCsM6U+oa92`Zg?Bau=HeJ2fpf=XM4RTz1#n+jJfZBjjdC2U@a3p>yZAbFyU^5my5;G7i>I<#& zEgaozciXm>(X3Nx`?a2&{Nkr1A%90=irDfTC~qyL=N(UxBgFvaO7R5re-Q+Mx%xU{ zEH=4QFYoO*$ll{Qdcsx4VGG}0a4ig0`NI|i-gKwHkr<`b1gMmPJh73L{1b2psj@kP zINN7Y{yOFDFO^qo6IOQFiwY*9Op#T2Pd=7P;m-3g=Cs9&3@ym=J*E3@pcJ1HI}whA z^rRShS&_AT)HVMAx^5bb?#3tG*;m(VknCrpVwX{1&0VZ|e%4B+oVeke0~G$T9ZNll z9!Ug>9SKl2-pN44T+p_v8QV>^l@4H5!%bCRb7KIuun`K?*(^nLF98bkTsKAm$j5Lp zGe5>d9sdAC3B_}5AKli6{imnhZSZYjSzXi%y|7T#&9$!9>y<6|jm@`|!)i=O?ilMK zPItmqym%o>7nf{YfxM1vix7OehgPp7^H!V1Yt|!M$Gg}qw=pgH3QbG%`OEKGV3Q_J)kO&GV9ZO3>QUryGbzN+KbXuKW{{W}z^wH$m>Jt?WT#d;;K{d*% z19rnpp@%9$8wg?P%8=TLc!0_ZeZUK-!~PSHoO-q^2$ERrQ1(9Rbf|)!rp`Ua$8|AQ zl5Xc})RUz{r>w8Kl}aYh3nk{84@OcJq@{h(w*o_WJx5cvm05>7&^;BS`@FiOW&PrD zjC-k?{eG{%Y!hQ_c3OROx}9oNn3h{5O576aU`WbP>!?EucgXm);FS{KDNqhONien; z+3b@ur&fP=JYg26Ubw8Q+cs#|G_UNJ5NWBMlO}?qB!^+jnR3#Wg1}-!4>YFJ=HXLL zcp*Uq^oO<7E-7|rx!{-)^}%#|6Jgrb#JI1NiSR6=Gb#ku6_(y%6c1ce zc6D7d_cDO(N-Jr3XTeQiq-5i{J&)oKr}OKVQcr^~Teph~y5UY>Q$j7UDGep~?qRnG zD)K)BW3lan>*_jv0@4f6A>zOP*Yzo|+Mypbg<&VqcT%&SzdI2{^;tO7qKm@^5<_hi zs7P5>NBX_RXZaj<>hKI5cFc-b1XJ8AaXps$4OQ~9Nq^Kwk@5!WPn=ojJhGSPGhNl%7f=`G&1NteQ_XO?~ zy1uTeE-y^^(m6|U+xO`dQT6$I6Rp_Jvo!M~{{E#_x#Yx@CB;6M9AUHlBn5e5uL{XNxnTlUw^j`5`x6pdVOdmKB!1#f=<^7O1D(>@Hlc zj^vcTUP_`o%dLGw31Lb|ZEc`-Pf+f(jLRG5-~OOCR|4u;2mqcP9bBA0_S2seZYC7^OIv3b3BZ;6%J(BqV78S5&ZXTWLuY20OKV#Eoq|$i zC-w;mVHQoIX!2Bu_MU7ZejzzX>!fNy!F+wO`X$Xq+WTECp?$n^w7yAWV%#)YZE8>M z+HTTQv|CYFO$_U`H#P2kL|S$u!)?SnDmvP2mei1t51)`JNtV1sDY?3WmlIrlldb3N z-<8-_(=Sue{e1sYrsB&kWrsCbYrgq zT%FtZH5(KKA_ot3(fotQ{D7)ow|$zMRjA!I4iuKu>;5>4DHU*LKJ6p5YIe2RK}?}= zoOrmxUcm6k@=CGNX-+Ibqp}kH#P4-Lapwo~UmEPwd0{+7tL--zwmZu!;+8KX#bTZ= z*J&2bi7_U<8B96kmP-=Q5S0;yH|9Q0uRTa=V?f?483$n7T%h+KZT$1Bafa{2ntr`O zwjNf~wR&r9vD=^9;!#PZZA{FJh>pi`*V-+s!YY%F!6Cqap6eZGJDM8PoBXUpk;ARN z5#6Wl)0$h{CvDpN2On!(iqDXEuh$~@Dskc#w5Ve#z zKS_A%3vUCUZ>T^JIn;G^Z_41UvNzjqm&bK*YNc)3Zo^l&D^s$tks`8um^a_OyH_H? zY!#HaNl16t@D2p1G?xBRBdQFf_@iP7!9}TfN0#@Gb(*Xm zW(7{MYf9>*zKF~r*-Lt3XXG9}01qNl+?jv?+yMUo)ab;B_39Z+9oPgMaR`=$6K$m@>)Sso@PI~loX5=coW;psTlxe#r{#uGXiX@P8i@` zY}GkmjrR@Fiq|T1x^0q%>Qh@A^4pTTbw+);l@yKF#D!fO&Nq*+f$n_&05a9#mD^fz zlvq9A*X1T*)8pY;RUdEr99xR%^IoTQsGRq8%C3N?6r)`>wq!V|8E5|h#!$E0Bxl3` zaK6BF$5cxi)1!PP1P?EjLCO0*9ye$h?)TK;?C&@&3ftLyDUywC%0C_BA<@xnhUEkVABuCnIUAB&8Rr9-?ZL*@m zm3vOXtT7HX=EXkh9Hl!<-<-sRPAHQVz?7(@6goSetaZf=o2>x$O5vMqepf^7yh*lK zR&XrtIQ@#o`+`5|;cM4U%7a~D4ccYYJci{V6W)sA5}>x0q&?fo3eT69T=1O;Cg`|w zcc@ej0_1xeJ>O^B?e$b%?>t|5rO1gx5!kSzPq?+4V3Lwh6zfeQN)oq}1FtM8#UK@9 zs-0m&fIlAy5E+KoQF{LXw$4Zc3HPSHcDk2*9aeX`5x zkgAk>4!G-Ogsl9F@lQ(~Sho@xQgafM?kX=~_KV3^bvyQ{FKngNHJygK*|83iZM)Uh zRx>Rl*~6S^WGO9Dc&UOUqPhP7>lLVv4%pJxj7!w|u?^yRtrO}3n)pq*l)@ys+A>DRr{sGtB~vKRF$cQ{j@aKqKe9jx=Bb8Oa%~>-i1uJ zy$gDe$o1T{#t%?Qyn9~$*4s6WnaNS&O@Pd$OoHEG)&OfL#{6b*E07%%|gQ;wrP`Rjr@&eppxFUPa z*2!8!jwmU}sBLQjU6iBPdIb`UWLs)1O+oQNU*d}Gdx*KeS=ySJx6^V3p4)dax{@QW zPgGmwsl>*N!ZNocH<98~kC*~6(?V|`Ls7450ECO}#FZ7{-X!E2-?mA*ropnw*15Bj zYHTfcjpR0k%ZajG$ME;o+iD3bhJedBLa+mWDfsjys~qm%Xg1&z7vEIJ?ep#9XW||E zaolcZ>j{Uq>(x~ADd~t-M0Mm8Sjk>QJ1d z)?Mf%9xi?m5iHyrZza?mRmQxNt?&DvBXVxpL$O+H)LQ<(TTQOl$b%9LdL`H_x#ucF z>v2*QJgr&4Ngg93zg+X2Vj?0e{xvOs`;>`L=B$>F#1xosYqH#@hOgmsDQ0@u?SA*k3~(& z`yCQD2CpXV8vf4B%bLv1*JIhW@7*?Mrt9$`!+qE@U6=IDroj-9rTg*SQ%h3Tf>cL| zmvHfG5D32BsiIiF7u#>9`$yTG_0$SF+U`Q8gu2-mQW@B!YwjxUnnktr%df82?BY*~ z{8!SMe#+45on?LqaJQVLOCI1>m*Yz{N9djH!_8d!mjInz-9f{)Ibyv}leT_H3vwt+ zl7G1wwQJ~9L!= z3u>F$`(~XNVeyM$dtr3Mn#SZyLSssg`;(1%E8K0t;-$6nfz|&2n%En?3wiId0y}MG z-j%h?Qc~7a!NQ?b!eRtOl%*fiirQL6QiP=g&=-eumRK?Xe%r!wJk^s z{ZAz1grpPbdmMlVTr;iLvD@%mBh7680MWeQBi&ERTONSt0Dm%j{{SAVp>^GY|Iqa* z&lwO_gp!o2Axa;B>^(aC?IPf>s>R``$Q2-;X5DifxM|^eH z_-6@9Bw0kvNCUk|Za0b=J*P?3=dI-2?~l)oK!i3{g*jOm%zQep^Z?pViSLu!u9!f` z84Cr>X-*1FO>swh+TWzPfps1`&c=Rh2`tEIr;Y^qkkHU$Q zhYEt$KIydGifsyA(szAtSlh2%q1E{c=B<|K=GeCDvCz_FF(vmJ4>=uSwLIDqquU^m zI_{TkD7}kZZc-9<w3x;E)1x3SdU)7ahC?KP62zfz_voMERC^&#<46brS&qGTlUmQONs>}%_T@7 zM#oMHgOw#6|blPFuMs}`1iD28&RHYO2 z&yav+Yxx6TnZC!1^{(l$>|?IY5&RPGxMHPc%y=m) z^!+3sL!N}8ARVZ%39iM=+)1b3v8rvHpQ`IyJd~krP+D6=i8Q5XE+s{mT}slGB_x7C z2jS6-Cm`&DArd~|csY$e9{%qv>cdK(J#}#QWZAH|j?HKisX=LEZKkflg+2xIc`UzYyB!D07)aK zj+tk`CCY5dFUUV~yj7s=HQGzNMP24JeEN3)jte_;>j7?io0OVi)RiUj0ud`K%T>LVNZ&*xXaAEkha`uX(TBsNdypZ zLF=BRqC+agbFU9CYP`~iBT}np)|i(j?x0A**iCbO^wgE(+fw5<^E}#AR@m;ej;eG` zIP*jT&YWmm)x_MRGJGCA-)eU0b&;8yDTof0AEb~Yv zF=REKe&KmrspG~uB9ZOQRxVRHMu+mWS+rIa0dDw~lPBa>8B)WF9*HBNEg3VMQvh(m zCkO5ih3qD5b@4e4vFEiIRyG%}e^n9D7NC)0>oQc>VnB#N4|^+LwtFiFtsNN#d}x6N z>HxpHZY{O9v7yu~*}r}sxmmPCxRj^ss${{iw*9Lu&2~D0Qd9!aLP}inN>Z-miX9Tw z<8BCu7uywP*K=PM+;392)~|1gGjfR{Of^+|Z>6^-K~J2>tV&ZtGtb9PORYBImW&@H zj2v^%PEiiXfJk)`=C8RfHsLy*rFXXt$=UV&az@6DWtQZusidLbr4r=FVfNuBQ>_-8 zTmB(R&ySWmXlTkrHY))B3T02rS~ayCE2Q4Uh?lM)YjT(>TD_a=1h87IQoIISCPEXO zW4P)$WNa{W<}6t8=!fcj-NoDf!8=yfHiX$+#%=iwHe$<+#P%XOBguZYREAq-b47hcZF@D7RzQp8~qsZPgQ z9cdo7XWYGd&M4K9>)!(+nJtaw%(MQ7QsSwKe{eAxvAslFD1WGd%4i-w-+o#gF1ax z8~ZGFp09~zYRq#MBBU+QmVTjamE|WNFv^_?2O`z!!8r_Da-Hg2-^Tmi$1hXY?54e9 z*q&fWm03CzD@0XD5iC_%GD|J9F)>~tw@WHliO0a_rPRuoOAL_tXI7iPtMrtw-`HA8TC_WWzp+Wb{5kz3Yrh$*4k}fDplm#vW%;@ zO&;0rdU&}(yRFq$8_u2R@zIHRr=H@HS<<>yIcB(?BYbILZgQdxTTzA z5|&54zZ7Q+{9;UMDj$_u6Gv_Bw}sJ~&$`VSI@X;c?lsM(-*q0r&5u*osBERorFM+6 z-Otv-aj_|e;X3*duQU~_$tpq=4@f&{$?)03Z=y12np=L{S4#aP6CICNx)D96Xolk$^QUx>yuI>uUA50 zaA!Qa;}IqWDNVBCen3e+g!qtqcOZT~qv6#wV#Rj?;eY?p^$n6!3Dc5o*CwvXbLY&bE910ImLQ$&9qliWINu{Mk|v53&5sDNaT* z6q$E%nu7s+Lmzby$0&&A#v!dsrB=z*1KG$ZFV&7%xYRcY1dp^Y2Z{&l2Mc9lhw5Qpj?t1NSeK{wcBw*QK=YE4X{&6ue4hQQeDQ| zIR39{ypzcMX+2lA&cm~rGKXBKqKRkj&3U$zv^L~vNm5kW3%@b;@URPiCYNAh-Y$HW zA?4!!h*tUbt;;(BvH|@J^zPhWv+4$zp6(acuP`A9+w-@y_t;l-q zeX}c;Yqf|`Yr=9cQh zrn{7_`3gS#-JZC`I-yQ7mcxF-b>{U_gD)l;*jxU`f^r=8!dn#7)fr!S8*ajhUX9IP z9EGUw`qv_Fdrq;(wmhMza`g>8X2)5t>@4fIl~d_Hr3|{nhu?+$2ilOIB{Lx|HnbDs zq_4EW5)t9Inh_$Ps#}lv+wND6?KM6{x6+RNe@^!MO4gL-+-AwHr`e~~&!xr9vWlcL z59k!b!AINx`JoH_Jrg(*Sg-^hj8kTC+&$G#GwnZ`%`I&WodoOT?mT&{>bny)8#Ps3 zT`bCQ_>j!gD!yFDqJ_KlEv^cJ{PH{!ygAhmaSEN!;^g=&_;Tn1=?Xu#yIRpsEGTLx zdmnH%+?#g$>TTC0);h%Y;7WB$3NAc?^F$#>DfReu9bI3vvHt)_=-&kx$P?%0U+Amt z2kp0$_3mP?m3bb@(^I14yY51Tx}BOTYh6XM<+|DhD{w^NGs0ifyXPa>C`ndSJX;N` ztqDcOEz!OZi`en%tj=BgdcNPLbNq;v6w{pK$GGeEM`tO&Ct~XJo0C14)TY!>j})k( zK8h#do|J2Vz+edRVuV9p&+xRk;r>$8`MUd?wGCRAeQ)=xfm5MMvPDviJGxDF66dic z$nP}M?MS9^wV_G**>I4o{HmbU1PGGM$I0lG>9++B)V|YqiXJfLola}C6Yu#4M5Cgl zkd>?H<1a`TpFN3GTM zTMaeNa;)YR@>JVJqQJ*RyTMfJKdu5Q6{G|AdW-4CsX7Kb{Bv9`8 zRYm^*+DARRq)5?gUZ|5E$4h%&isVg}O%ynCQ*UWt6=>8-_as`OZOv>l+TKe|FWk#` zQk19s&~kX5sOGnaMPuy0ZCt9Y%yLaaQ98m^#^CggLbGg}trnu~My>YW{mwK;iqy-s z<)@nV@U$r_O1zQaQ%_bcxX|=u2^PZLU3Cu&Q0!cDTdr{n`pkH`zJaAuCKlNaOs8VV zvUSN#ORr%QOOF&sOD(A@TdPq@$B<89)Z7UPbM-<*5LY8Z`#j_Z4Th^B_?8;|U8d)G zt?o1SyT`+i?6K`p87bFNhT=nzh1rz8_;J)J30X@;ZhV~*)(-o~K1{HXZw6gGqVWy( zt-0}T#U@Q?g`;sRe1BygDPNkVw<5jNt$h{{XGezLT)r$xP*LFdvT|R7yoeO?69b zDQNSJ83d>juXN)J2U;NbgSX1qa~~fH_T;_;+_t+%lR+|;9W9=Luj-POCD+<^EX{WH zt5#IYEyr41W#-F`oUIB$3Bptqd{ApNTDBw14{)#}F+5#Fv@f--uTbW9^UQuYu+-C2_ZzCi*YYdHMRBbz%n=Wn&;q^Xi}QAKLE0#JeV&Chk=goj(}T*ive?@#WplwXsCsZKS^B zYY8idToA)xINVgJE-d60(vXgZzOW#+CHCHw8aD(#ZTn*6{hO2F?u*(r>l)ggOt0T+ zY%OG5s&iG*7J?}muS37L#ton={-Fp`+&J?{Q7h@=+(uC$t{ZKrlooCZ*X3R*JJo+F75_AYCV2ztmXJS{;KQZ?g8F3K3AE!KeSOm)tp`H_B6WWdC>m=xE{5AF2<8- zUgU*WM}8;=F2rRjd1@+I0F?Bay0MrW`lSYq`Y9mbIpNL0^z4i@t)G~xIZdPVs>@8) zir}a#`TMPZLO^hK0YkTLoAbM!@c}5K4bRn8PyM0YK&a*jR2+z?vNtkFy;sJ;kfZ!WZNdAX$k0OYuBuqfj3URqK$J?DnwIltk8dL%Vu*-%w)M1Twf(1Hl(=Ihs()e zV5EDI5X?mw`M%rJ8kge!VZN!2m)VWt^$MDL?UP4~Y4z8(HVGP|j6toNa##${*WH6Y zHH=vhTaJd(+BkyA%eRU&+gnN^S?!j)?% zgCbLmHkQ=;iTz4JJwLPl$Ea@c?wa^aophl01@l_I^_3G%8 zg5V#x$nD0hZf}}{jsg}z$jLcTNbWEQ$v>Y|(5miwGXK)`Eln2d%eP%IU>5|5PZO25gtm}EvR9Gm z@IQxDA9aF}p}N}#%|Fp3_DYGsCm(e*vs z+iCRL3D?)tOe&b}vdLN-TduhDmr%rZ8flQFxZ}>PEu{$sN+bc-p`#g2kz5l15cfyY z{8TyOwV{WdQqq=OP(fPpl9Z29aC_sYi4{UX(-cLQ;w|GH4z=|Sfa|S=r_3c?lCqyr z4m%Ur^>{TXxuoe~A}5Q$y51uxLPETfppumN5WfEaE(dd;hkmLeY(hsjN-f*x%}^p_baQb<|>?zEiuNXW_b@6{iIQxq*5eyp0AI|}w{fv(0` zM4Rufj$ollSAvqcK7QCCN5q1!Ufog=mSP!BLW)Nf_9Zmi(Va|&T|iqeHbRiJEM+T7 zhCu`nK?fZ)OVKQYA*$G@e|2hvUe^oRC~?*)KB<#2Xk}h5DKY&0#RQRs5IcN&GK_^n z046s(MO`f{yR!OiTZ;-@*l=OE%H&Q=HdgbD#0zl=TZJef45N=EQ3fISCwALzt4m=| zM{~1OQ{3zeEYMUYF05RqzKQIcAxAZpuAp-H+%w2ua!=DxbcKU(We zI~f*?wER}2k2MC?w7h^5p5;TwIUOL2T{NOzl}{))8tc7oPSY_8*DE1CWZjaipNx?i zs>u&WdDop~=Ndu}vR9J4r9Z4CK}if?Wh}Qm5=doL^&i}44{Q^6l~(U`ZfjhBTT^L$ zzl%sJq6}LqN*YRLrS&!x+M_5eE62K$26}U)CjbhSj80b}N_L)E)V0npwdLqjo7=St z%Fo?cokaUG+L<5BATBe>U$n84>*bE!KAcR8Vvxm)BJsH=k0owWcVS zNN&b5ty^OOMa9GmE~OwSE4q6E525H~BxWLu5LUO`na5h5!$YTR`|Sk=)3hijT-PkD zV@91gseTChcD!Sjnh}!YW59ALoU9~ z%L-FZLM_KC4=B8qcqiH@A$cRjf)$K(GGI_H3a05k>G)q~+NDryTh$fqEl#Ilw`@DC zOE}A}u8ChNJY|VW^ZuAuzwRY!!b%cIBzNe~M1Uz*WWqSBUq<9T8dzSsp#xr`JjB!l9h4hTMk9;GPdEs7)@LZx5(r_>O~GCv{XS6E{^#YXtBq~$ zBG^&PwA&qavi|@RF)kE^7pTgt&okf!_!{6d7Zfi*Pxx2hsE zaDd4BxR)+0xca9IU+o)Sp$^`|mh~pA>m$9cvq>??QjnPrJXxIci)F&X7*-aPF z3rd$&tZ%r^3YOm9?0!(8QyL^^W^FS)^4xf_79BHJ~L7!L``*r zg{YHeN{-Wv!(ru*1UVsXq^J>`gNBBT*q&&RO#)Mnd8&(ixZCxafr?#|TiAALsI;Z! zJnYKtYGW|ou^%ErQdc3oqbCJJ1p4&z(IC>c>K!eE?R0xdxUx4(vRuJXNj@)UiA;wEiI?IYePk%2?iS4EVID!Ln_fHc~ z2UedRb0;10e3`Jc`)O`WuVOueuxx85)X07WvZTkcjLm}#E%>h#9|zhBZAblC>QmE{ zS<@G1Dx;$Nt}jyrn-S#6i!ro44fHF?E;8bL(6p=YQb-{6$spfNBK>ye`W)AdndO+k4|^6^ty9w7dudiVUg{OW8^1@!=PY5~PT))bji2x(|a z-dD7=kff(7J;?q&kHe>dXI`+ZMQ}x!LYAVWE8GkO`(a}NUPB=KeShKCL_?JckS~fT zg5Y_@IO3W{0l>k*#&h4dsRye>mCQiO7&q^O`I1TW^!5H7ST)L=i6Mp5k%f9^vWX-lk=UH}&T;wm*$FQ?VR6shPK&Z_ z8y6eC?F5axk1JqZH+M%HTRU1?xsmjuzEibHn+T};NPV`S%Dt7VI8UFNeb4RFj+_W~ zn~J_#R~9}a9xKn+c}d!gRa2{Rmep4LW%CaZZhXVKFJ09b;$4H?N7Pb31+tlOU$tsN z(^Vmv1us7(1!2@-K5r>LC%f`SU$R0mc{txv)M|!cHz>*CYg<>#-QRj6b;TR3nG@^k zII8)sZC1s&P2Ks$O)}Iw&30s4Q4SI;L;mEH$ZhzMnuw%fg*Fx9fY?##hO{VUCy(00 zaRfh=Uw;+ML8ug=e{ZJbLeuTa<5r~9VQIW*`&!(+4^LM$X_aNB-r1zn+r*J)UoYHw z36(AA%6BEz{{U49Qz~8+j)s?Unch`-G2G&uhV9E7cR2S;YQJv(0Ny;SRcCj?PEc?U z?wcgNQ;Tn+#%?WYo}{gd^=?!l*IA4v&TaLy&OTKq-6=wq)upH+KXrcBJMZ)yP|V}c z+v-rdZ?_%iRM2?#Ho3=2s@QC}t}Gr^Qwm`dEVejXB@E_`gZ}4~i3pC|#UX1_yi?|o zuRv=pXgPC?n~?>*lE8oZ{e9D2!$3y6xABZ?t{Ajql3)9PZg$1b&Y~h>SytOv%`lJG zB0}UyLy_KLgvDEUW5dxt2~w#E0wwnbY7NZWaZ+|MY(5GTuyH@!Cf~=Lb;gw3ZLn(= zd{@Jl+BM$GGDUk)Eo@wqNIs6a#LHQAxv^_qN?dU%LGuV-kI#%J7?*p={0NuIVPnX2 zBjB&1{l4xlYg})>ZoWrPC`PW<^vx79X-_Pmk`@&PqO|mR(GTQsc=U z>v&TQmFVilzZ@%r^UhV`2(l^XWjZmtw~_M$vk zuCm;jNsS@)pG(Dtom)-eZMMGz4yHeGF5&j-r>M>3xf4y&=Ir~gEkV|}MQ3kc+>E=Z z-*BlFzTIVYRisH1{G_e)&qIPcZpB1)+bDE9l6+L=I<=>|CR+sB#JxwJen3D+yOyI1v?Y8~*@QA$`nt^5m)QYwfp`p>ova-O=An zLtKTi?o9GCGIdz=(jeP4FffAhV5?$V<+&+_Q9ae z=8x`t2=)0)B~aVPx5B&SaIW<~?Voq!Mb|=mW|_O*Y;g72Qc{>!)yv%9zh=5a=nDvL z!X6o4kUl=<7CR_(Bd9+iFLC8YQz5eOR0ie1{Kda*JHI8?@e;VbiCZ3zd0(Mc+t8xo z-5Ts$h?5*ss%mXpQkzuf9b`Nfg$C38L@&A+>p-w42I>z4(fdX5evGd@Z-h5CKGu0p zj(=!+w{PT0SJt)ER<@C5y2I9wrPk3VR4DNwA;qaB*ApGTX)95}mEA>StPZ2$Zj6>e zh~S{GxMQ88bGEa$Ox23@{d<(Hwu#eVUDd*)a-!NS*a&_tLs1bi*`cW|s#}ttB}zhr zUTIPimzj=2F{ehqkwi`L-|npa?~Zvbj!Wek+V2%=T%WIVLmJyg{{Us2+e}a@l>vpd zIttrU(xae{t6)Z0SG=VKcy@E8grdNb%m~}vOdL4A+)#G@-8UAg^~j7=(JpL$Y2SCf zg}F{E+Lu+cMA+g*RE0DG*0rL_Ivh$*l2M!-q;*M57ykgu(Y_IJ;K$ujsrz5&`(1pc z>enb4(Sz_o;!10C8lsb*8c$8*D~?#*?(Eu`H6SZUQLbK_7|hSX$`n-u5{!v9S$weXesc+ zVK`9$tyx-->JP}{Z>myksjd6%{{WnMuFBHV`$g4wfWhO~daYC{YxPTh!ev&$S$52K zB}ahI(?NAGmdi)QYir1@P5%I(pUD`37kl*yfoCIv=%2R!FWfY_Jdd|;6|Ym?aumwd zE(G0`{jPttR~1pv?7IgTjLA}h%20-y`CCeSmZf$~by`Fbtu4HXY_jBv1{Rlum*NDy6@FnQhuKn=+QMA`_;{CaWgIBpsX<}m@VWN8 z?cbmEh#S_;qqiQDYUV52M!5>9?b^ak%X-}uDJ=lj*D3_3OzCgD0^CG!8DIo5Lcnkn zIFnoh3UN;1NOq66P1@&9)+%-G9@8}UnWnhbY$2|#v9IfTcIcOUBwHml zzQo5%IKwJoZKob8Q2D)k5!9l7;USHBq?vuUS#g~o*>@u`sv}Cbc9Bf!dYjsoowH2Y z_6wifT6%4Js(e*TNQqL~*n&OQT1);;6oe@VM}DnMQ2u8P#CzQ|W<56Ox*u-f9j9RB z_xTbPom_gy_gxQXF&$H>k@WhsD@c zP-?%mJ-R0u^A?jL_L){ZkH!)7iph!hy_RONCi(vWdE!|M_OWQzFbT?6^7>^?s1uB< zLVBl^oHs6kmC4Cmd%r)oahD}=xAygp(Z`hcG!k{~o%vBK8A}A-5ibNlhV`wlUVsl9aJ6NWznqEQc1Jtq$N2DQDT%Bm&qebWgW#Q_;5B`^Ow! zYLc(4tao_k7Qyw+#g9?8%deXq>MEmj{Jac;G+>GU=wRD}4(WOyLuMQbEt8uJo}5wKJR-R`N4r|idhyw@JoS>0%?Xe?_sirEZYw`wET zKd{|cS|-voC=%nfE=GdYuKU z@!zwgrh{8!CKs4t$D+qWD_bGooFJ5Bd3V9<%a8@tL8=R~#Y~v#0Y2hVuaqkoRt`w~ zvy64gsb^lVZdrNH_h6>cU0vqd!ctvRMJX!6h{4BvABXrJsoG+@jhFw_^=?2%?eYT3 zy|g5xC;~^RALZ&g{O>Q?SJO1f{DH2ZvO=19^X>;41w{>|K8R9|6s-3rxA}C@3)#~k zfl82$}yo*eH(SvIUUptD z%MZ(j)6v*^OHDZ;K@r`hc<@NRL(vu*Z3a^)ETMbeEu6$^Vkm3;^-gym$sqW1o8Bp>o@%cdY$8MBN zrjSw1-;p&QI;WF$wAwcwJa-|s>_)KctWKKEdrJ%h=27p+KvICf&QDJOWE^bONW_*; z;O*5DAhR}Gi`SDX(p5}ImmUzGdQ3?UMk#3yFX#6Z(NlgoDoF~*euSJjTP?XE@c9!{ zl=kS!dg^R?_(Ce3eU?-ldP+WG;7&4g z)gkv5bQrrR!+ie$M^c)l@@}Jl!v6r=cd#|RTl=|nU|LyN2TN^7HIwIrg!?DWPIx4F zC%Mm0Eg27eiy$KQE~b~LVdWcJmOU9vaDeM z_aJm4@(2OBF_FpqWX8s=N>?IlOzlzIlKa}q?V=`f8-{}9m98mw+ySHlrR6^;1fHH+ zWRO`XcA!l3&Ryf3_l{w5*0r_3bC0D(dSbR|4Zza#)6;P!@jXIO^qFqk22aS&GeP)!UDYbI#=3$!IKHy=US{3zz8H@5j}QFBZB_0^rATtqN_y(m+LAb;KQ_qy`pf1kySQb(Kwj@TI4>;@0`S~R%Y=x^M z#VU_iRrNOUrjpLkDZuG+5XIagP>q|uoYw(EG-an~BTg{4YM@*VQ<4JaW& zE6<4_fOFQAC7GFQtQ|mV{_Qv>&PL-ce1%5`P}L1AcK2s282Sm)?%0(jsBB>QeM4!8 zytGG|J-l<aG5X2)7qAWO+ZU&b!jdC0P8{& z7Ni5_l%FLe4zYoVb7GZ=s*76v!SU{~Ka>%@+Qrgo_{Q?Ch5Ne)flT=})r?s*+-6%z zaZB-hpdlejJ_=W+aDNnwWvxC!!pci?%iLeC=yCZ*>v*QGNt6^_>duaM_?}*1PN_Pp{YIt=S8V!J6a* zza{2bC}E|%*-Bk|+d)=R6_9#q_VWa_Kz@mV4&0G@FSxEX)gIW|-?nPaVO3i^{c^du z??|(G@mmrsxe^~@G-9~^$|R*vc>;!#Ql&Zb4wLXsRu68gW(*bD)VNb($FZ)I+{km7 zL$IZ?pzBVu@uJg0JQ8e`ppS52 zIq^|I?hj#r59QlEG-#S&8*R1GRvbYG!OsSgrF_TK{{Ru!L?j7ZvxyfKMp_-fzy#qy zf!vKZB%ihd){HE;+6H_vk@#U)Ir#Np9H_{!+)>Ex0F0%gl_+I-85qdU zJ%5jJ*G`=HE-gsb>VoClb!uF%!CQ>lyUFx5QTE7obEzq;ZWk5l@gaz)b&A#`IDqMC zNlJ=wp51#rv<$Ro5JS9fK;OKs4MH>2QN6QzG~|E#$hU&4 z@6PLGhi?@TDG#Q()dfdjDP;+n?D!z?V|jNG5vkMt^ff=@3N+tcb5e@mcp z^Sq0%SZ*DE(vUU|5YU;FEFpHF0$E$$YbrR8F)TRrL6%&Vwn+c(m z1UNCoUCs>exS|V_&!@th=|610S1W}VwdofU7`D^*m$`YX36qK@T`pWxNBg5{f5mHU z4!)?NV-4dd$B4t7aOH^o!N2@#(%jU5EsefDs;#Kwu6VGr)+O(7wvYRP`%fPK0Nbn4 zt=U@3tV~Mi2(&_OlWiIeTZov63Y?jYlJXUw>trD@C`hzY{%B>+uvFSyyMh(XB|+%|Q2 zBki{G?z?((cG6^Q8$Q{~nlqQyvli2`tTlSLRA0FHK826^V*4^n=uQ&if{97U>St4N zsEs+S;1Rjc(MMe2ZcdBOw$neiZ5Wc@DAn9(JEcy&0a0M-u>?e-8(SjgCCE`2jMK5* zuS|dH5}<^u-1idtnvuyvMyEbqT`Ug!;;i4eU$@IHMzs5e*yHE}VA(AybSPYHb_-%# zCIt6aY%88p!s9J0tcMnYg()N_Djm9QIf?*qK4}FTpG6$nctTF2%9E@Q3_Z2|xm9iM zSPm$lff7_FUY)Bzgw3lot8um@B0R<(ONlA+OOAWNDj=(%XA==tEGy!EiG+)7!|J2D z=i4^ZeL=|bH@+`KsdD(H*1w5qE!P@z)DmT0-_NV5Vbwb7Sd|Jah-nTstT)*Ra|!7L zz#**V`VO^EDN~I-{)k^8aQ^RSS+-Q&@I}WWa^A(d>6;$0%V|Y>jMmcEnpM9UR!_-H zhKwN=OKXmlkm{B04=*(k;KW9TnOV58OPlTuzuiW8SA#jO;sJ0sy9G9f)^^Hz?rs@9xqkHM*LzKeuqT&jRh{{Pl zOG;4!_5-8+5!5yF_Fa|sz;EDoMKK0N;eq&7d&dzyw1-C@(0`EIGb$Nwmpqo^jc0!`pQ8{ z$M1F)lWX7i8?#*0A;d^R2@#5rrFR$^>!8jfQ#*!!KL|(y2Lb4*+TXWb@>K@UV!kZg ztDqqob0bwtdNn-d%%YhhLzWO}tJrd$d4iV`f%WbWsX~;16X4pqF_?C7W4{*0`*Tex z2B!Z2owf??*?5zawhyyOyn6ot95#)#?G^U1^je1?(a4oo6KjoXwUox3V8NF3R@UO1 zk0>;U4jWQ^1`+~tFM+A#rtU&Q+l;L4DfH!0eYoxvDbhJlRNJOh?b{W0!6tM_>wY}P zpgAV)$t|igZY9SMryKJFhiL+wVGCUAV=^7rkC5Yy6W# zv^v9@v`uU3_K1(Fz1rsClWQ_Fk`jfw^^2={E-5G47*df_s{mf?LB`hi!3S|o%2`{& zJf_a$$Jdm6B<8a8hBOy82JGZ(b~H?lb*3ZCGnw-?74xD7+*D=MyyGtAvg$&My+q0; zEcOIZ{{TilX~dYC?YDxrIlGDX+dbQuY-sqR2Q0?sjUKyG*ER{$YvUbGR7A~X#mGeS z?g*t)(J#svTcyVQOL_26I&uvj4^8`Gq%6+MSbuICG#ZAIZE}%wyhNQA9I0(IpirbZ z5bA?u4(G&<-3;K!kXU6r{{U(N@f*HThPX?Tx6Vqd1dj}B< zSE;y)t2f??*kN*AkzmqWN^(-uNGebx#W?Cj45I=60PG1IkO#*8ine#{UzQx%?&)Pi zn?8m<$GPoPTZFB#AGW(AVU1*%s6`_%6D1N!unaz@WGSz0Dp)JZTTLac7_r2W(Y`6{ zh+;eym9>4gZ!+mP{kk|B^5y8fXQ|PzUXuElfn{r}-d5cH-0^LdgvEU@+(2-pK`KyD zK^f{IV=G9t`lb?T6N98^ct4f)j$W0^o2Hkm=+SJq{Yz?AsTRpLauUYBM{!u=@?UN% zO*t&RHI*mFus|O^QQf7gGPS@B)D)l%xglBy+b1IG{H;v&%yrsndcPpv@0GiI+jPex zx~o?wJkna$(Gj$@FnxEj>yAlVWeHM%QBX>DuAne@wg7*I(bNH+_N|)1}$ONMmIE?qdj-F$#J^pcN!7XhK|b zDhX{Q1iU#LdDSOs2zWlImM!UVqY1B&-heOij-7fX9y9(_|(-Tkuvs+4kAW zv*qk})Tq~GU+g4Lr*-^cEC$XacL?D zP6Bg*j=bGM?o~l@n%yVeinh|EhXP8*egJ2%&*#@9fh*9^p>@C<{Fj#&$)Zwx5Iv?m zzEGl*;zy}a$8(OGKo?%1{j2}h^}b36u(IOHP@kNrV<3fke}U`sIf1yZ*{X@hTFb=>Mh9?IKS@3Ne~8Cj8f3cW)B`J{Y!?^e5nn$g?W>=E3bOEH^R?8%n}`7xFhgh_(?k!3Qa05Dp8wV^}cLF=eOQ8g7( zl%m(7kTvA7=D#A@>`2H9SD^kNcJ=%^v`dPqN|YD$Pg+WnkPwoeOt?}=ARmYGJ#;{j z7$``BYMqd?@&v4?_gL{g{SR^KI~?^_DnYKdNXkovym>7b1YqL#8y%o@`%ba7oBruF5{NB?JE4~I3`1N26owmUsV71uxN=+Rrn*4{`j^w9EZZa06p{5yH*0o_N1J^hm2u4#6f@5~Y zN-HfQ+*a1xLibY=(mEwUG8u9^rMFTRkhWe*973=`C|W|3=s+W)=LDuKSf|-flA9_X zNC2%l?gF!nkI%nEy^0RCF0w+@7MwMZ>VfQ%22M|)$7A26CC!llr2eimY$i*x8EzuN zd?b~mGh^gzbjEFvqoTrc({a!dO6XW{6UteCeY=bRduz?j#F(Pv@S0!jnaO;UjxVH%? zZNDNsl&=%mcj+z&9MiG8A(UHwv$IOr;ZWSivX`h?8hws41o=dohMRp%xCkA?Zy@A$ z?~LReP>i=o#SNRt8k}9HT+;slb#6`m(Cv#A(PI$uQ0-K7$&%cKHlyt+EvyigcRe}M zkq)rlj3a2)*IPQ>yZW~(D-_}^t&=g67CPD>IG0}Y@NA<$Fi{xkDh^hv&59t@$dV#8 zJ|xCuz>?T~naFi3Wo;Ds2NK{VB_wwTILA{i3k2NMA5`US7je^HXICB%q68QC%~`7s9@s+X0n8Yn-rusijmIT^!mt^GpzQidiwkKT55`X zsnOYHbB_R~krl``feLM02U>;@UMsbq9=WAq#UVILk`kqN^as@T=|oI}ZXSUU zD%;dX2S4#+@lx)?x7BFxNZRi7%6MB0_^=+Zv7oVXx=+#}$A74mI)GD-_)>g;Cmmeq z$+xq5Ke`QCDUR*Px*r+9k8Q|%tv;1mK1hiQedOk0H0*^8hMH5#Kq~Rc!1Mzrw^58{ zU7yu3`wZAj;B8xTX@6GNq*+I5U4v`vg~n-1@^LHlMn6%{j(VAl zjB_)NiqQqz6`j+R_~VXTqldljw3>XKmE#_QHN@7Us#~C?Dh&rzl2Vl|AgKJKBP3*X zgd{~GXn+oGo6qHbEs4BF<4Jq{8$5|6gu4?>GTRfDmk_5ApJ*I~DX>*4(W9tlr{Z{od%WthhVO!oW#ij99(&+q@_VFE8J31gsbIR zk{9EijC*ZD(QB+t%D6S{nwxLesWy#%Vkc8<5E-$lnAyr)j`{?}uO)zl5D;EM)`lRYn(>p>qEQQ>rdK6aL+_! ze$K?nG{j44I+k8J1SL)-q^SA>>~Ia7yYDV$~WNeP`F8u0C1-FbM##asoih&zi>KP*lu>cmu$6{Le9Zfgx=IH3{_CJ znU5w0CD2K!RDic0B(W)}1xX7kND7bGbUxMq3Rt~&{^2fe88m^;LGkkR+(Mml?uEDQ z`^P?BBIkdukw<05a5&^qTiZa38YP3#+Pr=gc#fr&t!z5tURgrC0P^`%GuKX(qZmem z_R8&gx6yLfGY$U$3b^D*8y>G|dB)B)w@2ejjzzmht3G^aaOKDBuU`v7>gWHSV)(*iab_Bl;i)|K%nRd=S+jn`Axe3lo*LX`- ztkz;ke$or*xLWOEY%WHE^4n?aKVg7`twC!G@KROepreV?5)ll}eSY5sj%IVg{Hmmq zG`$Ou>^SO=jdlJ~bBmbeEplc1w~M}s6}2- zrU2$=ZX3n$d{LAn-hPLs|Xd{iA7 ziH72~-Xra>%Plo$D!$&XT*`Rq2~yQ(63ISJtt#+zm9{{TAB=#&SJ%z>{ZNZ$_1mA* z1%Ca))z(hr$P)PjRNi+j6zOsxXfZU#Eu@IMTawrBy6~zgG32d+z>6XO02Yylesp)p z?c@YQHR}Ezc%(5kz~H#n^IGMats{=2Cy)0E-Sa`v_}vZLRNW@R$tPe_oY_CZRJp00A24?~;Xzf@yF<9PPjmq+WoQL#Zry~vPt{jt6J+n9Hg zdpyjV)c*kOD;F=s27DyB?8l6xn2Tr40S&p}zQ?J4K_>;9?QW0m>6nUeKK}qkEc-H~ zzt%1GYNxde%9;ew)TRBJ?y}Ecl_uSXpG=l4E372SVr1l@K~LDhP-Wrb2>m!ZvJMV4 z$C2qRNuX^T}Y7hcVb&swN)*~ zUWn^*ddPX4-7@>!`9coF|xH?x+XL>dQ`^e?LSwdgBZ0&+Qrd-w57nTq9p~vpBvic9Is#=hfIm ztwalRsY{g05SdchnA>e2lERnolsE4vqMCCRi8ZI8*zZbkCu;9QC4H^#S6UYK?!%+m zY+bmv!U%z11%;LFU%SZU?7vF3mg=HTv98lmZLx}I(H+?rSM z9@}wJUP|Cywzq7uV_W0w@Lg8-GRhwx(`)rNkcgkGRYhuhI{ep|itA0yW>QuF^Fxjo zQl9ExRE(lc+STO$07Q>U@%BF`UcL6gv`*FeKyG|_F7IX>D_cp$60hBZHp05P~6V!&V%o@&Lb2v{i_P8~tqUs(a*a5Tg3p4RY!Y=rqp@rFyKTu) zo3Bu(vUsmxV#TeNf7+ZKqgJuh?O9^2$SVC*&ga3~~5TO~>uilr{|xM;+4fL>hgoUu%C= z_c9sPiT>^v^_HmBsM3-fGj> ze%I6Pa{R47jrGde_gcPz1COOej}9v1&7hR))4i2|l`y0aXoZY<_@}w??F~NUFb2PA z2Ak8!R_*t6Rlgy9wesxiyIXd3t1X_k?mr+@#-paN))_FUZDF*3ePH&lX$ zeXDas%X!djtJt@%s~o$Caa+~#;`L9P?ya5G_xC--ypO%?6uTE3 zYwSZC^c_gi!^XAXQx@GR<{@E-dLW8KPrLxmq1=<3CqM9{zJccrXN z8ondNLRsK$V2tIr96e90$wzZYj)XI^8&id`)-_SEL#Blq;dqKQ2PNMt=^x?MgdUTvXD@doKWhGMI*#|cF*EE z_zdx1-s!QBWm&$LT$3P$f#r_>2iLGSC; zKs=He1nA{UY$WAi`1bx?$FIX3I6i4?3JC7otu*G+hwouFy(I~AaZ8USKen>C{{U8% zODpW!OCQt)U+M4FvPs1%ROraHZ1}e|&@L+^CS_%WR^`^sWUIl*?<6?efcEU9C@5#3 z#N86Yh?(~S2`9lIk1Tf?&td-Gk5wdqrWw|$NEuNoA=C3Dk6d=gr^BTZ;)y*L%0r(o z>Pm_34}9c)0H#1$zaQt*u|N=$N*u`uN%K(sC%40_46sZ{#RA#3YAr^YcbhGfbrmsQ zj~Q|u4icv&x`@m&+h|IbwYuwxN>Y@PNf_yap9O{66Y7qmDN@K$@$&i4e1EX$31G3R zT`9;Uj1NLbr||0vq$Ma2qlKJ#45uI*5uE=3jyh_kBw1;U_fMe*D;}5!pj{VP1qlRT z5CB(v4_}T)O`9zcE>?V#<=sH3CkN9Yk=wWD)+c(&B|O)NS#dtmASFbAlaqmke0%zI zGaDiT9|H2eb)DrzZ-49c*BENeE=PH$ilsD{+xA{s0v`EPJd0{jNy=4)cIuW6l+_Yj z&82Op$vIw7gc1jl9|8EDre{_NfV3{4DS2_Uc!IV0EM+Mjim-kIrD9EyqRQWG2}v(D zlscdoQj`Evlsg2Hdz1Ne&P5gsv<@UVmi@#R97zdesXj^r)P$4p`1GL2B1l3ty{?CE zt^Lo6oS!m02BbKa7+db4 zptl@2OKB@3DpBkJ?s{<(Cn*yqq*7MB27wbH#FZhXxm{3RLSJ>X9Ib7%rFp0W-9!W5 z)bzPra7;-h)1}Lb+EVMXn@SWEq`0M|B|#n3bDUuycRvBt>``Pl`vb_i#(l{pgW~969)3;~C=jm@d`R!pw40L5oZMVf&_OnLmhh<{wzRaV_7WS6%3N9T zZ6(K4gyg8;4EOkTnnuV2R#56*Rnczg8rVO$p;TAOytCIKyJ;neUr}RIJ?iJ$V7lfU z@_IVFJV`1}4m!pXuM4tlwPhhz$*&8w>n8TNY{_Tp(XRBWT&`b z+)ZKas-2CNVu~T_s+}D(opC4*6e2H}aYP`6U?(^^^yx^D4^?0tC0)Gfmp3wX>Ycih z()KF~kuruIjA!Mt$XAJVY_{T@N`! zDVGv_g3!L{Qd9{99QGjh9ZZ#(lv`r&9pt2>_@H>DApZdKdQQjNqSLH5?X?!sLdo!3itm85ke?Et zh!_BmUa1#DQJToo2|-Fw3W5SbBk;$m@BF&GLgXRti#H`jrC@m^6Ox|l82mjm*Gy*N za!XI{TQK69SC9k+6shjrf&4$=o}LFP6OLi%i2{aWM(K0S1e?77XE z*CqYj-)yxfiz7$azqGja;&qtbZ-v#SxX0Bq84Ik9BHErLxl!A7Ma7H+CB>mAQu~Cf z-~QXD8Ae5(RA9nX#)N^p&3RqKh>!)^xVI|#`6?c#{_brWuJeDf@+R<`em~*beUCtT zs$HE-S(gZY{njSPh^AvITdpwza{CDVHl#2{I6c zM6iVWZz)rhY#Dg`M?vjF(*@I}>vzFf5A-Pc=ZNWIx? z^=NhcVFzZJ8H*S(&4kUBOt+r3P++_qwDejKJL=@m1KHO=+rUU)n&Gb@~$&oR3 zf0fOSH?nHnea2dhU5@)!(`e~7hG8yL{nP6k-q^j8+l-*n2V^-SJYdS=$C3X4PO`O> zp=v8VdNL7|r0nloe%dwd%z3VOxERL5?H>K0#1U-SMVonl9q2K+d!Inc zVYENLSL+-(b8B_F?Kco9EES>Avm0%zlQ}=WJh%#}oX^#)S)w9ZX(+smq`e%rw+eip z#*R`X004M!-No6y7BrU{KF7iT097x5*DFfI%6jTKqII%dv2|_4unfO7xS=7lli)u{z>7{r+LA5Fi+EXS25@+LeNq)C)mJsu`%d4hYjUmQZPwf`0^^b4>I~de?OQd3 zJI1zmo3Hw|X=lZp%*J7)Hx=nBQX5!tIYRQTi6BVX+&zUdjredzHEr$gRr^7&as@{< zah<-wLAq_b;=i*a+}K#w+QWT_EmN@?%3MpR5@l1ODpp)v=o3J7Z+o8Giz;PZMn~*w z0fl(^zaOf4Ib*+WTa}gf7&OVhay(%JlXY#UchC{{Y`9p%0(p*sZ7YrbxLivJn)gtueUKGIz5tf`3h3+=k>@;|6y~Gw# zHF}N0bjm8&x=e-A&HB1lV+ZHxGHgDk7%wGAL-6DvHuhgi5*$*x5tAF>J@LniGCZEU zaNw+Hx}QGlFmCxui;irD{iU~}SW$7~)(f6&qyGSGifh`Yratlal*-&os&U0-PBM~I zqw^C1645)o3H1tckmelqZ$hfg=k2?aDQ?wEZC8E1B2I@*U!!dm6mhR#g|n^sa_^-x zVJ>uE*(5(>BuWze2q^I$f715L3B-ry$iJ99VY7HcRyX+ zZ&z~=(~ekbZa|(G`m&{eQUj8M3i@(AwJ*g*zh0ts4pUmReZHvUOIO{!l{c{P2Pw9> z6?S?()vlDqR^zU5j=fb)S$Mivp4#nXz+7b5%4HQn`uCyzG{(X9kl%`mJW`WUsRC$m zbH;-1M*e%-casd*1#ouw|%mJcfEmiq4LDah~JJ5^TRxXqjF&GJWsWem*^ zB|ZV%xs)Fu4>#p+w!lTaYwpSD;En$O01EE=cZlB>RK((!`0j3{Ht%oWXSFgcIIP#I zD;BOzi7Uy6GN#^#Etc9>hhl=-f_zd6>V5Juecqo$txjJmi2JeP?pEEmJ>qVq$CGZP zIjK`c&^8LFbrT(tE)19ENkoeai9uBbg{dlU=-Eq;6Q6XcDG2G(oN`}(RWNJfrM4Qs zE6CY3ZAu>(UMjLTJ~PR7yQ|V5H(JKMDNjrI%P+1&ZoTa|%3I2ON`Wcy%D54cdx7on zu@w!2k5yyyhM78dBvtKpygMVFbf>gSO==#a9aXM=+ifmWZec`2Av_07_VamKSdQ+vn%$^jLBr)i(|#bR>V$u1hX2&-J0SbWXf2gB&-vjurP# z=KMz8e?=jC?cHnOi?Z}qb((` zZAn_3O8mF-G{LE*IzH;r=z#>V7pm{>JE**)sJJ1uYyHS8Y=;BUdI<5zvQI z5tO9?wt-0q0U!bBl#av8)M*mM!{Vy-bo%*}t(BhSf#v2&1Yl&~=i%EObLvDc-quTt zIbD$TU5Zkqtavy9?UVBrB>-VPy;JGbG=mTw*R>lj|I+o{(2OZbXe|U`Up708j=w(3 z75)5QdamZ-64o8=;zE7oC0~v`KQD(sP}P4yqgYbdCycn#hk_d?01!y-Jv*HKBk}6s zf+!TH5-Lh~&{0uJlpH<@AY%t3<{AG0e^miSM-fV*4Jl&*KPpH*>W6dNzhn7#>!K%e z=a2}35`qw)1gv8@AOdnbC}*mGHz*Q!qEW-7B#+d4_^Z_?0F&GOyYzh%Mv#ly= zAjq(~vx`+$!c*^0p7J8F-3=FNhixE*B^&) zI;>^EN?3ARHV0CB-8iceo2(5M9UCRtTQ*9d3 zET$Nh8cbJ^@)XpT!^}Ji3He+>3qkZ!dyd@+N>Lyi6|#%9kp0x^4eC1*c?b6I>~+9( zt*iHdg8@+79u5g1&y&D~VCSnq$Pm{^Sg8L1AMrOG@q}w6Xu8uBKfJor_H#p$B*>HO zB&C4liB7!fLrFM7Jp5DN#UnilY8lk0awwf|Txp~7b$lw_?^=toMXi!$)wuC-m*Pk% zEtexmVQsw8QdCl+g{R3U2P2~mSw_eZ6Rk!LkFLOXLeXQ_RKU=Z#0fghU`i2MA81Kw zw_8qdTtk7(tGc|ri6rNtGH!8NB}}kDz)ximqHuBiPs2WkpyY%ogF8h}`}9qnbrILG zLxS~WOTTP=LLo?T4!puw>)^K^s$Wsl zwVfu8F1x4eur+!ZUS=&#YY1XG6ym(xUxEN0OHnFPk98jBzfBNi@;6#@;-tX|&PQT@ z)$q?u!6T^P+Gv-wxugE(-}gwV7owXBE`Ho(7@|j?kB&XiQ-E{%W319Kb7a&NQU#%E zSCPm+>Iu*MIumkSAP50{6)srLwT!m!F0fQ{tqPr5OO_2l7&ErQ{`Tttvu?%CwM2;oGeuNTN_!tP+$G zlD{H^mH2w8K|Z)2AH%1NR&^HDw(1SvTGuwcep;NT+Tk~0Ok_5w?>ft<1Z9^(TuOlT zNf{p=gu#g;ZOP+Ae7ws=UQf1RtKaMfdRU4@8&Bz*Vp-F48?7I{i+G<%5qT5UkhXi-#JlhN*#JA+2rMT)q$oS{e zzeEWf77?%*sY{X@YC5IJd8S!IYIWIVKsJ`rGNl&@z(^hPPBG8~lnVqb?Hbc{ZQUk8QZD zwq09=Ln9suCnMLb9W$s{Vzz9m1*h`Ho4MN~R$x}=- zA>iVQFrt(xN=|UFl>(5H)0BA%Dh75cMJsO9V5Zp1+UaZm0AXw2yG!;F&>=PM7X8T~ zZVzQXV5cj<^6l%=9XS(gr_H@3VY}${RM2)SUCxHDTeee4s@SF2#%2tqy`OC?$#KBi z%JK4qlb?rJX_81}31uiMLX++#VNJLJNym^l!N~l7mr7Y+qgJ0f6qNjlUvBuvbKH0Q zagMoWYend21;%`+S!otcDT3g6C0_4ik)FVuc0I>@cIqSdI`;Jc0BZl!_3_5?!qegc zNF&p+!N~9V_4)o$p89l-5aryPp3o_=Az9@rDpXuWW>_$BfekZr5Zm$tl2}@EFTG{rjWPE3|#No|%ER*>r+A0S6wtc3pnBr*~}kLcHKSwDsA&l%8VmcSvOP$w9S9FS`7Hi7_uIgUz6q!flHn! z_aUJX8peYucBM#qy=ZGnE+bzT=VS1?3xYY#j!WJ++g_{O#?1Uq9A?jwqA~L#Hp}%@ z?5s^bAU7=;csS9*kPpm}k=Hh_ZZzQJF)}`13F2IwKxXk(e?0P3TCQB@N~`{G+cbO4 zKTOxII5R_|nyBnpY!YKl{*of0rHdC{kkc)gjujzm zaHVy$#7h7J<#ELF<%ab009z7zTBxH)5#_GW(@P)F30x#H15oBH3wE5_#9@)gdGYYO%wJZ+{?FzxI0_#`!Oi zZLjSvUfZ`GHsbsFmG-kGEe{823sWRD8Pn}2+meFO@gE_|duJU(Ua^kg{;O0I%~byY zcJ{5$KXR12#^t+J?ya*?7lE`&Cv1gntqZW>y(Pg0GE7;;$)8l2YIqeghS7q7;!jqH ziwXv7@vqS=b9GqOcCKG{?gn&A9jem5dPets2E$K`{=+rT?Dkog`**QM>|sQR<%F>F zGX3v0JbYHNrKzx|P68rtYS-o6Uv0^cM_WG6YLQ`g zDhrl{=bDg-(6$!6`ny%9=8+OKhhqeQQV>A$mvs;b@x$VWn%5RpXEn&Jq~-6qiwPSK zBkSCqDmJk%?fxFNZjo7Me$_K=w1(M&lL~8!eGRoC68w^u3G9^lC|&{M5L+u(%=nH8 z0V3P>`k@xQkGw?th^e}cwt1?LMlAIDa(BHSO3KT9fUinMEgcKRns*EyS1<9zAxiU3#bR>S+)2%`B4T4Dq_$K-Q-vux=|rI^RjDdtgCbcv*N#GzDcHsU#n zjz%~Q7kjBb;YU=AV-ZFrhVC!*N&y$+>WxQ_$(3AP+b{CPI-mr64lqZ6ew>m7fwrz^NG2$aht|{NHiz&E)O6Jo*jz1j-6mnA7v(OxUMMsy4CqM z$9=fB-@b5OPOdFw2%8 zRM&Orj-D^Pd#WzOPS_R3wJLf($2&ufxLm)Z>&w%2mnmN-g zIO@xVgHx>}M~L#}$6mtqdu~WtR<}}v^@_s0lb=6TWz58Y1*;PL{!s+Du01w&O-i8U zv$^c{b$TA*O?|W1a&1Q5%M>?myoYSyPc$t}*(6JGi!irZWl@zDIv9>T5Ehf-6+@IY zMF{ftM&X7dslqRYl(5y@iLj&P!`Ywqut^F=+NW?c0)Gl{var zTh}97drvl`HtQb9n2AbCLSFG%P&iH&GNw~(y?#-8hTmPca8(B%aStmqH)f4}LAp1* zzpd`@`EKr_nYvdt2W=R2xWT=WWt4_(99xABLGWQd&yR}zl;s8Wbs`8fy*Ya$8pp$~ z*sitvKcu|ZAaVp5nk0=sSbBYHn#{N9UeyJIq8Msoj<)2vjl*%JAqjEj3LBE6<`Ixo zu1#r0#yxlAiZTuqCC(GHjkBwfAZgN5$ZGqDHqPxnMN|I(vz~Oa_(O$xOch5_@??C3 zz&c(77geDr|Q;rxn{ydYP>~?l--lq>E;?M5mP0 zsp*etGI9knn*ORjo-A~^Bjx#=^1>+@M8c;7=5`fY5^psrjrQc-h0h&W-*Lc_#iu>) zd#5F?YEZREs&Nl7~Dob8o>aJv<2XAQF( z$HX$9ZN8c^iwf><0z9!;*Q@pSWhL7F*sb7kbuAXH#893saNfTMZ`R_q2g=7|q`9e_ zS$Qrvlu4EtZdgN$QO}Z-?hiilhNIq9c~_b)#=FAnuehxzX5Tnzsx2n1?|C+q7PdNK zS%P1gQvz!eCDtZ9<%mjGwwwlDU$mm1ZAZlQJs8F%u_B2xeZZU-HSvGjrM#{{0le+b*j=)?b3$AaosJ8y7V9`YkJQ z`id@*U;{A%Hlv^T#`khoSt+@?*avqqNEQJLvuWU57f=8lLf!iIRbwqWu z58Cd54i5TyE>55J^}SQ*+YX+`2}0a9K0)J6OIg%5lu4>)K9y@#Rw7Fet>=*ZcG#Gu zPeZU!;+%Az!G0an>&sF0In$1o8z~VnMC_}+Ndh8HW@s72YI#EFm`zmpB-ETuQFu`Z-LDKXqcq{LQQ3QxAD0-OZ?QC2l@ zUbSJtIHl?v!ux$!aPc0eVWV+p9qHD-YqQoUVAo1ZlK!-zY&4XXzNgw_-VNixC^n3M zK2SS#=IWP`JX5_<>x8zJN}L!39A*Zzh!~?1{S;B-UMtDTbs*cqi&3yo9>i z{Rj#|!2|+7$F8_ZtXXl(icwJ^NLwnA3OtoVSDaTC(hszt019u&e5V-ho~;QooQ0Em z+FFXqcQ#ek%|n~8Np5ZH;RD=~^Gr7#3w2pmN*ZY>1JeVy$Es%~p2KgH2vQ*)Ka-LR z4W)1Rmt=SkC6@mHN0PCVCAi=D^+b4L>Jlmmb4;8G*j-)NMtSF^Q3PwRb zK!e{o_4Ml5&M8Dts@+#!fwgR#j3|XW4%E$bYq?8tYDZ$RpT8kz4QXPuw9YQ2VS!w1}P*eij zT2z&!_ey~TXQ!Yoio_gK{1v2mj4T3s_aL7C0M9)&P0)5USOrN=GD?SJBj7RVp0;9% z0IdPZQTdXfRpN7;e0z8N`bYCbt$Y+h6f!bGi9PUh+;{%~Zv6%=L|h?A*69*j{#fh}Mkjg_DPJ%_Am_jg zoF7l&{(Uxg54kHO9r?)wi$J_3CmjM^73oVI#6eJbh7&WS;r|04|F)k*+Bw z9%a=!W4M0m=A!`tZ54d{gQ>ukrlHMAW5qsK`hGDGBZJkHetlk)lWi9D3j!5Apmz zEOkG)r!2lw2+j$?AdGe+_;k$JtP0U72=0DRla*uR&;hE6F0v8|mOvn!Wcqr3ALG$k z*(ByLphj`}Nc9-TdwTUbHIqd|FAvB(M~bp=Gw>hG3<7^2k6e1DtJLjRCUTdwsP2c9 z9YH}+Q1u=;83*ykKf|tgNyuK-kY)eX_7Xx$;i#yToC39eLkAzvuYpWc!GCk6T57Vi zD|W$tYQPEdLRZ;Cusx0jdmf@{SM;5*5!0g8g6GViAf+Gxl_Z|)Q6&0*Bh_Mzz`7|E zs~!ZQ1dM~_@`5|#@%8Q1pcgi%#;CkJ5JPDyDi|v#{n%5vQKmTJ|nKExLmR?bw+ch&3RETizp%P z;fJ>UNqUQJk{oAO;o0 z)Y7zET9Ro2Vfv~&iT>d25pF-eIcBE&MvU(z!>`?CHwFxQHEQ;CjaQVo%3E!2rYr9p zHQC>pVI%?L=xTN$+7TeUTvWDbx$2?${?bXn`nRH|HNUwoZrNMbZJ*ntQ%|kexc+55 zG@11E(KbgmC~+iCmoBmBZrDvshhBC&LIG?vw*5S_*JQg*C;|Yd-CB||lGU{sJE;Cb zPa1Ut%Jf~o&Kqo+&OqZmPQ#Vn;axKJzW&P7bY;j9otb4+VHj1(mt@QF+DUEq-&%Zp zol9OI_=R=Pp#We=j$+_=RcK1kz zclH~EI`i=6z?kgzP#I&&3_ykd09)cz*N>?_-V&KC?;;NX8pY|&MlxZ=hTD8A%l`H4 z&g>k$WnsZoU}(}WH9H!2+J}6Z z?E#n%waGQ*M)y-8pB=wN&2fI^cba|<+o$aOi!Lu9Y`kg4R~%RFw%c>;tZiZ;yNNJk zrM$XTAtcE0Ne%ZZ@f}!bz|Gp9bNCbN%#49>Iduc-r}QV0`6rV$y+(H>?iyydPS+;c z$7fb`6>55AZqnR(!nabwl%UHl94G$(r2hb4n9g)WV$>BQ{{U$BT66^Ma)oPLs-8jQ zjunq-&DXk3-EO<7-*WwQi{)0rwz{8N9q5!5wCijjnNBP_HN^a=N`pxLqlzu*#6}Fy ze*wRm(TkI9y@J>6pOE=)V&*+%y_i`ZNCkH2(ll4R}NYOlix`ywRh0b=w4=K63Wmtn2~`%Goxr@2 zewM-LO1P5~UWW;Bra@B@T=!>8k(Sn#A+UnlJdAXPN&)*xwmkiii3Nu8me$eTy8+wmjuVc&(_) zQUV-ESxAnqkus+0;pP*TXUA_f-iai9qd7`P;p_ST03N56M6H5+yAVQ$V4!_5-#rr$ zR(4w;c!Ev|!1=%7(?*C$y4-xp^2it@0!Mzwzx%po1Ug$5UlZhTpN=#9KMtBeO3Ml) z*OZ(QhQY^|KLq%%KQa=L@a_jnKs498mssTsF)IovQ6ObXCmoNWz~~kzhYRlK zA$Teo!Sx@<{CZ**vc=;SGe1AVv-_&$r8=`EqLOfhbek0;fap~OtIqG5zQ6<84j4ULa;C!PW$mI2G zj##O^5`igFNYBbfQ;x+WszxE1E7fb~gX4gYKr%)#@yA+%$g)XF^73yUKH5l02Luk- z$5JF33=;s=-nK~qf(LJkzmI(X0GCS=9RiSBfyF5aC*)BcIM1Q={{SA{DVUL9s3O%^ zDg_=&RsifX_&ahRq*eR_h+wx%H9k6a6aeas=HYUa?(Sg3Tc?+ zHVV>4NdN@_+@AeJny=}*ST>LsC1nc=SA%23sCF0`&&2lpaC&&v83q+Z+efrOPi(8y zp2QG;mV0FNU>eJsM=~)T1sNovL?<3#ejdNaf37Q*A>#!<2J5qD3Kk} zoZ-e@N|2xrz>d10NUUgAF|7)Y>)d6e(nhv`)g)UeR~rnCoWh*LGFgjdE5Mf{A#M1y z5E~xfh{}EkuA!|d8k_*4=a!fXaEb~wOMx+TweHx`q_;~cQJ618Nf=m;zYivoeLg}5 zSB$u*&8Ugas;aY%^ww3eY~uTgbVQiTZ#EW!6ovS>l_$w3xFBS8Sdc0d$tLUP>Z;`~ z5tUsH^+A8?VEe4Lzo&cu0ID_Ql2ELit_I6)ypge6OMC~M zOxaQ6#dyb28EFe{Ghn4B85!!5)FciA(IATkQv||??>PEm$8J-^2jzPy_Z$cqPm-~d z;uYH`uI;t`Qxfalv9;cr`wGnA9b|2 zJbaq+0OPhYpI?We>GRbn1xNKQQj1I0we3!ZAJWn4_3TztGV06AZZjzjp#|0a#N!z! z*Q1=sl5tpsMt#*4B4Z0Hcoj>P?g%KGA(lPj(hH6T{lz4!!3io>Jpjq=)5H=UI3Qe_ zr){N`eB~){tzPH45(rn9e5C&Xf$h=>J=G-mCuJaaNC_&&Rp@?SKuGn+On50QjASbr zB`4+s;p>izm5Oe;u-lf!a^^Cd32nIh5LD_z?zF)|Tv{8?l9Gij0YnTBA)isv`+!+G zE;r~;pvH0d^^DmJrEZk~ul{54>4b^|QG9}XpT|9qZ;$)>B2KiDo5`uZM@ zVnr}Y)krv`q13bQB`z!#7IHkw0rdkpz$YKiq?nM#>7raEQoMjLP6;HQ-4sd$pD%JB#d#AW01cc=J zgUr^mOaeyYScQgj8ailP06ZluiAIe%YY z8s2mO51Jv&b>?Hbaxg;I8N`en{Js7i54$Mi?479S!q75MQbAEFU#QREdPxi$n!w_) z>c}7jXUp{9XZho;DHLNB2Hp7|NaLtg7CXMhA6}1nV$D@k?}e;8CG3!rmeQh>B_OG8 zD+p~rGSrdZqZrCy$Y7WQn?_8ps`@4}!38066SO@7#Pwdyb>472Deyt~us# zrB+IPwKk=&LC77{6qO)_WG}cMAH)v0;ZnW*Dh2=7_6cb7X-s+04W~;jnOC%+=ZDOt5*Bmt z#yfuw{Z=KagvM$oZLGSmK=+iK_^;v#{B!xAhgFGnDGZ}>Cm4p-2Z$Yk2}nPrWC7dL zxBI%Z3l+_%93s(HN`6&)e(62coP^`B0Dm0y(*pLQ<<%9fSs8?^kDCrDuzZLo^?Ct< zeLfv^=?A*w)*F-XwINCcVb36Zf>VzlFX5j~+3Thhy;nH^i!vg^O3G9`P>$XJljc>Q ziTIAXV;#y9mI{r!wy&%En$y2SD* zwyy-I`h`pJ>>3dKWBu7*9y}SaHBx|jo$a?3Dd28e-?lDFl|j92?cB%MYpyMIwxPwW za+XU~_6@L?XzXj9RG(><9SD7!CXoLCxq^~#vDWT1AqvKfTNkz<aF!_-IjLcCL{?@Op#dpMp}Z%vkH!sG?^-p{s*{F07*ddP;TE! zIdc$XNo6U?$!rx_51u&@dnT2~Y1wNwoBnV9)4Sr`zM8dh;Hr%b6>ZWPW>QJ;WI|hv z``J+Xwnxq4I=SuOB4u6Q`JIN=p-Y;ryV0L+VN|=PDD2y>+wSpsvh#gqjP6t8UG`m< z2#V;T`e&|54WZ&MM=+m z%W2DUBBJT4{eFX!An2@Ul4R@b#D1A*VY2$-x#fD~$I$7N%Gx24kd*ioc`Qrt#~=*< z0BA2;`ZfxZY{!Wz%KK>L-P>s1oz{15Kvv%E{<9}yuUv20rqjFh^V*K5>f}|TG}tYr zFQv6av}4}#?w3?h=;-U|Mj^!m@$x)+Bmg%M$QRwMbjGgC9Y%}^!i^CLavmjmO>d3?bMPw7*MU3+-6B0uquLXeR1kc zTa_ZRGfk=1)Rqh92lV5f5sacF1zV2s>`^gebE?BufUPH(_L5WcI?8LNpCuRdAW^O8WtZ^NbaNCLY-hNLSrB$Sdm8em2yM}M(Ny{oWX2KPGiRh@RfGhpQe zY5OH#AJExo;%%{}8wJaP=u+#;I>GI0625gk1sV` zqtmEfne$b>%})?=6`e)u^(*@Qc1w|Vc40d?b?*CPGDLQe>xxTxDn2MtNFIJ9ryX(V z9Mb@ew!tKz1+43WweC`pXBvZC+c|?_);N+j**?2&pL?6Ia*!H2oG8Z*j@ z^U8g07m(YCbt#Oc_>`pFKnGyug*@umV4hLL4gTH--6ySFa`z)Z-0W?6D}94mr}0Ie z$Hua&-*Tn9BoB)#2U80E>vjpwkaRFC&V`u3KJwa z<18f+UGhVN%P3X}OX=v0u={9T-*>W6BE_!ivfVj{k|1&ht8I6%TWdSDCflM_?RtcZ zOEfl$>1@@D<;B;a!~MM1EXaLIn=$tmm4yTr{98{;_@ON_8~r4M#||&SR5+D4vD?tA zr|q|H*c|3vgI~7VwhhL0fY{_+u2lO>SD2Pa5gNInv0%rkc?nTwIj@jfeIGKLBgJ7m zn9x{T(*ua&Q4C|Y!;-u?dsUad^3N3Nv#&Oq%`!%}wM^LK>vq$rnv*U&)dC2WDg&&# z3O(0U+Cs)iR&tzMk`ucOo~TadK8EKr2Bh)NEnET}nvzZ8L#D-(nx7m;RQ z*1aFyX%``^$KAb@Gi$y3jJ@OCuFlu@%1HcOCtKqk&TF5#vYVK&XZyQO%*rZ9*DaYW zeHug2N4l2&quV3DRfvErF2svtZWIY$*VF2&iyMvE-5XY>w6(vTq0GM7p3rSm{rD=D z(@fVQ1Q@~*7uF8_O60BynIV>lO8kAmmXwenGn-)c*l}!C9)o$?ZVFu&miaEThqm~e zTbuOGMC8sl(7)~UX!Un4%yQ}^V+UbSTP&#%o?=U7$v)zcNcsL?ph(FK*f7oNTca`z zNd#{P&Arz}@w|QI&$tOT`viT@{?19X*jV9svzGZ{HP@}gn^r_RO zPS-Jfdmepdl|ymq%Mr)71~ts7b}5Kt`^soaQd9vU2n`1Mhj7`QlM!mwbNE?g#t;O3r+bZq)qI%0O@0JpNXQ zkORl)sSWdtc>+Ah+WyC^UoVC=X}j%T9MJy&ZEQPYBFb{-+^H=@r?an;&y*E-L6Y*; z%U~%0x7l4*5{3mjUaslfgT<-7=N~0Ko%ZdyZ52BW_Vcdn`v)VhX5yN*_IIC^ z8p%{*1sq+WZ5VQv+evi_mWid6s4EK!TD(E(UzLLfVHtV3ZyPQCtI_^CT}SyBhPNs$ zf_A*lnPdL|w>@)u*&U?QV(S(gbOx0^rjgpo4bnoeg7V^tA6}N6LY9UfQjdasg3#kq z1Uy?c9<97yydQcIGNbN3tI>`NtJ!FHbB<~^IhJzvTG~kL+BtTH(PRoi_S=*hdP+l$ zwo-+ERc9l*)N*?A^^9{8C>>FWDtlq(l_>~pC@5tLB$BT#${0SKa?Ra>?9gHymCF3c z(injtskE?GmEmYl%2WvP&!&6#@A&o314_%<&@L{&|IqdIUMX#5YVueFHlNENe~(`P zojR}Y1CvEv+avzJ3u_)hKH`UQoB$4gkm)gB&~~T(T?$2#>uVo52}touT)`fmIV0Dx z?Vg-CPcR5X;~+Mpl$Q!~hdciOtKvKU9ac$e zn84zTvV{VswJ+uCSJ&k zEdWB4kQB3wfs=#Wcm5}?y)nIW&RdaWB`XOjzyJ@Bd;#?ScQH)0G@LL2xo(ZGHh|DI^SM1Mus!M^GV5Zr2yK{;hWyz=Qlb(NKp8mo>hRT(8C*Yy z{)0@U*RS?B3!4q)b$ocz=P63_Dw6w1O58qQG4dxQ=hvs6shta_h+#xWWYTo~-VA!Z z(^aS2Yhyf_F>CIiu|1ZgBzT8gM1(jJpa~fRJyH{tY*|i5u7jtIX-6c-=+u21NQ+~4aUV~k zhiA1kS=uaGu8NoJlCRX6j)ubD2R*}t=b&{-Ad_XVAv;!~tGj;A)U9Hndn`sinl{R) zOn%~q0(^a@<#>C^M~Nc=SjSKKBtu}9gPK;iTh=I_x3Z?8s-u^5@6=t{Lx{vjW;>jh zWjNXrrw&OuStq|*T84L621Ol-22af@6LJ***+3@0;Nw5kLL5HR!wxs|4EQg^c_+~J z&sb`*#1(|WfD&3nHW1R?OY2HoN_#7zf{zT zZ?0sQ+l0av&X)Hd(9 z$?{54>J$%>PjTP3W7ZNP$W+~H1}$?@qqSJXMq)=nY8qo9326wWlrdpR7 z^gS8$CDtW0u%_09jHPH&atc&1K?et+m|n|P$yCRW?fW6N{g6oZ0zgl5<=A5%`Si{b zl2R5nb=1(Ev$wE~S6?3nT={OHh8yxwLVTQXr6b8o2^l`89W%caI3Lqt12i?eqrQ& zIxi*z0Ga4mDPeEZ#F65Zr66PB-^ciM8Ah~3Nj0A;C1go6=1OW5IE|`BgqPNq+hwMk zDqF5CSP4oHl1V234zYU#VqWNa?&w=~jfLF8Te}jouQl}z`Pg{0UnVMizp4`7^$&(e zkAF^s)5S1y{F2odHJ5M^XH91w)&#c{mM21aFRk(rq`EwB(GgwoS9#CzulYx~efCh2v(=jx3xvOOJ+8~7zLy1a9%5ZyUu=F1u zsp6A2k{kP-a;%-DO_K)k5fM5~P;h-fh~tZC52>vAgehoJLcIwDd^%zXuJpmY0wR?- z6@sjMNCyOW_>TQ-(n>&NI-35P?KWzuvyWFoikUJbwHc=5OYkzJAqh*4`(wqwH2?~{M`4rLblLM18G>Q3Y*gB{akbcO zBh*%<=<$Tf3h+sOQ>kHwk~@_x*A|o|AY_w{u>_$I<$@%m+@W5lK6(EDk5eZCoNo#@ zv+NW)bsX)ZXtQFIU#M*^SXoKPZKN$}Z7Nm)I4f8K`1LWSWLPH?!4`Cp;^&{Xgm+R@ z4`4ny?SYP#PDoD{stH-N(Ot?+3Tswuo>gQ^n6Aakj6VW$oJ462NJuR>mkUbAf{FAe zvW8rV00ImyjD$L~-6|?*{{YKK@9Eec-A1RHX9LA3GlErxB$7f%!Tj^lwbJrJZB*(I z14OODGn{rky)o2vNfupQumsl2mpOntCZ<9fP!0K#w4iswQb`^_4i{8); zb^p=z`Shphl;#hKKRNj1{{XS;;1ds3{p1hc%DT2tL#<;3oaKaioc^4GMtctDJxRc# z{)4p+52{6!w6W$%3dz7%eB^oq{@#bHMU%{tL{Sfa$^aiCJV^a11mNQzA6(p_#U)8-g?RZCq~HQRJ^g)p>x_Z2;*>}gDwF3e_jJ@(#PpgJx;nd_P2L&RWL)eF zJ1#U9UaX%mzRL{19ZtR#5g`at{8Ueg#&SI#&r42Xa+{o?>C6vx$*N=sh-&;2s94*F zH13?asOlAa#=k?iX-;q2&cV93PW-CNB)~?yDXC1QH^DQknmA?#M|AC$vsRRbIFhei+qPO7=q@``b8Bqd z?Ys4J-Lr-u#bvat#w%^{?|jY$dubhZ{{R{~K*XBMHGlj~DBtlYIFy`l9%8lhR~^6H z4>akpk0;yArP;Kpo0j{i*72+grA3;SHKwm*SIIU;LyBALRXA-{{Z)BAoNui z9dpM!RBAU{1XdfaS1!`Ur1zQi*N_cyc(#)y?LsiVCGI%+BoLgi(uvV>ULyFI4kJ-6=CmD)3`>;6M{Ojuj})n>t-Pr#9g~E2`FiHjfRvc= z@oK4>@Y~sW{krl#=c8}Dw+mk8mibdKD_-9pjgiX~sNTN3^k3r|NPymQxCuG!yJ@ z>$Od#&Mq&>CC?zFEOhbGi6)s? zkT}r&618`VKbo+)KbvOkJfA8?k85AZb^J-V!IP)e)vc*)y<+zs?K549Bt`NrsmBt~ zDe@#|#9;K<000^|5B~rV2x-IZcCCFDKF;?YvgdZ#BTU(A_R9V1SdF{xa!s`@toHUP zF0mZE*`tooixtKPwusW!ryKS_Z1{!ZebfsF6+WLt!LYDW{{Xm+^3E3VyXseb(l|p^ zq~f=>4N#QUr~8iPQ}g4=ZELb+;UTz9u*ytk3S3c;6`#?Ap{4+hE=%}eq)iSxU2{&W z%-pL1u0N)y++*tFRiNV`n4>jc?egKSRHLmARG|DHFw&csUjVzeYX0h8;9Jbw#CL;R0>Vz z4#T%Ag(Pg8nNr&j<{0;}?6tV*Goz`cC5O(E~AT z8>tG&;_gw}CH=x!>o;77J7;e4_iKX9L>Y0PhXyrj+;SvI^fDtwv8Qq?ZG?#-Pctas z`Tqb_yh~aDKrmxZPP@^F726&BsLEUSTX(wZ)_Q*3qe6CG-LB~zg8d;w1^)nQL5W?5 zLVO(xQ%Lf3C&6A`K0Ye_CA1-$Eh|5F~S#7obC@WhE^$1IePeWb+0Bn4^V6=y>-1(}{?yqWa+H>B! zyK=Sf8bGJx1jylycBSzhy_Uv&O9WYYG+J=kIG0e&f2IWcXjh+zD-H|jX#tRc^{L(P zrb!^M+mfg0w+;C`o1`i0wl&?ePnV->d}pl7vzXL}^?N${RoNwteVS<^dvghY-;`!2 z*e#5ypwG=CryP_H2!H(5#riV17aVK1x?6}Z?I~%rT8=v8eWKfzE%%MKqiEsh-+9XT z8tSFpIrV6+Qz5u%j-egqW#=xfULI=;@DD( zyfsa!4Zi-)eOCiYyXF?4eM=6;*x*=eXr!JzD{Y%=b|Xu$X}KzNA@!vETMJk~S6o`~0Ml@Nu;i%rek+doBFki?nZE1g z&4*WwZOGh-cUfSW`vpCG`AJ=BE8A&W*{*i&h zdYmZ`*Kc*)+-tJ!+fUlgtF>D_Io;~tjT(_^>e^g+#^hCy{{WLEC|Vx+l%JFULb~LP zGV3-E(a@Qt7X$Jhy}9d}zXR3Y-t5cQ*T)TQf4}TDyQG^1@*AO*zW)HfNFR~)j5eTR z#eAiZRN!s0uOZh~nTc~sn%dZYy-{-HZnC_XSKKOgO>2vi_Q7QS_ghiP_IuQnIT9^= zx|)=x%7N!Rh>i7^Y(#Lz2gEY;gk!{b^*D_)9Mr8ozwq@yk_l`!8*W_lvcTA{INC)v zg3l#vTUDnX$$##4vtmW;mX))nWm$}dnXyS>xt~?_J}7_#e@>Ed?S{`*U>ufrJFLg( z->T6y8>rr6>i+E z(|h}iA|=JLc39C`?JOxS`vO8^eE$GUFxd9|deV^1CTzsXt--ij+<2zT_Je~DL+^EB z>Kt;eOXO`kUV5K+f9-)g4%)3krs7TP1TF(ql_^KmnGUryLRFvCsvB~YJEW8+!^8|{ z7{-KVquY!7I+@Jazv$lUvOe2WwXwl`brX0^qBeLiWJ8{tknh)}xYJ)^H`EvZ0H~!1 z=x^p%bq|=6ob|!n<@|>&oTq>|?L~6S3Jj?w2^ksi?0pBIKOWt4$y-R(*DCW0U5iUS z#!8Y>m7i=RC@A_U;O8U&4t;(-aOG*Q=yW9EfB(|;{lq14%7<{E3IR9)BOUtq6vNej zcM{TN2(b;KK_n!hNmf*QdI8vD{JL5N?e^rDp-iLa_VT2uC0)`+KZlRUd_|!0s~g)stSM!@hM6bjHBa$-}qoH z#3?Gm&I^Oo5I-)vG~(-vQdLD-Lb2pOs8X+oY#_lQ)3cK70)PD#tOnlo2z)&w4HXl+N-pad05$w--8x&J@Y1F1~8XhGG6mo?yoiH z^&Y7i$m4eDWfEGdC#~?G59$Wb`(KRp%0*ntjW)$ltJ!QlA`AZjQw_oroDX5|>NFFC zp?@+!J^G}zr7Mzts|OZSHEFuCl&2M~R;kA=(SEY1jb&ENfRs;GQgb08AP0X|G2f=m zFJzgNYLkU{k63#CR=vhr%_6pUn}1>YI=IaVjx_hwHm8DH0bVbEPZrq^@DO(W5j0@olD>2|@>R*biQ?B>lxK&JKgp z@z)<~`xUm~MWawtZQB}FZ}ylq(WBT+^H5U#`7O2_aH&ZI`6%R!p8Ym*Kys9m;FbQt z(T3Ok_B6^b@5Qm~9mrQl7M{(5v=JXuNZ) zM5^4??rrsq)52~ws+N3-n%Y_je3EnXgWtceTk^^3YO_&IT#E=qRe6fYfTlj1=@i;a zMV}9E+V;rtDDmy%jAOS*Wt7s0ft!kmS8=Bt(^AjZs`MRhw_memOj%IIs)o!t4Hc=+ zY32~pP_+3eM+yXFlhG59F7-s0qB&EoYm_nT>*+P>>Sz@Vu02F5_>9JCBW{pfLkMXp z4W&c^pnx-hp0SgX=shm8U#e==Pu$F_)+%ddYz_xD2~nXi)05YN36!)TDbs}!mkIU! z`fSGglAXy~eOFbXj~*=swNpn5DuUxguY|;A+gJ(#No}Mg0s__C4~hIwM3X9|awwIp zprD{!@7U$~S&Q{Auk}3dw3PdcKNTw{^XSfXtX2{*_j>5Uqc1 zbVz{Yxb4U+yg&L@i-}i)vD?WwJs^~$$uqg)w@pP!n_oF~Fqb~9DrT~G)3#lV+Pf(X zxKrfXNbEvL80q5ZN~$-garU91!Z3B3cB3IrSV;QE5*?IHl-H~zAikhnC@;LV1m_9t z0PWG#)XYg*E{#NkLWvWbuZaPvWx)NLQQK)R7ajnIA4*4;lEOlQmEBnCMxj1p6ZFA` znGR28BTP<_gh`ScN?mmg_Cj29$H_o?08d2OE42#T%&#+ra-}eA5WtimmlN-M8TP}$ zy!ixqcFr-L+0RTyDM2en(Hb)jC?Tk^+benXBqg*1+^tIVADKVn)WIZgPH0e?J%?7> znnay;@}pv5q@qJoD`m%+l%el5q0qKgumb!RkbXWV9*3teB7`BE6nE*uf(Y>eDNsU) z?wseiKcB~;mDbM1U?H~D6cUmCpDcKg2d96-KM&8O3<@qvTqz`Yr3FZE0;7ODzaLUN zk@4yO03)Qz%jJH&BzWVxi68iNi@g>WNQDpzLR6wV1m_)(t`2@b9<)hoCnFTLR8&1l zR!%!-9}bI`NWqggrL!H_ti2%--I{%EP&;?e!yk`K^|A$u`CcJNK}JBy2mb&`_;juo z4$kX!C=ddVWSoLeVUCV%=m455sDyL^50C!8N3My#GI^_OmVNKLnw%>|FC|ig@N|%$|pNag(r(7Z}CH)qJ zoI3y0_6<#c()a~)3bx9=$MEATuIOA<&d0EI2|!vJybfa&n(v zUj14zE1qOJD9~{L40r^q3J1P3k>5D%NyqT(rXY*1S+PVLc_=~waP}Z5k@)uSkIV4t z@uGyFNwO~u!{RUpZ2tgNS@@iRkLTA$kzAV5{S`mXo5YPCFC19Iul>R4dvT7^OsO&2 z0W@~9fp9S51L?~FCAV^p{#f!#NcKA&5v`aV!~Xzq7_U2Am@((*RVvTiXD`uelv@_n zPpMj1at?)Cwdn9^+M5H{!dQ0yaEH=A_o?ESkh)Ncp9_e3QknFUjBb1hj zAiGt8H0H~mT9N^dE!AtTa(^yq-*R`_cJp;dw7+jVj`gS9t72prEXB8HWs>Zc>z?mqByDgZ}e{hdoF}ZM}x(mMi_SleymYgZ1jQLg_qy_IrsKf(J{HUh+ zn+N$mNIfSkbHcd->V}JP)vc@d{%U(x)@9h%N|wbfD>{pN3d}V(J)tNRc!q%pNl{ye zW*dX@*0C8Nk1>fynH`knu?zIbP*{)b zdF7r~*|uGaUFA4xafH#=>~we1DVWyQ+NVC`b;3j>T3IRfGL)7il_0C;LV}bt*FL-; z7{?v1fQ=bWZzn#--A^6BROcFpCyMsB+=3k;lH*r2VJ;T(0+f)l0meWlttfxW9Q~5S z)c7ub^ z$ge&EvD1jt0#_iOSNN(T0GAea^iy6Y<}OLJ=Bo`$e!Ge&HhKFyIxGm4k)5lR9+FW@ zKeXQ0%8*@smI3H-92mH<0Qm30`6}gLIEO{;zT^2flXbOhoMAP+dYN|m=BVXtbX9)(?a8f?XR<}7 zRqKsGepE%SJa1+75BV~DNq59_4{r$4R|AV(g}7UoLJsuA?Y9D~TaI4eFFx3{UEfLD z;XAwET0o|ieC&8MkI8X1YlAj4DEA9?0~RaxR@-QO#YZmZ!9^tY}rQ8`JAO2W)|36RUuTUlie_>?@Q zHJ6TzOA;8drCQ;R{CD7hub;QKB~yRyUzcrkIthy9hM~QwUT=_gC+V!UWnEcE*JMN$ z(-i#p%+%SUD^C$BJT=C4N0JuF#!pUkVhI3l--zg6d!icqUw7!O8Gmpa{dX+cSV!I8 z*{W?FelDA$)uyp=7Vq}jtfJP>qjjb);Y)S&2ZXTW@yZksLVSTthJZ1R8qdD<;CAAe zuzwXxao;O)j9p)mwi@nJp{}>&9agJu*!L?Nnj05j-%7HruPRHF_0J}*GqIgqMumzU zOl6@9KO!E(%St9dk-vS12YPiy-Z^j^bzN(x^6u#??W33Wy34B_lXBzLT*8As)K*%* z5p2g{^sRGg6ku8+BX9e@<0(N{PqgD<)GshPAnLTOy1P{gFafChS#oCY$eRX<$y=q* z7<0?q(olJ1u1ueZ&nvZm+nDeLc1uq7omB{k$kKVM%qD zR-l!%+KN)I2M@TOq9P%!78R!@wFANEsLdA3c&(el{9&qZmb#Tb$4kU8E-&k%R;Jli z_FDeUGF)`ZR5Auv5tJcCB(xKhVMRq&i)GA3YySYaBOvbldIcclE>z#>>yC=|D_udE zsatXcSX)({{0(W#CTS%_Zlp`GHPaoil)!wXM2i>~#uVx8g)o43YquMU{;33L4-MQ? zU2l~+V|&rJ{$xC_c@AcUuW^mN4zp4sH%jcwipUZ!#K`{uPPINBb;l5<%D`-c;u5b! z8c`o>V0_%Sr;0M9fZl#SRf0K3VTWzC+d}2r`#yMUVcn}CeYh~o6W}5xTUI}_GP<<1 zm*O$)F&app=lx|b!z)XvLQJ&7h_gnO^7F@%P$|BLZLX>fE0TG0WYm`|-rCaNPuS|BNmy=8 zEGYDjnD5JJaB{Geq$w!FWons(M5`V6HGyn;t7Q#N9;$h}!MvvCtwyHzcig6HJYmd? zGo{>5nIc>4ruRdaB@vu`Nd{nDi48QDRCDgCKbMN})^H;#TmpP0(w`_mW^WugD?9A( zbJ%Vzb_y$Pw%>not#Spep3frEWrcf|N|5tU2{A0=F(Q(|&fe{M99t+#a*rH*($|Q0 zwfJq%6lNMDZM~N|Yg_L&S;x0|-c8sk_u0C}!m-KHUh3GM%);S6P z02Id&9n6OF;qNO89Y9AlsPw{~=?D$s*Jq+KcYDhXJ}eY(caXJuUD_j4ua3#JOx3O% zdW~-wgKTCiSGB47oH|nKWHyNaG2~FNkeMRpj$3yh_S?&vV}&=<>$i#xxpEIJTPmJZ z?VoJY>{ZA5MJdO@*yMh()XzJNfUp zrM=bxiwl<6?c}ct8a_do<9mJf$Gpkd?fKg0P_}{lrJHrl>Jr_T6tKl}Zl#8!f#Ty* z5}$Fkc$7Q<1F1?;A(&7^_|g67g{0Uq_hruXQh7IB;r%X;L!Guj)#>=}RENF$ruoHJ z7IwK2wj?017d^KcWF@ygm->yz@-1O01XCNY^ zYVGjbZeEP)%GyN@diP}1qi0eT`=9J4LhHhc)#2)CZaiE^qCh@Gf#fsdJC5V|bpvJZ_JzV? z$n#3Vfm1Kz?) zI~Dma*D3=Cxde8{e*IW|#YFwMqU|<>mr9Z32}uagVUgG$#16XP0_2p5WKoo~@&XD| z;(yYi+qZ0f9sdB~*F;DwmSn`bYk#QgTXbsXwi>ps8mW>eS2XvQ8k6k37&?HGoF8rV zr@z5R^6RrpQc$c(ugm&?xaJ(O8-9pHjxFQq^>HbtY8BHd;%l#JQL5x2PBhgk>18fg z_$fqtYWimX06d{2ACFxcea@t63swA7=Lnh|&ETU|e{B38TUC2WAB~{?-?n`dn=FMt zDRU*gRN~x%>gBEVNe;&@sI=l-3PAZnv5vaq-D5p@$=k7IJ#)@?ti1^YD z(*ExYP_B!$zcq^&ZW>CGp)Mp9)-w7K6dOZ{hU%EgQVB<6oD4VRIatb@6rh(vHlMfN z7Tp`EV{GGEJLc&m&XrU35&r}^M z_}4@F_if$N>J5w1o|x>lMM8?7kzUnELVY^ll0aRp(#tp}Y*ceq z;654CDy-=>UNxbjr?;63ZKN2n5|lqCwdBZxv*nYBuB0uL1LE2J2^~4soT^U`G#!y` z?}vE1lwPct$hr+S=`M}8nx~g-6%rhdi6sT(G_`j~Sweh=#{;9Mttf&6gbO+vjt1dm zS!!1f@m8{JbO`N6(x;l{6zyvf)Ldb>>L|)XOHo^3=fOm&I47q3(qaiHl3l?@Y52R1 zbKB(bh!Fb6ibRoD>?bj3bJ}hYf4R53kZfG)B{%g zc;dZxbJ}?U?N+y7->vq04Vj(3!nQK(E8Vk0VNv2s_QL(NB?KV(6(`9}m<9_t$R>0#E@FC@67Wm(QomU4Q- zRzrCm>L}Dn*s?*x|*O`=zAGZcUkCF_O?@-F8c>bL2n> z$Or%d(#u*#Mq>OEu(k?l_K&B^*2b4NQL2}v`whbyn~+#tV2<7kZ3v1-v=EX31H%L1 z)N{y5>YhcyA2W+M)@3ygxi^nBsnj~lzfrExNvVXmb?$@Y7ZrsvTWI8-=m7jrSn9}F zmp4c%rhl>1K9@taFjR?hnwc%NM{PmbQN6!q=Q5Mz<6)Nk6nm$^I3vVjur30ei#mmF zoJXc^T87J}KU&=_M%`e|o&Nys4Ko$lGg+3z!uy1_q^)kb9RbBDB&j*c&IoZc8D_c`r)(vKhrB?`bIx+_I?e0SBJad@bU7;TQO#;8LFE>)b&c#+qGS+)Yqc@ zYI6Cwuw$~B%2**vmXsg|i3H@YIq%l|h283#4hWTHZABy&Dru|X)4+&~N2-F$QP^b) zQ8-I21f?LWK7;Y-J}6wKwfgqITN&83)HRjtI)?+X<3(kb+z+28g3#ImPq=%lKBw2M zn402=@nr4=ZDm|US5?A|0=b}2#e7zf(+NrLQkKvHKso$68Mv%m-EN3ci>Xp$w3Ro4 zgWv%kAcXjkJ7Xjd!#yaeOk}|(<#b0@%AbtGrI&s9>T#qm#o#+QoP*-5d`ExJtx<~E zoFx$&J0UH%9ketC6qF$;N$-$wJ9a$>D7%I7Ta1T{q@k~>b+Ct|1c2g@p5Y}}@*sQx z=!u=^F)QS@+iO`vP5C;aI|t#P8Q zXiKjpkUheL6XdS|N0AxFZk@??OJ($_uplyr=1h+XxiTAJ4?N-vT_aUfH4wXt{c~4pB#n~#x`I8V=3qf`#zS#Y zCTyIgnC%x7khfeQ_@zD0I}V;YWS!|up2_?P(QM$wu&))!{0r$WaqY99q2ESCWuY5|R&dj^O%d0C(%7E7@|A1qvXC9BIUd zRfh+|7)TiH{PI5@t_cRKoWw{{%A4nn#>-2s;=AZ}ax1IPA=I<8H5EiIO>fdpdQ5Vj z-f3U7K2wa4I`#hmx9JU0JAU4-7n|KnAp@VGR9#=)-zH1dAKMegQKhr6>(Mq1DmjO+ zS4M)VbF1R90@}vH3rxscjaVhry${JbLet_>P_=qr!PCsbRwNr60$efSisdttTJ6-2 zm14)|o?)liZz1ja)|@rH6MLx8_ZjsM*qL))y@wWS6D!(~0$NOD&1nm5(z4<6DN;KF zLE7oaeWbaIhvv+={{SHY$j8}Ny7%5kEltyH_h~$91=^eab={Ya8dME}wU}rUp*0pI zt(54kMwqD$Obhp5l9VX~c&#c*y6e>KG-5!EjVUW!17QT%A=Nn2*<2-stIUO;X+ywyAc*Kg z@scXx#{-#?2?JWSeHTh|mix2u&Y?|broySP*mfPeU)C$pbhn#?-|usqgkEs4LxtsTv)?~x3Kdj z(Vm=RJu?S#24e3Pa^T?hkRnv%x#!!NPBIcBEyfadzbpu4(Yyu78z%RzUp2VRVrI>( zTz=hV%4sKSGuds}tV(QH(@$~rMtFxwNon_5aUL!qe=$mUwKTGu5bEWyA#*<^6K|clv}i(sV%5 zG^;vTu{XNEzUXF8uHwcYfidV$joU^-q{ek@EHe{s^cbn=he4NjA~LC|ck@AgZ7*P%pS#?!~?qZS;-c)eSQ?w zbDuNXMz`e%TO|!*{Eew>Y1o!-7KNGVehGOQ){nn zQiF)`%J77sW6sjjfhH_y)$t!RQ-}l0*p!DR{oQWb&acLkb!jyA_uG#TMBA<7GKlU7 zR(5w9{YzFW4oG37M`!mb3kY@8Hl-j1ttm=~O+MU6Io^5#aO9YVksP|K@9o2p_uH2D zjdztS9D2)Jzl&Y1Tihy!ExhDRf%TtDG93ijkkI=;El3DjRJMpwK=CS9HlTOb5cAZ*o2+x5+!g1>0l^*9Vy zZfb6}1euXPzwK(c5TvkY0vc_YK`svw(N8^oOIm#i>bHw6&E(NmU8Uj!h>L!>!m5LW@;;5ehZH@oF#6=U$Wu(k`t1V&8q8jVG!v?axz%Yn4ZI>>UA&Jn?g-Dd* z8g#40EQBqxdOr+AZD#7%Hu69*p~d<-mdE>pQwHLF}|6<6|AhK05}jr!$Wwyi14qX(ju)}E{ywc-!~pc)V2+mkRAP# zbbj^LF8HjrhTPLjO|}@Sb$$qS<+$IBl|1KV`@psXV0A5M2+4=*w%DK0N4k(sfTFOz_6fAXYk*h}0 zd~fiSN|ncLy%lH59PP2nXl2iWST2Q#j1XMsqo)S=Mt2L z*AfgwsnSB0w0R{ZwDe+SYqtDAcJoeKE4Cj$3PRT~a<0oo$()eyD!oUlMn@XdA(%0s ze%r0X+G{E1>=)kZ*l}xeKh-(y7o1Zpe9BrBkZ}W}0sv<$PcjK%(%7dGW8>1FD3SL! z{$Jr8Z&~|^zTB!R?)S(D#R3o>$EwmO_*N03}Dw3Rg^J z_~1#6NsT=AWTXR8xcY|Mf}(exVC4;!8gz}1c7s!I$J(S#kBsfDE$it~d9$@X&b8Yo zs+_Et<*Lw_?XY7+2vQX4l-fewY^H}!01yQUFX2&KH>QZI^6D2!Xxz89{{Zf2YWMt+ zCt_;<0AjYQb4{w771;G{N31eigF9W75-p4o9mdMhWZRE4{!$l!>U<|CgQo1v2VY-r z1Tu$Vw%vR}w|?R&9KGbvwD}0Ov#)NueYaVU1<;mVQgv&2DO2cEYtME)zftly;(b++ zx-Bg^4qmBSET4f~qfxnX{LV4m_vqY{u+>fC%@d05HBDN*5u;Q&Cf2eu_JUkAMgFoR zc_}JyAuW#R30HB@VISJp&Crx2T0@EU2yN%wF8LRfAAYBiXEbg0ee++k)NC%BdSnRD zDy`K{+q&d>@YP?8xUs}%oR+8Lc><)UI6`!EqD4ir^&#tuCM+$#qp3B{+042wx2$~+ zChk|Ux2`4Dwyr_gtPm{bQo8l!Ok2BJwviZ!>uS1mh5JZBN_+!>9!Mn2WSv+zCA_Gx z7Y3I4x|7`U1@tP&(mvk#2W94H(62T|^?BCq{_P#f&1n{MBfy1h<9_7!lR2iANhig{ zdmdzbqeD&v{o$?ZiOk-6ZFNpk?_9NWs$19T+`n&N&AfdUCd+G6aci(x)!kZcHPGj} zCRkL$Zn5VfyCE*YKvG)(E89Q>s~oYZ3_zC*DM$TN<;_kb>$V&f;&x4sRr{BXtc}}i z*yE>Tr=zCTRcC13ggRqZhTU=csWIQLx36))r{1y;Hzl_`lat}%Wgrfn15>N--@$0s zt+Q=a-c&brJ5?oq!9^s@sI+K10$^=ysZE39enLZU9Ch%I5A>h_{%R?hxB8BPCfr<_bt8cNidgemLujQTvzlU97&<|JL>e zBh7@QgXU5XhrnQbJ|n+h1(0?9*`$;z^frgt1p$4(S7JNh`Vstkl(1gUVo8ar7ZD*L z846nSfD?>(s|WZV_&DkG*G{Q)MJZ^xl#mKCliwY^dt>47^y<+8*EuDsov_?=;R{Le z9w{l$kUxOWgMcIuh~bsszUt0W_(nwEW6^BBrC)%U6quOdxO_@ zo}q(?mT<>!1;r?WT&NWn+ourI$CnN!wDZv(j@%eFq!&> z8(D5RLQjGL7)Tv=4(nD|HQ)eu4Ci@e%`G^_!(gmuc;ii*F3x1SHe8c^e_ym)JXG#p zxT6)w4TpPhe#v;PiQA*#pei^A$`0+HBQ5woB;VQl9 zlVn7T8Obfpay4{kpIcCxaziLu+l-ddqLkzi0PCh*%;dnDsfaLerPBCkjP7r2_KO`| z59~K~^%vGQsgWh8m1RKM*{+n8H1d75GSjL-2*6rOlCYppU0=-9o}6JLNQM-_-MrTn zbR(lFN)#ly=FRN4<}N9z<~?G!QP>=9G_m$7Ys)wevRrOsRa0A(sH*W>Wj^Rfh*($4 zpCB?i8d}Fple{uJlN5cu@WVRenwoTI;-TB0?gw1@sh?h}Qqg1U&5ytJh5rC+`d;U~ z<>B&Y$K~n&067wV4d92|P-)+5zi;zusVY^)l?*`F;>)k4WZ(+ky4p>b~>LVCJPJvy>0m0z@qwKC8^U{Imv>eA8^ zgrr0g91Q?4Jda5oSq-=SR+)7dhxXyYmFn3O6O1TYXK#f4cEK5O{l;I1Dc`7(84WsC z+bufi4k-;K0IUTOkO-;PnIX-Ri7-=rCy#WVIjfabq-)W&=ri9`yAP-HQshV|LuKck zaZ7QXc0pJ6e0X|+mx}evSHVv>!?55i$pFz6Q%GWmfh`0Le)ikLT(@-5{)kk#?vf|RA z`kQgIttUN{0reeALsEKE6NzFh$+d(vAYwy=eq~pyPKc7>EsfnRyOhS*&;C>Uatkx-PxSvw6snVNMTBT$4 z5u9SZw-y$*BxODc@yCeh%TiA01IEe~uzkGoZRYK*ax)sGT@Lw2utnJB zZMD!Mw_{-JR$gb=mn+-%REGoESq)Yjf)YDBDGgr>aOS?{)AW2(sZ=?# zvnDpcsC2NJROV)sDpN9i8Xn_sDYTWLUn+4z-iS{95*>6GVTGHJ5a1 z_e6^AHFYr8R?DG9Va8#pqS95B6XX&ON$=mK{G<|Gxl|QIj)9>)RQ)5`O#_tjpnlsb zrFF4PS0O3oNHLVjZ@{)*QFFkLA0kzZ_vj5-3cXN}Mrmm1waVDEn*B^F8j9qW>*{Nx zw-PG}B&ekfvXr49l1Tt}Kc7Q5CCREaLJuG4O1GD>xua|5_H>3M%)d2}Ovm4hq^*Zs zk?nhmTV)|gQ8`HfgPxl_nx=_)FQaIhC3J~z*6DN=@+@V2eT&iSVzlImMZ`Px4=F7I zr#;4yza@9_N>%ES&^oevrih}EF%By-WX^6IEK8s5{^2RM(3f8=Bq6fm!17;$epLAr zf!K62l4`L4P$ZRIShB1@jHe8dIR5}i9pnzeN2mPXhnMOfk3%t72IPiL*Y&9`#D2qH zt(f(ElP-8YAYCr627V(d{_x7u8R$Z*lsvq>J23cN>B;) z3CHKq)RkP_9Xl*4mYzzXt@@~sIaspodX~ZzW4eD+jFJg$NAXF|S|!5LkqJdt)<=-- zlhI>GmWF&}*!ZCi`wjfSIOzdJ3H%Ab>42~`WHXwPig?naI?#Q!A@&|hR~^)0X(>?b zq!E#Vp5q?97iU1ZWaryyNdTmL0)XrY1GY!UqVAE%O`K{YL2^{nEQNsNnHWeOEu@gA z7Ju}Qi9Lrv)P%sZ)gcM^vYBFR7h855q$SwXSyEKn&8QCt5TxWNC=fz{!5tu>+@4n6 zoe&VTp}e69^h!r$=fA_OWM1h-mIw(+T2<-fR-)@mj~2#e`V%VMuChNsOiFvY1eDx0`Vx zNO85NAxTi~2<%5vB$U81-Ss4-fCADJ-#9;k{{S9=DWD6kdgY>)>*P7}rAY_~9wA8w zDk@P)$Rj`R>xy??{{Uv>FaOu}1(HGrQRIE1qMY|5u+RAQ@N>z3cQIcT5wSs8DOpN< zd;EvF@;`<@$EmZ0>h|TT5Py^0!+202c$1GJf1lx;b%7Wz%C%G0kdM|>TlTW01WIkP9@AfOZlsDbmS{7=WrAD()+;-S4)Jl)ArIJ=9tEx}ToiDM2DVbK=}P&QTz zOh^EwAe98jbtOOod_nv=^!ptj&#EKm$W?H6BmJbOk!+$-1P#>yj{^P+gYttA z4a1KhTW#uTQTHp#>(eTBdtN80RNe1DYkJWs=_5Xlf93e$!TM$^QVP zLy9R%+X*WPC5LIG3kez%6NN+CxUxej95;3F!A>~enqTA{vyD?Q!CRKlw;0l8YxZuv zQu3+Xsws7F)%J+cAorT_r|-?{xoe5kpZqDiYA zyq7fa*88~Y92r~9+a9ON*B10VaQ4+RW!kqkW@}dxgdpOIE19&A^I`H-rU1J@M8ATf zr`!01kUGA!BP~pTkKAl3I(S`ZzE|KqwzBFjRp*_rPuU#PbiH1p>iScPV2C$AV zfygQ2S&cIyVsBoYC#IR(MnZvQEq!|Mn92oy$Mp-oUoS`SM22$g{&n;#P)WD#?4Xrj zb$p9O#~gdi{FAC{DA4&XqT<4`gI$#^%ZM-4Q%<^MIP8#Gl8Fr0IF}+-MzPArT&}IIx6`Y)9dApx5bJFvyxZ66 ziqhYecAsvx3(?$`j6+ggacKccQa!|g<3I?LTRy|x2#4`Ib452^Uf8ZT{tX%wyIp@) zk+|Je@)btIty|a1vt}I(*})LnmWZo)BiJRiHid%khjW63Q}MJUF{UGWSjMh*6&U0n zx-FJw$*t-Z9S2;A<74N_H9u4>vw+Y6BG+qSN)6ZMUP+d@RexQ5wxjJ6wDHR%BODJDZGSLwo* zl(z)kIfg;s%M zCPJ(c;~^?Uw$jo`N`jjnN$EATga9KG&&2=%df7>?IS-Ma+_&j8w_0Ykpz$`tORnrS z8!K-!Ce+!+fht6lS*Ai!4+yYBaZqEq?>dr|DIs8|ei*O}T!;1eN+nUnQx_j{Jio7T zgB;BBnw6D4{{Tz3%+j+@$_^l(?sfa|3!P$>OKmPzEa*r>s!jSRrJ8!f36+CgfNu-u_-}{9I{{U)>703vf z?xgJ+;Y&j+edNdTV$s6$VQLvil1fwCsp@D^_>Uq9=*gmD1A()Ej<20I#eJXa9P+~z zirX!jAXNNImSmD);%)Ut;C-ynpx^2&0v{_L6+hMfrl+-Y1Gj6?OW0gYRlv_JkEy9f8iXM`t zopEiIgrK24%l`lyPUgh0@&^IM7dP7EE{)}VqSt5pWun|9vHJ~%$aGs-uwzO~$%^FL zx~E)axeX|x)DJZzDJsH;$G=><5NVpdCFoV81CC)*7awtaxl^jM%I<8`vg7YIyPXAJ z4J)i{412G+8e8j0!wUcwbzm!k2J<` z$3x}#k-QXupOmFOK1w8{^kXeI0jT~&1n}ioY`-N%05cmV&j80(uJ=Z~Q z9LKv?{hmqYnD12UTiSG}7p}`fo3g2kEA`g~TTJ0HbrSi;ZC=&bkZdQgeg%WxmX zE~AbPx#yF1t>SgXR~bX*_`HwpZ2V`k)pAP}wWV~@?XR7PVyT+{02r?}<4t`;bh-W*p#I#G9O5I5rXZd=hJfb&E3&$(Vk*lsvqa<|`_ zjjdm6dMmpYyRC{@45G_nbK071s^=E0+-g$P6BX*mRu~~(<4W;ZCsVhGi2z$R_o2fM zW62mXJlm+--5uZ_b>-dDlr>?q-!$!J_N|a?8XVg_eP*3CN?+3=vJG-gqYI3*24wwm zmF4H<@+-wAUDlK#64(*Gy!~jKOlI3|N?G?cyjhDrTGp)jtsEmssPSu;dfj@FRsi?A7K%4O-}15>J}2kbFPif9K^-unM+%+ zH?G0b+2gHyR?ueMQp1aHS7lXLxiTcxzZu(Uu1flsLk`7p2yIP)gW&FTwBr~%U`{u4 z;Hm@3p66}8tFgZ4cj@}R&A>Y2oUs1@4r$zrv|Ci}yL$?R!{189L(<}~iBs8msH=7K zB_Z5pIl%5mQ|;gkB_?tkW>b)9Hx8cmVG; z`rWh$6%wVp^r}H^LQ9Boal#V+0Jr2jFRSWCFt+e9qlX~~hYr|n(N@%(Z!+F-;=l9%l2z6 z$BhwAzJ&b8!Lk%%0Dk6oZa03Ex=|M!y+2i-{n=f@;63kV+PN-0R_%Af+V#&Gvbq}vE8)&zH*>3XCSGd=dFR4+G z-d;>}A@BL99xEMroyJk9L~N+Wu6Vk@r>sr9N>BmxitwUfqy~T28gQv(Dn(H5_60MvY-k60~!7~>)`~| ze|0hHq4q8%YDf$DNFHk-V2pR~o}-u$y?)*#At?wBC%94ud{6KI_dl4%I$#%3C6eg` zr1-3b5=w~l&PQ*LZv9d_!kM9}Cc;8W65tL6C0&#Hh&}uMSpNWbT`&OMb4zd03SiuOaNuct0L}z>^fZr(=%0m z>NB#=nQ+bZD_&$Yne4Lb4Ls^W@mXvdJzHT$fQORq6BtSk_!-beQrW*CE(1wd}srsdX5t zjDy_e^t-J`CwX&b#p&Wu)r@Ecj@5Qwzd){&zAkNBQ-JU zZ@%J`@|K8fpcUuEDG5MG>c?7gp|v+PEZ%A%nXR+!$yl&8O@1!Lv283s4eT3K7&X_^ z61NY(9=G56WOylF3GfnJ8A?Gp@0<)=YLdX=Wy>hARc^cX*Tp*BV{}!Kwl}qgt6!uV zg_hBKV@zu#u&B;OHPYuh9JlSbQk0hdUsT|Lda>@MBJ_8A1T9Vooe$fu5^Hjwv4^kB znQ0z#?Q3q4t;^Ud(_<@8v})^FmF_yzu;;eg*$%e0mW6k1)uBlz z#YrS7Bz1(`5rIn+mZ~wo@edqwaIJHA)>*rgN|_?Af4cl>EVVEsNo6u3y3@YX;UGBK zSAy_7l5jfF)i4w(fv-g79~SZ488GC*)9WHV2*NPEnCU}o{@q^nR79b%gd{Tw_gF~A z0u)C`b&166U)38SIv)*je;LlOpP^}Rb-9)-q7;b{{nfZ4HlpGpGG1}dWrV3kL6-bm z2fvR?J$X)qx@!dD--fuaW!xce*Sa-brr%n)u0*?#(Nmsq6jcq!5s=%fj-?eerxK#s zKOr47HOP)!5)wjU&jRq%HoG<3JZVOYJ<2TjTQrjxC`*rOfBN9rY@Y-Pey?~XCBxl* zT{q{{EmSx#XDB5oq1pM1`WH+Ay2ew)bil?EP_X{sV=F!9>r?>dJaTe z4Zao=bInHfjuzsb$|B)yIt3-$FI+u(>r&z&MRqb9OE1Y$7%E$>pdrkhEg%H~IzN_T z(kY@tqs-}gtZi6mZEKaN(a~G`Ds?2sN6;n#N44~VIRzfyfya(9j-n?aCwi)q2vLnw zhj^z(Luk}E@{3wqQ$>;eYNxZQ zDlH%)n$ET@l}RkC_Q?#P$o~NJ&LPH0X-O&mn}|Y_+pz$TPLeVpuqzXahJV_wE=I$! zZXfphTmI_V;ynXn*o|ycGJJUm4ZhTuy}u^|s85Q){a^sBjIKSWzflFKf(@=(}XRDeIE20U?&-9Db7fpK)Q zV$PSPoHidQ+(*cUWMv zYoX}Zp|xGJ`6pI+7sN)nLHYJ%gs|^_Lcx z^?L183+uF?+}*~6!xLtB0C4=4(3c#~WAhW-bvYSMgud7&69WcLEj4X!;n)&xs4Fhz zRXnGvU$ThImm)mi30l}&$Wd&NFiLUTri{#NS<;i3xl4a+YfG|$ZmoW;%ZgThlA_b- z*fOFpK?SJqczLvvJ9wah)nhgUIzxd`{ilxg9nR}fx7lE((pHNibef0`_&F7SxkGXT z>6F8XP<17xoB}bP{TS+)M1ha8#5r{>YOV_n#%Y*QqPGp7rizA|N>bAuzoLYv0Vw%L z$}l?)q)91+n#*SEp(J}qhR9k8h4^F=pFEJF zJ$^kL@?=28I9ymxCD6Fcyobk&>04<~aX$d8=OB9b&qPgy5|>+~ERwHl4TO}2`v5W9 z;rubwi6pxwECV`C{3Qh`R!@#pei=UyJx}A*=9(2MnBLRl5?aS~7M$}^)DiOI0Qr7O zIqQ;UtKIFazyHzo{1kYyJcuQNuaD*b029~2i&1}eL37PS>`n?mS7#EGAq6=oNbF93 ziO*9u3)St%L=<~yZ3D$vQBX^R@$ZBG01x5QMS|=uN_5y$ZJ@HCM_>X+@dwwpr>AbI z5I~}wh$OmpmlTizT9cAOR1!!8cmDu}dZ;{9On4&^)Z&O&nK&3qPx`Tr-e2X{L`f@? zPymdyv;8kTmAXa(d-oucPh)|B@$0Sto31I+$`Q&ug1$7@VcEo_cW2l(JF5L}Q`eh( zMoha)H$Aoz^rfX?mXH#+9AApOP?LnH;2!SVL-G>kfCQ7la%xV%3YEz2{n&1L72hM% z@)oyQS+*VC2DhW?)9)H$k_!meBihW8{n8;R#YbLCi2nelQ>AVtzX5~e>c{(hWf+(e z!Y)fxyoj+r?M2RYiOJZ$QKvZix-ECKQJwKkU8` zfb%77l{DZ=e9)w;12`PInny}TClA#cNCLUXX8WAK<6UxV^I=l#mTqnv;|wbH-BpA3 z{c_R9<3NPOC{yIfkfv0WBl;n#FOUm2*zVuG%S~T|#C~1F2?n2$I?s0V5zR1CHHsWssY0PpJ?iO0G7M_n);hsqxLM z-agm0t%sIj*xzb(w)d6~L61XNSZKXEL<)%xrc9Tg32CGzKMHj~=6%-kE}LP!QtVYa{QD~&S+~=;!N(l1F``vg z)iGxCwkfW!ks*HDZlELDZE9NFAxcUSW8a8M^N3r?o*c~v&BqA*Q@Baxmvt_QnakA8x6g4 z)pNYrhp)Vv%E?P{*$DSN$qu0nvb3R1g`S=ejGnl+mNh*F2#7O~<-V%WhxaSEOyoT- zntqoDPSf`kP$ID#5AG4HWw~`;+_!@hQykWz_)k0RDih8kL!~811IY7>O~gmtN<{WQIvvNV>IMhQ!-IHuO0ib)?H zlSH^KKhk{=5qXYkh134)H{G`JR&_jdiTXvm`#ddekp}V%sOzF`a^c9Gb2b_&)ZFJF zdtNO)mP?7sobg|cW!uIyGG=Z!;c&?1COpHdkAXRNW#qr^DxJbLRc6PoFP`}_0LKGG7;cUkv|HDL63`i ze5h4d-8Um$&9d2JX>Gm7@+a-}l#$%0wT$df?WSyud9p5FaWJI)OSPpgMrE+Jg2ooI zh4o4H@pgK+$A6{#P=Nbsc69NMeC9YZHAQT-T9dI)5KiU|;fko!%f*HYKAM`mxg}pY z_W)dn5=U;$ckMsJ88c%hA3sj0i2(dPR6-Zrmp-{eWF%;?C+rtA6*t)8 zqQjF0JR2(@<-*yIC*F>xUSsMOg4c>vwB(-N1cLOhr7FsnpuxVhT~ETh<*xmyPn~Zr z4C|^(iL~~gOJ6>f;N)V3Au{T$fsqP9Ly1z^Qr4c~NO4F|>z7&?B*UJ~bm5B?PwiaQ z%Jn-Y`)Lg7{{Z&;j`=5A(WL9HLYAv*7`qE}$#z%Q32A0J<1X7MNMT`N9x5p~JzVL= zQ2;xblj}zCQ-o?C65f?na{lVM7A=jvqFAfF)$jG)?$1V-9+F%dw7;oDdQ?@#vzILo z*`egKhscJ?60iAA6yUA@0E-J^;2$4PGPY_{bM3H1tp4HoUqRL=Ha(KZP2J@3R)9Ah zW(`Cc74c~$88vailKGV(Qfrg@m{Q(8+Q+s>qQ`>6x6{-#1ORKs=gx_Xhud)Xb*CZk z{Eb1p>O5t*ZB^TJ?O%E0{efFPxdqB)zY6L_w0A1zLK38)E6Nv}cwhApq2!#W$yjN` z#K;B&9)>paLLYI&Vdf9QsI=d?UQ~x$cg=Ph)3b*y>T)i1=r-}wUsphCjCSF(1>t7< zv!OO6t=X$gc9xesmP%5flpRjq23c*CkxXyGgts1vqWO8T^KYG82S<`shZ1q*q|?)cqn(Q}Ey=NK zRbn>tK6FuizwRTDbTMUPdtX(&Z9H6#N2+T15tRg3s+t`{xRMtYsU@aDkt}^eK_dM@BLtv^jc$ln=LydJwZ8oj&21nGZypXATYR{?Vsb!QAfYDw>xT7R;*_u=jr#PInlr(Lnu zf4L96sfSnUHaRt18Lg zyB>7dnUA(n*NT`rrkkbgcQlMgqD@WAjgk^&NE4=9+C`fhH=mOXDicl+uu96#8|t6N zgeYoD)~`ZEt%Xv7o0U4N&qU^J=l=HEQ}26xcJ$lpy{4~Gu4*M~)ZX0!TzEAe)*O$m zjW#nZIrXjBvX;pT_EZ2*mpt@9gTz!b@2JPwlYzG)yEQf}E-GfXC6f*G2}z!Xp~h6f zLRIdizZ-O z58mxM{>=wVwuNu6!aGfjWXp$N8p7%f8IoOP-xMt^u=><;dt*5rarU52c}RK^+=6XL zFnkMjT;(^Bxj}cbxVum1rEPKC-gOFJ`@V|mS(Bqi*kM`8u&eQiz<{^eOg5cqe$G&r zkQ@ug&40xbGZ_B>rq$j6JJ8I-$JzFxj!|>JHB9EYb#gW=M1jdN`1KkTx%%rd-K&b) z(A3Y{lG(ak=i5qVrPQf0$`6l#Yv$?YqX@%&0ea%z4Tm*@NbYy=XW6%TqD*uD03~kq zoFS}n*8c!gWy-rJ5#DW^eH$&pdF9{JCaK1v%48v5N?(!nQB;qRk2RbE*uoCn10yl^ z=E@HW`cR`Ofrbv=UsW95KIAzobJr^OZ35zEwZ)v5yS1xpTMA}XP)dsurm5%VJl&Pt zXQM`Tb)a%0RPq(_$MI<)ZUfV4_OXM4*`fp9~X(cbO$ zkuPnNHqr}Q1Q*zpix`lmy&5#7y%n~jIO^JL2NuG8rK~AU{E8iMcM*&xVjh@yDga0a zdc56P@laNBFiNmJe-B^b{ylQYr;JrGyr~SvCE${W5Ty98IZ+_tKM~*4zvb5qzy*8V zv2eft()IzAs3ng6tej`!G5-LUUkGZ2{oKv@sGYNFSBjeoPmV%LeKI?D$9x~psF2}$ zy{v$`29`oe9^#5XAU3Ri9+^G+;2d>;U8YZhAjok|r6tf(2=l=0jDhHW8S3!`uDRyG z*$`+PFo55Z6ckGEFf*KXKjGEmxpU0iq70x10rxOHdyd#6`2HRGv;u_XOCr&Oekxa& za!S0rXZd9H(E=APqo}6$pw;p|x^?@<=R<9|k!-3i>s>J{D{Nr69*H(1z$?MlmNGno zl15UbsVXC`zSmlMa?CNI2E=h(+R%jQh*flNwS6tP_7cwBx((LC{jH(SP5syl=Ixq+ z`(oZ{(8sbHb};swV6s|LKpq1F9*^^;Xhd?eGf|!Wd{-&bjDKt0_VDmm{*kEH={nR6 zZn|Zaqr*P#yXaj0xCvj%m_ zVhs(xuC1*nORCYe9eYfudRx@`y<}R7rOkKWd_;)fw8~cY5>!&y3C=zPsb({gk;O5a z05>Y)%kA@zr%-5m{Y1@^Q~vBJ0`brCbHfrZ$ftu6vQl9dc8 zAzgGsyg7+y%y(nIs+Z!WXnnQ_syHu>2EDZFN~x9mKH;pw)NkXebeCLus=2uhGJ^At zDbVI5yXNnaTFJ_ZJqY&`a81MYx@iGmm|Xq3@zvFa#bi~mRa)#9Y;5A%qUKx)HMZ?T z74A%|d4;7>S0XSCzLcK_K>5;of8e}zxszokmbM&xl%jIm4eBMu{{U&c zZKBZ9#kFc?&uLvxKB>jYwX%AuKkn#pt2e7F-;%Z=E=n9Jacre3!B7NwD=n$r8OX>m z4)}OJ_DoG1hTdv-v;DsDe%lvXk3OD!6RK1VdY)}9y`4OxP2!f#Y?%-wu;hr!2pMhF zC==h*l4Yl_D37;$+p1@+Rvr6&;&ZZB?JeuB#FtpAwW6LSjOg^vze?H~tdk<8r_%}d zqBh%UWycy)li-XTp*SaASy=Mp=CCFDt1oEPsCPP)QEYHgWmYA@vHC?VZI7z1l+@U+ zc{WmV+w37@z79L&cIz3CC|aJhDPmZIy5ZrrxE z?44qv*VhGyB_YM7)wIe~u%&{2Wo3tPCSq;Fb(0v;l$$`}JqL_Ui@I$~(4MwtG4EIk~lDPMp-es)vD?$BTJDYN)su%B&9XaN{-9Tu0-IXURF6cEJ9W<;c?S=_uGUs0 z-AJ0?jwEMcvfA3x;fu?)&NeRxANC8jZI)*~h@R<=)6!c~kn^p!m8>aVN^E8ay&=$>2igL0VI%G$`VRQImc7{hk2oNL`LhX`m^oJ zgX$`8XzTdSotn*-GZAhfIEQ3;M~dgY8apd_#i~0@z5Paz$wFIR6o8cgML(6ONH0*f zP^=9@Nz`;oQAMZHvqw-JarLs#nwI15A15Dq=Tx^{ad;j}aYbE*Phr$GH8cIi)6`Kn zlceesMZ9?$+$T}6T130NamEs)OR<6@{Vb<@RJf(TQ!pDb?gUTehkTA2| zK%V^>>qxM2NLm%(7TW&+5%Gqt5fHV_0)~yGSu<|hAwXfQPKuI<(sGmo?lOgVwy#tS zr8pf*TC$bNe`L-<&4+N%w~);Q~1*W$N5i&Vy~tBV~1d}Nfzm4@3Gaio$Eq1^+r zNF7k?N=COqm?;!}V_1P^^|W1nwl%w=N~Kw|8KlT?%~MN~r8*K6uX#-&PGtQ4DJsv1 z=}w_0xFQ{?Wg3^n++{LuzhxtiwYhV36rmcdm#U$-nkr-@;YkP}1KeYy z`SlpFEN-xBJ=5m6-;Z0lx7nJ}HRiTmftO?7>?y5^CQoVP`);=>@Yr$GtN;|1DESV` z$mst7B18u!mP?ce+*FuV)+Qus)?i0swlq-%nzoxtW2Q1w;Fg0yJ|Q6k#3T%0W7DKM zj$agF;1IBB=>>B&D5!<|L}aidRsB0WG=m19|~Q`Om7 zI=M3~A;FIxOYSTWHM;XiO4Oxe<|LAF->h{>8Dv}_BGn0bdhWL}sm*q6C3LDcf{`MX z_>4OdNh)+R-`6LUw6dA>wC$S;Nu3?CABQpvVL?x)PBcUy}+7bXt z5`+K{5(WSsgVU%~T~Waa!raIpsCi%&4C6nC`DdVH=m@f=xA4)9^RDC}B>7-|12_bB z?VpcaTDPkAdpBSg|I_vbubB+{dCD2bmQQb&=Klb9ZoUv|X|)&kQlT%sMJ%5}TS4xS zwD(`cgX`NL4_{8E;ez#hcoIqmt5~Zjto;Kl15EtY`j9~% zk?rf(L}mzF(t!mMXDLZqGwOU6q@4c%Gx-j$0f=1FtqQI=k8i)zDKzU!1*N$*Ti&Nf zWER>S4nefEYAlo_D>zcySpbgU_Z@nDrjVJF;Szj8;M6Q*5N=skb{y@!Xp!$}t@M?0 zRQ@BUYV(`+>ba4t6B0bXep4;hLUpv6uQvs+b;JVDI7mq=Ux@CHYYkEiPF%w_UiQTzU7KL%YmOKkcYUe$qt%q;8{Og?0Y`Nw8R=xwBwmpe7`i7U~w` z1h3^kD~Afh>VI#P9K8TH1Y4d5dIDg#F~<9Ts@i+*J6fgMwz?grz5RZhSbq8%_GceT zn0ijTQ3C2qKG;YoTH(!F&^){QEBv~6c9Jm#{{VASn}O-*p*f5dSu^hv%C@JFFK_sn zdfhgP*0&B+s~g5yb?t|1ivm;{vVk1?C}A^))W}i70&&A-wK58~8V zoVVmT(fplT+!@ZXxo=vf>0B?VBvN?{^ zWTCXzs_HDNE8yJ4pG7`hoChM!ac%u8(j`~d_{@&90OAmppoIk?WM>f8(HdY8j`|vS zl*TT(hJP{geNB%0wlj6f54WrG+{zW(%8ypAJ+9YSyJ{Q1TmwdLgE1DQm9{+6?~1eI z!x>yG`q>k;+s zZ+3T*HJU4(igN7bwRH-x!ew^1lVc(gh|@v!mfBCfmz+>a0K)tsEjW=P?8Sh%a1aQ5V)5I*>%F(+kzW7KP>Q8%q#Y+9(-WzCZDcA8{JiLIA5OeSldazduGeb`UD z+kY@ul5n+j9?{r7EPRQ6mQrS@`d~fRTXDtrD$jD_yOs5Qdtb4N+(}h)b&Dq_M3B_4 za5&1*Ev6(P*v=!xOYrvG3JO64DJkaF%R?7q!5pkNrFN^$svjD1MYP)Xb(`9{jg9Ij zVagJ`T8PY(Uo+e-wi4s5p$@4YKO(+gC1WJ%f%#%C2^BwgGJ@D*m@jG$9ihmT*JZ zyR|pbP(+x$>FBJ4eZunJ9_w_ja)oA){O!Mvm$vBBYvx!q!xLdDwmXn*9d!@6Ax@h% zR)-@t6zhRaA-^S{nGFp&)-J%Y@+J6KzU7>`82xr+8V5V`PRFw8`twSsqp+mqC|dU1 z{EACjcCD%B>r(DpLLgbVB}E{#pj6@RQrgB7=7Oh25Q#OcK^3>$1{YKX`8o7;Y49I4 zat9z^PS^P+x|3SEdW{#+^;RO;K(T;>C)h2ea|^L;V|Xb9PK58aRq~V%B%YVJ(Tpn- zM`zmHiqWq;cIKiNpK^PxcPql6X0o!|L9yPYXh?DeWvcy&EWwcQlI8n~ZUWy-h{|oq zY_zo@Im^CjQ0b3r2|}(20N;5Sc-)~GGd0WfbSII1;&AhZzb^kp7z|r z)2|x&(3_}p!ZH-l5ww!?$o+PiPuW9&{&CIoN zmZKp-*WP>Cj$|Y{vaqEDDPSWY4s9sMQ&EKn!1Y$ukK+NW`mSu>d3%~TrgY(C=hP97q*}#~UHGbvF(?(v`oG+lBkTG<8@*LAy@OoVDY*8tYC)@hbB@W_V^@g+ z&hk{q$&VnnF%GiacBHK2Dc{%Po{4Bg<_7-&aTUN5VAi4%BQWqDpDVGs8*tsm^T)hz zq}^2N78{cnmJ>FcXn(o*w@8@(0Q8X}d-1~EaZ-ZRR=<^`tbv~C<O72@=2) z;O!qeo=aykwlwJH*e7~-Jo9eLx$63rwEBH&Eh=}3d!4Xl-q<%BK5kb!(8O1H(hUIy5wDJYq)QZlU&Fe%e2*!Y#3LYPni!QBg~>C!6Vhx zj}qDWdU*D*l+0Lx83D{~UP^92<{urnF16#Gk9}v6w$44=Hh9~TYxRA5X|A>Xy_&_c zt7$e-Wke0fQj(@ns3}`YURFGmm8o5iTw3`|BPfP)dN<0fBF0a({udJiPF7h2_4X-FEPVWtQ=iW5(}C#)|rQaSyipr`zu$UTNH;%r%N?pWP65tMTO|BsQbwy!irh3D0nQe;>oHSx8x00Nqv_gN>>?$WkyIY-7t9 zIP5_r`kv#iNy&R1tXMDq)b;-W9tiLYz$_>c@gFXHy7)<Fj+l5n6; zmPjA`y}&&|*aho$!O21ciclWYKmd{gf`G{WC;tG5=z>>Kh{UDZIR5}y@Cg`n9^O5^ zKOgozSQL^TY2UUIQhsc9DajZkC)1~9Qq1U_cS6&QljM+8qI{Gve}+9f^>|8)n^G)M zc-_KK7D9adyg&!B^aP(z!>)*KT$-EEZNEyV-s`C=?WIXW6nE7-6cxmADD#y~DH7v_ zc_Dd0S^!W3BxeM5-=VH_!DDbon&Q-h$Pz4FKzS4G<6Gog`@3m-UdgT3?iKOsIU`@8 znABKXBnaN(T8}@?haGPSb#0d;xYE?pyb6jy$99KxH~<)ZwFKNg>^RleG_>MDy>2$D zZ4d3UU5ig;O*fD?d$cWzxO%OW+a?^5uC+-iGpog6L}Vbi%g9MC$wSUKl%)4}479^u!!!gj6j)O@)MZuupu<0k)N0xf(adH_cH`DP&a|Aby(?!@%nosI!7PZXf?J_ zk$Zi&Prj77*ZU63G}z9V@|!~*E)a&=X|yzir7g7D5CA_eRH9|8+!8^t8*duHxnY0AfUe4I4s1tuU z)K<^5Oo3$VI3DM;fhlZl`_0ap zNrzKkCJarEY9L65MHw+5#eO%LLfJz}`I|o~ik3*q)slO|IMuPMZ$lxBy^|Wxw0;+6 zTvuhly}gT5Ph+lBQe0nH&aa0@X3%B&mLk0IZ4t19lp!N2Qc$3;kvIdpnKu`E3-7ly zWHO6ho*Oc<`0I*v{xV&olrk=@ZLQNCn+v^$+HKW>qQgprNU4=M*HngBON;PAdu2*d z%9Ke>PUATOfv^FQ%3GQtPoltstL*xfrNrHivuc@pBEdEfIHyw{_4l4~6HXPCrKV8% zZLk&cr_;m?0r~#y!GR6XY*sLE#BAykkGH-n{^PCL8>z64?Q-hhT`LyW4OC2%O4DrC z%bi%4#92}!A(qmY9YU4zBgm+sBoW=rhJKZ8&%1)hO^c#hX9sb|9&ATt*6Sy+WQJx& zscLnc`v{dW>>f+=8LEpaL##q=_Y##YEFmD^57GeWYWGr*VtQk|wbqOSCYxv5#}V%v z6pfc**CfuLVKN-+7)@GO$E}w>ytZOakzB-<;=3iEWeH2lY_ADOB!D_`-AoLi;MTz4 z=|o!m)=~E7#7*7a-wj!7lYW~&uCH=@_0}}Iw%lsT=(VemsF7ZlhgKbRhLE*+FTc#J zlicbSt(y(jaFK9&Sm(IuF*%abL;0jA$= z4y7?mU@a(6?u6k_d#d8L;5w>)FnOixzT9|zolpH9u_Qev-oE}_leX59WSak0AgRxI#DN zM<^^Y_)Q2gb5za0x4sf$*3V!(Z%%D4o3W2JONn(~)3-v~ux*x>vePM)mlPchB_U+_ zD=NY1&v~f9Nont{uWlJYnu&ZLjU$BU4<7!HJu+%(x}y|>U#7#3I_|WKU~5vhm|A#a^6zOQ>$}7GS*b3 zd{1tcTExpU)i8}1)j=kGzHp@Hf9 z0#pZBcRHXJk;fFqF*sFDHq8r0{XCM0_}?a1~X@hB^3s1+ea3MnNd z5;6~C*3#B6E(r-WAov8rcM$Pav%1{dPCwSCPSY7?Hm@Pd=%rQcMOa*RWB&k8~geq?}q^y9dYi)QCkh9fhwl$~E!N+LAgw_4j!?47!ZQ5mc=X6l?6KdJHIU>&s)ZI45q^$5 zmlEuj8cS$MZ7w+4RNzl#sUb?q0QCLD}6Cvqa6j z#%EeH0;VisCRAsA_8)WFX+BG3(e5Ce_^akl4}PINZAr0|iB^aa8G35c&17ITic`R$SIxq3wj+#XwN zduBDU4T79&1*Z(6*StzRM~N!P?f7+H%_1`9ExFJEs=+#|(e$l;#@5=CRH&!Ay*^hq z(BQ_8Drxd7CQI!$mAjRaPmwu2`dv*zLlR4GD8}vr&F-V9?5s(Lf2>qqLz?3+O^IOz ziAa#R$?<8&QuAsHQ)w7Nm6DOzbU%?V^pYEzA_EcnrxjI|bZt2jmZ}XzM;ug_qr#5N zX4dkKR_c<{QVNtn%81G8M^;ibF01&!6hz#2EhrqNUMle<4)|ph`_{iT3bOvX zlj>9vW=TbwWDO0W#dx-}l8OLNF#Cdv*W2%RB0syik!^KNVLJ$rHLVyJK z@BV#SGIF`+78s&UsR>$e50Y}P5`J8I=N(%$S22wdsO$1LDMDMo#t1#~dg_dylH=43 z%{%w-;u}dFyZGZ79-aO<_3EQgg34cxj-266tf@|55!?Jaqzjaj3>`TREGT6}`sY5G$A4ePs%Idn|I|U4%!x1I2 zB_vjqE4q8Aeyj|P0y}})ZUtPU%)aC`d~sBx58Wk8k|C zFS!evq?aJ19}rdJ*=j~RcFs;ue%&m!4hhDatOACU=2Va|l!cMsK8O9?2N79}sI@5z z@bBP8PBYk#&++xgLWK}n*UXe5Iq@Y*z#x7kdj9|qkA8??7MqfsnE@e4NEta9Ab++x zKar>u{{S1*q)eoD@&~_vB9agC{#_5sF;Do4$uB4;A2*mP$?e=1cs>6Xk*;x5N>^ozz{{Rn8f!@f_Qt5m)mqUI8g(n4H!#|IH znZvT3NOkhv@Bt+_$s{Yb2_Crr03*{GtRm?y!AbeBv4waOpI_tf_;iGaPl7>9{-Tng zN0IRa=NbMV?dj0XRNzq}rvPvePB1|2oG5zW9N+`rq|C)QjTTVxC@D$79mjylBzMO| zPKX#)Dy5_kKR*(*{HFkS9rKg^eKUX^C>SPgt;PIKKhzro$mhT3)TJU-q5%4(oACaa zDmYF~2*Ei20MvgTnlcm#B=ui=s!xZA_dLn+!2l$V{vBO+Sd!iQ#}%R_Mq1jdqKS#x zP+M+rC7?+nY1>N8>eX^v4#1To69Q2X1qV3=x0N_jg^- zU*|a&+;HFLT%U8_=l*=k;aVvV&LI!1I@c~dOtk}3OY_adZEDjAk6qpT3CW(p?sS!M zbB@2nOG6wf?GpRX&&muM9A-s~(z9vsN+RU}W?J}EpU=oD(7U9;2b*z(a86a2)Nu>H zV01%SI2IoUGMPd3@ldTj3J;{bRJAMhyo@m$Xq7da_`1=kRgK*_`H4$zp2-Ig8NnF1 zQp;B0RQED_^u@Ngezv@n?e%5d2|(l-KDng(#FX(p%_H6SgqXEri5zhn4oOpv(u%Dp zF)1E?wBFFiPWfh>fibuFAko|#{q(_wBkpZyJ(m-GqAf)tK0METcPtSdS9`W|PEM6p zHYuV=4QQ1W{x;WnPLb>Ph}yN<-0-hgZ6GY;x#SEANQ|XTK0mY5sPB7)*XB>&I7h>j zL2>)b6dy-%dq4Uvvl`O(zen!Rl;4(TI)I2yX1B;Btnt)mA9gAZ%r(Cw7HbJSFjyU@ zPn`wZ`?UIbt&$6GKRPq_gf~GAE+V%HxNlsoEq7$oxj**U*5nqo8xb9879P@AM8z6> zs~8Y}=y>L!$}!*a6#0$ty4(nGnM-eskDZ-fnpxDTc=JRt&%td4iJbhZYYu<*M&gy{ao^Lb zBFFu?(hNR!)iauY@%KA!?^AVJiO$VFu=&}z*m;1q+SrxMDNo*->l7EB$oEXO^wu+n z8}k5OWvw*Vaf5B+eqWRceM`&296@0p5M*SB%($;9XKOu_%V>h^!7}>!9ckXZi&N5P zGBcE>Iq!zEy1Mg-X|nVmnM-P7D$^rv@fe|iojLvYMk)BRSJPqv=A$axnjTI_`qKi7wit~^MEh{!iQ^J0|8gjte9_bB<$U1JKpS;^# zT!9ApT^%k=YF}DttI~tFGwcrT$f%NvQjjphY+BE>T1}4i5D;T5+H#7XbK2~0h#=HU zr3wb~fmW<74WUevzoGVRf>LI2VLqZr^1szTrBigZu$W~ae0~Udsi2zv19H#+M200y zUJ|njN+Q+zE1TS)rP6Rj3>HCliJukY0a*xxoE@>mhq-qfAwGACKpw6To5D)o+;_xQ z!+eJVkJPXqiEtQ5#~xgh1!Z>^`HXB=hQ&6ImKgxzfC*#Jd?mny>6RBw2hLxxaPB}u zkZWQVc798sHOi)c`oB84L!jG?++iH_Ee;o~z!4?S<8P*9E0k>yarj!gV1Uzd;%FIq z*kR@*zuzVwJav8Jm6!QMH0_t$7+SY=jW>&(PdKO2(;B3RTni4_K!a}$OEs>}+(|Aq zyl-s()|2zb?ILKNCP7DzL0uo#;rjN|N+`H2oJt4s1JzNkX)1Rzub9{=WQDe{)lv^vv|yYzi<&vvm`CFYZ_-&-~_nWqbH3_G1} zxWli8)ZBJ}`N{Dj_>DO(DqM_$bIQ}=JC6sJ80SHj30Un20?idKAYG(4KhNNwziOs; zsV!#W`|Qi!?c$8TzSW9r$q1#nN~|uoPaJuzZSV7Zx!9nFVsU4}hlyV)hO2rG$hCz* zUXZ>bttoYA$c*rzrP?9Q8ToZXO$ zKCMo1i;y$=hWd5smKyZ&&TqT((9?OCdQsf>_)#T@LDPH`)NO!aidWkb_B8z*%oC$*UU}r7t;TJW;^wH{@iSZ1?`0fy0QuCexX0I} zrrNIZ*vu7y_mfI{BxGkn04KABJ0YjvYxWI1x+M}6Z&&EHr`T{cq0*)g7at=Dp;9E| zyyj|ygcsdc1ZBB3IY-^Iibr!)HK6WkbnbUrRa@z<2v@~1(65g~jGnU%MdS^J7ar5W|tBC_V>1IDmlp+S)vG)&0-w= zrFe1K4&A2hYd?z7V$snvAocETdz@=JakmEKI9lx19R=RqU?H#Ih#Tm`u8tr;tUS@c z%utQTX_1+-gi;-UU*1{c@_rdsf;I@$vpoaaN=}aftze{pd-1(A@%^Gkhf_OC&WNkRU}RVSLqcY}GM@ zHo11W*Ls)`vkAaC_l=SuM{Vt39cC=Myx>+yEp+)uAwfg+@6-!K%A`GnYNFPI!HtK={9VMTBUsG&X6i;ihh-)JRKOWcg7sFRcmN# zXvk3`pD#Dm5gt(th0j*+A@B)u?DPfW^wm^Num7@O1=$nUBq-d z>mKmKKn;8la5uPeyT)}Gb(gj9gI=!q++0GRveGW1Y((N6^*nA)&cb9)PAeBlv)y7EK z6s=8{%n+n3uYYzQ=r9T}Uo>w;C`rmkguIh>X{EZY<$vEV+PWcfm$yi*evZK}&crz$ z54=|s*+LUQcMQ8iW6gEV=Y~d6NqF_QX{#OOH>=8&cTsQ{ujf%D@C!|ILUL$%PbGwJ zwK5=YCd&u704!I9tN7!NeNco3SE>w7WpGX8lcS zp?hNQv}vr*e>cm&VwF??7TI^<^Ff`k>Mop0O)z)n)_~6KTP;GP70$>aoAmVRal;_W z!4J`1M$X=HG2&QIqy!=2gG=*Y*z3Yxge^!w0`Fx>%=XIdj_GOlJ($>&fgn4IM{qD2qm{&BI?SkCexknb4K@s^=V+!~ zU!^552StiBv{HIPGrQVx?eLR?_)0gs#v+hqeEp4$qkgz69+jaZmsHB?`WcZ~_z@~alj@xRcCV&K+Z`L+0S$9e z;ese=KpZGF&D}qxwv+J!qxUh8X$&hE={hvPD%N~^{*!rXPd%ep=f)DINj5EfVOl`C z01iyPw|jrqYuIZBTN8pn(0M+S4JhcyPuOpwd=ur|Yn?{u+Y$e)5_#Zs;+kCWvIN$x z2F6lBO2(JV~&yIPLJ+ke>E1p{4+T zkAy&Mr5VY_WlQv*1oq(eoPW#iVJLx>qH}Hh4vm6jMluJ({(Bk5QrF2cq$Q=a?{vzA zl@<8f>$l3pibYr#{oTinyn+HOhON6^(hkaIDM5q8QIo|F?&;Dnauq=>6_!(3_;yNQ zbTEFxbc+SSx!wt>ll$C7A;6&RKm-DDJB@zcuU8XtW9M;;eYX*hXpAcECmW}Mu!|%I ziu}BF)L7^iM&#byM@qHlxe$Fey)ADLJ6iK}|`pQ#r~iv@$`qm`uNQF~9BF=e8_8GwV-PzAY8&z7G6G z4zpReQeq!={kj4uo8;c$cnxcpEQL`gU^pYwnPLlf)A@(HFXvb1>9(ZRTdmU&;b2)2 zbZw#Y8>Ks1^?LnVMqKwZi2pt_m5?~-O#y&xmuE~5cs~0@kx2x4sXwu$uhcN0fd&ez zJRP9$XVai=+>ogDzV-E~m^(U88Vzj>U88nnF3GG2c;7Gq9l!q$pU6!j4K$nBVv~bF`w>82SybNIiwc4 zt5EFZqHz9Ec8?3;G47lmM!q=_Yv6W9mzDLxq(HR#(XsiA!!)6y^q`;yqn#i#uMvm$ z=PsJTwJOyQ-1%5JYf2O#ugM~zs%eo0@$?pn^~oJNjt0}oJq(B3{w4lS9E6ic^Q=s$y4RozXZ3!aRYTjaIbzXs-s+~O>dVG*_d%hTVPGkv#ud&$N%(u{r#$H z&H9j*VtY?kX+iurw~);egoe0n&8ayRoa#y(75@UdtSAca%Jr8PIuDJ~uFE9;Jexl{ zASq8x52A!5P;KMm7uhE??KOl@4=z(gaUDD?Z?>K-?m+5Ru_6SLPt zDWiAg)y-SMx{C;j=FuA&cX85=SsfX$HV9fi00BSvNWb@m=1O1sBTLyh=z;4d#?_4l z47761KW%MlX7ecRpzpiOS6xEUaHGpcZ8em*xPI;OI{$F6kgut+3S{E@8diJihw^y2 z5H)0I85|Dxg5M4LE_hQrmIk1kBl&9303PM$I`5s?Tz z_(g*+CTV@xu1%aQ*S_&+-L?+eHm2~7Mu)wY-hvl~Sye?my&Cwaa#VGWp-tmX5~#r; zeZ%nP>Ie7ql}oFMCG8nfHaNX&pYcI}bogMz>g;Y6^cNW2L%FDA#~8mo?$nU>a5#$Y zviFCxfZpW)CP~i7pv|8Gvy9MJm+01=o>AG7J~yk7!Ki(5Jh%u3S{PWgsRtMN9e21+ zxv*z2F%jgU*nxk@E@u|01MDFPpW{bP>^B~Swa2_xVcZN~4YEf>SiciRa?4G(jBCg4 zgven7442&d>})~O^yZ$}+1Z{I(9Md&ZA#Mqf4_SuXHbDZ*0gkRY)z(DSJS&<4byJ_QZ5K><)K_msK)vBPm?IfqZ4SHQI=w`$pUe7{{dbO7&M&~Mg# zPZW53uw)LdQ^TA?=bMTx+t<*&y#}S!juU z!lQ1F7idBj(PW&GO+o!08U?nHhr7}Hs*ynuKAr!*o4W)C@=8hqj#Eh9>79qSzTmcA zyKDsShAbI=c8c~x<@yZm~@veM`kMK1>=d)GBt-(cqFf|z@fuDlZF>&(FI)e;DI~q|Q zsjHn9DJ0jgqA|x;7xlVw;E&qWAfce+fsna^Xj>r7^cdUBeCYm_&q;m%PAD_Z6=?8v zdqVffpY?Y;B3FdaR;@1{BbxL{OIdG%GH2enDuCjn^p+`!$g&*2mmVO6c@rv!jKxaABkiDG&^SSTJcWr*9@so;vQ3 zq+|8!SFD9;#os`=?)rM&Ni$E>@HHiHh;NPDK+;EKfy;>D3* z7YAc`X`k~?{M($-uYTnR7@ko_rL+NihBSGo%Z?_MZeA(4B#5nm*m zRv`Xh9Bcb|;P#WDcc&2h>#9p?nR}Qj4ZU9l@T3YssA*^F)fTy@M=inxu|d0}&`e43 z%TaK-=;c6>#;}LQ2_kEO*0G}aChkd>t2@tSP3;?YnH|(=tS_Av|M1FBHnY_5)}?BU z2gYya*L+N{@%zv?upAa#3<;Z~J+=Gi1n?;q%O{M#b)lQxjsXk#DVZJaRA0430o!4+j3k2Hu-_@?WBCOo%$xuobk+ zQbY;r%G8x)|1eH2rFH(3UON&Hd=wWRXG&DHFm693KrmmjC%ckedg8|l#_vl9hyOlt z`}0>9q9_pkSPhv*-2}-;X{>I7(vNrA;OtI)*8ahIBkjg$8ERs!*U?R@|at$WqCEUACCq6G2|ZNsl+ z4xhT5G5Ge({S_DJzQ>;_&sq?hAYQxnJd`_6?Rb(-8(O0yvT3Hj4b68rLYz|vU$2%$ zlS7iFIL}d)OTY#6iQ{8C-Ic%758wRbU>^&P>a|iqU%Q7%h#z1@patR6uDQ&0 ze5R|uwB}3$9vL)nQ-vAzlN|4#{c%J;$o#|@a$GH3Up$%SB>Dh(Wlzw6f4w0NPVpuoE% zD&Vpt<&J8?>eu8INXkSyLa#QbO;qAhoKP|N5xgk72_kM6au=sr_o~R92Xz-;7Jx-b z`6uw^OS=bc_{bXoURvQFxU4j-#)()GuA=Te|5q?R=6;Wb z#!Ua;b{v1d`cToNOtsi%c);~UYpF2wWr0^dMu{}chAprO<3fv&PVYD7xZ`EJ=OgsG4UkxSp$h_nNfGuB01_tS(;AI27Ki4)v@9!kU zvx2QaeZn`*PKuh@BX^)?TB(hJu|q|u*L-q!UgkOB?{|`s3FSJ{M8hAaqLBbuxtzm6bxrS@=7zg!E15FomS4eXhs_JGpcVIkbc^#-@MO+t zO%Nb=fKrt6ik2)jpVK1$NZMx=&06PNOospBQ<35-Jm2~^{^J$=5R|fX>+*&-Tk$dd zKp(rKJ9dMagr`9y)9)$;Cmy4s{y_Nu^qVZUPx|qqgX!#20J;l8aX?qbu`m=QmGkEt z$;ZE;T#fiwa{FUQH+8AN!XSHt6XCx2aNovs)D7WLFAe_3a-a&x|6mNrvNe|w$ZzIn zNXnDcKUe=*aqW~aw?6p8g1gOjLzn1+NQC}+;e7eXvCxgNahvPESVAk8g$?VMv4SvL ziDiXk)}DsySepL)Nu47q5p7ZGuoq4)jfsy`KxPAb#hbnmC%qUv7Iu z=Z7{6)Q&lni|>AW_yKUlAUtZlw0FbHb5<-OuPbT7$Q#=p88BS;MOH=NTeIRhjms7?|* zVCL|Jh+50;(r5p41}cT`J@B# z@Ub8){C5M&eRdP{b+!|r0sstSs}^r?;Kx{0P6zOH2jk!?f@;{@OtN-h|ysx|odhjVa z2I$?SqoBInS?WRR%2cNT=hNQkmqS3Ab(L@`I{MumzwU9)h%hYU^z6Qd*?qNIr#%i) Zd7<0SuAcM?%k?5dFV=L-|Npbu|9`!ltrh?P literal 0 HcmV?d00001 diff --git a/public/La_fracture_55.jpg b/public/La_fracture_55.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f763870b9afcafad304976183b23457a69388234 GIT binary patch literal 177701 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 literal 0 HcmV?d00001 diff --git a/public/La_fracture_56.jpg b/public/La_fracture_56.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ba598bddbf5795c64b674e0057d3d84df447d14b GIT binary patch literal 184212 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Π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

      axTWu|t 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 literal 0 HcmV?d00001 diff --git a/public/La_fracture_57.jpg b/public/La_fracture_57.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3f49964ff7c3c04f410fdfeea012ab9b96d8723a GIT binary patch literal 167252 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 z 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 zaVkoZqregisterModule( + /* Name */ "altowithjQuery", + /* Description*/ "a multi theme", + /* Author */ "pyeb", + /* Version */ '1.5.2' +); +?> \ No newline at end of file diff --git a/themes/altowithjquery/custom.css b/themes/altowithjquery/custom.css new file mode 100644 index 0000000..2772ee8 --- /dev/null +++ b/themes/altowithjquery/custom.css @@ -0,0 +1,15 @@ +/********************** +* Plug-in specifiques * +**********************/ + +#tribunelibreformulaire input { + width: 170px; + padding: 0px; + margin: 5px 0; + } + +#tribunelibreformulaire input.submit { + width: auto; + margin: 0 0 2px 0; + padding: 2px; + } \ No newline at end of file diff --git a/themes/altowithjquery/img/attach.png b/themes/altowithjquery/img/attach.png new file mode 100644 index 0000000000000000000000000000000000000000..233671d3af08e0611216e94afc7b876e5df0fb30 GIT binary patch literal 326 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 z z1QlsRJp|Ae2?JlZ*G^^jvX7k{3Vqu@Urldkt$PVc&|GqB3>48P8o!j?-&X6CdyT%} zezyq19{E}Yo|20D%$2L>`fpmmFCi0B-)+!+Fcx^&)`sBBf&Q^6(9SM++$V(n!~~CQ z_P~{$KvtL69M-Z7u_I`?u$zsa*FeCOj` zoNb|q`_d9?VW(HKrIpm&kAo;;*Nu z>H|m~jMUE{6vzSvNxUS=en2TYsv8uE{VJKvDgGPKtdAi`?Ig+V=X7$Lzz1|Jp7gdpq)1LdzK}gOoozetf=}`SN@T{GD^9bR>|p|H;^?U{rsz9 zryvDAC;1TmJge%CI?jc(-4mv@u7+@rwP5@ zo6P#4|NlplFgW^pE=7(ndj<5LBUD#KUgk4fYLs@Ls;mXEWT8|ccQYYIaS`GB_u0|? z#cPz5)Re}Q4o+!rNopw6K))dr)&Ig-%ug=LRogG2x0Fcibe3aFCNY02`OAI&C=eLox!ls14tfw zT-Kz5g_fC{!<<}xE?d)Y<^6NSU?Z6S`bA0YLxE6q%qid{`^Sh*_xy$WOi!z3p1mcI zhjzktR|8>3sgI@0Qbrecq)dqt?ICB^d~SJ9^FWJLrmaUeQSU9EF8U9i`2FxMl|?%0 z$d7yn^g{!%dS}sC8vclw52N093U|gWs+b`cRD?(?VG)&m@rA}-0aOKT6lEa-73=m+ zZ}57l09H9As90q6^c??PSAtTy=taH_&m~3ll*7o%ju$jC#Oht#pU(vYT0f$6YE_@G ZN-r+UFpazZ?{6~%6$K6XI$86G{{e!8*OmYP literal 0 HcmV?d00001 diff --git a/themes/altowithjquery/img/footer.png b/themes/altowithjquery/img/footer.png new file mode 100644 index 0000000000000000000000000000000000000000..23320bd154afc629f1760b8bea5211bffbaf79a4 GIT binary patch literal 3891 zcmc(hXEYpIw8xJUy+!nrOZ46)7;Q!!eGsD?ZHQ3w-0&iU`N*7@zd&t7YvwG&N^b!n+Mr~m-8`g&Rj07(2U z>|hGwiya~t|NB7cr)M1i0QHsMiwNZAvjIS5;t7M9ntJ#K`UZIT`tj()U_5?zeBC{7 zyIs&TICHdx`8td0;le)DAOV9l@I^3F@F1W`7^XBqQC><0cmnU!X=byI%i7wcoc)Cf zBq=GFWM(sQnuk;$$ya!vr9?kZct|*23VZG~*>d=0=&XK9ZLMk#S2sf5PC=8YCugRB zp(%%6z5FST9 z^c&C|J0eUBQF~z84Fd`c6VM1vftCOb9U=@aThJU7k^-jz7w2VQDgm5?9()-G7~D}# z7!k0=@-h<@rU9NSZV6hzLj_cg+~~^ypLP;J#ro*T`ea80Wb!sk$c( z)aNJMPQx73Kj(j?04 zT}XZy2r(c7+dm%yu-ok0@j;k^1mh9CG!k^aqkgJeC;%|-`j7nqaM0qHv>?=}_fY_# zRTwGyQj>GPgH61hjH~0)TnF`ulVS{%zq=F40Ht!paNThdsfvOM#|^#Y7Il*PpusKQ zZsrk}?nfutY1v4p>PPyvK(%0@2NeOp?xw+s5}hB#%q%fPE^ zRWy~o94~KHku)bBxQx6CB4v!!Zl_cv4TAEZu4?Kb4Uxtl^~!j-_~kFpP+q4bi81RG zx|UvM@LKTA<)7Vb&ayJ`NIh}BNygMGQVd}Uu*D2k@_HP6>F;J-y=uvou;M&o{jn>!m97=J70wmjU0W)gvxa}sk@;s~1mPB(eU)KV zewEBETUOKZc`jnU?5V|Ng;X18^;10Jg;{*r75TflN<+~s`Ub_-&oah2JXk#rJzsnc zd~83fSIl5e>EWQF==4+u|6k&auNM_w-*kuAMGAn%LxZKjqL+!#|7c9=}MOztn zH&UTn@YT@t{d=O#*{9siNvaj)PnBSDa5<|w#2(gNoqRdl|0qAum~u_HG;1&7;R4f+ z$Y&AG5_!WW88YM#;2D9(dfEA-MP+3bcX-%V$=My@A>(D2A_S!A;FMIcT z_dXXS6XX>%FxoKM&P5nCm57w67^)cd4Gj)G8=A~f$WxV>l3mMN%bUtuY;dv(wh_md z;TzrbYgcSathezkKCw1R*2PFm8~Zw)YFxFzWOH?M>E+TU<8;RWnm)E&fHv3{*aock{e(uSj{1cG^Yq@~;UH!06W~-y>)K4;`y%wt?OkgIF z==wE2DHo|UtLmwj4aGqfho~J^wI6DCo-C^^L#{8#E?7GbUT<&cZx}G?@-1+TU4%X0 zJ9j+~Js$<77y%+QNn)gCq%HCBQRsc%w<+q%vu;0Xr?)hd3!5~VHB+OiqgFerc|H2S zJ*wtCT+1F#8}_7&HI4W>`JNp01(nnlK_e6!A8Qq-p5m8)_3_eqGc?}0=rj&1X8F%I=MU1*Q7=j zM-x86>_o2`@9K#fg+Bh4)}j!?-y>HnzS~3-$aUXME|FR%aU`v--k@Y2u&WCn- z<~8l&&DUE8KeT71vWA3bo1^itrsr=VjV*4a?}mp|)GdlE_AP!{C~l9<*Q2J6d`7o9 z!&-jGf18-KZ8;XdJZtbbg0s9uv;v3`_!>}_9d?CrnRM>0loO3p`z zpKAIr!9AvGfk>Sc+tj7&`>X8?w-Y2mt4M44cYg0@K0mFHmGwi)#lx$#$}{(p!>X3Z z$N##=jpmlR1f)yXr@J+^hWePc4HHafYn5PG6J`xkw_Jj6N#zGv~yb7nniJRQ9| zl8np1g-1yKoO7Ceh7VhF8D6|a@4NGcA#iC-`#fn)rA1}fZnrUTw{~{*idCak?h9o{ z?~T9>$XWWhNndk*b8bzOombO#Xls3#`{6og!S&(!{nn80Ea#IG1xl*(t$U%qhdqY} zi!AdIcZ5!d2b!mYgtn_&Oj;cGHMTUTVe|15>b7TdA9v;++-eUh+#8+KJtT{b9yv=p zNTr8eO3g_fh@*|$EV!Yjr1V++&guF|DQv`bM6iJM?Ah5s4J(UO#L>j&)bMEb=+ms- ztn|0u_lr+A+Bex>%=UKnUTu39EGOfzfAe^&BWNy&d*}Hgy~)abo(IC`9zS0ln7=PQ zPG?U~KPM&0-aB!TlbF4jH+fw25Jmum3IKqK2H@xUg{}i|R~mo~CjgYQ0buog?AW6N z0I7q%mZnAU%(r<><4t9tVb+&o{_65%`&k1BKmzInj-H<+)M9LLFFs7DqcIg_B-sAl zj4P$%YisDn^yM2V%fiLqj@x#Q4?^eh-u6>>?HwH)hyl%~)6;P4OgHO0!%AyYQ&Xj- zr30&v0~|61im`}?GREWbM(N`{=jMSIV>1I501Eg;CKuU8G5)t|QUc7yC<*>cHB5;C zk1!GVSO3NS)qnAe>;LKI5A3&_Ke69#{>1)_{(p@6NA&+KX$EYNtdaR4E9gbVMUhj$ z`B;DgWz_By+9^UTkyAc<#gLJ^Fq^V)b4efyu!#y!@I#QMy&jbeplc8-V^b6}8ok>h z&F+#cQ-ZZ)1HF`l3I#X&qxV_TrlxV@%Odq6w8lV(ny?31&2L9)PS1=|2>=(k$Xz4$ zHYo)0Aq~NY)tIv;iV;H;U2BXufO)}rVx&|5G0ETIE5gD>e0_aq@ztAeyk`$W!y_Wp z+8W)#T&V1=put=`GzYQ!ScOeSxXZJ?mdwq&Z(tRXDm5^63t>*|*X&v5Maa#Vm&49q z<#wao<8iqW!{7o*;p@FI5lBTqFuUmoSlg{4g&rA30RnAVFaExSBgnzJXvGcW^LUa1>r5`N;s>nRq;{EU6&EV6At*5lx7!tn$k@ERZKFuwg zGp-G~y1G!d6?Vd8thZ~yPWaS!J9v5C-I+}8ut3n5_5)tHjUupMZwjEQ3U8CtmY`Z! z!@2t8jgH%%c0wn=dVkppJv(&l%Zsly}DRE(IggVh&O1s0jo^eR5HNkh#g@;*e3zBl3e!I;96yVyzF z1xYplQxK32H09_5fSy~ln4T1c|J8|36W$IHwlEMEFvN(O+*k; zn)F^0AidW|6Hs~}U;~m+(zeX}=iJ$y%!VR)kG%i=-+y;9lbL(ZJ?GqW&pr3tGjnGG z29F*~WJLHW;9oK!ig;o}@Em?`^avO{BGjTgy=Y61k^{}_h6#cH>NhYsJ}hFAGSM|$ z85OPS?^d0b<>ne4+28F=-%yXx_+aJ4=;71U%CXa48y7KcQbb^++rR;K{gV48$HvDh z6T@7SV`EeaeUtmUg+<1NEBnGZCiii3r67ru`nv^ThU;6Qqg{jJ)Jj*M-k!Z8JiPr} zef)ZR`TO~MdAPfV#;IIGl;N(Pfv#R29{#RgUVVK$`g#Po8h>sB?BJ}QI&wnaF+)O( zG~ueh+r-4g_`ZGmOqnvJ_Z08maq6f(o`HdZeLTGSczN{#h+YX(Rf%EAy;KR$2}n$M zhA0yv)Y0*Y(LfsUhK0u^CH8l7Lqg)uSh=uxk&r5(H?3&zh`883$zkz*JbQce5ivu- zevsHVSgj08R1SfCfR~4-M=uYrULKy~JOlcA`t|kle96PJuZKrJEG~s?qD*mw#zjU? znEEI>Tz*#F$09=96d2EF)m?ZT)b=WSZ~)iqg9b{ zQxYUqG6Ea%^y`BnmWZ6TCrYbX`rkE0WQ5of@k#0!+Tf89eUvfESfwg40b0Y;yfq>t z`c8;b$A%>i2#b%8iH-=v2JbUj6=`h7cvC(4^=Sfq++2%9MCQ%ZNX))hnZ&HV!ErHh zYG`TY0PlW%?w2fSvZm}2!NH@|aTB6rlmimR3>)k^Vra0RXP}>7FR$L7QZy2{`{EfM zosbx(p4vxjx5w3>&<8?8?=Kcp?~08zZ&F$Wlt~>uSs59kj*F#A6Cb8dP>!1#uk7zO zMwt+oq>fO!iR>EtWoT&M5vqj5Fja(d#E=0=Nzsvgef@^`4ISb;*w@!1WJrjoXMm5V zSHRGrgMEg05BB%-@}eqjUQQw)BP($cNvM7zPTxnvIi#uF<7$IL&(t1s#)wJ!$}$arpJ|#G|pOG`o4xw;x_qn%%r;Q^_|} z(TM|~g(x%4lAD)$4XQO+IV3ttnE+*c{oK8L{b3J)J<#3D&&%D*-v@R`3-EFG_4a_> z6V4$$z}wv`(9hl5!_(c{GXVBLcV92qy}cj}@c4Vc4zT`s?F;#^d;55My*$+0&of|X zkiXAR|3L2mFK^!<-=LsiuMiJ^KM!A@;1DC@W}F$>er)zqnH>E9J;0oM^#D`*j*d=N z#=JEo8gx1V+cqEon)JRo5-B(3zui>Q)61-+B&T^vYTm|zE22czqsSyl&7sX?=Is~Y z=i~0<5$NYZkI+v3o?gPyi>3%iZ%Fs`6kvSZv6MeOLYqQ+K?)op#V5emgC3zh;T&2M zj?n)8-k=?L1b8?G;xPaq;fS=Lh3OHgc!Lh%5z4}mmIV#+@$>;*!Xt1CM2oo59FoA&-CeV|fBep<_Eie!% z22z}X$O$+le(s>R?x5@Le(wJ60q%kBAR13kcTX>OPj7cmA9v7W0P^&A2c-ue%?r8$ z^aSW6zR+Jl-JxfI!oTd{9}p7c=j-F+1HH%FH`pWCE6B?uD9C@XmzS5%kRW4Ynzh(N zwOr7BaPz>;>?8V_rh!Lv&06K8NzYmZy?~SvX_0W5xR|(FB!LzIGwovHYLNt51kALH ziK|5tXb~{eE+(!PNuWi*OuLx4S|ouM0WcJ`r5Jzp6;P)3HsDek7 z>UZF1g7Kv(y_!-e&IY(9B%TodzCXnun0?-`l5mGF6vC*ngu%;(EajFpt+utrW zEZIC2+lLH}QH2_ztZ99`F;$Mbb1%5s~nrCj2{*LVFVPT6%nh6BE_00 z)nTxd(MZV!673_EsyN`ZDOvs&!cuf&U=43%TvGU;0gxp8ED~X5)T5KYLJuHe6PX0e zz!IxR#`Z+~gR$97iBnG+p&IwNxU)xmqmmL^gz#Yul99oxM2WgMMa9I0hsBIj!vge? zu)uVD%*X^m#Kd-DSVCwViiRp7)dwG%7Xrt7^?~-6X8PcgFj1+b+{Z+#l%wcU?*tPK zim?mDh#DsJv8V7%5d;Tg&%p13l_r76%;;FsJSfv1c58YuVu*y6b(A_TDc&r}Doz~@FAz{d4}&reL&qX^SWyaT zaP1hDlo&Tmslv{ujD!S&OLdLFb^#`jE#c!&^#qH zAxdeMVigvXI4&&8EUit163Qu)6GtQr9~U|j6&4ZNn3BzaZ70U5rv=4CN0}t$BvgL5 zDH%#yM=B?TCB-DdsqJK?I`KZ><4wut;P&BBbk(Fpxa|b|gNKP3P=ve|r$SlVCdS1> z4^L1^6~`_H6zQH+hw!*WP^f#-?V*V$HV3D@>v<$Z9AK9XtfA*ZFLR>F!y#+<$Y@oZ z9MnHnm8iz$>2JOLj;r+%7zJ&iw}GOEMI^+Bjt#*!BCvGb71yu}nCKD2Tz6V%y`Osx zAMNTY$$OO3b`kMvkg{wv0DDKm3nAcq4xGnKNsPyI$VCkd!g(i5j}p$^ zDU5JF2+t#9RiNN<c9yJ#Gy6VHW*Bs~n;v=i!p`M9@HhCBbp=Q)!#HJ|FP{yip@C zz;(ECN{liwvDauYv|;KxRTKGyrQa>Z4)7hr9Zfgi}nnOs+QAvF|qP|Gp4ic@5 z=#2sue}4-gLO%FJLa#T{6W^`iIz;HguBg=!@al#nwQB;dZg%a}T#5hff)chQe7KKM zPEe|q@QMT1@t|eVswik~Rb(`drLNH`vo}CUF#MavBpC2i&}%qx-oO!;_j{AJM_q{G zW;wBNwkL{re}EjB*lr_j#}n*%Z$A6Gp!aYN`SfUZkS~Huc|tTD7D(`zajp?b>d69# z1^%-ncEpLekS9qO@*H`d^derwpS(;4k)h-jGK!2NZ4XGnK@Vl*LjxuN2ld@-J-DNMy zykr5g0kWa8k+Lzew`Cv5qGT#rl5B?TQ`rL9QrUO1wX!X;J+ecx99fC%xa^GVvg}XU zZJAcCkUPj-Tc4lt;-wl24P*kuQ|5kgt<(m#4^c=hjqT@}3)0g7P7D8)O92@191W5s;Ma>Y8uPQ_tGk>Y1Xh2n;y(Zb5Y*}~PL zm&MB#!!6#hh_Lv`;$w?1ExxnZY>{G-Z}GFmWs4dM&eGAcv*k;ceJw{=zGWF@ImL3W z<#Nl7mIo{gEKgZpv#hhSvg&Bn)5_m!xYgTMA6iYf`qFB()h?@StK(LcR<+jF)=yf$ zWZmC-ly#VOqV-(smDby>v#d{8U$btovA22F#>*ze<{cZA&1{?HHd}2nZBE$yZlkkp zYunwnuk9$?NZYBli)=U89=1Jdd(Bp7*Uqk|U4OfAb|2bl>{i(Av@5VXZ+FMu-rmhV z(EfG%X!}|AE9`gM7u#R9Z**wy@S;Po!@CYi4htPNIb=JWak%5?=-9(?kmEa!iH-{$ zw>aiGUUY0|fy)k;BQ7-^+IR5jFup@_hgBUiI#hI2bnMY_ zM8}wpi#qP@c)FwZiD#Y&dP4cc7fc9wU3vGbVD(>t&4T;93% znJ&)^dnW#wmCxiobE8YgE`z#!*kxIl%r1XE>-_A1XQQ88_H5R(f4O#W4RVcfUE!MV zTGO?2*Wq20x~}bdq^r)Yr`sEDv)y*NU3kv!xq#;;Jh$w*+~;b#J=-m`+l+48x}EKA z+dZKB#O~jAFX~?3qi2sddwkv_wZ|VlJM|pVb6U@BJ>-$?v7;msY=Y+}#r1E1+^;=l)AChh9OwCimLb>vHdo zy+`(*-8;2+RiAEs-s!WXPf;Jv!`CCmV}r*z&-R|Lc+U1b?0MVkMXw02RbD5(9lb-m zKk+{3eaq)1AEnO^KEL`p`-b{{?wjjt@bmXm`|b4m)4!Yl2mast{}SL5FgoDNfZ{;Q zz`=o^1f~Zz_Vw$V*mrN=>X&=HJn7}FFaOc6XFp}X4gD(nyY&z2zqWtH0M`K@3|KRu zVqn*SVFT97>e zU;XaYDb2BSWYmaJUyr&ly65PRMyI`Q_4?@7SH1q* z7|$^?#uSZp9{c{-tz+xP4IZ~>+_^WNeZtqZFS9})h2cuhob#J3UGBL_t;i~LjBU%6EI`-J`zmQMI1s(;ki zQGZSxIC1&J8_~hh-$md0aQKHmepo+g)TB+5_?S0icE#Gneh_;|)m}A8l^@q7E;;Ua z{7dn3<10Su`_VTa)u>-pZ%mLS{4?QTq6;`v@p7WpmuVX@U>)#B4j1}@pWwB6EaODn$){W@it z>$3UF?tb(BHzmt`mjC#z-M2~KR;(Dg;^4||D;KZSe>d^FQ>zBA+Vy?s@4xuIes$#P z6F&_4Vdsy}{J7vp?V9K{zpfp&Hf3Fpb<5XVt)IO9w+-Vr6#W$N)0T}-ZCtR?ut~M4 zV)K~I`CI(AY}wj*>!NM)ZAshy-2U$NV>^cIIJmRd&b7Nb?pm;$>`vPK*PajdoZkED z-rRiw`*!Z{zW@6J&IjhF$Wo@J)TB;KtvLAh!Q+QsIh1?&<--TkdZ%ql@0z|UqeI4` zOuNiEnS9o?tlI4O>>D{zIhDEZ=bp=ZEAM3f>-k3tUM(mt3@OYj3M$Gf?q8f<(zoPL zX+UXenO|8-xo`P_fBF9Fz!ASADM$T}9y}I!?C|k^$1_h1JdyMBke>@rjyPF%>a|nH zPrq^c*I(ZKrQ+AfU;j80bLQ6B$!B%vW}UY@KmS783(GHdzPRqv3zv3P_*G#bZ}GRkyz}IpO?Q3n=GKm`y;v7pr>mde@MOd0#(>5m?VH-)byM`# z`W1#342QW_x$}H1&(pbv3-t!j84zM&=s^>O4;;{+SOa@UIISS$g+Y+siF6_|{#U+& zw0$LHLXU1%ALV{uEF-3rj0&8(TYjS@TSY<0?#< zZHdf6rjT36Ev>C=EENvkkl9XQ(Y3v&Wzg$k&Tb!RysTW7tlcyCxo#cC*X{kZ$B?hbMGnnfpXm3*i8rn&Z||Fv_j6L^osgc(Hhi}KoBWek z@BVb4;MBF+@e?M`UA{4;@bqtW{=?pkn)3O#n^KE@`Mtg!k;{Qw3(AwVm8CCbp{r+m z3*g`*H)l&P%@P;nAZN_+8t-o5m({bE29NC!k>GQyyA?8E-NQHc1TeAwiO8XE_$4Z@ zh%7vqgPu(+@MnpGg3@e929mqJ(-!^q61Q1DfBwGrLSuGp?|R~xOjFT*tg@R^${Q8c zhx*WC_nspZH@``Kx$0GV95Ld=Af58PHoB$4aZKXk0cYO)H1ldEJuX}QpAeT)}CdNW)-pB!QmA1DNyQK)8}%GL~RS*BHNcLkhCqp`qkOII$ttvi9`011Kq^ zKLtKLf)Wxgds;mIQ1-kL20ELKePt%qD@!XfJ|7jYZ03Ab;sE?}LA4BN(O4d%%@$A+n*M~n#>1LtiqJxDbK zqo)|NXo~=_!_OGwM~+BP$XIEdhlHp{sEqMY^YEWpDS)D(zbLt*4PpsV4~Y>%fxLd~cGt@YeL{ub_!l)83 z)@%_Tr4p{EMn~c`>{J^fV!~ta8k-y8qg4}76RCXhdXj2Vob);-A%24K+LGdrh(Y|c zW#K=?F(FwU52q+Cvme~~I$}(iO=V<(^>)~bX>bG<;0Tg(*ov41Nm0aq7)w2}q^w7V zO;xI)4>m~&`?fV12~wI$RnzMx3DJ9L|AB-A{Er}^>=8l@K|(=r z<^}sOkk9}^CDb+?bKwXQf+I+%ZFrM}Kq%C}A?EFr(H;vk}v2sk9-F4+nEr{RY92;a7^(S1INiQa!!ZR zYB-w)ao#zwBlK6~Q!*dQE(1I(Al~~u>rRDI@qi&7^1g=i zsgOPe@J#`XD)=7*y)zs}>9-)F91bz%ao`G%Bd z?Bg}!cA6(#HUHd{8M8kB>YMM^ZQj0n-+|QBLx&HirKe|PW@cq)=j7z(<>luW6mW%r zwb)QXN*|HVAAtK`A|(yXjtSQYdtEEhyTdEE8lKa`Kc44~NGPA-v#(VkY-!0`^3a*yR*0s+<6z(Hz)E(^ASs*;caZyxY7_W1@c&=*568Q3)iu>s zm9QT>dgT1kqet#kS65VV)iND-Ou|{E(VRk#;!1UO4R_T3901>~s=icHRSkxyb=t3y zcLs6sxgd!wK@y<&Ja<&W*%fF)EpLZld0CkV#__Tm&d_@O58CiAXhTpKpax1zuH)b% zmDX9l?R8+Y0wFR{rLOawu9ZZDy&q~^UC;3r#$IJnj|N)W`_4822DGNFC7MR)PWme#Ahgz3&8+n~G)G!6oia2)R#$XX zuUbou>v>1LICyEH#!?$}hIcd@+Q9a-+R#zUTUFhtzEpi3B*L4Gpy!Q_nhoS#!VwAFi^gbh1RP5ZRi$xl6r&hSkr30<85$`%*FgOPqeKyCAbA*%a>Fw zuay+2Ih|ubx3wH#>C~~c>LaCb9O`nnmE=|nxKXwL8*Ow4=;TUt0dBi-k9m5Kk)D=z z=wRypJ!r_%CA6TOCeP3a)B7F9>3v#Sdd9ywy%*`AyKw_{l;O`3dgVs<5qz;$pn46c zp|Lt8p;%}fs-)x&9y8l+?#S`cUfr zy(m`>Js0TR(SdS#hgn+aey2`aeT2}48=W&EXMpO*)xFqF6>%i{#z?j z*Fd5%U}mz17atD~e2!ywmND*Vth!LgW>rTMqJzESeq@CpWEKV?AF=B9kiE!TW>fFK zmi8TRISF@5tUr~$3_UP#0jr=XvhUjjkA)ACbqgXl;K!jg!LHWS40F(CLJo%0Kpqj*(34>GLf>dWyj-X0lVE@-WDbtS0Hi-G;d3! z!Shy-Q3?AU?6^GlFisw1#HE^4q zAS zNts!fpcW7&g02tjIVaDU4f?fuJ?a+~8?eV^+T&fJM`e%CaWD-7B73zsOrED@^;v$XAKbN zlvPzi$oi=4*g5W~4MZX@)znngXd6WKJ_q9j@y09F?P{uz9)o!0k)wC2t1eYnQz&D@ znz-A$pE`tQoxqGcS!o&GP`g*-%-KuXhc*HRanNq7TpIO*7$X5qG8u0e%c^-BkQa(I zD_6)wZk&>5eoAGvc_(ml=ujG$?j-4w&AF*BH}Qgw43}?{mxEmr#t|;V8npjl%07rH z3d}&vnuZ{=QFF+3GiE^LOz}xjddx&-o)MV&Vf|JkGbX<^iw^Q!zTn>AokqU2IVH}gR*8@37D7+dFF zZs3+TsEU*ubicV=2b0YfnSt>DyiG?K&?{hvCcwWYsc3kxgw;1{AU0W3O?hZ1@&L0Q zkO;Ma4#ItL>iC!>axV`s)R}ldiHJPZ0S|afsF^FO;Vpq1jt9#~;LZyQzy*mf`SypO zw(SDqhmkm#I4+yy2iF@*ZVB$BVzQ6t;r zgKD6=;^>LqDf|fv(V23v0yx+WBLHxaVKN+fPdZwpJ_*^c>25Xv;arj^=Dr|*-nNG5Jn9?`NScf?rbTZRCuj9+{{m^9#Ks7{nm3V7J9Gf0h>-#a?E;aTW@Pcn z76LQvHkvu}mwdAd0v7^3E)#U)K7B|}t7@Xh7aEL{ctM+7sATu;+_vGzl}o>xH%IgF z%o)?CH%_fhCR26E4O1*9Cr?hEl6-TDM%@0KVgV^rrrb={PUWY$PM`VltU2?(TC!sG zhAlhyrW~ZkwMpvv`9RS4jEy-f2Kp=yNA>F|Ds}8id$(^~yXu?8U(WmNQ_ZYdpM3oB zC;E@Mne{Ws%v&>LGpApNbx)>EKSMr!#`HTgET+$d?dA-Ars3m`Goi#Mvoy0mo3~)` zvhRM}2sQ>D{7FaY$f@FCYY6=tTLW3*j9v<;h8W`DpszV+WuU_E-LYl;4=cY}vS9wa zxpP0`<}`k4n0-U@+boT^{V}UbW0>9e>9cb_`)uy#^S@lYY~||po44-)%IWFS&L*`i zIwNJlvIy-$@(gs;Ymby+$lJAT(^???_2PwJeaX!y3k>shUufr@{#+w&XFu1?(|w_z z&n1j~qom)1p zUA=0>@@31GYL^%m%N8xxEvjF5@hgqEUHPhhp>~mev0(|nwEfr1zWH|5>h(Wu1&=!Q zFm`h==b&Jq`a+e3UZ*c5Whic4DOX||>MdwLhfadVEwe39PuahF$Cgd&*ZjD8)psjb z8dm7OtzLfd8;!VCd{e#L@GZB3U+Mhasvp*@-?(K57&b~4)ec&Yk`){-p^Z&sg@?$n z$~ck;9)=Ticci*+&yHwTH_V8^lS)m67`FZU_U_)r?T~NZwpF)HzqN78>CGB(JGZ%hi+-zq8^4|3!S8b1v-bduR@kST zWQ)p#)(j1|zLbY1MT#g}>_LKTg^F^STsnWyGUdR5eS7yB_Hes(yYxG6?D%cFM%@0` zUcE!VQ@6{o+px!J-~Rn6*pg`(=^)mu96hz2_oF8Cnx^{6@<4l`lc(E24G*TK07=7s z!#=}aejnMZ+jDBSM%>Qs*6z{n<@Oo&^9T5pHZ%r`4uD{@Od=J`wI0khXRIKc7xUnT z@CAl^!D?9xV?}y8cbGq9NHwHb96-YL`%mrDh})Tc_4~O4x)eT@9OMq!(#la{sHhzE z#)alXVInO(6((wpP(6TwzA3}$uq-2;OEUm5?LmENb;{)f8gcvmz|9mxsuoDd4j1+I8GO1fjXSJ8q&s*rRU>Y{ zrs@uAfr38Gkj`hwL2TI7(a2y|*WW|I)KXl51^7;R)WR94AH!1$hQsxTZXLWT;@719 znOc3Y9w_M2tkG9NJEo^31Z#pMuv>%5K_zq`EhK>sB2MdgN&s{rOP5J9wCUQkn!}e5 zX~gZfLpOnS9n3}anJ~)%a{(rowt}g}1-x2gD+q&vo{ENA$Si%PAw!qmn0E58M%;b@ zX0_=Cz{zJBC{95fh*M8_)dR0hIQc@0fjeddjf-$ZPh^uN+?WYp8{eFkv@k6<$>k34i7sJ|==L~twfY=%bMDl%#^4d^j}L=mGLTz}x9 zKu4Pl>#Z%TgL*2GFq6nHq6BnW@dvW$SWu&^(9=+0#=IHkQ?z zp%U2B=K?Hrw(RV>tg|8(P3EP{+kgk{0|CYiLQ``_bUNS+(P3?oGpwzlKo7Om0=foJ zd@lP;mPXvpqmpMeWNRr~T5!j(1L=S*ZE1rMkB;JjniuHub$PnnhMZ&B8gVM~b&yWo^qMw5R!zZT?!^Au#V0ch2g>C5ZO`7#}p ztOrILiyJ}02vJs`5x0{C1gdu%XhA+LrK6>^PzqX!meSKwpk0M0#d4a0GeD0os4WDn zP_m)47U&6{8kVgug|y;^q8g~(#X^m^T`jCDxK&t3%hUspT3QA?kn&nurmpyIQJDy> zDLh(ux2U1GzC?gUZv_U}^1DXZn?)xjuxAQyP}n-)MF);*oe{RKw7#USIKN0EZbe1) zfU~ajF2EVe?xF_-IO|I5N^TdIicp%OBSm)r?k?cd02#^is)13Dni%3njM!mzF}^f}^(lR#{bPPKid`@=L0X5C+g8U0Gv! z4e*3ZGIB*2O-WHnP3cWaOz6oi(ww`awoPJ z#_UmEwiredjAV;p#MOsvF$_4yra1b21|+r^rsj<=JCG^p!p(|)>=H$oDN$I1L1*3cqfGE;cvDW#_VahzjHv~ zeyFhM1|PU!i(%Me7`Q{x;uoe+CBnraY%vU53}bpo>OSj$;8_OagDPw>jP&(Hf4lxf zSc`?v&9KEV!n2AGT91Ph0JazgmQuj7Ipcx=wixCI3}afPL6=9d#W2RZqwtC@Sh&F!!jVc23A{3ZO;7YU{KQTMYAWefX6vh5`L#Uxr~{hLL_wz%&(n&?j18D#*SJ1GXGj9`?yUqXW}c)TT^390Ow z$%p9&>mR0G!0drZ63jkguVDJX^nr~JYQ0er*qzu=`a8lzKz%pNd%z{X3ogls%u;{h8FZe3$DmH*Z(%4BnxN7Z0}=OhcH4Fb!ezD>lDk^D8#LVxu7&4cTbO zMng6lK6o@_5e61lXp#UMG1-X8MoczhvJvyaBPO$v%tkUB$!sLEk<3Q27#kZ6*=YFi z(U1tgfWad|M~5XQ;uW5UgeFXaQwKtLUVtE85RB;dKeV|K57>H>9;6F-igYCHn~s?{CuSq!dG0n#9d6gpb@vS3*1Hi5?{ezwxH0b0Gb16a>a02Uy*)E zBW~rF^c9B7a)9Elp1O9DLUC78E^EZC@G^IWhuo9be!gb7YN$-Tq7k>ED~3wL)t|2& zzoxsITB#AYqDtM>ME|u^bl1VsSoZ4mQfw~8=2GmQ6T9bR r7RzQnteKC-o>5@WXZ%k-zryBHX8n}SrPy5RzdeIs^aKekx%PhmiGf+} literal 0 HcmV?d00001 diff --git a/themes/altowithjquery/img/page.png b/themes/altowithjquery/img/page.png new file mode 100644 index 0000000000000000000000000000000000000000..058f7297205a87561f2b6842d5b31fc4e8c57dc8 GIT binary patch literal 183 zcmeAS@N?(olHy`uVBq!ia0y~yU@ic%nK+n$3z9dW_L?nM+Zx_s*XbRK&ngzopr0H9DoJ^%m! literal 0 HcmV?d00001 diff --git a/themes/altowithjquery/img/q.png b/themes/altowithjquery/img/q.png new file mode 100644 index 0000000000000000000000000000000000000000..4fb7ed6d0d132d8552e273839f37660c30d241c2 GIT binary patch literal 161 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2ZGmxy8xzq=wqyv0HT#b#5&)j`CbLPz5yLa!I z*Lv&4_ia}`ty;C}K)S*j)tR8I8t{5Zb*eHRojG+%w1mTf!;CJQ94r|giL+g`i9UM|sGq^p)z4*} HQ$iB}*!wjR literal 0 HcmV?d00001 diff --git a/themes/altowithjquery/img/retrolien.png b/themes/altowithjquery/img/retrolien.png new file mode 100644 index 0000000000000000000000000000000000000000..8828bd2cfb7099a10f87d7be06ed09120ea329ad GIT binary patch literal 28311 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

      88(VB#$ zoK;G{5TaQ5lWULNRfWv{U{B|cmf7NjtH|EMjO9n$>0AfzJg;%S^}+qR@#VCtR@loTu+S9 zkR9N~i}UoB_$zsDJ-$}ym2v9-S$Q!n^ZgfAXu2mKs!_} z3=>{M`rr)sm)88(CHId%ag15N8#K9qLnZzRy-%t@x7Q6!!5r>>aMMNyd{y*uEA4?f zn0kCW&^ikaA>BlhP0`?_KtuYzJ~CtKn8TCOgX&JJ?ha1$0zwhY4{>xmt~~V%I-iZW zWTTCoV_vC^)W%)IDwMkz?(Urqiuza-qGKya((~16+lV|zHxQt8k-63hxH_V8c>#mf zW2d%EbqyXCLLygk+O1 zW_LJ!3kki9IjWfrZg`axf#jBEQhv)otje!&7KI0rfhI79qOTM>bGw%1&bYQapN%aO|zUmZLA3 z=kYtAUUbdwiUj`4_Uh(-nOx%+qcM*xE+s)K7gS|G)Wq$`}7RBjT z#cc7y_`F)2H8OOWqLJyv8Hb3D&MLE+JazwuP@+doZ*=&VPJZH7JkhT&MYMHm*gB&2N zP*QZj@kh^9s8GGb!!PTNEA7Ec+s!pKcTG%8IxEl7RQN^6YE3e7XUBFZ#K*^n8*_es z4w!2Jv=~6O^J*c@ZsHH0!forA3JMDJs-aqQ%^+lR8jPNSVI+&x1=8~zcNQbLf|(nP zD^b0Ri^iGQ(Y95#XN^IHe#Lt&2z_F%PRXeMPVRy&(ZSidVh}S*Bu>pXou2wHEXnEn zte|*FZA)U)ZBVbd>6P&5KJ+py2q?1}oE`TK%&<8+-4pQ7Fjh2MK!u=4k#IPi&`Y0+KtKV>0S8$lWhyEvhAxtMk-HRB@x}Q5@d=+zyr3IzH_GxEm9DG5 ztn<-fngSFWzE&I-dFfU7-O%A3364)BSomlitFn{6L7Jk3Jaa~|1>I2=8(DT*sfK3I z8c^n#suA0%mGkf!ze#c4+Z-cijn=mvf2X_Cn2jYJ9v&XYMTPhmV+OQ2LzJ=~wM}j0 zpw;o9cdR2)ZRv^Tm=MKehbd4?tpJ?mVwafbutPeK3jt}ry!d_a{*Y_n?eJ@i7~$p?QUwuH7sCk&-CWP@PR>tC-T$QqXAkvM!p=)zrdm@M|+c|fw0?|*Xoc+9-xslpz<`rjl4 z(obK6k9i|)gs^id`;XFpTZS-?bvRvOW-J=e0S$l(nVGC1=dr-pDN=|FXXlwZ46o(H zQIU;0bK)71*;B`FinMm7tnLP;LHR57I=POV#~j}6bbcq)F5@^Y=HyRv(A{Fq;~hvHPuHSxjTy0CTBboc(eB#e-=dvza-h^Xh=i0UTTnqFq~FqIm^J>CSEiM2InSqb;DrNgQq1wmcxP%UN+&c?Nbk%Aw)nQi3x}%Cj9-wQae-Jg&1k*{rynK_RE~~peq-F zZ%a^0U|n;_>G1DK#rv2#fLCrn{BUqp<1rAX&YSnTSYAkEP9#(`Z4v~H$a^Ey%_wyd zPsTjmLF?s$0kV5}#-C=8u)xP>JmqKj94t>x>$aZ#1|N zX|-c)+#<-rE&JU!KEmrIf^sj!Fg)?8VL+!74i|2hVbH=LsX#REOmHyNWR5pP9X8(b zF@EyB>aun<97zo$gGE%wOtIL8IKxEwMva{d2OLPg>K10C~!Mft0Q z=GGm;K0Jufqwu&(;X%vbLHkdmrtLE&xR`_V{TBSQa<(pR|CRH&e$o@o|0A1E!tJIJ>OW(>d zoI(R|R;rU2dt}kLAM{RUKW{rQHw4$e(Ai=>O&Ia&Kw6NX@PN=o0Q7(qVzU%@1Vt`2 z5-vwE@J>Q!^(7k=Q;vCFHS34VQJu|Wg*yEwX_uIPJ`C|cOBc@px3LvXZx)}~l94@Q z_%HU(9RD4F{C_sce~YCNH5`df1*zJGF$>04|}OiV0) zCQuKTa|8k*urs8YC}S^#qCpV!)^9;%tKi!mc!(s3Y_Tp;pdYICA+n(7io03gbtf`d zcxcbrN7l8^w`s{6Z!=GTp8WA!NnWV=`sZXU*b9H6>_(QFy`sc7>mk z=5dQ=^1&^>>h#)hjpPuj%lxW8Hu+#yphtXjRcPoJ6JEgr39GPglKgX*O?_Q|zPQ{0 zv0n4h{c(Z(CF5>-F-?#cVx|!SwBf-`I=!;@K*_JVv#-1JHqt$!L-*zgu>3#GU1d`o zT(iUii@OAupuyc;gOl*!?(Xg^8r&_o2AAM2VQ~wvxV!t}`*Q!q{dPW0)lAK)nXc~B zXMvp4xsM(*(nHb37_R5fq*3eE%0VB+0$W?w3-2p8nQ$OXIO-pAKECfKBq5+}mGuQl zb@2A$`R!?WMXHDL7Q`LxAm>(|y#0$o(vc{J3;^ZPTdDwwN(FAbIaBb;K<$%}CrLByTslzZ zw{Bc_1dC4Au?L*jifLpnRw7#qhSX`Xd10|!7LMaD&bg|vA~0`3-gv|~v8d3MH)IL} z;cxB(g{}WtAGJVta|%gf9}jj=4hX1=NkQ@s<7IjTnM;7xo1^q|Q$5fj>v4HPPYb5!qHk zHS2mF{Jardl}9QX_?{fGzqYj$k<@{BEGh8Zyn`Hpx>y3ouUS*2NQxmf==sOi^b}JG z^=SW4stfKi*r)DOA?hJ{oKT4ap)IN!>-;CmjK|$eX}fFuffKLyLQSa5z(6q9-C9L| zYEoJIRQ@t0!66CDxu@nDog*wS^FhaK+mr zfyuvDQRe2IqP!g2;Y+(ncFBA_XNLQoFTG?i9g(1dq}7KB=QnON$MMhOF2R!9>1fnPfjB<5>PF-$_dcU!C;d! zqO^!;Jzc`jf}+A8W$|yt0=IB)aMe3s{<#?7!xq8>h{%T%pxGhJymJkY5q0d=Jsmf8 zxc923hy;bgG9&X1gAkiHJKxSu4&Bg)L=$(5xE@a|s?M1M!+@58^LEH+!%grt zYMXyIXU5l~w=I3n)(6V-4aP+KHU8E`cYC5wr2XQ$tdiZq#g{|~X%^SvF>yeR@0)ia z!$1d7^Gt=1<9GY_yBm5Hbdw14p&~i1cG|dzE}AMvv7@f(FP~uDC`dPv;f;7ia2wBc zNI{YsG%R-1E^=xtGZr}S)Q6Te{eXdO+Qr{2(e;I zeY9u9R7stpk9+1xa;qZ+)U5)>BG_QCpIcmMyPV*CY zy;sW=#TvF7@QSqqclQ*c(zIdPX%kxdB;hQ|fFRi;62B)U2LuK@l(FhpH@MYA+KmwY z*(WCsTWKZKE=8`Zq~R^lq#HSAMao^4IKw-mGV6wu<3Ke%a(G8lAcOyv<@~E}+h>QgnKb~*teD+me!Y}Zp+71OFA$#D<2a8@nZ_7NKvl~|)?td&7 zcRF#YF-AT9(c3ay;N4wZx!pCUWXU$C!`WsMX`vnJ8?)3&7Vb4n1}?Q48}a5=Y>xO_ zleJBpe&Sjx6b%mJr2MSbf%WVH1@j@{PscZ*zAa$9GOM`t*mlZhiAXm8d^JX`I1gz` zlPbS?K(L9|OlE}DI8ICuSNgk&I9D4M1C1twYXy}%m!rv@k{;cO6 zxbA8gedtMt0Qp_FwcCf11H+4oJ*zpYn?8*K4 zHtH#Cul_-w4$yp7a&$!DZ zE28b#P$Uc~>}^!zu*HZl;y$a1(V;jDB-$swCOX230)_0*aJs~_&!-m_uMWVszujFpT(RqB+FYIw2AcG=3;%h%} z{RL0{A2!C}nm$jjMdpf2;+cn@XeZh@n&SiwX3>Ntdx%;S2$& zTTaN0=Yj@D)#aqIlwO+^oz?Zv=B z&!PjxDm1ni$zy8ex%WnEp+4~S^)uli!c0SA0_h976IV4d9!^`hC4O{kt)5(MGVV+FB2*8UZVCMBPyRj z=R*|dCg`9+UdbSb1g+QI^jVQ}3H$2Bj?Jjz`|@zO?GdGO$MTmhtvunVkGe<)3t5C- zA>wU{49I`gdPL;cndJ~gqQn*$)}HVgI6(ED0D6J4?n++PZY|ADNQhMAJsx&7=wywf z`THW=T?tx7lh6!Q2RT`{bAH%0J%YLv{5ckvY`AbG82q2gJ+Uk~{=(yyE~2X_21jKp z^-We0udwEy{yP<$b6qwVbdmgCU`XRcaP!V;A54qj3%9cq5`$hh1kst>4YY~cO9iUc z!bG`Xk)L|d@iBybB7M>nl7uTvwx{%!J@p31BQ}K;#VF@M#&1xW{naed{<~i+c(4mi zqR&z3xHFwdWh?w5qmtHMi6Rd#0k+wAQAZUC^so<1K70N9(SurGcTsZ5*BLlbz36FQT4OJQ3dBkv#~*Fe zIXeRRk{U78)FWT~qMO69IQEEUz!yhuzVVr-aqM=|b<~>&1Zymx)g!YtSRI!cGG2 zTt)xd1R7%u!T>^(d^>Cnl^tjSeMX>yCe?u5jTUThh*E5hF8E$L6G25Wt-tgWWTH@W z7ZI)a*YptNZC&V3w$%jArBa~Dhiz8f29>0(=MlrKY9 zd*%OVOK~3{Ib)SkuCL`VeR~7kx$;ElWc;ps%kzkeXK}%!-W}%>q<4a2oaigq7JaP0 zt6{hN^?#?)HPH>U|t2lOG^~JYXE}L)GBx}qdXz=syb2PDH zN47>3_L?x;b zAB;(Lcs0z4JgjpX4e@^sbli0&`2tvQ^qixxc|$Qg&`E~3fy!i zpS(9yis_)3@veWwY&6m6-u3IVYeK`E8XxtnjDfx1`MkKT$~S#pWPO>kkf|AeYX~T} zL%2il%r4z6XV~j0U@ncy=Ol`J1v5@dAwdKgmJ@|CNY%MSyWhFD8J}sRp5{$?F9;?1 zVc+x%@F<#KoSW~nN6)G(gikuozaO__C5A4Yt$h7w>vlEd92?dK*rXMv`|R$=B^Fx@ zsPZRNhrHk$;?ZlJt!`v#pZ61e*!bc3Wj$U;b5o(WshooWW z=}ac?IMauP=#Gosj9nTV<*!Xo;+?uwiOBD*)3t%NTXQ<8>(%%~NrivrzL1OY{7frw zKy*Lxh%%szq>UGkhpdMSVsKmYuL9dL3p?FC&Iq~sgq~5Rl2l7LB-mVIdJ%fEKB15d zV^3=^@$`L+wDB{WH9A`w1RZit!HzGw00xs9^8@isQF>pLJUqlOuo6~vT~qZc9N}qX z%kOSp-Ne~Get%<a;{3NJ*)6cWeV(SywPIVCcW7OV-Awg3f{%W$> zIsp@{b3K(GtAknGy}tQjWN;x=Y1Pje@aJ>dD@8Qh64SU6bsV0#kq;WhWl+8yGxr6m z+(i1@tf{mpbN@7}lN}EAo3v1bKVP~YD?Vwn^rF-`p~SCz>^+)j8_>bAJ@mCMdOE*Q zVX=CK;0CaByFnq{>(XuTb%V%42085}-KdI%r63DfhPqO3_M0@P>F6-n@Ugd4=?*8; zrGX<5`xHwmaZ@S(Jf&y ze*Q1SsXR-0+=NoVl?a>g3k>eXLI)naE=!m7t)2A^1qy|jRLYlD$m2-eG<=y+PFIo3RF-Z29lapyFpSalR<{)8q^T(%L$ApKky zUiXoc>KX^Jb`;Ex zua~6Oc4IJbcYxmyvk$ujS;_6 zsf^~F?g^=CI5Xq!i)Hq)a8Gg`vcUmw;XUB3zJLx~>pIkI`vp9+7r?Q?&PxscL$#Q2 zn|~^BVs0-;pN{szAy3^eEU(f6M`wUK#54Vnz}q4KqWW-T;Si!u93_9e(D9a-1}m~; z_}m9M_*(~2WTTmrq8CvcTupbSDEOkkfaOFN}HM&-l+ zjH-D$%Ob*Jzo5!bJY;jZ@{I9P<>mL%>-|Sap#t)Mk8&bST8}|gu&%tvIbO5!T(=EG zodhp)&eYdr;MEvHG}!jS&|(@ZUMBBS0g9{IuuD5X`NUdbt;C84!1R~UY z@_z`}PvL%w*7x~_!V|JV_|aPEWWsyRN_`QaH$ks2{`F2e!M|A44TN#WswP*cwyE~> z+F!0@r^#K!u>!a(3pE~T$vQLRobZP}g2fllAiCB`-``xnV}2c1@jug<)OpQ{=Y6v! z$#8||nB~B?<9>X$q1PV${Avl*7hJQb-ROc)t_8NM31sijahz|)B{ZQtP(;x2#q+Bd znmAkBgRUfSJFPfk4XzDcPNu;EP#oW!kL8NyPk4na|!y)|T z_ov6^R&GCb#4we41DMg^jB>M6C@IqQL+zHU5jGz4?A@or?CabLVgwziIl;R;t){RR z`UU{~8?^D9wLL#?lT9V3_89elLH251ihOZr#~*<%N~2*6O_&!bjNa`{8Rq*qBE_zI zPl1T%w;0o0DP&>mv4(s_s}F)#SmEOvz`;So4iC5L>1-Ftc7CS*xFhReIqz7CdY$)= z>>PODfXadAe%~pq`UD)0k~Fl_$)p1Go~mL9^R1Cor`)A-GB{|oxQ>vRvR?#+y6KFF zBIWQ_S402M{gU^OUZ2_OKjH~hN{WUGbB_WqZ}d$+mA!maDgrx0TFk&w+3!DIrqJ(u z!jU=4s}@;t?92sJRZHj+f5w-3x(*-0_X;0k725#$4kf=Fa{Grj;|5)0a=Sk`5~-A$ zlI+(m&S(?>1te&3n+7=OO#kJNY~pyYIMtjVdmiC`Vc2ClTECYDoGfaXfB&SfjFG4B z=!F;`y1sEt?W`Q(18K4+Kl)SSdphwt7OqZ5!e&sit|Zxv^^kwMcVnyktvEXGs*bOX z7KMG7mpX1g8aC;6K&X!kCZXF_%~=zbaa9vVpbt$Eiz?AN>OxZGLu;Wzk#-s+(P42M z8!xEq9qGDa!e{zAWcEJa|MHcI-ATMCgv4MqCEAd|SPc_<%;mgl0O;9LV`13}dpzxV zL7%NEAtD+4LLLiT4|U$VluG$VgVI%jg|?WNmrxFMNjuxdeqC(?{=r8>=kQ7|^-}_woTc0<<{OagUwrtCV zVr#l^G+aGeZ>O0<*skJYU1d;o1Df%j*8engY9{T{4fcn}u)Rh9eX?n`M1Vxw>A^Wc z-sGQmj@>sB_C5(eic!Uml+PavF|}2$RvV7T5?P`kQ`3$dan#)Wa9eIr;P_ma5Eu zeNQ48718gMg)6sY>S8}mB7%8Xz2qIh4hzYRB*tS&m9*AHzv;^0G(*4N* z_e3lUdQ+pF)RfKwv4kRqG!F63<5SxS(L!p?_Hx2!v+f(N*YMw7-w0*w9pnbeO+*q< z39SJ)1OpY4az+Op;Z0y2N8Pik8d)7T$~(>DW@>z2WfHn^!SQuD$2Qn$k8{?0Y3*oY z;3$u_BOYmXf8hgMj?hLx%X}5BwyIcnASd0^`V#3y8|eTZ(8J(1ukn%j04Mmr^cBY>x` z@7sO0Xdu+)Psp#3#F^Vn1>r=y+;fb97WAm)l3l~1?_lq2y_h4U#zi-b;2Jq;!nSRK zzFme0n6J?p)H22GP4bS55fVl@+xoKgsJc(x%b#iICP-qEhvvjKpxnmI2-VeIxnOc5 zzh%BcQc|3DEb6;;_9~ro#Oqq|6w83j(w0%^;a@cw+d7Al6;HuS^$~Kis9uE2xeZs9 zo;p3RiMw3iEvAQtpFE_17&EaVTZ(+>K2d6Qs%0);b9086qR}j|TJ9`8Go_m@gVPUm z|D=<_6nz%jlcUt+7wfR(Gaq38O8no5tTqfUzA=?KjQ}4d3k<`U_-=u&~d#G!DD-a9X|6bCgQCm90b};H^oopR` zJwaV&^*Bh3E#d{p{6I7XFAEt_Kf}bH{~bdoT9Q0)RLHFT)~pCIZ=c27T`KdU9L|~d zi#&?-AUXrLD^BiE#KNz4!FW_v)|M-WteggC>+NEZbZNi5B(^o8{`ANW4)vV2^k8dR z)PzN(gkggRpi0DErQOxDhb&@BuE_e`!`M_L$NakSu* zz5a4OI)WSqK&m)6?$%{#k~Vd;fg#TLB`$cx1{rH^@gMsgv)%wL6CG(GVuLu4OuEbR zc5tp;B62y)(k&IOdz`rfxFOp6&ZRR=I-f=e5IPj3v6fM)2IuO*YN(pWjA0wf9cN3# zjsLdX4Ah}|8=u*e**_t=1~?M7V%)v5*9HFFVylwCSicEDNmtx=fP}&}V2K(+*R^zt zTq3BOVR3LvcZ7)mvk|gC8>dd0%#hl<1&O^^y~6xUCiA>%GHBl{tTn9a_m`ew57rLM zdj$^vyiTN5jt_d~arJqkOIu~dSs#juia~FoVp z@1wA-5!Lg*{EyJFIo11L1-O4RTz8A9%HgG{b8&~GTb`PkHMOWYIm7=5)-eI5YcUjy zQh=c1HSW9G+)>6?N^)h(dCqBon9;CZlgr)gzxDRy`Xzb-p=K|fytg}=7(r;tyq3%z zKX1CmVd!%ROR&Qc^Q2}Luel#>gry;l2#uG8G>_h|88c1j^1eKWJ(zlxD2+zHr~6xv zNdBn1|LS*$_EZ^{GMczHE{OC#ntj~~L{~Nipu52kfbrC1ygMU6OOZl5eGoIPe!^HL zM}4@=MX@Ys0=U-`D5wg!Z{QNQ?4bY-%xO&14O^_<+~1PnUxFMyrRzB?|B^xqi#*}6 zBxHC+Q(oL#TvoAx?~T{dp7EZkz%4yk5Gm(I@fngQQcV)x%VYP?PB;uA#pSvyoxlQ2 z=s_POkp+XyIg+S#msP)fRrH3~OeBk3x@GQvYkLo#w2fE5Q_|27Z(ow5^8SGe*QHT1r6YZH6Z zU$`=6mL@scyPrsg{T*BX!Q0m%9p`Gn6DF*_jv5x@9z7mBGt~f-i13e;b z>&@JArRJZv?$ucT>M*={L&5P01>IoZW-&e-_F*k;*|p*xCldHrlJ3^J7%pFon2?{r z?0}$pf?BM8GyV#V;uE=sA}fj<_N@n8G`O-K8JefWk2hi6od_|xUNzKg+)W#c2_I0k z=R&GS-B|CFpK4PILWkLiW1T@7e9PA~zg54Q!>)~mDO43~st~TU5aHSl(0}KlXFlG? z%v4e+2U(_#tOX|kd&@=ee*YsqM%Y}xJ|#GRYWjTl)XIYyYpScYE!&HQjo@yRYqj*L z0TLI`YOq7>~oPxE6pnnyPp|)|482zZL^28mXstcZmDjt z#POsqZzuCo!r_be8!Ce?ZDd39(xF%IY~S`zc~eB|AEum7@4{ao!%Sv80_L{wj$joJF+*di~DUWd(&FOfY^FNUdQtL^8-v7|hQamO7vKDw=i1 zbqV~M_UVmh_|%{T(Iq!BY{ErJf#B^5^IcgtI&884%6Cn*uOt`AU58iJG_=}KoLLy(Ej_|oX1qCV=M>B+U=7_v{ z&c0${5!d}E#XQg{*=4__rj81R3e>1(D9HN(1=ldTP zWw>sX?T?Xp$L~{Y)-r{iwOQ_h8|J@81K8l9e&U=-LXEULoZb$N6%{rW|C1MCPUzn$GbFsP0RLe1)V09%2DO3uUhiZ zN-FLSa=#*$)lOso#t)fTW~2ew{wL6>SW~Irv7ts#h4gx<$R7laQV&Dl!CJGr716IO`^3JV`>ZgS2UT^H3C3LU;&?alo>kJh=SZq9IOl5p(k=& zW`>942O0bx0=HewX(T&sQJbODn#Vqok&;4|sMI=%HX@7C<)|WKJEWog+)3v@=?deM zH^BZqQg119T%ALZY%7DMz}NR2Eh}3@>+cHMniwfb)Ep8#vgARo+=yTtzt`=xQ;EHd zV|&|tueKjoQ`_n5?!3ZemuxEi1(b36FD3W4RT`!4pcjlx6MwW}n~I4^(dZwn*;-B? zFHXE;)28dXbh-{k{0>`NVH}u|zBT$;Sp|%G1~Q%)U=q$AxKW9DJsv@{bD~2Ijxx#R zGGyyZ?Wy?UBQ$?4`b#-(6Ifn0g$uHZJGju+_8HhgS1|1=N@J;ab$(-Q>ij!Yy^ zyB0epCNO1a47h&_ZKe>(fN=x5|kU2IPoKd2D-un7|^mcH3(K>WSX{n(fE9h`-pBS6?^ahX%GoL~>C}7V4efdd3b!4u2*B z$fpdwpCt*#6Ci{eD~jG#<^RO5^b&8T6ta5ebtDZ4epHt2g{JndpkbABgp%Gj6CKT6Tj|F!8O0;;%@vxW3b z9E0u`iUyP~#EExe-RDDF!aU)ngL+0APIQ{%tMjUHa$8H;OPs39A zktI4|0JUW513opYd;r^XBt82EVK3&Y@M&!w3g@N#=J~mo>VEjvg_s1aJWWS zU*3CQ6^t`SZakKr@H_9@I8G)@MqgS1BhwIQ(EeAWr!lRbo3uLr|Nlq)U?|dh_U9}w z#xlrH+UI(p93d1d^SO+^`XU-$UvRKHYEzWxbhNdN0|WD1+hakyg@$#-HpK1v7$6rS zV&Wog=DGC+Wp*O}`O;ItMrQa#mGTDWm>*1kmzIcdadC%sT@Y)XG_FNy@KC76IXi0M zw{BkEtg|C*vL~jd;MlpifJF>2L=pYQD2V=t-jC0S^k21zC@7#d7?Fe4*~2F%OqG>I zl}s`JAzII|vpmDr@%7bTQp*nR?OwT+4gTwe|C;uVI%SkJY^33cSpEJ#E5~Ms6Cskj zu{Y*49#PHBtA`#&1td+f14qvv`Xt@T9)7uH4koR7e|{0bl&d0WKi?!n(!AQ`gbsDI}T^kDfU0^dSK^Feu|CGK8 MGAh!wlE$I`16cahq5uE@ literal 0 HcmV?d00001 diff --git a/themes/altowithjquery/img/rss.png b/themes/altowithjquery/img/rss.png new file mode 100644 index 0000000000000000000000000000000000000000..65506b808dc5758c3ecb09ec6e137deaee584e8c GIT binary patch literal 659 zcmV;E0&M+>P)^Ut zm~nJIZs)%9#y3;Yfx~_8o_qf1fByGe#~1@+gNDzyDYFp&w>=l(?6BjQXO|7jlMrdw zz=rU@hh0H)E6Vp4-a}zOj=71UV^B96J9YgLhlGHJDuaZ|s^Gh3GlU!9`4FzRQ6Ux9 zYM||me?r#m3e3C^ACpSy^6JY=3Sd(y#xk=Ie*&{YEtP<(YG~<&Q=3sKN0YP#c90Bf(xqBD{Y}k1d7H~gB{&MIR#Ts zHP(E>qwUO3=>M*R63_hwkWA?Cc#}A-YA;Ufe>kGF7vlaqsa{XhQSKR1fV2R((!yfg zzba9?cAuX7I-w)HsWE8zbody blockquote { + padding-left:10px; + } + +acronym { cursor: help; text-decoration: underline; } + +pre { + text-align:left; + overflow: scroll; + width: 475px; + border-left : 3px solid #008ACF; + font-family : Georgia, serif; + color : #0273b9; + font-size : 12px; + margin : 10px; + line-height :14px; +} + +html>body pre { + width: auto; + } + +code { + font-family : Georgia, serif; + color : #0273b9; + font-size : 12px; + margin : 0px; + text-align : left; + padding : 1px 5px 1px 5px; + line-height :14px; +} + +input { text-transform: lowercase; } + +.left { float: left; } + +.right { float: right; } + +img { + border : none; + } + +.error { + border: 1px dashed #fff; + padding: 5px 0; + margin: 20px 0 0 0; + color: #fff; + background: #E2001A; + } + +.message { + padding: 10px 0; + margin: 0; + } + +.post, .post-content, .footnotes, .postend, .attachments, .post-info-co, #comments, #footer, .pagination, #navlinks { + clear: both; + } + +/* Couleurs +--------------------------*/ + +body { color: #000; } + +h1, h2, h3, h4, h5, .post-title, .day-date { color: #333333; } + +a { + color: #0273B9; + text-decoration : none; + } +#top a:link { + color: #fff; +} +#top a:visited { + color: #fff; +} +#top a:hover { + color: #fff; +} +a:visited { + color: #0273B9; + text-decoration : none; + } + +a:hover { + color: #0273B9; + text-decoration : none; + } + + +input, textarea, select { border: 1px solid #999; background: #fff; color: #333333; } + +#comment-form textarea {border: 1px solid #999;} + +blockquote, pre { border-left : 3px solid #008ACF; } + +code { color : #0273b9; } + +.post, #comment-form .hidecomment-form, .content-inner ul, .dc-archive-month .content-inner { background: #ffffff; } + +.pagination, #navlinks { color: #333; } + +/* Choix des couleurs pour les éléments arrondis */ +#sidebar .tags ul, #sidebar .selected ul, #sidebar .feed ul, .dc-tags ul.tags, #sidebar .pages ul { background: #e5e5e5; } + +#sidebar .links ul, #sidebar .langs ul, #sidebar #authors ul { background: #e5e5e5; } + +#sidebar .syndicate ul, #sidebar .syndicate a/* le fond des liens RSS est blanc sinon */, #sidebar .lastposts ul, #attachments ul, #sidebar #related ul { background: #E5E5E5; } + +#sidebar .categories ul, #sidebar .lastcomments ul, #sidebar #galleries ul { background: #e5e5e5; } + +/* Pour Safari, ajouter les divisions contenant les élements arrondis */ +#content, #topnav, #sidebar .tags, #sidebar .selected, #sidebar .feed, div.content-inner, #sidebar .links, #sidebar .langs, #sidebar #authors, #sidebar .syndicate, #sidebar .lastposts, #attachments, dl, #sidebar .categories, #sidebar .lastcomments, #sidebar #galleries, #comment-form, #sidebar .pages {background: #ececec;} + +input:hover { + color: #0273B9; + } + +dd, dt { + background: #F7DFE6; + } + +#comment-form p.form-help { color: #999999; } + +#calendar table{ + font-size: 9px; + text-align: center; + margin: 0 auto; + border-collapse: collapse; + } + +#calendar table caption{ + margin: 0 auto; + } + +#calendar table th{ + color: #333333; + background: transparent; + } + +#calendar table td{ + width: 14%; + line-height: 2em; + border: 0.1em solid #EEE; + } + +#calendar table td a{ + display: block; + background: #F7DFE6; + color: #0273b9; + font-weight: normal; + text-decoration: none; + } + +#calendar table td a:hover{ + background: #0273b9; + color: #F7DFE6; + } + +/* Post +-------------------------------------------------------- */ +.post { + padding: 10px; + margin-bottom: 50px; + position: relative; + font-size: 1em; + overflow: visible; + } + +.post p { + padding: 0 0 5px 0; + text-align: justify; + } + +.read-it { + padding: 5px 0; + } + +.footnotes { + font-size:0.9em; + } + +.footnotes, .footnotes p { + margin-top : 1em; text-indent : 0; + } + +.post-content ul, .post-excerpt ul, .post-content ol, .post-excerpt ol { + padding: 0; + margin: 0 0 0 20px; + } + +.post-content ul li, .post-excerpt ul li, #attachments li { + padding: 0 0 5px 5px; + list-style-type: disc; + } + +.post-content ol li, .post-excerpt ol li { + padding: 0 0 5px 5px; + list-style-type: decimal; + } + +.day-date { + margin-top: -3px; + padding-bottom: 10px; + color: #B1B1B1; + } + +.post-title { + font-family: Georgia, serif; + font-size: 28px; + line-height: 28px; + margin: 0 0 20px 0; + text-align: left; + } + +.post-info { display: none; font-family: gerogia, serif; padding: 10px 0; } + +.post-tags { font-family: Georgia, Helvetica, "Trebuchet MS", serif; padding-bottom: 10px; } + +.post-tags a { padding: 2px 0 2px 18px; background: transparent url(img/tag.png) no-repeat 0 50%; } + +ul.post-tags li:after { content: ', '; } + +ul.post-tags li:last-child:after { content: ''; } + +.post-tags li { + display: inline; + /*white-space: nowrap;*/ + text-align: left; + } + +.post-info-co { + text-align: right; + padding: 20px 0; + } + +.post-info-co a:after { content: ' -'; } + +.post-info-co a:last-child:after { content: ''; } + +.post-info-co a { padding: 2px 0 2px 18px; } + +.comment_count { background: transparent url(img/commentaire.png) no-repeat 0 50%; } + +.ping_count { background: transparent url(img/retrolien.png) no-repeat 0 50%; } + +.attach_count { background: transparent url(img/attach.png) no-repeat 0 50%; } + +.read-it { + font-weight: bold; + padding-bottom: 10px; + clear: left; + } + +.pagination, #navlinks { + text-align: center; + font-weight: bold; + } +.pagination { padding-bottom: 10px; } + +#navlinks { padding-bottom: 20px; } + +#attachments { + clear: left; + padding: 0; + margin-bottom: 20px; + } + +#attachments ul { margin: 20px 0; padding: 10px; } + +#attachments li { list-style: none; } + +/* Comment +-------------------------------------------------------- */ +#comments, #pings { + margin: 20px 0; + font-size: 0.9em; + } + +#comments dt, #pings dt { + margin: 20px 0 0; + padding: 10px; + font-family:"century gothic", "gill sans", serif; + } + +#comments dd, #pings dd { + padding: 10px; + margin-bottom: 30px; + text-align: justify; + } + +#comments dd.me, #comments dt.me a { font-weight: bold; } + + +#comments dt .comment-number, #pings dt .comment-number { + font-size : 1.8em; + } + +#comments-feed { + font-weight: bold; + margin-top : 10px;; + } + +#comments-feed a:link, #comments-feed a:visited { + background: transparent url(img/rss.png) no-repeat 0px 50%; + padding: 3px 5px 2px 22px; + } + +#ping-url { + font-size: 0.85em; + text-align: left; + padding: 0; + } + +/* Comments forms +-------------------------------------------------------- */ +#pr p.buttons { margin: 0 0 20px 10px;} + +#pr dd { margin: 20px 0; padding: 10px; } + +#comment-form .hidecomment-form { + padding: 10px; + margin-bottom: 20px; + font-size: 0.9em; + } + +#comment-form h3 { margin-bottom: 20px;} + +#comment-form fieldset p { padding: 5px 0; } + +#comment-form fieldset p.field { padding: 7px 0; width: auto; margin: 0; } + +#comment-form p.form-help { + margin: 0; + text-align: justify; + } + +#comment-form p label { + width: auto; + } +#comment-form p.field label { + font-weight: bold; + display: block; + padding: 0 4px 4px 0; + } + +#comment-form input, #comment-form textarea { + padding: 1px 2px; + font: 1em Georgia, Helvetica, serif; + } + +#comment-form input { + width: 50%; + } + +#comment-form textarea { + width: 490px; + } + +#comment-form input#c_remember { + width: auto; + border: 0; + margin: 0 5px 0 0; + } + +#comment-form input.preview, #comment-form input.submit { + width: auto; + font-size: 1em; + font-weight: bold; + } + +/* Sidebar +-------------------------------------------------------- */ +#sidebar { + font-size: 0.85em; + overflow: visible; + } + +#sidebar h2 { + font-family: Georgia, Helvetica, "Trebuchet MS", serif; + font-size: 21px; + padding: 0 0 5px 0; + } + +#sidebar h3 { + font-size: 1em; + } + +#sidebar p { + margin: 5px 0; + } + +#sidebar .text { + margin: 5px 0; + overflow: visible; + } + +#sidebar ul { + margin: 10px 0; + padding: 10px; + } + +#sidebar ul li { + margin: 0; + font-size: 1em; + } + +#topnav { + text-align: center; + margin: 0; + padding: 5px 0; + } + +#sidebar #topnav ul { margin: 0; padding: 10px; } + +#sidebar #topnav li { + display: inline; + } + +#sidebar .tags ul { + font-size: 110%; + } + +#sidebar .tags ul li { + display: inline; + } + +.tag0 { font-size: 75%; } +.tag10 { font-size: 80%; } +.tag20 { font-size: 85%; } +.tag30 { font-size: 90%; } +.tag40 { font-size: 100%; } +.tag50 { font-size: 110%; } +.tag60 { font-size: 120%; } +.tag70 { font-size: 130%; } +.tag80 { font-size: 140%; } +.tag90 { font-size: 150%; } +.tag100 { font-size: 160%; } + +#sidebar .syndicate li { + margin: 0; + background: transparent url(img/rss.png) no-repeat 0px 50%; + padding: 5px 4px 5px 22px; + } + +/* Sidebar forms +-------------------------------------------------------- */ +#search input#q { + padding: 1px 1px 1px 18px; + margin: 0 5px 0 0; + width: 125px; + font-size: 0.9em; + background: #fff url(img/q.png) no-repeat 4px center; + } + +#search input[type=submit] { + padding: 0; + margin: 0; +} + +#search input.submit { + padding: 0; + margin: 0; +} + +#sidebar fieldset { + display : block; + border : none; + } + +#sidebar fieldset p { + margin-bottom : 1em; + } + +#sidebar input, #sidebar textarea, #sidebar select { + font-size: 0.9em; + margin: 5px 0; + padding: 1px; + line-height: 1.5em; + } + +#sidebar select, #sidebar input.text { + width: 175px; + } + +#sidebar input[type=text]#sidebar { + width: 175px; + } + +/* Page +-------------------------------------------------------- */ +#content-info { + font-size: 1.2em; + margin:0; + padding: 10px 0; + } + +#content-info h2, .content-inner h3 { + padding-bottom: 10px; + } + +.dc-archive-month .content-inner { + padding: 10px; + } +#subcategories { padding: 10px 0;} + +.dc-archive .content-inner ul { + padding: 10px; + margin-bottom: 30px; + } + +.dc-archive .content-inner ul li { + line-height: 2em; + } + +.dc-tags ul.tags { + margin: 0; + padding: 20px; + } + +.dc-tags ul.tags li { + display: inline; + font-size: 1.5em; + line-height: 1.8em; + } + +#content-info p { + padding: 10px 0; + font-size: 0.9em; + } + +#content-info p a.feed:link, #content-info p a.feed:visited { + padding: 3px 0 3px 22px; + background: transparent url(img/rss.png) no-repeat 1px 3px; + } + +.dc-category #content-info { + text-align: justify; + } \ No newline at end of file diff --git a/themes/altowithjquery/img/tag.png b/themes/altowithjquery/img/tag.png new file mode 100644 index 0000000000000000000000000000000000000000..fd62196df2ed117c83a26d056956e5daefe103d3 GIT binary patch literal 28051 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 z

      q;7W<{Et&+YV=%=PP3$Nsa`3$tC6oBDp0FJbrq=}sP46qbzy?u4c0jz{IXC7o{ zJ(Uh%cj2sF9rz=MPAM1}+Cxx&^z4+H-yiS36tCo0(mDl-E+|MHW4}>~SN~{HD|4Fs zO(2_j+k$4enKO7DYVN#_K3_+QjZ|eRzP^62lm|Jv^F{XL_O0q%Es_^sMP3U(JvEPR zcf34q_{x+utZeNq%r-o|+F{Oyp1xZ+k>~uI9P);AErr6+4w3hzq-}Pm$yq+&Crv|v z&Ci{0vhkjzQ#EvsOP~M7iw@ELy-SBU`NH0|M&WRxI15X=V_?y|Uo%PH{FAhqn2--ae^nSV?z|h#!n8-2-%EN zV*bY_O+W5G)*&LgTYo*5&*-u1NIFob<^L#*{+~BrN6@ol;ul5l$!mUKP<+byJSP9= z;{*V)*a0Nq7mxenSP9In z>{_t_scZA7leKOaaHRh%Fa6u({XB*h* zo6J<3K|YRUjgJ;?Y%yLQ zY?=t1T~+RELijh|0_*R^d(=}S^)~y3R;4?{!=;IaETs4k<_8I7cr}#I@x2|tO=Dmw z&lBiE12=9&cM#@Jw1Y_od3BF_sG!)O30g+`(jQEaX`OyodI|mBEl(FCE~2+goOHHW*Gly%kPMw9~c`)Q>y0rp#&KiGMi%;9kam($e=mT|X>Q zp$b|=ICtSY);n89vl#9HSHo8yP4!m!{)!}uNiI+Bw z%nSFBZ$araXGaI~>Bd7aFT|gXkO~5cmu>rMhZ7(+D8MLsoHuwNXx!TbN%$zS?+bSs zvH5tpkI*wpSgG9y$~5ef@E(+MrmwlU0p(J#;6y+WOj@QNqnpz?21`3*=fM(fP7M+` z+I8XqkV|xCO?6uoqIZ!Nj$YX%MMNy#Y3XgD^Tzijfg$^wYFR_+2n~D|6xEIQJ}^)M z7{~?{0C;ddmxo*R(@qmJ@z+{cVZdTb>02_GKj=qWk=NF#@3yl4N+Ao27QXxSy?^p2 z3xk79tfVy9#!%|=3%v!HwIS%VR;43~yqy}@jqSFvv6<9WC0xJq{W-`1);G=i*Nl z@ArG+mV#-a0r6*Ww6k$hP)NhE{`M7Ri{CrYe(E{opz&O2=f^Gqt~&@UAn16XAPS1q zm>D?_pJA#kUXL*id+V(x&h?VtBf#~~jst^Nn@wKuL2hx6A%L!iUxo*p{l==Uukeiz z?n?0ahSScjjd@&PO?F8e#Q+56(oZ8xl|sv{hKC028-9T+^Ec?a;TJtIqS@1s<*OVU zqD>5Vc&J)AU=#2!y1c#zr!!e~5bWrLhfCKbY+T*QVO(75qrLLqWGEfHx?vKUjqRts z!WwGgH^>7eD>w<}fgy3dLvWFf&VN7D&b;->p8MfUWx!m!(o6}Y3xX2~kiiUaD9c47iN@d`t*{n%>K3}}zP=g)^t#@?_^0Zt%5LdU7k{X!@k%j~jgamiYn zgIDxF0H8b4;^Nhgkp8~N=z!*zbNx>-VOGuly!c{lD=r&5MLXU5Y@%}FFdvAx-@MF^ zeLQ=<*>$R510@^=a81UMG$sI{ERGl-Nn)H-kiv5N!Ge6>pP$BPPS%U;kcI<)MP}Dc z1#mK!ymCY7fT(OXYb;Lh$xuiJ#`6p8_Ai!KLfk5g((SyQtZ7pdrNO-5 z8T@ikS;gr7Syn|b$n4D#}t8~NEyu1S;dhwYX{>s0K*u5OAzTOJ#}rz`Gba*-

      #*6}fL&U4{!>d;w#$>-xE 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 literal 0 HcmV?d00001 diff --git a/themes/altowithjquery/screenshot.jpg b/themes/altowithjquery/screenshot.jpg new file mode 100644 index 0000000000000000000000000000000000000000..dec670c5929ff93002cb0483cf607ce2fb3b4c8e GIT binary patch literal 8999 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 literal 0 HcmV?d00001 diff --git a/themes/altowithjquery/style.css b/themes/altowithjquery/style.css new file mode 100644 index 0000000..8d872a5 --- /dev/null +++ b/themes/altowithjquery/style.css @@ -0,0 +1,679 @@ +/* +alto with jQuery +-------------------------------------------------------- */ + +@import "custom.css"; + + +* { margin: 0; padding: 0; border: 0; } + +body { + background: #fff; + background: transparent url(img/background.gif) repeat-x top left;; + font-family: Georgia, serif; + font-size: 0.8em; + color: #333333; + line-height: 1.8em; + } + +/* Structure +-------------------------------------------------------- */ +#page { + width: 880px; + margin: 0 auto; + padding: 0; + position: relative; + background: transparent url(img/page.png) repeat-y top left; + } + +#top { + height: 153px; + background: transparent url(img/top.png) no-repeat top left; + margin: 0; + padding: 0; + z-index: 0; + } + +#banner { + display : block; + position : absolute; + background-color: transparent; + width: 780px; + height: 10px; + top : 41px ; + left : 50px ; + z-index: 1; + padding: 0; + } + + + +#top h1 { + position : absolute; + top: 50px; + left: 50px; + z-index: 2; + } + +#top h2 { + position : absolute; + top: 0px; + left: 50px; + z-index: 2; + } + + +#prelude { + display: none; + position: absolute; + top: 45px; + right: 120px; + padding: 0 10px; + font-size: 0.8em; + } + +#prelude a { color: #ddd;} + +#wrapper { + width: 780px; + margin: 0 50px; + } + +#main { + text-align: justify; + float: left; + width: 530px; + overflow: visible; + } + +#content { + margin-left: 30px; + overflow: visible; + } + +#sidebar { + float: right; + width: 230px; + margin-bottom: 30px; + } + +#blognav, #blogextra { + margin-right: 0px; + margin-left:40px; + } + +#footer { + height: 120px; + background: #fff url(img/footer.png) repeat-y top left; + } + +#footer p { + padding: 20px 100px 10px 100px; + font-size: 0.8em; + text-align: center; + } + +/* Styles communs +-------------------------------------------------------- */ +h1, h2, h3, h4, h5, .post-title { + font-family: Georgia, serif; + line-height: 24px; + letter-spacing: -1px; + font-style: normal; + font-weight: 500; +} + +h1{font-size: 46px;} +h2{font-size: 34px;} +h3{font-size: 20px;} +h4{font-size: 11px;} +h5{font-size: 1.1em;} +h6{font-size: 1em;} + +li { list-style: none; } + +blockquote { + text-align:left; + margin: 6px 20px 6px 20px; +} + +html>body blockquote { + padding-left:10px; + } + +acronym { cursor: help; text-decoration: underline; } + +pre { + text-align:left; + overflow: scroll; + width: 475px; + border-left : 3px solid #008ACF; + font-family : Georgia, serif; + color : #0273b9; + font-size : 12px; + margin : 10px; + line-height :14px; +} + +html>body pre { + width: auto; + } + +code { + font-family : Georgia, serif; + color : #0273b9; + font-size : 12px; + margin : 0px; + text-align : left; + padding : 1px 5px 1px 5px; + line-height :14px; +} + +input { text-transform: lowercase; } + +.left { float: left; } + +.right { float: right; } + +img { + border : none; + } + +.error { + border: 1px dashed #fff; + padding: 5px 0; + margin: 20px 0 0 0; + color: #fff; + background: #E2001A; + } + +.message { + padding: 10px 0; + margin: 0; + } + +.post, .post-content, .footnotes, .postend, .attachments, .post-info-co, #comments, #footer, .pagination, #navlinks { + clear: both; + } + +/* Couleurs +--------------------------*/ + +body { color: #000; } + +h1, h2, h3, h4, h5, .post-title, .day-date { color: #333333; } + +a { + color: #0273B9; + text-decoration : none; + } +#top a:link { + color: #fff; +} +#top a:visited { + color: #fff; +} +#top a:hover { + color: #fff; +} +a:visited { + color: #0273B9; + text-decoration : none; + } + +a:hover { + color: #0273B9; + text-decoration : none; + } + + +input, textarea, select { border: 1px solid #999; background: #fff; color: #333333; } + +#comment-form textarea {border: 1px solid #999;} + +blockquote, pre { border-left : 3px solid #008ACF; } + +code { color : #0273b9; } + +.post, #comment-form .hidecomment-form, .content-inner ul, .dc-archive-month .content-inner { background: #ffffff; } + +.pagination, #navlinks { color: #333; } + +/* Choix des couleurs pour les éléments arrondis */ +#sidebar .tags ul, #sidebar .selected ul, #sidebar .feed ul, .dc-tags ul.tags, #sidebar .pages ul { background: #ececec; } + +#sidebar .links ul, #sidebar .langs ul, #sidebar #authors ul { background: #ececec; } + +#sidebar .syndicate ul, #sidebar .syndicate a/* le fond des liens RSS est blanc sinon */, #sidebar .lastposts ul, #attachments ul, #sidebar #related ul { background: #ececec; } + +#sidebar .categories ul, #sidebar .lastcomments ul, #sidebar #galleries ul { background: #ececec; } + +/* Pour Safari, ajouter les divisions contenant les élements arrondis */ +#topnav, #sidebar .tags, #sidebar .selected, #sidebar .feed, div.content-inner, #sidebar .links, #sidebar .langs, #sidebar #authors, #sidebar .syndicate, #sidebar .lastposts, #attachments, dl, #sidebar .categories, #sidebar .lastcomments, #sidebar #galleries, #comment-form, #sidebar .pages {background: #ececec;} + +input:hover { + color: #0273B9; + } + +dd, dt { + background: #F7DFE6; + } + +#comment-form p.form-help { color: #999999; } + +#calendar table{ + font-size: 9px; + text-align: center; + margin: 0 auto; + border-collapse: collapse; + } + +#calendar table caption{ + margin: 0 auto; + } + +#calendar table th{ + color: #333333; + background: transparent; + } + +#calendar table td{ + width: 14%; + line-height: 2em; + border: 0.1em solid #EEE; + } + +#calendar table td a{ + display: block; + background: #F7DFE6; + color: #0273b9; + font-weight: normal; + text-decoration: none; + } + +#calendar table td a:hover{ + background: #0273b9; + color: #F7DFE6; + } + +/* Post +-------------------------------------------------------- */ +.post { + padding: 10px; + margin-bottom: 50px; + position: relative; + font-size: 1em; + overflow: visible; + } + +.post p { + padding: 0 0 5px 0; + text-align: justify; + } + +.read-it { + padding: 5px 0; + } + +.footnotes { + font-size:0.9em; + } + +.footnotes, .footnotes p { + margin-top : 1em; text-indent : 0; + } + +.post-content ul, .post-excerpt ul, .post-content ol, .post-excerpt ol { + padding: 0; + margin: 0 0 0 20px; + } + +.post-content ul li, .post-excerpt ul li, #attachments li { + padding: 0 0 5px 5px; + list-style-type: disc; + } + +.post-content ol li, .post-excerpt ol li { + padding: 0 0 5px 5px; + list-style-type: decimal; + } + +.day-date { + margin-top: -3px; + padding-bottom: 10px; + color: #B1B1B1; + } + +.post-title { + font-family: Georgia, serif; + font-size: 28px; + line-height: 28px; + margin: 0 0 20px 0; + text-align: left; + } + +.post-info { display: none; font-family: gerogia, serif; padding: 10px 0; } + +.post-tags { font-family: Georgia, Helvetica, "Trebuchet MS", serif; padding-bottom: 10px; } + +.post-tags a { padding: 2px 0 2px 18px; background: transparent url(img/tag.png) no-repeat 0 50%; } + +ul.post-tags li:after { content: ', '; } + +ul.post-tags li:last-child:after { content: ''; } + +.post-tags li { + display: inline; + /*white-space: nowrap;*/ + text-align: left; + } + +.post-info-co { + text-align: right; + padding: 20px 0; + } + +.post-info-co a:after { content: ' -'; } + +.post-info-co a:last-child:after { content: ''; } + +.post-info-co a { padding: 2px 0 2px 18px; } + +.comment_count { background: transparent url(img/commentaire.png) no-repeat 0 50%; } + +.ping_count { background: transparent url(img/retrolien.png) no-repeat 0 50%; } + +.attach_count { background: transparent url(img/attach.png) no-repeat 0 50%; } + +.read-it { + font-weight: bold; + padding-bottom: 10px; + clear: left; + } + +.pagination, #navlinks { + text-align: center; + font-weight: bold; + } +.pagination { padding-bottom: 10px; } + +#navlinks { padding-bottom: 20px; } + +#attachments { + clear: left; + padding: 0; + margin-bottom: 20px; + } + +#attachments ul { margin: 20px 0; padding: 10px; } + +#attachments li { list-style: none; } + +/* Comment +-------------------------------------------------------- */ +#comments, #pings { + margin: 20px 0; + font-size: 0.9em; + } + +#comments dt, #pings dt { + margin: 20px 0 0; + padding: 10px; + font-family:"century gothic", "gill sans", serif; + } + +#comments dd, #pings dd { + padding: 10px; + margin-bottom: 30px; + text-align: justify; + } + +#comments dd.me, #comments dt.me a { font-weight: bold; } + + +#comments dt .comment-number, #pings dt .comment-number { + font-size : 1.8em; + } + +#comments-feed { + font-weight: bold; + margin-top : 10px;; + } + +#comments-feed a:link, #comments-feed a:visited { + background: transparent url(img/rss.png) no-repeat 0px 50%; + padding: 3px 5px 2px 22px; + } + +#ping-url { + font-size: 0.85em; + text-align: left; + padding: 0; + } + +/* Comments forms +-------------------------------------------------------- */ +#pr p.buttons { margin: 0 0 20px 10px;} + +#pr dd { margin: 20px 0; padding: 10px; } + +#comment-form .hidecomment-form { + padding: 10px; + margin-bottom: 20px; + font-size: 0.9em; + } + +#comment-form h3 { margin-bottom: 20px;} + +#comment-form fieldset p { padding: 5px 0; } + +#comment-form fieldset p.field { padding: 7px 0; width: auto; margin: 0; } + +#comment-form p.form-help { + margin: 0; + text-align: justify; + } + +#comment-form p label { + width: auto; + } +#comment-form p.field label { + font-weight: bold; + display: block; + padding: 0 4px 4px 0; + } + +#comment-form input, #comment-form textarea { + padding: 1px 2px; + font: 1em Georgia, Helvetica, serif; + } + +#comment-form input { + width: 50%; + } + +#comment-form textarea { + width: 490px; + } + +#comment-form input#c_remember { + width: auto; + border: 0; + margin: 0 5px 0 0; + } + +#comment-form input.preview, #comment-form input.submit { + width: auto; + font-size: 1em; + font-weight: bold; + } + +/* Sidebar +-------------------------------------------------------- */ +#sidebar { + font-size: 0.85em; + overflow: visible; + } + +#sidebar h2 { + font-family: Georgia, Helvetica, "Trebuchet MS", serif; + font-size: 21px; + text-decoration:none; + padding: 10px 0 5px 0; + } + +#sidebar h3 { + font-size: 1em; + } + +#sidebar p { + margin: 5px 0; + } + +#sidebar .text { + margin: 5px 0; + overflow: visible; + } + +#sidebar ul { + margin: 10px 0; + padding: 10px; + } + +#sidebar ul li { + margin: 0; + font-size: 1em; + } + +#topnav { + text-align: center; + margin: 0; + padding: 5px 0; + } + +#sidebar #topnav ul { margin: 0; padding: 10px; } + +#sidebar #topnav li { + display: inline; + } + +#sidebar .tags ul { + font-size: 110%; + } + +#sidebar .tags ul li { + display: inline; + } + +.tag0 { font-size: 75%; } +.tag10 { font-size: 80%; } +.tag20 { font-size: 85%; } +.tag30 { font-size: 90%; } +.tag40 { font-size: 100%; } +.tag50 { font-size: 110%; } +.tag60 { font-size: 120%; } +.tag70 { font-size: 130%; } +.tag80 { font-size: 140%; } +.tag90 { font-size: 150%; } +.tag100 { font-size: 160%; } + +#sidebar .syndicate li { + margin: 0; + background: transparent url(img/rss.png) no-repeat 0px 50%; + padding: 5px 4px 5px 22px; + } + +/* Sidebar forms +-------------------------------------------------------- */ +#search input#q { + padding: 1px 1px 1px 18px; + margin: 0 5px 0 0; + width: 125px; + font-size: 0.9em; + background: #fff url(img/q.png) no-repeat 4px center; + } + +#search input[type=submit] { + padding: 0; + margin: 0; +} + +#search input.submit { + padding: 0; + margin: 0; +} + +#sidebar fieldset { + display : block; + border : none; + } + +#sidebar fieldset p { + margin-bottom : 1em; + } + +#sidebar input, #sidebar textarea, #sidebar select { + font-size: 0.9em; + margin: 5px 0; + padding: 1px; + line-height: 1.5em; + } + +#sidebar select, #sidebar input.text { + width: 175px; + } + +#sidebar input[type=text]#sidebar { + width: 175px; + } + +/* Page +-------------------------------------------------------- */ +#content-info { + font-size: 1.2em; + margin:0; + padding: 10px 0; + } + +#content-info h2, .content-inner h3 { + padding-bottom: 10px; + } + +.dc-archive-month .content-inner { + padding: 10px; + } +#subcategories { padding: 10px 0;} + +.dc-archive .content-inner ul { + padding: 10px; + margin-bottom: 30px; + } + +.dc-archive .content-inner ul li { + line-height: 2em; + } + +.dc-tags ul.tags { + margin: 0; + padding: 20px; + } + +.dc-tags ul.tags li { + display: inline; + font-size: 1.5em; + line-height: 1.8em; + } + +#content-info p { + padding: 10px 0; + font-size: 0.9em; + } + +#content-info p a.feed:link, #content-info p a.feed:visited { + padding: 3px 0 3px 22px; + background: transparent url(img/rss.png) no-repeat 1px 3px; + } + +.dc-category #content-info { + text-align: justify; + } \ No newline at end of file diff --git a/themes/altowithjquery/tpl/_footer.html b/themes/altowithjquery/tpl/_footer.html new file mode 100644 index 0000000..6edc9e8 --- /dev/null +++ b/themes/altowithjquery/tpl/_footer.html @@ -0,0 +1,5 @@ +

      + +{{tpl:SysBehavior behavior="publicFooterContent"}} \ No newline at end of file diff --git a/themes/altowithjquery/tpl/_head.html b/themes/altowithjquery/tpl/_head.html new file mode 100644 index 0000000..dbfbf2e --- /dev/null +++ b/themes/altowithjquery/tpl/_head.html @@ -0,0 +1,16 @@ + + + + + + + + + +{{tpl:include src="user_head.html"}} +{{tpl:SysBehavior behavior="publicHeadContent"}} + diff --git a/themes/altowithjquery/tpl/_top.html b/themes/altowithjquery/tpl/_top.html new file mode 100644 index 0000000..795a4af --- /dev/null +++ b/themes/altowithjquery/tpl/_top.html @@ -0,0 +1,7 @@ + + +

      {{tpl:lang To content}} | +{{tpl:lang To menu}} | +{{tpl:lang To search}}

      \ No newline at end of file diff --git a/themes/altowithjquery/tpl/archive_day.html b/themes/altowithjquery/tpl/archive_day.html new file mode 100644 index 0000000..d39b170 --- /dev/null +++ b/themes/altowithjquery/tpl/archive_day.html @@ -0,0 +1,123 @@ + + + + + + + + {{tpl:lang Archives}} - {{tpl:ArchiveDate}} - {{tpl:BlogName encode_html="1"}} + + + + + + + + + + + + + + + + + + + + + + + + + {{tpl:include src="_head.html"}} + + + + +
      +{{tpl:include src="_top.html"}} + +
      + +
      +
      + + + +
      +

      {{tpl:ArchiveDate}}

      +
      + + +
      +

      {{tpl:EntryTitle encode_html="1"}}

      + + + + + + + {{tpl:SysBehavior behavior="publicEntryBeforeContent"}} + + + +
      {{tpl:EntryExcerpt}}
      +

      {{tpl:lang Continue + reading}}...

      +
      + + + +
      {{tpl:EntryContent}}
      +
      + + + + + + + {{tpl:SysBehavior behavior="publicEntryAfterContent"}} + +
      + +
      +
      +
      + + + +
      + +{{tpl:include src="_footer.html"}} +
      + + \ No newline at end of file diff --git a/themes/altowithjquery/tpl/post.html b/themes/altowithjquery/tpl/post.html new file mode 100644 index 0000000..e5ef333 --- /dev/null +++ b/themes/altowithjquery/tpl/post.html @@ -0,0 +1,297 @@ + + + + + + + + {{tpl:EntryTitle encode_html="1"}} - {{tpl:BlogName encode_html="1"}} + + + + + + + + + + + + + + + + + + + + + + + + + + {{tpl:include src="_head.html"}} + + + + + +
      +{{tpl:EntryPingData}} + +{{tpl:include src="_top.html"}} + +
      + +
      +
      + + + +
      +

      {{tpl:EntryTitle encode_html="1"}}

      + + + + + + {{tpl:SysBehavior behavior="publicEntryBeforeContent"}} + + + +
      {{tpl:EntryExcerpt}}
      +
      + +
      {{tpl:EntryContent}}
      + + + + + + + {{tpl:SysBehavior behavior="publicEntryAfterContent"}} + +
       
      +
      + + + + +
      +

      {{tpl:lang Attachments}}

      +
        + +
      • + + {{tpl:include src="_mp3_player.html"/}} - + + + {{tpl:include src="_flv_player.html"/}} + + + {{tpl:AttachmentTitle}} + +
      • + +
      +
      + +
      + + + + + +
      +

      {{tpl:lang Comments}}

      +
      + +
      {{tpl:CommentOrderNumber}}. + {{tpl:lang On}} {{tpl:CommentDate}}, {{tpl:CommentTime}} + {{tpl:lang by}} {{tpl:CommentAuthorLink}}
      + +
      + + {{tpl:SysBehavior behavior="publicCommentBeforeContent"}} + + {{tpl:CommentContent}} + + + {{tpl:SysBehavior behavior="publicCommentAfterContent"}} +
      + +
      +
      + +
      +
      + + + +

      {{tpl:SysFormError}}

      +
      + + +

      {{tpl:lang Your comment has been published.}}

      +
      + + +

      {{tpl:lang Your comment has been submitted and + will be reviewed for publication.}}

      +
      + + + + +
      + +
      +

      {{tpl:lang Your comment}}

      +
      +
      {{tpl:CommentPreviewContent}}
      +
      +

      +
      +
      + +

      {{tpl:lang Add a comment}}

      +
      +
      + + {{tpl:SysBehavior behavior="publicCommentFormBeforeContent"}} + +

      + +

      + +

      + +

      + +

      + +

      + +

      + +

      + +

      +

      {{tpl:lang HTML code is displayed as text and web addresses are + automatically converted.}}

      + + + {{tpl:SysBehavior behavior="publicCommentFormAfterContent"}} +
      + +
      +

      +

      +
      +
      +
      +
      + + + +
      +

      {{tpl:lang They posted on the same topic}}

      + + +
      + +
      {{tpl:PingOrderNumber}}. + {{tpl:lang On}} {{tpl:PingDate}}, {{tpl:PingTime}} + {{tpl:lang by}} {{tpl:PingBlogName encode_html="1"}}
      + +
      + + {{tpl:SysBehavior behavior="publicPingBeforeContent"}} + +

      {{tpl:PingTitle encode_html="1"}}

      + {{tpl:PingContent}} + + + {{tpl:SysBehavior behavior="publicPingAfterContent"}} +
      + +
      + +
      +
      +
      + + +

      {{tpl:lang Trackback URL}} : {{tpl:EntryPingLink}}

      +
      + + +

      {{tpl:lang This post's comments feed}}

      +
      +
      +
      + + + +
      + +{{tpl:include src="_footer.html"}} +
      + + \ No newline at end of file diff --git a/themes/customCSS/_config.php b/themes/customCSS/_config.php new file mode 100644 index 0000000..792b6b4 --- /dev/null +++ b/themes/customCSS/_config.php @@ -0,0 +1,41 @@ +blog->public_path).'/custom_style.css'; + +if (!is_file($css_file) && !is_writable(dirname($css_file))) { + throw new Exception( + sprintf(__('File %s does not exist and directory %s is not writable.'), + $css_file,dirname($css_file)) + ); +} + +if (isset($_POST['css'])) +{ + @$fp = fopen($css_file,'wb'); + fwrite($fp,$_POST['css']); + fclose($fp); + + echo + '

      '. + __('Style sheet upgraded.'). + '

      '; +} + +$css_content = is_file($css_file) ? file_get_contents($css_file) : ''; + +echo +'

      '; +?> \ No newline at end of file diff --git a/themes/customCSS/_define.php b/themes/customCSS/_define.php new file mode 100644 index 0000000..41dec13 --- /dev/null +++ b/themes/customCSS/_define.php @@ -0,0 +1,20 @@ +registerModule( + /* Name */ "Custom theme", + /* Description*/ "A CSS customizable theme", + /* Author */ "Olivier", + /* Version */ '1.0' +); +?> \ No newline at end of file diff --git a/themes/customCSS/_public.php b/themes/customCSS/_public.php new file mode 100644 index 0000000..8515a07 --- /dev/null +++ b/themes/customCSS/_public.php @@ -0,0 +1,26 @@ +addBehavior('publicHeadContent',array('tplCustomTheme','publicHeadContent')); + +class tplCustomTheme +{ + public static function publicHeadContent(&$core) + { + echo + '\n"; + } +} +?> \ No newline at end of file diff --git a/themes/customCSS/locales/fr/main.lang.php b/themes/customCSS/locales/fr/main.lang.php new file mode 100644 index 0000000..f532e5c --- /dev/null +++ b/themes/customCSS/locales/fr/main.lang.php @@ -0,0 +1,22 @@ + \ No newline at end of file diff --git a/themes/customCSS/locales/fr/main.po b/themes/customCSS/locales/fr/main.po new file mode 100644 index 0000000..b84aa35 --- /dev/null +++ b/themes/customCSS/locales/fr/main.po @@ -0,0 +1,20 @@ +# French translation of DotClear +# Copyright (C) 2006. +# Olivier Meunier , 2006. +# + +msgid "" +msgstr "Content-Type: text/plain; charset=UTF-8\n" + +#: themes/custom/_config.php:27 +#, php-format +msgid "File %s does not exist and directory %s is not writable." +msgstr "Le fichier %s n'existe pas et le répertoire %s n'est pas accessible en écriture." + +#: themes/custom/_config.php:40 +msgid "Style sheet upgraded." +msgstr "Feuille de style mise à jour." + +#: themes/custom/_config.php:47 +msgid "Style sheet:" +msgstr "Feuille de style :" diff --git a/themes/customCSS/style.css b/themes/customCSS/style.css new file mode 100644 index 0000000..e69de29 diff --git a/themes/default/_define.php b/themes/default/_define.php new file mode 100644 index 0000000..ab48c68 --- /dev/null +++ b/themes/default/_define.php @@ -0,0 +1,20 @@ +registerModule( + /* Name */ "Blowup", + /* Description*/ "Fully customizable theme", + /* Author */ "Marco & Olivier", + /* Version */ '1.0' +); +?> \ No newline at end of file diff --git a/themes/default/img/attach.png b/themes/default/img/attach.png new file mode 100644 index 0000000000000000000000000000000000000000..fd7842aae114e111df27a8e1ad8a47fcd7bdcd73 GIT binary patch literal 1329 zcmcIkO-vI(6kdgdQXxi7h%p`}>q%le`%@_0v?b7jt)U2X6N`kT%kFI1wEN@ikd_`u zYV_dMpM>5a-sHwzLn#8DHk8k}uQ3&!Y)$?W{RyzhH&zIi*(7Uu5``)~Le zh8a$$l1p?R^1l8)I_|7YeWX*LJDrw&KHulV`(NpnTbPq)j*pLzj*bov4w}toqtV#k z-{0HY+uhx**Xz}46=SUH`s(WH;^JaDofbuLbnbAOVh5envdb`+u6o~v4_~%^GEDy! zGLs{@%$%g!W>C@WH59Cv4ilZMIEq?C1gxQgVZ~Sg01FH)#y%L!a2Y3o){RsZqil6v zR;xudqOp^4f3zY|u!)EQDrU)YrAmx#aY}UUnIQ{WE~FS^r@UYwmstP_8zT@3@&T0- zLm)IB6v9FzJbnjc6$0)l77)Tf;5a%663d02F2&o&pEWQl+qme0L{^M?$TLp8 zs69MNDg?znJp#0goJ=L*Led!j@D#r7^ang+Ylgmg7S79DMB>M(s2%tzrw%*{Jt0mB z(^B0#(;xQ#38txCy_^kPYF&$_LR3N~vWQDHRv`*|#((D5 z&YG45Elb#~%ahc*S9varp6=&D-zGiJAQSJO{Gu<$P498Y+BzvK7%_jT*zHfV-di=| z`L&AM`)y>yM2yHmE=>E2!%Ure@ag1~>|0Uu`FuV0v{tLVYQDXkdh|p1Uc0^Z?qz)Y md2Y0CXJUkh14~2o*B7rd-$Db|1{-mif|>NpeDck7{_$`07h_2P literal 0 HcmV?d00001 diff --git a/themes/default/img/body-bg.png b/themes/default/img/body-bg.png new file mode 100644 index 0000000000000000000000000000000000000000..469e6584167abf33346145520463f73d4b2f60fa GIT binary patch literal 211 zcmeAS@N?(olHy`uVBq!ia0vp^MnJrUg9%7RZh4^$q-J@#IEGZ*dVA#{CxZhAv!ndC z`zuYKWbK&$AmU&`LUmf!{nE8II{3kw`Y@sUhYlUOq^q2i$k`&eal?iUA@@2WA|iIR zwzjGY02yG`(rC9MD5^@hxw*X+fT}luSjgbD!E45E6*`3zbyDPku4M3Z^>bP0l+XkK Dk7Y$W literal 0 HcmV?d00001 diff --git a/themes/default/img/comment-b.png b/themes/default/img/comment-b.png new file mode 100644 index 0000000000000000000000000000000000000000..c65a0f045ecd65ada383fd5a5663b40d51cd9ec5 GIT binary patch literal 175 zcmV;g08sylP)000LF0ssI2am6U!0001XNklo^6NjshGK=8agTtt$Vm&X(JU)+KF^nXT@mesh=f6-rY2WC-&>{ecqmT7u+ dYB1}a^Dhp@De<09000>X0ssI2NEu5t0004PNklNEQ zBWKpVN^BB`E(kfDaYT8E0P79#5aX)SP_A=;~W#2g`fY!!+ev4`M!=`^U zj}8f-sd1mjNSj}0-LeBTHtzEnX?<(fQy=-&@c=Y3?(^H7r}fi4``~Nf&(`}Z)H3z>t10jPf5=kc$zp87~@rvgy@xIeb+9@_!xANNO>J@sze z0qP$2Czd^J90@?h<6e%BFS|D&0csxik{@_C#<&BtG4A>GnPoTb0QHXha~Cq7f4&63 zKaYFKk@qnTU%sU-NvgM1Ohe@Tw^t3X#(f@bx+FEc@>gHdJ&*g1FRDwDTIu}Xjk<`4 zeDI4%(n89Ii0GnZw=t5msQa0cJCE&>w7iG+E~dc`AxX=+c^^8zf+Q`kcY@li?+$C# Q;{X5v07*qoM6N<$g5pcazyJUM literal 0 HcmV?d00001 diff --git a/themes/default/img/comment.png b/themes/default/img/comment.png new file mode 100644 index 0000000000000000000000000000000000000000..b7f65efc1e351ce0db7730cd6d1ba0fbb7f1acfe GIT binary patch literal 1415 zcmcIkTSyd97@pK%vos2nh=Ri;^wREJcGY&;3%aYh;hO1yrZ0}O$8}ie!pzvNOY{(u zC_)b+6$Xig5JF%e_+U@^q9CFVK`lwLAPAzO4~ulMGrQ}qO4O5wGw1U2fB*NN@BDN6 z>+9|ou2$(|O(s)p?f!SPZK|(js}2qh_V@P_ ziNxOC-tO-1&d$#E_V(7+*5>Bs#>U3_`g%MbkHun3OH1?f^Ru(FGcz;O)6-K^QCqMd`E;qU=ivZh=^U1#zdTWGA4u8hMB-Y(nSwB@d|?sH2dp;M^+)QStv74 zT5Z5qW}(YzdwJO{(8%fF9w!019MB|*2AZKL#zvuJk_~s|quHSbI+zA;b($0HoOq|M zD-1z|!(mIY4MPZM1)fa%0d#E$Oz~_M#iH;PM1|ymb+Z3<5vqR49jXr1D-~! z!$2N$%Ccth(97x2W$0l>-Ab}Z64J($QY}aDDW?-~zZ?)cdXB>>mb5ce84@)OKjM^z zI|xIFBf=zAH_mjz{y)J2d`2&&TkT3-OMoX}7ZjnSYe+NdxMl&K>5x^C(_Mnd1tFnG zK?jjF{xiQ+)~GB{SrVDLJWM@vm8Y`E>V7KWQ$bIY9KcFZv35$qU})i_=!>ncbFf z-=uQ-zcw#@Txff-H_zt0kNe!7PiwEOc!OGOv#$P#y?aCFO;HQcMfT2e9B=ZGa?zvb pMRSP>*()U#UltG-=BujneyD7F`UiS4q(cAz literal 0 HcmV?d00001 diff --git a/themes/default/img/commentmy-b.png b/themes/default/img/commentmy-b.png new file mode 100644 index 0000000000000000000000000000000000000000..531a650e0b1ef75052991a8f6fc3173ae3d9a0cd GIT binary patch literal 186 zcmV;r07d_aP)000LF0ssI2am6U!0001iNkl000>X0ssI2NEu5t0004jNklfN)8d>kU3aM4&ttva zSDStP)^*1-0AL11YQNCw)HdzcvDuZ?x~x`%(f9bd(*l6Z;(l#wjp92b0LUrs5$>3z|CM!R2Y}4te#v^ZnaFxrH6M-#0P=`?3}L2k>w|~- z-Pr&@262y%Oye^CFzdZ*yD?8&Wr^D?Z(zzSFEbArC?IPE zj5cU%L1?t7EsG$wQa3;l6a=gaE@_Px+8U{CLlwl7RKLCf1T{_j%bR=8z4zpN=bZc9 z^X|)!2!DU3gOdXxWM)XPERvsR+lKu#UcTkxDCehX7XJ{1y}kX-zSX^iOkETast5$% zMusu+5FkfJb5_qWN-jO_b}A|3r_GF9gef8+k(0e@oggN^f+clZ2`V9<7*X;YH`Gb zS~ZTUP-8+(465T$nTgsk)I{S*3=XrXjz*OU)lsP4fSM>AUW>!)P!o&_7L^86MWI}e zsqYUJ~dD;t8|_DuRs!>j|O>6aM%gKsic?@4UGuYr53n8z*ZW~j&Z>9fD$n-f}U^EvU7AjSn46aIzNyWHY4J`5Y zv$9Hc0>e=%CQfJc5l|E*pmZ7^L6k?BFpLdg;&s6(W=5V8u282Ws3jVKpRa?rRmy`6 z45y^52EEZDwfYD~eMre7Nx4O{m~05xPq~M6u7{$BbTphnX}wZSwPQkwPeu ziadEz$KlTyjl;cZ8xhYCGs?Q{OfTsFk1&mTf-g4FtRKA=jhbfkjDaz77M?TF^PFka zQmx5sP;$OHgEEexS!0|xJ*oW9{Km58%YrXUdZI3$rap0%FJ&>w`%7^@=JaI-d9O9+ zG5=yX+a3qGNy{ZE%?$aMiY>YxWcxMEwb_jpx9zi0=nM>T6VgI2zVGe}D<))$V~A{p zV*ZBdx%&~A2_?*4GDV@A&1N!cVF`Kj-gT#8nT4*5yA?Tpy0TQ%`%{UoXthE9=>Pdc$I8 zW5tCdK{@?b98=qxgGEakt!T9#zMo#8H9+!jn z>!;4v(Q;^HQcN+3Dd;@-tu_By$#XKFlHgfU1 eb7wj(+~p2_x~6#ViF*Y=B@CXfelF{r5}E*-PDC64 literal 0 HcmV?d00001 diff --git a/themes/default/img/page-bg.png b/themes/default/img/page-bg.png new file mode 100644 index 0000000000000000000000000000000000000000..60331251519e470a7222fb2de9370e6fd4976e78 GIT binary patch literal 1263 zcmcIkzi-n(6uuIK+Mo^~fdpbW%mNbj*-qME%SqKHElt&wsIf$wsaN}wn#4ZKzBXIFJNFnNOWOiV+57EBu&~1!PL|Fems5Od+)w`zNgityW{Dr zX#l`@dA_s^Knn78dL+fiE&T2~pHlHm*&ZDo{jz`W8{eL*F50sP2M2q5d%MLggImVJ z`PCSJ^B2W8^6BftUjUrFz-Cw2N@dY>sIOp`t`jBkLtsrMA$D4X!FAH~g1iJFl%VJ4 zrTY^VwGtM|hBv(tNfe zw_z@q=K3-DE-!5`7McikIvu5xQE1denqe47)se2t93jWs0mF$L#5a0Q4*ir!>_lG3 zJQ_gZ7q8PzmX{ovBI(=}T)Ol^{j z+NU1@_30K8LL3pMtGYPT3H$#9bDe=+;bzqCUW@A>(k4C$Sj;ukj%(&RW`jmPW(Cj3 zO@hLpX`!LD9^IX%rFcRoJ;&0mab;&G_a2J7I6 zfWK7itIu=d1-dM7-QpI%jqUjaWK^W)cz>~9dCd`5%B5-h=5uH5&6%~gPpQ_ literal 0 HcmV?d00001 diff --git a/themes/default/img/page-t.png b/themes/default/img/page-t.png new file mode 100644 index 0000000000000000000000000000000000000000..bb44f4ee6c2984a9f92f9dae23fa87768565b74b GIT binary patch literal 25574 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

      CZ&;8HLZEYjSy><>N7J& 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 T+o{<=?=g6~`njxgN@xNA!1#|) literal 0 HcmV?d00001 diff --git a/themes/default/img/trackback.png b/themes/default/img/trackback.png new file mode 100644 index 0000000000000000000000000000000000000000..e5f6191d814ada5450725e492bfc89070e762867 GIT binary patch literal 1269 zcmcIkzi-n(6m~_0LTCpV0P#bd%)&r?wv#r*IH}sCB|%Mz8cP%=F7_q068kLss<<5h zA*2e40jUdYOpJ`o42X$|fdwH^2_*gqPUy?L=iZ8D5wd%5AGfyE7YfvTj0?C|<17f!+M-AF?{k)72l9B7=`_io>~;Lei1TvarvYnW#xm+dcsno8i(qK2 zT0=z^Qj}4&l&z*SC^M_*Sv{AXy@u+9qg%vBdKT%b3WIKFnvu~UnSPTCNtn&hX&S4g zrD06i<>htG0|Vo3x2ts13JY6U%jI%d)v>Op0FjC|eNN((A6*$Z+4EDPksZ1LcbSib zU(#S3JTJ>4(5MX$M}koxKN^Y$GUAv7SW{Fy@(e^1j7Bk}gtO3MtWy{qf5{DLmxb*J z73*nJFb{ynQOA5*BAgb49x3Q))dES>j4`9#+s7Y(4$-U3ahsb5>6)eH3~d%f9n$xK zhIA7PA@&K=S6!Uxko|vxIrd1eU?c4Guf?%3?NE>UJOa(MgPJ+E(PW`Vc)|5Zi{ij< znRsmcXMTgMp)8;*@u)8MQXgIAku1i#ABp>c)1wS>{r!{Q@M2sPk3*d`d6$G#`b)*W z_`D=upfdv3FK+SMSguE+Iai#QT;r`=4i|Rv` literal 0 HcmV?d00001 diff --git a/themes/default/js/jquery.cookie.js b/themes/default/js/jquery.cookie.js new file mode 100644 index 0000000..9b48982 --- /dev/null +++ b/themes/default/js/jquery.cookie.js @@ -0,0 +1,6 @@ + +jQuery.cookie=function(name,value,options){if(typeof value!='undefined'){options=options||{};if(value===null){value='';options.expires=-1;} +var expires='';if(options.expires&&(typeof options.expires=='number'||options.expires.toUTCString)){var date;if(typeof options.expires=='number'){date=new Date();date.setTime(date.getTime()+(options.expires*24*60*60*1000));}else{date=options.expires;} +expires='; expires='+date.toUTCString();} +var path=options.path?'; path='+(options.path):'';var domain=options.domain?'; domain='+(options.domain):'';var secure=options.secure?'; secure':'';document.cookie=[name,'=',encodeURIComponent(value),expires,path,domain,secure].join('');}else{var cookieValue=null;if(document.cookie&&document.cookie!=''){var cookies=document.cookie.split(';');for(var i=0;i)[^>]*$|^#([\w-]+)$/,isSimple=/^.[^:#\[\.,]*$/;jQuery.fn=jQuery.prototype={init:function(selector,context){selector=selector||document;if(selector.nodeType){this[0]=selector;this.length=1;this.context=selector;return this;} +if(typeof selector==="string"){var match=quickExpr.exec(selector);if(match&&(match[1]||!context)){if(match[1]) +selector=jQuery.clean([match[1]],context);else{var elem=document.getElementById(match[3]);if(elem&&elem.id!=match[3]) +return jQuery().find(selector);var ret=jQuery(elem||[]);ret.context=document;ret.selector=selector;return ret;}}else +return jQuery(context).find(selector);}else if(jQuery.isFunction(selector)) +return jQuery(document).ready(selector);if(selector.selector&&selector.context){this.selector=selector.selector;this.context=selector.context;} +return this.setArray(jQuery.isArray(selector)?selector:jQuery.makeArray(selector));},selector:"",jquery:"1.3.2",size:function(){return this.length;},get:function(num){return num===undefined?Array.prototype.slice.call(this):this[num];},pushStack:function(elems,name,selector){var ret=jQuery(elems);ret.prevObject=this;ret.context=this.context;if(name==="find") +ret.selector=this.selector+(this.selector?" ":"")+selector;else if(name) +ret.selector=this.selector+"."+name+"("+selector+")";return ret;},setArray:function(elems){this.length=0;Array.prototype.push.apply(this,elems);return this;},each:function(callback,args){return jQuery.each(this,callback,args);},index:function(elem){return jQuery.inArray(elem&&elem.jquery?elem[0]:elem,this);},attr:function(name,value,type){var options=name;if(typeof name==="string") +if(value===undefined) +return this[0]&&jQuery[type||"attr"](this[0],name);else{options={};options[name]=value;} +return this.each(function(i){for(name in options) +jQuery.attr(type?this.style:this,name,jQuery.prop(this,options[name],type,i,name));});},css:function(key,value){if((key=='width'||key=='height')&&parseFloat(value)<0) +value=undefined;return this.attr(key,value,"curCSS");},text:function(text){if(typeof text!=="object"&&text!=null) +return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(text));var ret="";jQuery.each(text||this,function(){jQuery.each(this.childNodes,function(){if(this.nodeType!=8) +ret+=this.nodeType!=1?this.nodeValue:jQuery.fn.text([this]);});});return ret;},wrapAll:function(html){if(this[0]){var wrap=jQuery(html,this[0].ownerDocument).clone();if(this[0].parentNode) +wrap.insertBefore(this[0]);wrap.map(function(){var elem=this;while(elem.firstChild) +elem=elem.firstChild;return elem;}).append(this);} +return this;},wrapInner:function(html){return this.each(function(){jQuery(this).contents().wrapAll(html);});},wrap:function(html){return this.each(function(){jQuery(this).wrapAll(html);});},append:function(){return this.domManip(arguments,true,function(elem){if(this.nodeType==1) +this.appendChild(elem);});},prepend:function(){return this.domManip(arguments,true,function(elem){if(this.nodeType==1) +this.insertBefore(elem,this.firstChild);});},before:function(){return this.domManip(arguments,false,function(elem){this.parentNode.insertBefore(elem,this);});},after:function(){return this.domManip(arguments,false,function(elem){this.parentNode.insertBefore(elem,this.nextSibling);});},end:function(){return this.prevObject||jQuery([]);},push:[].push,sort:[].sort,splice:[].splice,find:function(selector){if(this.length===1){var ret=this.pushStack([],"find",selector);ret.length=0;jQuery.find(selector,this[0],ret);return ret;}else{return this.pushStack(jQuery.unique(jQuery.map(this,function(elem){return jQuery.find(selector,elem);})),"find",selector);}},clone:function(events){var ret=this.map(function(){if(!jQuery.support.noCloneEvent&&!jQuery.isXMLDoc(this)){var html=this.outerHTML;if(!html){var div=this.ownerDocument.createElement("div");div.appendChild(this.cloneNode(true));html=div.innerHTML;} +return jQuery.clean([html.replace(/ jQuery\d+="(?:\d+|null)"/g,"").replace(/^\s*/,"")])[0];}else +return this.cloneNode(true);});if(events===true){var orig=this.find("*").andSelf(),i=0;ret.find("*").andSelf().each(function(){if(this.nodeName!==orig[i].nodeName) +return;var events=jQuery.data(orig[i],"events");for(var type in events){for(var handler in events[type]){jQuery.event.add(this,type,events[type][handler],events[type][handler].data);}} +i++;});} +return ret;},filter:function(selector){return this.pushStack(jQuery.isFunction(selector)&&jQuery.grep(this,function(elem,i){return selector.call(elem,i);})||jQuery.multiFilter(selector,jQuery.grep(this,function(elem){return elem.nodeType===1;})),"filter",selector);},closest:function(selector){var pos=jQuery.expr.match.POS.test(selector)?jQuery(selector):null,closer=0;return this.map(function(){var cur=this;while(cur&&cur.ownerDocument){if(pos?pos.index(cur)>-1:jQuery(cur).is(selector)){jQuery.data(cur,"closest",closer);return cur;} +cur=cur.parentNode;closer++;}});},not:function(selector){if(typeof selector==="string") +if(isSimple.test(selector)) +return this.pushStack(jQuery.multiFilter(selector,this,true),"not",selector);else +selector=jQuery.multiFilter(selector,this);var isArrayLike=selector.length&&selector[selector.length-1]!==undefined&&!selector.nodeType;return this.filter(function(){return isArrayLike?jQuery.inArray(this,selector)<0:this!=selector;});},add:function(selector){return this.pushStack(jQuery.unique(jQuery.merge(this.get(),typeof selector==="string"?jQuery(selector):jQuery.makeArray(selector))));},is:function(selector){return!!selector&&jQuery.multiFilter(selector,this).length>0;},hasClass:function(selector){return!!selector&&this.is("."+selector);},val:function(value){if(value===undefined){var elem=this[0];if(elem){if(jQuery.nodeName(elem,'option')) +return(elem.attributes.value||{}).specified?elem.value:elem.text;if(jQuery.nodeName(elem,"select")){var index=elem.selectedIndex,values=[],options=elem.options,one=elem.type=="select-one";if(index<0) +return null;for(var i=one?index:0,max=one?index+1:options.length;i=0||jQuery.inArray(this.name,value)>=0);else if(jQuery.nodeName(this,"select")){var values=jQuery.makeArray(value);jQuery("option",this).each(function(){this.selected=(jQuery.inArray(this.value,values)>=0||jQuery.inArray(this.text,values)>=0);});if(!values.length) +this.selectedIndex=-1;}else +this.value=value;});},html:function(value){return value===undefined?(this[0]?this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g,""):null):this.empty().append(value);},replaceWith:function(value){return this.after(value).remove();},eq:function(i){return this.slice(i,+i+1);},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments),"slice",Array.prototype.slice.call(arguments).join(","));},map:function(callback){return this.pushStack(jQuery.map(this,function(elem,i){return callback.call(elem,i,elem);}));},andSelf:function(){return this.add(this.prevObject);},domManip:function(args,table,callback){if(this[0]){var fragment=(this[0].ownerDocument||this[0]).createDocumentFragment(),scripts=jQuery.clean(args,(this[0].ownerDocument||this[0]),fragment),first=fragment.firstChild;if(first) +for(var i=0,l=this.length;i1||i>0?fragment.cloneNode(true):fragment);if(scripts) +jQuery.each(scripts,evalScript);} +return this;function root(elem,cur){return table&&jQuery.nodeName(elem,"table")&&jQuery.nodeName(cur,"tr")?(elem.getElementsByTagName("tbody")[0]||elem.appendChild(elem.ownerDocument.createElement("tbody"))):elem;}}};jQuery.fn.init.prototype=jQuery.fn;function evalScript(i,elem){if(elem.src) +jQuery.ajax({url:elem.src,async:false,dataType:"script"});else +jQuery.globalEval(elem.text||elem.textContent||elem.innerHTML||"");if(elem.parentNode) +elem.parentNode.removeChild(elem);} +function now(){return+new Date;} +jQuery.extend=jQuery.fn.extend=function(){var target=arguments[0]||{},i=1,length=arguments.length,deep=false,options;if(typeof target==="boolean"){deep=target;target=arguments[1]||{};i=2;} +if(typeof target!=="object"&&!jQuery.isFunction(target)) +target={};if(length==i){target=this;--i;} +for(;i-1;}},swap:function(elem,options,callback){var old={};for(var name in options){old[name]=elem.style[name];elem.style[name]=options[name];} +callback.call(elem);for(var name in options) +elem.style[name]=old[name];},css:function(elem,name,force,extra){if(name=="width"||name=="height"){var val,props={position:"absolute",visibility:"hidden",display:"block"},which=name=="width"?["Left","Right"]:["Top","Bottom"];function getWH(){val=name=="width"?elem.offsetWidth:elem.offsetHeight;if(extra==="border") +return;jQuery.each(which,function(){if(!extra) +val-=parseFloat(jQuery.curCSS(elem,"padding"+this,true))||0;if(extra==="margin") +val+=parseFloat(jQuery.curCSS(elem,"margin"+this,true))||0;else +val-=parseFloat(jQuery.curCSS(elem,"border"+this+"Width",true))||0;});} +if(elem.offsetWidth!==0) +getWH();else +jQuery.swap(elem,props,getWH);return Math.max(0,Math.round(val));} +return jQuery.curCSS(elem,name,force);},curCSS:function(elem,name,force){var ret,style=elem.style;if(name=="opacity"&&!jQuery.support.opacity){ret=jQuery.attr(style,"opacity");return ret==""?"1":ret;} +if(name.match(/float/i)) +name=styleFloat;if(!force&&style&&style[name]) +ret=style[name];else if(defaultView.getComputedStyle){if(name.match(/float/i)) +name="float";name=name.replace(/([A-Z])/g,"-$1").toLowerCase();var computedStyle=defaultView.getComputedStyle(elem,null);if(computedStyle) +ret=computedStyle.getPropertyValue(name);if(name=="opacity"&&ret=="") +ret="1";}else if(elem.currentStyle){var camelCase=name.replace(/\-(\w)/g,function(all,letter){return letter.toUpperCase();});ret=elem.currentStyle[name]||elem.currentStyle[camelCase];if(!/^\d+(px)?$/i.test(ret)&&/^\d/.test(ret)){var left=style.left,rsLeft=elem.runtimeStyle.left;elem.runtimeStyle.left=elem.currentStyle.left;style.left=ret||0;ret=style.pixelLeft+"px";style.left=left;elem.runtimeStyle.left=rsLeft;}} +return ret;},clean:function(elems,context,fragment){context=context||document;if(typeof context.createElement==="undefined") +context=context.ownerDocument||context[0]&&context[0].ownerDocument||document;if(!fragment&&elems.length===1&&typeof elems[0]==="string"){var match=/^<(\w+)\s*\/?>$/.exec(elems[0]);if(match) +return[context.createElement(match[1])];} +var ret=[],scripts=[],div=context.createElement("div");jQuery.each(elems,function(i,elem){if(typeof elem==="number") +elem+='';if(!elem) +return;if(typeof elem==="string"){elem=elem.replace(/(<(\w+)[^>]*?)\/>/g,function(all,front,tag){return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?all:front+">";});var tags=elem.replace(/^\s+/,"").substring(0,10).toLowerCase();var wrap=!tags.indexOf("",""]||!tags.indexOf("",""]||tags.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"","
      "]||!tags.indexOf("",""]||(!tags.indexOf("",""]||!tags.indexOf("",""]||!jQuery.support.htmlSerialize&&[1,"div

      ","
      "]||[0,"",""];div.innerHTML=wrap[1]+elem+wrap[2];while(wrap[0]--) +div=div.lastChild;if(!jQuery.support.tbody){var hasBody=/"&&!hasBody?div.childNodes:[];for(var j=tbody.length-1;j>=0;--j) +if(jQuery.nodeName(tbody[j],"tbody")&&!tbody[j].childNodes.length) +tbody[j].parentNode.removeChild(tbody[j]);} +if(!jQuery.support.leadingWhitespace&&/^\s/.test(elem)) +div.insertBefore(context.createTextNode(elem.match(/^\s*/)[0]),div.firstChild);elem=jQuery.makeArray(div.childNodes);} +if(elem.nodeType) +ret.push(elem);else +ret=jQuery.merge(ret,elem);});if(fragment){for(var i=0;ret[i];i++){if(jQuery.nodeName(ret[i],"script")&&(!ret[i].type||ret[i].type.toLowerCase()==="text/javascript")){scripts.push(ret[i].parentNode?ret[i].parentNode.removeChild(ret[i]):ret[i]);}else{if(ret[i].nodeType===1) +ret.splice.apply(ret,[i+1,0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))));fragment.appendChild(ret[i]);}} +return scripts;} +return ret;},attr:function(elem,name,value){if(!elem||elem.nodeType==3||elem.nodeType==8) +return undefined;var notxml=!jQuery.isXMLDoc(elem),set=value!==undefined;name=notxml&&jQuery.props[name]||name;if(elem.tagName){var special=/href|src|style/.test(name);if(name=="selected"&&elem.parentNode) +elem.parentNode.selectedIndex;if(name in elem&¬xml&&!special){if(set){if(name=="type"&&jQuery.nodeName(elem,"input")&&elem.parentNode) +throw"type property can't be changed";elem[name]=value;} +if(jQuery.nodeName(elem,"form")&&elem.getAttributeNode(name)) +return elem.getAttributeNode(name).nodeValue;if(name=="tabIndex"){var attributeNode=elem.getAttributeNode("tabIndex");return attributeNode&&attributeNode.specified?attributeNode.value:elem.nodeName.match(/(button|input|object|select|textarea)/i)?0:elem.nodeName.match(/^(a|area)$/i)&&elem.href?0:undefined;} +return elem[name];} +if(!jQuery.support.style&¬xml&&name=="style") +return jQuery.attr(elem.style,"cssText",value);if(set) +elem.setAttribute(name,""+value);var attr=!jQuery.support.hrefNormalized&¬xml&&special?elem.getAttribute(name,2):elem.getAttribute(name);return attr===null?undefined:attr;} +if(!jQuery.support.opacity&&name=="opacity"){if(set){elem.zoom=1;elem.filter=(elem.filter||"").replace(/alpha\([^)]*\)/,"")+ +(parseInt(value)+''=="NaN"?"":"alpha(opacity="+value*100+")");} +return elem.filter&&elem.filter.indexOf("opacity=")>=0?(parseFloat(elem.filter.match(/opacity=([^)]*)/)[1])/100)+'':"";} +name=name.replace(/-([a-z])/ig,function(all,letter){return letter.toUpperCase();});if(set) +elem[name]=value;return elem[name];},trim:function(text){return(text||"").replace(/^\s+|\s+$/g,"");},makeArray:function(array){var ret=[];if(array!=null){var i=array.length;if(i==null||typeof array==="string"||jQuery.isFunction(array)||array.setInterval) +ret[0]=array;else +while(i) +ret[--i]=array[i];} +return ret;},inArray:function(elem,array){for(var i=0,length=array.length;i0?this.clone(true):this).get();jQuery.fn[original].apply(jQuery(insert[i]),elems);ret=ret.concat(elems);} +return this.pushStack(ret,name,selector);};});jQuery.each({removeAttr:function(name){jQuery.attr(this,name,"");if(this.nodeType==1) +this.removeAttribute(name);},addClass:function(classNames){jQuery.className.add(this,classNames);},removeClass:function(classNames){jQuery.className.remove(this,classNames);},toggleClass:function(classNames,state){if(typeof state!=="boolean") +state=!jQuery.className.has(this,classNames);jQuery.className[state?"add":"remove"](this,classNames);},remove:function(selector){if(!selector||jQuery.filter(selector,[this]).length){jQuery("*",this).add([this]).each(function(){jQuery.event.remove(this);jQuery.removeData(this);});if(this.parentNode) +this.parentNode.removeChild(this);}},empty:function(){jQuery(this).children().remove();while(this.firstChild) +this.removeChild(this.firstChild);}},function(name,fn){jQuery.fn[name]=function(){return this.each(fn,arguments);};});function num(elem,prop){return elem[0]&&parseInt(jQuery.curCSS(elem[0],prop,true),10)||0;} +var expando="jQuery"+now(),uuid=0,windowData={};jQuery.extend({cache:{},data:function(elem,name,data){elem=elem==window?windowData:elem;var id=elem[expando];if(!id) +id=elem[expando]=++uuid;if(name&&!jQuery.cache[id]) +jQuery.cache[id]={};if(data!==undefined) +jQuery.cache[id][name]=data;return name?jQuery.cache[id][name]:id;},removeData:function(elem,name){elem=elem==window?windowData:elem;var id=elem[expando];if(name){if(jQuery.cache[id]){delete jQuery.cache[id][name];name="";for(name in jQuery.cache[id]) +break;if(!name) +jQuery.removeData(elem);}}else{try{delete elem[expando];}catch(e){if(elem.removeAttribute) +elem.removeAttribute(expando);} +delete jQuery.cache[id];}},queue:function(elem,type,data){if(elem){type=(type||"fx")+"queue";var q=jQuery.data(elem,type);if(!q||jQuery.isArray(data)) +q=jQuery.data(elem,type,jQuery.makeArray(data));else if(data) +q.push(data);} +return q;},dequeue:function(elem,type){var queue=jQuery.queue(elem,type),fn=queue.shift();if(!type||type==="fx") +fn=queue[0];if(fn!==undefined) +fn.call(elem);}});jQuery.fn.extend({data:function(key,value){var parts=key.split(".");parts[1]=parts[1]?"."+parts[1]:"";if(value===undefined){var data=this.triggerHandler("getData"+parts[1]+"!",[parts[0]]);if(data===undefined&&this.length) +data=jQuery.data(this[0],key);return data===undefined&&parts[1]?this.data(parts[0]):data;}else +return this.trigger("setData"+parts[1]+"!",[parts[0],value]).each(function(){jQuery.data(this,key,value);});},removeData:function(key){return this.each(function(){jQuery.removeData(this,key);});},queue:function(type,data){if(typeof type!=="string"){data=type;type="fx";} +if(data===undefined) +return jQuery.queue(this[0],type);return this.each(function(){var queue=jQuery.queue(this,type,data);if(type=="fx"&&queue.length==1) +queue[0].call(this);});},dequeue:function(type){return this.each(function(){jQuery.dequeue(this,type);});}});(function(){var chunker=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,done=0,toString=Object.prototype.toString;var Sizzle=function(selector,context,results,seed){results=results||[];context=context||document;if(context.nodeType!==1&&context.nodeType!==9) +return[];if(!selector||typeof selector!=="string"){return results;} +var parts=[],m,set,checkSet,check,mode,extra,prune=true;chunker.lastIndex=0;while((m=chunker.exec(selector))!==null){parts.push(m[1]);if(m[2]){extra=RegExp.rightContext;break;}} +if(parts.length>1&&origPOS.exec(selector)){if(parts.length===2&&Expr.relative[parts[0]]){set=posProcess(parts[0]+parts[1],context);}else{set=Expr.relative[parts[0]]?[context]:Sizzle(parts.shift(),context);while(parts.length){selector=parts.shift();if(Expr.relative[selector]) +selector+=parts.shift();set=posProcess(selector,set);}}}else{var ret=seed?{expr:parts.pop(),set:makeArray(seed)}:Sizzle.find(parts.pop(),parts.length===1&&context.parentNode?context.parentNode:context,isXML(context));set=Sizzle.filter(ret.expr,ret.set);if(parts.length>0){checkSet=makeArray(set);}else{prune=false;} +while(parts.length){var cur=parts.pop(),pop=cur;if(!Expr.relative[cur]){cur="";}else{pop=parts.pop();} +if(pop==null){pop=context;} +Expr.relative[cur](checkSet,pop,isXML(context));}} +if(!checkSet){checkSet=set;} +if(!checkSet){throw"Syntax error, unrecognized expression: "+(cur||selector);} +if(toString.call(checkSet)==="[object Array]"){if(!prune){results.push.apply(results,checkSet);}else if(context.nodeType===1){for(var i=0;checkSet[i]!=null;i++){if(checkSet[i]&&(checkSet[i]===true||checkSet[i].nodeType===1&&contains(context,checkSet[i]))){results.push(set[i]);}}}else{for(var i=0;checkSet[i]!=null;i++){if(checkSet[i]&&checkSet[i].nodeType===1){results.push(set[i]);}}}}else{makeArray(checkSet,results);} +if(extra){Sizzle(extra,context,results,seed);if(sortOrder){hasDuplicate=false;results.sort(sortOrder);if(hasDuplicate){for(var i=1;i":function(checkSet,part,isXML){var isPartStr=typeof part==="string";if(isPartStr&&!/\W/.test(part)){part=isXML?part:part.toUpperCase();for(var i=0,l=checkSet.length;i=0)){if(!inplace) +result.push(elem);}else if(inplace){curLoop[i]=false;}}} +return false;},ID:function(match){return match[1].replace(/\\/g,"");},TAG:function(match,curLoop){for(var i=0;curLoop[i]===false;i++){} +return curLoop[i]&&isXML(curLoop[i])?match[1]:match[1].toUpperCase();},CHILD:function(match){if(match[1]=="nth"){var test=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(match[2]=="even"&&"2n"||match[2]=="odd"&&"2n+1"||!/\D/.test(match[2])&&"0n+"+match[2]||match[2]);match[2]=(test[1]+(test[2]||1))-0;match[3]=test[3]-0;} +match[0]=done++;return match;},ATTR:function(match,curLoop,inplace,result,not,isXML){var name=match[1].replace(/\\/g,"");if(!isXML&&Expr.attrMap[name]){match[1]=Expr.attrMap[name];} +if(match[2]==="~="){match[4]=" "+match[4]+" ";} +return match;},PSEUDO:function(match,curLoop,inplace,result,not){if(match[1]==="not"){if(match[3].match(chunker).length>1||/^\w/.test(match[3])){match[3]=Sizzle(match[3],null,null,curLoop);}else{var ret=Sizzle.filter(match[3],curLoop,inplace,true^not);if(!inplace){result.push.apply(result,ret);} +return false;}}else if(Expr.match.POS.test(match[0])||Expr.match.CHILD.test(match[0])){return true;} +return match;},POS:function(match){match.unshift(true);return match;}},filters:{enabled:function(elem){return elem.disabled===false&&elem.type!=="hidden";},disabled:function(elem){return elem.disabled===true;},checked:function(elem){return elem.checked===true;},selected:function(elem){elem.parentNode.selectedIndex;return elem.selected===true;},parent:function(elem){return!!elem.firstChild;},empty:function(elem){return!elem.firstChild;},has:function(elem,i,match){return!!Sizzle(match[3],elem).length;},header:function(elem){return/h\d/i.test(elem.nodeName);},text:function(elem){return"text"===elem.type;},radio:function(elem){return"radio"===elem.type;},checkbox:function(elem){return"checkbox"===elem.type;},file:function(elem){return"file"===elem.type;},password:function(elem){return"password"===elem.type;},submit:function(elem){return"submit"===elem.type;},image:function(elem){return"image"===elem.type;},reset:function(elem){return"reset"===elem.type;},button:function(elem){return"button"===elem.type||elem.nodeName.toUpperCase()==="BUTTON";},input:function(elem){return/input|select|textarea|button/i.test(elem.nodeName);}},setFilters:{first:function(elem,i){return i===0;},last:function(elem,i,match,array){return i===array.length-1;},even:function(elem,i){return i%2===0;},odd:function(elem,i){return i%2===1;},lt:function(elem,i,match){return imatch[3]-0;},nth:function(elem,i,match){return match[3]-0==i;},eq:function(elem,i,match){return match[3]-0==i;}},filter:{PSEUDO:function(elem,match,i,array){var name=match[1],filter=Expr.filters[name];if(filter){return filter(elem,i,match,array);}else if(name==="contains"){return(elem.textContent||elem.innerText||"").indexOf(match[3])>=0;}else if(name==="not"){var not=match[3];for(var i=0,l=not.length;i=0);}}},ID:function(elem,match){return elem.nodeType===1&&elem.getAttribute("id")===match;},TAG:function(elem,match){return(match==="*"&&elem.nodeType===1)||elem.nodeName===match;},CLASS:function(elem,match){return(" "+(elem.className||elem.getAttribute("class"))+" ").indexOf(match)>-1;},ATTR:function(elem,match){var name=match[1],result=Expr.attrHandle[name]?Expr.attrHandle[name](elem):elem[name]!=null?elem[name]:elem.getAttribute(name),value=result+"",type=match[2],check=match[4];return result==null?type==="!=":type==="="?value===check:type==="*="?value.indexOf(check)>=0:type==="~="?(" "+value+" ").indexOf(check)>=0:!check?value&&result!==false:type==="!="?value!=check:type==="^="?value.indexOf(check)===0:type==="$="?value.substr(value.length-check.length)===check:type==="|="?value===check||value.substr(0,check.length+1)===check+"-":false;},POS:function(elem,match,i,array){var name=match[2],filter=Expr.setFilters[name];if(filter){return filter(elem,i,match,array);}}}};var origPOS=Expr.match.POS;for(var type in Expr.match){Expr.match[type]=RegExp(Expr.match[type].source+/(?![^\[]*\])(?![^\(]*\))/.source);} +var makeArray=function(array,results){array=Array.prototype.slice.call(array);if(results){results.push.apply(results,array);return results;} +return array;};try{Array.prototype.slice.call(document.documentElement.childNodes);}catch(e){makeArray=function(array,results){var ret=results||[];if(toString.call(array)==="[object Array]"){Array.prototype.push.apply(ret,array);}else{if(typeof array.length==="number"){for(var i=0,l=array.length;i";var root=document.documentElement;root.insertBefore(form,root.firstChild);if(!!document.getElementById(id)){Expr.find.ID=function(match,context,isXML){if(typeof context.getElementById!=="undefined"&&!isXML){var m=context.getElementById(match[1]);return m?m.id===match[1]||typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id").nodeValue===match[1]?[m]:undefined:[];}};Expr.filter.ID=function(elem,match){var node=typeof elem.getAttributeNode!=="undefined"&&elem.getAttributeNode("id");return elem.nodeType===1&&node&&node.nodeValue===match;};} +root.removeChild(form);})();(function(){var div=document.createElement("div");div.appendChild(document.createComment(""));if(div.getElementsByTagName("*").length>0){Expr.find.TAG=function(match,context){var results=context.getElementsByTagName(match[1]);if(match[1]==="*"){var tmp=[];for(var i=0;results[i];i++){if(results[i].nodeType===1){tmp.push(results[i]);}} +results=tmp;} +return results;};} +div.innerHTML="";if(div.firstChild&&typeof div.firstChild.getAttribute!=="undefined"&&div.firstChild.getAttribute("href")!=="#"){Expr.attrHandle.href=function(elem){return elem.getAttribute("href",2);};}})();if(document.querySelectorAll)(function(){var oldSizzle=Sizzle,div=document.createElement("div");div.innerHTML="

      ";if(div.querySelectorAll&&div.querySelectorAll(".TEST").length===0){return;} +Sizzle=function(query,context,extra,seed){context=context||document;if(!seed&&context.nodeType===9&&!isXML(context)){try{return makeArray(context.querySelectorAll(query),extra);}catch(e){}} +return oldSizzle(query,context,extra,seed);};Sizzle.find=oldSizzle.find;Sizzle.filter=oldSizzle.filter;Sizzle.selectors=oldSizzle.selectors;Sizzle.matches=oldSizzle.matches;})();if(document.getElementsByClassName&&document.documentElement.getElementsByClassName)(function(){var div=document.createElement("div");div.innerHTML="
      ";if(div.getElementsByClassName("e").length===0) +return;div.lastChild.className="e";if(div.getElementsByClassName("e").length===1) +return;Expr.order.splice(1,0,"CLASS");Expr.find.CLASS=function(match,context,isXML){if(typeof context.getElementsByClassName!=="undefined"&&!isXML){return context.getElementsByClassName(match[1]);}};})();function dirNodeCheck(dir,cur,doneName,checkSet,nodeCheck,isXML){var sibDir=dir=="previousSibling"&&!isXML;for(var i=0,l=checkSet.length;i0){match=elem;break;}} +elem=elem[dir];} +checkSet[i]=match;}}} +var contains=document.compareDocumentPosition?function(a,b){return a.compareDocumentPosition(b)&16;}:function(a,b){return a!==b&&(a.contains?a.contains(b):true);};var isXML=function(elem){return elem.nodeType===9&&elem.documentElement.nodeName!=="HTML"||!!elem.ownerDocument&&isXML(elem.ownerDocument);};var posProcess=function(selector,context){var tmpSet=[],later="",match,root=context.nodeType?[context]:context;while((match=Expr.match.PSEUDO.exec(selector))){later+=match[0];selector=selector.replace(Expr.match.PSEUDO,"");} +selector=Expr.relative[selector]?selector+"*":selector;for(var i=0,l=root.length;i0||elem.offsetHeight>0;};Sizzle.selectors.filters.animated=function(elem){return jQuery.grep(jQuery.timers,function(fn){return elem===fn.elem;}).length;};jQuery.multiFilter=function(expr,elems,not){if(not){expr=":not("+expr+")";} +return Sizzle.matches(expr,elems);};jQuery.dir=function(elem,dir){var matched=[],cur=elem[dir];while(cur&&cur!=document){if(cur.nodeType==1) +matched.push(cur);cur=cur[dir];} +return matched;};jQuery.nth=function(cur,result,dir,elem){result=result||1;var num=0;for(;cur;cur=cur[dir]) +if(cur.nodeType==1&&++num==result) +break;return cur;};jQuery.sibling=function(n,elem){var r=[];for(;n;n=n.nextSibling){if(n.nodeType==1&&n!=elem) +r.push(n);} +return r;};return;window.Sizzle=Sizzle;})();jQuery.event={add:function(elem,types,handler,data){if(elem.nodeType==3||elem.nodeType==8) +return;if(elem.setInterval&&elem!=window) +elem=window;if(!handler.guid) +handler.guid=this.guid++;if(data!==undefined){var fn=handler;handler=this.proxy(fn);handler.data=data;} +var events=jQuery.data(elem,"events")||jQuery.data(elem,"events",{}),handle=jQuery.data(elem,"handle")||jQuery.data(elem,"handle",function(){return typeof jQuery!=="undefined"&&!jQuery.event.triggered?jQuery.event.handle.apply(arguments.callee.elem,arguments):undefined;});handle.elem=elem;jQuery.each(types.split(/\s+/),function(index,type){var namespaces=type.split(".");type=namespaces.shift();handler.type=namespaces.slice().sort().join(".");var handlers=events[type];if(jQuery.event.specialAll[type]) +jQuery.event.specialAll[type].setup.call(elem,data,namespaces);if(!handlers){handlers=events[type]={};if(!jQuery.event.special[type]||jQuery.event.special[type].setup.call(elem,data,namespaces)===false){if(elem.addEventListener) +elem.addEventListener(type,handle,false);else if(elem.attachEvent) +elem.attachEvent("on"+type,handle);}} +handlers[handler.guid]=handler;jQuery.event.global[type]=true;});elem=null;},guid:1,global:{},remove:function(elem,types,handler){if(elem.nodeType==3||elem.nodeType==8) +return;var events=jQuery.data(elem,"events"),ret,index;if(events){if(types===undefined||(typeof types==="string"&&types.charAt(0)==".")) +for(var type in events) +this.remove(elem,type+(types||""));else{if(types.type){handler=types.handler;types=types.type;} +jQuery.each(types.split(/\s+/),function(index,type){var namespaces=type.split(".");type=namespaces.shift();var namespace=RegExp("(^|\\.)"+namespaces.slice().sort().join(".*\\.")+"(\\.|$)");if(events[type]){if(handler) +delete events[type][handler.guid];else +for(var handle in events[type]) +if(namespace.test(events[type][handle].type)) +delete events[type][handle];if(jQuery.event.specialAll[type]) +jQuery.event.specialAll[type].teardown.call(elem,namespaces);for(ret in events[type])break;if(!ret){if(!jQuery.event.special[type]||jQuery.event.special[type].teardown.call(elem,namespaces)===false){if(elem.removeEventListener) +elem.removeEventListener(type,jQuery.data(elem,"handle"),false);else if(elem.detachEvent) +elem.detachEvent("on"+type,jQuery.data(elem,"handle"));} +ret=null;delete events[type];}}});} +for(ret in events)break;if(!ret){var handle=jQuery.data(elem,"handle");if(handle)handle.elem=null;jQuery.removeData(elem,"events");jQuery.removeData(elem,"handle");}}},trigger:function(event,data,elem,bubbling){var type=event.type||event;if(!bubbling){event=typeof event==="object"?event[expando]?event:jQuery.extend(jQuery.Event(type),event):jQuery.Event(type);if(type.indexOf("!")>=0){event.type=type=type.slice(0,-1);event.exclusive=true;} +if(!elem){event.stopPropagation();if(this.global[type]) +jQuery.each(jQuery.cache,function(){if(this.events&&this.events[type]) +jQuery.event.trigger(event,data,this.handle.elem);});} +if(!elem||elem.nodeType==3||elem.nodeType==8) +return undefined;event.result=undefined;event.target=elem;data=jQuery.makeArray(data);data.unshift(event);} +event.currentTarget=elem;var handle=jQuery.data(elem,"handle");if(handle) +handle.apply(elem,data);if((!elem[type]||(jQuery.nodeName(elem,'a')&&type=="click"))&&elem["on"+type]&&elem["on"+type].apply(elem,data)===false) +event.result=false;if(!bubbling&&elem[type]&&!event.isDefaultPrevented()&&!(jQuery.nodeName(elem,'a')&&type=="click")){this.triggered=true;try{elem[type]();}catch(e){}} +this.triggered=false;if(!event.isPropagationStopped()){var parent=elem.parentNode||elem.ownerDocument;if(parent) +jQuery.event.trigger(event,data,parent,true);}},handle:function(event){var all,handlers;event=arguments[0]=jQuery.event.fix(event||window.event);event.currentTarget=this;var namespaces=event.type.split(".");event.type=namespaces.shift();all=!namespaces.length&&!event.exclusive;var namespace=RegExp("(^|\\.)"+namespaces.slice().sort().join(".*\\.")+"(\\.|$)");handlers=(jQuery.data(this,"events")||{})[event.type];for(var j in handlers){var handler=handlers[j];if(all||namespace.test(handler.type)){event.handler=handler;event.data=handler.data;var ret=handler.apply(this,arguments);if(ret!==undefined){event.result=ret;if(ret===false){event.preventDefault();event.stopPropagation();}} +if(event.isImmediatePropagationStopped()) +break;}}},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(event){if(event[expando]) +return event;var originalEvent=event;event=jQuery.Event(originalEvent);for(var i=this.props.length,prop;i;){prop=this.props[--i];event[prop]=originalEvent[prop];} +if(!event.target) +event.target=event.srcElement||document;if(event.target.nodeType==3) +event.target=event.target.parentNode;if(!event.relatedTarget&&event.fromElement) +event.relatedTarget=event.fromElement==event.target?event.toElement:event.fromElement;if(event.pageX==null&&event.clientX!=null){var doc=document.documentElement,body=document.body;event.pageX=event.clientX+(doc&&doc.scrollLeft||body&&body.scrollLeft||0)-(doc.clientLeft||0);event.pageY=event.clientY+(doc&&doc.scrollTop||body&&body.scrollTop||0)-(doc.clientTop||0);} +if(!event.which&&((event.charCode||event.charCode===0)?event.charCode:event.keyCode)) +event.which=event.charCode||event.keyCode;if(!event.metaKey&&event.ctrlKey) +event.metaKey=event.ctrlKey;if(!event.which&&event.button) +event.which=(event.button&1?1:(event.button&2?3:(event.button&4?2:0)));return event;},proxy:function(fn,proxy){proxy=proxy||function(){return fn.apply(this,arguments);};proxy.guid=fn.guid=fn.guid||proxy.guid||this.guid++;return proxy;},special:{ready:{setup:bindReady,teardown:function(){}}},specialAll:{live:{setup:function(selector,namespaces){jQuery.event.add(this,namespaces[0],liveHandler);},teardown:function(namespaces){if(namespaces.length){var remove=0,name=RegExp("(^|\\.)"+namespaces[0]+"(\\.|$)");jQuery.each((jQuery.data(this,"events").live||{}),function(){if(name.test(this.type)) +remove++;});if(remove<1) +jQuery.event.remove(this,namespaces[0],liveHandler);}}}}};jQuery.Event=function(src){if(!this.preventDefault) +return new jQuery.Event(src);if(src&&src.type){this.originalEvent=src;this.type=src.type;}else +this.type=src;this.timeStamp=now();this[expando]=true;};function returnFalse(){return false;} +function returnTrue(){return true;} +jQuery.Event.prototype={preventDefault:function(){this.isDefaultPrevented=returnTrue;var e=this.originalEvent;if(!e) +return;if(e.preventDefault) +e.preventDefault();e.returnValue=false;},stopPropagation:function(){this.isPropagationStopped=returnTrue;var e=this.originalEvent;if(!e) +return;if(e.stopPropagation) +e.stopPropagation();e.cancelBubble=true;},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=returnTrue;this.stopPropagation();},isDefaultPrevented:returnFalse,isPropagationStopped:returnFalse,isImmediatePropagationStopped:returnFalse};var withinElement=function(event){var parent=event.relatedTarget;while(parent&&parent!=this) +try{parent=parent.parentNode;} +catch(e){parent=this;} +if(parent!=this){event.type=event.data;jQuery.event.handle.apply(this,arguments);}};jQuery.each({mouseover:'mouseenter',mouseout:'mouseleave'},function(orig,fix){jQuery.event.special[fix]={setup:function(){jQuery.event.add(this,orig,withinElement,fix);},teardown:function(){jQuery.event.remove(this,orig,withinElement);}};});jQuery.fn.extend({bind:function(type,data,fn){return type=="unload"?this.one(type,data,fn):this.each(function(){jQuery.event.add(this,type,fn||data,fn&&data);});},one:function(type,data,fn){var one=jQuery.event.proxy(fn||data,function(event){jQuery(this).unbind(event,one);return(fn||data).apply(this,arguments);});return this.each(function(){jQuery.event.add(this,type,one,fn&&data);});},unbind:function(type,fn){return this.each(function(){jQuery.event.remove(this,type,fn);});},trigger:function(type,data){return this.each(function(){jQuery.event.trigger(type,data,this);});},triggerHandler:function(type,data){if(this[0]){var event=jQuery.Event(type);event.preventDefault();event.stopPropagation();jQuery.event.trigger(event,data,this[0]);return event.result;}},toggle:function(fn){var args=arguments,i=1;while(i=0){var selector=url.slice(off,url.length);url=url.slice(0,off);} +var type="GET";if(params) +if(jQuery.isFunction(params)){callback=params;params=null;}else if(typeof params==="object"){params=jQuery.param(params);type="POST";} +var self=this;jQuery.ajax({url:url,type:type,dataType:"html",data:params,complete:function(res,status){if(status=="success"||status=="notmodified") +self.html(selector?jQuery("
      ").append(res.responseText.replace(//g,"")).find(selector):res.responseText);if(callback) +self.each(callback,[res.responseText,status,res]);}});return this;},serialize:function(){return jQuery.param(this.serializeArray());},serializeArray:function(){return this.map(function(){return this.elements?jQuery.makeArray(this.elements):this;}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password|search/i.test(this.type));}).map(function(i,elem){var val=jQuery(this).val();return val==null?null:jQuery.isArray(val)?jQuery.map(val,function(val,i){return{name:elem.name,value:val};}):{name:elem.name,value:val};}).get();}});jQuery.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(i,o){jQuery.fn[o]=function(f){return this.bind(o,f);};});var jsc=now();jQuery.extend({get:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data=null;} +return jQuery.ajax({type:"GET",url:url,data:data,success:callback,dataType:type});},getScript:function(url,callback){return jQuery.get(url,null,callback,"script");},getJSON:function(url,data,callback){return jQuery.get(url,data,callback,"json");},post:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data={};} +return jQuery.ajax({type:"POST",url:url,data:data,success:callback,dataType:type});},ajaxSetup:function(settings){jQuery.extend(jQuery.ajaxSettings,settings);},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:function(){return window.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest();},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(s){s=jQuery.extend(true,s,jQuery.extend(true,{},jQuery.ajaxSettings,s));var jsonp,jsre=/=\?(&|$)/g,status,data,type=s.type.toUpperCase();if(s.data&&s.processData&&typeof s.data!=="string") +s.data=jQuery.param(s.data);if(s.dataType=="jsonp"){if(type=="GET"){if(!s.url.match(jsre)) +s.url+=(s.url.match(/\?/)?"&":"?")+(s.jsonp||"callback")+"=?";}else if(!s.data||!s.data.match(jsre)) +s.data=(s.data?s.data+"&":"")+(s.jsonp||"callback")+"=?";s.dataType="json";} +if(s.dataType=="json"&&(s.data&&s.data.match(jsre)||s.url.match(jsre))){jsonp="jsonp"+jsc++;if(s.data) +s.data=(s.data+"").replace(jsre,"="+jsonp+"$1");s.url=s.url.replace(jsre,"="+jsonp+"$1");s.dataType="script";window[jsonp]=function(tmp){data=tmp;success();complete();window[jsonp]=undefined;try{delete window[jsonp];}catch(e){} +if(head) +head.removeChild(script);};} +if(s.dataType=="script"&&s.cache==null) +s.cache=false;if(s.cache===false&&type=="GET"){var ts=now();var ret=s.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+ts+"$2");s.url=ret+((ret==s.url)?(s.url.match(/\?/)?"&":"?")+"_="+ts:"");} +if(s.data&&type=="GET"){s.url+=(s.url.match(/\?/)?"&":"?")+s.data;s.data=null;} +if(s.global&&!jQuery.active++) +jQuery.event.trigger("ajaxStart");var parts=/^(\w+:)?\/\/([^\/?#]+)/.exec(s.url);if(s.dataType=="script"&&type=="GET"&&parts&&(parts[1]&&parts[1]!=location.protocol||parts[2]!=location.host)){var head=document.getElementsByTagName("head")[0];var script=document.createElement("script");script.src=s.url;if(s.scriptCharset) +script.charset=s.scriptCharset;if(!jsonp){var done=false;script.onload=script.onreadystatechange=function(){if(!done&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){done=true;success();complete();script.onload=script.onreadystatechange=null;head.removeChild(script);}};} +head.appendChild(script);return undefined;} +var requestDone=false;var xhr=s.xhr();if(s.username) +xhr.open(type,s.url,s.async,s.username,s.password);else +xhr.open(type,s.url,s.async);try{if(s.data) +xhr.setRequestHeader("Content-Type",s.contentType);if(s.ifModified) +xhr.setRequestHeader("If-Modified-Since",jQuery.lastModified[s.url]||"Thu, 01 Jan 1970 00:00:00 GMT");xhr.setRequestHeader("X-Requested-With","XMLHttpRequest");xhr.setRequestHeader("Accept",s.dataType&&s.accepts[s.dataType]?s.accepts[s.dataType]+", */*":s.accepts._default);}catch(e){} +if(s.beforeSend&&s.beforeSend(xhr,s)===false){if(s.global&&!--jQuery.active) +jQuery.event.trigger("ajaxStop");xhr.abort();return false;} +if(s.global) +jQuery.event.trigger("ajaxSend",[xhr,s]);var onreadystatechange=function(isTimeout){if(xhr.readyState==0){if(ival){clearInterval(ival);ival=null;if(s.global&&!--jQuery.active) +jQuery.event.trigger("ajaxStop");}}else if(!requestDone&&xhr&&(xhr.readyState==4||isTimeout=="timeout")){requestDone=true;if(ival){clearInterval(ival);ival=null;} +status=isTimeout=="timeout"?"timeout":!jQuery.httpSuccess(xhr)?"error":s.ifModified&&jQuery.httpNotModified(xhr,s.url)?"notmodified":"success";if(status=="success"){try{data=jQuery.httpData(xhr,s.dataType,s);}catch(e){status="parsererror";}} +if(status=="success"){var modRes;try{modRes=xhr.getResponseHeader("Last-Modified");}catch(e){} +if(s.ifModified&&modRes) +jQuery.lastModified[s.url]=modRes;if(!jsonp) +success();}else +jQuery.handleError(s,xhr,status);complete();if(isTimeout) +xhr.abort();if(s.async) +xhr=null;}};if(s.async){var ival=setInterval(onreadystatechange,13);if(s.timeout>0) +setTimeout(function(){if(xhr&&!requestDone) +onreadystatechange("timeout");},s.timeout);} +try{xhr.send(s.data);}catch(e){jQuery.handleError(s,xhr,null,e);} +if(!s.async) +onreadystatechange();function success(){if(s.success) +s.success(data,status);if(s.global) +jQuery.event.trigger("ajaxSuccess",[xhr,s]);} +function complete(){if(s.complete) +s.complete(xhr,status);if(s.global) +jQuery.event.trigger("ajaxComplete",[xhr,s]);if(s.global&&!--jQuery.active) +jQuery.event.trigger("ajaxStop");} +return xhr;},handleError:function(s,xhr,status,e){if(s.error)s.error(xhr,status,e);if(s.global) +jQuery.event.trigger("ajaxError",[xhr,s,e]);},active:0,httpSuccess:function(xhr){try{return!xhr.status&&location.protocol=="file:"||(xhr.status>=200&&xhr.status<300)||xhr.status==304||xhr.status==1223;}catch(e){} +return false;},httpNotModified:function(xhr,url){try{var xhrRes=xhr.getResponseHeader("Last-Modified");return xhr.status==304||xhrRes==jQuery.lastModified[url];}catch(e){} +return false;},httpData:function(xhr,type,s){var ct=xhr.getResponseHeader("content-type"),xml=type=="xml"||!type&&ct&&ct.indexOf("xml")>=0,data=xml?xhr.responseXML:xhr.responseText;if(xml&&data.documentElement.tagName=="parsererror") +throw"parsererror";if(s&&s.dataFilter) +data=s.dataFilter(data,type);if(typeof data==="string"){if(type=="script") +jQuery.globalEval(data);if(type=="json") +data=window["eval"]("("+data+")");} +return data;},param:function(a){var s=[];function add(key,value){s[s.length]=encodeURIComponent(key)+'='+encodeURIComponent(value);};if(jQuery.isArray(a)||a.jquery) +jQuery.each(a,function(){add(this.name,this.value);});else +for(var j in a) +if(jQuery.isArray(a[j])) +jQuery.each(a[j],function(){add(j,this);});else +add(j,jQuery.isFunction(a[j])?a[j]():a[j]);return s.join("&").replace(/%20/g,"+");}});var elemdisplay={},timerId,fxAttrs=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];function genFx(type,num){var obj={};jQuery.each(fxAttrs.concat.apply([],fxAttrs.slice(0,num)),function(){obj[this]=type;});return obj;} +jQuery.fn.extend({show:function(speed,callback){if(speed){return this.animate(genFx("show",3),speed,callback);}else{for(var i=0,l=this.length;i").appendTo("body");display=elem.css("display");if(display==="none") +display="block";elem.remove();elemdisplay[tagName]=display;} +jQuery.data(this[i],"olddisplay",display);}} +for(var i=0,l=this.length;i=0;i--) +if(timers[i].elem==this){if(gotoEnd) +timers[i](true);timers.splice(i,1);}});if(!gotoEnd) +this.dequeue();return this;}});jQuery.each({slideDown:genFx("show",1),slideUp:genFx("hide",1),slideToggle:genFx("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(name,props){jQuery.fn[name]=function(speed,callback){return this.animate(props,speed,callback);};});jQuery.extend({speed:function(speed,easing,fn){var opt=typeof speed==="object"?speed:{complete:fn||!fn&&easing||jQuery.isFunction(speed)&&speed,duration:speed,easing:fn&&easing||easing&&!jQuery.isFunction(easing)&&easing};opt.duration=jQuery.fx.off?0:typeof opt.duration==="number"?opt.duration:jQuery.fx.speeds[opt.duration]||jQuery.fx.speeds._default;opt.old=opt.complete;opt.complete=function(){if(opt.queue!==false) +jQuery(this).dequeue();if(jQuery.isFunction(opt.old)) +opt.old.call(this);};return opt;},easing:{linear:function(p,n,firstNum,diff){return firstNum+diff*p;},swing:function(p,n,firstNum,diff){return((-Math.cos(p*Math.PI)/2)+0.5)*diff+firstNum;}},timers:[],fx:function(elem,options,prop){this.options=options;this.elem=elem;this.prop=prop;if(!options.orig) +options.orig={};}});jQuery.fx.prototype={update:function(){if(this.options.step) +this.options.step.call(this.elem,this.now,this);(jQuery.fx.step[this.prop]||jQuery.fx.step._default)(this);if((this.prop=="height"||this.prop=="width")&&this.elem.style) +this.elem.style.display="block";},cur:function(force){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null)) +return this.elem[this.prop];var r=parseFloat(jQuery.css(this.elem,this.prop,force));return r&&r>-10000?r:parseFloat(jQuery.curCSS(this.elem,this.prop))||0;},custom:function(from,to,unit){this.startTime=now();this.start=from;this.end=to;this.unit=unit||this.unit||"px";this.now=this.start;this.pos=this.state=0;var self=this;function t(gotoEnd){return self.step(gotoEnd);} +t.elem=this.elem;if(t()&&jQuery.timers.push(t)&&!timerId){timerId=setInterval(function(){var timers=jQuery.timers;for(var i=0;i=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var done=true;for(var i in this.options.curAnim) +if(this.options.curAnim[i]!==true) +done=false;if(done){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(jQuery.css(this.elem,"display")=="none") +this.elem.style.display="block";} +if(this.options.hide) +jQuery(this.elem).hide();if(this.options.hide||this.options.show) +for(var p in this.options.curAnim) +jQuery.attr(this.elem.style,p,this.options.orig[p]);this.options.complete.call(this.elem);} +return false;}else{var n=t-this.startTime;this.state=n/this.options.duration;this.pos=jQuery.easing[this.options.easing||(jQuery.easing.swing?"swing":"linear")](this.state,n,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update();} +return true;}};jQuery.extend(jQuery.fx,{speeds:{slow:600,fast:200,_default:400},step:{opacity:function(fx){jQuery.attr(fx.elem.style,"opacity",fx.now);},_default:function(fx){if(fx.elem.style&&fx.elem.style[fx.prop]!=null) +fx.elem.style[fx.prop]=fx.now+fx.unit;else +fx.elem[fx.prop]=fx.now;}}});if(document.documentElement["getBoundingClientRect"]) +jQuery.fn.offset=function(){if(!this[0])return{top:0,left:0};if(this[0]===this[0].ownerDocument.body)return jQuery.offset.bodyOffset(this[0]);var box=this[0].getBoundingClientRect(),doc=this[0].ownerDocument,body=doc.body,docElem=doc.documentElement,clientTop=docElem.clientTop||body.clientTop||0,clientLeft=docElem.clientLeft||body.clientLeft||0,top=box.top+(self.pageYOffset||jQuery.boxModel&&docElem.scrollTop||body.scrollTop)-clientTop,left=box.left+(self.pageXOffset||jQuery.boxModel&&docElem.scrollLeft||body.scrollLeft)-clientLeft;return{top:top,left:left};};else +jQuery.fn.offset=function(){if(!this[0])return{top:0,left:0};if(this[0]===this[0].ownerDocument.body)return jQuery.offset.bodyOffset(this[0]);jQuery.offset.initialized||jQuery.offset.initialize();var elem=this[0],offsetParent=elem.offsetParent,prevOffsetParent=elem,doc=elem.ownerDocument,computedStyle,docElem=doc.documentElement,body=doc.body,defaultView=doc.defaultView,prevComputedStyle=defaultView.getComputedStyle(elem,null),top=elem.offsetTop,left=elem.offsetLeft;while((elem=elem.parentNode)&&elem!==body&&elem!==docElem){computedStyle=defaultView.getComputedStyle(elem,null);top-=elem.scrollTop,left-=elem.scrollLeft;if(elem===offsetParent){top+=elem.offsetTop,left+=elem.offsetLeft;if(jQuery.offset.doesNotAddBorder&&!(jQuery.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(elem.tagName))) +top+=parseInt(computedStyle.borderTopWidth,10)||0,left+=parseInt(computedStyle.borderLeftWidth,10)||0;prevOffsetParent=offsetParent,offsetParent=elem.offsetParent;} +if(jQuery.offset.subtractsBorderForOverflowNotVisible&&computedStyle.overflow!=="visible") +top+=parseInt(computedStyle.borderTopWidth,10)||0,left+=parseInt(computedStyle.borderLeftWidth,10)||0;prevComputedStyle=computedStyle;} +if(prevComputedStyle.position==="relative"||prevComputedStyle.position==="static") +top+=body.offsetTop,left+=body.offsetLeft;if(prevComputedStyle.position==="fixed") +top+=Math.max(docElem.scrollTop,body.scrollTop),left+=Math.max(docElem.scrollLeft,body.scrollLeft);return{top:top,left:left};};jQuery.offset={initialize:function(){if(this.initialized)return;var body=document.body,container=document.createElement('div'),innerDiv,checkDiv,table,td,rules,prop,bodyMarginTop=body.style.marginTop,html='
      ';rules={position:'absolute',top:0,left:0,margin:0,border:0,width:'1px',height:'1px',visibility:'hidden'};for(prop in rules)container.style[prop]=rules[prop];container.innerHTML=html;body.insertBefore(container,body.firstChild);innerDiv=container.firstChild,checkDiv=innerDiv.firstChild,td=innerDiv.nextSibling.firstChild.firstChild;this.doesNotAddBorder=(checkDiv.offsetTop!==5);this.doesAddBorderForTableAndCells=(td.offsetTop===5);innerDiv.style.overflow='hidden',innerDiv.style.position='relative';this.subtractsBorderForOverflowNotVisible=(checkDiv.offsetTop===-5);body.style.marginTop='1px';this.doesNotIncludeMarginInBodyOffset=(body.offsetTop===0);body.style.marginTop=bodyMarginTop;body.removeChild(container);this.initialized=true;},bodyOffset:function(body){jQuery.offset.initialized||jQuery.offset.initialize();var top=body.offsetTop,left=body.offsetLeft;if(jQuery.offset.doesNotIncludeMarginInBodyOffset) +top+=parseInt(jQuery.curCSS(body,'marginTop',true),10)||0,left+=parseInt(jQuery.curCSS(body,'marginLeft',true),10)||0;return{top:top,left:left};}};jQuery.fn.extend({position:function(){var left=0,top=0,results;if(this[0]){var offsetParent=this.offsetParent(),offset=this.offset(),parentOffset=/^body|html$/i.test(offsetParent[0].tagName)?{top:0,left:0}:offsetParent.offset();offset.top-=num(this,'marginTop');offset.left-=num(this,'marginLeft');parentOffset.top+=num(offsetParent,'borderTopWidth');parentOffset.left+=num(offsetParent,'borderLeftWidth');results={top:offset.top-parentOffset.top,left:offset.left-parentOffset.left};} +return results;},offsetParent:function(){var offsetParent=this[0].offsetParent||document.body;while(offsetParent&&(!/^body|html$/i.test(offsetParent.tagName)&&jQuery.css(offsetParent,'position')=='static')) +offsetParent=offsetParent.offsetParent;return jQuery(offsetParent);}});jQuery.each(['Left','Top'],function(i,name){var method='scroll'+name;jQuery.fn[method]=function(val){if(!this[0])return null;return val!==undefined?this.each(function(){this==window||this==document?window.scrollTo(!i?val:jQuery(window).scrollLeft(),i?val:jQuery(window).scrollTop()):this[method]=val;}):this[0]==window||this[0]==document?self[i?'pageYOffset':'pageXOffset']||jQuery.boxModel&&document.documentElement[method]||document.body[method]:this[0][method];};});jQuery.each(["Height","Width"],function(i,name){var tl=i?"Left":"Top",br=i?"Right":"Bottom",lower=name.toLowerCase();jQuery.fn["inner"+name]=function(){return this[0]?jQuery.css(this[0],lower,false,"padding"):null;};jQuery.fn["outer"+name]=function(margin){return this[0]?jQuery.css(this[0],lower,false,margin?"margin":"border"):null;};var type=name.toLowerCase();jQuery.fn[type]=function(size){return this[0]==window?document.compatMode=="CSS1Compat"&&document.documentElement["client"+name]||document.body["client"+name]:this[0]==document?Math.max(document.documentElement["client"+name],document.body["scroll"+name],document.documentElement["scroll"+name],document.body["offset"+name],document.documentElement["offset"+name]):size===undefined?(this.length?jQuery.css(this[0],type):null):this.css(type,typeof size==="string"?size:size+"px");};});})(); \ No newline at end of file diff --git a/themes/default/js/post.js b/themes/default/js/post.js new file mode 100644 index 0000000..dd1ddde --- /dev/null +++ b/themes/default/js/post.js @@ -0,0 +1,7 @@ + +$(function(){$('#comment-form p:has(input[type=submit][name=preview])').before('

      '+''+'

      ');var cookie=readCookie($.cookie('comment_info'));if(cookie!=false){$('#c_name').val(cookie[0]);$('#c_mail').val(cookie[1]);$('#c_site').val(cookie[2]);$('#c_remember').attr('checked','checked');} +$('#c_remember').click(function(){if(this.checked){setCookie();}else{dropCookie();}});$('#c_name').change(function(){if($('#c_remember').get(0).checked){setCookie();}});$('#c_mail').change(function(){if($('#c_remember').get(0).checked){setCookie();}});$('#c_site').change(function(){if($('#c_remember').get(0).checked){setCookie();}});function setCookie(){var name=$('#c_name').val();var mail=$('#c_mail').val();var site=$('#c_site').val();$.cookie('comment_info',name+'\n'+mail+'\n'+site,{expires:60,path:'/'});} +function dropCookie(){$.cookie('comment_info','',{expires:-30,path:'/'});} +function readCookie(c){if(!c){return false;} +var s=c.split('\n');if(s.length!=3){dropCookie();return false;} +return s;}}); \ No newline at end of file diff --git a/themes/default/print.css b/themes/default/print.css new file mode 100644 index 0000000..d6a8624 --- /dev/null +++ b/themes/default/print.css @@ -0,0 +1,50 @@ +/* +# -- BEGIN LICENSE BLOCK ---------------------------------- +# +# This file is part of Dotclear 2. +# +# Copyright (c) 2003-2010 Olivier Meunier and contributors +# Licensed under the GPL version 2.0 license. +# See LICENSE file or +# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# +# -- END LICENSE BLOCK ------------------------------------ +*/ +body { + font : 10pt serif; + margin: 0; + color: #000; + background: #fff; +} + +#prelude, #sidebar, .pagination, #comment-form, object { + display: none; +} + +p { + margin: 0.2em 0 0.8em 0; + line-height: 1.3em; +} + +h1,h2,h3,h4,h5, h6 { + margin: 1em 0 0.2em 0; + font-weight: bold; +} +h1 { font-size: 160%; } +h2 { font-size: 140%; } +h3 { font-size: 120%; } +h4 { font-size: 100%; } +h5 { font-size: 90%; } +h6 { font-size: 80%; } + +a { + color: #00f; + text-decoration: none; + border-bottom: 1px solid #999; +} + +.post-content a[href^="http"]:after, #comments a[href^="http"]:after, +#trackbacks a[href^="http"]:after { + content: " ("attr(href)") "; + color: #333; +} \ No newline at end of file diff --git a/themes/default/screenshot.jpg b/themes/default/screenshot.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6724ac665d17bff52fd6f2c66d5502adea5d73e8 GIT binary patch literal 16340 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%0ALJ@uojhnLJK%EV;^e7?pBQXta``*CpDnmr-J!zu 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 literal 0 HcmV?d00001 diff --git a/themes/default/smilies/arrow.png b/themes/default/smilies/arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..73570cabe411bdafd58cc8a71d0f984b9bbada4b GIT binary patch literal 600 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMf^8lX^S7YO}y-S_`UXXckX<1HA z&i|K_=FZ*r_fAAhbM^mk7kqt6e>|DAbL;m1PwU&-mb^P8bnWu_|G(e-ziwGu+5Z2- zwy8Z?mX=xnpOhuX=3F~D@9$~m|8JN6x|`A6R`&nL?MDyp{JEra`^wSu^xmE8CVYIl z_y3EoTelwn|M&C%ZJ&yYnGW`O(UH|hk6!tGM&SRWY*W+pV=JxlGOPc;p1pMGp62G} zADg4ZUl|CHtE@uqgsWV`*U{A;~Cezls; zPp`lBx;#&%<%;=b0Ss;NC$k>MqOF6sRL{pRT2<^LaLzdI!K|INJGil+ZR?yQ_$ z(cM<||HIZ9{he{K4gYSr|9@KV=92yQf=otw$N%e=|Ns5Gd!qX9Y3Bc*k62k{9$RVk z`;5T9n1YWx4J1>}plyB`B7o01^E;Q!nmjlf?>FMGaA`!0I|9VoB z0gqd9Yvig;4WV0Jr}An!y9Q>+UjO#@{^>2h|DLj(>?2fQ_d-~UT`uxi<-&*nm4I1S zI+i_}Ywqx;nt#!i%?G*D-o4){SZH!}+FY50Y0GwR&3N=8tY`O}7PB_CN2{J}ow|eN ziId3@{kWd$PT>Pq%LHEEN~^xVaMkI*5Z?SYx;SP1Im0!zC+q*$Gh5b8{r_s_|A*PD7xYZ8llpSj zL`zd;?^37y^vss#>d#lAR?lnr|LbXcRWc6`_q}V|XHM_iy0mKMgxtN`=l}n(_5XFt zn`@a0bE@Y|O!<47`Twh_|3B{jdqL*^kJ~%f_WXah=JzF?!mRx6wz9u>B6zsjzaHm) zeyQQeJa(YS|7XqrZ~M%g+Prf~;_ov8ll!Xwf4i`C&HVpw7yo}!wtD#tW8<`AE3NV~ z%bJ^;KU_`y|NE_|F!z(Yhi1;0x_5oq%t>XpHgE#%{r~yM@5{zO-xoZ4@eW7@mjw9* z|ED@&Nb9VN1R8(Y)5S4FLQ?i%XIPVi1ltAus1+(a+KbQRZ2aLkd(sN#+;oxIVyl_& z|F-w(`Q9`wB8JKHBh%8dVE-Eony&9Ro7b%l(N#IPdg{?6gNj>!Z2Q0c^C;lG#<=FV zrJ{VT$*qig@$B&DB?5++R4Od+m~`|8IL|m$uKIoYK8-@t>zno*sGsKkm|8 z^8EjsMZYf_Z`k8s)v{#a{M8$lPW=Dv^0BM)zaHnVEG(PallA{$MpJo~m1UaT!dF@8 zjXljZ^QX4|e>Ej8x^&gS;=_+$R+cnxUz-2tlFo)jP0N<;TroX!_OYdZzMOZRxBLHx zZU1h$@89paa?zZf>!<(!_2kcKW}xkA%YQW0by`_v9$RVk_kzs3LqZuTwF~w(-+Qp6 zwYBxqix+Dbb^X5|x1cZX|BG&4pYs2okNkhP=Kpoe4SNDMtXlH_$DQ+cHvE551~fr_ z@t2JBj_$Uy|F37q#WtLO`M#;TVdb(73r-%iT5@#d;>CYXa{@zb!dnx0AeB@S!Mt_j8YJkJ`+Ca)saSb@!t?+JjfkEZul;>Hl4t zN;jF)H>QYWj4?3{Oxx OW$<+Mb6Mw<&;$TE37Q)K literal 0 HcmV?d00001 diff --git a/themes/default/smilies/dizzy.png b/themes/default/smilies/dizzy.png new file mode 100644 index 0000000000000000000000000000000000000000..373ad9dc6382da89ea54aad19e2eddb20463d337 GIT binary patch literal 634 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMf{{Wv5R}+)8qYGvKUXaPnYTmo9 z<@UvG^SgsW1M^<)=K23}(%FM^T3Z(<$7a2|oZVhq{Pc)xfM?XpJFC7P=dP}ta%GL! zo;_!~+sgibJ?CT}|NpvWTx8yGvg_ITKU_^6!^;iAE`l8pq ze%kFhH*~}0y!)*u?|k`qO>-%q)!VnN=eHHK$(G3;d6{bTPqtU<;l=Ip+(PH$x7(`B zUd`<0H{nUKmCQBoFUsnUt@Ed(-0GdH@*-a5=()^?{H!eoYMZ8Ma05Na;OXk;vd$@? F2>?i)V`%^Y literal 0 HcmV?d00001 diff --git a/themes/default/smilies/eek.png b/themes/default/smilies/eek.png new file mode 100644 index 0000000000000000000000000000000000000000..d4c2926a819e2d963898f4e3fcd23341465e9f4f GIT binary patch literal 565 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMfr2wB0S5wo}qYGvKUXXcuXMb)^ z@7hIOPcQcVf4ew5DC^xJp_bl=(XTsVgQ~%zH`2TKAa=8E31)Nd-f*KTbH|6 zP6twMB|(0{|EU2OGN-v*0GfEl)5S4FLQ=IaH@GQ4z)k+6np20z#s#ALf+ZGAm@&-flTl8$sUF*#WY#V+rJ2!j6QHjShKX3FboN3u8qOkGF%CkF;`952*COYA0 zL6nIjYnbXn#>bIc<0rA%_XtkX@-t{(mDGBX`^85FnYh#I6)(hJ7CsSOTNb`_@73z= zM(<4%r!LK1{<8V`d*ibj2hwYeZl0R@$el~|Lg@ASz5AE`urz;KvTWsh{qN0he)uh4 z#5d=%X;(~d(MPop`yE}}GP<@m-n5zNy7o+Y^kl_S-96_6fc|3eboFyt=akR{0P#gb A*Z=?k literal 0 HcmV?d00001 diff --git a/themes/default/smilies/evil.png b/themes/default/smilies/evil.png new file mode 100644 index 0000000000000000000000000000000000000000..54fbd06883deadee8e067132763d24297be0b187 GIT binary patch literal 623 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMf=K!A&S7YO}y-S_`UXb~3&hq)u z!gq&+YO@`e%$c+#BdMji`v2E6fA2(WSk&~t+hhKml~a4N{=Z$Cm0G@_&9tem^Z#|r z&*z=~|9<`dY5m{R%>O6nRu-1cnV4c_nYMPx)b6&j|3B_*ShZy3^6mdW?%KXI|Ia0z z|2FLZUrkxNsO$fevj2S%3+Jz&-{sZbI`jW+pZ_mg#dt)!<(!eB|#{v;Q{S|6k8uws28T`(&WM`$`V;0I9%|Aiv=MR0a$gZ&n-x z8h*>u#W6%elJ#J>(cu6Qhl`ipCLB?gs9JTkV$0N|CN^`!hh7H4l^g#5&t9X-uws=K z1ILGw8RD+;d-9n$UTnW}CGeZhb}o)Ad%YC>UsKl>%xem`I=_4R?icyDBd1=Ky7*^F z@h*+e*69z{+c;=FTL{F(y>VA^X$`${F7GyUgUk>zFv4@^IW6+QZ*?P z_si{@ufM+hGTfk~Hz3#MpGe|nZGm63gqY&LwiGUS+$ xm7QySr6kFL;o7=YyO_^2FfrUaV$9Z1Z_25!^d|T7FQ6|OJYD@<);T3K0RWAEVblNs literal 0 HcmV?d00001 diff --git a/themes/default/smilies/exclam.png b/themes/default/smilies/exclam.png new file mode 100644 index 0000000000000000000000000000000000000000..0d85b305e175254327f08079263bb927d2e831e1 GIT binary patch literal 519 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMfmH?j+S7YO}y-S_`oZ)(OV@peO z_5ZJD-W?M9f7_?Ixq1Gqx&L4E{(8Ok&n2CyJz4*MzuCHW!T(3uG2yv$C%6Cqar@fo zmGkGU{Qr9P{|}r0-EyDRTm1iN{oe~R-EC!mPcyf-OkXmq_y2Xv|NnmO+`KX-s`mfq zBUVCZ_!V`+3va75^WX#6%QMoiykFuc!at zF8%*$@7#&C|DUx0&1`R-xn$lPpu^`?UV8+jY)XRsg8!2b7?|}bRwhBG<%0Z=Z8ox36*(7g^@}r@x@QyD z_68fzPk%VLqcTMN7*;bbt$(&`)5m-HQzEZzD{{XxWwya0Z8tBw`hA_E-#ij>eSXbb z+Yu@F<9cDv+g+XBrAMQ$lxl7W%i4diX@~GTp`e=^#0CDh79Z5@u(A5i{E$OA`G5S< R9Y7y3c)I$ztaD0e0stE^B{u*7 literal 0 HcmV?d00001 diff --git a/themes/default/smilies/idea.png b/themes/default/smilies/idea.png new file mode 100644 index 0000000000000000000000000000000000000000..dea24025f9553326d4b83762176da39d094f5e84 GIT binary patch literal 627 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMfw*a3IS7YNe=2`#tE_Ir7{r{62 z`OlxM4qWo&#>@NuJO8(x`+wtRkMi<=?+yvIG*^HAc;U|(t}{;`<*a{_bKuwKdqw}R zTmFB$bZSr5|KD#vKk5)&_&0ph`KX<*R9F1}b4lm#ortyf{&%;P{r~mo|BJ4u&1dzZ zXFYko>&d4tlh6P9dz$&@my3Td$Q*d~|Nm{D|DTV@EdHK)=)e7@|NmdjG_on;p7Z`v3oDE&p!0|9`h;&cu}e z|9*yVy&JRdzs~Cazb_mAf0VuXA=m*gCq-?$3$*&wtN(IK{{p?vYFWq&q=HI<{DS{e z8!)WZf6!Hg&(%%d(XDyYK(> zk2XvVt5z{JFi7QeJu>7Iad3!Tf7N=IwD?k{rd{VBo|3pM*D_b6Wr6t}ITNwf8Y`b3 z-y8LMODK6Hrgx?6*_8hr2D!)$a}oZQp(}z`y+WW#iAEzkR)#{r_3Z)TtZ(oZ-55YFS)# zX=Q%a*Ec7p_GDcv3+N-j`?N|G((^eMSIiZ(MA{|IbI}Oia0Ua`yjU zPk;{i|M&Bc+ZmNb71u5v0ebYs+4IUk%BLjAFZe(80K>fACue}>p7nHb43P*o?avfG z=)lu71v=w8Qx)Dp(>Qg(af#Q+jCGQRieLidb|M#0Y6H^WzypS53{QuqRYe##o z?ezb9Ct_+(*0pO7{@rqqi*5LPuRlM3;{P9ay4%XGT|D*YlFs=}UVksh{C_iV)~rp} z4%J+{u>bFA=KueG{{MXB+R54fpS7eW)&96>eQc%G?=u3o&o0Q#?*4z<`~SDg&CSiH z_D+q9F8z9(`~Tn1%O-{-$L9V2u*PN1wT^DwLy~ww^ z@s8?|B{%N$8LCWgtY*{A*08D+v$(#xN@2=pdCMsppRO*yPz>}9gQu&X%Q~loCIJ6n BORN9@ literal 0 HcmV?d00001 diff --git a/themes/default/smilies/mrgreen.png b/themes/default/smilies/mrgreen.png new file mode 100644 index 0000000000000000000000000000000000000000..d8fe18a51d95f917ffa5d0ccf719e27cb7abad9b GIT binary patch literal 568 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMf?Es$;R}<4TuDM)`m+YE%V_ryX zwfA=KYu6s6w5Ciyuwd=69n3SCbyn)6Wp!sC&c6Ka@{#99nwy*LYC_)pc$2rRy61HN z!Gjkp*H{A;6iw`~2~A#oZ*_c9TUk??>l}aUUhAKKf3|O!y7TlAnZ+_o4{s2fCX}7m z|K!V)v#-y7{`GmzrFq^VC3aK14xBwDFjrvWuGvd(FAYzujo2NL)si)5|FW$o_j6C@ zHePMqa<1jh$2&(}9GN+56VU3Sbv0cVy4<(AyGP`0d$bK`V|8P-`+@+c9;c?QJ$uid z$jzGw^xxyu*-L?xXGxG>@P8@+1|E+2p+G|qd%8G=NQArgpA>5{;9&@6x!BRAVRJNA z@O!L4ZQlC4pa1nY>9Rk+GShi7gJ-~^IF_Kui{F<=FPp@X(c(8_ieH@$x4^w!!jh-@ zOB+ufIOG}3KY62Fw0vYcLw8@Y>Eufl#;0Q*JG8t^`uI}*)8W6bY7IBA&SUfs{@x+=l4ZN?>L-=C7teh4u>w(7aFCfl*qH6}M|#l55Zdw&Y~M&A`m w%-OP+(d|&^0zZX5-nf_wsg4~db62|9Ka^IU;oe#MALtzhPgg&ebxsLQ0OaZ|?f?J) literal 0 HcmV?d00001 diff --git a/themes/default/smilies/normal.png b/themes/default/smilies/normal.png new file mode 100644 index 0000000000000000000000000000000000000000..d8d7832d9c704db0fa5c2fa6a811791f2b1fbaa0 GIT binary patch literal 522 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMf_5hy{S7YO}y-S_`oZ-55cK!bs zz5l*Hb@=Fgn=_kzr|b36W?X1;cy@Y?ao|F2vA|M&CQN~_;z z1g@Rk^8eM8|KBcuJ^ndL$nU@|^3$ z=;S`@x$f$lnQx%Br+unx@;=U1<*O|J StEK=w#Ng@b=d#Wzp$PzIlPTK( literal 0 HcmV?d00001 diff --git a/themes/default/smilies/question.png b/themes/default/smilies/question.png new file mode 100644 index 0000000000000000000000000000000000000000..700d399299e4444e1d5850313a83825971e8f99e GIT binary patch literal 580 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMfjR2nzS7YO}y-S_`UXXcrf7$;x z^YXK6=g*)2_1)#acOuUpS=Q2A9T%DR|Ksj=hlGx9uK54s&Xk_q)Wov?*Ddc}+428r z{r`7s&YwB;_cZhWzn{N8UAlJ7?kh(oB*qj^?3w!Kl1@`i>&k`G{yog;Xs!7F_00AS zOaK3VJF7oEIjQa6E${y?djEge^!tp!=cgO5om%SRoOfWE{r|U1D~s!w%$xuB%f;5# z)|jZ;|DTV1ImUBzTigF%Pm>et|KD@i-s_jD5GEXzw`egAJ6pQp#t4*7?fL79!-4sx!M z-@aF!{p+h-z!0J8S;Wn)r!Ct*fsxJi;`{gd9kUk*KilG(w|)QNo9Z70ZG|Gde;T~L zD=>S~*6HWA?#q7k;78N{%G*niM0EtRdp`<`&|k7?;qgz!(Ol7+?=0M^Uc#>Z!STV7 R#X#>dc)I$ztaD0e0sxOWQM~{F literal 0 HcmV?d00001 diff --git a/themes/default/smilies/razz.png b/themes/default/smilies/razz.png new file mode 100644 index 0000000000000000000000000000000000000000..bb74936c02d102b025bac1601250a7bfa59cf895 GIT binary patch literal 601 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMf^8lX^*U0day-S_`UXb~Jas7W& zrvLL=|G%8{|LfV7=IZ~qQ~qbG{6AXp?vT*`k8l5PU;6)G-2V^Tl9Ss0U$>mvllA{u z%l`=_|F3NR@5=M{H1q$rOaK44)7@6~|6a}i0^9$mCjI~Y=Ks0Haj^}5F6sQgH34M8 zqwN1@L;k-xl95vT|F+M6FR9;W1pfc~`Tz93xaiVjE3N+9@%&%f|NqUr|KBb*H#h&i z6Y;;u^#94WugAInA5Hpq%YDwol>aZf{!gv?f8*SLSCKzwxcV!SNJe_c|8s|ce!ZjFdk{$ZmIV0)|ED5gxSS=}05tfDr;B5VM7U}H z>q!S41l-s+Dk+t9zTh;wQKVTuQ6M>7O;cO%^S|?p)2F--pC24stLVg*5~AASV&@}d z|HNw{!?dcEyZ5TjG-0W%3w$)0Pf4?)>gTKFd6`Zt&W1M~xbXR1ZF%%8oxk_bxH!fh z*A%JxfB&~vyW?z!M;Y&BBuqGJdba*JAEmQqbJ)7meIKsH=KEcJrEGR+kK_Zfs@})T zLg#FA<0;ZmSZr@SC#grGzohi#fo;}Xi%z5!@LbUsOzFA$SwK-+F-*-a`&r48=>ksn duNqwx=Xpiw%wuwrE(iLL!PC{xWt~$(695-SU8Mj3 literal 0 HcmV?d00001 diff --git a/themes/default/smilies/redface.png b/themes/default/smilies/redface.png new file mode 100644 index 0000000000000000000000000000000000000000..c7040b8c86dc2aa33d7fb22da6438c2677eca4b7 GIT binary patch literal 492 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMf(g2?jS7YO}fAebR)Rq1}yXRe1 zP;z4X|2I$n@0kC$J+7_3=KtMGzZ=5-AKU!@_lLO9s{b3O?X6AwUFAEqzWo2~bN|17 z`hRHc?@4*x4b{of4S$z)uAMUf|Min!s{%4oJO6)r_kaJYmWI0jPw)IcyCp8V>Hn3Z z8S#z(-@p35XX&5*%>NIr0&V&K=XYdy!~d7_u*yd=mk_&-^IK_GH&H_(Xvo-U3d65+c2uZ5Zv1l$aJ&S>1-BjQ-`(#coz zn!&#Ri?reGb^^toU(Vr2XTdxm66}4n6fZl%$9a3tkuw8b5HMn z`8C<{EgK*EC}^Ml+`94Iw#8RP7B7gpKk>5DH@5?g4JjQznwDJkIxvsny+MWF&Xa2O z&Py_*YW&sj@yu5#+u@qTp?E^@iN=CuQ$C$ih`!o3-_9qw&BsMLV#ftnN8Lr5jIA<9 pY>q{kos0gS-yNwR_59EmX07jX&Eh}f`hi|y@O1TaS?83{1OQ8c5jOw; literal 0 HcmV?d00001 diff --git a/themes/default/smilies/rolleyes.png b/themes/default/smilies/rolleyes.png new file mode 100644 index 0000000000000000000000000000000000000000..c71f0f9a4cd6fac85edbba03534c33fde042ecbf GIT binary patch literal 595 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMf^8lX^R}+)8y-S_`UXZzeb!%>B z-P-w;|KBc+4vxCNP5j;E?C!R*)R@?hcP89B6!riA|F6fn|K5rCf8DaBxqAEdlm9>N zo;Yz$dRm){bN;mh`S)&~{Qsov*h;J1tmdGg+NnKRc`0!ppB?;jhRfbA_xB~8wM!=d z|FHGlA))`TrvAU}vuDrQ|6k9&dwS&mv*z5?EGx^j?Tg~x-J4gKmA`gz&;NI8A_5a% z?&kS;qYUVb_opoXo@W04F#G>a$L8kd|DO-enzcDMtrd5diHJ*(k5?;_jP%omAU0^C0TzdyM`KP1^#dcu*tI==P%%vrpb zE-M$5{9@e_>nWiAShc`1j%oKgmev(K4f_}c_*ma9el>&fm#pytZ;cB-b+m$I#HVV? zDQ!FOC7-2d+qTB-&pVz!sM)w<--*9p{wbWR%4xi7^Zjq+t22)$?@r5DcwnaQa?eR` z?kqUl*1Dr8VE5mD95MbADnyUJPmlcmwSB3m%FYbP0l+XkKbQVxV literal 0 HcmV?d00001 diff --git a/themes/default/smilies/sad.png b/themes/default/smilies/sad.png new file mode 100644 index 0000000000000000000000000000000000000000..de83faf717d9003117c3ca588cda6c8ec2f459cf GIT binary patch literal 590 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMfy#SvOS7YO}y-S_`oZZbCnITKSnJ@Wos()s^p(e|bJ|9{-+>0Z2S+0J)|gg!r7 zSXo#$wI}QUqwLC(=Kt3%tt`{B(i=M)YyN*dvvSd#xaiWgOQ!z4AoKs#lnslTR!q!({;Wgc5;_4|y#{};U(DYebb&1)BR{r`OA@12Nc zi`Tc-)-C9Z^Yg9vecAZ`yEXrRJ=w5o$=BoD|6kAk|D^2SEq9>yjP#D~wzB`v9Ww;>l<(-suX;YdR*Ccrs>Yrd_Zb%S$V#)A7 YWvljI5x%rnKo2r_y85}Sb4q9e0NHX-1^@s6 literal 0 HcmV?d00001 diff --git a/themes/default/smilies/smile.png b/themes/default/smilies/smile.png new file mode 100644 index 0000000000000000000000000000000000000000..c67937d30fe8cf140565705a7c5629617ccfa2e0 GIT binary patch literal 555 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMf$pD`aS7YO}y-S_`UXXcoX+}m$ z?f+NP{(n8Qc2P%5bM@al5kdah?+yw5eZOmJPuBn6Z~kAmEGcL@zpvx})B3pR(nrVR z|DI<4|90vBA9uRj%Km>oGJkU2*@N?~EYtp6(kaO)`2VCVGQ8yfhpqqr{rrF1r?oQc z|BK$_q_*E@1dgq=dimgRMtaBpH}n2~yL@(QLUVKT|3}$D0VQ9LbI+NW^8fGWf4AIU zp3nOKtR*hC;m;Ya|L@lP|MdiD(fp|$=Z|l(vda8@*%;`yhKeenZ)9za&jBgtk|4j} z{}clT$0U~bK;zDNx;TbNgsb-7EIMSs<9c+`gx0oDGtH$YJk?H42Y9!&n*l9z4>kMl z`Mk$u(t#TbdROyAOqm)~sWDfn(Mf%l_{yxcjE~OV?d(~brM+a|d-++v|LR{mv6ykq zq$htKwBDcpbhnw>!7a-e?axlR&Jn|)b&mVd!c*nhjrk4tIO}vabJq0dxX*|?e%QzG zy)oDBLeJbZ(=A%4hj9e6Y=Mg&gU0KY#xA=>Cn$+{C$ax4t~?>gJmB=;p5fuV!|)l|8@M08}}7^14SSvi?6Q z|98v%<%7f5cKZLlAoKFZoZPI|A6I?<|9TqWSN!)h^N)+x|34p@)nAnuSN-VTrT@R* zE?Kb3!Xoq7N~_;z1Rh&XLH#h(PaogLgbaGG6&Yh>f9_Rl5DEs$i6ZTg?NXpiW=&ss^Yonm&sqv|YyaQ&`TO_p!Udav zq49g#&Z9sotR%=U_&+TGgO_j4O`r`|JY5_^BqU`Ia+@DYU|@T&{e0@8FrJ;y6I$N# zcAwb3ahs){Y|*p7|La{}S1#bvp4F@}t8kwDRvuI4&N>5*N56dM1q!+Rzx#Png)z_k zTPs;+KH%TcKfm$mN=Ysm{<29btK`*Ib9>L!E)Zh5`2FhbyQj}*yxPqD?Bh4*O;!L4-hoVAa)t})qosaQ8fZGYTyozs3hUTjWNOqzopr0JUCsi2wiq literal 0 HcmV?d00001 diff --git a/themes/default/smilies/wink.png b/themes/default/smilies/wink.png new file mode 100644 index 0000000000000000000000000000000000000000..684c84b444602ec1aa2b128352f4f76e24874f2c GIT binary patch literal 546 zcmV+-0^R+IP)!|JzLe+DGZwn*Y~1`_nW0(k%VZ9Ouny z{LBjb%n<#{1K`D9^~Vd*z=`g{63@3_#;H23rk$;%l&zwQy`@5-m42O*hn$gQm5geO zhIWI4gNcEBgoAs4b!u#EY;9A|?m` z0004WQchCmQCv^Y-0KZ8@K~xwS1;M>e!$1&)(eKWTosCI| zpaCfbTBXPXQ1JdO1+J;A6o{V+6oO)Gb~#4?WPkwx0h!|u)-7!SfNW+S&7#|8z{m$G z0QGa)K>+nZk0?v8zJHEspR(S&o1N5qQ$vx#xbo|X?*`)`07cJrxTdWlGfe}*p=TI_pl4^5x~C8 k5N#?w2mtPk07*qoM6N<$f@f0#>Hq)$ literal 0 HcmV?d00001 diff --git a/themes/default/style.css b/themes/default/style.css new file mode 100644 index 0000000..1f27a36 --- /dev/null +++ b/themes/default/style.css @@ -0,0 +1,576 @@ +/* +# -- BEGIN LICENSE BLOCK ---------------------------------- +# +# This file is part of Dotclear 2. +# +# Copyright (c) 2003-2010 Olivier Meunier and contributors +# Licensed under the GPL version 2.0 license. +# See LICENSE file or +# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# +# -- END LICENSE BLOCK ------------------------------------ +*/ +body { + margin: 0; + padding: 0; + background: #e0e0e0 url(img/body-bg.png) repeat-x top; + color: #6b6b6b; + font: 62.5% "Lucida Grande",Arial,sans-serif; +} + +a { + color: #279ac4; + text-decoration: none; +} +a:hover, a:active, a:focus { + color:#6d8824; + text-decoration: underline; +} + +a img { + border: none; +} + +pre { + white-space: pre; + white-space: -moz-pre-wrap; + white-space: -hp-pre-wrap; + white-space: -o-pre-wrap; + white-space: -pre-wrap; + white-space: pre-wrap; + white-space: pre-line; + word-wrap: break-word; +} + +sup { + font-size:80%; + line-height:50%; +} + +.left { + float: left; +} + +.right { + float: right; +} + +/* Layout +-------------------------------------------------------- */ +#page { + font-size: 1.2em; +} + +#top { + position: relative; + height: 180px; + width: 800px; + padding: 0; + margin: 50px auto 0 auto; + background: transparent url(img/page-t.png) no-repeat bottom left; +} +#top h1 { + position: absolute; + top: 25px; + width: 100%; + margin: 0; + text-align: center; + font-size: 3.5em; +} +#top h1 a { + color: #9ac528; + text-decoration: none; +} + +#prelude { + position: absolute; + top: 7px; + right: 7px; + margin: 0; + padding: 0; + color: #ededed; +} +#prelude a { + color: #ededed; +} +#prelude a:focus, #prelude a:hover { + background: yellow; + color: red; + text-decoration: none; +} + +#wrapper { + width: 800px; + overflow: hidden; + margin: 0 auto 0 auto; + padding: 20px 0; + background: #fff url(img/page-bg.png) repeat-y top left; +} + +#main { + width: 550px; + float: left; +} + +#content { + padding: 0 25px; +} + +#sidebar { + width: 250px; + float: right; +} +#blognav, #blogextra { + padding: 1px 25px; +} + +#footer { + clear: both; + padding: 30px 0 0 0; + background: transparent url(img/page-b.png) no-repeat top center; +} +#footer p { + margin: 0 auto; + padding: 10px 0 20px; + background: #e0e0e0; + color: #9ac528; + text-align: center; + font-size: 1.2em; +} +#footer p a { + color: #6d8824; +} + + +/* Sidebar styles +-------------------------------------------------------- */ +#sidebar h2 { + margin: 0; + color: #8fb22f; +} +#sidebar h3 { + margin: 1em 0 0.5em; + color: #279ac4; +} + +#sidebar div div { + margin-bottom: 2em; +} +#sidebar div div div { + margin-bottom: 0; +} + +#sidebar ul { + list-style: none; + margin: 1em 0; + padding: 0; + border-top: 1px solid #ffd02c; +} +#sidebar li { + display: block; + margin: 0; + padding: 4px 0; + border-bottom: 1px solid #FFD02C; +} +#sidebar li a { + color: #6B6B6B; + text-decoration: none; +} +#sidebar li a:hover, #sidebar li a:focus, #sidebar li a:active { + color: #9ac528; +} +#sidebar ul ul { + list-style: disc; + margin: 0; + padding: 0 0 0 15px; + border: none; +} +#sidebar li li { + display: list-item; + margin: 0.5em 0 0 0; + padding: 0 0; + border: none; +} + + +#search fieldset { + border: none; + margin: 0; + padding: 0; +} +#q { + border: 1px solid #bfbfbf; + width: 150px; + color: #6b6b6b; +} +#search .submit { + padding: 0; + border: 1px solid #fff; + background: none; + font-weight: bold; + color: #6b6b6b; + text-transform: uppercase; +} +#search .submit:hover { + background: #9ac528; + color: #fff; + border: 1px solid #9ac528; +} + +#topnav ul { + border-bottom: 1px solid #ffd02c; + padding: 4px 0; +} +#topnav li { + display: inline; + border-bottom: none; +} + +#sidebar .syndicate ul { + border-top: none; +} +#sidebar .syndicate li { + border-bottom: none; +} + +#sidebar .categories ul { + list-style: disc; + margin: 0; + padding: 0 0 0 15px; + border: none; +} +#sidebar .categories li { + display: list-item; + margin: 0.5em 0 0 0; + padding: 0 0; + border: none; +} +#sidebar .categories li.category-current { + font-weight: bold; +} +#sidebar .categories li.category-current li { + font-weight: normal; +} + +#sidebar .tags ul { + border-top: none; + font-size: 1.1em; + text-align: justify; +} +#sidebar .tags ul li { + display: inline; + background: none; + margin: 0; + padding: 0; + border: none; + line-height: 1.8em; +} + +.tag0 { font-size: 75%; } +.tag10 { font-size: 80%; } +.tag20 { font-size: 90%; } +.tag30 { font-size: 100%; } +.tag40 { font-size: 110%; } +.tag50 { font-size: 120%; } +.tag60 { font-size: 140%; } +.tag70 { font-size: 150%; } +.tag80 { font-size: 160%; } +.tag90 { font-size: 170%; } +.tag100 { font-size: 180%; } + +ul.tags { + list-style: none; + margin: 1em 0; + padding: 0; + font-size: 1.3em; + text-align: justify; +} +ul.tags li { + display: inline; + margin: 0; + padding: 0; + line-height: 1.8em; +} + + +/* Main content styles +-------------------------------------------------------- */ +h2, h3, h4 { + margin: 1em 0 0 0; + padding: 0; +} + +h2 { + font-size: 1.4em; +} +h3 { + font-size: 1.2em; +} +h4 { + font-size: 1em; +} + +#subcategories { + background: #fbfbfb; + border-color: #BFBFBF; + border-style: solid; + border-width: 1px 0; + margin: 1em 0; + padding: 0.5em; +} +#subcategories h3 { + margin: 0; +} +#subcategories ul { + margin: 0.5em 0 0 0; + padding: 0 0 0 20px; + line-height: 1.4; +} + +.day-date { + font-size: 1em; + margin: 0 0 0.5em; + text-align: right; + color: #279ac4; +} + +.post { + margin: 0 0 2em 0; +} +.post-title { + color:#9ac528; + font-size:1.7em; +} +.post-title a { + color:#9ac528; +} +.post-info { + margin: 0 0 0 0; +} + +.post-tags { + list-style: none; + margin: 1em 0 1em; + padding: 3px 0; +} +.post-tags li { + display: inline; + margin-right: 8px; + padding: 5px 0 5px 22px; + background: transparent url(img/tag.png) no-repeat 0 70%; +} +.post-tags li a { + color: #6b6b6b; +} + +.post-info-co { + clear: left; + padding: 3px 0 3px 0.5em; + border-width: 1px 0; + border-style: solid; + border-color: #bfbfbf; + background: #fbfbfb; +} +.post-info-co a { + color: #2b2b2b; + padding: 2px 10px 2px 18px; +} + +.comment_count { + background: transparent url(img/comment.png) no-repeat 0 50%; +} +.ping_count { + background: transparent url(img/trackback.png) no-repeat 0 50%; +} +.attach_count { + background: transparent url(img/attach.png) no-repeat 0 50%; +} + +.read-it { + font-weight: bold; + clear: left; +} + +a.feed { + background: transparent url(img/feed.png) no-repeat 0 0.25em; + padding: 5px 0 5px 22px; +} + +/* Post content +-------------------------------------------------------- */ +.post-content, .post-excerpt, #comments dd, #pings dd, dd.comment-preview { + line-height:1.4em; +} +.post-content acronym, .post-excerpt acronym { + cursor: help; + border-bottom: 1px dotted #666; +} + +.post-content pre, .post-excerpt pre { + padding: 10px ; + font: 1.1em 'courier new', courier, monospace; +} + +.post-content ul, .post-excerpt ul, .post-content ol, .post-excerpt ol { + margin: 0 0 0.5em 0; + padding: 0 0 0 15px; +} + +.post-content li, .post-excerpt li { + margin: 0; + padding: 0; +} + +.post-content blockquote, .post-excerpt blockquote { + margin: 4px 0 4px 0; + padding: 0 5px; + border-left: 4px solid #bfbfbf; +} + + +#attachments h3 { + font-size: 1.2em; +} + +#attachments ul { + list-style: none; + margin: 0; + padding: 4px 0; +} + +#attachments li { + margin: 0 0 0.6em; + padding: 2px 10px 2px 18px; + background: transparent url(img/attach.png) no-repeat 0 50%; +} + +#attachments li object { + display: inline; + margin: 0; + padding: 0; + vertical-align: bottom; +} + +/* Comments and trackbacks +-------------------------------------------------------- */ +#comments { + clear: both; +} +#comments h3, #comment-form h3, #pings h3 { + border-width: 1px 0; + border-style: solid; + border-color: #bfbfbf; + background: #fbfbfb; + padding: 5px; + margin: 20px 0 8px 0; + font-size: 1.2em; +} + +#comments dt { + margin: 1.5em 0 0 0; + padding: 5px 0 16px 0; + background: transparent url(img/comment-t.png) no-repeat bottom left; +} +#comments dt.me { + background-image: url(img/commentmy-t.png); +} +#comments a.comment-number { + display: block; + float: left; + width: 30px; + margin-right: 40px; + font-size: 1.2em; +} +#comments dd { + margin: 0; + padding: 1px 1em 0.5em 1em; + background: #fffad1 url(img/comment-b.png) no-repeat bottom left; + color:#6b6b6b; +} +#comments dd.me { + background-color:#f5f9d9; + color:#6b6b6b; + background-image:url(img/commentmy-b.png); +} +#comments dd p { + margin: 0.5em 0; + line-height: 1.5em; +} + +.error { + margin: 20px 0 0; + padding: 10px 5px; + background: #ffcccc; + border: 2px solid red; + font-weight: bold; +} + +/* Forms +-------------------------------------------------------- */ +#comment-form { + padding-top: 10px; +} + +#comment-form fieldset { + border: none; +} +#comment-form fieldset p { + padding: 5px 0; +} +#comment-form fieldset p.field { + padding: 5px 0; + width: auto; + margin: 0; + clear: left; +} +#comment-form p.form-help { + width: 60%; + margin: 0 0 0 30%; + font-style: italic; +} + +#comment-form p label { + width: auto; +} +#comment-form p.field label { + font-weight: bold; + display: block; + padding: 0 1% 0 0; + width: 29%; + float: left; + text-align: right; +} +#comment-form input, #comment-form textarea { + font: 1em "Lucida Grande",Arial,sans-serif; + color: #279ac4; + border: 1px solid #cdcdcd; + padding: 1px 2px; + width: 68%; +} + +#comment-form p.remember { + margin: 0; +} +#comment-form input#c_remember { + width: auto; + border: 0; + margin: 0 5px 0 30%; +} +#comment-form input.preview { + margin-left: 30%; +} + +#comment-form input.preview, #comment-form input.submit { + width: auto; + color: #279ac4; + background: #fff; + font-size: 1em; + font-weight: bold; + text-transform: uppercase; + border: 1px solid #fff; +} +#comment-form input.preview:hover, #comment-form input.submit:hover { + background: #6d8824; + color: #fff; + border: 1px solid #6d8824; +} diff --git a/themes/default/tpl/.htaccess b/themes/default/tpl/.htaccess new file mode 100644 index 0000000..3a42882 --- /dev/null +++ b/themes/default/tpl/.htaccess @@ -0,0 +1 @@ +Deny from all diff --git a/themes/default/tpl/404.html b/themes/default/tpl/404.html new file mode 100644 index 0000000..7dbf306 --- /dev/null +++ b/themes/default/tpl/404.html @@ -0,0 +1,63 @@ + + + + + + + + {{tpl:lang Document not found}} - {{tpl:BlogName encode_html="1"}} + + + + + + + + + + + + + + + + {{tpl:include src="_head.html"}} + + + +
      +{{tpl:include src="_top.html"}} + +
      + +
      +
      + +
      +

      {{tpl:lang Document not found}}

      +
      + +
      +

      {{tpl:lang The document you are looking for does not exist.}}

      +
      + +
      +
      + + + +
      + +{{tpl:include src="_footer.html"}} +
      + + \ No newline at end of file diff --git a/themes/default/tpl/_flv_player.html b/themes/default/tpl/_flv_player.html new file mode 100644 index 0000000..bb34328 --- /dev/null +++ b/themes/default/tpl/_flv_player.html @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/themes/default/tpl/_footer.html b/themes/default/tpl/_footer.html new file mode 100644 index 0000000..fac8db1 --- /dev/null +++ b/themes/default/tpl/_footer.html @@ -0,0 +1,5 @@ + + +{{tpl:SysBehavior behavior="publicFooterContent"}} \ No newline at end of file diff --git a/themes/default/tpl/_head.html b/themes/default/tpl/_head.html new file mode 100644 index 0000000..a79816f --- /dev/null +++ b/themes/default/tpl/_head.html @@ -0,0 +1,12 @@ + + + + + + +{{tpl:include src="user_head.html"}} +{{tpl:SysBehavior behavior="publicHeadContent"}} \ No newline at end of file diff --git a/themes/default/tpl/_mp3_player.html b/themes/default/tpl/_mp3_player.html new file mode 100644 index 0000000..df9fda9 --- /dev/null +++ b/themes/default/tpl/_mp3_player.html @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/themes/default/tpl/_top.html b/themes/default/tpl/_top.html new file mode 100644 index 0000000..829edae --- /dev/null +++ b/themes/default/tpl/_top.html @@ -0,0 +1,10 @@ +
      + +

      {{tpl:lang To content}} | +{{tpl:lang To menu}} | +{{tpl:lang To search}}

      \ No newline at end of file diff --git a/themes/default/tpl/archive.html b/themes/default/tpl/archive.html new file mode 100644 index 0000000..0df0406 --- /dev/null +++ b/themes/default/tpl/archive.html @@ -0,0 +1,80 @@ + + + + + + + + {{tpl:lang Archives}} - {{tpl:BlogName encode_html="1"}} + + + + + + + + + + + + + + + + + + + + + + {{tpl:include src="_head.html"}} + + + +
      +{{tpl:include src="_top.html"}} + +
      + +
      +
      + +
      +

      {{tpl:lang Archives}}

      +
      + +
      + + +

      {{tpl:ArchiveDate format="%Y"}}

      + + +
      +
      + +
      +
      + + + +
      + +{{tpl:include src="_footer.html"}} +
      + + \ No newline at end of file diff --git a/themes/default/tpl/archive_month.html b/themes/default/tpl/archive_month.html new file mode 100644 index 0000000..b7a3102 --- /dev/null +++ b/themes/default/tpl/archive_month.html @@ -0,0 +1,97 @@ + + + + + + + + {{tpl:lang Archives}} - {{tpl:ArchiveDate}} - {{tpl:BlogName encode_html="1"}} + + + + + + + + + + + + + + + + + + + + + + + + + + {{tpl:include src="_head.html"}} + + + +
      +{{tpl:include src="_top.html"}} + +
      + +
      +
      + + + +
      +

      {{tpl:ArchiveDate}}

      +
      + +
      + + +

      {{tpl:EntryDate}}

      + +

      {{tpl:EntryTitle encode_html="1"}}

      + + +
      +
      +
      +
      + + + +
      + +{{tpl:include src="_footer.html"}} +
      + + \ No newline at end of file diff --git a/themes/default/tpl/category.html b/themes/default/tpl/category.html new file mode 100644 index 0000000..e0fa4b8 --- /dev/null +++ b/themes/default/tpl/category.html @@ -0,0 +1,168 @@ + + + + + + + + {{tpl:CategoryTitle encode_html="1"}} - {{tpl:BlogName encode_html="1"}}<tpl:PaginationIf start="0"> - {{tpl:lang page}} {{tpl:PaginationCurrent}}</tpl:PaginationIf> + + + + + + + - {{tpl:lang page}} {{tpl:PaginationCurrent}}" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {{tpl:include src="_head.html"}} + + + +
      +{{tpl:include src="_top.html"}} + +
      + +
      +
      + +
      +

      {{tpl:CategoryTitle encode_html="1"}} + {{tpl:CategoryTitle encode_html="1"}}

      + {{tpl:CategoryDescription}} + + +

      {{tpl:lang Entries feed}} + + + - {{tpl:lang Comments feed}} + +

      +
      +
      + + + +
      +

      {{tpl:lang Subcategories}}

      + +
      + +
      + + +
      + +

      {{tpl:EntryDate}}

      + +

      {{tpl:EntryTitle encode_html="1"}}

      + + + + + + + + + {{tpl:SysBehavior behavior="publicEntryBeforeContent"}} + + + +
      {{tpl:EntryExcerpt}}
      +

      {{tpl:lang Continue + reading}}...

      +
      + + + +
      {{tpl:EntryContent}}
      +
      + + + {{tpl:SysBehavior behavior="publicEntryAfterContent"}} + + + + + +
      + + + +

      - + {{tpl:lang page}} {{tpl:PaginationCurrent}} {{tpl:lang of}} {{tpl:PaginationCounter}} + -

      +
      +
      +
      +
      +
      + + + +
      + +{{tpl:include src="_footer.html"}} +
      + + \ No newline at end of file diff --git a/themes/default/tpl/home.html b/themes/default/tpl/home.html new file mode 100644 index 0000000..5258d07 --- /dev/null +++ b/themes/default/tpl/home.html @@ -0,0 +1,145 @@ + + + + + + + + {{tpl:BlogName encode_html="1"}}<tpl:PaginationIf start="0"> - {{tpl:lang page}} {{tpl:PaginationCurrent}}</tpl:PaginationIf> + + + + + + + - {{tpl:lang page}} {{tpl:PaginationCurrent}}" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {{tpl:include src="_head.html"}} + + + +
      +{{tpl:include src="_top.html"}} + +
      + +
      +
      + +
      + +

      {{tpl:EntryDate}}

      + +

      {{tpl:EntryTitle encode_html="1"}}

      + + + + + + + + + {{tpl:SysBehavior behavior="publicEntryBeforeContent"}} + + + +
      {{tpl:EntryExcerpt}}
      +

      {{tpl:lang Continue + reading}}...

      +
      + + + +
      {{tpl:EntryContent}}
      +
      + + + {{tpl:SysBehavior behavior="publicEntryAfterContent"}} + + + + + +
      + + + +

      - + {{tpl:lang page}} {{tpl:PaginationCurrent}} {{tpl:lang of}} {{tpl:PaginationCounter}} + -

      +
      +
      +
      +
      +
      + + + +
      + +{{tpl:include src="_footer.html"}} +
      + + \ No newline at end of file diff --git a/themes/default/tpl/post.html b/themes/default/tpl/post.html new file mode 100644 index 0000000..e4d5219 --- /dev/null +++ b/themes/default/tpl/post.html @@ -0,0 +1,277 @@ + + + + + + + + {{tpl:EntryTitle encode_html="1"}} - {{tpl:BlogName encode_html="1"}} + + + + + + + + + + + + + + + + + + + + + + + + + + {{tpl:include src="_head.html"}} + + + + + + +
      +{{tpl:EntryPingData}} + +{{tpl:include src="_top.html"}} + +
      + +
      +
      + + + +
      +

      {{tpl:EntryTitle encode_html="1"}}

      + + + + + + + + + {{tpl:SysBehavior behavior="publicEntryBeforeContent"}} + + + +
      {{tpl:EntryExcerpt}}
      +
      + +
      {{tpl:EntryContent}}
      + + + {{tpl:SysBehavior behavior="publicEntryAfterContent"}} +
      + + + + +
      +

      {{tpl:lang Attachments}}

      +
        + +
      • + + {{tpl:include src="_mp3_player.html"/}} - + + + {{tpl:include src="_flv_player.html"/}} + + + {{tpl:AttachmentTitle}} + +
      • + +
      +
      + +
      + + + + + +
      +

      {{tpl:lang Comments}}

      +
      + +
      {{tpl:CommentOrderNumber}}. + {{tpl:lang On}} {{tpl:CommentDate}}, {{tpl:CommentTime}} + {{tpl:lang by}} {{tpl:CommentAuthorLink}}
      + +
      + + {{tpl:SysBehavior behavior="publicCommentBeforeContent"}} + + {{tpl:CommentContent}} + + + {{tpl:SysBehavior behavior="publicCommentAfterContent"}} +
      + +
      +
      + +
      +
      + + + +

      {{tpl:SysFormError}}

      +
      + + +

      {{tpl:lang Your comment has been published.}}

      +
      + + +

      {{tpl:lang Your comment has been submitted and + will be reviewed for publication.}}

      +
      + + +
      + +
      +

      {{tpl:lang Your comment}}

      +
      +
      {{tpl:CommentPreviewContent}}
      +
      +

      +
      +
      + +

      {{tpl:lang Add a comment}}

      +
      + + {{tpl:SysBehavior behavior="publicCommentFormBeforeContent"}} + +

      + +

      + +

      + +

      + +

      + +

      + +

      + +

      + +

      +

      {{tpl:lang HTML code is displayed as text and web addresses are + automatically converted.}}

      + + + {{tpl:SysBehavior behavior="publicCommentFormAfterContent"}} +
      + +
      +

      +

      +
      +
      +
      + + + +
      +

      {{tpl:lang They posted on the same topic}}

      + + +
      + +
      {{tpl:PingOrderNumber}}. + {{tpl:lang On}} {{tpl:PingDate}}, {{tpl:PingTime}} + {{tpl:lang by}} {{tpl:PingBlogName encode_html="1"}}
      + +
      + + {{tpl:SysBehavior behavior="publicPingBeforeContent"}} + +

      {{tpl:PingTitle encode_html="1"}}

      + {{tpl:PingContent}} + + + {{tpl:SysBehavior behavior="publicPingAfterContent"}} +
      + +
      + +
      +
      +
      + + +

      {{tpl:lang Trackback URL}} : {{tpl:EntryPingLink}}

      +
      + + +

      {{tpl:lang This post's comments feed}}

      +
      +
      +
      + + + +
      + +{{tpl:include src="_footer.html"}} +
      + + diff --git a/themes/default/tpl/search.html b/themes/default/tpl/search.html new file mode 100644 index 0000000..f18058c --- /dev/null +++ b/themes/default/tpl/search.html @@ -0,0 +1,153 @@ + + + + + + + + {{tpl:lang Search}} - {{tpl:SysSearchString encode_html="1"}} - {{tpl:BlogName encode_html="1"}}<tpl:PaginationIf start="0"> - {{tpl:lang page}} {{tpl:PaginationCurrent}}</tpl:PaginationIf> + + + + + + - {{tpl:lang page}} {{tpl:PaginationCurrent}}" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {{tpl:include src="_head.html"}} + + + +
      +{{tpl:include src="_top.html"}} + +
      + +
      +
      + +
      +

      {{tpl:lang Search}}

      + +

      {{tpl:SysSearchString encode_html="1" string="Your search for %1$s returned no result."}}

      +
      + +

      {{tpl:SysSearchString encode_html="1" string="Your search for %1$s returned %2$s result."}}

      +
      + +

      {{tpl:SysSearchString encode_html="1" string="Your search for %1$s returned %2$s results."}}

      +
      +
      + + +
      + +

      {{tpl:EntryDate}}

      + +

      {{tpl:EntryTitle encode_html="1"}}

      + + + + + + + + + {{tpl:SysBehavior behavior="publicEntryBeforeContent"}} + + + +
      {{tpl:EntryExcerpt}}
      +

      {{tpl:lang Continue + reading}}...

      +
      + + + +
      {{tpl:EntryContent}}
      +
      + + + {{tpl:SysBehavior behavior="publicEntryAfterContent"}} + + + + + +
      + + + +

      - + {{tpl:lang page}} {{tpl:PaginationCurrent}} {{tpl:lang of}} {{tpl:PaginationCounter}} + -

      +
      +
      +
      +
      +
      + + + +
      + +{{tpl:include src="_footer.html"}} +
      + + \ No newline at end of file diff --git a/themes/default/tpl/tag.html b/themes/default/tpl/tag.html new file mode 100644 index 0000000..40d8955 --- /dev/null +++ b/themes/default/tpl/tag.html @@ -0,0 +1,154 @@ + + + + + + + + {{tpl:lang Tag}} - {{tpl:TagID}} - {{tpl:BlogName encode_html="1"}}<tpl:PaginationIf start="0"> - {{tpl:lang page}} {{tpl:PaginationCurrent}}</tpl:PaginationIf> + + + + + + - {{tpl:lang page}} {{tpl:PaginationCurrent}}" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {{tpl:include src="_head.html"}} + + + +
      +{{tpl:include src="_top.html"}} + +
      + +
      +
      + +
      +

      {{tpl:lang Tag}} - {{tpl:TagID}}

      + +

      {{tpl:lang Entries feed}} + + + - {{tpl:lang Comments feed}} + +

      +
      + + +
      + +

      {{tpl:EntryDate}}

      + +

      {{tpl:EntryTitle encode_html="1"}}

      + + + + + + + + + {{tpl:SysBehavior behavior="publicEntryBeforeContent"}} + + + +
      {{tpl:EntryExcerpt}}
      +

      {{tpl:lang Continue + reading}}...

      +
      + + + +
      {{tpl:EntryContent}}
      +
      + + + {{tpl:SysBehavior behavior="publicEntryAfterContent"}} + + + + + +
      + + + +

      - + {{tpl:lang page}} {{tpl:PaginationCurrent}} {{tpl:lang of}} {{tpl:PaginationCounter}} + -

      +
      +
      +
      +
      +
      + + + +
      + +{{tpl:include src="_footer.html"}} +
      + + \ No newline at end of file diff --git a/themes/default/tpl/tags.html b/themes/default/tpl/tags.html new file mode 100644 index 0000000..a6323c3 --- /dev/null +++ b/themes/default/tpl/tags.html @@ -0,0 +1,70 @@ + + + + + + + + {{tpl:lang Tags}} - {{tpl:BlogName encode_html="1"}} + + + + + + + + + + + + + + + + + + + {{tpl:include src="_head.html"}} + + + +
      +{{tpl:include src="_top.html"}} + +
      + +
      +
      + +
      +

      {{tpl:lang Tags}}

      +
      + +
      + +
      + +
      +
      + + + +
      + +{{tpl:include src="_footer.html"}} +
      + + \ No newline at end of file diff --git a/themes/default/tpl/user_head.html b/themes/default/tpl/user_head.html new file mode 100644 index 0000000..4b380d4 --- /dev/null +++ b/themes/default/tpl/user_head.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v2/dotclear/CHANGELOG b/v2/dotclear/CHANGELOG new file mode 100644 index 0000000..4c0e362 --- /dev/null +++ b/v2/dotclear/CHANGELOG @@ -0,0 +1,385 @@ +Dotclear 2.4.4 - 2012-08-13 +=========================================================== +* Bugfix: Programmed entries works again. +* Compatibility fix: widgets are now fully php >=5.3 compliant +* Security fix: potential CSRF in user management +* has_tag now part of dotclear core, moved from tag plugin. +* empty title fixed on rss reader widget + + +Dotclear 2.4.3 - 2012-05-18 +=========================================================== +* Admin: My favorites menu can be hidden +* Admin: Fix wordpress importer +* Admin: about:config and user:pref tables are now more readable +* Ductile theme: Blog logo can be changed +* New lithuanian language (thanks to Paulius Černakauskas) +* Various bug fixes + +Dotclear 2.4.2 - 2012-02-11 +=========================================================== +* Security fix release +* 4 XSS vulnerabilities fixed, discovered by High-Tech Bridge + +Dotclear 2.4.1.2 - 2011-12-24 +=========================================================== +* Happy Christmas! +* Security: fixed one SQL injection vulnerability in Clearbricks, thanks to Adjaya +* New behaviour: publicGetURLFor +* New behaviour: publicRegisterURL +* New behaviour: templatePrepareParams +* Changed the way to get artefacts URLs, through $core->url->getURLFor calls, instead of $core->url->getBase() +* new/updated parameter sql_only in $core->blog->getPosts and $core->blog->getComments + +Dotclear 2.4.0 - 2011-11-13 +=========================================================== +* Admin: new iconset from Thomas Daveluy +* Admin: Accessibility enhancements +* Added a custom widget sidebar +* Added a new theme (Ductile) +* Added a new plugin (simpleMenu) +* handling of postgres non default schemas (db_prefix = 'schema.prefix') +* New iconset mechanism +* New behaviour: coreBlogBeforeGetPosts +* Security fix: Spam comments feed now checks for blog permission. Thanks to Romuald Brunet. +* Various bug fixes + +Dotclear 2.3.1 - 2011-06-14 +=========================================================== +* Updated makefile for cleaner distrib. +* Better localization handling for prefs and shortcuts. +* Misc JS & CSS cleaning. +* Import/Export preferences-related bugfix. +* Administrative mail address is now configurable. +* Security: one minor fix and changes for two potential problems. Thanks to Jeremie Boutoille + +Dotclear 2.3.0 - 2011-05-16 +=========================================================== +* Admin: Major backend redesign +* Admin: Customizable Dashboard +* Admin: New Favourites admin submenu +* Admin: New user preferences backend +* Admin: Accessibility enhancements +* Admin: Inline help extended +* Templates: Default theme templates moved to inc/public/default-templates +* Clearbricks: External libraries relocated to inc/libs +* Clearbricks: fixed utf-8 and mysql strict mode problems +* Added a safe mode connection, disabling all plugins +* Mysqli support (config.php may need to be updated manually) +* Fixed dcLog bug with pgsql +* Fixed comment/trackbacks counters reset. +* Several other bug fixes + + +Dotclear 2.2.3 - 2011-04-01 +=========================================================== +* Security fix in media manager. Thx to Raphaël +* Bugfix : 2.2.2 was preventing manual thumbnail regeneration. +* Database handling bugfixes + +Dotclear 2.2.2 - 2011-01-17 +=========================================================== +* Bugfix: 2.2.1 was blocking new installations +* Autoupdate procedure should now be "bad ftp client configuration"-proof. +* Several other small bugfixes + +Dotclear 2.2.1 - 2011-01-15 +=========================================================== +* ExternalMedia is not part of the core distribution anymore +* New attribute to tpl:SysIf: blog_id +* New behaviour: adminMediaItemForm +* Several bugfixes +* Several code optimizations +* Several typos corrected +* Security fix in Clearbricks. Thx to François Pierre-Doray for pointing it out. + +Dotclear 2.2 - 2010-07-01 +=========================================================== +* New installation wizard. +* Several new behaviours: + - adminCommentHeaders + - adminCommentsActionsCombo + - adminCommentsActions + - adminCommentsActionsContent + - adminBeforeCommentDelete + - adminPostsActionsHeaders + - adminUsersActionsCombo + - coreBeforeCategoryCreate & coreAfterCategoryCreate + - coreBeforeCategoryUpdate & coreAfterCategoryUpdate + - coreBeforeLogCreate & coreAfterLogCreate + - coreBeforePostCreate & coreAfterPostCreate + - coreBeforePostUpdate & coreAfterPostUpdate + - coreMediaConstruct + - templateCustomSortByAlias + - urlHandlerGetArgsDocument +* New methods for several core classes. +* Metadata integration to the core. +* Error handlers can now be extended. +* Templates: blocks can now be recursive. +* Templates: Entries & Comments tags can now be sorted. +* Templates: The template subsystem is quicker, linier, and ready to be extended. +* Complete reworking of the settings system +* Correct handling of postgresql non default schemas. +* Admin: Autocompletion and further enhancing to tags handling. +* Admin: Accessibility & ergonomic tweaks. +* Admin: Administrator tag in users list. +* Comment cookies are now specific to the blog rather than to the domain. +* Password changes can now be mandatory. +* jQuery updated to 1.4.2. +* And way too many bugfixes and typos squashes to be listed. + + +Dotclear 2.1.7 - 2010-05-25 +=========================================================== +* Auto-update procedure fix + +Dotclear 2.1.6 - 2009-10-01 +=========================================================== +* Install procedure fixes +* Admin: Page managers can now create pages +* Admin: several typos corrected. +* Admin: Widgets now work in IE8. +* Admin: Password protected posts can now be previewed. +* Templates: tpl:Meta* are now tpl:Tags*. +* Templates: now display all posts. +* new behavior: adminPageHTMLHead +* DB schema: new blog_id field in log table +* Media manager: Pubic folder can now be set on a different host. +* WordPress import fixes +* Dailymotion insertion fix +* Upgrade procedure: CRLF removed in files that were bugging the upgrade. +* JQuery updated to 1.3 +* IE7-js update +* security: Full Path Disclosure protection. Thx to Karim Ayad for pointing it out. +* and way too many bugfixes to be listed. + +Dotclear 2.1.5 - 2009-02-05 +=========================================================== +* Security release +* Youtube insertion update + +Dotclear 2.1.4 - 2008-12-21 +=========================================================== +* Security flaw fix +* WordPress import refining +* XML-RPC improvements + +Dotclear 2.1.3 - 2008-11-19 +=========================================================== +* Admin: New upgrade procedure +* Admin: Fixed video insertion bug +* Template: New attributes + * url on EntryIf + * only_category on Blogroll + * no_context on Pagination +* Template: New tag + * BlogID +* Admin: escaped blog_id on authentication page + +Dotclear 2.1.1 - 2008-11-07 +=========================================================== +* Admin: Automatic Update bug fixes +* Admin: Disable Automatic Update if no digests file +* Admin: Javascript fixes in authentication page +* Admin: Fixed errors with categories select boxes +* Template: Added level attribute in tpl:Categories +* Media: Added H.264/MPEG-4 AVC for mp4 files + +Dotclear 2.1 - 2008-11-01 +=========================================================== +* Subcategories +* Admin: Automatic Update +* Admin: Flash 10 support for uploader +* Admin: mailto link in comment details +* Admin: Embedded video size selection +* Admin: Restrict session cookie path to admin +* Media: H.264/MPEG-4 AVC (HD) support with m4v files +* Inherited themes +* WordPress XML-RPC methods support +* True unicode URLs +* Plugin: Widgets as template tags +* Plugin: Filters in entries widgets and Blogroll +* Plugin: Added vimeo.com in external media +* Template: New tags + * LoopPosition + * CommentAuthorDomain + * CommentAuthorMD5 + * EntryFirstImage + * EntryCategoryShortURL + * CategoryIf + * CategoryFirstChildren + * CategoryParents + * EntryCategoriesBreadcrum + * MediaURL + +Dotclear 2.0.2 - 2008-09-05 +=========================================================== +* New installation procedure +* Plugin: WordPress import fixes +* Plugin: Plain text export as downloadable files +* Plugin: Message about URLs in Dotclear 1.2 import +* Public: Display a message if search returns no result +* Admin: Fixed some CSS bugs +* Admin: Batch select/unselect entries +* Admin: In a media item, find entries containing it + +Dotclear 2.0.1 - 2008-08-16 +=========================================================== +* Plugin: Fixed a bug with Dotclear 1.2 URLs import. +* Plugin: Fixed a l10n bug in Pages +* Admin: Enhanced plugins resources loading and cache + +Dotclear 2.0 - 2008-08-01 +=========================================================== +* Public: Atom becomes the default feed format. RSS 2 is always available. +* Admin: design enhancements and new Dotclear logo +* Admin: entries preview in blog context +* L10N: New language manager with zip files support +* Plugin: Import/Export plugin version 2.0 with import from Dotclear 1.2 and WordPress +* Plugin: Pages enhancements (preview, sorting) +* Plugin: support for jamendo and deezer in External Media +* JSMin on JavaScript files instead of JS packing +* SQLite 3 only support (PDO based) +* Many bug fixes and major performances improvements + +Dotclear 2.0 RC2 - 2008-06-21 +=========================================================== +* FairTrackback spam filter +* Language pack infrastructure +* Bug fix on comment search with author "0" +* Javascript fixes +* dcAuth::sessionExists and dcAuth::checkSession new methods +* Right management in dcAuth::sudo +* Media File sorting options in media manager +* CandyUpload, new uploader tool based on SWFUpload +* New search engine robots options +* New image options +* L10N: Japanese and Portugues (Brazil) language packs +* Many bug fixes and enhancements + +Dotclear 2.0 RC1 - 2008-05-01 +=========================================================== +* New: Pages plugin +* New: Theme editor plugin +* Entries: Text and WYSIWYG enhancements +* Entries: Markup validator +* Entries: Insertion of links to other entries from toolbar +* Entries: External media insertion (dailymotion, youtube, google video) +* Tags: Same list for new and existing entries +* Tags: Tags can be removed on all associated entries +* Tags: Tags can be removed on a post selection +* Admin: Ask password for user management tasks, theme upload and plugin upload +* Admin: New contextual help viewer +* Media manager: Recreate thumbnails option +* Media manager: Custom medium thumbnail size (per blog) +* Media manager: Zip files extract support +* Media manager: Zip file download of directory +* Media manager: File exclusion pattern option +* Themes and plugins: Zip as new package format +* Themes and plugins: Upload +* Themes and plugins: Upgrade within administration interface +* Themes and plugins: Deletion +* Public: New default theme: Blowup (fully customizable) +* Public: Changed the way commenter cookie is handled +* Themes: Template files moved to tpl/ directory +* L10N: Polish, Catalan and Spanish translations +* Misc: jQuery upgraded to 1.2.3 +* Misc: Crushed png files +* Fixed many bugs + +Dotclear 2.0 beta 7 - 2007-07-12 +=========================================================== +* New way to display comments and trackbacks on entries in backend +* Dashboard visual improvements +* Default cache dir created by installation process +* Option to limit posts and comments in feeds +* Introduced UDBS for installation and upgrade +* Changed handling of XML-RPC URLs +* New option to force HTTPS redirect if wanted +* Enforced cookies security (directory and ssl support) +* Added Plugin auto-install and auto-upgrade support +* Added trackbacks ttl and moderation preferences +* Added an Internal search engine +* FLV support in backend with Neolao player +* Added nice messages if database is broken or Dotclear not installed +* upgrade jQuery to 1.1.3 +* Fixed many bugs +* Fixed security issues in backend + +Dotclear 2.0 beta 6 - 2007-02-19 +=========================================================== +* New antispam plugin, with a set of filters (rbl, ipblacklist, spamwords, akismet) +* New admin dashboard page +* Fixed unwanted logout bug +* Added settings to disable template caching and allow PHP code +* Blog preferences panel bug fix +* New XML-RPC Client and Server +* Comment posting permissions bug fix + +Dotclear 2.0 beta 5.4 - 2007-01-19 +=========================================================== +* Minor change on spam display in comments.php +* Command line upgrade script and fix in load_plugin_file.php +* Make akismet configurable only by superadmin with DC_AKISMET_SUPER +* SQL optimisations +* New comments view in post + +Dotclear 2.0 beta 5.2 - 2007-01-11 +=========================================================== +* Fixed a bug with imageMeta::getMeta +* Enhanced dynamic file uploader +* Move clearbricks files to their own repository +* Fixed a bug with auto_br in wikiSimpleComment +* Support for language restriction in feeds +* Default theme structure changes +* Fixed a PHP 5.0 compatibility issue +* Installation Wizard + +Dotclear 2.0 beta 4 - 2006-12-26 +=========================================================== +* Performances enhancements. +* Administration UI enhancements. +* More user-friendly Widgets (version 1.5). +* Switch to jQuery . +* Added jQuery in default theme. +* Major changes in HTTP client and Feed Parser based on a + generic socket handler. +* PHP 5.2 compatibility. +* Code documentation (all core and most of clearbricks). +* Many bug fixes. + +Dotclear 2.0 beta 3 - 2006-11-05 +=========================================================== +* Disallow special wrappers for fopen like functions. +* XML/RPC improvements. +* Read IPTC and EXIF metadata in uploaded pictures. +* MySQL 4.1 support only. +* Metadata import from Dotclear 1.2.x. +* Akismet plugin. +* Pings plugin. +* Added a priority setting for plugins. +* Many bug fixes. + +Dotclear 2.0 beta 2 - 2006-08-09 +=========================================================== +* DC_PLUGIN_ROOT can handle more than one path. +* OPML/XBEL import in blogroll plugin. +* Fixed a security issue in html::absoluteURLs(). +* Fixed issues with timezone on scheduled entries. +* Multiple categories selection in tpl:Entries. +* Improved dbLayer. +* Changed category feed URL. +* Feeds for tags (entries and comments). +* Added attachments count on backend and frontend. +* New settings code design. Can now handle wide system settings. +* Memory usage improvements with autoloader. +* Some code cleanup. +* Feed parser improvements. +* Themes can be configured if needed. +* XMP support on JPEG files. +* Media manager improvements. +* Spamplemousse now uses DNSBL (and the guy who left the bug was fired). +* Javascript editor and toolbar improvements. +* RDS support (XML/RPC API discovery). +* Added a theme with user stylesheet. +* Plugins manager diff --git a/v2/dotclear/CREDITS b/v2/dotclear/CREDITS new file mode 100644 index 0000000..76b9172 --- /dev/null +++ b/v2/dotclear/CREDITS @@ -0,0 +1,46 @@ +This is a credits file of people that have contributed to the Dotclear project. + +Dotclear Team +------------- + +Thomas Bouron +Anne Cavalier +Noé Cendrier +Benoit Clerc +Grégory Corvisier +Florent Cotton +Philippe Hénaff +Bruno Hondelatte +Olivier Meunier +Franck Paul +Michel Pelletier +Xavier Plantefève +Jean-Michel Royer +Anne Sophie Tranchet +Alain Vagner + +Dotclear Translators +-------------------- + +Benjamin Bank +Alain Béarez +Claire Cambier +Luis Correia +Andreas Diller +Alain Fagot +Sabrina Favier +Charles Hebert +Guillaume Jonquiere +Dennis S. L. Jørgensen +Miguel A. Muñoz +Sebestyén Muráncsik +Nnidŷu +Polo +Aina Chabert Ramon +Adnan Shameem +Enrique Matias Sanchez +Jan Skrasek +Takafumi +Regina Timbó + +... and all contributors. \ No newline at end of file diff --git a/v2/dotclear/LICENSE b/v2/dotclear/LICENSE new file mode 100644 index 0000000..d511905 --- /dev/null +++ b/v2/dotclear/LICENSE @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 Lesser 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 + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/v2/dotclear/README b/v2/dotclear/README new file mode 100644 index 0000000..ed0c4c4 --- /dev/null +++ b/v2/dotclear/README @@ -0,0 +1,22 @@ +Welcome to Dotclear + +WHAT YOU NEED TO RUN DOTCLEAR +----------------------------- +In order to run Dotclear you need: + + * A web server (Apache, Cheerokee, lightHttpd, etc.) + * PHP 5.2 with the following modules: + * mbstring + * iconv + * simplexml + * mysql, postgresql or sqlite + * A database server (MySQL or PostgreSQL) or SQLite. + + +INSTALLATION +------------ +Copy inc/config.php.in to inc/config.php and fill in the fields with appropriate +values. + +If you intend to use MySQL or PostgreSQL, you'll have to create a database +first. With SQLite, db/ folder will have to be writable by your web server. \ No newline at end of file diff --git a/v2/dotclear/admin/auth.php b/v2/dotclear/admin/auth.php new file mode 100644 index 0000000..414914c --- /dev/null +++ b/v2/dotclear/admin/auth.php @@ -0,0 +1,431 @@ +auth->allowPassChange() && isset($_POST['new_pwd']) && isset($_POST['new_pwd_c']) && isset($_POST['login_data']); +$login_data = !empty($_POST['login_data']) ? html::escapeHTML($_POST['login_data']) : null; +$recover = $core->auth->allowPassChange() && !empty($_REQUEST['recover']); +$safe_mode = !empty($_REQUEST['safe_mode']); +$akey = $core->auth->allowPassChange() && !empty($_GET['akey']) ? $_GET['akey'] : null; +$user_id = $user_pwd = $user_key = $user_email = null; +$err = $msg = null; + +# Auto upgrade +if (empty($_GET) && empty($_POST)) { + require dirname(__FILE__).'/../inc/dbschema/upgrade.php'; + try { + if (($changes = dotclearUpgrade($core)) !== false) { + $msg = __('Dotclear has been upgraded.').''; + } + } catch (Exception $e) { + $err = $e->getMessage(); + } +} + +# If we have POST login informations, go throug auth process +if (!empty($_POST['user_id']) && !empty($_POST['user_pwd'])) +{ + $user_id = !empty($_POST['user_id']) ? $_POST['user_id'] : null; + $user_pwd = !empty($_POST['user_pwd']) ? $_POST['user_pwd'] : null; +} +# If we have COOKIE login informations, go throug auth process +elseif (isset($_COOKIE['dc_admin']) && strlen($_COOKIE['dc_admin']) == 104) +{ + # If we have a remember cookie, go through auth process with user_key + $user_id = substr($_COOKIE['dc_admin'],40); + $user_id = @unpack('a32',@pack('H*',$user_id)); + if (is_array($user_id)) + { + $user_id = $user_id[1]; + $user_key = substr($_COOKIE['dc_admin'],0,40); + $user_pwd = null; + } + else + { + $user_id = null; + } +} + +# Recover password +if ($recover && !empty($_POST['user_id']) && !empty($_POST['user_email'])) +{ + $user_id = !empty($_POST['user_id']) ? $_POST['user_id'] : null; + $user_email = !empty($_POST['user_email']) ? $_POST['user_email'] : ''; + try + { + $recover_key = $core->auth->setRecoverKey($user_id,$user_email); + + $subject = mail::B64Header('DotClear '.__('Password reset')); + $message = + __('Someone has requested to reset the password for the following site and username.')."\n\n". + $page_url."\n".__('Username:').' '.$user_id."\n\n". + __('To reset your password visit the following address, otherwise just ignore this email and nothing will happen.')."\n". + $page_url.'?akey='.$recover_key; + + $headers[] = 'From: '.(defined('DC_ADMIN_MAILFROM') && DC_ADMIN_MAILFROM ? DC_ADMIN_MAILFROM : 'dotclear@local'); + $headers[] = 'Content-Type: text/plain; charset=UTF-8;'; + + mail::sendMail($user_email,$subject,$message,$headers); + $msg = sprintf(__('The e-mail was sent successfully to %s.'),$user_email); + } + catch (Exception $e) + { + $err = $e->getMessage(); + } +} +# Send new password +elseif ($akey) +{ + try + { + $recover_res = $core->auth->recoverUserPassword($akey); + + $subject = mb_encode_mimeheader('DotClear '.__('Your new password'),'UTF-8','B'); + $message = + __('Username:').' '.$recover_res['user_id']."\n". + __('Password:').' '.$recover_res['new_pass']."\n\n". + preg_replace('/\?(.*)$/','',$page_url); + + $headers[] = 'From: dotclear@'.$_SERVER['HTTP_HOST']; + $headers[] = 'Content-Type: text/plain; charset=UTF-8;'; + + mail::sendMail($recover_res['user_email'],$subject,$message,$headers); + $msg = __('Your new password is in your mailbox.'); + } + catch (Exception $e) + { + $err = $e->getMessage(); + } +} +# Change password and retry to log +elseif ($change_pwd) +{ + try + { + $tmp_data = explode('/',$_POST['login_data']); + if (count($tmp_data) != 3) { + throw new Exception(); + } + $data = array( + 'user_id'=>base64_decode($tmp_data[0]), + 'cookie_admin'=>$tmp_data[1], + 'user_remember'=>$tmp_data[2]=='1' + ); + if ($data['user_id'] === false) { + throw new Exception(); + } + + # Check login informations + $check_user = false; + if (isset($data['cookie_admin']) && strlen($data['cookie_admin']) == 104) + { + $user_id = substr($data['cookie_admin'],40); + $user_id = @unpack('a32',@pack('H*',$user_id)); + if (is_array($user_id)) + { + $user_id = $user_id[1]; + $user_key = substr($data['cookie_admin'],0,40); + $check_user = $core->auth->checkUser($user_id,null,$user_key) === true; + } + } + + if (!$core->auth->allowPassChange() || !$check_user) { + $change_pwd = false; + throw new Exception(); + } + + if ($_POST['new_pwd'] != $_POST['new_pwd_c']) { + throw new Exception(__("Passwords don't match")); + } + + if ($core->auth->checkUser($user_id,$_POST['new_pwd']) === true) { + throw new Exception(__("You didn't change your password.")); + } + + $cur = $core->con->openCursor($core->prefix.'user'); + $cur->user_change_pwd = 0; + $cur->user_pwd = $_POST['new_pwd']; + $core->updUser($core->auth->userID(),$cur); + + $core->session->start(); + $_SESSION['sess_user_id'] = $user_id; + $_SESSION['sess_browser_uid'] = http::browserUID(DC_MASTER_KEY); + + if ($data['user_remember']) + { + setcookie('dc_admin',$data['cookie_admin'],strtotime('+15 days'),'','',DC_ADMIN_SSL); + } + + http::redirect('index.php'); + } + catch (Exception $e) + { + $err = $e->getMessage(); + } +} +# Try to log +elseif ($user_id !== null && ($user_pwd !== null || $user_key !== null)) +{ + # We check the user + $check_user = $core->auth->checkUser($user_id,$user_pwd,$user_key) === true; + + $cookie_admin = http::browserUID(DC_MASTER_KEY.$user_id. + crypt::hmac(DC_MASTER_KEY,$user_pwd)).bin2hex(pack('a32',$user_id)); + + if ($check_user && $core->auth->mustChangePassword()) + { + $login_data = join('/',array( + base64_encode($user_id), + $cookie_admin, + empty($_POST['user_remember'])?'0':'1' + )); + + if (!$core->auth->allowPassChange()) { + $err = __('You have to change your password before you can login.'); + } else { + $err = __('In order to login, you have to change your password now.'); + $change_pwd = true; + } + } + elseif ($check_user && !empty($_POST['safe_mode']) && !$core->auth->isSuperAdmin()) + { + $err = __('Safe Mode can only be used for super administrators.'); + } + elseif ($check_user) + { + $core->session->start(); + $_SESSION['sess_user_id'] = $user_id; + $_SESSION['sess_browser_uid'] = http::browserUID(DC_MASTER_KEY); + + if (!empty($_POST['blog'])) { + $_SESSION['sess_blog_id'] = $_POST['blog']; + } + + if (!empty($_POST['safe_mode']) && $core->auth->isSuperAdmin()) { + $_SESSION['sess_safe_mode'] = true; + } + + if (!empty($_POST['user_remember'])) { + setcookie('dc_admin',$cookie_admin,strtotime('+15 days'),'','',DC_ADMIN_SSL); + } + + http::redirect('index.php'); + } + else + { + if (isset($_COOKIE['dc_admin'])) { + unset($_COOKIE['dc_admin']); + setcookie('dc_admin',false,-600,'','',DC_ADMIN_SSL); + } + $err = __('Wrong username or password'); + } +} + +if (isset($_GET['user'])) { + $user_id = $_GET['user']; +} + +header('Content-Type: text/html; charset=UTF-8'); +?> + + + + + + + + + + <?php echo html::escapeHTML(DC_VENDOR_NAME); ?> + + + + + + callBehavior('loginPageHTMLHead'); + ?> + + + + + + +
      +

      + +'.$err.'
      +

      {{tpl:BlogName encode_html="1"}}

      + + + {{tpl:SysBehavior behavior="publicTopAfterContent"}} +
      '; +} +if ($msg) { + echo '

      '.$msg.'

      '; +} + +if ($akey) +{ + echo '

      '.__('Back to login screen').'

      '; +} +elseif ($recover) +{ + echo + '
      '.__('Request a new password').''. + '

      '. + form::field(array('user_id','user_id'),20,32,html::escapeHTML($user_id)).'

      '. + + '

      '. + form::field(array('user_email','user_email'),20,255,html::escapeHTML($user_email)).'

      '. + + '

      '. + form::hidden(array('recover'),1).'

      '. + '
      '. + + ''; +} +elseif ($change_pwd) +{ + echo + '
      '.__('Change your password').''. + '

      '. + form::password(array('new_pwd','new_pwd'),20,255).'

      '. + + '

      '. + form::password(array('new_pwd_c','new_pwd_c'),20,255).'

      '. + ''. + + '

      '. + form::hidden('login_data',$login_data).'

      '; +} +else +{ + if (is_callable(array($core->auth,'authForm'))) + { + echo $core->auth->authForm($user_id); + } + else + { + if ($safe_mode) { + echo '
      '; + echo ''.__('Safe mode login').''; + echo + '

      '. + __('This mode allows you to login without activating any of your plugins. This may be useful to solve compatibility problems').' 
      '. + __('Disable or delete any plugin suspected to cause trouble, then log out and log back in normally.'). + '

      '; + } + else { + echo '
      '; + } + + echo + '

      '. + form::field(array('user_id','user_id'),20,32,html::escapeHTML($user_id)).'

      '. + + '

      '. + form::password(array('user_pwd','user_pwd'),20,255).'

      '. + + '

      '. + form::checkbox(array('user_remember','user_remember'),1). + '

      '. + + '

      '; + + if (!empty($_REQUEST['blog'])) { + echo form::hidden('blog',html::escapeHTML($_REQUEST['blog'])); + } + if($safe_mode) { + echo + form::hidden('safe_mode',1). + '
      '; + } + else { + echo '

      yKtcF!)YEB*&Eu&jyD*x7R!7g%?Hjl+vcaE^L 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

      '; + } + echo + ''; + + echo '
      '; + + if ($safe_mode) { + echo + '

      '.__('Get back to normal authentication').'

      '; + } else { + echo '

      '.__('Connection issue?').'

      '; + if ($core->auth->allowPassChange()) { + echo '

      '.__('I forgot my password').'

      '; + } + echo '

      '.__('I want to log in in safe mode').'

      '; + } + + echo '
      '; + } +} +?> + + + diff --git a/v2/dotclear/admin/blog.php b/v2/dotclear/admin/blog.php new file mode 100644 index 0000000..fc01915 --- /dev/null +++ b/v2/dotclear/admin/blog.php @@ -0,0 +1,96 @@ +con->openCursor($core->prefix.'blog'); + $blog_id = $cur->blog_id = $_POST['blog_id']; + $blog_url = $cur->blog_url = $_POST['blog_url']; + $blog_name = $cur->blog_name = $_POST['blog_name']; + $blog_desc = $cur->blog_desc = $_POST['blog_desc']; + + try + { + # --BEHAVIOR-- adminBeforeBlogCreate + $core->callBehavior('adminBeforeBlogCreate',$cur,$blog_id); + + $core->addBlog($cur); + + # Default settings and override some + $core->blogDefaults($cur->blog_id); + $blog_settings = new dcSettings($core,$cur->blog_id); + $blog_settings->addNamespace('system'); + $blog_settings->system->put('lang',$core->auth->getInfo('user_lang')); + $blog_settings->system->put('blog_timezone',$core->auth->getInfo('user_tz')); + + if (substr($blog_url,-1) == '?') { + $blog_settings->system->put('url_scan','query_string'); + } else { + $blog_settings->system->put('url_scan','path_info'); + } + + # --BEHAVIOR-- adminAfterBlogCreate + $core->callBehavior('adminAfterBlogCreate',$cur,$blog_id,$blog_settings); + + http::redirect('blog.php?id='.$cur->blog_id.'&add=1'); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} + +if (!empty($_REQUEST['id'])) +{ + $edit_blog_mode = true; + include dirname(__FILE__).'/blog_pref.php'; +} +else +{ + dcPage::open(__('New blog'),dcPage::jsConfirmClose('blog-form')); + + echo + '

      '.__('Blogs').''.__('New blog').'

      '. + + '
      '. + + $core->formNonce(). + '

      '. + '

      '.__('At least 2 characters using letters, numbers or symbols.').'

      '. + '

      '.__('Please note that changing your blog ID may require changes in your public index.php file.').'

      '. + + '

      '. + + '

      '. + + '

      '. + form::textarea('blog_desc',60,5,html::escapeHTML($blog_desc)).'

      '. + + '

      '. + '
      '; + + dcPage::close(); +} +?> \ No newline at end of file diff --git a/v2/dotclear/admin/blog_del.php b/v2/dotclear/admin/blog_del.php new file mode 100644 index 0000000..e0d31fe --- /dev/null +++ b/v2/dotclear/admin/blog_del.php @@ -0,0 +1,73 @@ +getBlog($_POST['blog_id']); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } + + if ($rs->isEmpty()) { + $core->error->add(__('No such blog ID')); + } else { + $blog_id = $rs->blog_id; + $blog_name = $rs->blog_name; + } +} + +# Delete the blog +if (!$core->error->flag() && $blog_id && !empty($_POST['del'])) +{ + if (!$core->auth->checkPassword(crypt::hmac(DC_MASTER_KEY,$_POST['pwd']))) { + $core->error->add(__('Password verification failed')); + } else { + try { + $core->delBlog($blog_id); + http::redirect('blogs.php?del=1'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } + } +} + +dcPage::open('Delete a blog'); + +if (!$core->error->flag()) +{ + echo + '

      '.__('Delete a blog').'

      '. + '

      '.__('Warning').'

      '. + '

      '.sprintf(__('You are about to delete the blog %s. Every entry, comment and category will be deleted.'), + ''.$blog_id.' ('.$blog_name.')').'

      '. + '

      '.__('Please give your password to confirm the blog deletion.').'

      '; + + echo + '
      '. + '
      '.$core->formNonce().'
      '. + '

      '. + '

      '. + form::hidden('blog_id',$blog_id).'

      '. + '
      '; +} + +dcPage::close(); +?> \ No newline at end of file diff --git a/v2/dotclear/admin/blog_pref.php b/v2/dotclear/admin/blog_pref.php new file mode 100644 index 0000000..e8e900a --- /dev/null +++ b/v2/dotclear/admin/blog_pref.php @@ -0,0 +1,553 @@ +blog->id; + $blog_status = $core->blog->status; + $blog_name = $core->blog->name; + $blog_desc = $core->blog->desc; + $blog_settings = $core->blog->settings; + $blog_url = $core->blog->url; + + $action = 'blog_pref.php'; + $redir = 'blog_pref.php?upd=1'; +} +else +{ + dcPage::checkSuper(); + try + { + if (empty($_REQUEST['id'])) { + throw new Exception(__('No given blog id.')); + } + $rs = $core->getBlog($_REQUEST['id']); + + if (!$rs) { + throw new Exception(__('No such blog.')); + } + + $blog_id = $rs->blog_id; + $blog_status = $rs->blog_status; + $blog_name = $rs->blog_name; + $blog_desc = $rs->blog_desc; + $blog_settings = new dcSettings($core,$blog_id); + $blog_url = $rs->blog_url ; + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } + + $action = 'blog.php'; + $redir = 'blog.php?id=%s&upd=1'; +} + +# Language codes +$langs = l10n::getISOcodes(1,1); +foreach ($langs as $k => $v) { + $lang_avail = $v == 'en' || is_dir(DC_L10N_ROOT.'/'.$v); + $lang_combo[] = new formSelectOption($k,$v,$lang_avail ? 'avail10n' : ''); +} + +# Status combo +foreach ($core->getAllBlogStatus() as $k => $v) { + $status_combo[$v] = (string) $k; +} + +# URL scan modes +$url_scan_combo = array( + 'PATH_INFO' => 'path_info', + 'QUERY_STRING' => 'query_string' +); + +# Post URL combo +$post_url_combo = array( + __('year/month/day/title') => '{y}/{m}/{d}/{t}', + __('year/month/title') => '{y}/{m}/{t}', + __('year/title') => '{y}/{t}', + __('title') => '{t}' +); +if (!in_array($blog_settings->system->post_url_format,$post_url_combo)) { + $post_url_combo[html::escapeHTML($blog_settings->system->post_url_format)] = html::escapeHTML($blog_settings->system->post_url_format); +} + +# Image title combo +$img_title_combo = array( + __('Title') => 'Title ;; separator(, )', + __('Title, Date') => 'Title ;; Date(%b %Y) ;; separator(, )', + __('Title, Country, Date') => 'Title ;; Country ;; Date(%b %Y) ;; separator(, )', + __('Title, City, Country, Date') => 'Title ;; City ;; Country ;; Date(%b %Y) ;; separator(, )', +); +if (!in_array($blog_settings->system->media_img_title_pattern,$img_title_combo)) { + $img_title_combo[html::escapeHTML($blog_settings->system->media_img_title_pattern)] = html::escapeHTML($blog_settings->system->media_img_title_pattern); +} + +# Robots policy options +$robots_policy_options = array( + 'INDEX,FOLLOW' => __("I would like search engines and archivers to index and archive my blog's content."), + 'INDEX,FOLLOW,NOARCHIVE' => __("I would like search engines and archivers to index but not archive my blog's content."), + 'NOINDEX,NOFOLLOW,NOARCHIVE' => __("I would like to prevent search engines and archivers from indexing or archiving my blog's content."), +); + +# Update a blog +if ($blog_id && !empty($_POST) && $core->auth->check('admin',$blog_id)) +{ + $cur = $core->con->openCursor($core->prefix.'blog'); + if ($core->auth->isSuperAdmin()) { + $cur->blog_id = $_POST['blog_id']; + $cur->blog_url = preg_replace('/\?+$/','?',$_POST['blog_url']); + if (in_array($_POST['blog_status'],$status_combo)) { + $cur->blog_status = (integer) $_POST['blog_status']; + } + } + $cur->blog_name = $_POST['blog_name']; + $cur->blog_desc = $_POST['blog_desc']; + + $media_img_t_size = abs((integer) $_POST['media_img_t_size']); + if ($media_img_t_size < 0) { $media_img_t_size = 100; } + + $media_img_s_size = abs((integer) $_POST['media_img_s_size']); + if ($media_img_s_size < 0) { $media_img_s_size = 240; } + + $media_img_m_size = abs((integer) $_POST['media_img_m_size']); + if ($media_img_m_size < 0) { $media_img_m_size = 448; } + + $nb_post_per_page = abs((integer) $_POST['nb_post_per_page']); + if ($nb_post_per_page <= 1) { $nb_post_per_page = 1; } + + $nb_post_per_feed = abs((integer) $_POST['nb_post_per_feed']); + if ($nb_post_per_feed <= 1) { $nb_post_per_feed = 1; } + + $nb_comment_per_feed = abs((integer) $_POST['nb_comment_per_feed']); + if ($nb_comment_per_feed <= 1) { $nb_comment_per_feed = 1; } + + try + { + if ($cur->blog_id != null && $cur->blog_id != $blog_id) { + $rs = $core->getBlog($cur->blog_id); + + if ($rs) { + throw new Exception(__('That blog Id is already in use.')); + } + } + + # --BEHAVIOR-- adminBeforeBlogUpdate + $core->callBehavior('adminBeforeBlogUpdate',$cur,$blog_id); + + if (!preg_match('/^[a-z]{2}(-[a-z]{2})?$/',$_POST['lang'])) { + throw new Exception(__('Invalid language code')); + } + + $core->updBlog($blog_id,$cur); + + # --BEHAVIOR-- adminAfterBlogUpdate + $core->callBehavior('adminAfterBlogUpdate',$cur,$blog_id); + + if ($cur->blog_id != null && $cur->blog_id != $blog_id) { + if ($blog_id == $core->blog->id) { + $core->setBlog($cur->blog_id); + $_SESSION['sess_blog_id'] = $cur->blog_id; + $blog_settings = $core->blog->settings; + } else { + $blog_settings = new dcSettings($core,$cur->blog_id); + } + + $blog_id = $cur->blog_id; + } + + + $blog_settings->addNameSpace('system'); + + $blog_settings->system->put('editor',$_POST['editor']); + $blog_settings->system->put('copyright_notice',$_POST['copyright_notice']); + $blog_settings->system->put('post_url_format',$_POST['post_url_format']); + $blog_settings->system->put('lang',$_POST['lang']); + $blog_settings->system->put('blog_timezone',$_POST['blog_timezone']); + $blog_settings->system->put('date_format',$_POST['date_format']); + $blog_settings->system->put('time_format',$_POST['time_format']); + $blog_settings->system->put('comments_ttl',abs((integer) $_POST['comments_ttl'])); + $blog_settings->system->put('trackbacks_ttl',abs((integer) $_POST['trackbacks_ttl'])); + $blog_settings->system->put('allow_comments',!empty($_POST['allow_comments'])); + $blog_settings->system->put('allow_trackbacks',!empty($_POST['allow_trackbacks'])); + $blog_settings->system->put('comments_pub',empty($_POST['comments_pub'])); + $blog_settings->system->put('trackbacks_pub',empty($_POST['trackbacks_pub'])); + $blog_settings->system->put('comments_nofollow',!empty($_POST['comments_nofollow'])); + $blog_settings->system->put('wiki_comments',!empty($_POST['wiki_comments'])); + $blog_settings->system->put('enable_xmlrpc',!empty($_POST['enable_xmlrpc'])); + + $blog_settings->system->put('nb_post_per_page',$nb_post_per_page); + $blog_settings->system->put('use_smilies',!empty($_POST['use_smilies'])); + $blog_settings->system->put('media_img_t_size',$media_img_t_size); + $blog_settings->system->put('media_img_s_size',$media_img_s_size); + $blog_settings->system->put('media_img_m_size',$media_img_m_size); + $blog_settings->system->put('media_img_title_pattern',$_POST['media_img_title_pattern']); + $blog_settings->system->put('nb_post_per_feed',$nb_post_per_feed); + $blog_settings->system->put('nb_comment_per_feed',$nb_comment_per_feed); + $blog_settings->system->put('short_feed_items',!empty($_POST['short_feed_items'])); + + if (isset($_POST['robots_policy'])) { + $blog_settings->system->put('robots_policy',$_POST['robots_policy']); + } + + # --BEHAVIOR-- adminBeforeBlogSettingsUpdate + $core->callBehavior('adminBeforeBlogSettingsUpdate',$blog_settings); + + if ($core->auth->isSuperAdmin() && in_array($_POST['url_scan'],$url_scan_combo)) { + $blog_settings->system->put('url_scan',$_POST['url_scan']); + } + + http::redirect(sprintf($redir,$blog_id)); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} + +dcPage::open(__('Blog settings'), + '". + dcPage::jsConfirmClose('blog-form'). + dcPage::jsLoad('js/_blog_pref.js'). + + + # --BEHAVIOR-- adminBlogPreferencesHeaders + $core->callBehavior('adminBlogPreferencesHeaders'). + + dcPage::jsPageTabs() +); + +if ($blog_id) +{ + echo '

      '.(!$standalone ? ''.__('Blogs').' › ' : ''). + html::escapeHTML($blog_name).' › '. + __('Blog settings').'

      '; + + if (!empty($_GET['add'])) { + echo '

      '.__('Blog has been successfully created.').'

      '; + } + + if (!empty($_GET['upd'])) { + echo '

      '.__('Blog has been successfully updated.').'

      '; + } + + echo + '
      '. + '

      '.__('Parameters').'

      '. + '
      '; + + echo + '
      '.__('Blog details').''. + $core->formNonce(); + + if ($core->auth->isSuperAdmin()) + { + echo + '

      '. + '

      '.__('At least 2 characters using letters, numbers or symbols.').'

      '. + '

      '.__('Please note that changing your blog ID may require changes in your public index.php file.').'

      '; + } + + echo + '

      '; + + if ($core->auth->isSuperAdmin()) + { + echo + '

      '. + + '

      '. + + '

      '; + } + + echo + '

      '. + form::textarea('blog_desc',60,5,html::escapeHTML($blog_desc)).'

      '. + '
      '; + + + echo + '
      '.__('Blog configuration').''. + '
      '. + '
      '. + '

      '. + + '

      '. + + '

      '. + '
      '. + + '
      '. + '

      '. + + '

      '. + + '

      '. + ' - '.__('more information').'

      '. + '
      '. + '
      '. + '
      '. //Opera sucks + '
      '; + + echo + '
      '.__('Comments and trackbacks').''. + '
      '. + '
      '. + '

      '. + + '

      '. + + '

      '. + '

      '.__('Leave blank to disable this feature.').'

      '. + + '

      '. + '
      '. + + '
      '. + '

      '. + + '

      '. + + '

      '. + '

      '.__('Leave blank to disable this feature.').'

      '. + + '

      '. + '
      '. + '
      '. + '
      '. //Opera sucks + '
      '; + + echo + '
      '.__('Blog presentation').''. + '
      '. + '
      '. + '

      '. + + '

      '. + + '

      '. + '
      '. + + '
      '. + '

      '. + + '

      '. + + '

      '. + + '

      '. + '
      '. + '
      '. + '
      '. //Opera sucks + '
      '; + + echo + '
      '.__('Media and images').''. + '
      '. + '
      '. + '

      '.__('Generated image sizes (in pixels)').'

      '. + '

      '. + + '

      '. + + '

      '. + '
      '. + + '
      '. + '

      '. + '

      '.__('This defines image tag title when you insert it in a post from the media manager. It is retrieved from the picture\'s metadata.').'

      '. + '

      '.form::combo('media_img_title_pattern',$img_title_combo,html::escapeHTML($blog_settings->system->media_img_title_pattern)).'

      '. + '
      '. + '
      '. + '
      '; + + echo + '
      '.__('Search engines robots policy').''; + + $i = 0; + foreach ($robots_policy_options as $k => $v) + { + echo '

      '; + $i++; + } + + echo '
      '; + + + # --BEHAVIOR-- adminBlogPreferencesForm + $core->callBehavior('adminBlogPreferencesForm',$core,$blog_settings); + + echo + '

      '. + (!$standalone ? form::hidden('id',$blog_id) : ''). + '

      '. + '
      '; + + if ($core->auth->isSuperAdmin() && $blog_id != $core->blog->id) + { + echo + '
      '. + '

      '. + form::hidden(array('blog_id'),$blog_id). + $core->formNonce().'

      '. + '
      '; + } + + # XML/RPC information + echo '

      '.__('XML/RPC interface').'

      '; + + echo '

      '.__('XML/RPC interface allows you to edit your blog with an external client.').'

      '; + + if (!$blog_settings->system->enable_xmlrpc) + { + echo '

      '.__('XML/RPC interface is not active. Change settings to enable it.').'

      '; + } + else + { + echo + '

      '.__('XML/RPC interface is active. You should set the following parameters on your XML/RPC client:').'

      '. + '
        '. + '
      • '.__('Server URL:').' '. + sprintf(DC_XMLRPC_URL,$core->blog->url,$core->blog->id). + '
      • '. + '
      • '.__('Blogging system:').' Movable Type
      • '. + '
      • '.__('User name:').' '.$core->auth->userID().'
      • '. + '
      • '.__('Password:').' '.__('your password').'
      • '. + '
      • '.__('Blog ID:').' 1
      • '. + '
      '; + } + + echo '
      '; + + # + # Users on the blog (with permissions) + + $blog_users = $core->getBlogPermissions($blog_id,$core->auth->isSuperAdmin()); + $perm_types = $core->auth->getPermissionsTypes(); + + echo + '
      '. + '

      '.__('Users on this blog').'

      '; + + if (empty($blog_users)) + { + echo '

      '.__('No users').'

      '; + } + else + { + if ($core->auth->isSuperAdmin()) { + $user_url_p = '%1$s'; + } else { + $user_url_p = '%1$s'; + } + + foreach ($blog_users as $k => $v) + { + if (count($v['p']) > 0) + { + echo + '

      '.sprintf($user_url_p,html::escapeHTML($k)). + ' ('.html::escapeHTML(dcUtils::getUserCN( + $k, $v['name'], $v['firstname'], $v['displayname'] + )).')'; + + if (!$v['super'] && $core->auth->isSuperAdmin()) { + echo + ' - ' + .__('Change permissions').''; + } + + echo '

      '; + + echo '
        '; + if ($v['super']) { + echo '
      • '.__('Super administrator').'
      • '; + } else { + foreach ($v['p'] as $p => $V) { + echo '
      • '.__($perm_types[$p]).'
      • '; + } + } + echo '
      '; + } + } + } + + echo '
      '; +} + +dcPage::helpBlock('core_blog_pref'); +dcPage::close(); +?> \ No newline at end of file diff --git a/v2/dotclear/admin/blog_theme.php b/v2/dotclear/admin/blog_theme.php new file mode 100644 index 0000000..d463379 --- /dev/null +++ b/v2/dotclear/admin/blog_theme.php @@ -0,0 +1,363 @@ +themes = new dcThemes($core); +$core->themes->loadModules($core->blog->themes_path,null); + +# Theme screenshot +if (!empty($_GET['shot']) && $core->themes->moduleExists($_GET['shot'])) +{ + if (empty($_GET['src'])) { + $f = $core->blog->themes_path.'/'.$_GET['shot'].'/screenshot.jpg'; + } else { + $f = $core->blog->themes_path.'/'.$_GET['shot'].'/'.path::clean($_GET['src']); + } + + $f = path::real($f); + + if (!file_exists($f)) { + $f = dirname(__FILE__).'/images/noscreenshot.png'; + } + + http::cache(array_merge(array($f),get_included_files())); + + header('Content-Type: '.files::getMimeType($f)); + header('Content-Length: '.filesize($f)); + readfile($f); + + exit; +} + +$can_install = $core->auth->isSuperAdmin(); +$is_writable = is_dir($core->blog->themes_path) && is_writable($core->blog->themes_path); +$default_tab = 'themes-list'; + +# Selecting theme +if (!empty($_POST['theme']) && !empty($_POST['select']) && empty($_REQUEST['conf'])) +{ + $core->blog->settings->addNamespace('system'); + $core->blog->settings->system->put('theme',$_POST['theme']); + $core->blog->triggerBlog(); + http::redirect('blog_theme.php?upd=1'); +} + +if ($can_install && !empty($_POST['theme']) && !empty($_POST['remove']) && empty($_REQUEST['conf'])) +{ + try + { + if ($_POST['theme'] == 'default') { + throw new Exception(__('You can\'t remove default theme.')); + } + + if (!$core->themes->moduleExists($_POST['theme'])) { + throw new Exception(__('Theme does not exist.')); + } + + $theme = $core->themes->getModules($_POST['theme']); + + # --BEHAVIOR-- themeBeforeDelete + $core->callBehavior('themeBeforeDelete',$theme); + + $core->themes->deleteModule($_POST['theme']); + + # --BEHAVIOR-- themeAfterDelete + $core->callBehavior('themeAfterDelete',$theme); + + http::redirect('blog_theme.php?del=1'); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} + +# Theme upload +if ($can_install && $is_writable && ((!empty($_POST['upload_pkg']) && !empty($_FILES['pkg_file'])) || + (!empty($_POST['fetch_pkg']) && !empty($_POST['pkg_url'])))) +{ + try + { + if (empty($_POST['your_pwd']) || !$core->auth->checkPassword(crypt::hmac(DC_MASTER_KEY,$_POST['your_pwd']))) { + throw new Exception(__('Password verification failed')); + } + + if (!empty($_POST['upload_pkg'])) + { + files::uploadStatus($_FILES['pkg_file']); + + $dest = $core->blog->themes_path.'/'.$_FILES['pkg_file']['name']; + if (!move_uploaded_file($_FILES['pkg_file']['tmp_name'],$dest)) { + throw new Exception(__('Unable to move uploaded file.')); + } + } + else + { + $url = urldecode($_POST['pkg_url']); + $dest = $core->blog->themes_path.'/'.basename($url); + + try + { + $client = netHttp::initClient($url,$path); + $client->setUserAgent('Dotclear - http://www.dotclear.org/'); + $client->useGzip(false); + $client->setPersistReferers(false); + $client->setOutput($dest); + $client->get($path); + } + catch( Exception $e) + { + throw new Exception(__('An error occurred while downloading the file.')); + } + + unset($client); + } + + $ret_code = dcModules::installPackage($dest,$core->themes); + http::redirect('blog_theme.php?added='.$ret_code); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + $default_tab = 'add-theme'; + } +} + +$theme_conf_mode = false; +if (!empty($_REQUEST['conf'])) +{ + $theme_conf_file = path::real($core->blog->themes_path.'/'.$core->blog->settings->system->theme).'/_config.php'; + if (file_exists($theme_conf_file)) { + $theme_conf_mode = true; + } +} + +function display_theme_details($id,$details,$current) +{ + global $core; + + $screenshot = 'images/noscreenshot.png'; + if (file_exists($core->blog->themes_path.'/'.$id.'/screenshot.jpg')) { + $screenshot = 'blog_theme.php?shot='.rawurlencode($id); + } + + $radio_id = 'theme_'.html::escapeHTML($id); + if (preg_match('#^http(s)?://#',$core->blog->settings->system->themes_url)) { + $theme_url = http::concatURL($core->blog->settings->system->themes_url,'/'.$id); + } else { + $theme_url = http::concatURL($core->blog->url,$core->blog->settings->system->themes_url.'/'.$id); + } + $has_conf = file_exists(path::real($core->blog->themes_path.'/'.$id).'/_config.php'); + $has_css = file_exists(path::real($core->blog->themes_path.'/'.$id).'/style.css'); + $parent = $core->themes->moduleInfo($id,'parent'); + $has_parent = (boolean)$parent; + if ($has_parent) { + $is_parent_present = $core->themes->moduleExists($parent); + } + + $res = + '
      '. + '
      '. + '
      '. + '

      '.form::radio(array('theme',$radio_id),html::escapeHTML($id),$current,'','',($has_parent && !$is_parent_present)).' '. + '

      '. + '

      '.html::escapeHTML($details['desc']).' '. + ''.sprintf(__('by %s'),html::escapeHTML($details['author'])).' '. + ''.sprintf(__('version %s'),html::escapeHTML($details['version'])).' '; + if ($has_parent) { + if ($is_parent_present) { + $res .= ''.sprintf(__('(built on "%s")'),html::escapeHTML($parent)).' '; + } else { + $res .= ''.sprintf(__('(requires "%s")'),html::escapeHTML($parent)).' '; + } + } + if ($has_css) { + $res .= ''.__('Stylesheet').''; + } + $res .= '

      '; + $res .= + '
      '. + '
      '; + if ($current && $has_conf) { + $res .= '

      '.__('Configure theme').'

      '; + } + if ($current) { + # --BEHAVIOR-- adminCurrentThemeDetails + $res .= $core->callBehavior('adminCurrentThemeDetails',$core,$id,$details); + } + $res .= + '
      '. + '
      '; + + return $res; +} + +dcPage::open(__('Blog appearance'), + (!$theme_conf_mode ? dcPage::jsLoad('js/_blog_theme.js') : ''). + dcPage::jsPageTabs($default_tab). + dcPage::jsColorPicker() +); + +if (!$theme_conf_mode) +{ + echo + '

      '.html::escapeHTML($core->blog->name).' › '.__('Blog appearance').'

      '; + + if (!empty($_GET['upd'])) { + echo '

      '.__('Theme has been successfully changed.').'

      '; + } + + if (!empty($_GET['added'])) { + echo '

      '. + ($_GET['added'] == 2 ? __('Theme has been successfully upgraded') : __('Theme has been successfully installed.')). + '

      '; + } + + if (!empty($_GET['del'])) { + echo '

      '.__('Theme has been successfully deleted.').'

      '; + } + + if ($can_install) { + echo + '

      '.sprintf(__('You can find additional themes for your blog on %s.'), + 'Dotaddict').' '. + __('To install or upgrade a theme you generally just need to upload it '. + 'in "Install or upgrade a theme" section.').'

      '; + } + + # Themes list + echo '
      '; + + $themes = $core->themes->getModules(); + if (isset($themes[$core->blog->settings->system->theme])) { + echo '

      '.sprintf(__('You are currently using "%s"'),$themes[$core->blog->settings->system->theme]['name']).'

      '; + } + + echo + '
      '. + '
      '; + + if (isset($themes[$core->blog->settings->system->theme])) { + echo display_theme_details($core->blog->settings->system->theme,$themes[$core->blog->settings->system->theme],true); + } + + foreach ($themes as $k => $v) + { + if ($core->blog->settings->system->theme == $k) { // Current theme + continue; + } + echo display_theme_details($k,$v,false); + } + + echo '
      '; + + echo + '
      '. + $core->formNonce(). + '

      '; + + if ($can_install) { + echo '

      '; + } + + echo + '
      '. + '
      '. + '
      '; + + # Add a new theme + if ($can_install) + { + echo + '
      '; + + if ($is_writable) + { + echo '

      '.__('You can install themes by uploading or downloading zip files.').'

      '; + + # 'Upload theme' form + echo + '
      '. + '
      '. + ''.__('Upload a zip file').''. + '

      '. + '

      '. + ''. + $core->formNonce(). + '
      '. + '
      '; + + # 'Fetch theme' form + echo + '
      '. + '
      '. + ''.__('Download a zip file').''. + '

      '. + '

      '. + ''. + $core->formNonce(). + '
      '. + '
      '; + } + else + { + echo + '

      '. + __('To enable this function, please give write access to your themes directory.'). + '

      '; + } + echo '
      '; + } +} +else +{ + $theme_name = $core->themes->moduleInfo($core->blog->settings->system->theme,'name'); + $core->themes->loadModuleL10Nresources($core->blog->settings->system->theme,$_lang); + echo + '

      '.html::escapeHTML($core->blog->name). + ' › '.__('Blog appearance').''.__('Theme configuration').'

      '. + '

      '.__('back').'

      '; + + try + { + # Let theme configuration set their own form(s) if required + $standalone_config = (boolean) $core->themes->moduleInfo($core->blog->settings->system->theme,'standalone_config'); + + if (!$standalone_config) + echo '
      '; + + include $theme_conf_file; + + if (!$standalone_config) + echo + '

      '. + $core->formNonce().'

      '. + '
      '; + + } + catch (Exception $e) + { + echo '

      '.$e->getMessage().'

      '; + } +} + +dcPage::close(); +?> \ No newline at end of file diff --git a/v2/dotclear/admin/blogs.php b/v2/dotclear/admin/blogs.php new file mode 100644 index 0000000..ce572d6 --- /dev/null +++ b/v2/dotclear/admin/blogs.php @@ -0,0 +1,185 @@ + 'blog_upddt', +__('Blog name') => 'UPPER(blog_name)', +__('Blog ID') => 'B.blog_id' +); + +$order_combo = array( +__('Descending') => 'desc', +__('Ascending') => 'asc' +); + +$q = !empty($_GET['q']) ? $_GET['q'] : ''; +$sortby = !empty($_GET['sortby']) ? $_GET['sortby'] : 'blog_upddt'; +$order = !empty($_GET['order']) ? $_GET['order'] : 'desc'; + +$page = !empty($_GET['page']) ? $_GET['page'] : 1; +$nb_per_page = 30; + +if (!empty($_GET['nb']) && (integer) $_GET['nb'] > 0) { + $nb_per_page = (integer) $_GET['nb']; +} + +$show_filters = false; + +# - Search filter +if ($q) { + $params['q'] = $q; + $show_filters = true; +} + +# - Sortby and order filter +if ($sortby !== '' && in_array($sortby,$sortby_combo)) { + if ($order !== '' && in_array($order,$order_combo)) { + $params['order'] = $sortby.' '.$order; + } + + if ($sortby != 'blog_upddt' || $order != 'desc') { + $show_filters = true; + } +} + +$params['limit'] = array((($page-1)*$nb_per_page),$nb_per_page); + +try { + $counter = $core->getBlogs($params,1); + $rs = $core->getBlogs($params); + $nb_blog = $counter->f(0); +} catch (Exception $e) { + $core->error->add($e->getMessage()); +} + +/* DISPLAY +-------------------------------------------------------- */ +$starting_script = ''; +if (!$show_filters) { + $starting_script .= dcPage::jsLoad('js/filter-controls.js'); +} +dcPage::open(__('List of blogs'),$starting_script); + +if (!empty($_GET['del'])) { + echo '

      '.__('Blog has been successfully deleted.').'

      '; +} + +echo '

      '.__('List of blogs').'

      '; + +if (!$core->error->flag()) +{ + if ($core->auth->isSuperAdmin()) { + echo '

      '.__('Create a new blog').'

      '; + } + + if (!$show_filters) { + echo '

      '.__('Filters').'

      '; + } + + echo + '
      '. + '
      '.__('Filters').''. + + '
      '. + '

      '. + '

      '. + '
      '. + + '
      '. + '

      '. + '

      '. + '

      '. + '
      '. + + '
      '. //Opera sucks + '
      '. + '
      '; + + # Show blogs + if ($nb_blog == 0) + { + echo '

      '.__('No blog').'

      '; + } + else + { + $pager = new pager($page,$nb_blog,$nb_per_page,10); + $pager->var_page = 'page'; + + echo '

      '.__('Page(s)').' : '.$pager->getLinks().'

      '; + + echo + ''. + ''. + ''. + ''. + ''. + ''. + ''. + ''; + + while ($rs->fetch()) { + echo blogLine($rs); + } + + echo '
      '.__('Blog name').''.__('Last update').''.__('Entries').''.__('Blog ID').' '.__('Status').'
      '; + + echo '

      '.__('Page(s)').' : '.$pager->getLinks().'

      '; + } +} + +dcPage::close(); + +function blogLine($rs) +{ + global $core; + + $blog_id = html::escapeHTML($rs->blog_id); + $edit_link = ''; + + if ($GLOBALS['core']->auth->isSuperAdmin()) { + $edit_link = + ''. + __('edit').''; + } + + $img_status = $rs->blog_status == 1 ? 'check-on' : 'check-off'; + $txt_status = $GLOBALS['core']->getBlogStatus($rs->blog_status); + $img_status = sprintf('%2$s',$img_status,$txt_status); + $offset = dt::getTimeOffset($core->auth->getInfo('user_tz')); + $blog_upddt = dt::str(__('%Y-%m-%d %H:%M'),strtotime($rs->blog_upddt) + $offset); + + return + ''. + ''. + html::escapeHTML($rs->blog_name).''. + ''.$blog_upddt.''. + ''.$core->countBlogPosts($rs->blog_id).''. + ''.$blog_id.''. + ''.$edit_link.''. + ''.$img_status.''. + ''; +} +?> \ No newline at end of file diff --git a/v2/dotclear/admin/categories.php b/v2/dotclear/admin/categories.php new file mode 100644 index 0000000..15f0301 --- /dev/null +++ b/v2/dotclear/admin/categories.php @@ -0,0 +1,190 @@ +blog->getCategory((integer) $_POST['del_cat']); + if ($c->isEmpty()) { + throw new Exception(__('This category does not exist.')); + } + unset($c); + $core->blog->delCategory($_POST['del_cat']); + http::redirect('categories.php?del=1'); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} + +# Reset order +if (!empty($_POST['reset'])) +{ + try + { + $core->blog->resetCategoriesOrder(); + http::redirect('categories.php?reord=1'); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} + +/* Display +-------------------------------------------------------- */ +dcPage::open(__('Categories'), + dcPage::jsToolMan()."\n". + dcPage::jsLoad('js/_categories.js') +); + +if (!empty($_GET['add'])) { + echo '

      '.__('The category has been successfully created.').'

      '; +} +if (!empty($_GET['del'])) { + echo '

      '.__('The category has been successfully removed.').'

      '; +} +if (!empty($_GET['reord'])) { + echo '

      '.__('Categories have been successfully reordered.').'

      '; +} +if (!empty($_GET['moved'])) { + echo '

      '.__('The category has been successfully moved.').'

      '; +} + +echo '

      '.html::escapeHTML($core->blog->name).' › '.__('Categories').'

      '; + +$rs = $core->blog->getCategories(array('post_type'=>'post')); + +echo +'
      '. +'
      '; +if ($rs->isEmpty()) +{ + echo '

      '.__('No category yet.').'

      '; +} +else +{ + echo + '

      '.__('Categories list').'

      '. + '
      '; + + $ref_level = $level = $rs->level-1; + while ($rs->fetch()) + { + $attr = 'id="cat'.$rs->cat_id.'"'; + if ($rs->nb_total == 0) { + $attr .= ' class="deletable"'; + } + + if ($rs->level > $level) { + echo str_repeat('
      • ',$rs->level - $level); + } elseif ($rs->level < $level) { + echo str_repeat('
      ',-($rs->level - $level)); + } + + if ($rs->level <= $level) { + echo '
    • '; + } + + echo + '

      '.html::escapeHTML($rs->cat_title).''. + ' ('. + sprintf(($rs->nb_post > 1 ? __('%d entries') : __('%d entry') ),$rs->nb_post).''. + ', '.__('total:').' '.$rs->nb_total.')

      '. + '

      '.__('URL:').' '.html::escapeHTML($rs->cat_url).'

      '; + + $level = $rs->level; + } + + if ($ref_level - $level < 0) { + echo str_repeat('
    • ',-($ref_level - $level)); + } + echo '
      '; +} +echo '
      '; + +echo '
      '. + +'
      '. +'
      '.__('Add a new category').''. +'

      '. +'

      '. +'

      '. +$core->formNonce(). +'
      '. +'
      '; + +if (!$rs->isEmpty()) +{ + $deletable = array(); + $l = $rs->level; + $full_name = array($rs->cat_title); + while ($rs->fetch()) + { + if ($rs->level < $l) { + $full_name = array(); + } elseif ($rs->level == $l) { + array_pop($full_name); + } + $full_name[] = html::escapeHTML($rs->cat_title); + if ($rs->nb_post == 0) { + $deletable[implode(' / ',$full_name)] = $rs->cat_id; + } + $l = $rs->level; + } + + if (count($deletable) > 0) + { + echo + '
      '. + '
      '.__('Remove a category').''. + '

      '. + '

      '. + $core->formNonce(). + '
      '. + '
      '; + } + + echo + '
      '. + '
      '.__('Reorder categories').''. + '

      '.__('This will relocate all categories on the top level').'

      '. + '

      '. + form::hidden(array('reset'),1). + $core->formNonce(). + '
      '. + '
      '; +} +echo '
      '; +echo '
      '; + +dcPage::helpBlock('core_categories'); +dcPage::close(); +?> \ No newline at end of file diff --git a/v2/dotclear/admin/category.php b/v2/dotclear/admin/category.php new file mode 100644 index 0000000..d91895a --- /dev/null +++ b/v2/dotclear/admin/category.php @@ -0,0 +1,260 @@ +blog->getCategory($_REQUEST['id']); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } + + if (!$core->error->flag() && !$rs->isEmpty()) + { + $cat_id = (integer) $rs->cat_id; + $cat_title = $rs->cat_title; + $cat_url = $rs->cat_url; + $cat_desc = $rs->cat_desc; + } + unset($rs); + + # Getting hierarchy information + $parents = $core->blog->getCategoryParents($cat_id); + $rs = $core->blog->getCategoryParent($cat_id); + $cat_parent = $rs->isEmpty() ? 0 : (integer) $rs->cat_id; + unset($rs); + + # Allowed parents list + $children = $core->blog->getCategories(array('post_type'=>'post','start'=>$cat_id)); + $allowed_parents = array(__('Top level')=>0); + + $p = array(); + while ($children->fetch()) { + $p[$children->cat_id] = 1; + } + + $rs = $core->blog->getCategories(array('post_type'=>'post')); + while ($rs->fetch()) { + if (!isset($p[$rs->cat_id])) { + $allowed_parents[] = new formSelectOption( + str_repeat('  ',$rs->level-1).($rs->level-1 == 0 ? '' : '• ').html::escapeHTML($rs->cat_title), + $rs->cat_id + ); + } + } + unset($rs); + + # Allowed siblings list + $siblings = array(); + $rs = $core->blog->getCategoryFirstChildren($cat_parent); + while ($rs->fetch()) { + if ($rs->cat_id != $cat_id) { + $siblings[html::escapeHTML($rs->cat_title)] = $rs->cat_id; + } + } + unset($rs); +} + +# Changing parent +if ($cat_id && isset($_POST['cat_parent'])) +{ + $new_parent = (integer) $_POST['cat_parent']; + if ($cat_parent != $new_parent) + { + try { + $core->blog->setCategoryParent($cat_id,$new_parent); + http::redirect('categories.php?moved=1'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } + } +} + +# Changing sibling +if ($cat_id && isset($_POST['cat_sibling'])) +{ + try { + $core->blog->setCategoryPosition($cat_id,(integer) $_POST['cat_sibling'],$_POST['cat_move']); + http::redirect('categories.php?moved=1'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} + +# Create or update a category +if (isset($_POST['cat_title'])) +{ + $cur = $core->con->openCursor($core->prefix.'category'); + + $cur->cat_title = $cat_title = $_POST['cat_title']; + + if (isset($_POST['cat_desc'])) { + $cur->cat_desc = $cat_desc = $_POST['cat_desc']; + } + + if (isset($_POST['cat_url'])) { + $cur->cat_url = $cat_url = $_POST['cat_url']; + } else { + $cur->cat_url = $cat_url; + } + + try + { + # Update category + if ($cat_id) + { + # --BEHAVIOR-- adminBeforeCategoryUpdate + $core->callBehavior('adminBeforeCategoryUpdate',$cur,$cat_id); + + $core->blog->updCategory($_POST['id'],$cur); + + # --BEHAVIOR-- adminAfterCategoryUpdate + $core->callBehavior('adminAfterCategoryUpdate',$cur,$cat_id); + + http::redirect('category.php?id='.$_POST['id'].'&upd=1'); + } + # Create category + else + { + # --BEHAVIOR-- adminBeforeCategoryCreate + $core->callBehavior('adminBeforeCategoryCreate',$cur); + + $id = $core->blog->addCategory($cur,(integer) $_POST['new_cat_parent']); + + # --BEHAVIOR-- adminAfterCategoryCreate + $core->callBehavior('adminAfterCategoryCreate',$cur,$id); + + http::redirect('categories.php?add=1'); + } + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} + + +$title = $cat_id ? html::escapeHTML($cat_title) : __('New category'); + +dcPage::open($title, + dcPage::jsConfirmClose('category-form'). + dcPage::jsToolBar(). + dcPage::jsLoad('js/_category.js') +); + +if (!empty($_GET['upd'])) { + echo '

      '.__('Category has been successfully updated.').'

      '; +} + +echo +'

      '.html::escapeHTML($core->blog->name).' › '. +__('Categories').' › '; + +if ($cat_id) +{ + while($parents->fetch()) { + echo ''.html::escapeHTML($parents->cat_title).''; + echo " › "; + } +} + +echo ''.$title.'

      '; + +echo +'
      '. +'
      '.__('Category information').''. +'

      '; +if (!$cat_id) +{ + $rs = $core->blog->getCategories(array('post_type'=>'post')); + echo + '

      '; + unset($rs); +} +echo +'
      '. +'

      '. +'

      '. +__('Warning: If you set the URL manually, it may conflict with another category.').'

      '. +'
      '. + +'

      '. +form::textarea('cat_desc',50,8,html::escapeHTML($cat_desc)). +'

      '. + +'

      '. +($cat_id ? form::hidden('id',$cat_id) : ''). +$core->formNonce(). +'

      '. +'
      '. +'
      '; + +if ($cat_id) +{ + echo + '

      '.__('Move this category').'

      '. + '
      '. + '
      '. + + '
      '. + '
      '.__('Category parent').''. + '

      '. + '

      '. + form::hidden(array('id'),$cat_id).$core->formNonce().'

      '. + '
      '. + '
      '. + '
      '; + + if (count($siblings) > 0) { + echo + '
      '. + '
      '. + '
      '.__('Category sibling').''. + '

      '. + form::combo('cat_move',array(__('before')=>'before',__('after')=>'after'),'','','',false,'title="'.__('position: ').'"').' '. + form::combo('cat_sibling',$siblings).'

      '. + '

      '. + form::hidden(array('id'),$cat_id).$core->formNonce().'

      '. + '
      '. + '
      '. + '
      '; + } + + echo '
      '; +} + +dcPage::helpBlock('core_categories'); +dcPage::close(); +?> \ No newline at end of file diff --git a/v2/dotclear/admin/comment.php b/v2/dotclear/admin/comment.php new file mode 100644 index 0000000..0ef8cec --- /dev/null +++ b/v2/dotclear/admin/comment.php @@ -0,0 +1,236 @@ +blog->getAllCommentStatus() as $k => $v) { + $status_combo[$v] = (string) $k; +} + +# Adding comment +if (!empty($_POST['add']) && !empty($_POST['post_id'])) +{ + try + { + $rs = $core->blog->getPosts(array('post_id' => $_POST['post_id'], 'post_type' => '')); + + if ($rs->isEmpty()) { + throw new Exception(__('Entry does not exist.')); + } + + $cur = $core->con->openCursor($core->prefix.'comment'); + + $cur->comment_author = $_POST['comment_author']; + $cur->comment_email = html::clean($_POST['comment_email']); + $cur->comment_site = html::clean($_POST['comment_site']); + $cur->comment_content = $core->HTMLfilter($_POST['comment_content']); + $cur->post_id = (integer) $_POST['post_id']; + + # --BEHAVIOR-- adminBeforeCommentCreate + $core->callBehavior('adminBeforeCommentCreate',$cur); + + $comment_id = $core->blog->addComment($cur); + + # --BEHAVIOR-- adminAfterCommentCreate + $core->callBehavior('adminAfterCommentCreate',$cur,$comment_id); + + http::redirect($core->getPostAdminURL($rs->post_type,$rs->post_id,false).'&co=1&creaco=1'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} + +if (!empty($_REQUEST['id'])) +{ + $params['comment_id'] = $_REQUEST['id']; + + try { + $rs = $core->blog->getComments($params); + if (!$rs->isEmpty()) { + $comment_id = $rs->comment_id; + $post_id = $rs->post_id; + $post_type = $rs->post_type; + $post_title = $rs->post_title; + $comment_dt = $rs->comment_dt; + $comment_author = $rs->comment_author; + $comment_email = $rs->comment_email; + $comment_site = $rs->comment_site; + $comment_content = $rs->comment_content; + $comment_ip = $rs->comment_ip; + $comment_status = $rs->comment_status; + $comment_trackback = (boolean) $rs->comment_trackback; + $comment_spam_status = $rs->comment_spam_status; + } + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} + +if (!$comment_id && !$core->error->flag()) { + $core->error->add(__('No comment')); +} + +if (!$core->error->flag() && isset($rs)) +{ + $can_edit = $can_delete = $can_publish = $core->auth->check('contentadmin',$core->blog->id); + + if (!$core->auth->check('contentadmin',$core->blog->id) && $core->auth->userID() == $rs->user_id) { + $can_edit = true; + if ($core->auth->check('delete',$core->blog->id)) { + $can_delete = true; + } + if ($core->auth->check('publish',$core->blog->id)) { + $can_publish = true; + } + } + + # update comment + if (!empty($_POST['update']) && $can_edit) + { + $cur = $core->con->openCursor($core->prefix.'comment'); + + $cur->comment_author = $_POST['comment_author']; + $cur->comment_email = html::clean($_POST['comment_email']); + $cur->comment_site = html::clean($_POST['comment_site']); + $cur->comment_content = $core->HTMLfilter($_POST['comment_content']); + + if (isset($_POST['comment_status'])) { + $cur->comment_status = (integer) $_POST['comment_status']; + } + + try + { + # --BEHAVIOR-- adminBeforeCommentUpdate + $core->callBehavior('adminBeforeCommentUpdate',$cur,$comment_id); + + $core->blog->updComment($comment_id,$cur); + + # --BEHAVIOR-- adminAfterCommentUpdate + $core->callBehavior('adminAfterCommentUpdate',$cur,$comment_id); + + http::redirect('comment.php?id='.$comment_id.'&upd=1'); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } + } + + if (!empty($_POST['delete']) && $can_delete) + { + try { + # --BEHAVIOR-- adminBeforeCommentDelete + $core->callBehavior('adminBeforeCommentDelete',$comment_id); + + $core->blog->delComment($comment_id); + http::redirect($core->getPostAdminURL($rs->post_type,$rs->post_id).'&co=1#c'.$comment_id,false); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } + } + + if (!$can_edit) { + $core->error->add(__("You can't edit this comment.")); + } +} + +/* DISPLAY +-------------------------------------------------------- */ +dcPage::open(__('Edit comment'), + dcPage::jsConfirmClose('comment-form'). + dcPage::jsToolBar(). + dcPage::jsLoad('js/_comment.js'). + # --BEHAVIOR-- adminCommentHeaders + $core->callBehavior('adminCommentHeaders') +); + +if ($comment_id) +{ + if (!empty($_GET['upd'])) { + echo '

      '.__('Comment has been successfully updated.').'

      '; + } + + $comment_mailto = ''; + if ($comment_email) + { + $comment_mailto = 'getPostURL())) + .'">'.__('Send an e-mail').''; + } + + echo '

      '.html::escapeHTML($core->blog->name).' › '. + $post_title.''.__('Edit comment').'

      '; + + echo + '
      '. + '

      '.__('IP address:').'
      '. + ''.$comment_ip.'

      '. + + '

      '.__('Date:').'
      '. + dt::dt2str(__('%Y-%m-%d %H:%M'),$comment_dt).'

      '. + + '

      '. + + '

      '. + + '

      '. + + '

      '. + + # --BEHAVIOR-- adminAfterCommentDesc + $core->callBehavior('adminAfterCommentDesc', $rs). + + '

      '. + form::textarea('comment_content',50,10,html::escapeHTML($comment_content)). + '

      '. + + '

      '.form::hidden('id',$comment_id). + $core->formNonce(). + ' '; + + if ($can_delete) { + echo ''; + } + echo + '

      '. + '
      '; +} + +dcPage::helpBlock('core_comments'); +dcPage::close(); +?> \ No newline at end of file diff --git a/v2/dotclear/admin/comments.php b/v2/dotclear/admin/comments.php new file mode 100644 index 0000000..1d1d303 --- /dev/null +++ b/v2/dotclear/admin/comments.php @@ -0,0 +1,251 @@ + '' +); +foreach ($core->blog->getAllCommentStatus() as $k => $v) { + $status_combo[$v] = (string) $k; +} + +$type_combo = array( +'-' => '', +__('comment') => 'co', +__('trackback') => 'tb' +); + +$sortby_combo = array( +__('Date') => 'comment_dt', +__('Entry title') => 'post_title', +__('Author') => 'comment_author', +__('Status') => 'comment_status' +); + +$order_combo = array( +__('Descending') => 'desc', +__('Ascending') => 'asc' +); + + +/* Get comments +-------------------------------------------------------- */ +$author = isset($_GET['author']) ? $_GET['author'] : ''; +$status = isset($_GET['status']) ? $_GET['status'] : ''; +$type = !empty($_GET['type']) ? $_GET['type'] : ''; +$sortby = !empty($_GET['sortby']) ? $_GET['sortby'] : 'comment_dt'; +$order = !empty($_GET['order']) ? $_GET['order'] : 'desc'; +$ip = !empty($_GET['ip']) ? $_GET['ip'] : ''; + +$with_spam = $author || $status || $type || $sortby != 'comment_dt' || $order != 'desc' || $ip; + +$show_filters = false; + +$page = !empty($_GET['page']) ? (integer) $_GET['page'] : 1; +$nb_per_page = 30; + +if (!empty($_GET['nb']) && (integer) $_GET['nb'] > 0) { + if ($nb_per_page != $_GET['nb']) { + $show_filters = true; + } + $nb_per_page = (integer) $_GET['nb']; +} + +$params['limit'] = array((($page-1)*$nb_per_page),$nb_per_page); +$params['no_content'] = true; + +# Author filter +if ($author !== '') { + $params['q_author'] = $author; + $show_filters = true; +} else { + $author=''; +} + +# - Type filter +if ($type == 'tb' || $type == 'co') { + $params['comment_trackback'] = ($type == 'tb'); + $show_filters = true; +} else { + $type=''; +} + +# - Status filter +if ($status !== '' && in_array($status,$status_combo)) { + $params['comment_status'] = $status; + $show_filters = true; +} elseif (!$with_spam) { + $params['comment_status_not'] = -2; + $status=''; +} else { + $status=''; +} + +# - IP filter +if ($ip) { + $params['comment_ip'] = $ip; + $show_filters = true; +} + +# Sortby and order filter +if ($sortby !== '' && in_array($sortby,$sortby_combo)) { + if ($order !== '' && in_array($order,$order_combo)) { + $params['order'] = $sortby.' '.$order; + } else { + $order = 'desc'; + } + + if ($sortby != 'comment_dt' || $order != 'desc') { + $show_filters = true; + } +} else { + $sortby = 'comment_dt'; + $order = 'desc'; +} + +# Actions combo box +$combo_action = array(); +$default = ''; +if ($core->auth->check('publish,contentadmin',$core->blog->id)) +{ + $combo_action[__('publish')] = 'publish'; + $combo_action[__('unpublish')] = 'unpublish'; + $combo_action[__('mark as pending')] = 'pending'; + $combo_action[__('mark as junk')] = 'junk'; +} +if ($core->auth->check('delete,contentadmin',$core->blog->id)) +{ + $combo_action[__('Delete')] = 'delete'; + if ($status == -2) { + $default = 'delete'; + } +} + +# --BEHAVIOR-- adminCommentsActionsCombo +$core->callBehavior('adminCommentsActionsCombo',array(&$combo_action)); + +/* Get comments +-------------------------------------------------------- */ +try { + $comments = $core->blog->getComments($params); + $counter = $core->blog->getComments($params,true); + $comment_list = new adminCommentList($core,$comments,$counter->f(0)); +} catch (Exception $e) { + $core->error->add($e->getMessage()); +} + +/* DISPLAY +-------------------------------------------------------- */ +$starting_script = dcPage::jsLoad('js/_comments.js'); +if (!$show_filters) { + $starting_script .= dcPage::jsLoad('js/filter-controls.js'); +} +# --BEHAVIOR-- adminCommentsHeaders +$starting_script .= $core->callBehavior('adminCommentsHeaders'); + +dcPage::open(__('Comments and trackbacks'),$starting_script); + +echo '

      '.html::escapeHTML($core->blog->name).' › '.__('Comments and trackbacks').'

      '; + +if (!$core->error->flag()) +{ + # Filters + if (!$show_filters) { + echo '

      '. + __('Filters').'

      '; + } + + echo + '
      '. + '
      '.__('Filters').''. + '
      '. + '
      '. + ' '. + ''. + '
      '. + + '
      '. + '

      '. + '

      '. + '

      '. + '
      '. + + '
      '. + '

      '. + '

      '. + '

      '. + '
      '. + + '
      '. + '
      '. //Opera sucks + '
      '. + '
      '; + + if (!$with_spam) { + $spam_count = $core->blog->getComments(array('comment_status'=>-2),true)->f(0); + if ($spam_count == 1) { + echo '

      '.sprintf(__('You have one spam comments.'),''.$spam_count.'').' '. + ''.__('Show it.').'

      '; + } elseif ($spam_count > 1) { + echo '

      '.sprintf(__('You have %s spam comments.'),''.$spam_count.'').' '. + ''.__('Show them.').'

      '; + } + } + + # Show comments + $comment_list->display($page,$nb_per_page, + '
      '. + + '%s'. + + '
      '. + '

      '. + + '

      '. + form::combo('action',$combo_action,$default,'','','','title="'.__('action: ').'"'). + $core->formNonce(). + '

      '. + form::hidden(array('type'),$type). + form::hidden(array('sortby'),$sortby). + form::hidden(array('order'),$order). + form::hidden(array('author'),preg_replace('/%/','%%',$author)). + form::hidden(array('status'),$status). + form::hidden(array('ip'),preg_replace('/%/','%%',$ip)). + form::hidden(array('page'),$page). + form::hidden(array('nb'),$nb_per_page). + '
      '. + + '
      ' + ); +} + +dcPage::helpBlock('core_comments'); +dcPage::close(); +?> diff --git a/v2/dotclear/admin/comments_actions.php b/v2/dotclear/admin/comments_actions.php new file mode 100644 index 0000000..c90edb3 --- /dev/null +++ b/v2/dotclear/admin/comments_actions.php @@ -0,0 +1,136 @@ + $v) { + $comments[$k] = (integer) $v; + } + + $params['sql'] = 'AND C.comment_id IN('.implode(',',$comments).') '; + + if (!isset($_POST['full_content']) || empty($_POST['full_content'])) { + $params['no_content'] = true; + } + + $co = $core->blog->getComments($params); + + # --BEHAVIOR-- adminCommentsActions + $core->callBehavior('adminCommentsActions',$core,$co,$action,$redir); + + if (preg_match('/^(publish|unpublish|pending|junk)$/',$action)) + { + switch ($action) { + case 'unpublish' : $status = 0; break; + case 'pending' : $status = -1; break; + case 'junk' : $status = -2; break; + default : $status = 1; break; + } + + while ($co->fetch()) + { + try { + $core->blog->updCommentStatus($co->comment_id,$status); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } + } + + if (!$core->error->flag()) { + http::redirect($redir); + } + } + elseif ($action == 'delete') + { + while ($co->fetch()) + { + try { + # --BEHAVIOR-- adminBeforeCommentDelete + $core->callBehavior('adminBeforeCommentDelete',$co->comment_id); + + $core->blog->delComment($co->comment_id); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } + } + + if (!$core->error->flag()) { + http::redirect($redir); + } + } +} + +/* DISPLAY +-------------------------------------------------------- */ +dcPage::open(__('Comments')); + +if (!isset($action)) { + dcPage::close(); + exit; +} + +$hidden_fields = ''; +while ($co->fetch()) { + $hidden_fields .= form::hidden(array('comments[]'),$co->comment_id); +} + +if (isset($_POST['redir']) && strpos($_POST['redir'],'://') === false) +{ + $hidden_fields .= form::hidden(array('redir'),html::escapeURL($_POST['redir'])); +} +else +{ + $hidden_fields .= + form::hidden(array('type'),$_POST['type']). + form::hidden(array('author'),$_POST['author']). + form::hidden(array('status'),$_POST['status']). + form::hidden(array('sortby'),$_POST['sortby']). + form::hidden(array('ip'),$_POST['ip']). + form::hidden(array('order'),$_POST['order']). + form::hidden(array('page'),$_POST['page']). + form::hidden(array('nb'),$_POST['nb']); +} + +# --BEHAVIOR-- adminCommentsActionsContent +$core->callBehavior('adminCommentsActionsContent',$core,$action,$hidden_fields); + +echo '

      '.__('back').'

      '; + +dcPage::close(); +?> \ No newline at end of file diff --git a/v2/dotclear/admin/dispatcher.php b/v2/dotclear/admin/dispatcher.php new file mode 100644 index 0000000..9c923ab --- /dev/null +++ b/v2/dotclear/admin/dispatcher.php @@ -0,0 +1,34 @@ +What the hell are you doing here?

      '; +exit; +?> \ No newline at end of file diff --git a/v2/dotclear/admin/images/add.png b/v2/dotclear/admin/images/add.png new file mode 100644 index 0000000000000000000000000000000000000000..e892690ac5b45a68001c585abbec612edfa9b55b GIT binary patch literal 1193 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+m{T%CB1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+* zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxKsVXI%s|1+P|wiV z#N6CmN5ROz&_Lh7NZ-&%*U;R`*vQJjKmiJrfVLH-q*(>IxIyg#@@$ndN=gc>^!3Zj z%k|2Q_413-^$jg8EkR}&8R-I5=oVMzl_XZ^<`pZ$OmImpPA){ffi_eM3D1{oGuTzrd=COM+4n&cLd=IHa;5RX-@T zIKQ+g85kdF$}r8qu)}W=NFmTQR{lkqz(`5Vami0E%}vcK@pQ3O0?O#6WTsdd8k)IS zxEdO`89AA_8WFYa`DL%v85MT^vIyZY>Eu z$aTno=dD-j_Je$3W?%UK81FxB|M^L%F|8TPJq=O|?JxeF>hJYD@<);T3K0RYaVkC*@e literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/admin.png b/v2/dotclear/admin/images/admin.png new file mode 100644 index 0000000000000000000000000000000000000000..074b4068b21c8ada6cc16213e93030f536f85807 GIT binary patch literal 625 zcmV-%0*?KOP)Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUz?@2^KR47wpWPpOW>KV;?&Q8@2K742V^ZOsepFe*Y{{H#LAkWM8 z|H^@Vt!pL~)xy+*>6pst&7He${7YYP?tlJ@)Bj7Bo%kO;>)8LAmFNBi=JYh9C3z@4|%(|2A*i z^|G_GXL)UH?Tq~V{9bc&a|H$=AtA=Z#6;_@TeqIRapT6X%aVP}&;Qx9Y18w4lt*0xJdP7YNuNT;BnAY*H5YyYK7 zm;P!{K25D(&b{7|y=-}Ys5SRu4i-zZeTs2>>00000 LNkvXXu0mjfh6y$Z literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/attach.png b/v2/dotclear/admin/images/attach.png new file mode 100644 index 0000000000000000000000000000000000000000..f87bc77b50dadd1b8c89de269c7670268c93016a GIT binary patch literal 370 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=$3?vg*uel1On2Vh}LpV4%Za?&Y0OV!{_=LFr z|NsBjuV3H4fB*XR>z6NIK7IQ1@#DvrFJC@?{`}s(dw1^Kxqkin`Sa&bpFVy3`0*V( zc5L6iecQHe>({Sex^(HxnKNr^YpbfN%FD}(ii!#g3-j{wa&mIAva-_B(qdy{Lqb9V z0|PxhJ&lcx@2}d~2eg#2B*-tA!Qt7BG$4nwz$3Dlfq`2Hgc&d0t@{HM6f1F!C~+=I zO)SaG&r=A=%uQu5Fw{4&&^IutDrQgus!#x_2+mI{DNig)W$;Z*F3QhMP037DaLX)8 zEzd8?E>`f3*ga881*q25)5S4_BRV;Ofzi$|GEmN-JFvmEvAs83@J!;=#Hs8-9x|$@ zEV$+v@J%*p?^vR+TV}>#1*L;WPw1-hJT&0$Jni|3S(0Jz6xN6Gyw99~1~PcM`njxg HN@xNAAb^u| literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/check-off.png b/v2/dotclear/admin/images/check-off.png new file mode 100644 index 0000000000000000000000000000000000000000..fc5f661d721bce85d63fe782bad90d4e2e5b09a0 GIT binary patch literal 450 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=$3?vg*uel1On2Vh}LpV4%Za?&Y0OU>x@CkAK z|NsBLfB*h|{`~jTr@tRR{(kuI_k#z&?%w@%=gzO&w|`x~{$v0CZyPs$TfhFx;>Dk* zO!?H(^0BJwLrKYpf`SkE`5&^f-e+dMPfdN7knk=({#{($yO@}F(b4ZBBj1IEy$ub0 z8yx&LDCn)P?^{2=H=dqvJUm{zy1sFCe(mJ++Sc}!we>4=^Opt&FSWH_sH(n@le3E2 zoCtIqV@Z%-FoVOh8)-leXMsm#F#`j)5C}6~x?A@LC@5Cq8d2h0l$uzQnV+W+l9`*z zU|^_kV4-hdQdP{L1XQ5_QW2b=R#Ki=l*-_nm|T>fo0^iDsNj}alv^#UfR7-`qJDWr*qo7UN3*B olRo3-qr7R$^o?t(8{*mPEf(|d)VTkI1!yyar>mdKI;Vst0E=S9@8j@P$+@g%ubY&ZAdh#W(NcjUG9Q0D64(PU%^^} zC?>Ud0wtstK{0hob}>|1w=kO^YU|UMtaL*JI$)P(1jxmwlO)j80C~hOF_P5;lUj4X z4cq!#<4S+G!mDI`9jHwUSU`tJ25G&=aD;S#T-6ou-aV#CunIxl0rF2$2`LJiOdA3} z#ds8kV*tleY?ZINy7~a{GAu(gUYhlK*lMB5D=-XLdr0hNtDQnj46k|NC_p9=vILq= zrBYO?iZbmkn&o-k)$n>f7~ygH3?!#LhO;lPAVNp6H4AB`0bE77!|X)?5@-6S1l?Mf zHJr6;!WTxTWs7Dh#w{ril%)Sdb$uP}pcvf9_n*Q}yw8Gk3_517t>DIW?sKgyp~;3a zGVQo&_T+CdnlzE=Buxu6wfTW0E1KcPt9VHgB8G!xLxB-7KwMd0#Lr`Z+G> zXW01P@b!9aJhn9cNBCBJB!fPPCzwmn>tu6Se}t#U-L8)<4%P=B8hF}mJl2`yxQc&?W6_p)D3{Bv ztgI~mTKe(x``qHEFAML!E`0nt|9*CUX6$*-jj6*oCZeO02Ztxbk%{m~ws|<)n8`K_ zKdZm?Oc;8~4`sQlPnav?`!7D)d+9Ma|FB~4LHXJH+t1wFJaC&xT_;Xn-93lBicqYz zjcAyC*NKDnh}alUe`tBJb>}ItYx7k0#ir%bl3Tgl%|tMxo}!AT_Z%3lJ2xPmeNZ_) zcBuVcvTW@2_zZts_hc@=tQef;w=O=q(!8TCSkhSj=JUBg?AyxJQgLP*RkVeetuLKv Szc76i`w)>(t9Unf?DTJ3@qq#W literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/check-wrn.png b/v2/dotclear/admin/images/check-wrn.png new file mode 100644 index 0000000000000000000000000000000000000000..fa327f0e609396c5111896ace7e21a276cd22a8e GIT binary patch literal 394 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=$3?vg*uel1On2Vh}LpV4%Za?&Y0OV!{_=LFr z|NsBrzkh#!eER$2)q{N?{EKlck9Q4y&n%&eLPtGepk->9U1R;q`%vi z^ln??yR8ZDHpjf%9Q|%%#M_PGZ#RU#T_5~*UBKIQfp1oOy;jYXc2>_tDnm{r-UW|w2G|f literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/date-picker.png b/v2/dotclear/admin/images/date-picker.png new file mode 100644 index 0000000000000000000000000000000000000000..e35e932ca785f3649eafe142bd98c5895cbe4546 GIT binary patch literal 1199 zcmd^7J&T@I5IsvG#9+XW6d@pt*!uw~(kRE}O|nbEvcv@qSPTj_779wR^AG}lRQU;0 z1k3#mV_~7D2-X&ZjUpD?Dfsbv?*0ugJkQ)a%$+mmocrbB!Ho;&FP{f+VSjIP+woa{ z&zw8s|1bBS`T;nD!&^t!eAMZu(;%Ou_WG&6{{Do43@A{64om<<5G0ZiQA86%AQ1^B zGND8zIxz|N3xPt)jZs1iW2{0HSjd73Rp`PL(1->b*-)bz-IxXjG2kEv8q}Z%GXNNC z9OeRHt*ac+Q$~=%3@TW`4o=XuPJ1OOvdAXK4U&;7n@J@r*~v+oWN4M9D6zyAM>O-O zbw7(LRef^X*SiYW;ds4jbdn|9BNp@9?lR;UAI#%c~pzE2C`}q3p+y!Rj5M~ z!eX-q$~BIW4dQ;XzL9InOes~VPEER{Z@bXBwMuGfBs&o$^GT;lRqE1|Y)`aIGF{iI zR=1{Q&thce>C2-U^=L*|@51!#wu|hc?Xok=#fYUv#_Cwn9X(-l?86c$xnOF^VN>?C<#h|Np`L+uyvpcmC{=dv`9*oH_IT`+M8BuIcG+ zIev8SnKNe|+`IhZ+3kh%r=K}>prgI<_RVv*XMu`0ZCr8r;_<0ddVuUj z3ubQmr+)=#9cO_@WHAE+w-5+3Ub#8IXksPAt^OIGtX8@K|w)DAv48RDcsc8z_-9TH6zobswg$M$}c3jDm&RSMakZd z%cjB#s5v*aBvGLvHz%*ys=`(YY^D{E4HDK@QUEI{$+lH;1X-pK;TxdfoL`ixV4`QJ zn`~fgqF`dCXJl?O*Y5S&<|;FXxCU}UafWMBX!jI0a|txODojsXKDJ1!t?Qv55FG|-pw6wI;H!#vSGSUUA&@HaaD@m--%_~-h z7y>iLCAB!YD6^m>Ge1uOWNufvSUNJQAfWfF=kyxN_sAr%L zHyNnW1}JFdT$Gwvl3x^(pPyp~@xEJTQEGX9QFgI{bFi@uNGFOSgslkusV<2nsdm8d zu+TLy(KRv*F*LO@HL^0bj6%{6QG}-5H$NpatrAJQIas?HSi2!qJCY)(b{lJ#}JM4rIQ}= zH7oG6G-}?+YUuD$J@@AC{30I4)}8+r?tE{dFoomd0e@2`fkM$UGpro-{#{I*{e434 zmW~_g*BLd8j$OzyX}3~&PwK3%$>gW_p?3I z+U0~_gfB4JaXmAB#+~WRa~Kb#Mr^Bb)A_lMzklho>I9BE&GVM`tupFb(!M>IvrKxn z?=*(18&ku!ux$8fS->sIaO~%jwu0=SUZzsDy0s0rKLvkEud!oE6npZ!VZA)iHw>Px KelF{r5}E*DJ>Y-< literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/edit-mini.png b/v2/dotclear/admin/images/edit-mini.png new file mode 100644 index 0000000000000000000000000000000000000000..890bae6452b8a54bfa35cd841ee774f8d9498050 GIT binary patch literal 614 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=$3?vg*uel1On2Vh}LpV4%Za?&Y0OWoP@CkAC zx0SwkD!;X>_vixUhmW4tRur7MaD8dL_R7`Ech8JJd+O-XmCpS!TtB~kdVFlg;|p_c z9*$kV{phagF%zqU4=%FUw{PFfnKQ2+2y5?bEeevod-v9-PoK`rWVnC#?EnA&SGG7^ z-(=JmFMjms(F03MP8{BO_w0^~+w3172n{!4*tW6%_OXon&)zPX)!k8-d*kN){)xTs z&gSo3*0iw3>e{K@_wL=hzsvQ~-Yqw7T$`S$a&k@Jlc&$uwCO#&vbwXoZSvF!4b^$S zf4q2lW!a4#9?uTNcQ=2bOZQAqUfJ&T?B27BS8kj+bEYF&_|fC*eQ7F( z7L{K+cU1UNYzQy}rMq>1fPxAot`Q}{ z`DrEPiAAXlzKO|2`MIennTZN+nMJAP`9;~q3ceA$Cu*qx)rx`CIv1rTmSpDVDTHL^ zrZN~9>Kj<-8<RY)8l1R2@EK!~&zCP-Ty147bweCwgw6FT>lEvgEd|;<}v!PC{xWt~$(697~aD-{3$ literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/favicon.png b/v2/dotclear/admin/images/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..01fa2e27e9df4c03c31cc8562aacb963ac35e0c9 GIT binary patch literal 858 zcmV-g1Eu_lP)iz^d=O_&y@3@78X?Y!$1T4Jv}~B3g}NT z@Ha$aWq`n^>17%H4@P2quu*m+f>nEt5txB-F*68bLo%8G`a;0%cEjuSUOUG13e;pW z>A<2W!awH0_RcQS>2&W22!a5oQ$R4_$HSlxK938zqY}2Zayqj(Yt!k|`AqyBUQ-@qP&KJdcqPHW6a!4Go4x37TTFXC||1dcOZyVsdqk;<;=`)#wD zn`4FI3D#tVw4ZAG|6C_CVcpJTbvbfs33<}D%lUw`K6+uSR;%M@YzrG3GLfv`o&YnI z@vwLWI755wCT<=x9*(2e*46=+efb4K5+5&*3-8(oxHXF#LYFw zZZ0`=W8VH7Gk4#ZwBvg3*6ZC{u6Jy@*0k-LKlZ5Iq0FX%U1&}+D$Q-5Bq`n+oOdF86}(xvCbip~kfMH?3pCQl$&H|6fVg?3oArNM~ zbhqvg0|Sd-iEBhjgs+cPa(=E}VoH8es$NBI0fUWwML}Y6c4~=2Qfhi;o~@FCf`XDl zW{Ry+xT&v!Z-H}aMy5wqQEG6NUr2IQcCuxPlD!?5O@$Rub8c!$qC!P(PF}H9g{>0U zOe-K8B&@Hb09I0xZL8!6vP>buH$cHTzbI9~M9)w+*}&LD!Ng3@$lS=%+)PIyII%>* zD=|;O$Xvn5zyL@XSs5BynHT~c0|rWVTtM2UC?(A*$i)q6Cy-~Wlu=SrV5P5LUS6(O zZmgGIl&)`RX=$l%V5DzkqzhD`TU?n}l31aeSF8*%1ZIv)YH@N=WKgSN@ zeYeb_)bjkI>|zDyU}GDQP83B5TM_zGT@p)D?SSE7p=)5GYh)N=Xli9@WMyg@g`^*% z2u-_heoAIqC6aca31%UNCRT=KRz?<3?MRBC+HLef0f7`S;7|wo2~C_(fTbkE!>gdQ zC+u5Cats;6w|`4k4MjsSE~|`i2(z2Byrv z!;^t3WI!r{^V3So6N^$Au%zi3*W5rQaF3^pV~EA+WCK+OiMGW|vaFh#mAZ4dzO+aj zXb2bH&6I1#rjZbIc$LEhM!p?B8#Dsgy+3|z)C|?(TH+{lXxXwk3Q=O+OqPZU0Y+C7 z7&QZqiSqqgbVi}F%vpx3XU9Rk2O$SV1B?+V;6Mt+Q*I`)ivgR5kWhHS|{2b(Pk1mDRMDR(F%i-WNl$NtKD`le=lt61C+0mo<9+$)?E5FI z?;dhKx3}-c4%-_$bdGJVJ+!Xm@(QJ0OOkdjO4vLrc-IboFyt=akR{05#H)4*&oF literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/logout.png b/v2/dotclear/admin/images/logout.png new file mode 100644 index 0000000000000000000000000000000000000000..ce75f91167f5c5b98cc6c646c8015014ebe132f7 GIT binary patch literal 915 zcmV;E18n?>P)DQ67S|3H;Rh4I z7Z~#B=+Y4u+Y1!X5*D-=7r7W0;|LSu4HLf?7}*UKy%!k37Z>Ca6`MXfycZYa3lp#y z7u^aJ;|>$t3lzc^7r+`E-w71n2^6&>C%PCHyc`|6939{Y6r4Xg)DRZ8ASdGq6WuH# zrzIt{B`EOY(C}&Mh$CHmY3lhA&)jU@aE;WA}7=%9ro_-(IOhxB_6dH7w_8Ix>Zt`J2>|6 z@5v@4!5SRLJUp-{Dg68Tyc!tBYHH&S6w{cO%U)jJFC)*3ir}cGDCMdQZAHW+P!x>#I+7T7R7#O!07rtO!;wmoAadO<5nfv$m-C$atBqXaPCcPXTtR*I@B_*IFB(x$Y zLh0VmK)Fm5B5|6uSsScw3de1=z?*@OWe6ZV0r!zZ;^G|l7nLCeBe zMhQ-I&k=YJaC~=YLdf&j#OZVwg3l;~dSMiynAJ*-qNIMgg(|cSJBa@?J(8C9vUph~ zxm9hz*R@HSnF@(<@Nnd#;BUctie$cHYX7lxEy4et5;VZQfNJwfcB^kKE>CLrRYXG2 pVRdM1z(IONr(ABeK7IcQFaQO>K%T#JickOm002ovPDHLkV1gy#ih%$C literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/media/audio.png b/v2/dotclear/admin/images/media/audio.png new file mode 100644 index 0000000000000000000000000000000000000000..fec7e22c8e7392acc5b8297bc09be3a7ba5d89b5 GIT binary patch literal 1170 zcmV;D1a13?P)#2%*=d>Goq<`ov1k>1|kXmcw6|Np(c zy~N0@i)_bi$ajK1mZ4o^aUgMiE6df4yU1&g zn^35^LYt#+#n6P(+nt4xLfqcYsbjgLa3-jUyvRbp`uBp za%CcPQQ16WDn0;aonR=?vbO>?-N%1cz4>h<`0zO^wl*4fDdpw;sKFc1=dXXf`Kg0^Jv!PCA}#u7h+9<3>gnm}=;-L@=jZ0;=H=z(T|N#K6G7yu7@+y1KWwx3#skw6wIdv$L_Wv9PePudlDIt*xxAtgEZ5si~=_r>CT( zq@$ywqN1XopP!zdo}HbYoSdASo12=NnwgoIn3$NCmzS27mX(#2larH?k&%#)kdKd# zj*gCvjg5?qjEjqlii(PfiHV4ah=+%VhK7cOgoJ~GgMxyBfq{X5fPjC0e|>#@dwY9% zd3knrc6D`ib8~ZXadB{PaBgmHYinz1X=!I?XJut&V`F1tVq#%oVPIfjUteEdUS3^Y zU0hsTTU%RNT3T6ISy)(DS65e6RaI0}R8vz^Qc_Y-P*6`#PpDqW{{R3032;bRa{vGe z@Bjb`@Bu=sG?)MY03dWlSaefwW^{L9a%BKbVPkS{ZDnL>VIW3na%FdKa%*!SO<22; zDkJ~^0^UhPK~zY`y_QXG<3EV2r+$Q6=FV0lc5 zKV8*XbdwS#dVp*~fC54Ft9tKMRW~F5@rwT!;Kz@WbIwvPRaH@upjw_q{FmP^0U!VP z`y518A#=H(KCJ+|=O3DRMG#=KZ!(C?zV7@8PtS1QO=w|-=3853?p7O{{Rv|?oC1qWHpi*TN*lfP|@Cs`1bVvZ&_WkB&EOVK?)T^~P z0dVK1Hvl4JIFJKir_=?&`7*beaqAKQ4F+msQ>`@4`|2g2bobJ1;qhfEt3{Sg?}`!v zHs7tsks@EyriLc#0m7IyuZ2W>^7! z{@k7a*Yl&-Aj17mE5NV6wIKUu-!xiJ|LpFb-P1UZeP&o^U@W_fgxJI;gs9?fmeQ1x j_*{If800000NkvXXu0mjf&25Wr literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/media/document.png b/v2/dotclear/admin/images/media/document.png new file mode 100644 index 0000000000000000000000000000000000000000..5af28a8658b659a8ba95ce3f83e03648eda008e3 GIT binary patch literal 762 zcmV@Bjb*WO9kR&c2SB zrkAhD=H}+i%*9k_rJTCfnVFe!dya>QijJDHhl-5% z_wJ6Is+z39x6Qwll%<-t*JfsBX>^8@rMP;2g_)U|V!W7QeL?Lp*;u!qxG^0j>`c<9F3L&+O>4~7&!_i1aCn9=gRQ^zCsS(|G_$~`07f9{&3g9z-MAP$ zlGe0O-+#BR*6SQ##o&%5%d+D*%cUdB6bL-fKWahh_lv11D|S=TqLYB@np(J*6uMC` s=d6Jt0=l9oH8#vAY5%aR2}S07*qoM6N<$f-hTh-~a#s literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/media/executable.png b/v2/dotclear/admin/images/media/executable.png new file mode 100644 index 0000000000000000000000000000000000000000..bb830b8924b2578fc1ded1bf989aa444216d11ba GIT binary patch literal 1240 zcmV;}1Sk86P)}rvLx{uC~ZYWs-V| zuguKMj+?S(fum$-d@fRgy}iA(x6!7w$%~J%-s9_6Zkc_7pHNkBW_hE;$lLe#_k@bA zLt&1qtg*|@-1b9alc zy3dW2y4~L6=H}*RbCXnEdTV^8w!_qUhOLjAyT!%DRAYruRBm;FppK!tY;1xySchX| zet(U!gp;*&dy>)8*rlz#O=y(J%iVH)qot;+ade57sla@FnPYRMl9i@qXn{&mY*AWu zgpIVFqr{Szyi#kNTXUSPwas&js-3OHij}vtyvvlHzPGoxSYCNQUW{sZn30~fy}!`b z*4C%6%C)}JmX@}{#@Ty(mzAc#aDAIxVtjUksCpgQaYAjA3n!p`@}pTZx2} ztx|KGYn7=SMlMuy8m5*5_g zNt1RGM-E(uu`3B_2M2gqOw^JYnSz$*^!I!3Wn;VBu;ZtmPn_*}wwHT1Koj=_{kNcs z#CrwRn{TRkkDz)pBfRu4&{K@bW`vl)-a6;0D(c7eRUU?Ro)t(H{C z0I}6!foz|*WsT79PYJ}%7)mJg-YSsoJ7u#_h>zz9Kg|L$zG)Jzb&dP|3)7c?uY&?v zzUGh#lBCRI;!764=nm3AJ>s1%1#g}cbTC&ae`@Hr6^QEFG-Df+X^b=A8g1vdy{^IYI=GX-)rsZXI}OE38?<(w+E~+go(ER}dbaO)mY}Fu6X)}7(0L8ydcEGe zoE!Sir&UxpuBc3gP}-Sp*QnRsKJz}1!W;ropN$vy!Xg}^i7PO5F&qv*fMN`I zJ-)qH>c9b-Sj8})KAi1zO2?@9d2Hl~oH`qW6_Ob8{{>5M6J{y@3PeT|00000p+)8Vey}i9tg1K8;Tal5FQD}z3&)_?0rt$Up z;_33Ot*vHpe`cA?jIr2omBXjQ;Y@d}#l^+e*49!|QgU{BbfM6DdwYGR(^YVkwaw+D zxzXKTyKb4 zh`wx*zWR(z?f?J)32;bRa{vGe@Bjb`@Bu=sG?)MY03dWlSaefwW^{L9a%BKbVPkS{ zZDnL>VIW3na%FdKa%*!SO<22;DkJ~^0xU^HK~zY`-Ii-}lRy-PlhAgtw%lr(x=LIp zEx|&JaSdssm9b%@cQ5pOM7{*$%EMR0oFbuaiTA9N` zcoK$Mz0D~Ju<6(q!~(lu1lUs{z`%>&eK#axxjb0^_$jJqa{m-L*Pa-t)B_W2C z+s=2HFnOH|3if|YC4$#EI~4+<7JapIP@VV2YhMZh51;Qx)p>7x@ly!8Z_&qV=T&*b zFwXb43xN%H&zjYFBii{Ogx1jVzjemf=8ZWA(`SXCXh-ilRpq(hJP?AaVc%{}R+BS8 zq`9!!E(Aqek2cC@Vq7JP^RLx?iMQgYBFpi{n|yjckR4N2;{Doh_8x-t?iA4B&+ z2s&~L29#S*6VuH1z?Hho=N6Y>9L<3%m|r~YrfF8bG)4K!k`&$qUJl&VAq(N)y0IGo hZ8M|IZ*JtT!(Ym_)8#kqCS3pk002ovPDHLkV1km??hOC{ literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/media/html.png b/v2/dotclear/admin/images/media/html.png new file mode 100644 index 0000000000000000000000000000000000000000..eed6e049e42497a1b4dd4c2588ced234eba860db GIT binary patch literal 1811 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 VLnw+QwaWki002ovPDHLkV1lf+$fN)O literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/media/package.png b/v2/dotclear/admin/images/media/package.png new file mode 100644 index 0000000000000000000000000000000000000000..82f5cdff6fcd2f3f7f071d283f58d6cb563e5e54 GIT binary patch literal 1153 zcmV-{1b+L8P)$?e62@9*#D$CS^qgzwLs&x|6sib1t{8|vN3rEnSP)wb8u%)**k$dW$n zzk2S+jPTa1=Co+ln?T{OVE_OB-oll~q;189BH6{J`0LmA=grlgO7!8y)3}b^yo;@U zFWt_z-L`wo%*?8FAgFU7?bx>F$eP2hjNabfw0k13gE`m0ox-PlyNyE3q-6H+=iS%N z;LWe^%8vK<_tw_d?BUL$Y7p#j7IU@z2C*2u6ZHx z>D<<@a>Jcs%C(ZrmPE{%GvvO5!i+b?j48~A9lf7$=(=;t#=zdal)HW$=*yk%)2Gh?^N|Nl~Uu`3V-ky?R!1J|sWOB9zv7Ey5p(>gGL?a*} zQACo2Xz>EC$!+%6CQDqbB}jyKcs^sBB_^)o@%YtcoS2_@8NI*1fA2XwI?{28W{?#s z{LZP>rE>WFdc8ijzP^5ay`7y)eIRz&Qb`B14?#-Edluv^gR4urLAj+^9m}QEpb)+_ z3Pxj~$K*j%VDA{3OhN$%`#CPWSzrQ{9+OMN4B=9ktP{%2zK=R)V!&t28(Kz}mL4aG zI_53sEEXqM^-*M9iG@JA-9xKF`wc|kGe~ioHG4)f$DH$TVs@rQQGi8u=&FQ zV3D`(G@P3u0HF0=0HyX}*1dag>8=>xC_e{f>tve`hXgD0|4sOOY z3>G^AfMn~ShLsFNQcEBqyIfh(u|l0YMn5E5nYvWB1I&`$sP3>@G`m>!Y6FElKs zp-3aOcuIhmMBAZjX0gA6A|pO7NiC+Tj@IXMyj?N)`C-1ft@M;2aD53E__S(2D#;h2 z?P4;S{D@r=fy~Uzx+^PJSyk#~)fUl6L91Jj z)*}-vHsTq@@oYWEBOdjNM?Gqk9byl!f7@LGlrwC&-q~ed3F~b71 z0s-i%%z~=ReZlfD8>SRi5N#I32|1httg--waMFs>l?Z}Gzz89ZOyWE*i1{VpP(U*-zW4PCTb#%lJQbY2EThD3uaJzkAwtlLU zDj;Wt*B9TA@E#5S(rSI2OIAn;GHqy#cGI4%*IRFghMtYY(-X47*|8o?|L^{drAG@3 z_g3N+a)p(BKWR6oZ~u5QzJKZ1i?!r(eud-Ln@!Tq$vguIKTQ?lJvT^f+McPc1K3~wzou9gSV*9Tssoj$!j|%FV_T3W)fTt34$cxbov5e;0Kx&q9s(NIQ?isN*I_NWCbN$LMcrU zo+AuMPEj&~luxlxn47gisZf}^L;!$IC?_HC-E#Q2kfAEhkxo$Tf7d~ z1q=nQ1~I!JPdGJte6R|f;gLCb2FEC<(1Dg9kWpn3fMfEI=0=b=9Z(_wfDFem`u~7= zdWq?-$PwsnAu+BEdC{YX90hqI4{bNtVR0ddc9Ch?)24;35Odl#O{Doh6yHe-64VVt zL^u*K79rH36bOkqP=_2t9On-q{t9p$W2_B&vC)5ZJ;gv?Jd!@_t*00000NkvXX Hu0mjfrtJ+~ literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/media/spreadsheet.png b/v2/dotclear/admin/images/media/spreadsheet.png new file mode 100644 index 0000000000000000000000000000000000000000..842750909f3deb0bd7c8529330b7d76b2a6e0309 GIT binary patch literal 1624 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 N002ovPDHLkV1gt+Fk%1z literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/media/video.png b/v2/dotclear/admin/images/media/video.png new file mode 100644 index 0000000000000000000000000000000000000000..a0ed12ccbcef5ead8b18f29f752d657bd47d5299 GIT binary patch literal 1250 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 literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/menu/blog-pref-b.png b/v2/dotclear/admin/images/menu/blog-pref-b.png new file mode 100644 index 0000000000000000000000000000000000000000..47ffc037e0c190320fe8d658de2b859be3180789 GIT binary patch literal 5339 zcmbVQXH*mGx(*;!5Rn>b0i~COKnT5eX@W=*l@J1iKmsJxNN-A4P^w`oMVfR(N@z+) zK#-z>fJl>$(giN=vpx6zIP3hlv)0Vl-sgGytTpq%+*F^5;W7gN0AMmS(6KlhHGbc8 zG-uCZwAYuj0Z7obAz0#^34RD~6hPAn=ZFFsdLUd-7AS;MfL9Mn1puIOLf^0<*q9hA zA#onkh~F~O{vMuZXaGP(-QN>|#GnWuN0bX1t17tB*dho*JE;m(ujH>P_&2Z8+5Go5SP=BL2mzxi_%EYu zOw2*rIBygPCJm87LgXPJc^PRLSvfcyE(wA{WFTM&6f6Ukl7TD9LX{v8&_9>pnKo}H zXC(_Ay?=C_tyBeF2?S3iFxbz}Pufpb8t3f-mQhqx{LKM{N}Wka;RCP)gufIPf8`H@ z4hoO-Mtc&_I4tNlBf=5qLr@hwv-DpsczBwa{F@ky|0hsqAp`p(Ji#*35U_{GZ@>PQ z#uF@1|7*s7l*Zo(@I-+vPEnUI z5)5@z1>VypDpNE<{E~K>;SOCkvH_D?;IV5G~jrj{k(!foSVO zpb)60CR9O2Mi-)>EvKuepr@^=rwEnTm6Q2{HN@fx2rLryM=$zJ?>|_X|B6-8_C_HH zIPV)coco^&Fn7ffaCldoCrH~82C_zDop65m-^uxxuR17iv@gm@&l~3f`a8Nx=>MQy z7pez=!XOGzn5O1$ueEd_Fl|j)xV$`ER!>e#LGT}})Bh)8;4@>uzf0r)l**s2v-@?2j*l+x!s#IYrFk@;pJ81V~+RoI;^y$%9G5&P%mhg#13$m+NKs&mLBqj9} z?zA*iTvjIScYL_xv`F;x+dFMC|L8upp&fI<2ZchNOmqeptsL%<$IEUX^$q7=!?05K zXTti{rd!mjiF@k_^X%+ktJE}?-oC!$1R)_IzsSe<`s|g}RRS+B@4B15{z>m+iBtO; z&smxj)tve8wVfRpoqAP+lC0xfy7Ee6;ki9!MBn0%3%M8g)h2H@-vd6oQ(RK=`R62l z(Boa^&b9vU<;Z}@x{I6Pxv-H`3>rNv+;aLv-U*ST;Psqa-aUQK*=a62K)Z8*jIAnv zOJ#KJS~dQCGVgxYgFVX^ruD}O3G4e?&f~#FQ?+$z*~}d?i_SqN0QJ|>r0aQ=eP6$cxj;m1-m>x;#nG^C-ub40Ux>$G zF!;20DQV!l>zzsb8)W5BWPZ;`ZfH}V2%Ouf;awKI@%$p#KMkmiEiK`>zTDf31B+g& zqh9W%8K~cvZN9mU91GkS$pg83-y` ze~xDI%Yb-=mlPLoUuK0|cv2DQYqxp#P~}@I1{i|5R?>JlVzxd}iNr4SXV7;de!0KC zQg2&NQUJ<2$8*{&V?0T{fuWD)5o^X)r2FA~z|q4E<&gchr@T(o#w3-GOttBe zd7=YxQMR7e>e9m#X9gTgw?{uV^x?s)FCR789``Sgl;zisy3{0=SWgw0WKC8Ns%5Fj zUf1v|Qx4GdGY4=BK+-vK;33U}BaB?3R+&Z;6y;aBDTXQ(?XxPatgVlD!y~j57EW%m z9%@*oaJwv?IXG7hSiHcil-ezvQC&Gord&nUYx;IgtYl_o9WT1~jb71D{5i(P|1iH* z$iglth|JI5j`UCgbX*-vrCd{Ei)w$}+^ayr(BO8b)el@Ug)|y;+PNgw%1@id?M@9b zFCBCUso@Ix`CdP$jAPTy{qT6Q9*_OG^gc){pDTFDPvyK&!ev;mL>RKi77+e`HvQF) zx*n=+L}>5qTN$bZOX;yLZ~a6bu^EBOxa^~mMMqr%*FY%0O41_1PoFEfZ!f%mke!p?OjP(8{IcV|sx@tl0^b)tAt8Ypmq zV!$LF(nh2l2ZW1icPBwFlFVn*i3!Zf0cVfJ9=3hw=EIrJla^O~IrWKun| z`mYMJk+3_IRI`ChYGf9_P!5Jzc%)5*Ls&@C5chllb3D_f)UX#YU=>xWO48Twsserc~OKr`h>>sx1Jj`!SL9;g5FbY>A>;VZCN5Tag$!3jb%X zgyJ}f0=f6$cY$4E?Z*f6X{vUXslV1nt;truaPkU(q%hqNHAyROck8|L8;{l- zr%(*rL{dt) z-7Mc7J84UIJE4&a+-CFOLMfd{ zsvN49ZQ~HXIIyF4>3S@?P)3TJ=s2pPI1FA)Xi9cQsklPAx@y?m zSm#`@5k{0MRC|_+g|~`^s5GB%_((&JuOtn2AMCy%>s<(mG>XF8au`sa3>-OqdnUS<}epBp!tSG=g=<^t|@wnvDBf{lQMA`dyt zyBJ30To>ko0b-h7;WL*=o}iGB)8oDMrT4j{n67-$2x`WBz*peAMEM~Wnr@?+uD&Oi z=2eR~`9gkqrPX4(G93L$_nAw*Kfm%&>uify9(mCS!;D=WloWPvqHhY4(Y-qY5noU- zifE%cv@naLMXMitV`YZWCHVmJ)M|4XO=NkYX7!FWDWw8t$@6S{mEqt!O-tnPBfxuO zjr|l6v%|e@Ml}i*HV_|6^Zku-&tZ}+7jWeo^#%gp`wE6-Z?zn-td zFPet%qW6nlkc`$f{rx*({!wCw$rM{UvPKPL>qmMAWuC@OR}3UKLsQ~4f&R2n`f(j) zG&~#G+C>n>bIzg9hqomkSNPv&iwT{SxaaEX`curZEOFRLqipdbgSHqKE-tS5EtTU- z0xdJ(Ufx=mc!MLV@Q!eY_|8(trSOs;yWG>rnQ!n&7ncYF7U96LsPmlm9v&Xg2__5X zlFu~CQaFpAeGL~F>6A1)fA!^@R%PRsgAbzOCZqTAhwg&)I2usf0h^SGjqB!LIsN#H z@&(`Av%8*e$4cFLbu~ywjI?2&%Oq5!BbWT)Kr@#ki4R96uN=eRaLu0`!}6^o%t14c^8i9A-f@JYOqvP~R{GDn&4ZWMctqJJuo`Xj3)83HbBF_ltFuE}EIu9A%mJ+24$)P~sbyk~6P_Qq?>(0zaTCij zMaallwosQmRlraN97jqLs%j&t5)UsX#ucD;Rf&5IA>`9$5$Ls-0D(LDKrch_auC6e zew8uajVZ08@ghT84^5u7{jF9}>ZM}_-Gp0+qAB&hNPQqXBKmcm9U%&ouBSiDRsZ9u z-#*HwA0 zz2`s)MT$2?7+s&YI-;XXZ7QFe$@dj#3Yb2)VHM)PZMgCMvm55UhvOFs)AbtuGn*wi{41UoPMn^=gn;Mh$^Ef~}7cb1-va?eqrdE9be+cr@cu!DhEIECe+EY~piW1f5MaGiGvJsTd*LPoRkIYrASwz3w>n1g{MK%-nx zlEm;gHIt`ed_Qy3xkC3AvTzN9>Zg;eIq8F4JHCOJZ)MU-R?>~nHt^ru40FMYMt-6E z2!Qh<_$XFB5aZ~_rt8BB+G9s0xBC4$*=H#-fr4u2@X+Dncl-h09_BU1ns1QzNH{MR zzYkk0UhC9-R1R!K-#Y-uiYD{)kHDj*WKTG*;h)omeJEW-e61R z#SK+1OwHM470F6U4lt=3#OMWDfB#bo{91uf zHzA&wq<*51G0=I8)M9%vq;Lc4yxHQ$ptfq9R8(n~%78&SQnd=IrP&}NK$%mBDW3pd3-H)CJt>8%xX5tM>v=` zXBLvD-vkj`irA{N)~GWl$-Owd75890(&VPTzpvRUr7w}$9P_}Qd7HIPhO>oLp8XnK zQt30oy6u%n-^j78pXnTuY`M=nT-_SXzk{WwmK5O)Cwf_jp`Ua=J~Wf)xMAc1t1AzI z4sTns&5n;xQc^P#jvd4_yqEYjKWvX1vA<&vq%KT(9wPB@%!o2JEn1~{L==1uT|<$_ zMXJ!kM5Tw!Rkw+*_uEznLPL8oflL7YD67KDiUTprZa!G-W6GK|ozVj5?F^@dJOjg! zzJbq@Q}0c~0rL?<6&))JM!#N>o7HUR+lDWf{ix@sMA_kLF^0;v-03awQU=XRNeB13 z6?`4gGm1#fXYQU$P<1$We?pUvCQ+o~#CMOR8eGq?*u6rRRPe&&>GzkOJr+z>LSm1{ z6cs~4EK_K0hc6xkoPFkE3vV|PK307$3(ezz?0qR{ze<)tXmVrLGGQcJ7*IKqq70S@ z_>p^6SW-B$=bAH4G_v(#K|$9oH}<8Ww~r zGYYzPcktL^irYhZYipZ~WfAZJ;}5*e&5jE)3D)s44DqeMf~6!QkQbXZd(~Z|qvzK? zrAyZheaRGUwU|*iE|jNd!__o;`HU?fRL3?!-=2h=em<4x_5N|88F@PsWNgN(>f2vV zm5t@I;J8n_ChnYYkwmmTm>oa-ahIn~=Hz-qLLE~EIV`G_qr@!B>I+mr|57zwT*u6j zXmr>}^KhnC?3GjI2NXL8WEIK#AH+QeC06$>TwO|Lw)ZR;qYTdr{Bm%n5VvJ?o|$r< z^WO?%myl-{4SiWww(cj~8n-Z9!t~TyL<0V-v!*d*P2Kd(X|9=+*V>-Kq1sHn;Is_m zzE%YMbG1JPGcjFkOFp!L<|#*QoDQ$4Q!)a|?Q-5MXME`V{kzdn*HouW%OU)K07^ip AM*si- literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/menu/blog-pref.png b/v2/dotclear/admin/images/menu/blog-pref.png new file mode 100644 index 0000000000000000000000000000000000000000..6fa527fddc5dce108c563d3c3d1b76127abd5f48 GIT binary patch literal 1621 zcmbVMe^8TU9A82~I<|MddtuWl zX@SKdQU_KlV1(l=q;rvUsVHXtCbgM)saTp|(c#WKLT;qJ184nV{n2yxzR&l0-tXu0 z{r%P~$<2;o&SWwej2O*AL{IPW!6)(s`ptgu7^SzDC{;dXAc`p`N@5JTnJB^ljTJ4y z^cZShzwRuS!C-`$abrG}uhYUN!pcK~Iy{%vPNNx&j4YQOHCZqUD8fo`n~dW>e2fF& zW*KL>NC)cdN~{!LxPinB8*+`N4HlEs%*o0GGF&iCV8tjDa9PW24%j8*Oz^_A9K7ap zfC&}KBI8Utm9JX@CNDa3$a z4ikynDV(qYK}NKQD5qo`+SADptahF5DY4D*BvEwA_%77Whj<|0Y7NFUq3xjb*xznE zQ`=!&Z^!t0%t4fsCb}NQNg*(uyZ<&6RHVIu7n3+$6toN>OyyS0MrjZkhyKDd<7OBU z$>oq#El8IrKotnlq7aeG(^Nu{TCGkKC_)_1!m5-IBos(N1(Ys@AQh+(LUN@@DNYAP z2qZ}tgs>W$gFD`-R z#@Awrgw3p;k|~^86HZt7_STiQrkB}tU&P$9Cq@JU2duNQva{FC3uHJrECfp+Y&V~) zy!g#6%WC%i+S({{SHa%PxK^uO<95&TwsSZ7{n?N1guC7Dhazc>um6>V88gsb+~^Yv z{vZ-6lEXW`EnQPlkx&dUD&ykfejXT5mFzJ;d{4VpjWT~6WwE$d*5-{S68BGxc9cH$ zZQqz#-`18CGc+`$DEVmGRvehK^VI3n@8)`l2R zx4&`V5O3|lnKyC<@}{so0r%(K-M5E^n2(XK8Uj`JGxDKqromvy*}Xq;_w>b)EoaS{ ziSa!i&+}nnVae~GkDpUjO{UGP#tQuHzCGv9FWRw;h5Mt+=I^U*ZGAO5HZ}#gO5`?( z-Bp91WRb>^@%j{FO3Sj%yXM1i+CF1SYiFlUx3aL%*X8v>;U^o4yl)rwwAX0$rk#vMGj*W}+dc9lR z(9R!zxi~U%ko!SP%lAjYJ7m)Adef#&tGXP%Ri3#6o(qz;F9$zt(%{6ouJ9|v!^3q4 zwnfkB{Nnf`nM{_lC9u*m`eJ-X_u<38k#oC`92xJ84fFxMeSO;TV~jAyJMCrVZ9dtx P;E!IT%0)g^ta;-v_*h^l literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/menu/blog-theme-b.png b/v2/dotclear/admin/images/menu/blog-theme-b.png new file mode 100644 index 0000000000000000000000000000000000000000..ecbc7c489255c243f57308f284f90a8a043113a6 GIT binary patch literal 3925 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 literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/menu/blogs-b.png b/v2/dotclear/admin/images/menu/blogs-b.png new file mode 100644 index 0000000000000000000000000000000000000000..33904fc55e0c5df40c6d5f5d2d1db3da8c1f25de GIT binary patch literal 4371 zcmbVQX*`ts`+i22$&!glLYbMe6=sZO#+rS}*d`%M1~VAT3^S9h$RKMAr;;^GNJLZ& zN%o?sMAlMN_G1YL+5Y34)A|2ioX_vY@A-V5=eyn4b=~*CbhoMnQC?pDvR6;8#VKkJ{8YmR( z?+3wFqY*td@P@{JYq3|_2yX@>Km&;k4h~ifR#v3aypT%j>gu~3XtV;`LV+GiVYr1T zQ0Pa0F&L8Q9yD?QgG{Bsb{XB=splEm2)3txh2S4xVetjbNWB63Ijjw7Rhh#!z2h%@AvBgi=z%VpY|QmCbSuD72BD9vY*hWQ4+EFb3*Is%q*e6voI9Yw!zeMxis@C?2F=x@5NQ-&n){iq$Zn zk=z(mnk|*;_p1V|y{QZ;-J2Q!GdQgZvnNxC)L{DV<@^<^A&Eu~A`y*gRDal?+0`Kb zi@FiY7=>0vVbQ93db?5U8=_PV^pr7bY8Yi>6@4t?Z!GbD$rzID405+L{-acWZL#Zb zcluA^vlsug4vE6<7aF@Ul&&7V#coz3GebSwkfB~DbER`rYhf!@Gke0S2K~mX{G>~{qnj2MnO{GjIa6g0H+t+!OXDtm zkH+;}QA8?O&CbrYKGS*Fp(Tn3pXUQ`(!yrpYn=;i!z}8~=KDf()@DS5RsZ4Za)}`; zOo8=??am2W>lH6)8JV4h%(prl-)EOQl`l0?hfr%!cX)cqK-H-;QFH4ub@4EFUIrvwzV z-p<@Fn6=nF&J?qVmJ(hfBF6gA?vadRV-KHdU73| zpYTm{`cU4rB9e_R2*1E-nni#0PBu>WBN;RP{4;M^m>8zf_6 z`0o4c^{<;arR>sJ;sdIwuBd=*ij7~H{~+2-B{&y-2 z>i8(W#stz)KE_=yWihAt&Jc97p&(|xO9Av7A|-w%DbONAlatdoWq-qFgtM!w)4erI z=S}VxgTt5af7Nt1x3aq4t{B3~P58)VT?$!tv?#y$o^jlQzC>@HkBg1vv_WUQ_G-lH zkZj8f&VLmC6#stcX9lGAOJi>Q!lT*PibxqX42DdhSQgZmmzO7sSl-FHorm;xej9%sLR0P7kEq%h=q z6{buf3FP775e4@CKz?Hhn&qMfA`|7I$nfy+=4XYsZoW;}6J=tQ7y?tczp1To6=b>B zK$Eg`|X+?wkzQ9P4UZVF}8Yv(9({Ku0=Bct7QOatbVaEqOdwX)Wjz2c*k-=(c#DAE*np z{)4G<{{ru)qA(M88Th3BPX(`s^V z!Kh*?HOULEtd6pN*gfbd4H!lc z0H|uxLy`N+ALa1wp$dX8Dy1u*K05w!yfr}>5t2x`VLnt~$Ju1JyhJ)DsikDfB+a#7{>r!p0M6RO;?dS|c_B1Q*Pt{V6pM2U{?Yve5Z8Zl_N z-pAK?$a!&ZPuw_(nx`e)!F{UgL9Y-9xMVP0<|uSy4#t=FgW%ws&Q}^3l#nS6q)Fy8 zO8Yri`D%2Jdi!Sp6(t-w(bP9@-zNQ(JR^?pcRK_T4dCREmFIafbf&P13i?J5<%^J+ z34HQgMn=X6R#Nq4?Gk@>lNII!x7-0hE&-PDX4VyumhtYL$wbvnfEdp)K6^lx=@hR663$b%yPl^=CRowgRL7zj@<22XN zJvkZmL&s7Fo;0h^rR2)B%y)0W-(PV#Qc~EN@i-C+$Ttp7#>`t-Sn+xDj*33mpRQnA zXQ6}9G~e3V8asP>`A65-$dU97t`d4B|E9EH_C&8nGymnm&hzeVS-Pn_`jtRRXdu}P z{NQ%1X!GPA``YS6Rgg}L%Vn$MQ11wfykp8)Y64<+-+z24y1vB+ zY~MZZ6TkIzyJBCDI_uo?$o@>; zyM_yth=j$)#jf3XMldcHG(~Zo*7ju8vREvmim1{?Jn>*iXlQzDT%26z*&?4FBb(1< zJtvL{d7pUt+)YWubTLb$fmL}J;T#l(YkBf~d)!w;C%}2F+|M*0v1egz=CL>{vb}o(JqRaOIv;8A|}~@ld;Mc z;)HKG6PKO`Y(E2sKzP%Z3F@!k@Gh)ALm3Hy_VY=i?FF-ST)>ozE>MhVDQSZzD+w{i z@=J^^cERXkH#cE9g0i7Q*Cu4U$}x2nraM2UmCna%K>Kp;SQd3%T@kno2chmZf*8}w za+RZ_qb&_ReUdx2oRW{^YJG1e`kLHdw%z~9dG*34Cd4pri0^2s!K!!uxBasZK7El$ zh?$xlqz|MwyBItaW zbAj`2vo?R8@6t8p)m2O>z4Aw|>F8EQe&BYWY%$MNbh+SUQWtWPG$wVG)1;N60@kmJ z`4BU}VO#C6+|d>54s4tqsl|m8bc?T!fb=6iAm1Fs^D(q(_0R^WSdq>ww5<9p%?ft2 zi{yc;30=@_-)i2P41Wr#X{;D4Jw|L~sn+-_-RE@+>+IIWAXMhF^<*oUq2J9lmiB@0pli zTio@mLs!efj1a}!=&+ZE0z&hao_iB3;O%*|*HeJNP{#1C{2{BX8hpGM9EHkw%5Y@3@Uj%m%ZLz_vzyoXa} zbsUC5jz__s-MC(12hNbK-^<~4dzmJZ5dM=qDt5=6TzjXJ$C4F-Xwg*(2>TDO7rz}uvp;-%`GSnVzJafjqO1$a{5 z$TK&gp4S)7$CT`WdlE>b@9WV#g4>}G-S*l)tbena?UAUn8QTs=541fQ8R1wOi0=|v ztTVYTSzcDI%_BI7tIj9h@*#UKHy6L0S>ncyjnu5SWS-n=>dN%E7Z)1_xy;q{#~q2i zF@(JzB9qC=$99g{@Iiii{VlOmh_;a=xBbSh=EZ#HfViy4^L5Xe)!?1Y<&pXe4dbCZ z&7CstPL-Q8ANuV+afsGox%n2+kF#+L!PgjvLmSHK!;{mO!RD|+=p=S^{`j22iqMVf zrrtZ6C%dzS_>MXzNWu8N|EL`s0ofTVW}iY*D3tB!%UT_YgU0HQE1$dB{amei)c<+H z;4s{-CN`=$6DNIi^F82b!4Tcirkp*icu9B`?c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxKsVXI%s|1+P|wiV z#N6CmN5ROz&_Lh7NZ-&%*U;R`*vQJjKmiJrfVLH-q*(>IxIyg#@@$ndN=gc>^!3Zj z%k|2Q_413-^$jg8EkR}&8R-I5=oVMzl_XZ^<`pZ$OmImpPA){ffi_eM3D1{oGuTzrd=COM+4n&cLd=IHa;5RX-@T zIKQ+g85kdF$}r8qu)}W=NFmTQR{lkqz(`5Vami0E%}vcK@pQ3O0?O#6WTsfTm^wNd zTDloom^&G`8W;kZ#x9PICa%V&Zfw6HWZbTx1?bg^(U za4~f=c5-nvax#bM^~@_SNz6-5h1r`4v=^$^6t7+@=c3falKi5O{QMkP3JA!^FUc>? z$S+WE4mMQ?&&*57FE0i~4#cl6sYRJ(sVQzn`MC<<(6!3MV!OGap{b>di>0MAE?-0R zrjQe2`as9%gOUbPQh^Bp(;tWlPxwF%JnN+90rN`{Fk_T{Iyi}efw9Qb#WAGf)|Q~t zc})Q#B74-BvV`*tl6b9!e{-tUvFv{^KgzW5>9JO6a~mOHX2od_7Td_$=+@@ES+-eW z`sp(>cNPog+%AjV9=D#mDPZ^Fs3(+(p736MEy^HXKdZ;20{R+V?o9VeNP8ZMSm;SYn>O zUB2z!<%1S-{T&x`%r@T7FwvXNeWK@(EFb%iFJJeqIk6z=a_Jov-ve%Y9`W6%z6X{EOF0UvdHYk6bBJk3#&;97vGk39#~;*v^FbuYg9#B ze&Vd966O_h3mWc3646)+D$_h&{an^LB{Ts5>Jr(x literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/menu/categories-b.png b/v2/dotclear/admin/images/menu/categories-b.png new file mode 100644 index 0000000000000000000000000000000000000000..d91c5ddd6c634577b5c62cfb1ca15a5f476e82eb GIT binary patch literal 3859 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 literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/menu/categories.png b/v2/dotclear/admin/images/menu/categories.png new file mode 100644 index 0000000000000000000000000000000000000000..0587a860774b7e7ef6dbe7fe88857dcca3b8daf9 GIT binary patch literal 1472 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 literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/menu/dashboard.png b/v2/dotclear/admin/images/menu/dashboard.png new file mode 100644 index 0000000000000000000000000000000000000000..95a9ac43817a5b8ec273e31c6638a85cd7f0372b GIT binary patch literal 256 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~i!3-n?Kj!QJQj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS>Jii`t%LR`ZmBfozAdiLD8`i6#O%a^}?{W>u@`TC6;*}1t7 zA3mHkWy-EyyAB^YvSGu9(z3G7uC6)r=Jh19vjep!d%8G=RNR_#Znsdg0gubYSXFVdQ&MBb@ E04_{w(*OVf literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/menu/edit-b.png b/v2/dotclear/admin/images/menu/edit-b.png new file mode 100644 index 0000000000000000000000000000000000000000..c386f2a1392f1f6f356a0998e540827701a65656 GIT binary patch literal 3356 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 ARR910 literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/menu/edit.png b/v2/dotclear/admin/images/menu/edit.png new file mode 100644 index 0000000000000000000000000000000000000000..516e8ba21782158d556ff6343b71230678fb00f4 GIT binary patch literal 1591 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 B&}#qy literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/menu/entries.png b/v2/dotclear/admin/images/menu/entries.png new file mode 100644 index 0000000000000000000000000000000000000000..2f0070636b984219efa94dd82039adf0f344f3d2 GIT binary patch literal 1547 zcmbVMdr;GM9FOy=6^~6e$Eib_Mcmw^P0}ZgRBf9Ex>;bf9H5gCnm}`qq)US>RS|Gb z@O2<66Ljivvds#kjJ>EXM-O&9f>pgi!@pufzs`#CZWP=`N&2Fpn-^I1}`swH*Q($^>QV z9Eihfr9Dh?P@tW`6qh?#=r&T&yt!av0Fwk*S|q^$Tg3UWfC(DX#iV&?8-~Ckh*)TX zhMmfCq=8mmph2AqQMwU50_sr}s?iz@hImkopa_hpVN|U|4VXraAqY6~K$10q%E!`i zV#JoTGC>|u^kOjV_xn|TjfxivVAN4`CP+F_Q4EFQ1~ZE2^oS9)AT|U= zjf4g_o3%ELjvxrF+7i|njZ5eV9d01>7Bs<#qBg{mV76Lx2?o8aPfRmxC7EWyvX}Jyce`ObzmmLQM}(5D$a1MI4v+sXo?Vc z797eh#*Aj&m|(P`R)fK8k^CMl>R~SRe=-J3&cLD8_)n{Zx1|0HO`kQsw0L%PXimB> zf^;!@dfNs8;02Q%H@gDYmQ_1E7t>-o2JHtAF~^KIl6x-Ou&nJ$EN1bXZ41_ne+&jE zCkD>f7R;M+BIR!O!(ZqBWPT~w0|h6UWm|tq+FYgR-g0O${eAJG_KU}# zOSY6gs7t!BxHKU%e$z)3l(V8|$*LXizOko;{h_aG_7Se2_g4Sbzs7yCZ>&5=1?97i zCq6jl9r*do>eL4Ju4=v|`dYuH;mbXHVyaJqyA%hTW~u!T@7;O2|L@Me?Mu(5DsG>@ zz?Wew<9AMLj&93fyStn{eRY>FSC;PG{lx{K$((S~ea3vM>%ebSmugPlK3!FK zb^Id()6uD|SygQ_M6Minty8h?e&fX8$7>apmM9;lue$Omd(frL+Y(`15tn$l`Ol~O zUfvKl73z4k>`iUtE9>-@6Mx7Ju^Ug%Zi$c3XJp4wx{TK^QMU5&sh=JxDrd6GKAQpI z^0@=wRa~EvIkRDUxwEWNu3(GmL78hui?ZN7OHx@(`Gk})QKeVc?v;`6=N3;4-r4Z^ zdbl2HjktHEUABESMK7wfeN(Ztys6LGO|_I}%v39?pVX6Bf?MMr<{Py6cVfU-X$ifEGAU%a>J?5&+~ny(+ho-1!J zPt_yx_08wrYC3SA{WiC`_u%fX%+zzs=GNA)|51o}(r3Ld%V~^^-FEZ(?#8vfv9jZa ulvB~3H46ieRm*QWI@FWjiCwdKK#l;5YNq=$ZYmX_-?QD8g73BDR{R6sXFb#a literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/menu/favorite-b.png b/v2/dotclear/admin/images/menu/favorite-b.png new file mode 100644 index 0000000000000000000000000000000000000000..a2dca4c60e14a8c3c88029353d31f9c09c13beb0 GIT binary patch literal 6047 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 literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/menu/media.png b/v2/dotclear/admin/images/menu/media.png new file mode 100644 index 0000000000000000000000000000000000000000..f4de5e3e5461105dc455b4960078c4c3d9048f75 GIT binary patch literal 1532 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+m{T%CB1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+* zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxKsVXI%s|1+P|wiV z#N6CmN5ROz&_Lh7NZ-&%*U;R`*vQJjKmiJrfVLH-q*(>IxIyg#@@$ndN=gc>^!3Zj z%k|2Q_413-^$jg8EkR}&8R-I5=oVMzl_XZ^<`pZ$OmImpPA){ffi_eM3D1{oGuTzrd=COM+4n&cLd=IHa;5RX-@T zIKQ+g85kdF$}r8qu)}W=NFmTQR{lkqz(`5Vami0E%}vcK@pQ3O0?O#6WTse|8aSI- zxEfhl7&;lc8WxAZL)R)3i|wXHgnSLrn?g>A=>r|3 z4@w$HNd+bZOn)FIJmCX5@T`-X2h1-;z>IP9rPM(N1|~gE7srr_TT_C4^MwLMY~Sx? z^a}Qh?!0TFBa*aB!RZjwCAGYse+)v*(;STl@K(?e{aXY+X@n)jrBk^jdnu=6S1=6uK(xOwYn}!f@=?b__ZU~{%4I;r<)lK*UV^)n`CS3HdTZ62-vKzY4t zu2()&&1*kGG z2|G^}G*98Z`N;U6pzP6o#qU+iru~^XEq9_`$<6q4>x9cVC#rtGdTcA_{CX|}hF$9w VkEgGU1*RMZ22WQ%mvv4FO#uD4GbI23 literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/menu/plugins-b.png b/v2/dotclear/admin/images/menu/plugins-b.png new file mode 100644 index 0000000000000000000000000000000000000000..c3b59260b2e983d8033d2cf8865cfb8d1611d09c GIT binary patch literal 8750 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 literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/menu/plugins.png b/v2/dotclear/admin/images/menu/plugins.png new file mode 100644 index 0000000000000000000000000000000000000000..39995bb1882943ce9c614aa9b78693251fb861d2 GIT binary patch literal 1663 zcmbVNX;2eq7|u`+h~=oac(7ThVwLP>b3nEP&61=AG2GX$?{A!2rZMU`CWcC3vT&N$&`)I^a&+@&LANjrz;@j@4{cHERkFhDY4vDy^iqxwb=u$mR% zGN}&M*~5ucYeY6p#ANG@rtCD6+zc)V143DpBOnO|2Us%Q=0I5mIK+!`vg;TEfgu$p zO#!}iDo$qr!YP^nq(V5z1j}GRCK8IolHlOr`2YfoU?j0fWn~Go#6pU;Kq9$Z?&3g@AWkF5vBt*WY>>_2Kf<6Q946Xo zXRMSBa53V^R0g8}IZt1PK-zV>SHw2QaH6=BK`d^EL_!!MNmpD$+72d~_}7isYCDW; z>;x1|IH(NT#ML9ke+10s?#+f=ikvs-657fY1y5H|rVNs>FvYCW0{}Sfddk zBUr7?!QeI%F=E%s*&W6z--t!SX#!^`+DK99BOPE!r5MVQO4)(%7%8yKYBN(=4p(tr z#;PJ{YbIgV&=d&_Wf!%+#=1NN!8C|kCJVvDLs28)YNeQKBQ6+BE{DNktoi?B4C0)D zT&?k+Rv9_s`p+f4YJ6_DBY8Zx8m&rcWIIZV6PHYgnz*^~eo1Uf zTSBFw#IR)}?Gf1IE@&ECa6E5z0Nd~RVzl4m)=JHU$aRmkems$zN75(m&Ern4N)VRw zf=CNG#gY$he|G%(^_HDqHT)94_ClDO&yHQYIv4MaPW@6N+qE}tes^F0jq{1}+SvRf zCqp*;Hc_Y3Z90MX_V(U;@W7KVyOyx+^v?2f^^}aGb!~ywlCZ`K`-hYEnEZ{GV-MFH zZF-h>den0z_O;L8;Gm>AnJsP!5R1k4@|AsEnrz?t_=*)ho%N5{bLu;*rnMsl5{>enTm7tW8n7@kW4P(X52;S5&6`I6*-f4C9`W(u$;@TBH#Je1NiZ z0_}LG)5)fL8b=46BCq?#Lff_oD^3sWtMr>7oXv>(g)v{Z1U$ZWCn zENp5kYklJVq$r{5o4f0zv2!Dx=WBm|UrNW_?Jm@3=hsL5;CtJ*VbBY=ESFftV+_kI%ApItL5YFZEJyng1=5Z-bw@< z*l=5VA#eJYeGezEUq4WIp_;^M+L@b=K;!g*?-oM6foHvn27I4(&gsaz+}4IU|IknN zThDY2_Rr6$j!!>C)|TD$r>pakZBs7kmqx{JICggD(S$Knl4(CV702-={+PT-y`J7K zh2dNJs^H?5J5`tV8{^~qZ(`2#GZVkP@=;k|W%r+~-oCr9xw(0FRp6ZHTgyXG)c3jn Z&%Bz3FIt`KTo2bTL95oQ4q+>E{{af!d3^u? literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/menu/search-b.png b/v2/dotclear/admin/images/menu/search-b.png new file mode 100644 index 0000000000000000000000000000000000000000..6cd92c55227d131a7423dad772d0f5c703f38e1e GIT binary patch literal 6716 zcmbVRbyO5>-yW7mVi74NmZc?jS-NXMLK-AiB$pCcQd&Y90ZBzvKzadbkZwsyX^=)r z36T~)eBS4IzweLtynlRi&deQiUDq$}-#v5AOq90fJu;HpBme-Asj47#uUol4ClSH* z6>IPM^}3<=P%`q+!`OIuS-7DAd25U%8lviCVT;y9TUh(J_M)W#0N2`H-^jyAo|208+BvE*4gg(H;;>w5`3fG<3J21q!jZmWCP%Yrr*J6w!9}D!y)L zJzq_IE8oXf;?_`E8Hkj(#I=AE+QS0k?d0g}F5xW={YzKky8mYy28H|u@pvo^{g+cl z8rl#=j2jvv%n#?Yf{VZ*A_DvZfKfr5mB(&V@uNTF_5s9(# zbV56Os3N7I*LV1>?X4vc;>tpzNCgEEq?oc2TtGlfOjtx&5FsKeju2IbD+vFi@t?S2 zg31a4*Ej_MQ4s+FCAfl^qN1X*yqK7nh$tK`ru+|A)!E&{!r2P_k6rs~yMJ><{wr5P z(G6|kfpOEvU>yIc0Bt*r2gcnF;{s9C6NVVtJ6mJC-2W`jzhXtA-Rz&Bt(Dy{PLRK{ zD`Ed1tcwT>3nSs8NYQKif1(yw7DUR+3n>W-D=RAtArzp0bFKeB8G~Ir1N&1N|EE;` znYymOKiz*9{`KJBTLOnaaKjj>wC}4p-}D&ldeDNb}U^9ad?Tq zUfP-7l=ulDNVP_l1V-s8ox+D}$PaUmbPJQ24_@?X^`Ni^FJ7LoQ>dzG?jT+35(^mA zD|%nt)j=rf;I-W$3IbF@Is?i9n%cK%hhFQ4JJW6aonqyQb_LnfZ{PNBmNvBf7?Umw zfs}F2mDL_HbqE~M{Wv?Tw=zzRSwW#t{DC#KwYB@{VH#%fe64xMm+R{`i|5VV9Ya4; z``17+so$3NrJG`7$z+pyz5Dz7FX!go44p3?eV>(a7Lt_QHmh@E&uo9NRq0dw<+vg} z7e~9@jG5`_bj^2JFUD`$(6r)TQt?J|%i>AhtV0XN1eW%ZVVTv{!qv9&kvKXn+-y$i zC%)Ll1Z;86U8WQ%IFF~a)iXb?(8EU`3|jD)E`keBjgJoKhoYFfRoHH>*7LLPU+Aj^ z*w9y;e*c~>H6+W(z;Mxn*IMWElSAnIC3WE!W`jIk8h&g+fi?x4v#P#cjf#p&NLV;G zXu8stVtjH^&(qV>L&n|$AOS3$Mn^{z&zyF@Hhr0x$m3u?7LEWQ3Q9?4O_1)67uj$RAw3&{-O}RUU8?YqAqu^v_wU>o?ppSgUln-3MM_fpz+yL z7;Y#f_k$4OS}r*45ph~!rmw5V4ZvVO~*Q4}Ta-v)C{ zP$*ah2O$f?03q$^%mB;b)YPk+jpc<=PyLtl&QAB}e5i%LOpM6;(Letb?u#uc%mrX{Q4#WXOQ@%tw})?qhm#q5f}v$lq-rN)$ibaGl#sCObq!zo1sEm~vGU8^dn zZv5K&B=XW}mHc=2Udt%+(-l%iF_)n5Qi@6uL{;C!>M7GtQi^qY|G3sYdb~2EcBawn z-Cc47AZHrDh%(`1Ts-aA>QqoLo>zo;(ek&V$cPj#ywK<{ezWG{BV1hE!w&b1;qLg! z&7QQy_zeb{H2{wNY$r@6D%($|oW$|!A?}P%8#1R}pS3*nsf(*0VZp1p!4{MR{#q3gc zKl6V$A(@nauwHC(e;%FWg3Ia<^m!;lwv-6B{py#NOiom0_+aCc=o!?Q+DZ=IdIZYc zk_QB7OA?!SlarJEJ8r1$ZP7H8;Aleoo+X`U0!!Os4QkdRQ05C_R# zV+j5&VrHvzH-?~vgV~+k$3@AegQJHX_P)DK#~YtT7xb+e2Q}u$p3u{G9}2=nE>`!J zIt~ZJc!VrOhkI$wGClONCnPxW{F#JyjI#FP>Qn6kO%;sgv{eXR*$9LE%L+%c#!O>( z_{g=`RCfap1ah~ThXseE6uo}TMR8yb+TuQ%h7f5im3O;7oGr@_ez0X|x4uuxXN%~o z#tD+bt*uOpWLWZJz+3utcsM*y7{8f)DkXh&@iS{rlS``Vjf-Qo)x>#u1B@wOP|XZ`sq$b zM;NIP0g^i=GIYEz(l&0Sk@RJv-!uR`C#G5Ve|XxXb&pBM3j?ck4;$qW;*o*LiOrDQ zBvn=%<%d^t^wg1M{IHRl*#mhx;W0f6+Vy>+Z(yp(*Yx}F$C?E-+05)Lwbi|}H$+Cz z?+E zg&{Z6#fvOPO<^2g(eeW85qsYZzGsDRB`>+-n~8=|(grCDP_K*n_OxSsxI%M!*`*Q}dBfIC3s5HkD#>=xyJ`JQDG-*?1@JV`5*w>+m>N>c`WMH!QDtXC0& zz4_r0E3Fa3>)O>rdAr^gkRH>iaf1#V7kW|v)w-ObS%j+c-D9D%(_?vGO&8? za)}|ud`vjYF?lCyT$a9b>}rZyDo z!Jn!X;SxI5r65zO>m)eumcV_vQr-u=sCJ=DBW)fk%r+x`X>79qy|^Dp#CcU zmvNDq4*^;=$CU3AqZ|Pe-+0D8Sfq>}6xhg_Pn5lD2ilCdcPoHL4)N4h_75}-5ess7iybsjM4<168j?~vBdrV2KPyVFr59iS6E0&hto5pbo z#$pSmoKg59M;`4-$G_n5`^G)Eolgv>?&?m6Jg^&KSVpc_p6V8|S3KtgaH&f|B<+A4 zZ%z(8LzR*6!PWLV(XemRyZh5iF^q2yZie;7X7_5~+TGB22mOxmbIEpbRFVs4#b!EVM)at+x2A2Vd!Db^6cd7LxHJ-qsl)o_ z<+#*Jy6{ir0MJcqFo~JN-p1QGgpR3uPkTXOn}(FS?5p?exkIjlWFF675^~p)d=5|t z_BzUOAX19n6G($2N-`nCB3pH79U(L96S`8CPvY4OI=-JQxk#RI8AuLnMYeE3st)d! zNH#^7bm!aE*igVs6jcQn6z~;X|LXNhyT9GYTT02*Fg8;*v7Z9v{?-6b8D# zzI}T}|K{Oh8}7`i^>a)5^j^Zm!`9o5PWTCTx(@=WLK{^>X7FF&6MV!Oz__~VxB_w~ zz5#KG{qfmoRuQ6L?V7=J27zUtrTWAXfv zqiUf74-xoRz3~I&EpZQ$81Q;w6k#78dns%aTCM|GZ#QY342_I_K}ZEU179w6MBJs? z-n7gAhKU`8=?bqJPTYG!0rscXGwv7&?ZK__n0ZWJBp-FlXYCw*{^I@(PJxYS``aEg zCq4m=IAmDM7zUua$Jk z*9cze)&L(|7nB>05a)k-cXzLXYNE`^ny}HWY%u zU6Q}W2dLkC7Ix^nue-ZW%IJvA863pz>w@)3cf3I3CaHB_zks7%n4w+Zl(^_H|zI$of<*zD17sQk$PR+GL7djE<(LialfIh#qI= zb$0ZB7*POvMoXDa(^DnW@`n1A0n6`cQH1<>tG!e8+K^N>zD9R%!($)=}Qv{rSwGN%N8YI9*sKyklv}!uN0^0TCE# z#?bKex9=CK$n$D(wO`;BVTF;W7ju^6!~CtU_wEOFsFsBk?ZoT_GDsc_2&&0#ehcQM zS>0pCqPj0YOXVvcDX8o+XLSBxf3SS02KcrAcWehjYsB8c=fuv4B2_%Q4rI zf_wJPLBNt0e-edTze{kND9w#M&vnoE045MG8u2AjbF2~<7h4@RPB*A1U{DN9s&UUE z=}ict)C$k{SGpaRk9QaHl|>b|slIXTyF8yrUAGsk)zsRRMYbGoOCQ$CHs!CIZUZDtm;n(Jb+JQ82WTB*u>vNuiy@jEs#X0g zbOVg35KQtb#a5khn;M2ja~!#~ulKfh^|sG$CKV_?F{plR@4UlN{exoT*lahe#V-(Q z^0Bj0R`4_-N99O9s>eLF)7m{hFV9~O<*;0AOc5Z$Btu|E#5Y*B4*rlR@%WZ*sO(A# zT_r0nn8iDF-aM`}E&Z**vB>FqM-1)e;^S(4vy}J0T6u1X@&>u2&m5r+8_c%zcCQ>0 zIn4%s1b>V`f_~4#4EZKtDxL1QhWFV`1hOK+J@hzPYiMMA>4PyKc@8n3x}i%a8n)%S zkH-0eE0uPd#yATwV`G$E5S=*E`GThUnDY10V-_O$VkxFq0WyMQ<3qnb;?+1cFXNl9uTaWvIWJ}Y^6t;+Pr?Xg(4 zvGe01V*@$y&kzs&{2q%os=~6+^)0o7trJEE3-HsQj)cD#FTRjltfUEEH1qV?XV6qZ!a(NuKBdFv z!RD;(%x1(lju_sy_!7wHA(Vu{!X_wuXw`~;j}1shC3m(_wy7r+((`?7p)qNX`YN$i zppno8nes6+4*mSV+^^@|y~4V&e9T+t{6GoW)35-%HBkLbqaXzwD8Q2UkEyt3oP@0) z#O1hu#)k4;vnNeP<0$`2w_SX#NOx>4rd(mor1b#w9{I=<; zaY(L_?5aVUg!IOHn@=*ndfPMq-dNT*rj;YJq$ssqG00(L#BZby*QEx}mT>Fz&GnHH z7p*@EKV^F1bAM2B2=ef@>HDbraiH#N-ynpInab?bjZo7DS$X@w1bMsoN1<@SEpR|n zlgGu$ej)?dTs0bfmuaf=^mlI(=Qx{ouJNFaLEC{U@8S(JOT=9fB|doekzq6^|JR2) zo!*TNaWi7b@YL21K{B~p1_V`?=82;vZx8Rlyhh_;b9!%plF2gl>^4UtYC8v5M)oydU7{OEK`;>5+Sqmw z~9J1T~jmq`f1^`JbpU5 zbIws&TceAiKKTON0vu7u&BZK5kIm8C z0yn?I4IT9Q2@jPWWeNP^^ah|5K~F{vwu=jsKALmK%6=?q(CQI4zub_1O3y|VW|4Ak z=PS{1Kvp)ZfpXKMS(cP4+!X-G_KX3RSh9yiCF6_iHcbOaeljzfiSAwQi9C{Y z@C~-Q_PQ+-0&xeg$4gIBfK0}g&S$-n9Y0TgL?v+sW?tTEZ`|a}@E`30`M=aS6RP}a zuNrEO7=DdubU0IA&lyoCKd3qWkP*Avz{ImZKk=6Do~YH*y08E4m(4M~o2$j8YRy;b e&PRbHZ~$5hOS3YlI{x!NM^#A^`9Z-vXzO({K~XrBj}choCb^rSFLK#)(8xDFe-@0fdBrqnhj zW*ab2ju~+ip`_}O?l%dha`)ec9Ey}ToH#;F6$RA_aivLz>B$%&mrmU z4)I;%Q=50AgXyVxA*jLN4JDtX(WZ6B2ziO-JK8<%`21Dw=eKlwwWUX}GJklqk-_$#;e@nz?`~Mr#dykrFK)-A8TvQ0jn>nsvm#T+@;u6IXG)$ zW1PFFCG$YbjT`Qr8#?77Yalg1Gf+}ltcYb*6&cT%YVppVN>x#?X9r-myWa0dPBl2~l z3*)+SwhblR+aj7X=PO3}p(Rzc(#L!XS&STihB0-_s2)##`CqeO|4I!W|#lEq%SL=cK8(;3D(Q%OrynDihKtp zP7epH){tVgymTHE^_ck0ZB=d1Cv~prbCHtx(sQi?l82@j8yEE#N*8?)kWHRV)qi2x z8$LhEZ}ElY``nU1iCiY|x!0ICVhfM#>$2@AXg}8Naj-Yv^X;)iw|f0gR2@I=AJ5z` zOZW^qT5;2NR+Z%WNNsC*LeFJ3^Q9CLccY`EGf`vTo73{3C!;HBw|7JR{Z}vGr=7P( zwAD==hpb8X+DE;%ljkzq z&Gr$^g_O#*Rc*!C$%Y1N@&W(Cg=au-i|3N%7e^~+M>Y-Reso$Fem*T8ba%GT-LtH| zu&+Qyc-*YZ^yz!XA%I7hF2z<|fAV~b`LJ-v;!$lI9IXCRlJg$TRjUlQjBI8*ej+iV LmBJJJbzlAs-K3%m literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/menu/themes.png b/v2/dotclear/admin/images/menu/themes.png new file mode 100644 index 0000000000000000000000000000000000000000..9af61c3f6e505d2bdc7835f0a02df5993bc3c4cf GIT binary patch literal 1442 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+m{T%CB1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+* zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxKsVXI%s|1+P|wiV z#N6CmN5ROz&_Lh7NZ-&%*U;R`*vQJjKmiJrfVLH-q*(>IxIyg#@@$ndN=gc>^!3Zj z%k|2Q_413-^$jg8EkR}&8R-I5=oVMzl_XZ^<`pZ$OmImpPA){ffi_eM3D1{oGuTzrd=COM+4n&cLd=IHa;5RX-@T zIKQ+g85kdF$}r8qu)}W=NFmTQR{lkqz(`5Vami0E%}vcK@pQ3O0?O#6WTsfT7&$r` zTDloom^&G`8W;kZ#x9PICa%V&ZfLA36r&aFW4VA^hnBDko!N= zM#1hS6CN~%1u|`4zFlWsu{mdw2iIQq_sZE*k((>1qgNGG%SY7=5 zFGaAnq#>b{#;aI)$7M6U?WK82VaO9akYyjbR0 zu(qk*PfbMCDKt;-=c@bK>WVtsMVqE2EUAtu+$L#mbSwVUmVH$ctkeHAxJdkzUie!s z)RO)7BFp6hXRMyyc;s2!{rjBO*X@R9muFj)J8R|Mocxu!WqxEi-?D!SPx3Wca`}ue z?@Yd*qG;b8_%`7_$BFYgPD+BW)D?81{Lar8RVz#Hh)Oe_Huur=V3nPF9HI(6lY75B z*y+}%l(BNvSB38rmd<7BC2l?(*J_pHU}#E-Te75%AJ&z3^S7EI;7obK}ms d{h#w0*%+$6)EWl+Fzf`Cnx3wHF6*2UngB8z5;*_> literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/menu/update.png b/v2/dotclear/admin/images/menu/update.png new file mode 100644 index 0000000000000000000000000000000000000000..5ea2c56c7594cf14307599c3248cc60b7bd9f017 GIT binary patch literal 3364 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 upuQCsFcuIf16D&)MSg`q0QhwUe+B@6X- literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/menu/user-pref-b.png b/v2/dotclear/admin/images/menu/user-pref-b.png new file mode 100644 index 0000000000000000000000000000000000000000..b2facf96d35175b7539327d4587a708c764c5d6f GIT binary patch literal 6605 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 literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/menu/users-b.png b/v2/dotclear/admin/images/menu/users-b.png new file mode 100644 index 0000000000000000000000000000000000000000..e39152e6e8af9c0ec18bf3fe2de653148bcef2df GIT binary patch literal 5292 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 literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/menu/users.png b/v2/dotclear/admin/images/menu/users.png new file mode 100644 index 0000000000000000000000000000000000000000..81531fd7e5bd62bb3916ca792704f72ce0223124 GIT binary patch literal 1584 zcmbVMZA=qq9Iuuch8o!<6tw8AICV&ScP+HNqea^urOm7$Ah66AuI&Mra=qj3SW6Qp zsIeQ0FB3Fq97D&17-0#oAEU|oAKA%k&@*bQeL3& zSYw@qXclIkvL)>FvSOZRP!RNZJPMCWL9<05j37veL#dPt8gj1O&EsCVn~R@jzzEL4 zk_=DMZXm>n+vzf1FB3eS41r>7wi#kKH!AmgOQAQDN-iqmE!i~a7I#DdyV1N;` zQmZjSX%H-kD$HO=N>e49&E_PfahhW`Y?=~7k_;N95!NCwoCax4YOPsiG;54nSgBIY zV6ASB$K4KM+Ab;Box;Me#G)paz6{eu)<)#ahC@~qPcb}X2|j0smZowEZ!KUZ;dNX+4F_G*i!XV_rZJyH^z5- z8zYf@H2#_+uJRtZ{g;Gt@rL<9UNSlc=vBwysJ5?rFy>+ z(Q1QNuFQ*$mUK%F?5Z!n*0fhu-_@rZ(PeypyCgc|7wMIucYfY3!F^>FT~Ag;9bKe9 z_TxH#nDoT>&ik!ERK)f6V1gZgU%lYg?j6XoLv6Ze1><-ts`eb*^M*G?DOPTRc zmbLn~wbUHn{M|9@y;$v;k-oJ<%ocyevcW->TzrJ+cw4OgBW3YnZ`--u1wch0JG<%j zr~5E71kdS&R_F~4WN^j)jtY~$P8zJeVfu9lIneVUGOWjCIknvj7ByJT1y0wB->AGc z-rJj}+wm-_@n*&lk@8Z^)%jyAD<3}^*0@i$wJol?S$V3n^GHN=^MixChnM%2J`Jo# znytb9{?y#OB%SXfFuE;uxQ1DJ-eGzRc_g{e5Pp`r+L-YBmw~|Ebx`;w{i-?k_O`?R z$GynC<0o1rd8Urq#=gwI#>Scx!9z*X+eCGhzrNY9WNGcy_a5#0dex#rSfvu@u8#6* zrF&Y2sTb=V4o6e&naqURsza6)J^6{xy8L{4O;6#Am((Fk*kyZnBwR)w%S}y9b+4KG gkn#D@@$`y0q8GW+O{YHZ)rbD!*0c>+i?LwmKa>eelK=n! literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/menu_off.png b/v2/dotclear/admin/images/menu_off.png new file mode 100644 index 0000000000000000000000000000000000000000..7bb65236b5fbcbbbfa3a77383dd15d02146a7654 GIT binary patch literal 1346 zcmcIkO=uHA6y91XX=)EGC`CLB+g=2d+1;c`vm|NSq(6}+EzN?}i*9!(>5^o3*`1O! zVkv@R!B!L$#hZs7Jg6wNJqk+e!INk!h)@qUHw)s=L7~njY0?(aQ-__u$NRqb=6jEw z9f=P#+mG8RifWDyMn=hggiO1wo~%n>hhLGc-t3JEHk<9kr{N89b&U)OecRjHKdtd& zYwJs~__!?<>kuCi>1Y9i;GVe79QNWeRF>9+SMyF)0c8Xzs_GI@H#vi zPf(%F_epYT)CbR+6xGyf&AK-qr+*XU3EVe^6Iv4IL<3PhvNn!Dzha=AW~5CJPPp!_ z^;_v3v;4va60xGGKv1%XVpzy@LB?G$DVm}Vw^$xyu_0d4vQE(=a^|x-YYsfZNGBB*x_iZjY1maz3x;6iA2|oEBBUc>%{TWZ`(0 z<=revrZniFo$P)?PV%FX{z^=83(yl7>pXL#s=)ow5@MGyCDpAr?X!db2qsHaz4S>VQ!0xrL6kvRq+*k3#_rWj zmiVM*WJMfQvSJEBT}}C6&G^s!%2|`PAZ-b&eYul*wUh^PsOf$n^kve64DzkvVF&qr zaM4JQV7n)6h{+IDHy!VopP^t=>p*Dce&cNW^VRv+Vpv~pYiW2wU*8P1&1FtfkG~(f Tb;EshnV_j?Up(@t_rm2rZ)|Yj literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/menu_on.png b/v2/dotclear/admin/images/menu_on.png new file mode 100644 index 0000000000000000000000000000000000000000..9b3ccdf0765143a41d08394d4923753189d3b424 GIT binary patch literal 1334 zcmcIkOK1~87@j`R7;QlhQpCfs_9B? z5kJvkKV%00bVP?DNj&ev-QM1YN3C`44W8Qc{wQa&**<+4`HZ*SiD7PFeSN)BsjRK7 zuBgAKi59jCSZrz-{er@K`#p$VY=E&@~QH*aflJOKczWgzVH+$5f(>efq z4_LkB{nFHL96W3cq>Yr4GfZAXpf9Ur5F8XWWGY%ghvAg#_QIf5&p`_p)(~%qiVQhX zLV%)4s)wZ9WgQRzwC}eN>DVwUD3X)6gq$Tw1%cj@$_oW#zzoWZa*%)!5>U(riBp~! z6;s1#TpTKEC{>PgLb)LLvqW#m9w@PxEFpu3C8;RuY$-@oHCep2!XyE!5Tg(zYE`FW z2^dy11l>;BAy6(ibbFnQkMaAw$6$&#;7MMFj1Mvtg$IVEY1U2SVycY@+3_6EvN<*x z8La2TyC5-c7%EGWrfE7&ms8R5B<=V6Ns1vE#(@zIeNr~~l0(*y)I>IPB1jiBQLXxA z>GBz6!Uz(Cm8j9`hvU^oB3ZAShixQFyh_qeifkxjVgLu(>P;vbrzpkHUoI_RF}Hx4 zS(|(m;SChB{BYop@p80_b^BS5Z*&vC2HHlCDOoW$xk2x-=(L}sXx8OrJ#?ME2~?*C zNXv*###CLm&a^EK|6^EIX!xa0XvONaWCaoxk%VMJ$DYw!JKg{az_?T-*-g5Cc2YJe(t*8jej4WXrzy`oe{>Sr@t>f zGnM?!*u@Ok^wx z@(X5gcy=QV$l)yTh%9Dc;1&X5#!GkW{s0BVN?apKoQqNuOEUBG6hbm{QyB~l^$jfa z4NR(v8I*u36hJD1^V3So6N^$Ad=rz4@^e#DG7}ZtGK*5n^NX^J6?`LhPt;NYs@3y! zaSY*zPEHI;NJ#i`Jm~}jlTK5_%6M*x8$uB*^+pB;TuiLi1*=N-FsRrwGpKU0Z%T9v Rcm&kR;OXk;vd$@?2>{JhTfhJS literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/noscreenshot.png b/v2/dotclear/admin/images/noscreenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..e9ba66d9ed7e8d7e1ee8fcb7180ecd73ab2ef5f1 GIT binary patch literal 1395 zcmeAS@N?(olHy`uVBq!ia0vp^AAtB02OE$qG4x%}z`$zd>EaktaqI2f=YEef7}_rG z{GYwJZJOeQ3(onBP8o4~Cn~KCTYa}>#tpf-%8^or|9j-_?EAEuLF)DNU z5Ed{{NC07n10dYcz{uDP#LOTC*c3H1IFhYMzyNIB1N&>&uZMs9^eO1hojW3b>-JmN z*yvcz_1n04b8t>hj!1TP_R&+Pyf*IH6QiT6+xvg+{HOnKy)E0ge}DX(dGo}!Z{L3O z_3PEbS_xvBhH7Uv^@Xht{Zh5}(Z7Fne~vRUer`V1^L@ViKZ`kY=7_w1|K4v)gXZny z$B*~3*;p3co;$(b-hOTgWAHSa&3Z}?PHx<{&u-sVw*yliynLCtkkP;I@#Ez4$C=XN zc1nc_7WD1iYrFjlQ<~h*l912?mUaLCz4g*b*!TL;qeYh*ic5CK?&o0qEGyX%SbD%x zPhbD95zCo1eSLjdf(3TQl1Eh&(x%+LZpAW3+1W_Y!1%`9yK8+9SQ@EGGa4`TiC7VQ zV5Uc7!_1&Gk*k^yu3inDKb7Uo7NIjwRD;$XV`pbS`txUHVR^Z^+)`7i-eZrK3Wu`A z?%BJyw|?ICW0h%heGGLzOYpGO88W3wUB7<4*tR@vT3}xFX`UZ%-ki~QJD?NPmhw#N zUGA2K%oUs3QuA_iEoU+<`!|b)7NIQ_^=vvW#4PqyvzisYWD2eYTvnMsCiW^6XBY{R#jK0 zm#UGP=B}6^rV)N-)3O_~yDvbwxvF!hy0t0RvvX8&c<(mK|h_KJ0bC#3CWO5$JjL zJ)1W_KEgR;8QYw{4T1)|ycVlV6%wQ*3hp^XACEk6#pXfFtmvnU7cc(!sJQvy0V4~h zWqF&t+?>w-I&<^6#==>J_hVIf*aHCrQxjk+ zXtrDyS$OGJIMXsWp(i@h<>?#CR{L|!m=#l*-ueB#;BF!A8C|}`xBtX%zdWy#)yGv% zPVQOUnY(MZG_3Ske|@&~gFSQI4umMoZ$EY8vp8dLW6k5a<_X+;xFr~s6Vj$`Kasak zu)sO>#FIUY&s`;eksbLv3mEUticHIt=K4Lq{c+pvT=jqhAur#)U7N8r>i(@8)fO^V zjZDk3I18tB2DaDq!3SSbT3M1Z9X yq@;lrMUdhMrU+gXp(?^rUJ<1TRH$iv7H4kKE}8XSmLFJ{GI+ZBxvXjyn4Q literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/outgoing-blue.png b/v2/dotclear/admin/images/outgoing-blue.png new file mode 100644 index 0000000000000000000000000000000000000000..d3a3c9326efa8c9fa9b05a88d5df3559e0a6c611 GIT binary patch literal 972 zcmaJ=&ui0A9FG%W6b6E)?J%F27r`bk>AEaoaci5@1)5U2g7wzdm>gWyZob{_0<$oqaDpU>y}^BpzncNcO?IYAH> zoNcSg&&%D8@p`CtVDj5bfb6M*iTzTf89%m&KsfW^K1- zcqEiihLO^ca<(9BY^D@>`{mP_ioq9`^j>vo}B)K~4ox(2JZJ>go! zI}CBeCS3oVTbaqtRw1N3vW4T|A@-{=3BjmjBbc3wK2vYZ^=Ic&n#q-UGIBQ9e+E6d z;@gv%)3xQ!bn$V-w>{=-oxXVXgg=Qb$11hb58bP`p8mS7bU8=`OP$v&uL|=}c=KC&R~~*^&fb?}*R7Z3&ZED| C^)Mj- literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/outgoing.png b/v2/dotclear/admin/images/outgoing.png new file mode 100644 index 0000000000000000000000000000000000000000..8a36d2f62c6f592e94900fc1e24ff665eee83ca6 GIT binary patch literal 965 zcmaJ=zi-n(6to0y8vRix)O9~{Hu-=TQQ~aIW$sSMQNm_15zFPl31yI#=a6a z6JldxU|~dz4EzBwFn8e(VB!xzV(P%gIf+w-6c4`lPT%*v@7=w7(>{K-UVKnw7-qeB z1Uqz1cuSZ2#O#q1JRlQ0Ld>Cy`v^3Bdx$#7cCTJsqZ-5HSg+e7J*%ZT z*yrpN!zF%5*$h)VNJ85gBLezp=mk3a`|CFrc&^T#mMy^w4K(tOrV%=s9(SGT*il{f z;0dTD8Wr#nu|eWr1hJOr>`Ygqak|a3UNNS#4n82!S#ulpH}3fFg3@zFetP z_JAaa0xw9sD3!#Dwl8Ud02Uuht3~cW>%hjM7R_{aL`bOd{A4oWCi@(YhPQ4$8ZO6{Cdd3ttsb8`d!e6Q1;$4z+H zO@8#x-B&r`-NxF7Rw2K&UF<)7f4*JV-MY@V9zA68_n0-A+1>lZJWn51(>#Ws>*ufk E0{<%{5C8xG literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/picker.png b/v2/dotclear/admin/images/picker.png new file mode 100644 index 0000000000000000000000000000000000000000..d70e6b250a3f76395c9fb7db64153685d0f0d038 GIT binary patch literal 1520 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=$3?vg*uel1On2Vh}LpV4%Za?&Y0OYO?@Ck9{ zZ;;Db_szHWmSg7Dpmmo2|Np;z|5@LWMW4TY-@4~^^``c7Pya31cs93Vi~ID@)n_+H zF3Vc5_NYpqLhPcnzQu>mfBf&zwdl#)mlOBSK7Q`mic?!f8Z;DJjB57(kD2@Gz>Q%z4L@*gYvug@0BKMHEr))v*m_Zo%-J6cf&VX-+uV6epA=d zHP>TTWxn|MI-q?2y>I{Ty??fJ>ov)41(^n2J=?+}ptIRZg8YJk?)?9sVe|ea`+*{y z1s;*b3=G^tAk28_ZrvZCpje4(M2T}zYGO%dex5=|W^O8jfuX*Eg}#AFRWXASP=yRg zMR0yvNqJ&XDuZK6ep0G}TV_#ed45rLv4V53@r-M3z|dn61gVSg^|4CM&(%u=DbuUS zEnu**uP8`N&Q2{+NJ>r5%(GQeP*6}($V{%1*XS zQL?w=vZ=5FYR*k9NmQuF&B-gas<2f8n`s4PgM{^!6u?SKvTcwn? zGt^BsFg8&zG1D_LH?lN0(@_XcEK%@E%u_HjS1>X#01`%4hK5!qhCs)Ffs!2;khUpG zNwW%aaf8|k1^l#~=$>Fbx5m+O@q>*W`v>l<2HTIw4Z=^Gj80#)c1SLT%@R_Nvx zD?xrs^nr6smXN+65i0P4BK0=Pwa#n8Y52BUsOVu8M)o`F8x zWS~YHpr92v#`23o^7C`-utbRsNGFOSgslkusV<2nsdk|7&;=qRvk*gLD-%mAQ}ZY! z{SZZH+I{m=GSe!Nv|H#JnuD~P8dw=wK(!+&f@-(X2L%LDz<@&?(71p)z8 zg3_WKaI~Z(>!;?V=BDPA6a&M|5H-wFlC9G6i*gf7>@sr`(^K^e^3rYe5rTN#2XQqp zSpbuzK0IB*oDPplnlKRIP7~uHhSJg!-FYD;z(OS1)5S4_LzeYms}Lij2*Uw&vE!M` zt4pr){QsX?#{9re|rYMlPg zmfaM%Y1Vbe8#Z=3RR#REMkeyNl>F9XJhXH#`w!+06AqEZp7VWx)-iax`njxgN@xNA DIONiO literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/plus.png b/v2/dotclear/admin/images/plus.png new file mode 100644 index 0000000000000000000000000000000000000000..77229ad40b982b5e529f3265e65d9e18d7bdf58e GIT binary patch literal 297 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=%3?!FCJ6-`&%*9TgAsieWw;%dH0CKegd_r9R z|NsB*-@n?qXRGI&DVuSsaLS3C3CGfVk0f;-ifcO<*|a~TZm(a}Zm;s4$1LSsfVvn< zg8YIR9G=}s19CVEJR*x37`TN%nDNrxx<5ccu@cva66d1S#FEVXJcW?V+*AewLwy4a zeFKxKVg@Ck3I&jg;QX|b^2DN42H(WwqWs*{l*~j0x6Go{^8BLgVg=ub-4nG`fNHHh zT^vI=qLY(?n3!1AoE;Se(u7!;6^>R5`fwUFX}sgzZ_cF2$j0WTpnCDZ#f}NWQ=&MQ g9rz{VsKU)Kv4S(}cgeh2Kw}s@UHx3vIVCg!0Ni9>g#Z8m literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/scheduled.png b/v2/dotclear/admin/images/scheduled.png new file mode 100644 index 0000000000000000000000000000000000000000..f6e2e9caba31ca0bfaef7b6df7bb5b2efbee4b3b GIT binary patch literal 316 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=%3?!FCJ6-`&%*9TgAsieWw;%dH0CIH$d_r9R z1HtVn|8GzJf2;rhjqd-~+x}mv|9`dV|K+Ox7t8)%DEfas@Bi7XnKNhpXJC-Lvqcc7 zk+CGmFPOpM*^M+HhqJ&VvY3H^TL^?1FWs&C0~8c1ag8W(E=o--$;{7F2+7P%WiT+* zH?Yt*FsUkLPy(t@0I3MhPb(=;EJ|hYO-wGz&rMCqOjK~oEJ`iUFUl@f@Qv6#QA-7= z*4xv?F@z&JIcbk}^~ZG#la-nol$!-6CrCsm%}|)UV8ItRM}e&kf*zWhz6?przQ4Es zQ~zJ?L=eMA7FJe?gI-J#2d~`R?4T7Oz!AatM^jK#r9;vPXe@)LtDnm{r-UW|G=*`O literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/selected.png b/v2/dotclear/admin/images/selected.png new file mode 100644 index 0000000000000000000000000000000000000000..373a85c48c0b01ed904095b873c886e14b3fc164 GIT binary patch literal 259 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=$1|-8uW1a&k$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWw1GOFdm2Ln>}1B^+Q%V*c~jQDU|XH*=W)!&37_-UbgZ3N-jO zan3Gon8Lu3Tr8#>U?9JWflX$C1Ph;oAx}+0BbN?C60?q;!?ha54&fR4cX#{@ig!+C zouJ(4EX;i6K*v#OGrJU*;{P=hG&8!)8ARD0eKIkV774KFP1$8Lp{n7@O@0r@)eJ>^ zyLb&wvMpGmd_|HsqewzZrh!X3kttvs^Cq?i24;r8;s&ynLZ?>)9n9eA>gTe~DWM4f DkY!Nd literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/superadmin.png b/v2/dotclear/admin/images/superadmin.png new file mode 100644 index 0000000000000000000000000000000000000000..a0d9bbfbdc9459fa4a60712640cdfa10437ca26a GIT binary patch literal 638 zcmV-^0)hRBP)Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUz{7FPXR47wpWPpN-c}G@=DvF2SfB%i)&+mT>fByVs`1|J{gFGKQ z!<&0gS57JRih!vF(`B;{t?1f)^MCq^bN@@1Z~I@jbn*Y_S;zj@tUCWcvwO=56vZG; z!PH&z+O}T%Td?Zv|5fWs{vX^N^S@xu*8detPXA4AUONv%Lr7|ce)`lySG(8k`+t33 z^#7;F(*Dm`)c!xBdFxfb*g}1{1|}vZ1~E}VCPRI7wuJ1=phVz1idW@Y|h_;jiG|L5yKKU~iG|M^nZ|I2f2uG*Lzp(+OHR8o{< zy0Rf;^XID#|6lHl`}$<7|C{$`GXCFLVgDl7-B=1ESl#Wl1s-pzR=_j> Y00)NjSxdx~bpQYW07*qoM6N<$f@YCEkN^Mx literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/images/trash.png b/v2/dotclear/admin/images/trash.png new file mode 100644 index 0000000000000000000000000000000000000000..399189944045ba8061120d0ee1d43c00d221caab GIT binary patch literal 718 zcmV;<0x|uGP)FMR?<^Sg9?&jv};o;xm;ojZh z=-uA`;@#`h;p)xeyY)!Ose*zU;R+r{77*Vo|H)zr|?`_a+h)6>$=&)Lk(*vrb? z$;sTw$=S%r;mOI>!^ZNv%HPJt>Y&rK!^7jh#OK1o;lje=!ouUi!p6S7+rPikuEoy4 zz`wn{+@Qt4ySdrAy1KWw*0;CEwYAo@wav7&)wHzJwX@EgyS}rt#5Bq`Ru2%A};YoTS8lubqskuA`!- zqN1dqpT3`;zn`DHprE9noWGo#zMGr2nVGqmm%x{oxtEu-Vy$_Xmz$K7uab|kkdU=d zs&9~wv`ngNj*Xd(jgpIssD_KHiHW9&h^arOS%-(GhlI2*r%+6rWru>8gnyfTeV%%H zn0$GkFqlbnbcbnac@l*olM~U900001bW%=J06^y0W&i*H32;bRa{vGf5&!@T5&_cP ze*6Fc02XvbSad^jWnpw_Z*Cw|X>DZyFflJMI4>|XdUF6G0000WbVXQnQ*UN;cVTj6 z08L?Ia&K*AWNBd_Mrm?ocW-iQb0AGvyOAm+0001)Nkl(liZE794reeEv6PqM=N01M%XDLqQPkpOWbw?6w<(rp z;IdbjV^kCMs0u7%XJEC^wq_C&5LWR|2O6hm?j=}|rXP?M1mq}q`x>Q`7rK<006F5Z zks6Z9j`@|`Kn{abNla>KMTP_e80aJf8}NV_07P>gPHEOsetUserDefaultBlog($core->auth->userID(),$core->blog->id); + http::redirect('index.php'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} + +dcPage::check('usage,contentadmin'); + +# Logout +if (!empty($_GET['logout'])) { + $core->session->destroy(); + if (isset($_COOKIE['dc_admin'])) { + unset($_COOKIE['dc_admin']); + setcookie('dc_admin',false,-600,'','',DC_ADMIN_SSL); + } + http::redirect('auth.php'); + exit; +} + +# Plugin install +$plugins_install = $core->plugins->installModules(); + +# Check dashboard module prefs +$ws = $core->auth->user_prefs->addWorkspace('dashboard'); +if (!$core->auth->user_prefs->dashboard->prefExists('doclinks')) { + if (!$core->auth->user_prefs->dashboard->prefExists('doclinks',true)) { + $core->auth->user_prefs->dashboard->put('doclinks',true,'boolean','',null,true); + } + $core->auth->user_prefs->dashboard->put('doclinks',true,'boolean'); +} +if (!$core->auth->user_prefs->dashboard->prefExists('dcnews')) { + if (!$core->auth->user_prefs->dashboard->prefExists('dcnews',true)) { + $core->auth->user_prefs->dashboard->put('dcnews',true,'boolean','',null,true); + } + $core->auth->user_prefs->dashboard->put('dcnews',true,'boolean'); +} +if (!$core->auth->user_prefs->dashboard->prefExists('quickentry')) { + if (!$core->auth->user_prefs->dashboard->prefExists('quickentry',true)) { + $core->auth->user_prefs->dashboard->put('quickentry',true,'boolean','',null,true); + } + $core->auth->user_prefs->dashboard->put('quickentry',true,'boolean'); +} + +# Dashboard icons +$__dashboard_icons = new ArrayObject(); + +# Dashboard favorites +$post_count = $core->blog->getPosts(array(),true)->f(0); +$str_entries = ($post_count > 1) ? __('%d entries') : __('%d entry'); + +$comment_count = $core->blog->getComments(array(),true)->f(0); +$str_comments = ($comment_count > 1) ? __('%d comments') : __('%d comment'); + +$ws = $core->auth->user_prefs->addWorkspace('favorites'); +$count = 0; +foreach ($ws->dumpPrefs() as $k => $v) { + // User favorites only + if (!$v['global']) { + $fav = unserialize($v['value']); + if (($fav['permissions'] == '*') || $core->auth->check($fav['permissions'],$core->blog->id)) { + $count++; + $title = ($fav['name'] == 'posts' ? sprintf($str_entries,$post_count) : + ($fav['name'] == 'comments' ? sprintf($str_comments,$comment_count) : $fav['title'])); + $__dashboard_icons[$fav['name']] = new ArrayObject(array(__($title),$fav['url'],$fav['large-icon'])); + + # Let plugins set their own title for favorite on dashboard + $core->callBehavior('adminDashboardFavsIcon',$core,$fav['name'],$__dashboard_icons[$fav['name']]); + } + } +} +if (!$count) { + // Global favorites if any + foreach ($ws->dumpPrefs() as $k => $v) { + $fav = unserialize($v['value']); + if (($fav['permissions'] == '*') || $core->auth->check($fav['permissions'],$core->blog->id)) { + $count++; + $title = ($fav['name'] == 'posts' ? sprintf($str_entries,$post_count) : + ($fav['name'] == 'comments' ? sprintf($str_comments,$comment_count) : $fav['title'])); + $__dashboard_icons[$fav['name']] = new ArrayObject(array(__($title),$fav['url'],$fav['large-icon'])); + + # Let plugins set their own title for favorite on dashboard + $core->callBehavior('adminDashboardFavsIcon',$core,$fav['name'],$__dashboard_icons[$fav['name']]); + } + } +} +if (!$count) { + // No user or global favorites, add "user pref" and "new entry" fav + if ($core->auth->check('usage,contentadmin',$core->blog->id)) { + $__dashboard_icons['new_post'] = new ArrayObject(array(__('New entry'),'post.php','images/menu/edit-b.png')); + } + $__dashboard_icons['prefs'] = new ArrayObject(array(__('My preferences'),'preferences.php','images/menu/user-pref-b.png')); +} + +# Latest news for dashboard +$__dashboard_items = new ArrayObject(array(new ArrayObject,new ArrayObject)); + +# Documentation links +$dashboardItem = 0; +if ($core->auth->user_prefs->dashboard->doclinks) { + if (!empty($__resources['doc'])) + { + $doc_links = '

      '.__('Documentation and support').'

        '; + + foreach ($__resources['doc'] as $k => $v) { + $doc_links .= '
      • '.$k.'
      • '; + } + + $doc_links .= '
      '; + $__dashboard_items[$dashboardItem][] = $doc_links; + $dashboardItem++; + } +} + +if ($core->auth->user_prefs->dashboard->dcnews) { + try + { + if (empty($__resources['rss_news'])) { + throw new Exception(); + } + + $feed_reader = new feedReader; + $feed_reader->setCacheDir(DC_TPL_CACHE); + $feed_reader->setTimeout(2); + $feed_reader->setUserAgent('Dotclear - http://www.dotclear.org/'); + $feed = $feed_reader->parse($__resources['rss_news']); + if ($feed) + { + $latest_news = '

      '.__('Latest news').'

      '; + $i = 1; + foreach ($feed->items as $item) + { + $dt = isset($item->link) ? ''.$item->title.'' : $item->title; + + if ($i < 3) { + $latest_news .= + '
      '.$dt.'
      '. + '

      '.dt::dt2str('%d %B %Y',$item->pubdate,'Europe/Paris').': '. + ''.text::cutString(html::clean($item->content),120).'...

      '; + } else { + $latest_news .= + '
      '.$dt.'
      '. + '
      '.dt::dt2str('%d %B %Y',$item->pubdate,'Europe/Paris').'
      '; + } + $i++; + if ($i > 3) { break; } + } + $latest_news .= '
      '; + $__dashboard_items[$dashboardItem][] = $latest_news; + $dashboardItem++; + } + } + catch (Exception $e) {} +} + +$core->callBehavior('adminDashboardItems', $core, $__dashboard_items); + +# Dashboard content +$dashboardContents = ''; +$__dashboard_contents = new ArrayObject(array(new ArrayObject,new ArrayObject)); +$core->callBehavior('adminDashboardContents', $core, $__dashboard_contents); + +/* DISPLAY +-------------------------------------------------------- */ +dcPage::open(__('Dashboard'), + dcPage::jsToolBar(). + dcPage::jsLoad('js/_index.js'). + # --BEHAVIOR-- adminDashboardHeaders + $core->callBehavior('adminDashboardHeaders') +); + +echo '

      '.html::escapeHTML($core->blog->name).' › '.__('Dashboard').'

      '; + +if ($core->auth->getInfo('user_default_blog') != $core->blog->id && $core->auth->blog_count > 1) { + echo + '

      '.__('Make this blog my default blog').'

      '; +} + +if ($core->blog->status == 0) { + echo '

      '.__('This blog is offline').'

      '; +} elseif ($core->blog->status == -1) { + echo '

      '.__('This blog is removed').'

      '; +} + +if (!defined('DC_ADMIN_URL') || !DC_ADMIN_URL) { + echo + '

      '. + 'DC_ADMIN_URL '.__('is not defined, you should edit your configuration file.'). + '

      '; +} + +if (!defined('DC_ADMIN_MAILFROM') || !DC_ADMIN_MAILFROM) { + echo + '

      '. + 'DC_ADMIN_MAILFROM '.__('is not defined, you should edit your configuration file.'). + '

      '; +} + +# Plugins install messages +if (!empty($plugins_install['success'])) +{ + echo '
      '.__('Following plugins have been installed:').'
        '; + foreach ($plugins_install['success'] as $k => $v) { + echo '
      • '.$k.'
      • '; + } + echo '
      '; +} +if (!empty($plugins_install['failure'])) +{ + echo '
      '.__('Following plugins have not been installed:').'
        '; + foreach ($plugins_install['failure'] as $k => $v) { + echo '
      • '.$k.' ('.$v.')
      • '; + } + echo '
      '; +} + +# Dashboard columns (processed first, as we need to know the result before displaying the icons.) +$dashboardItems = ''; + +# Dotclear updates notifications +if ($core->auth->isSuperAdmin() && is_readable(DC_DIGESTS)) +{ + $updater = new dcUpdate(DC_UPDATE_URL,'dotclear',DC_UPDATE_VERSION,DC_TPL_CACHE.'/versions'); + $new_v = $updater->check(DC_VERSION); + $version_info = $new_v ? $updater->getInfoURL() : ''; + + if ($updater->getNotify() && $new_v) { + $dashboardItems .= + '

      '.sprintf(__('Dotclear %s is available!'),$new_v).'

      '. + '
      '; + } +} + +# Errors modules notifications +if ($core->auth->isSuperAdmin()) +{ + $list = array(); + foreach ($core->plugins->getErrors() as $k => $error) { + $list[] = '
    • '.$error.'
    • '; + } + + if (count($list) > 0) { + $dashboardItems .= + '

      '.__('Some plugins are installed twice:').'

      '. + '
        '.implode("\n",$list).'
      '; + } + +} + +foreach ($__dashboard_items as $i) +{ + if ($i->count() > 0) + { + $dashboardItems .= '
      '; + foreach ($i as $v) { + $dashboardItems .= $v; + } + $dashboardItems .= '
      '; + } +} + +# Dashboard icons +echo '
      '; +foreach ($__dashboard_icons as $i) +{ + echo + '

      '. + '
      '.$i[0].'

      '; +} +echo '
      '; + +if ($core->auth->user_prefs->dashboard->quickentry) { + if ($core->auth->check('usage,contentadmin',$core->blog->id)) + { + $categories_combo = array(' ' => ''); + try { + $categories = $core->blog->getCategories(array('post_type'=>'post')); + while ($categories->fetch()) { + $categories_combo[] = new formSelectOption( + str_repeat('  ',$categories->level-1). + ($categories->level-1 == 0 ? '' : '• ').html::escapeHTML($categories->cat_title), + $categories->cat_id + ); + } + } catch (Exception $e) { } + + echo + '
      '. + '

      '.__('Quick entry').'

      '. + '
      '. + '
      '.__('New entry').''. + '

      '. + '

      '. + form::textarea('post_content',50,7). + '

      '. + '

      '. + '

      '. + ($core->auth->check('publish',$core->blog->id) + ? '' + : ''). + $core->formNonce(). + form::hidden('post_status',-2). + form::hidden('post_format',$core->auth->getOption('post_format')). + form::hidden('post_excerpt',''). + form::hidden('post_lang',$core->auth->getInfo('user_lang')). + form::hidden('post_notes',''). + '

      '. + '
      '. + '
      '. + '
      '; + } +} + +foreach ($__dashboard_contents as $i) +{ + if ($i->count() > 0) + { + $dashboardContents .= '
      '; + foreach ($i as $v) { + $dashboardContents .= $v; + } + $dashboardContents .= '
      '; + } +} +echo ($dashboardContents ? '
      '.$dashboardContents.'
      ' : ''); + +echo '
      '; + +echo ($dashboardItems ? '
      '.$dashboardItems.'
      ' : ''); + +dcPage::close(); +?> \ No newline at end of file diff --git a/v2/dotclear/admin/install/check.php b/v2/dotclear/admin/install/check.php new file mode 100644 index 0000000..3d4ebc1 --- /dev/null +++ b/v2/dotclear/admin/install/check.php @@ -0,0 +1,83 @@ +driver() == 'mysql') + { + if (version_compare($con->version(),'4.1','<')) + { + $err[] = sprintf(__('MySQL version is %s (4.1 or earlier needed).'),$con->version()); + } + else + { + $rs = $con->select('SHOW ENGINES'); + $innodb = false; + while ($rs->fetch()) { + if (strtolower($rs->f(0)) == 'innodb' && strtolower($rs->f(1)) != 'disabled' && strtolower($rs->f(1)) != 'no') { + $innodb = true; + break; + } + } + + if (!$innodb) { + $err[] = __('MySQL InnoDB engine is not available.'); + } + } + } + elseif ($con->driver() == 'pgsql') + { + if (version_compare($con->version(),'8.0','<')) + { + $err[] = sprintf(__('PostgreSQL version is %s (8.0 or earlier needed).'),$con->version()); + } + } + + return count($err) == 0; +} +?> \ No newline at end of file diff --git a/v2/dotclear/admin/install/index.php b/v2/dotclear/admin/install/index.php new file mode 100644 index 0000000..9705b59 --- /dev/null +++ b/v2/dotclear/admin/install/index.php @@ -0,0 +1,401 @@ +'.__('Please set a master key (DC_MASTER_KEY) in configuration file.').'

      '; +} + +# Check if dotclear is already installed +$schema = dbSchema::init($core->con); +if (in_array($core->prefix.'post',$schema->getTables())) { + $can_install = false; + $err = '

      '.__('Dotclear is already installed.').'

      '; +} + +# Check system capabilites +if (!dcSystemCheck($core->con,$_e)) { + $can_install = false; + $err = '

      '.__('Dotclear cannot be installed.').'

      • '.implode('
      • ',$_e).'
      '; +} + +# Get information and perform install +$u_email = $u_firstname = $u_name = $u_login = $u_pwd = ''; +$mail_sent = false; +if ($can_install && !empty($_POST)) +{ + $u_email = !empty($_POST['u_email']) ? $_POST['u_email'] : null; + $u_firstname = !empty($_POST['u_firstname']) ? $_POST['u_firstname'] : null; + $u_name = !empty($_POST['u_name']) ? $_POST['u_name'] : null; + $u_login = !empty($_POST['u_login']) ? $_POST['u_login'] : null; + $u_pwd = !empty($_POST['u_pwd']) ? $_POST['u_pwd'] : null; + $u_pwd2 = !empty($_POST['u_pwd2']) ? $_POST['u_pwd2'] : null; + + try + { + # Check user information + if (empty($u_login)) { + throw new Exception(__('No user ID given')); + } + if (!preg_match('/^[A-Za-z0-9@._-]{2,}$/',$u_login)) { + throw new Exception(__('User ID must contain at least 2 characters using letters, numbers or symbols.')); + } + if ($u_email && !text::isEmail($u_email)) { + throw new Exception(__('Invalid email address')); + } + + if (empty($u_pwd)) { + throw new Exception(__('No password given')); + } + if ($u_pwd != $u_pwd2) { + throw new Exception(__("Passwords don't match")); + } + if (strlen($u_pwd) < 6) { + throw new Exception(__('Password must contain at least 6 characters.')); + } + + # Try to guess timezone + $default_tz = 'Europe/London'; + if (!empty($_POST['u_date']) && function_exists('timezone_open')) + { + if (preg_match('/\((.+)\)$/',$_POST['u_date'],$_tz)) { + $_tz = $_tz[1]; + $_tz = @timezone_open($_tz); + if ($_tz instanceof DateTimeZone) { + $_tz = @timezone_name_get($_tz); + if ($_tz) { + $default_tz = $_tz; + } + } + unset($_tz); + } + } + + # Create schema + $_s = new dbStruct($core->con,$core->prefix); + require dirname(__FILE__).'/../../inc/dbschema/db-schema.php'; + + $si = new dbStruct($core->con,$core->prefix); + $changes = $si->synchronize($_s); + + # Create user + $cur = $core->con->openCursor($core->prefix.'user'); + $cur->user_id = $u_login; + $cur->user_super = 1; + $cur->user_pwd = crypt::hmac(DC_MASTER_KEY,$u_pwd); + $cur->user_name = (string) $u_name; + $cur->user_firstname = (string) $u_firstname; + $cur->user_email = (string) $u_email; + $cur->user_lang = $dlang; + $cur->user_tz = $default_tz; + $cur->user_creadt = date('Y-m-d H:i:s'); + $cur->user_upddt = date('Y-m-d H:i:s'); + $cur->user_options = serialize($core->userDefaults()); + $cur->insert(); + + $core->auth->checkUser($u_login); + + $admin_url = preg_replace('%install/index.php$%','',$_SERVER['REQUEST_URI']); + $root_url = preg_replace('%/admin/install/index.php$%','',$_SERVER['REQUEST_URI']); + + # Create blog + $cur = $core->con->openCursor($core->prefix.'blog'); + $cur->blog_id = 'default'; + $cur->blog_url = http::getHost().$root_url.'/index.php?'; + $cur->blog_name = __('My first blog'); + $core->addBlog($cur); + $core->blogDefaults($cur->blog_id); + + $blog_settings = new dcSettings($core,'default'); + $blog_settings->addNamespace('system'); + $blog_settings->system->put('blog_timezone',$default_tz); + $blog_settings->system->put('lang',$dlang); + $blog_settings->system->put('public_url',$root_url.'/public'); + $blog_settings->system->put('themes_url',$root_url.'/themes'); + $blog_settings->system->put('date_format',__('%A, %B %e %Y')); + + # Add Dotclear version + $cur = $core->con->openCursor($core->prefix.'version'); + $cur->module = 'core'; + $cur->version = (string) DC_VERSION; + $cur->insert(); + + # Create first post + $core->setBlog('default'); + + $cur = $core->con->openCursor($core->prefix.'post'); + $cur->user_id = $u_login; + $cur->post_format = 'xhtml'; + $cur->post_lang = $dlang; + $cur->post_title = __('Welcome to Dotclear!'); + $cur->post_content = '

      '.__('This is your first entry. When you\'re ready '. + 'to blog, log in to edit or delete it.').'

      '; + $cur->post_content_xhtml = $cur->post_content; + $cur->post_status = 1; + $cur->post_open_comment = 1; + $cur->post_open_tb = 0; + $post_id = $core->blog->addPost($cur); + + # Add a comment to it + $cur = $core->con->openCursor($core->prefix.'comment'); + $cur->post_id = $post_id; + $cur->comment_tz = $default_tz; + $cur->comment_author = __('Dotclear Team'); + $cur->comment_email = 'contact@dotclear.net'; + $cur->comment_site = 'http://www.dotclear.org/'; + $cur->comment_content = __("

      This is a comment.

      \n

      To delete it, log in and ". + "view your blog's comments. Then you might remove or edit it.

      "); + $core->blog->addComment($cur); + + # Plugins initialization + define('DC_CONTEXT_ADMIN',true); + $core->plugins->loadModules(DC_PLUGINS_ROOT); + $plugins_install = $core->plugins->installModules(); + + # Add dashboard module options + $core->auth->user_prefs->addWorkspace('dashboard'); + $core->auth->user_prefs->dashboard->put('doclinks',true,'boolean','',null,true); + $core->auth->user_prefs->dashboard->put('dcnews',true,'boolean','',null,true); + $core->auth->user_prefs->dashboard->put('quickentry',true,'boolean','',null,true); + + # Add accessibility options + $core->auth->user_prefs->addWorkspace('accessibility'); + $core->auth->user_prefs->accessibility->put('nodragdrop',false,'boolean','',null,true); + + # Add user interface options + $core->auth->user_prefs->addWorkspace('interface'); + $core->auth->user_prefs->interface->put('enhanceduploader',false,'boolean','',null,true); + + # Add default favorites + $core->auth->user_prefs->addWorkspace('favorites'); + + $init_fav = array(); + + $init_fav['new_post'] = array('new_post','New entry','post.php', + 'images/menu/edit.png','images/menu/edit-b.png', + 'usage,contentadmin',null,'menu-new-post'); + $init_fav['posts'] = array('posts','Entries','posts.php', + 'images/menu/entries.png','images/menu/entries-b.png', + 'usage,contentadmin',null,null); + $init_fav['comments'] = array('comments','Comments','comments.php', + 'images/menu/comments.png','images/menu/comments-b.png', + 'usage,contentadmin',null,null); + $init_fav['prefs'] = array('prefs','My preferences','preferences.php', + 'images/menu/user-pref.png','images/menu/user-pref-b.png', + '*',null,null); + $init_fav['blog_pref'] = array('blog_pref','Blog settings','blog_pref.php', + 'images/menu/blog-pref.png','images/menu/blog-pref-b.png', + 'admin',null,null); + $init_fav['blog_theme'] = array('blog_theme','Blog appearance','blog_theme.php', + 'images/menu/themes.png','images/menu/blog-theme-b.png', + 'admin',null,null); + + $init_fav['pages'] = array('pages','Pages','plugin.php?p=pages', + 'index.php?pf=pages/icon.png','index.php?pf=pages/icon-big.png', + 'contentadmin,pages',null,null); + $init_fav['blogroll'] = array('blogroll','Blogroll','plugin.php?p=blogroll', + 'index.php?pf=blogroll/icon-small.png','index.php?pf=blogroll/icon.png', + 'usage,contentadmin',null,null); + + $count = 0; + foreach ($init_fav as $k => $f) { + $t = array('name' => $f[0],'title' => $f[1],'url' => $f[2], 'small-icon' => $f[3], + 'large-icon' => $f[4],'permissions' => $f[5],'id' => $f[6],'class' => $f[7]); + $core->auth->user_prefs->favorites->put(sprintf("g%03s",$count),serialize($t),'string',null,true,true); + $count++; + } + + $step = 1; + } + catch (Exception $e) + { + $err = $e->getMessage(); + } +} + +if (!isset($step)) { + $step = 0; +} +header('Content-Type: text/html; charset=UTF-8'); +?> + + + + + + + + + + <?php echo __('Dotclear Install'); ?> + + + + + + + + +
      +'.__('Dotclear installation').''. +'
      '; + +if (!is_writable(DC_TPL_CACHE)) { + echo '

      '.sprintf(__('Cache directory %s is not writable.'),DC_TPL_CACHE).'

      '; +} + +if ($can_install && !empty($err)) { + echo '

      '.__('Errors:').'

      '.$err.'
      '; +} + +if (!empty($_GET['wiz'])) { + echo '

      '.__('Configuration file has been successfully created.').'

      '; +} + +if ($can_install && $step == 0) +{ + echo + '

      '.__('User information').'

      '. + + '

      '.__('Please provide the following information needed to create the first user.').'

      '. + + '
      '. + '
      '.__('User information').''. + '

      '. + '

      '. + '

      '. + '
      '. + + '
      '.__('Username and password').''. + '

      '. + '

      '. + '

      '. + '
      '. + + '

      '. + '
      '; +} +elseif ($can_install && $step == 1) +{ + # Plugins install messages + $plugins_install_result = ''; + if (!empty($plugins_install['success'])) + { + $plugins_install_result .= '
      '.__('Following plugins have been installed:').'
        '; + foreach ($plugins_install['success'] as $k => $v) { + $plugins_install_result .= '
      • '.$k.'
      • '; + } + $plugins_install_result .= '
      '; + } + if (!empty($plugins_install['failure'])) + { + $plugins_install_result .= '
      '.__('Following plugins have not been installed:').'
        '; + foreach ($plugins_install['failure'] as $k => $v) { + $plugins_install_result .= '
      • '.$k.' ('.$v.')
      • '; + } + $plugins_install_result .= '
      '; + } + + echo + '

      '.__('All done!').'

      '. + + $plugins_install_result. + + '

      '.__('Dotclear has been successfully installed. Here is some useful information you should keep.').'

      '. + + '

      '.__('Your account').'

      '. + '
        '. + '
      • '.__('Username:').' '.html::escapeHTML($u_login).'
      • '. + '
      • '.__('Password:').' '.html::escapeHTML($u_pwd).'
      • '. + '
      '. + + '

      '.__('Your blog').'

      '. + '
        '. + '
      • '.__('Blog address:').' '.html::escapeHTML(http::getHost().$root_url).'/index.php?
      • '. + '
      • '.__('Administration interface:').' '.html::escapeHTML(http::getHost().$admin_url).'
      • '. + '
      '. + + '
      '. + '

      '. + form::hidden(array('user_id'),html::escapeHTML($u_login)). + form::hidden(array('user_pwd'),html::escapeHTML($u_pwd)). + '

      '. + '
      '; +} +elseif (!$can_install) +{ + echo '

      '.__('Installation can not be completed').'

      '. + '

      '.__('Errors:').'

      '.$err.'
      '. + '

      '.__('For the said reasons, Dotclear can not be installed. '. + 'Please refer to '. + 'the documentation to learn how to correct the problem.').'

      '; +} +?> +
      +
      + + \ No newline at end of file diff --git a/v2/dotclear/admin/install/wizard.php b/v2/dotclear/admin/install/wizard.php new file mode 100644 index 0000000..2f9120e --- /dev/null +++ b/v2/dotclear/admin/install/wizard.php @@ -0,0 +1,190 @@ +' . __($e->getMessage()) . '

      '); + } + + # Checks system capabilites + require dirname(__FILE__).'/check.php'; + if (!dcSystemCheck($con,$_e)) { + $can_install = false; + throw new Exception('

      '.__('Dotclear cannot be installed.').'

      • '.implode('
      • ',$_e).'
      '); + } + + # Check if dotclear is already installed + $schema = dbSchema::init($con); + if (in_array($DBPREFIX.'version',$schema->getTables())) { + throw new Exception(__('Dotclear is already installed.')); + } + + # Does config.php.in exist? + $config_in = dirname(__FILE__).'/../../inc/config.php.in'; + if (!is_file($config_in)) { + throw new Exception(sprintf(__('File %s does not exist.'),$config_in)); + } + + # Can we write config.php + if (!is_writable(dirname(DC_RC_PATH))) { + throw new Exception(sprintf(__('Cannot write %s file.'),DC_RC_PATH)); + } + + # Creates config.php file + $full_conf = file_get_contents($config_in); + + writeConfigValue('DC_DBDRIVER',$DBDRIVER,$full_conf); + writeConfigValue('DC_DBHOST',$DBHOST,$full_conf); + writeConfigValue('DC_DBUSER',$DBUSER,$full_conf); + writeConfigValue('DC_DBPASSWORD',$DBPASSWORD,$full_conf); + writeConfigValue('DC_DBNAME',$DBNAME,$full_conf); + writeConfigValue('DC_DBPREFIX',$DBPREFIX,$full_conf); + + $admin_url = preg_replace('%install/wizard.php$%','',$_SERVER['REQUEST_URI']); + writeConfigValue('DC_ADMIN_URL',http::getHost().$admin_url,$full_conf); + writeConfigValue('DC_ADMIN_MAILFROM','dotclear@'.$_SERVER['HTTP_HOST'],$full_conf); + writeConfigValue('DC_MASTER_KEY',md5(uniqid()),$full_conf); + + $fp = @fopen(DC_RC_PATH,'wb'); + if ($fp === false) { + throw new Exception(sprintf(__('Cannot write %s file.'),DC_RC_PATH)); + } + fwrite($fp,$full_conf); + fclose($fp); + chmod(DC_RC_PATH, 0666); + + $con->close(); + http::redirect('index.php?wiz=1'); + } + catch (Exception $e) + { + $err = $e->getMessage(); + } +} + +function writeConfigValue($name,$val,&$str) +{ + $val = str_replace("'","\'",$val); + $str = preg_replace('/(\''.$name.'\')(.*?)$/ms','$1,\''.$val.'\');',$str); +} + +header('Content-Type: text/html; charset=UTF-8'); +?> + + + + + + + + + + <?php echo __('Dotclear installation wizard'); ?> + + + + +
      +'.__('Dotclear installation wizard').''. +'
      '; + +if (!empty($err)) { + echo '

      '.__('Errors:').'

      '.$err.'
      '; +} else { + echo '

      '.__('Welcome').'

      '. + '

      '.__('To complete your Dotclear installation and start writing on your blog, '. + 'we just need to know how to access your database and who you are. '. + 'Just fill this two steps wizard with this information and we will be done.').'

      '. + '

      '.__('Attention:').' '. + __('this wizard may not function on every host. If it does not work for you, '. + 'please refer to '. + 'the documentation to learn how to create the config.php '. + 'file manually.').'

      '; +} + +echo +'

      '.__('System information').'

      '. + +'

      '.__('Please provide the following information needed to create your configuration file.').'

      '. + +'
      '. +'

      '. +'

      '. +'

      '. +'

      '. +'

      '. +'

      '. + +'

      '. +'
      '; +?> +
      +
      + + \ No newline at end of file diff --git a/v2/dotclear/admin/js/_blog_pref.js b/v2/dotclear/admin/js/_blog_pref.js new file mode 100644 index 0000000..8762ac5 --- /dev/null +++ b/v2/dotclear/admin/js/_blog_pref.js @@ -0,0 +1,4 @@ + +function checkQueryString(){var blogUrl=$('#blog_url')[0].value;var urlScan=$('#url_scan')[0].value;errorMsg='';if(/.*[^\/]$/.exec(blogUrl)&&urlScan=='path_info'){errorMsg=dotclear.msg.warning_path_info;}else if(/.*[^\?]$/.exec(blogUrl)&&urlScan=='query_string'){errorMsg=dotclear.msg.warning_query_string;} +$("p#urlwarning").remove();if(errorMsg!=''){$("#blog_url").parents('p').before('

      '+errorMsg+'

      ');}} +$(function(){checkQueryString();$('#blog_url').focusout(checkQueryString);$('#url_scan').live("change",checkQueryString);}); \ No newline at end of file diff --git a/v2/dotclear/admin/js/_blog_theme.js b/v2/dotclear/admin/js/_blog_theme.js new file mode 100644 index 0000000..77e42ec --- /dev/null +++ b/v2/dotclear/admin/js/_blog_theme.js @@ -0,0 +1,6 @@ + +$(function(){$('#themes-actions').hide();var submit_s=$('#themes-actions input[name=select]');var submit_r=$('#themes-actions input[name=remove]');var details=$('#themes div.theme-details');$('div.theme-actions',details).hide();$('input:radio',details).hide();$('div.theme-info span, div.theme-info a',details).hide();details.removeClass('theme-details').addClass('theme-details-js');var themes_wrapper=$('
      ');var theme_box=$('
      ');$('#themes').wrap(themes_wrapper).before(theme_box);details.each(function(){var box=this;var a=$(document.createElement('a'));a.attr('href','#');a.attr('title',$('>div h3>label',this).text());$(box).wrap(a);$(box).parent().click(function(event){update_box(box);event.preventDefault();return false;});});function update_box(e){theme_box.empty();var img=$('div.theme-shot',e).clone();var info=$('div.theme-info',e).clone();if($(e).hasClass('current-theme')){var actions=$('div.theme-actions',e).clone();actions.show();}else{var actions=$('
      ');if(submit_s.length>0&&!$('input:radio',info).attr('disabled')){var select=$(''+dotclear.msg.use_this_theme+'');select.css('font-weight','bold').click(function(){submit_s.click();return false;});actions.append(select).append('  ');} +if(submit_r.length>0&&$('input:radio',info).attr('id')!='theme_default'){var remove=$(''+dotclear.msg.remove_this_theme+'');remove.click(function(){var t_name=$(this).parents('#theme-box').find('div.theme-info h3:first').text();t_name=$.trim(t_name);if(window.confirm(dotclear.msg.confirm_delete_theme.replace('%s',t_name))){submit_r.click();} +return false;});actions.append(remove);}} +$('input:radio',info).remove();$('span, a',info).show();theme_box.append(img).append(info).append(actions);details.removeClass('theme-selected');$(e).addClass('theme-selected');$('input:radio',e).attr('checked','checked');} +update_box(details[0]);}); \ No newline at end of file diff --git a/v2/dotclear/admin/js/_categories.js b/v2/dotclear/admin/js/_categories.js new file mode 100644 index 0000000..8e6929e --- /dev/null +++ b/v2/dotclear/admin/js/_categories.js @@ -0,0 +1,2 @@ + +$(function(){$('form#delete-category').submit(function(){var c_id=$('#del_cat').val();var c_name=$('#del_cat option[value='+c_id+']').text();return window.confirm(dotclear.msg.confirm_delete_category.replace('%s',c_name));});});$(function(){$('form#reset-order').submit(function(){return window.confirm(dotclear.msg.confirm_reorder_categories);});}); \ No newline at end of file diff --git a/v2/dotclear/admin/js/_category.js b/v2/dotclear/admin/js/_category.js new file mode 100644 index 0000000..496a4c4 --- /dev/null +++ b/v2/dotclear/admin/js/_category.js @@ -0,0 +1,2 @@ + +$(function(){dotclear.hideLockable();var tbCategory=new jsToolBar(document.getElementById('cat_desc'));tbCategory.draw('xhtml');}); \ No newline at end of file diff --git a/v2/dotclear/admin/js/_comment.js b/v2/dotclear/admin/js/_comment.js new file mode 100644 index 0000000..a46fa52 --- /dev/null +++ b/v2/dotclear/admin/js/_comment.js @@ -0,0 +1,3 @@ + +$(function(){if(!document.getElementById){return;} +var tbComment=new jsToolBar(document.getElementById('comment_content'));tbComment.draw('xhtml');$('#comment-form input[name="delete"]').click(function(){return window.confirm(dotclear.msg.confirm_delete_comment);});}); \ No newline at end of file diff --git a/v2/dotclear/admin/js/_comments.js b/v2/dotclear/admin/js/_comments.js new file mode 100644 index 0000000..55e0bf5 --- /dev/null +++ b/v2/dotclear/admin/js/_comments.js @@ -0,0 +1,6 @@ + +dotclear.commentExpander=function(line){var td=line.firstChild;var img=document.createElement('img');img.src=dotclear.img_plus_src;img.alt=dotclear.img_plus_alt;img.className='expand';$(img).css('cursor','pointer');img.line=line;img.onclick=function(){dotclear.viewCommentContent(this,this.line);};td.insertBefore(img,td.firstChild);};dotclear.viewCommentContent=function(img,line){var commentId=line.id.substr(1);var tr=document.getElementById('ce'+commentId);if(!tr){tr=document.createElement('tr');tr.id='ce'+commentId;var td=document.createElement('td');td.colSpan=6;td.className='expand';tr.appendChild(td);img.src=dotclear.img_minus_src;img.alt=dotclear.img_minus_alt;$.get('services.php',{f:'getCommentById',id:commentId},function(data){var rsp=$(data).children('rsp')[0];if(rsp.attributes[0].value=='ok'){var comment=$(rsp).find('comment_display_content').text();if(comment){$(td).append(comment);var comment_email=$(rsp).find('comment_email').text();var comment_site=$(rsp).find('comment_site').text();var comment_ip=$(rsp).find('comment_ip').text();var comment_spam_disp=$(rsp).find('comment_spam_disp').text();$(td).append('

      '+dotclear.msg.website+' '+comment_site+'
      '+''+dotclear.msg.email+' '+comment_email+'
      '+''+dotclear.msg.ip_address+' '+comment_ip+''+'
      '+comment_spam_disp+'

      ');}}else{alert($(rsp).find('message').text());}});$(line).toggleClass('expand');line.parentNode.insertBefore(tr,line.nextSibling);} +else if(tr.style.display=='none') +{$(tr).toggle();$(line).toggleClass('expand');img.src=dotclear.img_minus_src;img.alt=dotclear.img_minus_alt;} +else +{$(tr).toggle();$(line).toggleClass('expand');img.src=dotclear.img_plus_src;img.alt=dotclear.img_plus_alt;}};$(function(){$('#form-comments tr.line').each(function(){dotclear.commentExpander(this);});$('.checkboxes-helpers').each(function(){dotclear.checkboxesHelpers(this);});$('#form-comments td input[type=checkbox]').enableShiftClick();dotclear.commentsActionsHelper();}); \ No newline at end of file diff --git a/v2/dotclear/admin/js/_index.js b/v2/dotclear/admin/js/_index.js new file mode 100644 index 0000000..ac78b57 --- /dev/null +++ b/v2/dotclear/admin/js/_index.js @@ -0,0 +1,10 @@ + +$(function(){var f=$('#quick-entry');if(f.length>0){var contentTb=new jsToolBar($('#post_content',f)[0]);contentTb.switchMode($('#post_format',f).val());$('input[name=save]',f).click(function(){quickPost(f,-2);return false;});if($('input[name=save-publish]',f).length>0){var btn=$('');$('input[name=save-publish]',f).remove();$('input[name=save]',f).after(btn).after(' ');btn.click(function(){quickPost(f,1);return false;});} +function quickPost(f,status){if(contentTb.getMode()=='wysiwyg'){contentTb.syncContents('iframe');} +var params={f:'quickPost',xd_check:dotclear.nonce,post_title:$('#post_title',f).val(),post_content:$('#post_content',f).val(),cat_id:$('#cat_id',f).val(),post_status:status,post_format:$('#post_format',f).val(),post_lang:$('#post_lang',f).val()} +$('p.qinfo',f).remove();$.post('services.php',params,function(data){if($('rsp[status=failed]',data).length>0){var msg='

      '+dotclear.msg.error+' '+$('rsp',data).text()+'

      ';}else{var msg='

      '+dotclear.msg.entry_created+' - '+ +dotclear.msg.edit_entry+'';if($('rsp>post',data).attr('post_status')==1){msg+=' - '+ +dotclear.msg.view_entry+'';} +msg+='

      ';$('#post_title',f).val('');$('#post_content',f).val('');if(contentTb.getMode()=='wysiwyg'){contentTb.syncContents('textarea');}} +$('fieldset',f).prepend(msg);});}} +$('#quick h3').toggleWithLegend($('#quick').children().not('h3'),{cookie:'dcx_quick_entry'},positionFooter);}); \ No newline at end of file diff --git a/v2/dotclear/admin/js/_langs.js b/v2/dotclear/admin/js/_langs.js new file mode 100644 index 0000000..8824cff --- /dev/null +++ b/v2/dotclear/admin/js/_langs.js @@ -0,0 +1,2 @@ + +$(function(){$('table.plugins form input[type=submit][name=delete]').click(function(){var l_name=$(this).parents('tr.line').find('td:first').text();return window.confirm(dotclear.msg.confirm_delete_lang.replace('%s',l_name));});}); \ No newline at end of file diff --git a/v2/dotclear/admin/js/_media.js b/v2/dotclear/admin/js/_media.js new file mode 100644 index 0000000..19893c0 --- /dev/null +++ b/v2/dotclear/admin/js/_media.js @@ -0,0 +1,7 @@ + +$(function(){fileRemoveAct();function fileRemoveAct(){$('a.media-remove').click(function(){var m_name=$(this).parents('ul').find('li:first>a').text();if(window.confirm(dotclear.msg.confirm_delete_media.replace('%s',m_name))){var f=$('#media-remove-hide').get(0);f.elements['remove'].value=this.href.replace(/^(.*)&remove=(.*?)(&|$)/,'$2');this.href='';f.submit();} +return false;});} +if(!$.browser.opera){if(dotclear.candyUpload_force_init=='1'){candyUploadInit();}} +function candyUploadInit() +{var candy_upload_success=false;var candy_upload_form_url=$('#media-upload').attr('action')+'&file_sort=date-desc&d='+$('#media-upload input[name=d]').val();var candy_upload_limit=$('#media-upload input[name=MAX_FILE_SIZE]').val();$('#media-upload').candyUpload({upload_url:dotclear.candyUpload.base_url+'/media.php',flash_movie:dotclear.candyUpload.movie_url,file_size_limit:candy_upload_limit+'b',params:'swfupload=1&'+dotclear.candyUpload.params,callbacks:{createControls:function(){var _this=this;this.ctrl.btn_browse.hide();this.ctrl.msg.html(dotclear.msg.load_enhanced_uploader);},flashReady:function(){var _this=this;this.ctrl.msg.fadeOut('fast',function(){$(this).text(_this.locales.no_file_in_queue).fadeIn('fast');_this.ctrl.btn_browse.fadeIn('fast',function(){_this.upldr.container.children().css({width:$('.cu-btn-browse').width(),height:$('.cu-btn-browse').height()});});});},uploadSuccess:function(o,data){if(data=='ok'){candy_upload_success=true;this.fileMsg(o.id,this.locales.file_uploaded);}else{this.fileErrorMsg(o.id,data);} +if(candy_upload_success&&$('div.cu-file:has(span.cu-filecancel a)',this.ctrl.files).length==0){$.cookie('dc_candy_upl','1',{expires:30});$.get(candy_upload_form_url,function(data){var media=$('div.media-list');media.after($('div.media-list',data)).remove();fileRemoveAct();});}},fileQueued:function(){positionFooter();}}});}}); \ No newline at end of file diff --git a/v2/dotclear/admin/js/_media_item.js b/v2/dotclear/admin/js/_media_item.js new file mode 100644 index 0000000..c9a2eeb --- /dev/null +++ b/v2/dotclear/admin/js/_media_item.js @@ -0,0 +1,4 @@ + +$(function(){$('#media-details-tab').onetabload(function(){var media_dt=document.getElementById('media_dt');if(media_dt==undefined){return;} +var post_dtPick=new datePicker(media_dt);post_dtPick.img_top='1.5em';post_dtPick.draw();});$('#file-unzip').each(function(){var a=document.createElement('a');var mediaId=$(this).find('input[name=id]').val();var self=$(this);a.href='#';$(a).text(dotclear.msg.zip_file_content);self.before(a);$(a).wrap('

      ');$(a).click(function(){$.get('services.php',{f:'getZipMediaContent',id:mediaId},function(data){var rsp=$(data).children('rsp')[0];if(rsp.attributes[0].value=='ok'){var div=document.createElement('div');var list=document.createElement('ul');var expanded=false;$(div).css({overflow:'auto',border:'1px solid #ccc',margin:'1em 0',padding:'1px 0.5em'});$(div).append(list);self.before(div);$(a).hide();$(div).before('

      '+dotclear.msg.zip_file_content+'

      ');$(rsp).find('file').each(function(){$(list).append('
    • '+$(this).text()+'
    • ');if($(div).height()>200&&!expanded){$(div).css({height:'200px'});expanded=true;}});}else{alert($(rsp).find('message').text());}});return false;});});$('#file-unzip').submit(function(){if($(this).find('#inflate_mode').val()=='current'){return window.confirm(dotclear.msg.confirm_extract_current);} +return true;});}); \ No newline at end of file diff --git a/v2/dotclear/admin/js/_permissions.js b/v2/dotclear/admin/js/_permissions.js new file mode 100644 index 0000000..1547911 --- /dev/null +++ b/v2/dotclear/admin/js/_permissions.js @@ -0,0 +1,6 @@ + +jQuery.fn.updatePermissionsForm=function(){return this.each(function(){var perms={};var re=/^perm\[(.+?)\]\[(.+?)\]$/;var e,prop;for(var i=0;i'+dotclear.msg.website+' '+comment_site+'
      '+''+dotclear.msg.email+' '+ +comment_email+'
      '+comment_spam_disp+'

      ');}}else{alert($(rsp).find('message').text());}});$(line).toggleClass('expand');line.parentNode.insertBefore(tr,line.nextSibling);} +else if(tr.style.display=='none') +{$(tr).toggle();$(line).toggleClass('expand');img.src=dotclear.img_minus_src;img.alt=dotclear.img_minus_alt;} +else +{$(tr).toggle();$(line).toggleClass('expand');img.src=dotclear.img_plus_src;img.alt=dotclear.img_plus_alt;}};$(function(){if(!document.getElementById){return;} +if(document.getElementById('edit-entry')) +{var formatField=$('#post_format').get(0);$(formatField).change(function(){excerptTb.switchMode(this.value);contentTb.switchMode(this.value);});var excerptTb=new jsToolBar(document.getElementById('post_excerpt'));var contentTb=new jsToolBar(document.getElementById('post_content'));excerptTb.context=contentTb.context='post';} +if(document.getElementById('comment_content')){var commentTb=new jsToolBar(document.getElementById('comment_content'));} +$('#post-preview').modalWeb($(window).width()-40,$(window).height()-40);$('#edit-entry').onetabload(function(){dotclear.hideLockable();var post_dtPick=new datePicker($('#post_dt').get(0));post_dtPick.img_top='1.5em';post_dtPick.draw();$('input[name="delete"]').click(function(){return window.confirm(dotclear.msg.confirm_delete_post);});$('#notes-area label').toggleWithLegend($('#notes-area').children().not('label'),{cookie:'dcx_post_notes',hide:$('#post_notes').val()==''});$('#post_lang').parent().toggleWithLegend($('#post_lang'),{cookie:'dcx_post_lang'});$('#post_password').parent().toggleWithLegend($('#post_password'),{cookie:'dcx_post_password',hide:$('#post_password').val()==''});$('#excerpt-area label').toggleWithLegend($('#excerpt-area').children().not('label'),{fn:function(){excerptTb.switchMode(formatField.value);},cookie:'dcx_post_excerpt',hide:$('#post_excerpt').val()==''});contentTb.switchMode(formatField.value);$('a.attachment-remove').click(function(){this.href='';var m_name=$(this).parents('ul').find('li:first>a').attr('title');if(window.confirm(dotclear.msg.confirm_remove_attachment.replace('%s',m_name))){var f=$('#attachment-remove-hide').get(0);f.elements['media_id'].value=this.id.substring(11);f.submit();} +return false;});var h=document.createElement('h4');var a=document.createElement('a');a.href='#';$(a).click(function(){var params={xd_check:dotclear.nonce,f:'validatePostMarkup',excerpt:$('#post_excerpt').text(),content:$('#post_content').text(),format:$('#post_format').get(0).value,lang:$('#post_lang').get(0).value};$.post('services.php',params,function(data){if($(data).find('rsp').attr('status')!='ok'){alert($(data).find('rsp message').text());return false;} +if($(data).find('valid').text()==1){var p=document.createElement('p');p.id='markup-validator';if($('#markup-validator').length>0){$('#markup-validator').remove();} +$(p).addClass('message');$(p).text(dotclear.msg.xhtml_valid);$(p).insertAfter(h);$(p).backgroundFade({sColor:'#666666',eColor:'#ffcc00',steps:50},function(){$(this).backgroundFade({sColor:'#ffcc00',eColor:'#666666'});});}else{var div=document.createElement('div');div.id='markup-validator';if($('#markup-validator').length>0){$('#markup-validator').remove();} +$(div).addClass('error');$(div).html('

      '+dotclear.msg.xhtml_not_valid+'

      '+$(data).find('errors').text());$(div).insertAfter(h);$(div).backgroundFade({sColor:'#ffffff',eColor:'#ff9999',steps:50},function(){$(this).backgroundFade({sColor:'#ff9999',eColor:'#ffffff'});});} +return false;});return false;});a.appendChild(document.createTextNode(dotclear.msg.xhtml_validator));h.appendChild(a);$(h).appendTo('#entry-content');var excerpt=$('#post_excerpt').val();var content=$('#post_content').val();$('#convert-xhtml').click(function(){if(excerpt!=$('#post_excerpt').val()||content!=$('#post_content').val()){return window.confirm(dotclear.msg.confirm_change_post_format);}});});$('#comments').onetabload(function(){$('.comments-list tr.line').each(function(){dotclear.commentExpander(this);});$('.checkboxes-helpers').each(function(){dotclear.checkboxesHelpers(this);});dotclear.commentsActionsHelper();});$('#add-comment').onetabload(function(){commentTb.draw('xhtml');});}); \ No newline at end of file diff --git a/v2/dotclear/admin/js/_posts_list.js b/v2/dotclear/admin/js/_posts_list.js new file mode 100644 index 0000000..2719cca --- /dev/null +++ b/v2/dotclear/admin/js/_posts_list.js @@ -0,0 +1,7 @@ + +dotclear.postExpander=function(line){var td=line.firstChild;var img=document.createElement('img');img.src=dotclear.img_plus_src;img.alt=dotclear.img_plus_alt;img.className='expand';$(img).css('cursor','pointer');img.line=line;img.onclick=function(){dotclear.viewPostContent(this,this.line);positionFooter();};td.insertBefore(img,td.firstChild);};dotclear.viewPostContent=function(img,line){var postId=line.id.substr(1);var tr=document.getElementById('pe'+postId);if(!tr){tr=document.createElement('tr');tr.id='pe'+postId;var td=document.createElement('td');td.colSpan=8;td.className='expand';tr.appendChild(td);img.src=dotclear.img_minus_src;img.alt=dotclear.img_minus_alt;$.get('services.php',{f:'getPostById',id:postId,post_type:''},function(data){var rsp=$(data).children('rsp')[0];if(rsp.attributes[0].value=='ok'){var post=$(rsp).find('post_display_content').text();var post_excerpt=$(rsp).find('post_display_excerpt').text();var res='';if(post){if(post_excerpt){res+=post_excerpt+'
      ';} +res+=post;$(td).append(res);}}else{alert($(rsp).find('message').text());}});$(line).toggleClass('expand');line.parentNode.insertBefore(tr,line.nextSibling);} +else if(tr.style.display=='none') +{$(tr).toggle();$(line).toggleClass('expand');img.src=dotclear.img_minus_src;img.alt=dotclear.img_minus_alt;} +else +{$(tr).toggle();$(line).toggleClass('expand');img.src=dotclear.img_plus_src;img.alt=dotclear.img_plus_alt;}};$(function(){$('#form-entries tr.line').each(function(){dotclear.postExpander(this);});$('.checkboxes-helpers').each(function(){dotclear.checkboxesHelpers(this);});$('#form-entries td input[type=checkbox]').enableShiftClick();dotclear.postsActionsHelper();}); \ No newline at end of file diff --git a/v2/dotclear/admin/js/_preferences-dragdrop.js b/v2/dotclear/admin/js/_preferences-dragdrop.js new file mode 100644 index 0000000..3599f30 --- /dev/null +++ b/v2/dotclear/admin/js/_preferences-dragdrop.js @@ -0,0 +1,2 @@ + +$(function(){$("#my-favs ul").sortable({'cursor':'move'});$("#my-favs ul").hover(function(){$(this).css({'cursor':'move'});},function(){$(this).css({'cursor':'auto'});});$('#favs-form').submit(function(){var order=[];$("#my-favs ul li input.position").each(function(){order.push(this.name.replace(/^order\[([^\]]+)\]$/,'$1'));});$("input[name=favs_order]")[0].value=order.join(',');return true;});$("#my-favs ul li input.position").hide();}); \ No newline at end of file diff --git a/v2/dotclear/admin/js/_preferences.js b/v2/dotclear/admin/js/_preferences.js new file mode 100644 index 0000000..d47d010 --- /dev/null +++ b/v2/dotclear/admin/js/_preferences.js @@ -0,0 +1,5 @@ + +$(function(){if($('#new_pwd').length==0){return;} +var user_email=$('#user_email').val();$('#user-form').submit(function(){var e=this.elements['cur_pwd'];if(e.value!=''){return true;} +if($('#user_email').val()!=user_email||$('#new_pwd').val()!=''){e.focus();$(e).backgroundFade({sColor:'#ffffff',eColor:'#ff9999',steps:50},function(){$(this).backgroundFade({sColor:'#ff9999',eColor:'#ffffff'});});return false;} +return true;});}); \ No newline at end of file diff --git a/v2/dotclear/admin/js/_trackbacks.js b/v2/dotclear/admin/js/_trackbacks.js new file mode 100644 index 0000000..b3842d7 --- /dev/null +++ b/v2/dotclear/admin/js/_trackbacks.js @@ -0,0 +1,2 @@ + +$(function(){$('#tb_excerpt').keypress(function(){if(this.value.length>255){this.value=this.value.substring(0,255);}});}); \ No newline at end of file diff --git a/v2/dotclear/admin/js/_users.js b/v2/dotclear/admin/js/_users.js new file mode 100644 index 0000000..ae2756f --- /dev/null +++ b/v2/dotclear/admin/js/_users.js @@ -0,0 +1,7 @@ + +$(function(){$('.checkboxes-helpers').each(function(){dotclear.checkboxesHelpers(this);});$('#form-users').submit(function(){var action=$(this).find('select[name="dispatch_action"]').val();var user_ids=new Array();var nb_posts=new Array();var i;var msg_cannot_delete=false;$(this).find('input[name="user_id[]"]').each(function(){user_ids.push(this);});$(this).find('input[name="nb_post[]"]').each(function(){nb_posts.push(this.value);});if(action=='deleteuser'){for(i=0;i0){if(user_ids[i].checked==true){msg_cannot_delete=true;user_ids[i].checked=false;}}} +if(msg_cannot_delete==true){alert(dotclear.msg.cannot_delete_users);}} +var selectfields=0;for(i=0;iThis.height()){This.css('height',$('body').height()+'px');}};var textToggler=function(o){var i=$(''+p.img_on_alt+'');o.css('cursor','pointer');var hide=true;o.prepend(' ').prepend(i);o.click(function(){$(this).nextAll().each(function(){if($(this).is('h3')){return false;} +$(this).toggle();sizeBox();return true;});hide=!hide;var img=$(this).find('img');if(!hide){img.attr('src',p.img_off_src);}else{img.attr('src',p.img_on_src);}});};this.addClass('help-box');this.find('>hr').remove();this.find('h3').each(function(){textToggler($(this));});this.find('h3:first').nextAll('*:not(h3)').hide();sizeBox();var img=$(''+dotclear.msg.help+'');var select=$();img.click(function(){return toggle();});$('#content').append(img);return this;};var dotclear={msg:{},hideLockable:function(){$('div.lockable').each(function(){var current_lockable_div=this;$(this).find('p.form-note').hide();$(this).find('input').each(function(){this.disabled=true;$(this).width(($(this).width()-14)+'px');var imgE=document.createElement('img');imgE.src='images/locker.png';imgE.style.position='absolute';imgE.style.top='1.7em';imgE.style.left=($(this).width()+4)+'px';$(imgE).css('cursor','pointer');$(imgE).click(function(){$(this).hide();$(this).prev('input').each(function(){this.disabled=false;$(this).width(($(this).width()+14)+'px');});$(current_lockable_div).find('p.form-note').show();});$(this).parent().css('position','relative');$(this).after(imgE);});});},checkboxesHelpers:function(e){var a=document.createElement('a');a.href='#';$(a).append(document.createTextNode(dotclear.msg.select_all));a.onclick=function(){$(this).parents('form').find('input[type="checkbox"]').check();return false;};$(e).append(a);$(e).append(document.createTextNode(' - '));a=document.createElement('a');a.href='#';$(a).append(document.createTextNode(dotclear.msg.no_selection));a.onclick=function(){$(this).parents('form').find('input[type="checkbox"]').unCheck();return false;};$(e).append(a);$(e).append(document.createTextNode(' - '));a=document.createElement('a');a.href='#';$(a).append(document.createTextNode(dotclear.msg.invert_sel));a.onclick=function(){$(this).parents('form').find('input[type="checkbox"]').toggleCheck();return false;};$(e).append(a);},postsActionsHelper:function(){$('#form-entries').submit(function(){var action=$(this).find('select[name="action"]').val();var checked=false;$(this).find('input[name="entries[]"]').each(function(){if(this.checked){checked=true;}});if(!checked){return false;} +if(action=='delete'){return window.confirm(dotclear.msg.confirm_delete_posts.replace('%s',$('input[name="entries[]"]:checked').size()));} +return true;});},commentsActionsHelper:function(){$('#form-comments').submit(function(){var action=$(this).find('select[name="action"]').val();var checked=false;$(this).find('input[name="comments[]"]').each(function(){if(this.checked){checked=true;}});if(!checked){return false;} +if(action=='delete'){return window.confirm(dotclear.msg.confirm_delete_comments.replace('%s',$('input[name="comments[]"]:checked').size()));} +return true;});}};function positionFooter(){$("#wrapper").css({overflow:"auto"});var page_height=$("#top").height()+$("#wrapper").height()-$("#footer").height();if(page_height<$(window).height()){var page_width=$(document).width()-30;$("#footer").css({position:"absolute",bottom:"10px",width:page_width+"px",padding:".75em 0",marginbottom:"0"});}else{$("#footer").css({position:"static",padding:".75em 0",width:"auto"});}} +$(function(){$('#switchblog').change(function(){this.form.submit();});var menu_settings={img_on_src:dotclear.img_menu_off,img_off_src:dotclear.img_menu_on,legend_click:true,speed:100} +$('#blog-menu h3:first').toggleWithLegend($('#blog-menu ul:first'),$.extend({cookie:'dc_blog_menu'},menu_settings));$('#system-menu h3:first').toggleWithLegend($('#system-menu ul:first'),$.extend({cookie:'dc_system_menu'},menu_settings));$('#plugins-menu h3:first').toggleWithLegend($('#plugins-menu ul:first'),$.extend({cookie:'dc_plugins_menu'},menu_settings));$('#favorites-menu h3:first').toggleWithLegend($('#favorites-menu ul:first'),$.extend({cookie:'dc_favorites_menu',hide:false,reverse_cookie:true},menu_settings));$('#help').helpViewer();$('.message').backgroundFade({sColor:'#cccccc',eColor:'#666666',steps:20});$('.error').backgroundFade({sColor:'#f5e5e5',eColor:'#e5bfbf',steps:20});$('form:has(input[type=password][name=your_pwd])').submit(function(){var e=this.elements['your_pwd'];if(e.value==''){e.focus();$(e).backgroundFade({sColor:'#ffffff',eColor:'#ff9999',steps:50},function(){$(this).backgroundFade({sColor:'#ff9999',eColor:'#ffffff'});});return false;} +return true;});positionFooter();$(window).resize(positionFooter);}); \ No newline at end of file diff --git a/v2/dotclear/admin/js/confirm-close.js b/v2/dotclear/admin/js/confirm-close.js new file mode 100644 index 0000000..41489c9 --- /dev/null +++ b/v2/dotclear/admin/js/confirm-close.js @@ -0,0 +1,12 @@ + +function confirmClose(){if(arguments.length>0){for(var i=0;i0){var res=new Array();var f;for(var i=0;i23){h=0;} +if(h<10){h='0'+h;} +this.hour=h*1;this.oHour.value=h;},setMinute:function(m){if(m<0){m=59;} +if(m>59){m=0;} +if(m<10){m='0'+m;} +this.minute=m*1;this.oMinute.value=m;},changeMonth:function(dir){var y=this.year;var m=this.month;m=m+dir;if(m>12){this.month=1;this.year++;} +else if(m<1){this.month=12;this.year--;} +else{this.month=m;} +this.setDate();},changeYear:function(dir){this.year=this.year+dir;this.setDate();},changeHour:function(dir){this.setHour(this.hour*1+dir);},changeMinute:function(dir){this.setMinute(this.minute*1+dir);},sendDate:function(d){var m=this.month;var hour=this.oHour.value*1;var minute=this.oMinute.value*1;if(hour<0||hour>23||isNaN(hour)){hour=0;} +if(minute<0||minute>59||isNaN(minute)){minute=0;} +if(m<10){m='0'+m;} +if(d<10){d='0'+d;} +if(hour<10){hour='0'+hour;} +if(minute<10){minute='0'+minute;} +this.target.value=this.year+'-'+m+'-'+d+' '+hour+':'+minute;this.close();},sendNow:function(){var dt=new Date();var y=dt.getFullYear();var m=dt.getMonth()+1;var d=dt.getDate();var h=dt.getHours();var i=dt.getMinutes();if(m<10){m='0'+m;} +if(d<10){d='0'+d;} +if(h<10){h='0'+h;} +if(i<10){i='0'+i;} +this.target.value=y+'-'+m+'-'+d+' '+h+':'+i;this.close();},close:function(){document.body.removeChild(this.oTable);},numberOfDays:function(){var res=31;if(this.month==4||this.month==6||this.month==9||this.month==11){res=30;}else if(this.month==2){res=28;if(this.year%4==0&&(this.year%100!=0||this.year%400==0)){res=29;}} +return res;},firstDay:function(){var dt=new Date(this.year,this.month-1,1);var res=dt.getDay();if(res==0){res=7;} +return res;},show:function(){var re=/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2})/;var match=re.exec(this.target.value);if(match){this.year=match[1]*1;this.month=match[2]*1;this.day=match[3]*1;this.hour=match[4]*1;this.minute=match[5]*1;}else{var dt=new Date();this.year=dt.getFullYear();this.month=dt.getMonth()+1;this.day=dt.getDate();this.hour=dt.getHours();this.minute=dt.getMinutes();} +this.oTable.appendChild(this.oBody);this.setDate();this.setPosition();document.body.appendChild(this.oTable);this.oHour.focus();},setPosition:function(){var t_x=this.findPosX(this.target);var t_y=this.findPosY(this.target);var o_h=this.oTable.offsetHeight;var o_w=this.oTable.offsetWidth;this.oTable.style.position='absolute';this.oTable.style.zIndex='100';this.oTable.style.top=t_y+'px';this.oTable.style.left=t_x+'px';},findPosX:function(obj){var curleft=0;if(obj.offsetParent){while(1){curleft+=obj.offsetLeft;if(!obj.offsetParent){break;} +obj=obj.offsetParent;}}else if(obj.x){curleft+=obj.x;} +return curleft;},findPosY:function(obj){var curtop=0;if(obj.offsetParent){while(1){curtop+=obj.offsetTop;if(!obj.offsetParent){break;} +obj=obj.offsetParent;}}else if(obj.y){curtop+=obj.y;} +return curtop;},draw:function(){var imgE=document.createElement('img');imgE.src=this.img_src;imgE.style.position='absolute';imgE.style.top=this.img_top;imgE.style.left=(this.target.clientWidth+4)+'px';imgE.obj=this;imgE.fn=this.show;imgE.onclick=function(){this.fn.apply(this.obj);};this.target.parentNode.style.position='relative';this.target.parentNode.insertBefore(imgE,this.target.nextSibling);}}; \ No newline at end of file diff --git a/v2/dotclear/admin/js/dragsort-tablerows.js b/v2/dotclear/admin/js/dragsort-tablerows.js new file mode 100644 index 0000000..164b5ec --- /dev/null +++ b/v2/dotclear/admin/js/dragsort-tablerows.js @@ -0,0 +1,2 @@ + +ToolMan._dragsortFactory.makeTableSortable=function(table){if(table==null)return;var helpers=ToolMan.helpers();var coordinates=ToolMan.coordinates();var items=table.getElementsByTagName("tr");helpers.map(items,function(item){var dragGroup=dragsort.makeSortable(item);dragGroup.setThreshold(4);var min,max;dragGroup.addTransform(function(coordinate,dragEvent){return coordinate.constrainTo(min,max);});dragGroup.register('dragstart',function(){var items=table.getElementsByTagName("tr");min=max=coordinates.topLeftOffset(items[0]);for(var i=1,n=items.length;i":"","\\/\\*[^*]*\\*+([^\\/][^*]*\\*+)*\\/":"","@(namespace|import)[^;\\n]+[;\\n]":"","'(\\\\.|[^'\\\\])*'":encodeString,'"(\\\\.|[^"\\\\])*"':encodeString,"\\s+":" "});function encode(cssText){return encoder.exec(cssText);};function decode(cssText){return cssText.replace(ENCODED,function(match,index){return _strings[index-1];});};function encodeString(string){return"\x01"+_strings.push(string.replace(UNICODE,function(match,chr){return eval("'\\u"+"0000".slice(chr.length)+chr+"'");}).slice(1,-1).replace(QUOTES,"\\'"));};function getString(value){return STRING.test(value)?_strings[value.slice(1)-1]:value;};var rotater=new RegGrp({Width:"Height",width:"height",Left:"Top",left:"top",Right:"Bottom",right:"bottom",onX:"onY"});function rotate(fn){return rotater.exec(fn);};var eventHandlers=[];function addResize(handler){addRecalc(handler);addEventHandler(window,"onresize",handler);};function addEventHandler(element,type,handler){element.attachEvent(type,handler);eventHandlers.push(arguments);};function removeEventHandler(element,type,handler){try{element.detachEvent(type,handler);}catch(ignore){}};addEventHandler(window,"onunload",function(){var handler;while(handler=eventHandlers.pop()){removeEventHandler(handler[0],handler[1],handler[2]);}});function register(handler,element,condition){if(!handler.elements)handler.elements={};if(condition)handler.elements[element.uniqueID]=element;else delete handler.elements[element.uniqueID];return condition;};addEventHandler(window,"onbeforeprint",function(){if(!IE7.CSS.print)new StyleSheet("print");IE7.CSS.print.recalc();});var PIXEL=/^\d+(px)?$/i;var PERCENT=/^\d+%$/;var getPixelValue=function(element,value){if(PIXEL.test(value))return parseInt(value);var style=element.style.left;var runtimeStyle=element.runtimeStyle.left;element.runtimeStyle.left=element.currentStyle.left;element.style.left=value||0;value=element.style.pixelLeft;element.style.left=style;element.runtimeStyle.left=runtimeStyle;return value;};var $IE7="ie7-";var Fix=Base.extend({constructor:function(){this.fixes=[];this.recalcs=[];},init:Undefined});var recalcs=[];function addRecalc(recalc){recalcs.push(recalc);};IE7.recalc=function(){IE7.HTML.recalc();IE7.CSS.recalc();for(var i=0;i1?2:0;var block=cssParser.exec(selectors[i])||"if(0){";if(_wild){block+=format("if(e%1.nodeName!='!'){",_index);} +var store=_duplicate>1?_TEST:"";block+=format(store+_STORE,_index);block+=Array(match(block,/\{/g).length+1).join("}");fn+=block;} +eval(format(_FN,reg)+cssParser.unescape(fn)+"return s?null:r}");_cache[selector]=_selectorFunction;} +return _cache[selector](context||document,single);};var _MSIE5=appVersion<6;var _EVALUATED=/^(href|src)$/;var _ATTRIBUTES={"class":"className","for":"htmlFor"};IE7._indexed=1;IE7._byId=function(document,id){var result=document.all[id]||null;if(!result||result.id==id)return result;for(var i=0;i+~,]|[^(]\+|^)([#.:\[])/g,IMPLIED_SPACE=/(^|,)([^\s>+~])/g,WHITESPACE=/\s*([\s>+~(),]|^|$)\s*/g,WILD_CARD=/\s\*\s/g;;var CSSParser=RegGrp.extend({constructor:function(items){this.base(items);this.sorter=new RegGrp;this.sorter.add(/:not\([^)]*\)/,RegGrp.IGNORE);this.sorter.add(/([ >](\*|[\w-]+))([^: >+~]*)(:\w+-child(\([^)]+\))?)([^: >+~]*)/,"$1$3$6$4");},ignoreCase:true,escape:function(selector){return this.optimise(this.format(selector));},format:function(selector){return selector.replace(WHITESPACE,"$1").replace(IMPLIED_SPACE,"$1 $2").replace(IMPLIED_ASTERISK,"$1*$2");},optimise:function(selector){return this.sorter.exec(selector.replace(WILD_CARD,">* "));},unescape:function(selector){return decode(selector);}});var _OPERATORS={"":"%1!=null","=":"%1=='%2'","~=":/(^| )%1( |$)/,"|=":/^%1(-|$)/,"^=":/^%1/,"$=":/%1$/,"*=":/%1/};var _PSEUDO_CLASSES={"first-child":"!IE7._getPreviousElementSibling(e%1)","link":"e%1.currentStyle['ie7-link']=='link'","visited":"e%1.currentStyle['ie7-link']=='visited'"};var _VAR="var p%2=0,i%2,e%2,n%2=e%1.";var _ID="e%1.sourceIndex";var _TEST="var g="+_ID+";if(!p[g]){p[g]=1;";var _STORE="r[r.length]=e%1;if(s)return e%1;";var _FN="var _selectorFunction=function(e0,s){IE7._indexed++;var r=[],p={},reg=[%1],d=document;";var reg;var _index;var _wild;var _list;var _duplicate;var _cache={};var cssParser=new CSSParser({" (\\*|[\\w-]+)#([\\w-]+)":function(match,tagName,id){_wild=false;var replacement="var e%2=IE7._byId(d,'%4');if(e%2&&";if(tagName!="*")replacement+="e%2.nodeName=='%3'&&";replacement+="(e%1==d||e%1.contains(e%2))){";if(_list)replacement+=format("i%1=n%1.length;",_list);return format(replacement,_index++,_index,tagName.toUpperCase(),id);}," (\\*|[\\w-]+)":function(match,tagName){_duplicate++;_wild=tagName=="*";var replacement=_VAR;replacement+=(_wild&&_MSIE5)?"all":"getElementsByTagName('%3')";replacement+=";for(i%2=0;(e%2=n%2[i%2]);i%2++){";return format(replacement,_index++,_list=_index,tagName.toUpperCase());},">(\\*|[\\w-]+)":function(match,tagName){var children=_list;_wild=tagName=="*";var replacement=_VAR;replacement+=children?"children":"childNodes";if(!_wild&&children)replacement+=".tags('%3')";replacement+=";for(i%2=0;(e%2=n%2[i%2]);i%2++){";if(_wild){replacement+="if(e%2.nodeType==1){";_wild=_MSIE5;}else{if(!children)replacement+="if(e%2.nodeName=='%3'){";} +return format(replacement,_index++,_list=_index,tagName.toUpperCase());},"\\+(\\*|[\\w-]+)":function(match,tagName){var replacement="";if(_wild)replacement+="if(e%1.nodeName!='!'){";_wild=false;replacement+="e%1=IE7._getNextElementSibling(e%1);if(e%1";if(tagName!="*")replacement+="&&e%1.nodeName=='%2'";replacement+="){";return format(replacement,_index,tagName.toUpperCase());},"~(\\*|[\\w-]+)":function(match,tagName){var replacement="";if(_wild)replacement+="if(e%1.nodeName!='!'){";_wild=false;_duplicate=2;replacement+="while(e%1=e%1.nextSibling){if(e%1.ie7_adjacent==IE7._indexed)break;if(";if(tagName=="*"){replacement+="e%1.nodeType==1";if(_MSIE5)replacement+="&&e%1.nodeName!='!'";}else replacement+="e%1.nodeName=='%2'";replacement+="){e%1.ie7_adjacent=IE7._indexed;";return format(replacement,_index,tagName.toUpperCase());},"#([\\w-]+)":function(match,id){_wild=false;var replacement="if(e%1.id=='%2'){";if(_list)replacement+=format("i%1=n%1.length;",_list);return format(replacement,_index,id);},"\\.([\\w-]+)":function(match,className){_wild=false;reg.push(new RegExp("(^|\\s)"+rescape(className)+"(\\s|$)"));return format("if(e%1.className&®[%2].test(e%1.className)){",_index,reg.length-1);},"\\[([\\w-]+)\\s*([^=]?=)?\\s*([^\\]]*)\\]":function(match,attr,operator,value){var alias=_ATTRIBUTES[attr]||attr;if(operator){var getAttribute="e%1.getAttribute('%2',2)";if(!_EVALUATED.test(attr)){getAttribute="e%1.%3||"+getAttribute;} +attr=format("("+getAttribute+")",_index,attr,alias);}else{attr=format("IE7._getAttribute(e%1,'%2')",_index,attr);} +var replacement=_OPERATORS[operator||""]||"0";if(replacement&&replacement.source){reg.push(new RegExp(format(replacement.source,rescape(cssParser.unescape(value)))));replacement="reg[%2].test(%1)";value=reg.length-1;} +return"if("+format(replacement,attr,value)+"){";},":+([\\w-]+)(\\(([^)]+)\\))?":function(match,pseudoClass,$2,args){pseudoClass=_PSEUDO_CLASSES[pseudoClass];return"if("+(pseudoClass?format(pseudoClass,_index,args||""):"0")+"){";}});var HYPERLINK=/a(#[\w-]+)?(\.[\w-]+)?:(hover|active)/i;var BRACE1=/\s*\{\s*/,BRACE2=/\s*\}\s*/,COMMA=/\s*\,\s*/;var FIRST_LINE_LETTER=/(.*)(:first-(line|letter))/;var styleSheets=document.styleSheets;IE7.CSS=new(Fix.extend({parser:new Parser,screen:"",print:"",styles:[],rules:[],pseudoClasses:appVersion<7?"first\\-child":"",dynamicPseudoClasses:{toString:function(){var strings=[];for(var pseudoClass in this)strings.push(pseudoClass);return strings.join("|");}},init:function(){var NONE="^\x01$";var CLASS="\\[class=?[^\\]]*\\]";var pseudoClasses=[];if(this.pseudoClasses)pseudoClasses.push(this.pseudoClasses);var dynamicPseudoClasses=this.dynamicPseudoClasses.toString();if(dynamicPseudoClasses)pseudoClasses.push(dynamicPseudoClasses);pseudoClasses=pseudoClasses.join("|");var unknown=appVersion<7?["[>+~[(]|([:.])\\w+\\1"]:[CLASS];if(pseudoClasses)unknown.push(":("+pseudoClasses+")");this.UNKNOWN=new RegExp(unknown.join("|")||NONE,"i");var complex=appVersion<7?["\\[[^\\]]+\\]|[^\\s(\\[]+\\s*[+~]"]:[CLASS];var complexRule=complex.concat();if(pseudoClasses)complexRule.push(":("+pseudoClasses+")");Rule.COMPLEX=new RegExp(complexRule.join("|")||NONE,"ig");if(this.pseudoClasses)complex.push(":("+this.pseudoClasses+")");DynamicRule.COMPLEX=new RegExp(complex.join("|")||NONE,"i");DynamicRule.MATCH=new RegExp(dynamicPseudoClasses?"(.*):("+dynamicPseudoClasses+")(.*)":NONE,"i");this.createStyleSheet();this.refresh();},addEventHandler:function(){addEventHandler.apply(null,arguments);},addFix:function(expression,replacement){this.parser.add(expression,replacement);},addRecalc:function(propertyName,test,handler,replacement){test=new RegExp("([{;\\s])"+propertyName+"\\s*:\\s*"+test+"[^;}]*");var id=this.recalcs.length;if(replacement)replacement=propertyName+":"+replacement;this.addFix(test,function(match,$1){return(replacement?$1+replacement:match)+";ie7-"+match.slice(1)+";ie7_recalc"+id+":1";});this.recalcs.push(arguments);return id;},apply:function(){this.getInlineStyles();new StyleSheet("screen");this.trash();},createStyleSheet:function(){this.styleSheet=document.createStyleSheet();this.styleSheet.ie7=true;this.styleSheet.owningElement.ie7=true;this.styleSheet.cssText=HEADER;},getInlineStyles:function(){var styleSheets=document.getElementsByTagName("style"),styleSheet;for(var i=styleSheets.length-1;(styleSheet=styleSheets[i]);i--){if(!styleSheet.disabled&&!styleSheet.ie7){this.styles.push(styleSheet.innerHTML);}}},getText:function(styleSheet,path){try{var cssText=styleSheet.cssText;}catch(e){cssText="";} +if(httpRequest)cssText=loadFile(styleSheet.href,path)||cssText;return cssText;},recalc:function(){this.screen.recalc();var RECALCS=/ie7_recalc\d+/g;var start=HEADER.match(/[{,]/g).length;var stop=start+(this.screen.cssText.match(/\{/g)||"").length;var rules=this.styleSheet.rules,rule;var calcs,calc,elements,element,i,j,k,id;for(i=start;i0&&Rule.CLASS.test(simple)){simple=simple.replace(Rule.CLASS,"");classes--;} +while(tags>0&&Rule.TAG.test(simple)){simple=simple.replace(Rule.TAG,"$1*");tags--;} +simple+="."+this.className;classes=Math.min(classes,2);tags=Math.min(tags,2);var score=-10*classes-tags;if(score>0){simple=simple+","+Rule.MAP[score]+" "+simple;} +return simple;},remove:function(element){element.className=element.className.replace(this.MATCH,"$1");},toString:function(){return format("%1 {%2}",this.selectorText,this.cssText);}},{CHILD:/>/g,CLASS:/\.[\w-]+/,CLASSES:/[.:\[]/g,MULTI:/(\.[\w-]+)+/g,PREFIX:"ie7_class",TAG:/^\w+|([\s>+~])\w+/,TAGS:/^\w|[\s>+~]\w/g,MAP:{1:"html",2:"html body",10:".ie7_html",11:"html.ie7_html",12:"html.ie7_html body",20:".ie7_html .ie7_body",21:"html.ie7_html .ie7_body",22:"html.ie7_html body.ie7_body"}});var DynamicRule=Rule.extend({constructor:function(selector,attach,dynamicPseudoClass,target,cssText){this.attach=attach||"*";this.dynamicPseudoClass=IE7.CSS.dynamicPseudoClasses[dynamicPseudoClass];this.target=target;this.base(selector,cssText);},recalc:function(){var attaches=cssQuery(this.attach),attach;for(var i=0;attach=attaches[i];i++){var target=this.target?cssQuery(this.target,attach):[attach];if(target.length)this.dynamicPseudoClass.apply(attach,target,this);}}});var DynamicPseudoClass=Base.extend({constructor:function(name,apply){this.name=name;this.apply=apply;this.instances={};IE7.CSS.dynamicPseudoClasses[name]=this;},register:function(instance){var _class=instance[2];instance.id=_class.id+instance[0].uniqueID;if(!this.instances[instance.id]){var target=instance[1],j;for(j=0;j*:"+(type=="marginTop"?"first":"last")+"-child",element,true);if(child&&child.currentStyle.styleFloat=="none"&&IE7.hasLayout(child)){collapseMargin(child,type);margin=_getMargin(element,element.currentStyle[type]);childMargin=_getMargin(child,child.currentStyle[type]);if(margin<0||childMargin<0){element.runtimeStyle[type]=margin+childMargin;}else{element.runtimeStyle[type]=Math.max(childMargin,margin);} +child.runtimeStyle[type]="0px";}}};function _getMargin(element,value){return value=="auto"?0:getPixelValue(element,value);};var UNIT=/^[.\d][\w%]*$/,AUTO=/^(auto|0cm)$/;var applyWidth,applyHeight;IE7.Layout.borderBox=function(element){applyWidth(element);applyHeight(element);};var fixWidth=function(HEIGHT){applyWidth=function(element){if(!PERCENT.test(element.currentStyle.width))fixWidth(element);collapseMargins(element);};function fixWidth(element,value){if(!element.runtimeStyle.fixedWidth){if(!value)value=element.currentStyle.width;element.runtimeStyle.fixedWidth=(UNIT.test(value))?Math.max(0,getFixedWidth(element,value)):value;setOverrideStyle(element,"width",element.runtimeStyle.fixedWidth);}};function layoutWidth(element){if(!isFixed(element)){var layoutParent=element.offsetParent;while(layoutParent&&!IE7.hasLayout(layoutParent))layoutParent=layoutParent.offsetParent;} +return(layoutParent||viewport).clientWidth;};function getPixelWidth(element,value){if(PERCENT.test(value))return parseInt(parseFloat(value)/100*layoutWidth(element));return getPixelValue(element,value);};var getFixedWidth=function(element,value){var borderBox=element.currentStyle["box-sizing"]=="border-box";var adjustment=0;if(quirksMode&&!borderBox) +adjustment+=getBorderWidth(element)+getWidth(element,"padding");else if(!quirksMode&&borderBox) +adjustment-=getBorderWidth(element)+getWidth(element,"padding");return getPixelWidth(element,value)+adjustment;};function getBorderWidth(element){return element.offsetWidth-element.clientWidth;};function getWidth(element,type){return getPixelWidth(element,element.currentStyle[type+"Left"])+getPixelWidth(element,element.currentStyle[type+"Right"]);};HEADER+="*{minWidth:none;maxWidth:none;min-width:none;max-width:none}";layout.minWidth=function(element){if(element.currentStyle["min-width"]!=null){element.style.minWidth=element.currentStyle["min-width"];} +if(register(arguments.callee,element,element.currentStyle.minWidth!="none")){layout.boxSizing(element);fixWidth(element);resizeWidth(element);}};eval("IE7.Layout.maxWidth="+String(layout.minWidth).replace(/min/g,"max"));function resizeWidth(element){var rect=element.getBoundingClientRect();var width=rect.right-rect.left;if(element.currentStyle.minWidth!="none"&&width<=getFixedWidth(element,element.currentStyle.minWidth)){element.runtimeStyle.width=element.currentStyle.minWidth;}else if(element.currentStyle.maxWidth!="none"&&width>=getFixedWidth(element,element.currentStyle.maxWidth)){element.runtimeStyle.width=element.currentStyle.maxWidth;}else{element.runtimeStyle.width=element.runtimeStyle.fixedWidth;}};function fixRight(element){if(register(fixRight,element,/^(fixed|absolute)$/.test(element.currentStyle.position)&&getDefinedStyle(element,"left")!="auto"&&getDefinedStyle(element,"right")!="auto"&&AUTO.test(getDefinedStyle(element,"width")))){resizeRight(element);IE7.Layout.boxSizing(element);}};IE7.Layout.fixRight=fixRight;function resizeRight(element){var left=getPixelWidth(element,element.runtimeStyle._left||element.currentStyle.left);var width=layoutWidth(element)-getPixelWidth(element,element.currentStyle.right)-left-getWidth(element,"margin");if(parseInt(element.runtimeStyle.width)==width)return;element.runtimeStyle.width="";if(isFixed(element)||HEIGHT||element.offsetWidth=5.5&&appVersion<7){IE7.CSS.addFix(/background(-image)?\s*:\s*([^};]*)?url\(([^\)]+)\)([^;}]*)?/,function(match,$1,$2,url,$4){url=getString(url);return PNG.test(url)?"filter:"+format(PNG_FILTER,url,"crop")+";zoom:1;background"+($1||"")+":"+($2||"")+"none"+($4||""):match;});IE7.HTML.addRecalc("img,input",function(element){if(element.tagName=="INPUT"&&element.type!="image")return;fixImage(element);addEventHandler(element,"onpropertychange",function(){if(!printing&&event.propertyName=="src"&&element.src.indexOf(BLANK_GIF)==-1)fixImage(element);});});var printing=false;addEventHandler(window,"onbeforeprint",function(){printing=true;for(var i=0;i=7)return;IE7.CSS.addRecalc("position","fixed",_positionFixed,"absolute");IE7.CSS.addRecalc("background(-attachment)?","[^};]*fixed",_backgroundFixed);var $viewport=quirksMode?"body":"documentElement";function _fixBackground(){if(body.currentStyle.backgroundAttachment!="fixed"){if(body.currentStyle.backgroundImage=="none"){body.runtimeStyle.backgroundRepeat="no-repeat";body.runtimeStyle.backgroundImage="url("+BLANK_GIF+")";} +body.runtimeStyle.backgroundAttachment="fixed";} +_fixBackground=Undefined;};var _tmp=createTempElement("img");function _isFixed(element){return element?isFixed(element)||_isFixed(element.parentElement):false;};function _setExpression(element,propertyName,expression){setTimeout("document.all."+element.uniqueID+".runtimeStyle.setExpression('"+propertyName+"','"+expression+"')",0);};function _backgroundFixed(element){if(register(_backgroundFixed,element,element.currentStyle.backgroundAttachment=="fixed"&&!element.contains(body))){_fixBackground();bgLeft(element);bgTop(element);_backgroundPosition(element);}};function _backgroundPosition(element){_tmp.src=element.currentStyle.backgroundImage.slice(5,-2);var parentElement=element.canHaveChildren?element:element.parentElement;parentElement.appendChild(_tmp);setOffsetLeft(element);setOffsetTop(element);parentElement.removeChild(_tmp);};function bgLeft(element){element.style.backgroundPositionX=element.currentStyle.backgroundPositionX;if(!_isFixed(element)){_setExpression(element,"backgroundPositionX","(parseInt(runtimeStyle.offsetLeft)+document."+$viewport+".scrollLeft)||0");}};eval(rotate(bgLeft));function setOffsetLeft(element){var propertyName=_isFixed(element)?"backgroundPositionX":"offsetLeft";element.runtimeStyle[propertyName]=getOffsetLeft(element,element.style.backgroundPositionX)- +element.getBoundingClientRect().left-element.clientLeft+2;};eval(rotate(setOffsetLeft));function getOffsetLeft(element,position){switch(position){case"left":case"top":return 0;case"right":case"bottom":return viewport.clientWidth-_tmp.offsetWidth;case"center":return(viewport.clientWidth-_tmp.offsetWidth)/2;default:if(PERCENT.test(position)){return parseInt((viewport.clientWidth-_tmp.offsetWidth)*parseFloat(position)/100);} +_tmp.style.left=position;return _tmp.offsetLeft;}};eval(rotate(getOffsetLeft));function _positionFixed(element){if(register(_positionFixed,element,isFixed(element))){setOverrideStyle(element,"position","absolute");setOverrideStyle(element,"left",element.currentStyle.left);setOverrideStyle(element,"top",element.currentStyle.top);_fixBackground();IE7.Layout.fixRight(element);_foregroundPosition(element);}};function _foregroundPosition(element,recalc){positionTop(element,recalc);positionLeft(element,recalc,true);if(!element.runtimeStyle.autoLeft&&element.currentStyle.marginLeft=="auto"&&element.currentStyle.right!="auto"){var left=viewport.clientWidth-getPixelWidth(element,element.currentStyle.right)- +getPixelWidth(element,element.runtimeStyle._left)-element.clientWidth;if(element.currentStyle.marginRight=="auto")left=parseInt(left/2);if(_isFixed(element.offsetParent))element.runtimeStyle.pixelLeft+=left;else element.runtimeStyle.shiftLeft=left;} +clipWidth(element);clipHeight(element);};function clipWidth(element){var fixWidth=element.runtimeStyle.fixWidth;element.runtimeStyle.borderRightWidth="";element.runtimeStyle.width=fixWidth?getPixelWidth(element,fixWidth):"";if(element.currentStyle.width!="auto"){var rect=element.getBoundingClientRect();var width=element.offsetWidth-viewport.clientWidth+rect.left-2;if(width>=0){element.runtimeStyle.borderRightWidth="0px";width=Math.max(getPixelValue(element,element.currentStyle.width)-width,0);setOverrideStyle(element,"width",width);return width;}}};eval(rotate(clipWidth));function positionLeft(element,recalc){if(!recalc&&PERCENT.test(element.currentStyle.width)){element.runtimeStyle.fixWidth=element.currentStyle.width;} +if(element.runtimeStyle.fixWidth){element.runtimeStyle.width=getPixelWidth(element,element.runtimeStyle.fixWidth);} +element.runtimeStyle.shiftLeft=0;element.runtimeStyle._left=element.currentStyle.left;element.runtimeStyle.autoLeft=element.currentStyle.right!="auto"&&element.currentStyle.left=="auto";element.runtimeStyle.left="";element.runtimeStyle.screenLeft=getScreenLeft(element);element.runtimeStyle.pixelLeft=element.runtimeStyle.screenLeft;if(!recalc&&!_isFixed(element.offsetParent)){_setExpression(element,"pixelLeft","runtimeStyle.screenLeft+runtimeStyle.shiftLeft+document."+$viewport+".scrollLeft");}};eval(rotate(positionLeft));function getScreenLeft(element){var screenLeft=element.offsetLeft,nested=1;if(element.runtimeStyle.autoLeft){screenLeft=viewport.clientWidth-element.offsetWidth-getPixelWidth(element,element.currentStyle.right);} +if(element.currentStyle.marginLeft!="auto"){screenLeft-=getPixelWidth(element,element.currentStyle.marginLeft);} +while(element=element.offsetParent){if(element.currentStyle.position!="static")nested=-1;screenLeft+=element.offsetLeft*nested;} +return screenLeft;};eval(rotate(getScreenLeft));function getPixelWidth(element,value){return PERCENT.test(value)?parseInt(parseFloat(value)/100*viewport.clientWidth):getPixelValue(element,value);};eval(rotate(getPixelWidth));function _resize(){var elements=_backgroundFixed.elements;for(var i in elements)_backgroundPosition(elements[i]);elements=_positionFixed.elements;for(i in elements){_foregroundPosition(elements[i],true);_foregroundPosition(elements[i],true);} +_timer=0;};var _timer;addResize(function(){if(!_timer)_timer=setTimeout(_resize,0);});};var WRAPPER_STYLE={backgroundColor:"transparent",backgroundImage:"none",backgroundPositionX:null,backgroundPositionY:null,backgroundRepeat:null,borderTopWidth:0,borderRightWidth:0,borderBottomWidth:0,borderLeftStyle:"none",borderTopStyle:"none",borderRightStyle:"none",borderBottomStyle:"none",borderLeftWidth:0,height:null,marginTop:0,marginBottom:0,marginRight:0,marginLeft:0,width:"100%"};IE7.CSS.addRecalc("overflow","visible",function(element){if(element.parentNode.ie7_wrapped)return;if(IE7.Layout&&element.currentStyle["max-height"]!="auto"){IE7.Layout.maxHeight(element);} +if(element.currentStyle.marginLeft=="auto")element.style.marginLeft=0;if(element.currentStyle.marginRight=="auto")element.style.marginRight=0;var wrapper=document.createElement(ANON);wrapper.ie7_wrapped=element;for(var propertyName in WRAPPER_STYLE){wrapper.style[propertyName]=element.currentStyle[propertyName];if(WRAPPER_STYLE[propertyName]!=null){element.runtimeStyle[propertyName]=WRAPPER_STYLE[propertyName];}} +wrapper.style.display="block";wrapper.style.position="relative";element.runtimeStyle.position="absolute";element.parentNode.insertBefore(wrapper,element);wrapper.appendChild(element);});function ie7Quirks(){var FONT_SIZES="xx-small,x-small,small,medium,large,x-large,xx-large".split(",");for(var i=0;i":"","\\/\\*[^*]*\\*+([^\\/][^*]*\\*+)*\\/":"","@(namespace|import)[^;\\n]+[;\\n]":"","'(\\\\.|[^'\\\\])*'":encodeString,'"(\\\\.|[^"\\\\])*"':encodeString,"\\s+":" "});function encode(cssText){return encoder.exec(cssText);};function decode(cssText){return cssText.replace(ENCODED,function(match,index){return _strings[index-1];});};function encodeString(string){return"\x01"+_strings.push(string.replace(UNICODE,function(match,chr){return eval("'\\u"+"0000".slice(chr.length)+chr+"'");}).slice(1,-1).replace(QUOTES,"\\'"));};function getString(value){return STRING.test(value)?_strings[value.slice(1)-1]:value;};var rotater=new RegGrp({Width:"Height",width:"height",Left:"Top",left:"top",Right:"Bottom",right:"bottom",onX:"onY"});function rotate(fn){return rotater.exec(fn);};var eventHandlers=[];function addResize(handler){addRecalc(handler);addEventHandler(window,"onresize",handler);};function addEventHandler(element,type,handler){element.attachEvent(type,handler);eventHandlers.push(arguments);};function removeEventHandler(element,type,handler){try{element.detachEvent(type,handler);}catch(ignore){}};addEventHandler(window,"onunload",function(){var handler;while(handler=eventHandlers.pop()){removeEventHandler(handler[0],handler[1],handler[2]);}});function register(handler,element,condition){if(!handler.elements)handler.elements={};if(condition)handler.elements[element.uniqueID]=element;else delete handler.elements[element.uniqueID];return condition;};addEventHandler(window,"onbeforeprint",function(){if(!IE7.CSS.print)new StyleSheet("print");IE7.CSS.print.recalc();});var PIXEL=/^\d+(px)?$/i;var PERCENT=/^\d+%$/;var getPixelValue=function(element,value){if(PIXEL.test(value))return parseInt(value);var style=element.style.left;var runtimeStyle=element.runtimeStyle.left;element.runtimeStyle.left=element.currentStyle.left;element.style.left=value||0;value=element.style.pixelLeft;element.style.left=style;element.runtimeStyle.left=runtimeStyle;return value;};var $IE7="ie7-";var Fix=Base.extend({constructor:function(){this.fixes=[];this.recalcs=[];},init:Undefined});var recalcs=[];function addRecalc(recalc){recalcs.push(recalc);};IE7.recalc=function(){IE7.HTML.recalc();IE7.CSS.recalc();for(var i=0;i1?2:0;var block=cssParser.exec(selectors[i])||"if(0){";if(_wild){block+=format("if(e%1.nodeName!='!'){",_index);} +var store=_duplicate>1?_TEST:"";block+=format(store+_STORE,_index);block+=Array(match(block,/\{/g).length+1).join("}");fn+=block;} +eval(format(_FN,reg)+cssParser.unescape(fn)+"return s?null:r}");_cache[selector]=_selectorFunction;} +return _cache[selector](context||document,single);};var _MSIE5=appVersion<6;var _EVALUATED=/^(href|src)$/;var _ATTRIBUTES={"class":"className","for":"htmlFor"};IE7._indexed=1;IE7._byId=function(document,id){var result=document.all[id]||null;if(!result||result.id==id)return result;for(var i=0;i+~,]|[^(]\+|^)([#.:\[])/g,IMPLIED_SPACE=/(^|,)([^\s>+~])/g,WHITESPACE=/\s*([\s>+~(),]|^|$)\s*/g,WILD_CARD=/\s\*\s/g;;var CSSParser=RegGrp.extend({constructor:function(items){this.base(items);this.sorter=new RegGrp;this.sorter.add(/:not\([^)]*\)/,RegGrp.IGNORE);this.sorter.add(/([ >](\*|[\w-]+))([^: >+~]*)(:\w+-child(\([^)]+\))?)([^: >+~]*)/,"$1$3$6$4");},ignoreCase:true,escape:function(selector){return this.optimise(this.format(selector));},format:function(selector){return selector.replace(WHITESPACE,"$1").replace(IMPLIED_SPACE,"$1 $2").replace(IMPLIED_ASTERISK,"$1*$2");},optimise:function(selector){return this.sorter.exec(selector.replace(WILD_CARD,">* "));},unescape:function(selector){return decode(selector);}});var _OPERATORS={"":"%1!=null","=":"%1=='%2'","~=":/(^| )%1( |$)/,"|=":/^%1(-|$)/,"^=":/^%1/,"$=":/%1$/,"*=":/%1/};var _PSEUDO_CLASSES={"first-child":"!IE7._getPreviousElementSibling(e%1)","link":"e%1.currentStyle['ie7-link']=='link'","visited":"e%1.currentStyle['ie7-link']=='visited'"};var _VAR="var p%2=0,i%2,e%2,n%2=e%1.";var _ID="e%1.sourceIndex";var _TEST="var g="+_ID+";if(!p[g]){p[g]=1;";var _STORE="r[r.length]=e%1;if(s)return e%1;";var _FN="var _selectorFunction=function(e0,s){IE7._indexed++;var r=[],p={},reg=[%1],d=document;";var reg;var _index;var _wild;var _list;var _duplicate;var _cache={};var cssParser=new CSSParser({" (\\*|[\\w-]+)#([\\w-]+)":function(match,tagName,id){_wild=false;var replacement="var e%2=IE7._byId(d,'%4');if(e%2&&";if(tagName!="*")replacement+="e%2.nodeName=='%3'&&";replacement+="(e%1==d||e%1.contains(e%2))){";if(_list)replacement+=format("i%1=n%1.length;",_list);return format(replacement,_index++,_index,tagName.toUpperCase(),id);}," (\\*|[\\w-]+)":function(match,tagName){_duplicate++;_wild=tagName=="*";var replacement=_VAR;replacement+=(_wild&&_MSIE5)?"all":"getElementsByTagName('%3')";replacement+=";for(i%2=0;(e%2=n%2[i%2]);i%2++){";return format(replacement,_index++,_list=_index,tagName.toUpperCase());},">(\\*|[\\w-]+)":function(match,tagName){var children=_list;_wild=tagName=="*";var replacement=_VAR;replacement+=children?"children":"childNodes";if(!_wild&&children)replacement+=".tags('%3')";replacement+=";for(i%2=0;(e%2=n%2[i%2]);i%2++){";if(_wild){replacement+="if(e%2.nodeType==1){";_wild=_MSIE5;}else{if(!children)replacement+="if(e%2.nodeName=='%3'){";} +return format(replacement,_index++,_list=_index,tagName.toUpperCase());},"\\+(\\*|[\\w-]+)":function(match,tagName){var replacement="";if(_wild)replacement+="if(e%1.nodeName!='!'){";_wild=false;replacement+="e%1=IE7._getNextElementSibling(e%1);if(e%1";if(tagName!="*")replacement+="&&e%1.nodeName=='%2'";replacement+="){";return format(replacement,_index,tagName.toUpperCase());},"~(\\*|[\\w-]+)":function(match,tagName){var replacement="";if(_wild)replacement+="if(e%1.nodeName!='!'){";_wild=false;_duplicate=2;replacement+="while(e%1=e%1.nextSibling){if(e%1.ie7_adjacent==IE7._indexed)break;if(";if(tagName=="*"){replacement+="e%1.nodeType==1";if(_MSIE5)replacement+="&&e%1.nodeName!='!'";}else replacement+="e%1.nodeName=='%2'";replacement+="){e%1.ie7_adjacent=IE7._indexed;";return format(replacement,_index,tagName.toUpperCase());},"#([\\w-]+)":function(match,id){_wild=false;var replacement="if(e%1.id=='%2'){";if(_list)replacement+=format("i%1=n%1.length;",_list);return format(replacement,_index,id);},"\\.([\\w-]+)":function(match,className){_wild=false;reg.push(new RegExp("(^|\\s)"+rescape(className)+"(\\s|$)"));return format("if(e%1.className&®[%2].test(e%1.className)){",_index,reg.length-1);},"\\[([\\w-]+)\\s*([^=]?=)?\\s*([^\\]]*)\\]":function(match,attr,operator,value){var alias=_ATTRIBUTES[attr]||attr;if(operator){var getAttribute="e%1.getAttribute('%2',2)";if(!_EVALUATED.test(attr)){getAttribute="e%1.%3||"+getAttribute;} +attr=format("("+getAttribute+")",_index,attr,alias);}else{attr=format("IE7._getAttribute(e%1,'%2')",_index,attr);} +var replacement=_OPERATORS[operator||""]||"0";if(replacement&&replacement.source){reg.push(new RegExp(format(replacement.source,rescape(cssParser.unescape(value)))));replacement="reg[%2].test(%1)";value=reg.length-1;} +return"if("+format(replacement,attr,value)+"){";},":+([\\w-]+)(\\(([^)]+)\\))?":function(match,pseudoClass,$2,args){pseudoClass=_PSEUDO_CLASSES[pseudoClass];return"if("+(pseudoClass?format(pseudoClass,_index,args||""):"0")+"){";}});var HYPERLINK=/a(#[\w-]+)?(\.[\w-]+)?:(hover|active)/i;var BRACE1=/\s*\{\s*/,BRACE2=/\s*\}\s*/,COMMA=/\s*\,\s*/;var FIRST_LINE_LETTER=/(.*)(:first-(line|letter))/;var styleSheets=document.styleSheets;IE7.CSS=new(Fix.extend({parser:new Parser,screen:"",print:"",styles:[],rules:[],pseudoClasses:appVersion<7?"first\\-child":"",dynamicPseudoClasses:{toString:function(){var strings=[];for(var pseudoClass in this)strings.push(pseudoClass);return strings.join("|");}},init:function(){var NONE="^\x01$";var CLASS="\\[class=?[^\\]]*\\]";var pseudoClasses=[];if(this.pseudoClasses)pseudoClasses.push(this.pseudoClasses);var dynamicPseudoClasses=this.dynamicPseudoClasses.toString();if(dynamicPseudoClasses)pseudoClasses.push(dynamicPseudoClasses);pseudoClasses=pseudoClasses.join("|");var unknown=appVersion<7?["[>+~[(]|([:.])\\w+\\1"]:[CLASS];if(pseudoClasses)unknown.push(":("+pseudoClasses+")");this.UNKNOWN=new RegExp(unknown.join("|")||NONE,"i");var complex=appVersion<7?["\\[[^\\]]+\\]|[^\\s(\\[]+\\s*[+~]"]:[CLASS];var complexRule=complex.concat();if(pseudoClasses)complexRule.push(":("+pseudoClasses+")");Rule.COMPLEX=new RegExp(complexRule.join("|")||NONE,"ig");if(this.pseudoClasses)complex.push(":("+this.pseudoClasses+")");DynamicRule.COMPLEX=new RegExp(complex.join("|")||NONE,"i");DynamicRule.MATCH=new RegExp(dynamicPseudoClasses?"(.*):("+dynamicPseudoClasses+")(.*)":NONE,"i");this.createStyleSheet();this.refresh();},addEventHandler:function(){addEventHandler.apply(null,arguments);},addFix:function(expression,replacement){this.parser.add(expression,replacement);},addRecalc:function(propertyName,test,handler,replacement){test=new RegExp("([{;\\s])"+propertyName+"\\s*:\\s*"+test+"[^;}]*");var id=this.recalcs.length;if(replacement)replacement=propertyName+":"+replacement;this.addFix(test,function(match,$1){return(replacement?$1+replacement:match)+";ie7-"+match.slice(1)+";ie7_recalc"+id+":1";});this.recalcs.push(arguments);return id;},apply:function(){this.getInlineStyles();new StyleSheet("screen");this.trash();},createStyleSheet:function(){this.styleSheet=document.createStyleSheet();this.styleSheet.ie7=true;this.styleSheet.owningElement.ie7=true;this.styleSheet.cssText=HEADER;},getInlineStyles:function(){var styleSheets=document.getElementsByTagName("style"),styleSheet;for(var i=styleSheets.length-1;(styleSheet=styleSheets[i]);i--){if(!styleSheet.disabled&&!styleSheet.ie7){this.styles.push(styleSheet.innerHTML);}}},getText:function(styleSheet,path){try{var cssText=styleSheet.cssText;}catch(e){cssText="";} +if(httpRequest)cssText=loadFile(styleSheet.href,path)||cssText;return cssText;},recalc:function(){this.screen.recalc();var RECALCS=/ie7_recalc\d+/g;var start=HEADER.match(/[{,]/g).length;var stop=start+(this.screen.cssText.match(/\{/g)||"").length;var rules=this.styleSheet.rules,rule;var calcs,calc,elements,element,i,j,k,id;for(i=start;i0&&Rule.CLASS.test(simple)){simple=simple.replace(Rule.CLASS,"");classes--;} +while(tags>0&&Rule.TAG.test(simple)){simple=simple.replace(Rule.TAG,"$1*");tags--;} +simple+="."+this.className;classes=Math.min(classes,2);tags=Math.min(tags,2);var score=-10*classes-tags;if(score>0){simple=simple+","+Rule.MAP[score]+" "+simple;} +return simple;},remove:function(element){element.className=element.className.replace(this.MATCH,"$1");},toString:function(){return format("%1 {%2}",this.selectorText,this.cssText);}},{CHILD:/>/g,CLASS:/\.[\w-]+/,CLASSES:/[.:\[]/g,MULTI:/(\.[\w-]+)+/g,PREFIX:"ie7_class",TAG:/^\w+|([\s>+~])\w+/,TAGS:/^\w|[\s>+~]\w/g,MAP:{1:"html",2:"html body",10:".ie7_html",11:"html.ie7_html",12:"html.ie7_html body",20:".ie7_html .ie7_body",21:"html.ie7_html .ie7_body",22:"html.ie7_html body.ie7_body"}});var DynamicRule=Rule.extend({constructor:function(selector,attach,dynamicPseudoClass,target,cssText){this.attach=attach||"*";this.dynamicPseudoClass=IE7.CSS.dynamicPseudoClasses[dynamicPseudoClass];this.target=target;this.base(selector,cssText);},recalc:function(){var attaches=cssQuery(this.attach),attach;for(var i=0;attach=attaches[i];i++){var target=this.target?cssQuery(this.target,attach):[attach];if(target.length)this.dynamicPseudoClass.apply(attach,target,this);}}});var DynamicPseudoClass=Base.extend({constructor:function(name,apply){this.name=name;this.apply=apply;this.instances={};IE7.CSS.dynamicPseudoClasses[name]=this;},register:function(instance){var _class=instance[2];instance.id=_class.id+instance[0].uniqueID;if(!this.instances[instance.id]){var target=instance[1],j;for(j=0;j*:"+(type=="marginTop"?"first":"last")+"-child",element,true);if(child&&child.currentStyle.styleFloat=="none"&&IE7.hasLayout(child)){collapseMargin(child,type);margin=_getMargin(element,element.currentStyle[type]);childMargin=_getMargin(child,child.currentStyle[type]);if(margin<0||childMargin<0){element.runtimeStyle[type]=margin+childMargin;}else{element.runtimeStyle[type]=Math.max(childMargin,margin);} +child.runtimeStyle[type]="0px";}}};function _getMargin(element,value){return value=="auto"?0:getPixelValue(element,value);};var UNIT=/^[.\d][\w%]*$/,AUTO=/^(auto|0cm)$/;var applyWidth,applyHeight;IE7.Layout.borderBox=function(element){applyWidth(element);applyHeight(element);};var fixWidth=function(HEIGHT){applyWidth=function(element){if(!PERCENT.test(element.currentStyle.width))fixWidth(element);collapseMargins(element);};function fixWidth(element,value){if(!element.runtimeStyle.fixedWidth){if(!value)value=element.currentStyle.width;element.runtimeStyle.fixedWidth=(UNIT.test(value))?Math.max(0,getFixedWidth(element,value)):value;setOverrideStyle(element,"width",element.runtimeStyle.fixedWidth);}};function layoutWidth(element){if(!isFixed(element)){var layoutParent=element.offsetParent;while(layoutParent&&!IE7.hasLayout(layoutParent))layoutParent=layoutParent.offsetParent;} +return(layoutParent||viewport).clientWidth;};function getPixelWidth(element,value){if(PERCENT.test(value))return parseInt(parseFloat(value)/100*layoutWidth(element));return getPixelValue(element,value);};var getFixedWidth=function(element,value){var borderBox=element.currentStyle["box-sizing"]=="border-box";var adjustment=0;if(quirksMode&&!borderBox) +adjustment+=getBorderWidth(element)+getWidth(element,"padding");else if(!quirksMode&&borderBox) +adjustment-=getBorderWidth(element)+getWidth(element,"padding");return getPixelWidth(element,value)+adjustment;};function getBorderWidth(element){return element.offsetWidth-element.clientWidth;};function getWidth(element,type){return getPixelWidth(element,element.currentStyle[type+"Left"])+getPixelWidth(element,element.currentStyle[type+"Right"]);};HEADER+="*{minWidth:none;maxWidth:none;min-width:none;max-width:none}";layout.minWidth=function(element){if(element.currentStyle["min-width"]!=null){element.style.minWidth=element.currentStyle["min-width"];} +if(register(arguments.callee,element,element.currentStyle.minWidth!="none")){layout.boxSizing(element);fixWidth(element);resizeWidth(element);}};eval("IE7.Layout.maxWidth="+String(layout.minWidth).replace(/min/g,"max"));function resizeWidth(element){var rect=element.getBoundingClientRect();var width=rect.right-rect.left;if(element.currentStyle.minWidth!="none"&&width<=getFixedWidth(element,element.currentStyle.minWidth)){element.runtimeStyle.width=element.currentStyle.minWidth;}else if(element.currentStyle.maxWidth!="none"&&width>=getFixedWidth(element,element.currentStyle.maxWidth)){element.runtimeStyle.width=element.currentStyle.maxWidth;}else{element.runtimeStyle.width=element.runtimeStyle.fixedWidth;}};function fixRight(element){if(register(fixRight,element,/^(fixed|absolute)$/.test(element.currentStyle.position)&&getDefinedStyle(element,"left")!="auto"&&getDefinedStyle(element,"right")!="auto"&&AUTO.test(getDefinedStyle(element,"width")))){resizeRight(element);IE7.Layout.boxSizing(element);}};IE7.Layout.fixRight=fixRight;function resizeRight(element){var left=getPixelWidth(element,element.runtimeStyle._left||element.currentStyle.left);var width=layoutWidth(element)-getPixelWidth(element,element.currentStyle.right)-left-getWidth(element,"margin");if(parseInt(element.runtimeStyle.width)==width)return;element.runtimeStyle.width="";if(isFixed(element)||HEIGHT||element.offsetWidth=5.5&&appVersion<7){IE7.CSS.addFix(/background(-image)?\s*:\s*([^};]*)?url\(([^\)]+)\)([^;}]*)?/,function(match,$1,$2,url,$4){url=getString(url);return PNG.test(url)?"filter:"+format(PNG_FILTER,url,"crop")+";zoom:1;background"+($1||"")+":"+($2||"")+"none"+($4||""):match;});IE7.HTML.addRecalc("img,input",function(element){if(element.tagName=="INPUT"&&element.type!="image")return;fixImage(element);addEventHandler(element,"onpropertychange",function(){if(!printing&&event.propertyName=="src"&&element.src.indexOf(BLANK_GIF)==-1)fixImage(element);});});var printing=false;addEventHandler(window,"onbeforeprint",function(){printing=true;for(var i=0;i=7)return;IE7.CSS.addRecalc("position","fixed",_positionFixed,"absolute");IE7.CSS.addRecalc("background(-attachment)?","[^};]*fixed",_backgroundFixed);var $viewport=quirksMode?"body":"documentElement";function _fixBackground(){if(body.currentStyle.backgroundAttachment!="fixed"){if(body.currentStyle.backgroundImage=="none"){body.runtimeStyle.backgroundRepeat="no-repeat";body.runtimeStyle.backgroundImage="url("+BLANK_GIF+")";} +body.runtimeStyle.backgroundAttachment="fixed";} +_fixBackground=Undefined;};var _tmp=createTempElement("img");function _isFixed(element){return element?isFixed(element)||_isFixed(element.parentElement):false;};function _setExpression(element,propertyName,expression){setTimeout("document.all."+element.uniqueID+".runtimeStyle.setExpression('"+propertyName+"','"+expression+"')",0);};function _backgroundFixed(element){if(register(_backgroundFixed,element,element.currentStyle.backgroundAttachment=="fixed"&&!element.contains(body))){_fixBackground();bgLeft(element);bgTop(element);_backgroundPosition(element);}};function _backgroundPosition(element){_tmp.src=element.currentStyle.backgroundImage.slice(5,-2);var parentElement=element.canHaveChildren?element:element.parentElement;parentElement.appendChild(_tmp);setOffsetLeft(element);setOffsetTop(element);parentElement.removeChild(_tmp);};function bgLeft(element){element.style.backgroundPositionX=element.currentStyle.backgroundPositionX;if(!_isFixed(element)){_setExpression(element,"backgroundPositionX","(parseInt(runtimeStyle.offsetLeft)+document."+$viewport+".scrollLeft)||0");}};eval(rotate(bgLeft));function setOffsetLeft(element){var propertyName=_isFixed(element)?"backgroundPositionX":"offsetLeft";element.runtimeStyle[propertyName]=getOffsetLeft(element,element.style.backgroundPositionX)- +element.getBoundingClientRect().left-element.clientLeft+2;};eval(rotate(setOffsetLeft));function getOffsetLeft(element,position){switch(position){case"left":case"top":return 0;case"right":case"bottom":return viewport.clientWidth-_tmp.offsetWidth;case"center":return(viewport.clientWidth-_tmp.offsetWidth)/2;default:if(PERCENT.test(position)){return parseInt((viewport.clientWidth-_tmp.offsetWidth)*parseFloat(position)/100);} +_tmp.style.left=position;return _tmp.offsetLeft;}};eval(rotate(getOffsetLeft));function _positionFixed(element){if(register(_positionFixed,element,isFixed(element))){setOverrideStyle(element,"position","absolute");setOverrideStyle(element,"left",element.currentStyle.left);setOverrideStyle(element,"top",element.currentStyle.top);_fixBackground();IE7.Layout.fixRight(element);_foregroundPosition(element);}};function _foregroundPosition(element,recalc){positionTop(element,recalc);positionLeft(element,recalc,true);if(!element.runtimeStyle.autoLeft&&element.currentStyle.marginLeft=="auto"&&element.currentStyle.right!="auto"){var left=viewport.clientWidth-getPixelWidth(element,element.currentStyle.right)- +getPixelWidth(element,element.runtimeStyle._left)-element.clientWidth;if(element.currentStyle.marginRight=="auto")left=parseInt(left/2);if(_isFixed(element.offsetParent))element.runtimeStyle.pixelLeft+=left;else element.runtimeStyle.shiftLeft=left;} +clipWidth(element);clipHeight(element);};function clipWidth(element){var fixWidth=element.runtimeStyle.fixWidth;element.runtimeStyle.borderRightWidth="";element.runtimeStyle.width=fixWidth?getPixelWidth(element,fixWidth):"";if(element.currentStyle.width!="auto"){var rect=element.getBoundingClientRect();var width=element.offsetWidth-viewport.clientWidth+rect.left-2;if(width>=0){element.runtimeStyle.borderRightWidth="0px";width=Math.max(getPixelValue(element,element.currentStyle.width)-width,0);setOverrideStyle(element,"width",width);return width;}}};eval(rotate(clipWidth));function positionLeft(element,recalc){if(!recalc&&PERCENT.test(element.currentStyle.width)){element.runtimeStyle.fixWidth=element.currentStyle.width;} +if(element.runtimeStyle.fixWidth){element.runtimeStyle.width=getPixelWidth(element,element.runtimeStyle.fixWidth);} +element.runtimeStyle.shiftLeft=0;element.runtimeStyle._left=element.currentStyle.left;element.runtimeStyle.autoLeft=element.currentStyle.right!="auto"&&element.currentStyle.left=="auto";element.runtimeStyle.left="";element.runtimeStyle.screenLeft=getScreenLeft(element);element.runtimeStyle.pixelLeft=element.runtimeStyle.screenLeft;if(!recalc&&!_isFixed(element.offsetParent)){_setExpression(element,"pixelLeft","runtimeStyle.screenLeft+runtimeStyle.shiftLeft+document."+$viewport+".scrollLeft");}};eval(rotate(positionLeft));function getScreenLeft(element){var screenLeft=element.offsetLeft,nested=1;if(element.runtimeStyle.autoLeft){screenLeft=viewport.clientWidth-element.offsetWidth-getPixelWidth(element,element.currentStyle.right);} +if(element.currentStyle.marginLeft!="auto"){screenLeft-=getPixelWidth(element,element.currentStyle.marginLeft);} +while(element=element.offsetParent){if(element.currentStyle.position!="static")nested=-1;screenLeft+=element.offsetLeft*nested;} +return screenLeft;};eval(rotate(getScreenLeft));function getPixelWidth(element,value){return PERCENT.test(value)?parseInt(parseFloat(value)/100*viewport.clientWidth):getPixelValue(element,value);};eval(rotate(getPixelWidth));function _resize(){var elements=_backgroundFixed.elements;for(var i in elements)_backgroundPosition(elements[i]);elements=_positionFixed.elements;for(i in elements){_foregroundPosition(elements[i],true);_foregroundPosition(elements[i],true);} +_timer=0;};var _timer;addResize(function(){if(!_timer)_timer=setTimeout(_resize,0);});};var WRAPPER_STYLE={backgroundColor:"transparent",backgroundImage:"none",backgroundPositionX:null,backgroundPositionY:null,backgroundRepeat:null,borderTopWidth:0,borderRightWidth:0,borderBottomWidth:0,borderLeftStyle:"none",borderTopStyle:"none",borderRightStyle:"none",borderBottomStyle:"none",borderLeftWidth:0,height:null,marginTop:0,marginBottom:0,marginRight:0,marginLeft:0,width:"100%"};IE7.CSS.addRecalc("overflow","visible",function(element){if(element.parentNode.ie7_wrapped)return;if(IE7.Layout&&element.currentStyle["max-height"]!="auto"){IE7.Layout.maxHeight(element);} +if(element.currentStyle.marginLeft=="auto")element.style.marginLeft=0;if(element.currentStyle.marginRight=="auto")element.style.marginRight=0;var wrapper=document.createElement(ANON);wrapper.ie7_wrapped=element;for(var propertyName in WRAPPER_STYLE){wrapper.style[propertyName]=element.currentStyle[propertyName];if(WRAPPER_STYLE[propertyName]!=null){element.runtimeStyle[propertyName]=WRAPPER_STYLE[propertyName];}} +wrapper.style.display="block";wrapper.style.position="relative";element.runtimeStyle.position="absolute";element.parentNode.insertBefore(wrapper,element);wrapper.appendChild(element);});function ie7Quirks(){var FONT_SIZES="xx-small,x-small,small,medium,large,x-large,xx-large".split(",");for(var i=0;i=%2",a,b,position,last,"&&","%","==");if(negate)query="!("+query+")";return query;};_PSEUDO_CLASSES={"link":"e%1.currentStyle['ie7-link']=='link'","visited":"e%1.currentStyle['ie7-link']=='visited'","checked":"e%1.checked","contains":"e%1.innerText.indexOf('%2')!=-1","disabled":"e%1.isDisabled","empty":"IE7._isEmpty(e%1)","enabled":"e%1.disabled===false","first-child":"!IE7._getPreviousElementSibling(e%1)","lang":"IE7._isLang(e%1,'%2')","last-child":"!IE7._getNextElementSibling(e%1)","only-child":"!IE7._getPreviousElementSibling(e%1)&&!IE7._getNextElementSibling(e%1)","target":"e%1.id==location.hash.slice(1)","indeterminate":"e%1.indeterminate"};IE7._register=function(element){if(element.rows){element.ie7_length=element.rows.length;element.ie7_lookup="rowIndex";}else if(element.cells){element.ie7_length=element.cells.length;element.ie7_lookup="cellIndex";}else if(element.ie7_indexed!=IE7._indexed){var index=0;var child=element.firstChild;while(child){if(child.nodeType==1&&child.nodeName!="!"){child.ie7_index=++index;} +child=child.nextSibling;} +element.ie7_length=index;element.ie7_lookup="ie7_index";} +element.ie7_indexed=IE7._indexed;return element;};var keys=cssParser[_KEYS];var pseudoClass=keys[keys.length-1];keys.length--;cssParser.merge({":not\\((\\*|[\\w-]+)?([^)]*)\\)":function(match,tagName,filters){var replacement=(tagName&&tagName!="*")?format("if(e%1.nodeName=='%2'){",_index,tagName.toUpperCase()):"";replacement+=cssParser.exec(filters);return"if(!"+replacement.slice(2,-1).replace(/\)\{if\(/g,"&&")+"){";},":nth(-last)?-child\\(([^)]+)\\)":function(match,last,args){_wild=false;last=format("e%1.parentNode.ie7_length",_index);var replacement="if(p%1!==e%1.parentNode)p%1=IE7._register(e%1.parentNode);";replacement+="var i=e%1[p%1.ie7_lookup];if(p%1.ie7_lookup!='ie7_index')i++;if(";return format(replacement,_index)+_nthChild(match,args,"i",last)+"){";}});keys.push(pseudoClass);var BRACKETS="\\([^)]*\\)";if(IE7.CSS.pseudoClasses)IE7.CSS.pseudoClasses+="|";IE7.CSS.pseudoClasses+="before|after|last\\-child|only\\-child|empty|root|"+"not|nth\\-child|nth\\-last\\-child|contains|lang".split("|").join(BRACKETS+"|")+BRACKETS;encoder.add(/::/,":");var Focus=new DynamicPseudoClass("focus",function(element){var instance=arguments;IE7.CSS.addEventHandler(element,"onfocus",function(){Focus.unregister(instance);Focus.register(instance);});IE7.CSS.addEventHandler(element,"onblur",function(){Focus.unregister(instance);});if(element==document.activeElement){Focus.register(instance)}});var Active=new DynamicPseudoClass("active",function(element){var instance=arguments;IE7.CSS.addEventHandler(element,"onmousedown",function(){Active.register(instance);});});addEventHandler(document,"onmouseup",function(){var instances=Active.instances;for(var i in instances)Active.unregister(instances[i]);});var Checked=new DynamicPseudoClass("checked",function(element){if(typeof element.checked!="boolean")return;var instance=arguments;IE7.CSS.addEventHandler(element,"onpropertychange",function(){if(event.propertyName=="checked"){if(element.checked)Checked.register(instance);else Checked.unregister(instance);}});if(element.checked)Checked.register(instance);});var Enabled=new DynamicPseudoClass("enabled",function(element){if(typeof element.disabled!="boolean")return;var instance=arguments;IE7.CSS.addEventHandler(element,"onpropertychange",function(){if(event.propertyName=="disabled"){if(!element.isDisabled)Enabled.register(instance);else Enabled.unregister(instance);}});if(!element.isDisabled)Enabled.register(instance);});var Disabled=new DynamicPseudoClass("disabled",function(element){if(typeof element.disabled!="boolean")return;var instance=arguments;IE7.CSS.addEventHandler(element,"onpropertychange",function(){if(event.propertyName=="disabled"){if(element.isDisabled)Disabled.register(instance);else Disabled.unregister(instance);}});if(element.isDisabled)Disabled.register(instance);});var Indeterminate=new DynamicPseudoClass("indeterminate",function(element){if(typeof element.indeterminate!="boolean")return;var instance=arguments;IE7.CSS.addEventHandler(element,"onpropertychange",function(){if(event.propertyName=="indeterminate"){if(element.indeterminate)Indeterminate.register(instance);else Indeterminate.unregister(instance);}});IE7.CSS.addEventHandler(element,"onclick",function(){Indeterminate.unregister(instance);});});var Target=new DynamicPseudoClass("target",function(element){var instance=arguments;if(!element.tabIndex)element.tabIndex=0;IE7.CSS.addEventHandler(document,"onpropertychange",function(){if(event.propertyName=="activeElement"){if(element.id&&element.id==location.hash.slice(1))Target.register(instance);else Target.unregister(instance);}});if(element.id&&element.id==location.hash.slice(1))Target.register(instance);});var ATTR=/^attr/;var URL=/^url\s*\(\s*([^)]*)\)$/;var POSITION_MAP={before0:"beforeBegin",before1:"afterBegin",after0:"afterEnd",after1:"beforeEnd"};var PseudoElement=IE7.PseudoElement=Rule.extend({constructor:function(selector,position,cssText){this.position=position;var content=cssText.match(PseudoElement.CONTENT),match,entity;if(content){content=content[1];match=content.split(/\s+/);for(var i=0;(entity=match[i]);i++){match[i]=ATTR.test(entity)?{attr:entity.slice(5,-1)}:(entity.charAt(0)=="'")?getString(entity):decode(entity);} +content=match;} +this.content=content;this.base(selector,decode(cssText));},init:function(){this.match=cssQuery(this.selector);for(var i=0;i%4",MATCH:/(.*):(before|after).*/,count:0});var UNSUCCESSFUL=/^(submit|reset|button)$/;IE7.HTML.addRecalc("button,input",function(button){if(button.tagName=="BUTTON"){var match=button.outerHTML.match(/ value="([^"]*)"/i);button.runtimeStyle.value=(match)?match[1]:"";} +if(button.type=="submit"){addEventHandler(button,"onclick",function(){button.runtimeStyle.clicked=true;setTimeout("document.all."+button.uniqueID+".runtimeStyle.clicked=false",1);});}});IE7.HTML.addRecalc("form",function(form){addEventHandler(form,"onsubmit",function(){for(var element,i=0;element=form[i];i++){if(UNSUCCESSFUL.test(element.type)&&!element.disabled&&!element.runtimeStyle.clicked){element.disabled=true;setTimeout("document.all."+element.uniqueID+".disabled=false",1);}else if(element.tagName=="BUTTON"&&element.type=="submit"){setTimeout("document.all."+element.uniqueID+".value='"+ +element.value+"'",1);element.value=element.runtimeStyle.value;}}});});IE7.HTML.addRecalc("img",function(img){if(img.alt&&!img.title)img.title="";});IE7.CSS.addRecalc("border-spacing",NUMERIC,function(element){if(element.currentStyle.borderCollapse!="collapse"){element.cellSpacing=getPixelValue(element,element.currentStyle["border-spacing"]);}});IE7.CSS.addRecalc("box-sizing","content-box",IE7.Layout.boxSizing);IE7.CSS.addRecalc("box-sizing","border-box",IE7.Layout.borderBox);IE7.CSS.addFix(/opacity\s*:\s*([\d.]+)/,function(match,value){return"zoom:1;filter:Alpha(opacity="+((value*100)||1)+")";});var IMAGE=/^image/i;IE7.HTML.addRecalc("object",function(element){if(IMAGE.test(element.type)){element.body.style.cssText="margin:0;padding:0;border:none;overflow:hidden";return element;}});IE7.loaded=true;(function(){try{documentElement.doScroll("left");}catch(e){setTimeout(arguments.callee,1);return;} +try{eval(script.innerHTML);}catch(e){} +PNG=new RegExp(rescape(typeof IE7_PNG_SUFFIX=="string"?IE7_PNG_SUFFIX:"-trans.png")+"$","i");body=document.body;viewport=quirksMode?body:documentElement;body.className+=" ie7_body";documentElement.className+=" ie7_html";if(quirksMode)ie7Quirks();IE7.CSS.init();IE7.HTML.init();IE7.HTML.apply();IE7.CSS.apply();IE7.recalc();})();})(); \ No newline at end of file diff --git a/v2/dotclear/admin/js/ie7/blank.gif b/v2/dotclear/admin/js/ie7/blank.gif new file mode 100644 index 0000000000000000000000000000000000000000..a4fe2e6297c7a013637b0e15f842dca1ef3128c4 GIT binary patch literal 48 wcmZ?wbhEHbWMp7un83&Y1poj4SNzEWWHK`7fcPL81|}vSMh3-y@(c{t0P2MZQ2+n{ literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/js/ie7/ie7-recalc.js b/v2/dotclear/admin/js/ie7/ie7-recalc.js new file mode 100644 index 0000000..3acd0cb --- /dev/null +++ b/v2/dotclear/admin/js/ie7/ie7-recalc.js @@ -0,0 +1,5 @@ + +(function(){if(!IE7.loaded)return;CLASSES=/\sie7_class\d+/g;IE7.CSS.extend({elements:{},handlers:[],reset:function(){this.removeEventHandlers();var elements=this.elements;for(var i in elements)elements[i].runtimeStyle.cssText="";this.elements={};var elements=IE7.Rule.elements;for(var i in elements){with(elements[i])className=className.replace(CLASSES,"");} +IE7.Rule.elements={};},reload:function(){this.rules=[];this.getInlineStyles();this.screen.load();if(this.print)this.print.load();this.refresh();this.trash();},addRecalc:function(propertyName,test,handler,replacement){this.base(propertyName,test,function(element){handler(element);IE7.CSS.elements[element.uniqueID]=element;},replacement);},recalc:function(){this.reset();this.base();},addEventHandler:function(element,type,handler){element.attachEvent(type,handler);this.handlers.push(arguments);},removeEventHandlers:function(){var handler;while(handler=this.handlers.pop()){handler[0].detachEvent(handler[1],handler[2]);}},getInlineStyles:function(){var styleSheets=document.getElementsByTagName("style"),styleSheet;for(var i=styleSheets.length-1;(styleSheet=styleSheets[i]);i--){if(!styleSheet.disabled&&!styleSheet.ie7){var cssText=styleSheet.cssText||styleSheet.innerHTML;this.styles.push(cssText);styleSheet.cssText=cssText;}}},trash:function(){var styleSheets=document.styleSheets,styleSheet,i;for(i=0;i=6)IE7.CSS.addRecalc("float","(left|right)",function(element){IE7.Layout.boxSizing(element.parentElement);element.style.display="inline";});IE7.CSS.addRecalc("position","absolute|fixed",function(element){if(element.offsetParent&&element.offsetParent.currentStyle.position=="relative") +IE7.Layout.boxSizing(element.offsetParent);});} \ No newline at end of file diff --git a/v2/dotclear/admin/js/jquery/jquery-ui-1.8.12.custom.min.js b/v2/dotclear/admin/js/jquery/jquery-ui-1.8.12.custom.min.js new file mode 100644 index 0000000..b99518d --- /dev/null +++ b/v2/dotclear/admin/js/jquery/jquery-ui-1.8.12.custom.min.js @@ -0,0 +1,8 @@ + +(function(c,j){function k(a){return!c(a).parents().andSelf().filter(function(){return c.curCSS(this,"visibility")==="hidden"||c.expr.filters.hidden(this)}).length}c.ui=c.ui||{};if(!c.ui.version){c.extend(c.ui,{version:"1.8.12",keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});c.fn.extend({_focus:c.fn.focus,focus:function(a,b){return typeof a==="number"?this.each(function(){var d=this;setTimeout(function(){c(d).focus();b&&b.call(d)},a)}):this._focus.apply(this,arguments)},scrollParent:function(){var a;a=c.browser.msie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(c.curCSS(this,"position",1))&&/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0);return/fixed/.test(this.css("position"))||!a.length?c(document):a},zIndex:function(a){if(a!==j)return this.css("zIndex",a);if(this.length){a=c(this[0]);for(var b;a.length&&a[0]!==document;){b=a.css("position");if(b==="absolute"||b==="relative"||b==="fixed"){b=parseInt(a.css("zIndex"),10);if(!isNaN(b)&&b!==0)return b}a=a.parent()}}return 0},disableSelection:function(){return this.bind((c.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(a){a.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}});c.each(["Width","Height"],function(a,b){function d(f,g,l,m){c.each(e,function(){g-=parseFloat(c.curCSS(f,"padding"+this,true))||0;if(l)g-=parseFloat(c.curCSS(f,"border"+this+"Width",true))||0;if(m)g-=parseFloat(c.curCSS(f,"margin"+this,true))||0});return g}var e=b==="Width"?["Left","Right"]:["Top","Bottom"],h=b.toLowerCase(),i={innerWidth:c.fn.innerWidth,innerHeight:c.fn.innerHeight,outerWidth:c.fn.outerWidth,outerHeight:c.fn.outerHeight};c.fn["inner"+b]=function(f){if(f===j)return i["inner"+b].call(this);return this.each(function(){c(this).css(h,d(this,f)+"px")})};c.fn["outer"+b]=function(f,g){if(typeof f!=="number")return i["outer"+b].call(this,f);return this.each(function(){c(this).css(h,d(this,f,true,g)+"px")})}});c.extend(c.expr[":"],{data:function(a,b,d){return!!c.data(a,d[3])},focusable:function(a){var b=a.nodeName.toLowerCase(),d=c.attr(a,"tabindex");if("area"===b){b=a.parentNode;d=b.name;if(!a.href||!d||b.nodeName.toLowerCase()!=="map")return false;a=c("img[usemap=#"+d+"]")[0];return!!a&&k(a)}return(/input|select|textarea|button|object/.test(b)?!a.disabled:"a"==b?a.href||!isNaN(d):!isNaN(d))&&k(a)},tabbable:function(a){var b=c.attr(a,"tabindex");return(isNaN(b)||b>=0)&&c(a).is(":focusable")}});c(function(){var a=document.body,b=a.appendChild(b=document.createElement("div"));c.extend(b.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0});c.support.minHeight=b.offsetHeight===100;c.support.selectstart="onselectstart"in b;a.removeChild(b).style.display="none"});c.extend(c.ui,{plugin:{add:function(a,b,d){a=c.ui[a].prototype;for(var e in d){a.plugins[e]=a.plugins[e]||[];a.plugins[e].push([b,d[e]])}},call:function(a,b,d){if((b=a.plugins[b])&&a.element[0].parentNode)for(var e=0;e0)return true;a[b]=1;d=a[b]>0;a[b]=0;return d},isOverAxis:function(a,b,d){return a>b&&a=9)&&!a.button)return this._mouseUp(a);if(this._mouseStarted){this._mouseDrag(a);return a.preventDefault()}if(this._mouseDistanceMet(a)&&this._mouseDelayMet(a))(this._mouseStarted=this._mouseStart(this._mouseDownEvent,a)!==false)?this._mouseDrag(a):this._mouseUp(a);return!this._mouseStarted},_mouseUp:function(a){b(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;a.target==this._mouseDownEvent.target&&b.data(a.target,this.widgetName+".preventClickEvent",true);this._mouseStop(a)}return false},_mouseDistanceMet:function(a){return Math.max(Math.abs(this._mouseDownEvent.pageX-a.pageX),Math.abs(this._mouseDownEvent.pageY-a.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return true}})})(jQuery);;(function(d){d.widget("ui.sortable",d.ui.mouse,{widgetEventPrefix:"sort",options:{appendTo:"parent",axis:false,connectWith:false,containment:false,cursor:"auto",cursorAt:false,dropOnEmpty:true,forcePlaceholderSize:false,forceHelperSize:false,grid:false,handle:false,helper:"original",items:"> *",opacity:false,placeholder:false,revert:false,scroll:true,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1E3},_create:function(){this.containerCache={};this.element.addClass("ui-sortable");this.refresh();this.floating=this.items.length?/left|right/.test(this.items[0].item.css("float"))||/inline|table-cell/.test(this.items[0].item.css("display")):false;this.offset=this.element.offset();this._mouseInit()},destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled").removeData("sortable").unbind(".sortable");this._mouseDestroy();for(var a=this.items.length-1;a>=0;a--)this.items[a].item.removeData("sortable-item");return this},_setOption:function(a,b){if(a==="disabled"){this.options[a]=b;this.widget()[b?"addClass":"removeClass"]("ui-sortable-disabled")}else d.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(a,b){if(this.reverting)return false;if(this.options.disabled||this.options.type=="static")return false;this._refreshItems(a);var c=null,e=this;d(a.target).parents().each(function(){if(d.data(this,"sortable-item")==e){c=d(this);return false}});if(d.data(a.target,"sortable-item")==e)c=d(a.target);if(!c)return false;if(this.options.handle&&!b){var f=false;d(this.options.handle,c).find("*").andSelf().each(function(){if(this==a.target)f=true});if(!f)return false}this.currentItem=c;this._removeCurrentsFromItems();return true},_mouseStart:function(a,b,c){b=this.options;var e=this;this.currentContainer=this;this.refreshPositions();this.helper=this._createHelper(a);this._cacheHelperProportions();this._cacheMargins();this.scrollParent=this.helper.scrollParent();this.offset=this.currentItem.offset();this.offset={top:this.offset.top-this.margins.top,left:this.offset.left- +this.margins.left};this.helper.css("position","absolute");this.cssPosition=this.helper.css("position");d.extend(this.offset,{click:{left:a.pageX-this.offset.left,top:a.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this._generatePosition(a);this.originalPageX=a.pageX;this.originalPageY=a.pageY;b.cursorAt&&this._adjustOffsetFromHelper(b.cursorAt);this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]};this.helper[0]!=this.currentItem[0]&&this.currentItem.hide();this._createPlaceholder();b.containment&&this._setContainment();if(b.cursor){if(d("body").css("cursor"))this._storedCursor=d("body").css("cursor");d("body").css("cursor",b.cursor)}if(b.opacity){if(this.helper.css("opacity"))this._storedOpacity=this.helper.css("opacity");this.helper.css("opacity",b.opacity)}if(b.zIndex){if(this.helper.css("zIndex"))this._storedZIndex=this.helper.css("zIndex");this.helper.css("zIndex",b.zIndex)}if(this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML")this.overflowOffset=this.scrollParent.offset();this._trigger("start",a,this._uiHash());this._preserveHelperProportions||this._cacheHelperProportions();if(!c)for(c=this.containers.length-1;c>=0;c--)this.containers[c]._trigger("activate",a,e._uiHash(this));if(d.ui.ddmanager)d.ui.ddmanager.current=this;d.ui.ddmanager&&!b.dropBehaviour&&d.ui.ddmanager.prepareOffsets(this,a);this.dragging=true;this.helper.addClass("ui-sortable-helper");this._mouseDrag(a);return true},_mouseDrag:function(a){this.position=this._generatePosition(a);this.positionAbs=this._convertPositionTo("absolute");if(!this.lastPositionAbs)this.lastPositionAbs=this.positionAbs;if(this.options.scroll){var b=this.options,c=false;if(this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"){if(this.overflowOffset.top+this.scrollParent[0].offsetHeight-a.pageY=0;b--){c=this.items[b];var e=c.item[0],f=this._intersectsWithPointer(c);if(f)if(e!=this.currentItem[0]&&this.placeholder[f==1?"next":"prev"]()[0]!=e&&!d.ui.contains(this.placeholder[0],e)&&(this.options.type=="semi-dynamic"?!d.ui.contains(this.element[0],e):true)){this.direction=f==1?"down":"up";if(this.options.tolerance=="pointer"||this._intersectsWithSides(c))this._rearrange(a,c);else break;this._trigger("change",a,this._uiHash());break}}this._contactContainers(a);d.ui.ddmanager&&d.ui.ddmanager.drag(this,a);this._trigger("sort",a,this._uiHash());this.lastPositionAbs=this.positionAbs;return false},_mouseStop:function(a,b){if(a){d.ui.ddmanager&&!this.options.dropBehaviour&&d.ui.ddmanager.drop(this,a);if(this.options.revert){var c=this;b=c.placeholder.offset();c.reverting=true;d(this.helper).animate({left:b.left-this.offset.parent.left-c.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:b.top-this.offset.parent.top-c.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){c._clear(a)})}else this._clear(a,b);return false}},cancel:function(){var a=this;if(this.dragging){this._mouseUp({target:null});this.options.helper=="original"?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var b=this.containers.length-1;b>=0;b--){this.containers[b]._trigger("deactivate",null,a._uiHash(this));if(this.containers[b].containerCache.over){this.containers[b]._trigger("out",null,a._uiHash(this));this.containers[b].containerCache.over=0}}}if(this.placeholder){this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]);this.options.helper!="original"&&this.helper&&this.helper[0].parentNode&&this.helper.remove();d.extend(this,{helper:null,dragging:false,reverting:false,_noFinalSort:null});this.domPosition.prev?d(this.domPosition.prev).after(this.currentItem):d(this.domPosition.parent).prepend(this.currentItem)}return this},serialize:function(a){var b=this._getItemsAsjQuery(a&&a.connected),c=[];a=a||{};d(b).each(function(){var e=(d(a.item||this).attr(a.attribute||"id")||"").match(a.expression||/(.+)[-=_](.+)/);if(e)c.push((a.key||e[1]+"[]")+"="+(a.key&&a.expression?e[1]:e[2]))});!c.length&&a.key&&c.push(a.key+"=");return c.join("&")},toArray:function(a){var b=this._getItemsAsjQuery(a&&a.connected),c=[];a=a||{};b.each(function(){c.push(d(a.item||this).attr(a.attribute||"id")||"")});return c},_intersectsWith:function(a){var b=this.positionAbs.left,c=b+this.helperProportions.width,e=this.positionAbs.top,f=e+this.helperProportions.height,g=a.left,h=g+a.width,i=a.top,k=i+a.height,j=this.offset.click.top,l=this.offset.click.left;j=e+j>i&&e+jg&&b+la[this.floating?"width":"height"]?j:g0?"down":"up")},_getDragHorizontalDirection:function(){var a=this.positionAbs.left-this.lastPositionAbs.left;return a!=0&&(a>0?"right":"left")},refresh:function(a){this._refreshItems(a);this.refreshPositions();return this},_connectWith:function(){var a=this.options;return a.connectWith.constructor==String?[a.connectWith]:a.connectWith},_getItemsAsjQuery:function(a){var b=[],c=[],e=this._connectWith();if(e&&a)for(a=e.length-1;a>=0;a--)for(var f=d(e[a]),g=f.length-1;g>=0;g--){var h=d.data(f[g],"sortable");if(h&&h!=this&&!h.options.disabled)c.push([d.isFunction(h.options.items)?h.options.items.call(h.element):d(h.options.items,h.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),h])}c.push([d.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):d(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]);for(a=c.length-1;a>=0;a--)c[a][0].each(function(){b.push(this)});return d(b)},_removeCurrentsFromItems:function(){for(var a=this.currentItem.find(":data(sortable-item)"),b=0;b=0;f--)for(var g=d(e[f]),h=g.length-1;h>=0;h--){var i=d.data(g[h],"sortable");if(i&&i!=this&&!i.options.disabled){c.push([d.isFunction(i.options.items)?i.options.items.call(i.element[0],a,{item:this.currentItem}):d(i.options.items,i.element),i]);this.containers.push(i)}}for(f=c.length-1;f>=0;f--){a=c[f][1];e=c[f][0];h=0;for(g=e.length;h=0;b--){var c=this.items[b];if(!(c.instance!=this.currentContainer&&this.currentContainer&&c.item[0]!=this.currentItem[0])){var e=this.options.toleranceElement?d(this.options.toleranceElement,c.item):c.item;if(!a){c.width=e.outerWidth();c.height=e.outerHeight()}e=e.offset();c.left=e.left;c.top=e.top}}if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(b=this.containers.length-1;b>=0;b--){e=this.containers[b].element.offset();this.containers[b].containerCache.left=e.left;this.containers[b].containerCache.top=e.top;this.containers[b].containerCache.width=this.containers[b].element.outerWidth();this.containers[b].containerCache.height=this.containers[b].element.outerHeight()}return this},_createPlaceholder:function(a){var b=a||this,c=b.options;if(!c.placeholder||c.placeholder.constructor==String){var e=c.placeholder;c.placeholder={element:function(){var f=d(document.createElement(b.currentItem[0].nodeName)).addClass(e||b.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];if(!e)f.style.visibility="hidden";return f},update:function(f,g){if(!(e&&!c.forcePlaceholderSize)){g.height()||g.height(b.currentItem.innerHeight()-parseInt(b.currentItem.css("paddingTop")||0,10)-parseInt(b.currentItem.css("paddingBottom")||0,10));g.width()||g.width(b.currentItem.innerWidth()-parseInt(b.currentItem.css("paddingLeft")||0,10)-parseInt(b.currentItem.css("paddingRight")||0,10))}}}}b.placeholder=d(c.placeholder.element.call(b.element,b.currentItem));b.currentItem.after(b.placeholder);c.placeholder.update(b,b.placeholder)},_contactContainers:function(a){for(var b=null,c=null,e=this.containers.length-1;e>=0;e--)if(!d.ui.contains(this.currentItem[0],this.containers[e].element[0]))if(this._intersectsWith(this.containers[e].containerCache)){if(!(b&&d.ui.contains(this.containers[e].element[0],b.element[0]))){b=this.containers[e];c=e}}else if(this.containers[e].containerCache.over){this.containers[e]._trigger("out",a,this._uiHash(this));this.containers[e].containerCache.over=0}if(b)if(this.containers.length===1){this.containers[c]._trigger("over",a,this._uiHash(this));this.containers[c].containerCache.over=1}else if(this.currentContainer!=this.containers[c]){b=1E4;e=null;for(var f=this.positionAbs[this.containers[c].floating?"left":"top"],g=this.items.length-1;g>=0;g--)if(d.ui.contains(this.containers[c].element[0],this.items[g].item[0])){var h=this.items[g][this.containers[c].floating?"left":"top"];if(Math.abs(h- +f)this.containment[2])f=this.containment[2]+this.offset.click.left;if(a.pageY-this.offset.click.top>this.containment[3])g=this.containment[3]+this.offset.click.top}if(b.grid){g=this.originalPageY+Math.round((g- +this.originalPageY)/b.grid[1])*b.grid[1];g=this.containment?!(g-this.offset.click.topthis.containment[3])?g:!(g-this.offset.click.topthis.containment[2])?f:!(f-this.offset.click.left=0;e--)if(d.ui.contains(this.containers[e].element[0],this.currentItem[0])&&!b){c.push(function(f){return function(g){f._trigger("receive",g,this._uiHash(this))}}.call(this,this.containers[e]));c.push(function(f){return function(g){f._trigger("update",g,this._uiHash(this))}}.call(this,this.containers[e]))}}for(e=this.containers.length-1;e>=0;e--){b||c.push(function(f){return function(g){f._trigger("deactivate",g,this._uiHash(this))}}.call(this,this.containers[e]));if(this.containers[e].containerCache.over){c.push(function(f){return function(g){f._trigger("out",g,this._uiHash(this))}}.call(this,this.containers[e]));this.containers[e].containerCache.over=0}}this._storedCursor&&d("body").css("cursor",this._storedCursor);this._storedOpacity&&this.helper.css("opacity",this._storedOpacity);if(this._storedZIndex)this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex);this.dragging=false;if(this.cancelHelperRemoval){if(!b){this._trigger("beforeStop",a,this._uiHash());for(e=0;e li > :first-child,> :not(li):even",icons:{header:"ui-icon-triangle-1-e",headerSelected:"ui-icon-triangle-1-s"},navigation:false,navigationFilter:function(){return this.href.toLowerCase()===location.href.toLowerCase()}},_create:function(){var a=this,b=a.options;a.running=0;a.element.addClass("ui-accordion ui-widget ui-helper-reset").children("li").addClass("ui-accordion-li-fix");a.headers=a.element.find(b.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all").bind("mouseenter.accordion",function(){b.disabled||c(this).addClass("ui-state-hover")}).bind("mouseleave.accordion",function(){b.disabled||c(this).removeClass("ui-state-hover")}).bind("focus.accordion",function(){b.disabled||c(this).addClass("ui-state-focus")}).bind("blur.accordion",function(){b.disabled||c(this).removeClass("ui-state-focus")});a.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom");if(b.navigation){var d=a.element.find("a").filter(b.navigationFilter).eq(0);if(d.length){var h=d.closest(".ui-accordion-header");a.active=h.length?h:d.closest(".ui-accordion-content").prev()}}a.active=a._findActive(a.active||b.active).addClass("ui-state-default ui-state-active").toggleClass("ui-corner-all").toggleClass("ui-corner-top");a.active.next().addClass("ui-accordion-content-active");a._createIcons();a.resize();a.element.attr("role","tablist");a.headers.attr("role","tab").bind("keydown.accordion",function(f){return a._keydown(f)}).next().attr("role","tabpanel");a.headers.not(a.active||"").attr({"aria-expanded":"false","aria-selected":"false",tabIndex:-1}).next().hide();a.active.length?a.active.attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}):a.headers.eq(0).attr("tabIndex",0);c.browser.safari||a.headers.find("a").attr("tabIndex",-1);b.event&&a.headers.bind(b.event.split(" ").join(".accordion ")+".accordion",function(f){a._clickHandler.call(a,f,this);f.preventDefault()})},_createIcons:function(){var a=this.options;if(a.icons){c("").addClass("ui-icon "+a.icons.header).prependTo(this.headers);this.active.children(".ui-icon").toggleClass(a.icons.header).toggleClass(a.icons.headerSelected);this.element.addClass("ui-accordion-icons")}},_destroyIcons:function(){this.headers.children(".ui-icon").remove();this.element.removeClass("ui-accordion-icons")},destroy:function(){var a=this.options;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role");this.headers.unbind(".accordion").removeClass("ui-accordion-header ui-accordion-disabled ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-selected").removeAttr("tabIndex");this.headers.find("a").removeAttr("tabIndex");this._destroyIcons();var b=this.headers.next().css("display","").removeAttr("role").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled");if(a.autoHeight||a.fillHeight)b.css("height","");return c.Widget.prototype.destroy.call(this)},_setOption:function(a,b){c.Widget.prototype._setOption.apply(this,arguments);a=="active"&&this.activate(b);if(a=="icons"){this._destroyIcons();b&&this._createIcons()}if(a=="disabled")this.headers.add(this.headers.next())[b?"addClass":"removeClass"]("ui-accordion-disabled ui-state-disabled")},_keydown:function(a){if(!(this.options.disabled||a.altKey||a.ctrlKey)){var b=c.ui.keyCode,d=this.headers.length,h=this.headers.index(a.target),f=false;switch(a.keyCode){case b.RIGHT:case b.DOWN:f=this.headers[(h+1)%d];break;case b.LEFT:case b.UP:f=this.headers[(h-1+d)%d];break;case b.SPACE:case b.ENTER:this._clickHandler({target:a.target},a.target);a.preventDefault()}if(f){c(a.target).attr("tabIndex",-1);c(f).attr("tabIndex",0);f.focus();return false}return true}},resize:function(){var a=this.options,b;if(a.fillSpace){if(c.browser.msie){var d=this.element.parent().css("overflow");this.element.parent().css("overflow","hidden")}b=this.element.parent().height();c.browser.msie&&this.element.parent().css("overflow",d);this.headers.each(function(){b-=c(this).outerHeight(true)});this.headers.next().each(function(){c(this).height(Math.max(0,b-c(this).innerHeight()+ +c(this).height()))}).css("overflow","auto")}else if(a.autoHeight){b=0;this.headers.next().each(function(){b=Math.max(b,c(this).height("").height())}).height(b)}return this},activate:function(a){this.options.active=a;a=this._findActive(a)[0];this._clickHandler({target:a},a);return this},_findActive:function(a){return a?typeof a==="number"?this.headers.filter(":eq("+a+")"):this.headers.not(this.headers.not(a)):a===false?c([]):this.headers.filter(":eq(0)")},_clickHandler:function(a,b){var d=this.options;if(!d.disabled)if(a.target){a=c(a.currentTarget||b);b=a[0]===this.active[0];d.active=d.collapsible&&b?false:this.headers.index(a);if(!(this.running||!d.collapsible&&b)){var h=this.active;j=a.next();g=this.active.next();e={options:d,newHeader:b&&d.collapsible?c([]):a,oldHeader:this.active,newContent:b&&d.collapsible?c([]):j,oldContent:g};var f=this.headers.index(this.active[0])>this.headers.index(a[0]);this.active=b?c([]):a;this._toggle(j,g,e,b,f);h.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header);if(!b){a.removeClass("ui-state-default ui-corner-all").addClass("ui-state-active ui-corner-top").children(".ui-icon").removeClass(d.icons.header).addClass(d.icons.headerSelected);a.next().addClass("ui-accordion-content-active")}}}else if(d.collapsible){this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header);this.active.next().addClass("ui-accordion-content-active");var g=this.active.next(),e={options:d,newHeader:c([]),oldHeader:d.active,newContent:c([]),oldContent:g},j=this.active=c([]);this._toggle(j,g,e)}},_toggle:function(a,b,d,h,f){var g=this,e=g.options;g.toShow=a;g.toHide=b;g.data=d;var j=function(){if(g)return g._completed.apply(g,arguments)};g._trigger("changestart",null,g.data);g.running=b.size()===0?a.size():b.size();if(e.animated){d={};d=e.collapsible&&h?{toShow:c([]),toHide:b,complete:j,down:f,autoHeight:e.autoHeight||e.fillSpace}:{toShow:a,toHide:b,complete:j,down:f,autoHeight:e.autoHeight||e.fillSpace};if(!e.proxied)e.proxied=e.animated;if(!e.proxiedDuration)e.proxiedDuration=e.duration;e.animated=c.isFunction(e.proxied)?e.proxied(d):e.proxied;e.duration=c.isFunction(e.proxiedDuration)?e.proxiedDuration(d):e.proxiedDuration;h=c.ui.accordion.animations;var i=e.duration,k=e.animated;if(k&&!h[k]&&!c.easing[k])k="slide";h[k]||(h[k]=function(l){this.slide(l,{easing:k,duration:i||700})});h[k](d)}else{if(e.collapsible&&h)a.toggle();else{b.hide();a.show()}j(true)}b.prev().attr({"aria-expanded":"false","aria-selected":"false",tabIndex:-1}).blur();a.prev().attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}).focus()},_completed:function(a){this.running=a?0:--this.running;if(!this.running){this.options.clearStyle&&this.toShow.add(this.toHide).css({height:"",overflow:""});this.toHide.removeClass("ui-accordion-content-active");if(this.toHide.length)this.toHide.parent()[0].className=this.toHide.parent()[0].className;this._trigger("change",null,this.data)}}});c.extend(c.ui.accordion,{version:"1.8.12",animations:{slide:function(a,b){a=c.extend({easing:"swing",duration:300},a,b);if(a.toHide.size())if(a.toShow.size()){var d=a.toShow.css("overflow"),h=0,f={},g={},e;b=a.toShow;e=b[0].style.width;b.width(parseInt(b.parent().width(),10)-parseInt(b.css("paddingLeft"),10)-parseInt(b.css("paddingRight"),10)-(parseInt(b.css("borderLeftWidth"),10)||0)-(parseInt(b.css("borderRightWidth"),10)||0));c.each(["height","paddingTop","paddingBottom"],function(j,i){g[i]="hide";j=(""+c.css(a.toShow[0],i)).match(/^([\d+-.]+)(.*)$/);f[i]={value:j[1],unit:j[2]||"px"}});a.toShow.css({height:0,overflow:"hidden"}).show();a.toHide.filter(":hidden").each(a.complete).end().filter(":visible").animate(g,{step:function(j,i){if(i.prop=="height")h=i.end-i.start===0?0:(i.now-i.start)/(i.end-i.start);a.toShow[0].style[i.prop]=h*f[i.prop].value+f[i.prop].unit},duration:a.duration,easing:a.easing,complete:function(){a.autoHeight||a.toShow.css("height","");a.toShow.css({width:e,overflow:d});a.complete()}})}else a.toHide.animate({height:"hide",paddingTop:"hide",paddingBottom:"hide"},a);else a.toShow.animate({height:"show",paddingTop:"show",paddingBottom:"show"},a)},bounceslide:function(a){this.slide(a,{easing:a.down?"easeOutBounce":"swing",duration:a.down?1E3:200})}}})})(jQuery);; \ No newline at end of file diff --git a/v2/dotclear/admin/js/jquery/jquery.bgFade.js b/v2/dotclear/admin/js/jquery/jquery.bgFade.js new file mode 100644 index 0000000..cdf201a --- /dev/null +++ b/v2/dotclear/admin/js/jquery/jquery.bgFade.js @@ -0,0 +1,7 @@ + +jQuery.fn.backgroundFade=function(s,callback){var defaults={sColor:[255,0,0],eColor:[255,255,255],fColor:null,steps:200,intervals:5,powr:4},params=jQuery.extend(defaults,s);return this.each(function(){this.bgFade_sColor=jQuery.backgroundFade.parseHexColor(params.sColor);this.bgFade_eColor=jQuery.backgroundFade.parseHexColor(params.eColor);this.bgFade_fColor=params.fColor?params.fColor:jQuery(this).css('backgroundColor');this.bgFade_steps=params.steps;this.bgFade_intervals=params.intervals;this.bgFade_powr=params.powr;this.bgFade_fn=callback;jQuery.backgroundFade.doFade(this);});};jQuery.backgroundFade={parseHexColor:function(c){if(c.constructor==String&&c.substr(0,1)=='#'){return[parseInt(c.substr(1,2),16),parseInt(c.substr(3,2),16),parseInt(c.substr(5,2),16)];} +return c;},easeInOut:function(minValue,maxValue,totalSteps,actualStep,powr){var delta=maxValue-minValue;var stepp=minValue+(Math.pow(((1/totalSteps)*actualStep),powr)*delta);return Math.ceil(stepp);},doFade:function(e){if(e.bgFadeInt)window.clearInterval(e.bgFadeInt);var act_step=0;e.bgFadeInt=window.setInterval(function(){e.style.backgroundColor="rgb("+ +jQuery.backgroundFade.easeInOut(e.bgFade_sColor[0],e.bgFade_eColor[0],e.bgFade_steps,act_step,e.bgFade_powr)+","+ +jQuery.backgroundFade.easeInOut(e.bgFade_sColor[1],e.bgFade_eColor[1],e.bgFade_steps,act_step,e.bgFade_powr)+","+ +jQuery.backgroundFade.easeInOut(e.bgFade_sColor[2],e.bgFade_eColor[2],e.bgFade_steps,act_step,e.bgFade_powr)+")";act_step++;if(act_step>e.bgFade_steps){window.clearInterval(e.bgFadeInt);e.bgFade_sColor=undefined;e.bgFade_eColor=undefined;e.bgFade_fColor=undefined;e.bgFade_steps=undefined;e.bgFade_intervals=undefined;e.bgFade_powr=undefined;if(typeof(e.bgFade_fn)=='function'){e.bgFade_fn.call(e);} +e.style.backgroundColor=e.bgFade_fColor;}},e.bgFade_intervals);}}; \ No newline at end of file diff --git a/v2/dotclear/admin/js/jquery/jquery.biscuit.js b/v2/dotclear/admin/js/jquery/jquery.biscuit.js new file mode 100644 index 0000000..8b74194 --- /dev/null +++ b/v2/dotclear/admin/js/jquery/jquery.biscuit.js @@ -0,0 +1,5 @@ + +jQuery.cookie=function(name,value,options){if(typeof value!='undefined'){options=options||{};var expires='';if(options.expires&&(typeof options.expires=='number'||options.expires.toGMTString)){var date;if(typeof options.expires=='number'){date=new Date();date.setTime(date.getTime()+(options.expires*24*60*60*1000));}else{date=options.expires;} +expires='; expires='+date.toGMTString();} +var path=options.path?'; path='+options.path:'';var domain=options.domain?'; domain='+options.domain:'';var secure=options.secure?'; secure':'';document.cookie=[name,'=',encodeURIComponent(value),expires,path,domain,secure].join('');return null;}else{var cookieValue=null;if(document.cookie&&document.cookie!=''){var cookies=document.cookie.split(';');for(var i=0;i'+''+''+''+''+''+'';this.container=$('');if(this.params.target_element==null){this.container.css({display:'block',position:'absolute',left:$(document).scrollLeft()+'px',top:$(document).scrollTop()+'px',width:'30px',height:'30px',background:'#f00'});$('body').append(this.container);}else{$(this.params.target_element).append(this.container);this.container.css({display:'block',position:'absolute',top:0,left:0,zIndex:1});} +this.container[0].innerHTML=flash;this.movie=document.getElementById(this.params.movie_name);return this;},addFlashVar:function(fv,n,v){if(v!=null){fv.push(n+'='+encodeURIComponent(v));}},flashBind:function(){_this=this;var events={flashReady:function(){if(window[_this.params.movie_name]==undefined){window[_this.params.movie_name]=_this.movie;} +_this.flashBindEvent('flashReady',arguments);},fileDialogComplete:function(){_this.flashBindEvent('fileDialogComplete',arguments);},fileDialogStart:function(){_this.flashBindEvent('fileDialogStart',arguments);},fileQueued:function(file_object){_this.flashBindEvent('fileQueued',arguments);},fileQueueError:function(file_object,error_code,error_msg){_this.flashBindEvent('fileQueueError',arguments);},uploadStart:function(){_this.flashBindEvent('uploadStart',arguments);},uploadProgress:function(){_this.flashBindEvent('uploadProgress',arguments);},uploadError:function(){_this.flashBindEvent('uploadError',arguments);},uploadSuccess:function(){_this.flashBindEvent('uploadSuccess',arguments);},uploadComplete:function(){_this.flashBindEvent('uploadComplete',arguments);},debug:function(){_this.flashBindEvent('debug',arguments);}};window.SWFUpload.instances[this.params.movie_name]=events;window.SWFUpload.movieCount++;},flashEventQueue:[],flashBindEvent:function(evt,a){a=a||new Array();var _this=this;if($.isFunction(this.callbacks[evt])){this.flashEventQueue.push(function(){this.callbacks[evt].apply(this,a);});setTimeout(function(){_this.flashExecuteNextEvent();},0);}else if(this.callbacks[evt]!==null){throw'Event handler '+evt+' is unknown or is not a function';}},flashExecuteNextEvent:function(){var f=this.flashEventQueue?this.flashEventQueue.shift():null;if($.isFunction(f)){f.apply(this);}},destroy:function(){try{this.StopUpload();$(this.movie).remove();SWFUpload.instances[this.params.movie_name]=null;SWFUpload.movieCount--;delete SWFUpload.instances[this.movieName];delete window[this.movieName];return true;}catch(e){return false;}},StartUpload:function(file_id){return this.movie.StartUpload(file_id);},ReturnUploadStart:function(value){return this.movie.ReturnUploadStart(value);},StopUpload:function(){return this.movie.StopUpload();},CancelUpload:function(file_id){return this.movie.CancelUpload(file_id);},GetStats:function(){return this.movie.GetStats();},SetStats:function(stats){return this.movie.SetStats(stats);},GetFile:function(file_id){return this.movie.GetFile(file_id);},GetFileByIndex:function(file_index){return this.movie.GetFileByIndex(file_index);},getFileSizeLimit:function(size){var value=0;var unit='kb';size=$.trim(size.toLowerCase());var values=size.match(/^\d+/);if(values!=null&&values.length>0){value=parseInt(values[0]);} +var units=size.match(/(b|kb|mb|gb)/);if(units!=null&&units.length>0){unit=units[0];} +var multiplier=1024;if(unit==="b"){multiplier=1;}else if(unit==="mb"){multiplier=1048576;}else if(unit==="gb"){multiplier=1073741824;} +return value*multiplier;}};})(jQuery);(function($){$.fn.candyUpload=function(settings,callbacks){new $._candyUpload(this,settings,callbacks);return this;};$._candyUpload=function(target,settings,callbacks){var defaults={debug:false,upload_url:'',params:null,flash_movie:'',file_types:'*.*',file_types_description:'All files',file_size_limit:0,file_upload_limit:0,file_queue_limit:-1,callbacks:{}};this.params=$.extend(defaults,settings);this.params.movie_name='SWFU-'+(window.SWFUpload.instances.length+1);this.target=target;this.createControls();this.target.hide().after(this.ctrl.block).hide();this.params.target_element=this.ctrl.btn_browse.parent().get(0);var _this=this;this.upldr=$.uploader(this.params,{debug:function(msg){$('body').append('
      '+msg+'
      ');_this.bindEvent('debug',arguments);},flashReady:function(){_this.initControls(this);_this.bindEvent('flashReady',arguments);this.movie.style.width=_this.ctrl.btn_browse.width()+'px';this.movie.style.height=_this.ctrl.btn_browse.height()+'px';},fileDialogComplete:function(num_ref_files,num_queue_files){_this.bindEvent('fileDialogComplete',arguments);},fileDialogStart:function(){_this.bindEvent('fileQueued',arguments);},fileQueued:function(o){_this.appendFile(this,o);_this.refreshControls(this);_this.bindEvent('fileQueued',arguments);},fileQueueError:function(o,code,msg){var codes=window.SWFUpload.QUEUE_ERROR;switch(code){case codes.QUEUE_LIMIT_EXCEEDED:_this.queueErrorMsg(_this.locales.limit_exceeded);break;case codes.FILE_EXCEEDS_SIZE_LIMIT:_this.queueErrorMsg(_this.locales.size_limit_exceeded);break;case codes.ZERO_BYTE_FILE:case codes.INVALID_FILETYPE:_this.queueErrorMsg(msg);break;} +_this.bindEvent('fileQueueError',arguments);},uploadStart:function(){this.ReturnUploadStart(true);_this.bindEvent('uploadStart',arguments);},uploadProgress:function(o,bytes,total){_this.fileProgressBar(o.id,bytes,total);_this.bindEvent('uploadProgress',arguments);},uploadError:function(o,code,msg){var codes=window.SWFUpload.UPLOAD_ERROR;switch(code){case codes.FILE_CANCELLED:_this.fileErrorMsg(o.id,_this.locales.canceled);break;case codes.HTTP_ERROR:_this.fileErrorMsg(o.id,_this.locales.http_error+' '+msg);break;case codes.MISSING_UPLOAD_URL:case codes.IO_ERROR:case codes.SECURITY_ERROR:case codes.UPLOAD_LIMIT_EXCEEDED:case codes.UPLOAD_FAILED:case codes.SPECIFIED_FILE_ID_NOT_FOUND:case codes.FILE_VALIDATION_FAILED:case codes.FILE_CANCELLED:case codes.UPLOAD_STOPPED:_this.fileErrorMsg(o.id,_this.locales.error+' '+msg);break;} +_this.refreshControls(this);_this.removeFileCancel(o);_this.bindEvent('uploadError',arguments);},uploadSuccess:function(o,data){_this.fileProgressBar(o.id,1,1);_this.refreshControls(this);_this.removeFileCancel(o);_this.bindEvent('uploadSuccess',arguments);},uploadComplete:function(o){this.StartUpload();_this.refreshControls(this);_this.bindEvent('uploadComplete',arguments);}});};$._candyUpload.prototype={locales:{max_file_size:'Maximum file size allowed:',limit_exceeded:'Limit exceeded.',size_limit_exceeded:'File size exceeds allowed limit.',canceled:'Canceled.',http_error:'HTTP Error:',error:'Error:',choose_file:'Choose file',choose_files:'Choose files',cancel:'Cancel',clean:'Clean',upload:'Upload',no_file_in_queue:'No file in queue.',file_in_queue:'1 file in queue.',files_in_queue:'%d files in queue.',queue_error:'Queue error:'},ctrl:{block:$('
      '),files:null},createControls:function(){this.ctrl.btn_browse=$(' ').click(function(){return false;});this.ctrl.btn_cancel=$(''+this.locales.cancel+'').click(function(){return false;});this.ctrl.btn_clean=$(''+this.locales.clean+'').click(function(){return false;});this.ctrl.btn_upload=$(''+this.locales.upload+'').click(function(){return false;});this.ctrl.msg=$('
      '+this.locales.no_file_in_queue+'
      ').appendTo(this.ctrl.block);var btn=$('
      ').appendTo(this.ctrl.block);var brw=$('').append(this.ctrl.btn_browse).appendTo(btn);$('').append(this.ctrl.btn_upload).appendTo(btn).hide();$('').append(this.ctrl.btn_cancel).appendTo(btn).hide();$('').append(this.ctrl.btn_clean).appendTo(btn).hide();this.bindEvent('createControls');},initControls:function(upldr){if(this.params.file_queue_limit==1){this.ctrl.btn_browse.text(this.locales.choose_file);}else{this.ctrl.btn_browse.text(this.locales.choose_files);} +var _this=this;this.ctrl.btn_cancel.click(function(){_this.cancelQueue(upldr);return false;});this.ctrl.btn_clean.click(function(){_this.cleanQueue(upldr);return false;});this.ctrl.btn_upload.click(function(){_this.uploadQueue(upldr);return false;});var size=this.formatSize(upldr.params.file_size_limit);$('

      '+this.locales.max_file_size+' '+size+'

      ').appendTo(this.ctrl.block);},refreshControls:function(upldr){if(!this.ctrl.files||this.ctrl.files.length==0){return;} +var stats=upldr.GetStats();if(stats.files_queued>0){this.ctrl.btn_cancel.parent().show();this.ctrl.btn_upload.parent().show();if(this.params.file_queue_limit>0&&this.params.file_queue_limit==stats.files_queued){this.ctrl.btn_browse.hide();}else{this.ctrl.btn_browse.show();} +if(stats.files_queued>1){var msg=this.locales.files_in_queue.replace(/%d/,stats.files_queued);}else{var msg=this.locales.file_in_queue;}}else{this.ctrl.btn_browse.show();this.ctrl.btn_cancel.parent().hide();this.ctrl.btn_upload.parent().hide();var msg=this.locales.no_file_in_queue;} +this.ctrl.msg.removeClass('cu-error').text(msg);if(stats.successful_uploads>0||stats.upload_errors>0||stats.upload_cancelled>0){this.ctrl.btn_clean.parent().show();}else{this.ctrl.btn_clean.parent().hide();}},removeFileCancel:function(o){$('#'+o.id+' span.cu-filecancel',this.ctrl.files).remove();},appendFile:function(upldr,o){if(!this.ctrl.files){this.ctrl.files=$('
      ');this.ctrl.msg.after(this.ctrl.files);} +var fileblock=$('
      '+'
      '+o.name+' '+'('+this.formatSize(o.size)+') '+'cancel '+''+'
      ');$('span.cu-filecancel a',fileblock).click(function(){upldr.CancelUpload(o.id);return false;});this.ctrl.files.append(fileblock);},fileProgressBar:function(file_id,bytes,total){var bar=$('#'+file_id+' div.cu-progress>div',this.ctrl.files);if(bar.length==0){$('#'+file_id,this.ctrl.files).append('
       
      ');bar=$('#'+file_id+' div.cu-progress>div',this.ctrl.files);} +var percent=Math.round((bytes*100)/total);bar.css('width',percent+'%').text(percent+'%');},fileMsg:function(file_id,msg,error){error=error||false;var span=$('#'+file_id+' span.cu-filemsg',this.ctrl.files).attr('class','cu-filemsg');if(error){span.addClass('cu-error');} +span.text(msg);},fileErrorMsg:function(file_id,msg){this.fileMsg(file_id,msg,true);},cancelQueue:function(upldr){if(!this.ctrl.files||this.ctrl.files.length==0){return;} +this.ctrl.files.children('div').each(function(){upldr.CancelUpload(this.id);});},uploadQueue:function(upldr){if(!this.ctrl.files||this.ctrl.files.length==0){return;} +upldr.StartUpload();},cleanQueue:function(upldr){var _this=this;var e=$('div.cu-file',this.ctrl.files).not(':has(span.cu-filecancel a)');e.filter(':last').slideUp(200,function(){$(this).remove();if(e.length==1){upldr.SetStats({successful_uploads:0,upload_errors:0,upload_cancelled:0});_this.refreshControls(upldr);}else if(e.length>1){_this.cleanQueue(upldr);}});},queueErrorMsg:function(msg){this.ctrl.msg.addClass('cu-error').text(this.locales.queue_error+' '+msg);},formatSize:function(s){var a_size=Array('B','KB','MB','GB','TB');var i_index=0;while(s>1024){i_index++;s/=1024;} +return(Math.round(s*100)/100)+' '+a_size[i_index];},bindEvent:function(evt,a){if(this.params.callbacks[evt]!=undefined&&$.isFunction(this.params.callbacks[evt])){a=a||new Array();this.params.callbacks[evt].apply(this,a);}}};})(jQuery); \ No newline at end of file diff --git a/v2/dotclear/admin/js/jquery/jquery.farbtastic.js b/v2/dotclear/admin/js/jquery/jquery.farbtastic.js new file mode 100644 index 0000000..26103df --- /dev/null +++ b/v2/dotclear/admin/js/jquery/jquery.farbtastic.js @@ -0,0 +1,22 @@ + +jQuery.fn.farbtastic=function(callback){$.farbtastic(this,callback);return this;};jQuery.farbtastic=function(container,callback){var container=$(container).get(0);return container.farbtastic||(container.farbtastic=new jQuery._farbtastic(container,callback));};jQuery._farbtastic=function(container,callback){var fb=this;$(container).html('
      ');var e=$('.farbtastic',container);fb.wheel=$('.wheel',container).get(0);fb.radius=84;fb.square=100;fb.width=194;if(navigator.appVersion.match(/MSIE [0-6]\./)){$('*',e).each(function(){if(this.currentStyle.backgroundImage!='none'){var image=this.currentStyle.backgroundImage;image=this.currentStyle.backgroundImage.substring(5,image.length-2);$(this).css({'backgroundImage':'none','filter':"progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='"+image+"')"});}});} +fb.linkTo=function(callback){if(typeof fb.callback=='object'){$(fb.callback).unbind('keyup',fb.updateValue);} +fb.color=null;if(typeof callback=='function'){fb.callback=callback;} +else if(typeof callback=='object'||typeof callback=='string'){fb.callback=$(callback);fb.callback.bind('keyup',fb.updateValue);if(fb.callback.get(0).value){fb.setColor(fb.callback.get(0).value);}} +return this;};fb.updateValue=function(event){if(this.value&&this.value!=fb.color){fb.setColor(this.value);}};fb.setColor=function(color){var unpack=fb.unpack(color);if(fb.color!=color&&unpack){fb.color=color;fb.rgb=unpack;fb.hsl=fb.RGBToHSL(fb.rgb);fb.updateDisplay();} +return this;};fb.setHSL=function(hsl){fb.hsl=hsl;fb.rgb=fb.HSLToRGB(hsl);fb.color=fb.pack(fb.rgb);fb.updateDisplay();return this;};fb.widgetCoords=function(event){var x,y;var el=event.target||event.srcElement;var reference=fb.wheel;if(typeof event.offsetX!='undefined'){var pos={x:event.offsetX,y:event.offsetY};var e=el;while(e){e.mouseX=pos.x;e.mouseY=pos.y;pos.x+=e.offsetLeft;pos.y+=e.offsetTop;e=e.offsetParent;} +var e=reference;var offset={x:0,y:0};while(e){if(typeof e.mouseX!='undefined'){x=e.mouseX-offset.x;y=e.mouseY-offset.y;break;} +offset.x+=e.offsetLeft;offset.y+=e.offsetTop;e=e.offsetParent;} +e=el;while(e){e.mouseX=undefined;e.mouseY=undefined;e=e.offsetParent;}} +else{var pos=fb.absolutePosition(reference);x=(event.pageX||0*(event.clientX+$('html').get(0).scrollLeft))-pos.x;y=(event.pageY||0*(event.clientY+$('html').get(0).scrollTop))-pos.y;} +return{x:x-fb.width/2,y:y-fb.width/2};};fb.mousedown=function(event){if(!document.dragging){$(document).bind('mousemove',fb.mousemove).bind('mouseup',fb.mouseup);document.dragging=true;} +var pos=fb.widgetCoords(event);fb.circleDrag=Math.max(Math.abs(pos.x),Math.abs(pos.y))*2>fb.square;fb.mousemove(event);return false;};fb.mousemove=function(event){var pos=fb.widgetCoords(event);if(fb.circleDrag){var hue=Math.atan2(pos.x,-pos.y)/6.28;if(hue<0)hue+=1;fb.setHSL([hue,fb.hsl[1],fb.hsl[2]]);} +else{var sat=Math.max(0,Math.min(1,-(pos.x/fb.square)+.5));var lum=Math.max(0,Math.min(1,-(pos.y/fb.square)+.5));fb.setHSL([fb.hsl[0],sat,lum]);} +return false;};fb.mouseup=function(){$(document).unbind('mousemove',fb.mousemove);$(document).unbind('mouseup',fb.mouseup);document.dragging=false;};fb.updateDisplay=function(){var angle=fb.hsl[0]*6.28;$('.h-marker',e).css({left:Math.round(Math.sin(angle)*fb.radius+fb.width/2)+'px',top:Math.round(-Math.cos(angle)*fb.radius+fb.width/2)+'px'});$('.sl-marker',e).css({left:Math.round(fb.square*(.5-fb.hsl[1])+fb.width/2)+'px',top:Math.round(fb.square*(.5-fb.hsl[2])+fb.width/2)+'px'});$('.color',e).css('backgroundColor',fb.pack(fb.HSLToRGB([fb.hsl[0],1,0.5])));if(typeof fb.callback=='object'){$(fb.callback).css({backgroundColor:fb.color,color:fb.hsl[2]>0.5?'#000':'#fff'});$(fb.callback).each(function(){if(this.value!=fb.color){this.value=fb.color;}});$(fb.callback).change();} +else if(typeof fb.callback=='function'){fb.callback.call(fb,fb.color);}};fb.absolutePosition=function(el){var r={x:el.offsetLeft,y:el.offsetTop};if(el.offsetParent){var tmp=fb.absolutePosition(el.offsetParent);r.x+=tmp.x;r.y+=tmp.y;} +return r;};fb.pack=function(rgb){var r=Math.round(rgb[0]*255);var g=Math.round(rgb[1]*255);var b=Math.round(rgb[2]*255);return'#'+(r<16?'0':'')+r.toString(16)+ +(g<16?'0':'')+g.toString(16)+ +(b<16?'0':'')+b.toString(16);};fb.unpack=function(color){if(color.length==7){return[parseInt('0x'+color.substring(1,3))/255,parseInt('0x'+color.substring(3,5))/255,parseInt('0x'+color.substring(5,7))/255];} +else if(color.length==4){return[parseInt('0x'+color.substring(1,2))/15,parseInt('0x'+color.substring(2,3))/15,parseInt('0x'+color.substring(3,4))/15];}};fb.HSLToRGB=function(hsl){var m1,m2,r,g,b;var h=hsl[0],s=hsl[1],l=hsl[2];m2=(l<=0.5)?l*(s+1):l+s-l*s;m1=l*2-m2;return[this.hueToRGB(m1,m2,h+0.33333),this.hueToRGB(m1,m2,h),this.hueToRGB(m1,m2,h-0.33333)];};fb.hueToRGB=function(m1,m2,h){h=(h<0)?h+1:((h>1)?h-1:h);if(h*6<1)return m1+(m2-m1)*h*6;if(h*2<1)return m2;if(h*3<2)return m1+(m2-m1)*(0.66666-h)*6;return m1;};fb.RGBToHSL=function(rgb){var min,max,delta,h,s,l;var r=rgb[0],g=rgb[1],b=rgb[2];min=Math.min(r,Math.min(g,b));max=Math.max(r,Math.max(g,b));delta=max-min;l=(min+max)/2;s=0;if(l>0&&l<1){s=delta/(l<0.5?(2*l):(2-2*l));} +h=0;if(delta>0){if(max==r&&max!=g)h+=(g-b)/delta;if(max==g&&max!=b)h+=(2+(b-r)/delta);if(max==b&&max!=r)h+=(4+(r-g)/delta);h/=6;} +return[h,s,l];};$('*',e).mousedown(fb.mousedown);fb.setColor('#000000');if(callback){fb.linkTo(callback);}}; \ No newline at end of file diff --git a/v2/dotclear/admin/js/jquery/jquery.js b/v2/dotclear/admin/js/jquery/jquery.js new file mode 100644 index 0000000..772d440 --- /dev/null +++ b/v2/dotclear/admin/js/jquery/jquery.js @@ -0,0 +1,471 @@ + +(function(window,undefined){var jQuery=function(selector,context){return new jQuery.fn.init(selector,context);},_jQuery=window.jQuery,_$=window.$,document=window.document,rootjQuery,quickExpr=/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,isSimple=/^.[^:#\[\.,]*$/,rnotwhite=/\S/,rtrim=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,rsingleTag=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,userAgent=navigator.userAgent,browserMatch,readyBound=false,readyList=[],DOMContentLoaded,toString=Object.prototype.toString,hasOwnProperty=Object.prototype.hasOwnProperty,push=Array.prototype.push,slice=Array.prototype.slice,indexOf=Array.prototype.indexOf;jQuery.fn=jQuery.prototype={init:function(selector,context){var match,elem,ret,doc;if(!selector){return this;} +if(selector.nodeType){this.context=this[0]=selector;this.length=1;return this;} +if(selector==="body"&&!context){this.context=document;this[0]=document.body;this.selector="body";this.length=1;return this;} +if(typeof selector==="string"){match=quickExpr.exec(selector);if(match&&(match[1]||!context)){if(match[1]){doc=(context?context.ownerDocument||context:document);ret=rsingleTag.exec(selector);if(ret){if(jQuery.isPlainObject(context)){selector=[document.createElement(ret[1])];jQuery.fn.attr.call(selector,context,true);}else{selector=[doc.createElement(ret[1])];}}else{ret=buildFragment([match[1]],[doc]);selector=(ret.cacheable?ret.fragment.cloneNode(true):ret.fragment).childNodes;} +return jQuery.merge(this,selector);}else{elem=document.getElementById(match[2]);if(elem){if(elem.id!==match[2]){return rootjQuery.find(selector);} +this.length=1;this[0]=elem;} +this.context=document;this.selector=selector;return this;}}else if(!context&&/^\w+$/.test(selector)){this.selector=selector;this.context=document;selector=document.getElementsByTagName(selector);return jQuery.merge(this,selector);}else if(!context||context.jquery){return(context||rootjQuery).find(selector);}else{return jQuery(context).find(selector);}}else if(jQuery.isFunction(selector)){return rootjQuery.ready(selector);} +if(selector.selector!==undefined){this.selector=selector.selector;this.context=selector.context;} +return jQuery.makeArray(selector,this);},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length;},toArray:function(){return slice.call(this,0);},get:function(num){return num==null?this.toArray():(num<0?this.slice(num)[0]:this[num]);},pushStack:function(elems,name,selector){var ret=jQuery();if(jQuery.isArray(elems)){push.apply(ret,elems);}else{jQuery.merge(ret,elems);} +ret.prevObject=this;ret.context=this.context;if(name==="find"){ret.selector=this.selector+(this.selector?" ":"")+selector;}else if(name){ret.selector=this.selector+"."+name+"("+selector+")";} +return ret;},each:function(callback,args){return jQuery.each(this,callback,args);},ready:function(fn){jQuery.bindReady();if(jQuery.isReady){fn.call(document,jQuery);}else if(readyList){readyList.push(fn);} +return this;},eq:function(i){return i===-1?this.slice(i):this.slice(i,+i+1);},first:function(){return this.eq(0);},last:function(){return this.eq(-1);},slice:function(){return this.pushStack(slice.apply(this,arguments),"slice",slice.call(arguments).join(","));},map:function(callback){return this.pushStack(jQuery.map(this,function(elem,i){return callback.call(elem,i,elem);}));},end:function(){return this.prevObject||jQuery(null);},push:push,sort:[].sort,splice:[].splice};jQuery.fn.init.prototype=jQuery.fn;jQuery.extend=jQuery.fn.extend=function(){var target=arguments[0]||{},i=1,length=arguments.length,deep=false,options,name,src,copy;if(typeof target==="boolean"){deep=target;target=arguments[1]||{};i=2;} +if(typeof target!=="object"&&!jQuery.isFunction(target)){target={};} +if(length===i){target=this;--i;} +for(;i
      a";var all=div.getElementsByTagName("*"),a=div.getElementsByTagName("a")[0];if(!all||!all.length||!a){return;} +jQuery.support={leadingWhitespace:div.firstChild.nodeType===3,tbody:!div.getElementsByTagName("tbody").length,htmlSerialize:!!div.getElementsByTagName("link").length,style:/red/.test(a.getAttribute("style")),hrefNormalized:a.getAttribute("href")==="/a",opacity:/^0.55$/.test(a.style.opacity),cssFloat:!!a.style.cssFloat,checkOn:div.getElementsByTagName("input")[0].value==="on",optSelected:document.createElement("select").appendChild(document.createElement("option")).selected,parentNode:div.removeChild(div.appendChild(document.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};script.type="text/javascript";try{script.appendChild(document.createTextNode("window."+id+"=1;"));}catch(e){} +root.insertBefore(script,root.firstChild);if(window[id]){jQuery.support.scriptEval=true;delete window[id];} +try{delete script.test;}catch(e){jQuery.support.deleteExpando=false;} +root.removeChild(script);if(div.attachEvent&&div.fireEvent){div.attachEvent("onclick",function click(){jQuery.support.noCloneEvent=false;div.detachEvent("onclick",click);});div.cloneNode(true).fireEvent("onclick");} +div=document.createElement("div");div.innerHTML="";var fragment=document.createDocumentFragment();fragment.appendChild(div.firstChild);jQuery.support.checkClone=fragment.cloneNode(true).cloneNode(true).lastChild.checked;jQuery(function(){var div=document.createElement("div");div.style.width=div.style.paddingLeft="1px";document.body.appendChild(div);jQuery.boxModel=jQuery.support.boxModel=div.offsetWidth===2;document.body.removeChild(div).style.display='none';div=null;});var eventSupported=function(eventName){var el=document.createElement("div");eventName="on"+eventName;var isSupported=(eventName in el);if(!isSupported){el.setAttribute(eventName,"return;");isSupported=typeof el[eventName]==="function";} +el=null;return isSupported;};jQuery.support.submitBubbles=eventSupported("submit");jQuery.support.changeBubbles=eventSupported("change");root=script=div=all=a=null;})();jQuery.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var expando="jQuery"+now(),uuid=0,windowData={};jQuery.extend({cache:{},expando:expando,noData:{"embed":true,"object":true,"applet":true},data:function(elem,name,data){if(elem.nodeName&&jQuery.noData[elem.nodeName.toLowerCase()]){return;} +elem=elem==window?windowData:elem;var id=elem[expando],cache=jQuery.cache,thisCache;if(!id&&typeof name==="string"&&data===undefined){return null;} +if(!id){id=++uuid;} +if(typeof name==="object"){elem[expando]=id;thisCache=cache[id]=jQuery.extend(true,{},name);}else if(!cache[id]){elem[expando]=id;cache[id]={};} +thisCache=cache[id];if(data!==undefined){thisCache[name]=data;} +return typeof name==="string"?thisCache[name]:thisCache;},removeData:function(elem,name){if(elem.nodeName&&jQuery.noData[elem.nodeName.toLowerCase()]){return;} +elem=elem==window?windowData:elem;var id=elem[expando],cache=jQuery.cache,thisCache=cache[id];if(name){if(thisCache){delete thisCache[name];if(jQuery.isEmptyObject(thisCache)){jQuery.removeData(elem);}}}else{if(jQuery.support.deleteExpando){delete elem[jQuery.expando];}else if(elem.removeAttribute){elem.removeAttribute(jQuery.expando);} +delete cache[id];}}});jQuery.fn.extend({data:function(key,value){if(typeof key==="undefined"&&this.length){return jQuery.data(this[0]);}else if(typeof key==="object"){return this.each(function(){jQuery.data(this,key);});} +var parts=key.split(".");parts[1]=parts[1]?"."+parts[1]:"";if(value===undefined){var data=this.triggerHandler("getData"+parts[1]+"!",[parts[0]]);if(data===undefined&&this.length){data=jQuery.data(this[0],key);} +return data===undefined&&parts[1]?this.data(parts[0]):data;}else{return this.trigger("setData"+parts[1]+"!",[parts[0],value]).each(function(){jQuery.data(this,key,value);});}},removeData:function(key){return this.each(function(){jQuery.removeData(this,key);});}});jQuery.extend({queue:function(elem,type,data){if(!elem){return;} +type=(type||"fx")+"queue";var q=jQuery.data(elem,type);if(!data){return q||[];} +if(!q||jQuery.isArray(data)){q=jQuery.data(elem,type,jQuery.makeArray(data));}else{q.push(data);} +return q;},dequeue:function(elem,type){type=type||"fx";var queue=jQuery.queue(elem,type),fn=queue.shift();if(fn==="inprogress"){fn=queue.shift();} +if(fn){if(type==="fx"){queue.unshift("inprogress");} +fn.call(elem,function(){jQuery.dequeue(elem,type);});}}});jQuery.fn.extend({queue:function(type,data){if(typeof type!=="string"){data=type;type="fx";} +if(data===undefined){return jQuery.queue(this[0],type);} +return this.each(function(i,elem){var queue=jQuery.queue(this,type,data);if(type==="fx"&&queue[0]!=="inprogress"){jQuery.dequeue(this,type);}});},dequeue:function(type){return this.each(function(){jQuery.dequeue(this,type);});},delay:function(time,type){time=jQuery.fx?jQuery.fx.speeds[time]||time:time;type=type||"fx";return this.queue(type,function(){var elem=this;setTimeout(function(){jQuery.dequeue(elem,type);},time);});},clearQueue:function(type){return this.queue(type||"fx",[]);}});var rclass=/[\n\t]/g,rspace=/\s+/,rreturn=/\r/g,rspecialurl=/href|src|style/,rtype=/(button|input)/i,rfocusable=/(button|input|object|select|textarea)/i,rclickable=/^(a|area)$/i,rradiocheck=/radio|checkbox/;jQuery.fn.extend({attr:function(name,value){return access(this,name,value,true,jQuery.attr);},removeAttr:function(name,fn){return this.each(function(){jQuery.attr(this,name,"");if(this.nodeType===1){this.removeAttribute(name);}});},addClass:function(value){if(jQuery.isFunction(value)){return this.each(function(i){var self=jQuery(this);self.addClass(value.call(this,i,self.attr("class")));});} +if(value&&typeof value==="string"){var classNames=(value||"").split(rspace);for(var i=0,l=this.length;i-1){return true;}} +return false;},val:function(value){if(value===undefined){var elem=this[0];if(elem){if(jQuery.nodeName(elem,"option")){return(elem.attributes.value||{}).specified?elem.value:elem.text;} +if(jQuery.nodeName(elem,"select")){var index=elem.selectedIndex,values=[],options=elem.options,one=elem.type==="select-one";if(index<0){return null;} +for(var i=one?index:0,max=one?index+1:options.length;i=0;}else if(jQuery.nodeName(this,"select")){var values=jQuery.makeArray(val);jQuery("option",this).each(function(){this.selected=jQuery.inArray(jQuery(this).val(),values)>=0;});if(!values.length){this.selectedIndex=-1;}}else{this.value=val;}});}});jQuery.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(elem,name,value,pass){if(!elem||elem.nodeType===3||elem.nodeType===8){return undefined;} +if(pass&&name in jQuery.attrFn){return jQuery(elem)[name](value);} +var notxml=elem.nodeType!==1||!jQuery.isXMLDoc(elem),set=value!==undefined;name=notxml&&jQuery.props[name]||name;if(elem.nodeType===1){var special=rspecialurl.test(name);if(name==="selected"&&!jQuery.support.optSelected){var parent=elem.parentNode;if(parent){parent.selectedIndex;if(parent.parentNode){parent.parentNode.selectedIndex;}}} +if(name in elem&¬xml&&!special){if(set){if(name==="type"&&rtype.test(elem.nodeName)&&elem.parentNode){jQuery.error("type property can't be changed");} +elem[name]=value;} +if(jQuery.nodeName(elem,"form")&&elem.getAttributeNode(name)){return elem.getAttributeNode(name).nodeValue;} +if(name==="tabIndex"){var attributeNode=elem.getAttributeNode("tabIndex");return attributeNode&&attributeNode.specified?attributeNode.value:rfocusable.test(elem.nodeName)||rclickable.test(elem.nodeName)&&elem.href?0:undefined;} +return elem[name];} +if(!jQuery.support.style&¬xml&&name==="style"){if(set){elem.style.cssText=""+value;} +return elem.style.cssText;} +if(set){elem.setAttribute(name,""+value);} +var attr=!jQuery.support.hrefNormalized&¬xml&&special?elem.getAttribute(name,2):elem.getAttribute(name);return attr===null?undefined:attr;} +return jQuery.style(elem,name,value);}});var rnamespaces=/\.(.*)$/,fcleanup=function(nm){return nm.replace(/[^\w\s\.\|`]/g,function(ch){return"\\"+ch;});};jQuery.event={add:function(elem,types,handler,data){if(elem.nodeType===3||elem.nodeType===8){return;} +if(elem.setInterval&&(elem!==window&&!elem.frameElement)){elem=window;} +var handleObjIn,handleObj;if(handler.handler){handleObjIn=handler;handler=handleObjIn.handler;} +if(!handler.guid){handler.guid=jQuery.guid++;} +var elemData=jQuery.data(elem);if(!elemData){return;} +var events=elemData.events=elemData.events||{},eventHandle=elemData.handle,eventHandle;if(!eventHandle){elemData.handle=eventHandle=function(){return typeof jQuery!=="undefined"&&!jQuery.event.triggered?jQuery.event.handle.apply(eventHandle.elem,arguments):undefined;};} +eventHandle.elem=elem;types=types.split(" ");var type,i=0,namespaces;while((type=types[i++])){handleObj=handleObjIn?jQuery.extend({},handleObjIn):{handler:handler,data:data};if(type.indexOf(".")>-1){namespaces=type.split(".");type=namespaces.shift();handleObj.namespace=namespaces.slice(0).sort().join(".");}else{namespaces=[];handleObj.namespace="";} +handleObj.type=type;handleObj.guid=handler.guid;var handlers=events[type],special=jQuery.event.special[type]||{};if(!handlers){handlers=events[type]=[];if(!special.setup||special.setup.call(elem,data,namespaces,eventHandle)===false){if(elem.addEventListener){elem.addEventListener(type,eventHandle,false);}else if(elem.attachEvent){elem.attachEvent("on"+type,eventHandle);}}} +if(special.add){special.add.call(elem,handleObj);if(!handleObj.handler.guid){handleObj.handler.guid=handler.guid;}} +handlers.push(handleObj);jQuery.event.global[type]=true;} +elem=null;},global:{},remove:function(elem,types,handler,pos){if(elem.nodeType===3||elem.nodeType===8){return;} +var ret,type,fn,i=0,all,namespaces,namespace,special,eventType,handleObj,origType,elemData=jQuery.data(elem),events=elemData&&elemData.events;if(!elemData||!events){return;} +if(types&&types.type){handler=types.handler;types=types.type;} +if(!types||typeof types==="string"&&types.charAt(0)==="."){types=types||"";for(type in events){jQuery.event.remove(elem,type+types);} +return;} +types=types.split(" ");while((type=types[i++])){origType=type;handleObj=null;all=type.indexOf(".")<0;namespaces=[];if(!all){namespaces=type.split(".");type=namespaces.shift();namespace=new RegExp("(^|\\.)"+ +jQuery.map(namespaces.slice(0).sort(),fcleanup).join("\\.(?:.*\\.)?")+"(\\.|$)")} +eventType=events[type];if(!eventType){continue;} +if(!handler){for(var j=0;j=0){event.type=type=type.slice(0,-1);event.exclusive=true;} +if(!elem){event.stopPropagation();if(jQuery.event.global[type]){jQuery.each(jQuery.cache,function(){if(this.events&&this.events[type]){jQuery.event.trigger(event,data,this.handle.elem);}});}} +if(!elem||elem.nodeType===3||elem.nodeType===8){return undefined;} +event.result=undefined;event.target=elem;data=jQuery.makeArray(data);data.unshift(event);} +event.currentTarget=elem;var handle=jQuery.data(elem,"handle");if(handle){handle.apply(elem,data);} +var parent=elem.parentNode||elem.ownerDocument;try{if(!(elem&&elem.nodeName&&jQuery.noData[elem.nodeName.toLowerCase()])){if(elem["on"+type]&&elem["on"+type].apply(elem,data)===false){event.result=false;}}}catch(e){} +if(!event.isPropagationStopped()&&parent){jQuery.event.trigger(event,data,parent,true);}else if(!event.isDefaultPrevented()){var target=event.target,old,isClick=jQuery.nodeName(target,"a")&&type==="click",special=jQuery.event.special[type]||{};if((!special._default||special._default.call(elem,event)===false)&&!isClick&&!(target&&target.nodeName&&jQuery.noData[target.nodeName.toLowerCase()])){try{if(target[type]){old=target["on"+type];if(old){target["on"+type]=null;} +jQuery.event.triggered=true;target[type]();}}catch(e){} +if(old){target["on"+type]=old;} +jQuery.event.triggered=false;}}},handle:function(event){var all,handlers,namespaces,namespace,events;event=arguments[0]=jQuery.event.fix(event||window.event);event.currentTarget=this;all=event.type.indexOf(".")<0&&!event.exclusive;if(!all){namespaces=event.type.split(".");event.type=namespaces.shift();namespace=new RegExp("(^|\\.)"+namespaces.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)");} +var events=jQuery.data(this,"events"),handlers=events[event.type];if(events&&handlers){handlers=handlers.slice(0);for(var j=0,l=handlers.length;j-1?jQuery.map(elem.options,function(elem){return elem.selected;}).join("-"):"";}else if(elem.nodeName.toLowerCase()==="select"){val=elem.selectedIndex;} +return val;},testChange=function testChange(e){var elem=e.target,data,val;if(!formElems.test(elem.nodeName)||elem.readOnly){return;} +data=jQuery.data(elem,"_change_data");val=getVal(elem);if(e.type!=="focusout"||elem.type!=="radio"){jQuery.data(elem,"_change_data",val);} +if(data===undefined||val===data){return;} +if(data!=null||val){e.type="change";return jQuery.event.trigger(e,arguments[1],elem);}};jQuery.event.special.change={filters:{focusout:testChange,click:function(e){var elem=e.target,type=elem.type;if(type==="radio"||type==="checkbox"||elem.nodeName.toLowerCase()==="select"){return testChange.call(this,e);}},keydown:function(e){var elem=e.target,type=elem.type;if((e.keyCode===13&&elem.nodeName.toLowerCase()!=="textarea")||(e.keyCode===32&&(type==="checkbox"||type==="radio"))||type==="select-multiple"){return testChange.call(this,e);}},beforeactivate:function(e){var elem=e.target;jQuery.data(elem,"_change_data",getVal(elem));}},setup:function(data,namespaces){if(this.type==="file"){return false;} +for(var type in changeFilters){jQuery.event.add(this,type+".specialChange",changeFilters[type]);} +return formElems.test(this.nodeName);},teardown:function(namespaces){jQuery.event.remove(this,".specialChange");return formElems.test(this.nodeName);}};changeFilters=jQuery.event.special.change.filters;} +function trigger(type,elem,args){args[0].type=type;return jQuery.event.handle.apply(elem,args);} +if(document.addEventListener){jQuery.each({focus:"focusin",blur:"focusout"},function(orig,fix){jQuery.event.special[fix]={setup:function(){this.addEventListener(orig,handler,true);},teardown:function(){this.removeEventListener(orig,handler,true);}};function handler(e){e=jQuery.event.fix(e);e.type=fix;return jQuery.event.handle.call(this,e);}});} +jQuery.each(["bind","one"],function(i,name){jQuery.fn[name]=function(type,data,fn){if(typeof type==="object"){for(var key in type){this[name](key,data,type[key],fn);} +return this;} +if(jQuery.isFunction(data)){fn=data;data=undefined;} +var handler=name==="one"?jQuery.proxy(fn,function(event){jQuery(this).unbind(event,handler);return fn.apply(this,arguments);}):fn;if(type==="unload"&&name!=="one"){this.one(type,data,fn);}else{for(var i=0,l=this.length;i+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,done=0,toString=Object.prototype.toString,hasDuplicate=false,baseHasDuplicate=true;[0,0].sort(function(){baseHasDuplicate=false;return 0;});var Sizzle=function(selector,context,results,seed){results=results||[];var origContext=context=context||document;if(context.nodeType!==1&&context.nodeType!==9){return[];} +if(!selector||typeof selector!=="string"){return results;} +var parts=[],m,set,checkSet,extra,prune=true,contextXML=isXML(context),soFar=selector;while((chunker.exec(""),m=chunker.exec(soFar))!==null){soFar=m[3];parts.push(m[1]);if(m[2]){extra=m[3];break;}} +if(parts.length>1&&origPOS.exec(selector)){if(parts.length===2&&Expr.relative[parts[0]]){set=posProcess(parts[0]+parts[1],context);}else{set=Expr.relative[parts[0]]?[context]:Sizzle(parts.shift(),context);while(parts.length){selector=parts.shift();if(Expr.relative[selector]){selector+=parts.shift();} +set=posProcess(selector,set);}}}else{if(!seed&&parts.length>1&&context.nodeType===9&&!contextXML&&Expr.match.ID.test(parts[0])&&!Expr.match.ID.test(parts[parts.length-1])){var ret=Sizzle.find(parts.shift(),context,contextXML);context=ret.expr?Sizzle.filter(ret.expr,ret.set)[0]:ret.set[0];} +if(context){var ret=seed?{expr:parts.pop(),set:makeArray(seed)}:Sizzle.find(parts.pop(),parts.length===1&&(parts[0]==="~"||parts[0]==="+")&&context.parentNode?context.parentNode:context,contextXML);set=ret.expr?Sizzle.filter(ret.expr,ret.set):ret.set;if(parts.length>0){checkSet=makeArray(set);}else{prune=false;} +while(parts.length){var cur=parts.pop(),pop=cur;if(!Expr.relative[cur]){cur="";}else{pop=parts.pop();} +if(pop==null){pop=context;} +Expr.relative[cur](checkSet,pop,contextXML);}}else{checkSet=parts=[];}} +if(!checkSet){checkSet=set;} +if(!checkSet){Sizzle.error(cur||selector);} +if(toString.call(checkSet)==="[object Array]"){if(!prune){results.push.apply(results,checkSet);}else if(context&&context.nodeType===1){for(var i=0;checkSet[i]!=null;i++){if(checkSet[i]&&(checkSet[i]===true||checkSet[i].nodeType===1&&contains(context,checkSet[i]))){results.push(set[i]);}}}else{for(var i=0;checkSet[i]!=null;i++){if(checkSet[i]&&checkSet[i].nodeType===1){results.push(set[i]);}}}}else{makeArray(checkSet,results);} +if(extra){Sizzle(extra,origContext,results,seed);Sizzle.uniqueSort(results);} +return results;};Sizzle.uniqueSort=function(results){if(sortOrder){hasDuplicate=baseHasDuplicate;results.sort(sortOrder);if(hasDuplicate){for(var i=1;i":function(checkSet,part){var isPartStr=typeof part==="string";if(isPartStr&&!/\W/.test(part)){part=part.toLowerCase();for(var i=0,l=checkSet.length;i=0)){if(!inplace){result.push(elem);}}else if(inplace){curLoop[i]=false;}}} +return false;},ID:function(match){return match[1].replace(/\\/g,"");},TAG:function(match,curLoop){return match[1].toLowerCase();},CHILD:function(match){if(match[1]==="nth"){var test=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(match[2]==="even"&&"2n"||match[2]==="odd"&&"2n+1"||!/\D/.test(match[2])&&"0n+"+match[2]||match[2]);match[2]=(test[1]+(test[2]||1))-0;match[3]=test[3]-0;} +match[0]=done++;return match;},ATTR:function(match,curLoop,inplace,result,not,isXML){var name=match[1].replace(/\\/g,"");if(!isXML&&Expr.attrMap[name]){match[1]=Expr.attrMap[name];} +if(match[2]==="~="){match[4]=" "+match[4]+" ";} +return match;},PSEUDO:function(match,curLoop,inplace,result,not){if(match[1]==="not"){if((chunker.exec(match[3])||"").length>1||/^\w/.test(match[3])){match[3]=Sizzle(match[3],null,null,curLoop);}else{var ret=Sizzle.filter(match[3],curLoop,inplace,true^not);if(!inplace){result.push.apply(result,ret);} +return false;}}else if(Expr.match.POS.test(match[0])||Expr.match.CHILD.test(match[0])){return true;} +return match;},POS:function(match){match.unshift(true);return match;}},filters:{enabled:function(elem){return elem.disabled===false&&elem.type!=="hidden";},disabled:function(elem){return elem.disabled===true;},checked:function(elem){return elem.checked===true;},selected:function(elem){elem.parentNode.selectedIndex;return elem.selected===true;},parent:function(elem){return!!elem.firstChild;},empty:function(elem){return!elem.firstChild;},has:function(elem,i,match){return!!Sizzle(match[3],elem).length;},header:function(elem){return/h\d/i.test(elem.nodeName);},text:function(elem){return"text"===elem.type;},radio:function(elem){return"radio"===elem.type;},checkbox:function(elem){return"checkbox"===elem.type;},file:function(elem){return"file"===elem.type;},password:function(elem){return"password"===elem.type;},submit:function(elem){return"submit"===elem.type;},image:function(elem){return"image"===elem.type;},reset:function(elem){return"reset"===elem.type;},button:function(elem){return"button"===elem.type||elem.nodeName.toLowerCase()==="button";},input:function(elem){return/input|select|textarea|button/i.test(elem.nodeName);}},setFilters:{first:function(elem,i){return i===0;},last:function(elem,i,match,array){return i===array.length-1;},even:function(elem,i){return i%2===0;},odd:function(elem,i){return i%2===1;},lt:function(elem,i,match){return imatch[3]-0;},nth:function(elem,i,match){return match[3]-0===i;},eq:function(elem,i,match){return match[3]-0===i;}},filter:{PSEUDO:function(elem,match,i,array){var name=match[1],filter=Expr.filters[name];if(filter){return filter(elem,i,match,array);}else if(name==="contains"){return(elem.textContent||elem.innerText||getText([elem])||"").indexOf(match[3])>=0;}else if(name==="not"){var not=match[3];for(var i=0,l=not.length;i=0);}}},ID:function(elem,match){return elem.nodeType===1&&elem.getAttribute("id")===match;},TAG:function(elem,match){return(match==="*"&&elem.nodeType===1)||elem.nodeName.toLowerCase()===match;},CLASS:function(elem,match){return(" "+(elem.className||elem.getAttribute("class"))+" ").indexOf(match)>-1;},ATTR:function(elem,match){var name=match[1],result=Expr.attrHandle[name]?Expr.attrHandle[name](elem):elem[name]!=null?elem[name]:elem.getAttribute(name),value=result+"",type=match[2],check=match[4];return result==null?type==="!=":type==="="?value===check:type==="*="?value.indexOf(check)>=0:type==="~="?(" "+value+" ").indexOf(check)>=0:!check?value&&result!==false:type==="!="?value!==check:type==="^="?value.indexOf(check)===0:type==="$="?value.substr(value.length-check.length)===check:type==="|="?value===check||value.substr(0,check.length+1)===check+"-":false;},POS:function(elem,match,i,array){var name=match[2],filter=Expr.setFilters[name];if(filter){return filter(elem,i,match,array);}}}};var origPOS=Expr.match.POS;for(var type in Expr.match){Expr.match[type]=new RegExp(Expr.match[type].source+/(?![^\[]*\])(?![^\(]*\))/.source);Expr.leftMatch[type]=new RegExp(/(^(?:.|\r|\n)*?)/.source+Expr.match[type].source.replace(/\\(\d+)/g,function(all,num){return"\\"+(num-0+1);}));} +var makeArray=function(array,results){array=Array.prototype.slice.call(array,0);if(results){results.push.apply(results,array);return results;} +return array;};try{Array.prototype.slice.call(document.documentElement.childNodes,0)[0].nodeType;}catch(e){makeArray=function(array,results){var ret=results||[];if(toString.call(array)==="[object Array]"){Array.prototype.push.apply(ret,array);}else{if(typeof array.length==="number"){for(var i=0,l=array.length;i";var root=document.documentElement;root.insertBefore(form,root.firstChild);if(document.getElementById(id)){Expr.find.ID=function(match,context,isXML){if(typeof context.getElementById!=="undefined"&&!isXML){var m=context.getElementById(match[1]);return m?m.id===match[1]||typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id").nodeValue===match[1]?[m]:undefined:[];}};Expr.filter.ID=function(elem,match){var node=typeof elem.getAttributeNode!=="undefined"&&elem.getAttributeNode("id");return elem.nodeType===1&&node&&node.nodeValue===match;};} +root.removeChild(form);root=form=null;})();(function(){var div=document.createElement("div");div.appendChild(document.createComment(""));if(div.getElementsByTagName("*").length>0){Expr.find.TAG=function(match,context){var results=context.getElementsByTagName(match[1]);if(match[1]==="*"){var tmp=[];for(var i=0;results[i];i++){if(results[i].nodeType===1){tmp.push(results[i]);}} +results=tmp;} +return results;};} +div.innerHTML="";if(div.firstChild&&typeof div.firstChild.getAttribute!=="undefined"&&div.firstChild.getAttribute("href")!=="#"){Expr.attrHandle.href=function(elem){return elem.getAttribute("href",2);};} +div=null;})();if(document.querySelectorAll){(function(){var oldSizzle=Sizzle,div=document.createElement("div");div.innerHTML="

      ";if(div.querySelectorAll&&div.querySelectorAll(".TEST").length===0){return;} +Sizzle=function(query,context,extra,seed){context=context||document;if(!seed&&context.nodeType===9&&!isXML(context)){try{return makeArray(context.querySelectorAll(query),extra);}catch(e){}} +return oldSizzle(query,context,extra,seed);};for(var prop in oldSizzle){Sizzle[prop]=oldSizzle[prop];} +div=null;})();} +(function(){var div=document.createElement("div");div.innerHTML="
      ";if(!div.getElementsByClassName||div.getElementsByClassName("e").length===0){return;} +div.lastChild.className="e";if(div.getElementsByClassName("e").length===1){return;} +Expr.order.splice(1,0,"CLASS");Expr.find.CLASS=function(match,context,isXML){if(typeof context.getElementsByClassName!=="undefined"&&!isXML){return context.getElementsByClassName(match[1]);}};div=null;})();function dirNodeCheck(dir,cur,doneName,checkSet,nodeCheck,isXML){for(var i=0,l=checkSet.length;i0){match=elem;break;}} +elem=elem[dir];} +checkSet[i]=match;}}} +var contains=document.compareDocumentPosition?function(a,b){return!!(a.compareDocumentPosition(b)&16);}:function(a,b){return a!==b&&(a.contains?a.contains(b):true);};var isXML=function(elem){var documentElement=(elem?elem.ownerDocument||elem:0).documentElement;return documentElement?documentElement.nodeName!=="HTML":false;};var posProcess=function(selector,context){var tmpSet=[],later="",match,root=context.nodeType?[context]:context;while((match=Expr.match.PSEUDO.exec(selector))){later+=match[0];selector=selector.replace(Expr.match.PSEUDO,"");} +selector=Expr.relative[selector]?selector+"*":selector;for(var i=0,l=root.length;i=0)===keep;});};jQuery.fn.extend({find:function(selector){var ret=this.pushStack("","find",selector),length=0;for(var i=0,l=this.length;i0){for(var n=length;n0;},closest:function(selectors,context){if(jQuery.isArray(selectors)){var ret=[],cur=this[0],match,matches={},selector;if(cur&&selectors.length){for(var i=0,l=selectors.length;i-1:jQuery(cur).is(match)){ret.push({selector:selector,elem:cur});delete matches[selector];}} +cur=cur.parentNode;}} +return ret;} +var pos=jQuery.expr.match.POS.test(selectors)?jQuery(selectors,context||this.context):null;return this.map(function(i,cur){while(cur&&cur.ownerDocument&&cur!==context){if(pos?pos.index(cur)>-1:jQuery(cur).is(selectors)){return cur;} +cur=cur.parentNode;} +return null;});},index:function(elem){if(!elem||typeof elem==="string"){return jQuery.inArray(this[0],elem?jQuery(elem):this.parent().children());} +return jQuery.inArray(elem.jquery?elem[0]:elem,this);},add:function(selector,context){var set=typeof selector==="string"?jQuery(selector,context||this.context):jQuery.makeArray(selector),all=jQuery.merge(this.get(),set);return this.pushStack(isDisconnected(set[0])||isDisconnected(all[0])?all:jQuery.unique(all));},andSelf:function(){return this.add(this.prevObject);}});function isDisconnected(node){return!node||!node.parentNode||node.parentNode.nodeType===11;} +jQuery.each({parent:function(elem){var parent=elem.parentNode;return parent&&parent.nodeType!==11?parent:null;},parents:function(elem){return jQuery.dir(elem,"parentNode");},parentsUntil:function(elem,i,until){return jQuery.dir(elem,"parentNode",until);},next:function(elem){return jQuery.nth(elem,2,"nextSibling");},prev:function(elem){return jQuery.nth(elem,2,"previousSibling");},nextAll:function(elem){return jQuery.dir(elem,"nextSibling");},prevAll:function(elem){return jQuery.dir(elem,"previousSibling");},nextUntil:function(elem,i,until){return jQuery.dir(elem,"nextSibling",until);},prevUntil:function(elem,i,until){return jQuery.dir(elem,"previousSibling",until);},siblings:function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);},children:function(elem){return jQuery.sibling(elem.firstChild);},contents:function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);}},function(name,fn){jQuery.fn[name]=function(until,selector){var ret=jQuery.map(this,fn,until);if(!runtil.test(name)){selector=until;} +if(selector&&typeof selector==="string"){ret=jQuery.filter(selector,ret);} +ret=this.length>1?jQuery.unique(ret):ret;if((this.length>1||rmultiselector.test(selector))&&rparentsprev.test(name)){ret=ret.reverse();} +return this.pushStack(ret,name,slice.call(arguments).join(","));};});jQuery.extend({filter:function(expr,elems,not){if(not){expr=":not("+expr+")";} +return jQuery.find.matches(expr,elems);},dir:function(elem,dir,until){var matched=[],cur=elem[dir];while(cur&&cur.nodeType!==9&&(until===undefined||cur.nodeType!==1||!jQuery(cur).is(until))){if(cur.nodeType===1){matched.push(cur);} +cur=cur[dir];} +return matched;},nth:function(cur,result,dir,elem){result=result||1;var num=0;for(;cur;cur=cur[dir]){if(cur.nodeType===1&&++num===result){break;}} +return cur;},sibling:function(n,elem){var r=[];for(;n;n=n.nextSibling){if(n.nodeType===1&&n!==elem){r.push(n);}} +return r;}});var rinlinejQuery=/ jQuery\d+="(?:\d+|null)"/g,rleadingWhitespace=/^\s+/,rxhtmlTag=/(<([\w:]+)[^>]*?)\/>/g,rselfClosing=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,rtagName=/<([\w:]+)/,rtbody=/";},wrapMap={option:[1,""],legend:[1,"
      ","
      "],thead:[1,"","
      "],tr:[2,"","
      "],td:[3,"","
      "],col:[2,"","
      "],area:[1,"",""],_default:[0,"",""]};wrapMap.optgroup=wrapMap.option;wrapMap.tbody=wrapMap.tfoot=wrapMap.colgroup=wrapMap.caption=wrapMap.thead;wrapMap.th=wrapMap.td;if(!jQuery.support.htmlSerialize){wrapMap._default=[1,"div
      ","
      "];} +jQuery.fn.extend({text:function(text){if(jQuery.isFunction(text)){return this.each(function(i){var self=jQuery(this);self.text(text.call(this,i,self.text()));});} +if(typeof text!=="object"&&text!==undefined){return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(text));} +return jQuery.text(this);},wrapAll:function(html){if(jQuery.isFunction(html)){return this.each(function(i){jQuery(this).wrapAll(html.call(this,i));});} +if(this[0]){var wrap=jQuery(html,this[0].ownerDocument).eq(0).clone(true);if(this[0].parentNode){wrap.insertBefore(this[0]);} +wrap.map(function(){var elem=this;while(elem.firstChild&&elem.firstChild.nodeType===1){elem=elem.firstChild;} +return elem;}).append(this);} +return this;},wrapInner:function(html){if(jQuery.isFunction(html)){return this.each(function(i){jQuery(this).wrapInner(html.call(this,i));});} +return this.each(function(){var self=jQuery(this),contents=self.contents();if(contents.length){contents.wrapAll(html);}else{self.append(html);}});},wrap:function(html){return this.each(function(){jQuery(this).wrapAll(html);});},unwrap:function(){return this.parent().each(function(){if(!jQuery.nodeName(this,"body")){jQuery(this).replaceWith(this.childNodes);}}).end();},append:function(){return this.domManip(arguments,true,function(elem){if(this.nodeType===1){this.appendChild(elem);}});},prepend:function(){return this.domManip(arguments,true,function(elem){if(this.nodeType===1){this.insertBefore(elem,this.firstChild);}});},before:function(){if(this[0]&&this[0].parentNode){return this.domManip(arguments,false,function(elem){this.parentNode.insertBefore(elem,this);});}else if(arguments.length){var set=jQuery(arguments[0]);set.push.apply(set,this.toArray());return this.pushStack(set,"before",arguments);}},after:function(){if(this[0]&&this[0].parentNode){return this.domManip(arguments,false,function(elem){this.parentNode.insertBefore(elem,this.nextSibling);});}else if(arguments.length){var set=this.pushStack(this,"after",arguments);set.push.apply(set,jQuery(arguments[0]).toArray());return set;}},remove:function(selector,keepData){for(var i=0,elem;(elem=this[i])!=null;i++){if(!selector||jQuery.filter(selector,[elem]).length){if(!keepData&&elem.nodeType===1){jQuery.cleanData(elem.getElementsByTagName("*"));jQuery.cleanData([elem]);} +if(elem.parentNode){elem.parentNode.removeChild(elem);}}} +return this;},empty:function(){for(var i=0,elem;(elem=this[i])!=null;i++){if(elem.nodeType===1){jQuery.cleanData(elem.getElementsByTagName("*"));} +while(elem.firstChild){elem.removeChild(elem.firstChild);}} +return this;},clone:function(events){var ret=this.map(function(){if(!jQuery.support.noCloneEvent&&!jQuery.isXMLDoc(this)){var html=this.outerHTML,ownerDocument=this.ownerDocument;if(!html){var div=ownerDocument.createElement("div");div.appendChild(this.cloneNode(true));html=div.innerHTML;} +return jQuery.clean([html.replace(rinlinejQuery,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(rleadingWhitespace,"")],ownerDocument)[0];}else{return this.cloneNode(true);}});if(events===true){cloneCopyEvent(this,ret);cloneCopyEvent(this.find("*"),ret.find("*"));} +return ret;},html:function(value){if(value===undefined){return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(rinlinejQuery,""):null;}else if(typeof value==="string"&&!rnocache.test(value)&&(jQuery.support.leadingWhitespace||!rleadingWhitespace.test(value))&&!wrapMap[(rtagName.exec(value)||["",""])[1].toLowerCase()]){value=value.replace(rxhtmlTag,fcloseTag);try{for(var i=0,l=this.length;i0||results.cacheable||this.length>1?fragment.cloneNode(true):fragment);}} +if(scripts.length){jQuery.each(scripts,evalScript);}} +return this;function root(elem,cur){return jQuery.nodeName(elem,"table")?(elem.getElementsByTagName("tbody")[0]||elem.appendChild(elem.ownerDocument.createElement("tbody"))):elem;}}});function cloneCopyEvent(orig,ret){var i=0;ret.each(function(){if(this.nodeName!==(orig[i]&&orig[i].nodeName)){return;} +var oldData=jQuery.data(orig[i++]),curData=jQuery.data(this,oldData),events=oldData&&oldData.events;if(events){delete curData.handle;curData.events={};for(var type in events){for(var handler in events[type]){jQuery.event.add(this,type,events[type][handler],events[type][handler].data);}}}});} +function buildFragment(args,nodes,scripts){var fragment,cacheable,cacheresults,doc=(nodes&&nodes[0]?nodes[0].ownerDocument||nodes[0]:document);if(args.length===1&&typeof args[0]==="string"&&args[0].length<512&&doc===document&&!rnocache.test(args[0])&&(jQuery.support.checkClone||!rchecked.test(args[0]))){cacheable=true;cacheresults=jQuery.fragments[args[0]];if(cacheresults){if(cacheresults!==1){fragment=cacheresults;}}} +if(!fragment){fragment=doc.createDocumentFragment();jQuery.clean(args,doc,fragment,scripts);} +if(cacheable){jQuery.fragments[args[0]]=cacheresults?fragment:1;} +return{fragment:fragment,cacheable:cacheable};} +jQuery.fragments={};jQuery.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(name,original){jQuery.fn[name]=function(selector){var ret=[],insert=jQuery(selector),parent=this.length===1&&this[0].parentNode;if(parent&&parent.nodeType===11&&parent.childNodes.length===1&&insert.length===1){insert[original](this[0]);return this;}else{for(var i=0,l=insert.length;i0?this.clone(true):this).get();jQuery.fn[original].apply(jQuery(insert[i]),elems);ret=ret.concat(elems);} +return this.pushStack(ret,name,insert.selector);}};});jQuery.extend({clean:function(elems,context,fragment,scripts){context=context||document;if(typeof context.createElement==="undefined"){context=context.ownerDocument||context[0]&&context[0].ownerDocument||document;} +var ret=[];for(var i=0,elem;(elem=elems[i])!=null;i++){if(typeof elem==="number"){elem+="";} +if(!elem){continue;} +if(typeof elem==="string"&&!rhtml.test(elem)){elem=context.createTextNode(elem);}else if(typeof elem==="string"){elem=elem.replace(rxhtmlTag,fcloseTag);var tag=(rtagName.exec(elem)||["",""])[1].toLowerCase(),wrap=wrapMap[tag]||wrapMap._default,depth=wrap[0],div=context.createElement("div");div.innerHTML=wrap[1]+elem+wrap[2];while(depth--){div=div.lastChild;} +if(!jQuery.support.tbody){var hasBody=rtbody.test(elem),tbody=tag==="table"&&!hasBody?div.firstChild&&div.firstChild.childNodes:wrap[1]===""&&!hasBody?div.childNodes:[];for(var j=tbody.length-1;j>=0;--j){if(jQuery.nodeName(tbody[j],"tbody")&&!tbody[j].childNodes.length){tbody[j].parentNode.removeChild(tbody[j]);}}} +if(!jQuery.support.leadingWhitespace&&rleadingWhitespace.test(elem)){div.insertBefore(context.createTextNode(rleadingWhitespace.exec(elem)[0]),div.firstChild);} +elem=div.childNodes;} +if(elem.nodeType){ret.push(elem);}else{ret=jQuery.merge(ret,elem);}} +if(fragment){for(var i=0;ret[i];i++){if(scripts&&jQuery.nodeName(ret[i],"script")&&(!ret[i].type||ret[i].type.toLowerCase()==="text/javascript")){scripts.push(ret[i].parentNode?ret[i].parentNode.removeChild(ret[i]):ret[i]);}else{if(ret[i].nodeType===1){ret.splice.apply(ret,[i+1,0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))));} +fragment.appendChild(ret[i]);}}} +return ret;},cleanData:function(elems){var data,id,cache=jQuery.cache,special=jQuery.event.special,deleteExpando=jQuery.support.deleteExpando;for(var i=0,elem;(elem=elems[i])!=null;i++){id=elem[jQuery.expando];if(id){data=cache[id];if(data.events){for(var type in data.events){if(special[type]){jQuery.event.remove(elem,type);}else{removeEvent(elem,type,data.handle);}}} +if(deleteExpando){delete elem[jQuery.expando];}else if(elem.removeAttribute){elem.removeAttribute(jQuery.expando);} +delete cache[id];}}}});var rexclude=/z-?index|font-?weight|opacity|zoom|line-?height/i,ralpha=/alpha\([^)]*\)/,ropacity=/opacity=([^)]*)/,rfloat=/float/i,rdashAlpha=/-([a-z])/ig,rupper=/([A-Z])/g,rnumpx=/^-?\d+(?:px)?$/i,rnum=/^-?\d/,cssShow={position:"absolute",visibility:"hidden",display:"block"},cssWidth=["Left","Right"],cssHeight=["Top","Bottom"],getComputedStyle=document.defaultView&&document.defaultView.getComputedStyle,styleFloat=jQuery.support.cssFloat?"cssFloat":"styleFloat",fcamelCase=function(all,letter){return letter.toUpperCase();};jQuery.fn.css=function(name,value){return access(this,name,value,true,function(elem,name,value){if(value===undefined){return jQuery.curCSS(elem,name);} +if(typeof value==="number"&&!rexclude.test(name)){value+="px";} +jQuery.style(elem,name,value);});};jQuery.extend({style:function(elem,name,value){if(!elem||elem.nodeType===3||elem.nodeType===8){return undefined;} +if((name==="width"||name==="height")&&parseFloat(value)<0){value=undefined;} +var style=elem.style||elem,set=value!==undefined;if(!jQuery.support.opacity&&name==="opacity"){if(set){style.zoom=1;var opacity=parseInt(value,10)+""==="NaN"?"":"alpha(opacity="+value*100+")";var filter=style.filter||jQuery.curCSS(elem,"filter")||"";style.filter=ralpha.test(filter)?filter.replace(ralpha,opacity):opacity;} +return style.filter&&style.filter.indexOf("opacity=")>=0?(parseFloat(ropacity.exec(style.filter)[1])/100)+"":"";} +if(rfloat.test(name)){name=styleFloat;} +name=name.replace(rdashAlpha,fcamelCase);if(set){style[name]=value;} +return style[name];},css:function(elem,name,force,extra){if(name==="width"||name==="height"){var val,props=cssShow,which=name==="width"?cssWidth:cssHeight;function getWH(){val=name==="width"?elem.offsetWidth:elem.offsetHeight;if(extra==="border"){return;} +jQuery.each(which,function(){if(!extra){val-=parseFloat(jQuery.curCSS(elem,"padding"+this,true))||0;} +if(extra==="margin"){val+=parseFloat(jQuery.curCSS(elem,"margin"+this,true))||0;}else{val-=parseFloat(jQuery.curCSS(elem,"border"+this+"Width",true))||0;}});} +if(elem.offsetWidth!==0){getWH();}else{jQuery.swap(elem,props,getWH);} +return Math.max(0,Math.round(val));} +return jQuery.curCSS(elem,name,force);},curCSS:function(elem,name,force){var ret,style=elem.style,filter;if(!jQuery.support.opacity&&name==="opacity"&&elem.currentStyle){ret=ropacity.test(elem.currentStyle.filter||"")?(parseFloat(RegExp.$1)/100)+"":"";return ret===""?"1":ret;} +if(rfloat.test(name)){name=styleFloat;} +if(!force&&style&&style[name]){ret=style[name];}else if(getComputedStyle){if(rfloat.test(name)){name="float";} +name=name.replace(rupper,"-$1").toLowerCase();var defaultView=elem.ownerDocument.defaultView;if(!defaultView){return null;} +var computedStyle=defaultView.getComputedStyle(elem,null);if(computedStyle){ret=computedStyle.getPropertyValue(name);} +if(name==="opacity"&&ret===""){ret="1";}}else if(elem.currentStyle){var camelCase=name.replace(rdashAlpha,fcamelCase);ret=elem.currentStyle[name]||elem.currentStyle[camelCase];if(!rnumpx.test(ret)&&rnum.test(ret)){var left=style.left,rsLeft=elem.runtimeStyle.left;elem.runtimeStyle.left=elem.currentStyle.left;style.left=camelCase==="fontSize"?"1em":(ret||0);ret=style.pixelLeft+"px";style.left=left;elem.runtimeStyle.left=rsLeft;}} +return ret;},swap:function(elem,options,callback){var old={};for(var name in options){old[name]=elem.style[name];elem.style[name]=options[name];} +callback.call(elem);for(var name in options){elem.style[name]=old[name];}}});if(jQuery.expr&&jQuery.expr.filters){jQuery.expr.filters.hidden=function(elem){var width=elem.offsetWidth,height=elem.offsetHeight,skip=elem.nodeName.toLowerCase()==="tr";return width===0&&height===0&&!skip?true:width>0&&height>0&&!skip?false:jQuery.curCSS(elem,"display")==="none";};jQuery.expr.filters.visible=function(elem){return!jQuery.expr.filters.hidden(elem);};} +var jsc=now(),rscript=//gi,rselectTextarea=/select|textarea/i,rinput=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,jsre=/=\?(&|$)/,rquery=/\?/,rts=/(\?|&)_=.*?(&|$)/,rurl=/^(\w+:)?\/\/([^\/?#]+)/,r20=/%20/g,_load=jQuery.fn.load;jQuery.fn.extend({load:function(url,params,callback){if(typeof url!=="string"){return _load.call(this,url);}else if(!this.length){return this;} +var off=url.indexOf(" ");if(off>=0){var selector=url.slice(off,url.length);url=url.slice(0,off);} +var type="GET";if(params){if(jQuery.isFunction(params)){callback=params;params=null;}else if(typeof params==="object"){params=jQuery.param(params,jQuery.ajaxSettings.traditional);type="POST";}} +var self=this;jQuery.ajax({url:url,type:type,dataType:"html",data:params,complete:function(res,status){if(status==="success"||status==="notmodified"){self.html(selector?jQuery("
      ").append(res.responseText.replace(rscript,"")).find(selector):res.responseText);} +if(callback){self.each(callback,[res.responseText,status,res]);}}});return this;},serialize:function(){return jQuery.param(this.serializeArray());},serializeArray:function(){return this.map(function(){return this.elements?jQuery.makeArray(this.elements):this;}).filter(function(){return this.name&&!this.disabled&&(this.checked||rselectTextarea.test(this.nodeName)||rinput.test(this.type));}).map(function(i,elem){var val=jQuery(this).val();return val==null?null:jQuery.isArray(val)?jQuery.map(val,function(val,i){return{name:elem.name,value:val};}):{name:elem.name,value:val};}).get();}});jQuery.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(i,o){jQuery.fn[o]=function(f){return this.bind(o,f);};});jQuery.extend({get:function(url,data,callback,type){if(jQuery.isFunction(data)){type=type||callback;callback=data;data=null;} +return jQuery.ajax({type:"GET",url:url,data:data,success:callback,dataType:type});},getScript:function(url,callback){return jQuery.get(url,null,callback,"script");},getJSON:function(url,data,callback){return jQuery.get(url,data,callback,"json");},post:function(url,data,callback,type){if(jQuery.isFunction(data)){type=type||callback;callback=data;data={};} +return jQuery.ajax({type:"POST",url:url,data:data,success:callback,dataType:type});},ajaxSetup:function(settings){jQuery.extend(jQuery.ajaxSettings,settings);},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:window.XMLHttpRequest&&(window.location.protocol!=="file:"||!window.ActiveXObject)?function(){return new window.XMLHttpRequest();}:function(){try{return new window.ActiveXObject("Microsoft.XMLHTTP");}catch(e){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(origSettings){var s=jQuery.extend(true,{},jQuery.ajaxSettings,origSettings);var jsonp,status,data,callbackContext=origSettings&&origSettings.context||s,type=s.type.toUpperCase();if(s.data&&s.processData&&typeof s.data!=="string"){s.data=jQuery.param(s.data,s.traditional);} +if(s.dataType==="jsonp"){if(type==="GET"){if(!jsre.test(s.url)){s.url+=(rquery.test(s.url)?"&":"?")+(s.jsonp||"callback")+"=?";}}else if(!s.data||!jsre.test(s.data)){s.data=(s.data?s.data+"&":"")+(s.jsonp||"callback")+"=?";} +s.dataType="json";} +if(s.dataType==="json"&&(s.data&&jsre.test(s.data)||jsre.test(s.url))){jsonp=s.jsonpCallback||("jsonp"+jsc++);if(s.data){s.data=(s.data+"").replace(jsre,"="+jsonp+"$1");} +s.url=s.url.replace(jsre,"="+jsonp+"$1");s.dataType="script";window[jsonp]=window[jsonp]||function(tmp){data=tmp;success();complete();window[jsonp]=undefined;try{delete window[jsonp];}catch(e){} +if(head){head.removeChild(script);}};} +if(s.dataType==="script"&&s.cache===null){s.cache=false;} +if(s.cache===false&&type==="GET"){var ts=now();var ret=s.url.replace(rts,"$1_="+ts+"$2");s.url=ret+((ret===s.url)?(rquery.test(s.url)?"&":"?")+"_="+ts:"");} +if(s.data&&type==="GET"){s.url+=(rquery.test(s.url)?"&":"?")+s.data;} +if(s.global&&!jQuery.active++){jQuery.event.trigger("ajaxStart");} +var parts=rurl.exec(s.url),remote=parts&&(parts[1]&&parts[1]!==location.protocol||parts[2]!==location.host);if(s.dataType==="script"&&type==="GET"&&remote){var head=document.getElementsByTagName("head")[0]||document.documentElement;var script=document.createElement("script");script.src=s.url;if(s.scriptCharset){script.charset=s.scriptCharset;} +if(!jsonp){var done=false;script.onload=script.onreadystatechange=function(){if(!done&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){done=true;success();complete();script.onload=script.onreadystatechange=null;if(head&&script.parentNode){head.removeChild(script);}}};} +head.insertBefore(script,head.firstChild);return undefined;} +var requestDone=false;var xhr=s.xhr();if(!xhr){return;} +if(s.username){xhr.open(type,s.url,s.async,s.username,s.password);}else{xhr.open(type,s.url,s.async);} +try{if(s.data||origSettings&&origSettings.contentType){xhr.setRequestHeader("Content-Type",s.contentType);} +if(s.ifModified){if(jQuery.lastModified[s.url]){xhr.setRequestHeader("If-Modified-Since",jQuery.lastModified[s.url]);} +if(jQuery.etag[s.url]){xhr.setRequestHeader("If-None-Match",jQuery.etag[s.url]);}} +if(!remote){xhr.setRequestHeader("X-Requested-With","XMLHttpRequest");} +xhr.setRequestHeader("Accept",s.dataType&&s.accepts[s.dataType]?s.accepts[s.dataType]+", */*":s.accepts._default);}catch(e){} +if(s.beforeSend&&s.beforeSend.call(callbackContext,xhr,s)===false){if(s.global&&!--jQuery.active){jQuery.event.trigger("ajaxStop");} +xhr.abort();return false;} +if(s.global){trigger("ajaxSend",[xhr,s]);} +var onreadystatechange=xhr.onreadystatechange=function(isTimeout){if(!xhr||xhr.readyState===0||isTimeout==="abort"){if(!requestDone){complete();} +requestDone=true;if(xhr){xhr.onreadystatechange=jQuery.noop;}}else if(!requestDone&&xhr&&(xhr.readyState===4||isTimeout==="timeout")){requestDone=true;xhr.onreadystatechange=jQuery.noop;status=isTimeout==="timeout"?"timeout":!jQuery.httpSuccess(xhr)?"error":s.ifModified&&jQuery.httpNotModified(xhr,s.url)?"notmodified":"success";var errMsg;if(status==="success"){try{data=jQuery.httpData(xhr,s.dataType,s);}catch(err){status="parsererror";errMsg=err;}} +if(status==="success"||status==="notmodified"){if(!jsonp){success();}}else{jQuery.handleError(s,xhr,status,errMsg);} +complete();if(isTimeout==="timeout"){xhr.abort();} +if(s.async){xhr=null;}}};try{var oldAbort=xhr.abort;xhr.abort=function(){if(xhr){oldAbort.call(xhr);} +onreadystatechange("abort");};}catch(e){} +if(s.async&&s.timeout>0){setTimeout(function(){if(xhr&&!requestDone){onreadystatechange("timeout");}},s.timeout);} +try{xhr.send(type==="POST"||type==="PUT"||type==="DELETE"?s.data:null);}catch(e){jQuery.handleError(s,xhr,null,e);complete();} +if(!s.async){onreadystatechange();} +function success(){if(s.success){s.success.call(callbackContext,data,status,xhr);} +if(s.global){trigger("ajaxSuccess",[xhr,s]);}} +function complete(){if(s.complete){s.complete.call(callbackContext,xhr,status);} +if(s.global){trigger("ajaxComplete",[xhr,s]);} +if(s.global&&!--jQuery.active){jQuery.event.trigger("ajaxStop");}} +function trigger(type,args){(s.context?jQuery(s.context):jQuery.event).trigger(type,args);} +return xhr;},handleError:function(s,xhr,status,e){if(s.error){s.error.call(s.context||s,xhr,status,e);} +if(s.global){(s.context?jQuery(s.context):jQuery.event).trigger("ajaxError",[xhr,s,e]);}},active:0,httpSuccess:function(xhr){try{return!xhr.status&&location.protocol==="file:"||(xhr.status>=200&&xhr.status<300)||xhr.status===304||xhr.status===1223||xhr.status===0;}catch(e){} +return false;},httpNotModified:function(xhr,url){var lastModified=xhr.getResponseHeader("Last-Modified"),etag=xhr.getResponseHeader("Etag");if(lastModified){jQuery.lastModified[url]=lastModified;} +if(etag){jQuery.etag[url]=etag;} +return xhr.status===304||xhr.status===0;},httpData:function(xhr,type,s){var ct=xhr.getResponseHeader("content-type")||"",xml=type==="xml"||!type&&ct.indexOf("xml")>=0,data=xml?xhr.responseXML:xhr.responseText;if(xml&&data.documentElement.nodeName==="parsererror"){jQuery.error("parsererror");} +if(s&&s.dataFilter){data=s.dataFilter(data,type);} +if(typeof data==="string"){if(type==="json"||!type&&ct.indexOf("json")>=0){data=jQuery.parseJSON(data);}else if(type==="script"||!type&&ct.indexOf("javascript")>=0){jQuery.globalEval(data);}} +return data;},param:function(a,traditional){var s=[];if(traditional===undefined){traditional=jQuery.ajaxSettings.traditional;} +if(jQuery.isArray(a)||a.jquery){jQuery.each(a,function(){add(this.name,this.value);});}else{for(var prefix in a){buildParams(prefix,a[prefix]);}} +return s.join("&").replace(r20,"+");function buildParams(prefix,obj){if(jQuery.isArray(obj)){jQuery.each(obj,function(i,v){if(traditional||/\[\]$/.test(prefix)){add(prefix,v);}else{buildParams(prefix+"["+(typeof v==="object"||jQuery.isArray(v)?i:"")+"]",v);}});}else if(!traditional&&obj!=null&&typeof obj==="object"){jQuery.each(obj,function(k,v){buildParams(prefix+"["+k+"]",v);});}else{add(prefix,obj);}} +function add(key,value){value=jQuery.isFunction(value)?value():value;s[s.length]=encodeURIComponent(key)+"="+encodeURIComponent(value);}}});var elemdisplay={},rfxtypes=/toggle|show|hide/,rfxnum=/^([+-]=)?([\d+-.]+)(.*)$/,timerId,fxAttrs=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];jQuery.fn.extend({show:function(speed,callback){if(speed||speed===0){return this.animate(genFx("show",3),speed,callback);}else{for(var i=0,l=this.length;i").appendTo("body");display=elem.css("display");if(display==="none"){display="block";} +elem.remove();elemdisplay[nodeName]=display;} +jQuery.data(this[i],"olddisplay",display);}} +for(var j=0,k=this.length;j=0;i--){if(timers[i].elem===this){if(gotoEnd){timers[i](true);} +timers.splice(i,1);}}});if(!gotoEnd){this.dequeue();} +return this;}});jQuery.each({slideDown:genFx("show",1),slideUp:genFx("hide",1),slideToggle:genFx("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(name,props){jQuery.fn[name]=function(speed,callback){return this.animate(props,speed,callback);};});jQuery.extend({speed:function(speed,easing,fn){var opt=speed&&typeof speed==="object"?speed:{complete:fn||!fn&&easing||jQuery.isFunction(speed)&&speed,duration:speed,easing:fn&&easing||easing&&!jQuery.isFunction(easing)&&easing};opt.duration=jQuery.fx.off?0:typeof opt.duration==="number"?opt.duration:jQuery.fx.speeds[opt.duration]||jQuery.fx.speeds._default;opt.old=opt.complete;opt.complete=function(){if(opt.queue!==false){jQuery(this).dequeue();} +if(jQuery.isFunction(opt.old)){opt.old.call(this);}};return opt;},easing:{linear:function(p,n,firstNum,diff){return firstNum+diff*p;},swing:function(p,n,firstNum,diff){return((-Math.cos(p*Math.PI)/2)+0.5)*diff+firstNum;}},timers:[],fx:function(elem,options,prop){this.options=options;this.elem=elem;this.prop=prop;if(!options.orig){options.orig={};}}});jQuery.fx.prototype={update:function(){if(this.options.step){this.options.step.call(this.elem,this.now,this);} +(jQuery.fx.step[this.prop]||jQuery.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style){this.elem.style.display="block";}},cur:function(force){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null)){return this.elem[this.prop];} +var r=parseFloat(jQuery.css(this.elem,this.prop,force));return r&&r>-10000?r:parseFloat(jQuery.curCSS(this.elem,this.prop))||0;},custom:function(from,to,unit){this.startTime=now();this.start=from;this.end=to;this.unit=unit||this.unit||"px";this.now=this.start;this.pos=this.state=0;var self=this;function t(gotoEnd){return self.step(gotoEnd);} +t.elem=this.elem;if(t()&&jQuery.timers.push(t)&&!timerId){timerId=setInterval(jQuery.fx.tick,13);}},show:function(){this.options.orig[this.prop]=jQuery.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());jQuery(this.elem).show();},hide:function(){this.options.orig[this.prop]=jQuery.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0);},step:function(gotoEnd){var t=now(),done=true;if(gotoEnd||t>=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var i in this.options.curAnim){if(this.options.curAnim[i]!==true){done=false;}} +if(done){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;var old=jQuery.data(this.elem,"olddisplay");this.elem.style.display=old?old:this.options.display;if(jQuery.css(this.elem,"display")==="none"){this.elem.style.display="block";}} +if(this.options.hide){jQuery(this.elem).hide();} +if(this.options.hide||this.options.show){for(var p in this.options.curAnim){jQuery.style(this.elem,p,this.options.orig[p]);}} +this.options.complete.call(this.elem);} +return false;}else{var n=t-this.startTime;this.state=n/this.options.duration;var specialEasing=this.options.specialEasing&&this.options.specialEasing[this.prop];var defaultEasing=this.options.easing||(jQuery.easing.swing?"swing":"linear");this.pos=jQuery.easing[specialEasing||defaultEasing](this.state,n,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update();} +return true;}};jQuery.extend(jQuery.fx,{tick:function(){var timers=jQuery.timers;for(var i=0;i
      ";jQuery.extend(container.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"});container.innerHTML=html;body.insertBefore(container,body.firstChild);innerDiv=container.firstChild;checkDiv=innerDiv.firstChild;td=innerDiv.nextSibling.firstChild.firstChild;this.doesNotAddBorder=(checkDiv.offsetTop!==5);this.doesAddBorderForTableAndCells=(td.offsetTop===5);checkDiv.style.position="fixed",checkDiv.style.top="20px";this.supportsFixedPosition=(checkDiv.offsetTop===20||checkDiv.offsetTop===15);checkDiv.style.position=checkDiv.style.top="";innerDiv.style.overflow="hidden",innerDiv.style.position="relative";this.subtractsBorderForOverflowNotVisible=(checkDiv.offsetTop===-5);this.doesNotIncludeMarginInBodyOffset=(body.offsetTop!==bodyMarginTop);body.removeChild(container);body=container=innerDiv=checkDiv=table=td=null;jQuery.offset.initialize=jQuery.noop;},bodyOffset:function(body){var top=body.offsetTop,left=body.offsetLeft;jQuery.offset.initialize();if(jQuery.offset.doesNotIncludeMarginInBodyOffset){top+=parseFloat(jQuery.curCSS(body,"marginTop",true))||0;left+=parseFloat(jQuery.curCSS(body,"marginLeft",true))||0;} +return{top:top,left:left};},setOffset:function(elem,options,i){if(/static/.test(jQuery.curCSS(elem,"position"))){elem.style.position="relative";} +var curElem=jQuery(elem),curOffset=curElem.offset(),curTop=parseInt(jQuery.curCSS(elem,"top",true),10)||0,curLeft=parseInt(jQuery.curCSS(elem,"left",true),10)||0;if(jQuery.isFunction(options)){options=options.call(elem,i,curOffset);} +var props={top:(options.top-curOffset.top)+curTop,left:(options.left-curOffset.left)+curLeft};if("using"in options){options.using.call(elem,props);}else{curElem.css(props);}}};jQuery.fn.extend({position:function(){if(!this[0]){return null;} +var elem=this[0],offsetParent=this.offsetParent(),offset=this.offset(),parentOffset=/^body|html$/i.test(offsetParent[0].nodeName)?{top:0,left:0}:offsetParent.offset();offset.top-=parseFloat(jQuery.curCSS(elem,"marginTop",true))||0;offset.left-=parseFloat(jQuery.curCSS(elem,"marginLeft",true))||0;parentOffset.top+=parseFloat(jQuery.curCSS(offsetParent[0],"borderTopWidth",true))||0;parentOffset.left+=parseFloat(jQuery.curCSS(offsetParent[0],"borderLeftWidth",true))||0;return{top:offset.top-parentOffset.top,left:offset.left-parentOffset.left};},offsetParent:function(){return this.map(function(){var offsetParent=this.offsetParent||document.body;while(offsetParent&&(!/^body|html$/i.test(offsetParent.nodeName)&&jQuery.css(offsetParent,"position")==="static")){offsetParent=offsetParent.offsetParent;} +return offsetParent;});}});jQuery.each(["Left","Top"],function(i,name){var method="scroll"+name;jQuery.fn[method]=function(val){var elem=this[0],win;if(!elem){return null;} +if(val!==undefined){return this.each(function(){win=getWindow(this);if(win){win.scrollTo(!i?val:jQuery(win).scrollLeft(),i?val:jQuery(win).scrollTop());}else{this[method]=val;}});}else{win=getWindow(elem);return win?("pageXOffset"in win)?win[i?"pageYOffset":"pageXOffset"]:jQuery.support.boxModel&&win.document.documentElement[method]||win.document.body[method]:elem[method];}};});function getWindow(elem){return("scrollTo"in elem&&elem.document)?elem:elem.nodeType===9?elem.defaultView||elem.parentWindow:false;} +jQuery.each(["Height","Width"],function(i,name){var type=name.toLowerCase();jQuery.fn["inner"+name]=function(){return this[0]?jQuery.css(this[0],type,false,"padding"):null;};jQuery.fn["outer"+name]=function(margin){return this[0]?jQuery.css(this[0],type,false,margin?"margin":"border"):null;};jQuery.fn[type]=function(size){var elem=this[0];if(!elem){return size==null?null:this;} +if(jQuery.isFunction(size)){return this.each(function(i){var self=jQuery(this);self[type](size.call(this,i,self[type]()));});} +return("scrollTo"in elem&&elem.document)?elem.document.compatMode==="CSS1Compat"&&elem.document.documentElement["client"+name]||elem.document.body["client"+name]:(elem.nodeType===9)?Math.max(elem.documentElement["client"+name],elem.body["scroll"+name],elem.documentElement["scroll"+name],elem.body["offset"+name],elem.documentElement["offset"+name]):size===undefined?jQuery.css(elem,type):this.css(type,typeof size==="string"?size:size+"px");};});window.jQuery=window.$=jQuery;})(window); \ No newline at end of file diff --git a/v2/dotclear/admin/js/jquery/jquery.modal.js b/v2/dotclear/admin/js/jquery/jquery.modal.js new file mode 100644 index 0000000..03703e9 --- /dev/null +++ b/v2/dotclear/admin/js/jquery/jquery.modal.js @@ -0,0 +1,17 @@ + +(function($){if(/^1\.(0|1)\./.test($.fn.jquery)||/^1\.2\.(0|1|2|3|4|5)/.test($.fn.jquery)){throw('Modal requieres jQuery v1.2.6 or later. You are using v'+$.fn.jquery);return;} +$.modal=function(data,params){this.params=$.extend(this.params,params);return this.build(data);};$.modal.version='1.0';$.modal.prototype={params:{width:null,height:null,speed:300,opacity:0.9,loader_img:'loader.gif',loader_txt:'loading...',close_img:'close.png',close_txt:'close',on_close:function(){}},ctrl:{box:$(),loader:$(),overlay:$('
      '),hidden:$()},build:function(data){this.ctrl.loader=$('
      '+this.params.loader_txt+'
      ');this.addOverlay();var size=this.getBoxSize(this.ctrl.loading);this.ctrl.box=this.getBox(this.ctrl.loading,{top:Math.round($(window).height()/2+$(window).scrollTop()-size.h/2),left:Math.round($(window).width()/2+$(window).scrollLeft()-size.w/2),visibility:'hidden'});this.ctrl.overlay.after(this.ctrl.box);if(data!=undefined){this.updateBox(data);this.data=data;} +return this;},updateBox:function(data,fn){var This=this;this.hideCloser();fn=$.isFunction(fn)?fn:function(){};var content=$('div.jq-modal-content',this.ctrl.box);content.empty().append(this.ctrl.loader);var size=this.getBoxSize(data,this.params.width,this.params.height);var top=Math.round($(window).height()/2+$(window).scrollTop()-size.h/2);var left=Math.round($(window).width()/2+$(window).scrollLeft()-size.w/2);this.ctrl.box.css('visibility','visible').animate({top:top<0?0:top,left:left<0?0:left,width:size.w,height:size.h},this.params.speed,function(){This.setContentSize(content,This.params.width,This.params.height);content.empty().append(data).css('opacity',0).fadeTo(This.params.speed,1,function(){fn.call(This,content);});This.showCloser();});},getBox:function(data,css,content_w,content_h){var box=$('
      '+'
      '+'
      ').css($.extend({position:'absolute',top:0,left:0,zIndex:100},css));if(data!=undefined){$('div.jq-modal-content',box).append(data);} +this.setContentSize($('div.jq-modal-content',box),content_w,content_h);return box;},getBoxSize:function(data,content_w,content_h){var box=this.getBox(data,{visibility:'hidden'},content_w,content_h);this.ctrl.overlay.after(box);var size={w:box.width(),h:box.height()};box.remove();box=null;return size;},setContentSize:function(content,w,h){content.css({width:w>0?w:'auto',height:h>0?h:'auto'});},showCloser:function(){if($('div.jq-modal-closer',this.ctrl.box).length>0){$('div.jq-modal-closer',this.ctrl.box).show();return;} +$('div.jq-modal-container',this.ctrl.box).append('');var This=this;var close=$('div.jq-modal-closer a',this.ctrl.box) +close.css({background:'transparent url('+this.params.close_img+') no-repeat'}).click(function(){This.removeOverlay();return false;});if(document.all){close[0].runtimeStyle.filter='progid:DXImageTransform.Microsoft.AlphaImageLoader(src="'+this.params.close_img+'", sizingMethod="crop")';close[0].runtimeStyle.backgroundImage="none"}},hideCloser:function(){$('div.jq-modal-closer',this.ctrl.box).hide();},addOverlay:function(){var This=this;if(document.all){this.ctrl.hidden=$('select:visible, object:visible, embed:visible').css('visibility','hidden');} +this.ctrl.overlay.css({backgroundColor:'#000',position:'absolute',top:0,left:0,zIndex:90,opacity:this.params.opacity}).appendTo('body').dblclick(function(){This.removeOverlay();});this.resizeOverlay({data:this.ctrl});$(window).bind('resize.modal',this.ctrl,this.resizeOverlay);$(document).bind('keypress.modal',this,this.keyRemove);},resizeOverlay:function(e){e.data.overlay.css({width:$(window).width(),height:$(document).height()});if(e.data.box.parents('body').length>0){var top=Math.round($(window).height()/2+$(window).scrollTop()-e.data.box.height()/2);var left=Math.round($(window).width()/2+$(window).scrollLeft()-e.data.box.width()/2);e.data.box.css({top:top<0?0:top,left:left<0?0:left});}},keyRemove:function(e){if(e.keyCode==27){e.data.removeOverlay();} +return true;},removeOverlay:function(){$(window).unbind('resize.modal');$(document).unbind('keypress');this.params.on_close.apply(this);this.ctrl.overlay.remove();this.ctrl.hidden.css('visibility','visible');this.ctrl.box.remove();this.ctrl.box=$();}};})(jQuery);(function($){$.fn.modalImages=function(params){params=$.extend(this.params,params);var links=new Array();this.each(function(){if($(this).attr('href')==''||$(this).attr('href')==undefined||$(this).attr('href')=='#'){return false;} +var index=links.length;links.push($(this));$(this).click(function(){new $.modalImages(index,links,params);return false;});return true;});return this;};$.modalImages=function(index,links,params){this.links=links;this.modal=new $.modal(null,params);this.showImage(index);};$.modalImages.prototype={params:{prev_txt:'previous',next_txt:'next',prev_img:'prev.png',next_img:'next.png',blank_img:'blank.gif'},showImage:function(index){var This=this;$(document).unbind('keypress.modalImage');if(this.links[index]==undefined){this.modal.removeOverlay();} +var link=this.links[index];var modal=this.modal;var res=$('
      ');res.append('');var thumb=$('img:first',link);if(thumb.length>0&&thumb.attr('title')){res.append(''+thumb.attr('title')+'');}else if(link.attr('title')){res.append(''+link.attr('title')+'');} +if(index!=0){$('prev').appendTo(res);} +if(index+1next').appendTo(res);} +var img=new Image();if(this.modal.ctrl.box.css('visibility')=='visible'){$('div.jq-modal-content',this.modal.ctrl.box).empty().append(this.modal.ctrl.loader);}else{this.modal.updateBox(this.modal.ctrl.loader);} +img.onload=function(){modal.updateBox(res,function(){var Img=$('div.jq-modal-content img',this.ctrl.box);This.navBtnStyle($('a.jq-modal-next',this.ctrl.box),true).css('height',Img.height()).bind('click',index+1,navClick);This.navBtnStyle($('a.jq-modal-prev',this.ctrl.box),false).css('height',Img.height()).bind('click',index-1,navClick);Img.click(function(){This.modal.removeOverlay();});$(document).bind('keypress.modalImage',navKey);});this.onload=function(){};};img.src=link.attr('href');var navClick=function(e){This.showImage(e.data);return false;};var navKey=function(e){var key=String.fromCharCode(e.which).toLowerCase();if((key=='n'||e.keyCode==39)&&index+1').css({border:'none',width:w,height:h});return new $.modal(iframe);};$.fn.modalWeb=function(w,h){this.click(function(){if(this.href!=undefined){$.modalWeb(this.href,w,h);} +return false;});};})(jQuery); \ No newline at end of file diff --git a/v2/dotclear/admin/js/jquery/jquery.pageTabs.js b/v2/dotclear/admin/js/jquery/jquery.pageTabs.js new file mode 100644 index 0000000..5cca2c3 --- /dev/null +++ b/v2/dotclear/admin/js/jquery/jquery.pageTabs.js @@ -0,0 +1,4 @@ + +jQuery.pageTabs=function(start_tab,settings){return new jQuery._pageTabs(start_tab,settings);};jQuery._pageTabs=function(start_tab,settings){var defaults={className:'multi-part',listClassName:'part-tabs',breakerClassName:'clear'};var index=start_tab?start_tab:0;this.params=jQuery.extend(defaults,settings);this.divs=jQuery('div.'+this.params.className);this.createList();this.showDiv(index);};jQuery._pageTabs.prototype={items:new Array(),createList:function(){if(this.divs.length<=0){return;} +this.block=document.createElement('div');this.block.className=this.params.listClassName;this.list=document.createElement('ul');this.block.appendChild(this.list);var li,a;var This=this;var i=0;jQuery('.'+this.params.className).each(function(){if(this.tagName=="DIV"){li=document.createElement('li');a=document.createElement('a');a.appendChild(document.createTextNode(this.title));this.title='';a.href='#';a.fn=This.showDiv;a.index=this.id||i;a.obj=This;jQuery(a).click(function(){this.fn.call(this.obj,this.index);return false;});li.appendChild(a);This.list.appendChild(li);This.items[i]=li;i++;}else{li=document.createElement('li');li.className=This.params.listClassName+'-link';li.appendChild(this);This.list.appendChild(li);}});this.breaker=document.createElement('br');this.breaker.className=this.params.breakerClassName;jQuery(this.divs.get(0)).before(this.block);jQuery(this.block).after(this.breaker);},showDiv:function(index){var This=this;var i=0;var to_trigger=null;this.divs.each(function(){if((this.id!=''&&this.id==index)||i==index){jQuery(this).show(0,positionFooter);This.items[i].className=This.params.listClassName+'-active';to_trigger=i;}else{jQuery(this).hide(0,positionFooter);This.items[i].className='';} +i++;});if(to_trigger!=null){jQuery(this.divs[to_trigger]).onetabload();jQuery(this.divs[to_trigger]).tabload();}}};jQuery.fn.tabload=function(f){this.each(function(){if(f){chainHandler(this,'tabload',f)}else{var h=this.tabload;if(h){h.apply(this);}}});return this;};jQuery.fn.onetabload=function(f){this.each(function(){if(f){chainHandler(this,'onetabload',f);}else{var h=this.onetabload;if(h!=null){h.apply(this);this.onetabload=null;}}});return this;}; \ No newline at end of file diff --git a/v2/dotclear/admin/js/jsToolBar/jsToolBar.dotclear.js b/v2/dotclear/admin/js/jsToolBar/jsToolBar.dotclear.js new file mode 100644 index 0000000..83dd320 --- /dev/null +++ b/v2/dotclear/admin/js/jsToolBar/jsToolBar.dotclear.js @@ -0,0 +1,35 @@ + +jsToolBar.prototype.elements.link.data={};jsToolBar.prototype.elements.link.fncall={};jsToolBar.prototype.elements.link.open_url='popup_link.php';jsToolBar.prototype.elements.link.popup=function(args){window.the_toolbar=this;args=args||'';this.elements.link.data={};var url=this.elements.link.open_url+args;var p_win=window.open(url,'dc_popup','alwaysRaised=yes,dependent=yes,toolbar=yes,height=420,width=520,'+'menubar=no,resizable=yes,scrollbars=yes,status=no');};jsToolBar.prototype.elements.link.fn.wiki=function(){this.elements.link.popup.call(this,'?hreflang='+this.elements.link.default_hreflang);};jsToolBar.prototype.elements.link.fncall.wiki=function(){var data=this.elements.link.data;if(data.href==''){return;} +var etag='|'+data.href;if(data.hreflang){etag+='|'+data.hreflang;} +if(data.title){if(!data.hreflang){etag+='|';} +etag+='|'+data.title;} +if(data.content){this.encloseSelection('['+data.content,etag+']');}else{this.encloseSelection('[',etag+']');}};jsToolBar.prototype.elements.link.fn.xhtml=function(){this.elements.link.popup.call(this,'?hreflang='+this.elements.link.default_hreflang);};jsToolBar.prototype.elements.link.fncall.xhtml=function(){var data=this.elements.link.data;if(data.href==''){return;} +var stag='','>').replace('<','<').replace('"','"')+'"';} +res+=' />';if(d.link){var ltitle=(alt)?' title="'+alt.replace('&','&').replace('>','>').replace('<','<').replace('"','"')+'"':'';res=''+res+'';} +return res;});};jsToolBar.prototype.elements.img.fn.wysiwyg=function(){var src=this.elements.img.prompt.call(this);if(!src){return;} +var img=this.iwin.document.createElement('img');img.src=src;img.setAttribute('alt',this.getSelectedText());this.insertNode(img);};jsToolBar.prototype.elements.img_select.fn.wysiwyg=function(){this.elements.img_select.popup.call(this);};jsToolBar.prototype.elements.img_select.fncall.wysiwyg=function(){var d=this.elements.img_select.data;var alt=(this.getSelectedText())?this.getSelectedText():d.title;if(d.src==undefined){return;} +var img=this.iwin.document.createElement('img');img.src=d.src;img.setAttribute('alt',alt);if(d.alignment=='left'){if(img.style.styleFloat!=undefined){img.style.styleFloat='left';}else{img.style.cssFloat='left';} +img.style.marginTop=0;img.style.marginRight='1em';img.style.marginBottom='1em';img.style.marginLeft=0;}else if(d.alignment=='right'){if(img.style.styleFloat!=undefined){img.style.styleFloat='right';}else{img.style.cssFloat='right';} +img.style.marginTop=0;img.style.marginRight=0;img.style.marginBottom='1em';img.style.marginLeft='1em';}else if(d.alignment=='center'){img.style.marginTop=0;img.style.marginRight='auto';img.style.marginBottom=0;img.style.marginLeft='auto';img.style.display='block';} +if(d.description){img.setAttribute('title',d.description);} +if(d.link){var a=this.iwin.document.createElement('a');a.href=d.url;if(alt){a.setAttribute('title',alt);} +a.appendChild(img);this.insertNode(a);}else{this.insertNode(img);}};jsToolBar.prototype.elements.mp3_insert={fncall:{},data:{}};jsToolBar.prototype.elements.mp3_insert.fncall.wiki=function(){var d=this.elements.mp3_insert.data;if(d.player==undefined){return;} +this.encloseSelection('','',function(str){return'\n///html\n'+d.player+'///\n';});};jsToolBar.prototype.elements.mp3_insert.fncall.xhtml=function(){var d=this.elements.mp3_insert.data;if(d.player==undefined){return;} +this.encloseSelection('','',function(str){return'\n'+d.player+'\n';});};jsToolBar.prototype.elements.mp3_insert.fncall.wysiwyg=function(){return;};jsToolBar.prototype.elements.flv_insert={fncall:{},data:{}};jsToolBar.prototype.elements.flv_insert.fncall.wiki=function(){var d=this.elements.flv_insert.data;if(d.player==undefined){return;} +this.encloseSelection('','',function(str){return'\n///html\n'+d.player+'///\n';});};jsToolBar.prototype.elements.flv_insert.fncall.xhtml=function(){var d=this.elements.flv_insert.data;if(d.player==undefined){return;} +this.encloseSelection('','',function(str){return'\n'+d.player+'\n';});};jsToolBar.prototype.elements.flv_insert.fncall.wysiwyg=function(){return;};jsToolBar.prototype.elements.post_link={type:'button',title:'Link to an entry',fn:{},open_url:'popup_posts.php',data:{},popup:function(){window.the_toolbar=this;this.elements.img_select.data={};var p_win=window.open(this.elements.post_link.open_url,'dc_popup','alwaysRaised=yes,dependent=yes,toolbar=yes,height=500,width=760,'+'menubar=no,resizable=yes,scrollbars=yes,status=no');}};jsToolBar.prototype.elements.post_link.fn.wiki=function(){this.elements.post_link.popup.call(this);};jsToolBar.prototype.elements.post_link.fn.xhtml=function(){this.elements.post_link.popup.call(this);};jsToolBar.prototype.elements.post_link.fn.wysiwyg=function(){this.elements.post_link.popup.call(this);};jsToolBar.prototype.elements.space3={type:'space'}; \ No newline at end of file diff --git a/v2/dotclear/admin/js/jsToolBar/jsToolBar.js b/v2/dotclear/admin/js/jsToolBar/jsToolBar.js new file mode 100644 index 0000000..091df72 --- /dev/null +++ b/v2/dotclear/admin/js/jsToolBar/jsToolBar.js @@ -0,0 +1,29 @@ + +function jsToolBar(textarea){if(!document.createElement){return;} +if(!textarea){return;} +if((typeof(document["selection"])=="undefined")&&(typeof(textarea["setSelectionRange"])=="undefined")){return;} +this.textarea=textarea;this.editor=document.createElement('div');this.editor.className='jstEditor';this.textarea.parentNode.insertBefore(this.editor,this.textarea);this.editor.appendChild(this.textarea);this.toolbar=document.createElement("div");this.toolbar.className='jstElements';this.editor.parentNode.insertBefore(this.toolbar,this.editor);if(navigator.appName=='Microsoft Internet Explorer') +{if(this.editor.addEventListener) +{this.handle=document.createElement('div');this.handle.className='jstHandle';var dragStart=this.resizeDragStart;var This=this;this.handle.addEventListener('mousedown',function(event){dragStart.call(This,event);},false);this.editor.parentNode.insertBefore(this.handle,this.editor.nextSibling);}} +this.context=null;this.toolNodes={};};function jsButton(title,fn,scope,className){this.title=title||null;this.fn=fn||function(){};this.scope=scope||null;this.className=className||null;};jsButton.prototype.draw=function(){if(!this.scope)return null;var button=document.createElement('button');button.setAttribute('type','button');if(this.className)button.className=this.className;button.title=this.title;var span=document.createElement('span');span.appendChild(document.createTextNode(this.title));button.appendChild(span);if(this.icon!=undefined){button.style.backgroundImage='url('+this.icon+')';} +if(typeof(this.fn)=='function'){var This=this;button.onclick=function(){try{This.fn.apply(This.scope,arguments)}catch(e){}return false;};} +return button;};function jsSpace(id){this.id=id||null;this.width=null;};jsSpace.prototype.draw=function(){var span=document.createElement('span');if(this.id)span.id=this.id;span.appendChild(document.createTextNode(String.fromCharCode(160)));span.className='jstSpacer';if(this.width)span.style.marginRight=this.width+'px';return span;};function jsCombo(title,options,scope,fn,className){this.title=title||null;this.options=options||null;this.scope=scope||null;this.fn=fn||function(){};this.className=className||null;};jsCombo.prototype.draw=function(){if(!this.scope||!this.options)return null;var select=document.createElement('select');if(this.className)select.className=className;select.title=this.title;for(var o in this.options){var option=document.createElement('option');option.value=o;option.appendChild(document.createTextNode(this.options[o]));select.appendChild(option);} +var This=this;select.onchange=function(){try{This.fn.call(This.scope,this.value);}catch(e){alert(e);} +return false;};return select;};jsToolBar.prototype={base_url:'',mode:'xhtml',elements:{},getMode:function(){return this.mode;},setMode:function(mode){this.mode=mode||'xhtml';},switchMode:function(mode){mode=mode||'xhtml';this.draw(mode);},button:function(toolName){var tool=this.elements[toolName];if(typeof tool.fn[this.mode]!='function')return null;var b=new jsButton(tool.title,tool.fn[this.mode],this,'jstb_'+toolName);if(tool.icon!=undefined){b.icon=tool.icon;} +return b;},space:function(toolName){var tool=new jsSpace(toolName);if(this.elements[toolName].width!==undefined){tool.width=this.elements[toolName].width;} +return tool;},combo:function(toolName){var tool=this.elements[toolName];var length=tool[this.mode].list.length;if(typeof tool[this.mode].fn!='function'||length==0){return null;}else{var options={};for(var i=0;i','');}catch(e){};this.toolNodes.blocks.value='nonebis';}},wiki:{list:['nonebis','h2','h3','h4','h5'],fn:function(opt){switch(opt){case'nonebis':this.textarea.focus();break;case'h2':this.encloseSelection('!!!!');break;case'h3':this.encloseSelection('!!!');break;case'h4':this.encloseSelection('!!');break;case'h5':this.encloseSelection('!');break;} +this.toolNodes.blocks.value='nonebis';}}};jsToolBar.prototype.elements.space0={type:'space'};jsToolBar.prototype.elements.strong={type:'button',title:'Strong emphasis',fn:{wiki:function(){this.singleTag('__')},xhtml:function(){this.singleTag('','')}}};jsToolBar.prototype.elements.em={type:'button',title:'Emphasis',fn:{wiki:function(){this.singleTag("''")},xhtml:function(){this.singleTag('','')}}};jsToolBar.prototype.elements.ins={type:'button',title:'Inserted',fn:{wiki:function(){this.singleTag('++')},xhtml:function(){this.singleTag('','')}}};jsToolBar.prototype.elements.del={type:'button',title:'Deleted',fn:{wiki:function(){this.singleTag('--')},xhtml:function(){this.singleTag('','')}}};jsToolBar.prototype.elements.quote={type:'button',title:'Inline quote',fn:{wiki:function(){this.singleTag('{{','}}')},xhtml:function(){this.singleTag('','')}}};jsToolBar.prototype.elements.code={type:'button',title:'Code',fn:{wiki:function(){this.singleTag('@@')},xhtml:function(){this.singleTag('','')}}};jsToolBar.prototype.elements.space1={type:'space'};jsToolBar.prototype.elements.br={type:'button',title:'Line break',fn:{wiki:function(){this.encloseSelection("%%%\n",'')},xhtml:function(){this.encloseSelection("
      \n",'')}}};jsToolBar.prototype.elements.space2={type:'space'};jsToolBar.prototype.elements.blockquote={type:'button',title:'Blockquote',fn:{xhtml:function(){this.singleTag('
      ','
      ')},wiki:function(){this.encloseSelection("\n",'',function(str){str=str.replace(/\r/g,'');return'> '+str.replace(/\n/g,"\n> ");});}}};jsToolBar.prototype.elements.pre={type:'button',title:'Preformated text',fn:{wiki:function(){this.singleTag("///\n","\n///")},xhtml:function(){this.singleTag('
      ','
      ')}}};jsToolBar.prototype.elements.ul={type:'button',title:'Unordered list',fn:{wiki:function(){this.encloseSelection('','',function(str){str=str.replace(/\r/g,'');return'* '+str.replace(/\n/g,"\n* ");});},xhtml:function(){this.encloseSelection('','',function(str){str=str.replace(/\r/g,'');str=str.replace(/\n/g,"\n
    • ");return"
        \n
      • "+str+"
      • \n
      ";});}}};jsToolBar.prototype.elements.ol={type:'button',title:'Ordered list',fn:{wiki:function(){this.encloseSelection('','',function(str){str=str.replace(/\r/g,'');return'# '+str.replace(/\n/g,"\n# ");});},xhtml:function(){this.encloseSelection('','',function(str){str=str.replace(/\r/g,'');str=str.replace(/\n/g,"
    • \n
    • ");return"
        \n
      1. "+str+"
      2. \n
      ";});}}};jsToolBar.prototype.elements.space3={type:'space'};jsToolBar.prototype.elements.link={type:'button',title:'Link',fn:{},href_prompt:'Please give page URL:',hreflang_prompt:'Language of this page:',default_hreflang:'',prompt:function(href,hreflang){href=href||'';hreflang=hreflang||this.elements.link.default_hreflang;href=window.prompt(this.elements.link.href_prompt,href);if(!href){return false;} +hreflang=window.prompt(this.elements.link.hreflang_prompt,hreflang);return{href:this.stripBaseURL(href),hreflang:hreflang};}};jsToolBar.prototype.elements.link.fn.xhtml=function(){var link=this.elements.link.prompt.call(this);if(link){var stag='';var etag='';this.encloseSelection(stag,etag);}};jsToolBar.prototype.elements.link.fn.wiki=function(){var link=this.elements.link.prompt.call(this);if(link){var stag='[';var etag='|'+link.href;if(link.hreflang){etag=etag+'|'+link.hreflang;} +etag=etag+']';this.encloseSelection(stag,etag);}};jsToolBar.prototype.elements.img={type:'button',title:'External image',src_prompt:'Please give image URL:',fn:{},prompt:function(src){src=src||'';return this.stripBaseURL(window.prompt(this.elements.img.src_prompt,src));}};jsToolBar.prototype.elements.img.fn.xhtml=function(){var src=this.elements.img.prompt.call(this);if(src){this.encloseSelection('','',function(str){if(str){return''+str+'';}else{return'';}});}};jsToolBar.prototype.elements.img.fn.wiki=function(){var src=this.elements.img.prompt.call(this);if(src){this.encloseSelection('','',function(str){if(str){return'(('+src+'|'+str+'))';}else{return'(('+src+'))';}});}}; \ No newline at end of file diff --git a/v2/dotclear/admin/js/jsToolBar/jsToolBar.wysiwyg.js b/v2/dotclear/admin/js/jsToolBar/jsToolBar.wysiwyg.js new file mode 100644 index 0000000..c1e0b0a --- /dev/null +++ b/v2/dotclear/admin/js/jsToolBar/jsToolBar.wysiwyg.js @@ -0,0 +1,47 @@ + +jsToolBar.prototype.can_wwg=(document.designMode!=undefined);jsToolBar.prototype.iframe=null;jsToolBar.prototype.iwin=null;jsToolBar.prototype.ibody=null;jsToolBar.prototype.iframe_css=null;jsToolBar.prototype.drawToolBar=jsToolBar.prototype.draw;jsToolBar.prototype.draw=function(mode){mode=mode||'xhtml';if(this.can_wwg){this.mode='wysiwyg';this.drawToolBar('wysiwyg');this.initWindow();}else{this.drawToolBar(mode);}};jsToolBar.prototype.switchMode=function(mode){mode=mode||'xhtml';if(mode=='xhtml'){this.draw(mode);}else{if(this.wwg_mode){this.syncContents('iframe');} +this.removeEditor();this.textarea.style.display='';this.drawToolBar(mode);}};jsToolBar.prototype.syncContents=function(from){from=from||'textarea';var This=this;if(from=='textarea'){initContent();}else{this.validBlockquote();var html=this.applyHtmlFilters(this.ibody.innerHTML);if(html=='
      '){html='

      ';} +this.textarea.value=html;} +function initContent(){if(!This.iframe.contentWindow.document||!This.iframe.contentWindow.document.body){setTimeout(initContent,1);return;} +This.ibody=This.iframe.contentWindow.document.body;if(This.textarea.value!=''&&This.textarea.value!='

      '){This.ibody.innerHTML=This.applyWysiwygFilters(This.textarea.value);if(This.ibody.createTextRange){var IErange=This.ibody.createTextRange();IErange.execCommand("SelectAll");IErange.collapse();IErange.select();}}else if(window.navigator.product!=undefined&&window.navigator.product=='Gecko'){This.ibody.innerHTML='


      ';}else{var idoc=This.iwin.document;var para=idoc.createElement('p');para.appendChild(idoc.createTextNode(''));while(idoc.body.hasChildNodes()){idoc.body.removeChild(idoc.body.lastChild);} +idoc.body.appendChild(para);}}};jsToolBar.prototype.htmlFilters={tagsoup:function(str){return this.tagsoup2xhtml(str);}};jsToolBar.prototype.applyHtmlFilters=function(str){for(var fn in this.htmlFilters){str=this.htmlFilters[fn].call(this,str);} +return str;};jsToolBar.prototype.wysiwygFilters={};jsToolBar.prototype.applyWysiwygFilters=function(str){for(var fn in this.wysiwygFilters){str=this.wysiwygFilters[fn].call(this,str);} +return str;};jsToolBar.prototype.switchEdit=function(){if(this.wwg_mode){this.textarea.style.display='';this.iframe.style.display='none';this.syncContents('iframe');this.drawToolBar('xhtml');this.wwg_mode=false;this.focusEditor();}else{this.iframe.style.display='';this.textarea.style.display='none';this.syncContents('textarea');this.drawToolBar('wysiwyg');this.wwg_mode=true;this.focusEditor();} +this.setSwitcher();};jsToolBar.prototype.initWindow=function(){var This=this;this.iframe=document.createElement('iframe');this.textarea.parentNode.insertBefore(this.iframe,this.textarea.nextSibling);this.switcher=document.createElement('ul');this.switcher.className='jstSwitcher';this.editor.appendChild(this.switcher);this.iframe.height=this.textarea.offsetHeight+0;this.iframe.width=this.textarea.offsetWidth+0;if(this.textarea.tabIndex!=undefined){this.iframe.tabIndex=this.textarea.tabIndex;} +function initIframe(){var doc=This.iframe.contentWindow.document;if(!doc){setTimeout(initIframe,1);return false;} +doc.open();var html='\n'+'\n'+'\n'+ +(This.base_url!=''?'':'')+'\n'+'\n'+'\n'+'';doc.write(html);doc.close();if(document.all){doc.designMode='on';} +This.iwin=This.iframe.contentWindow;This.syncContents('textarea');if(This.wwg_mode==undefined){This.wwg_mode=true;} +if(This.wwg_mode){This.textarea.style.display='none';}else{This.iframe.style.display='none';} +if(This.textarea.form){chainHandler(This.textarea.form,'onsubmit',function(){if(This.wwg_mode){This.syncContents('iframe');}});} +for(var evt in This.iwinEvents){var event=This.iwinEvents[evt];This.addIwinEvent(This.iframe.contentWindow.document,event.type,event.fn,This);} +This.setSwitcher();setTimeout(function(){This.focusEditor();},1);return true;} +initIframe();};jsToolBar.prototype.addIwinEvent=function(target,type,fn,scope){var myFn=function(e){fn.call(scope,e)};addEvent(target,type,myFn,true);addEvent(scope.iwin,'unload',function(){removeEvent(target,type,myFn,true);},true);};jsToolBar.prototype.iwinEvents={block1:{type:'mouseup',fn:function(){this.adjustBlockLevelCombo()}},block2:{type:'keyup',fn:function(){this.adjustBlockLevelCombo()}}};jsToolBar.prototype.switcher_visual_title='visual';jsToolBar.prototype.switcher_source_title='source';jsToolBar.prototype.setSwitcher=function(){while(this.switcher.hasChildNodes()){this.switcher.removeChild(this.switcher.firstChild);} +var This=this;function setLink(title,link){var li=document.createElement('li');if(link){var a=document.createElement('a');a.href='#';a.editor=This;a.onclick=function(){this.editor.switchEdit();return false;};a.appendChild(document.createTextNode(title));}else{li.className='jstSwitcherCurrent';a=document.createTextNode(title);} +li.appendChild(a);This.switcher.appendChild(li);} +setLink(this.switcher_visual_title,!this.wwg_mode);setLink(this.switcher_source_title,this.wwg_mode);};jsToolBar.prototype.removeEditor=function(){if(this.iframe!=null){this.iframe.parentNode.removeChild(this.iframe);this.iframe=null;} +if(this.switcher!=undefined&&this.switcher.parentNode!=undefined){this.switcher.parentNode.removeChild(this.switcher);}};jsToolBar.prototype.focusEditor=function(){if(this.wwg_mode){try{this.iwin.document.designMode='on';}catch(e){};var This=this;setTimeout(function(){This.iframe.contentWindow.focus()},1);}else{this.textarea.focus();}};jsToolBar.prototype.resizeSetStartH=function(){if(this.wwg_mode&&this.iframe!=undefined){this.dragStartH=this.iframe.offsetHeight;return;} +this.dragStartH=this.textarea.offsetHeight+0;};jsToolBar.prototype.resizeDragMove=function(event){var new_height=(this.dragStartH+event.clientY-this.dragStartY)+'px';if(this.iframe!=undefined){this.iframe.style.height=new_height;} +this.textarea.style.height=new_height;};jsToolBar.prototype.insertNode=function(node){var range;if(this.iwin.getSelection){var sel=this.iwin.getSelection();range=sel.getRangeAt(0);sel.removeAllRanges();range.deleteContents();range.insertNode(node);range.selectNodeContents(node);range.setEndAfter(node);if(range.endContainer.childNodes.length>range.endOffset&&range.endContainer.nodeType!=Node.TEXT_NODE){range.setEnd(range.endContainer.childNodes[range.endOffset],0);}else{range.setEnd(range.endContainer.childNodes[0]);} +sel.addRange(range);sel.collapseToEnd();}else{var p=this.iwin.document.createElement('div');p.appendChild(node);range=this.iwin.document.selection.createRange();range.execCommand('delete');range.pasteHTML(p.innerHTML);range.collapse(false);range.select();} +this.iwin.focus();};jsToolBar.prototype.getSelectedNode=function(){if(this.iwin.getSelection){var sel=this.iwin.getSelection();var range=sel.getRangeAt(0);var content=range.cloneContents();}else{var sel=this.iwin.document.selection;var d=this.iwin.document.createElement('div');d.innerHTML=sel.createRange().htmlText;var content=this.iwin.document.createDocumentFragment();for(var i=0;i/gim,''],[/[\w\W]*?<\/style>/gim,''],[/<\/?font[\w\W]*?>/gim,''],[/<(\/?)(B|b|STRONG)([\s>\/])/g,"<$1strong$3"],[/<(\/?)(I|i|EM)([\s>\/])/g,"<$1em$3"],[/]*?[^\/])>/gi,""],[/]*?[^\/])>/gi,""],[/]*?[^\/])>/gi,""],[/]*?[^\/])>/gi,""],[/]*?[^\/])>/gi,""],[/
      ]*?[^\/])>/gi,"
      "],[/
      ]*?[^\/])>/gi,"
      "],[/<(\/?)U([\s>\/])/gi,"<$1ins$2"],[/<(\/?)STRIKE([\s>\/])/gi,"<$1del$2"],[/([\w\W]*?)<\/span>/gm,"$1"],[/([\w\W]*?)<\/span>/gm,"$1"],[/([\w\W]*?)<\/span>/gm,"$1"],[/([\w\W]*?)<\/span>/gm,"$1"],[/([\w\W]*?)<\/span>/gm,"$1"],[/([\w\W]*?)<\/span>/gm,"$1"],[/([\w\W]*?)<\/span>/gm,"$2"],[/([\w\W]*?)<\/span>/gm,"$2"],[/([\w\W]*?)<\/span>/gm,"$2"],[/([\w\W]*?)<\/span>/gm,"$2"],[/([\w\W]*?)<\/span>/gm,"$2"],[/([\w\W]*?)<\/span>/gm,"$2"],[/([\w\W]*?)<\/span>/gm,"$2"],[/([\w\W]*?)<\/span>/gm,"$2"],[/([\w\W]*?)<\/strong>/gm,"$1"],[/<([a-z]+) style="font-weight: normal;">([\w\W]*?)<\/\1>/gm,"<$1>$2"],[/<([a-z]+) style="font-weight: bold;">([\w\W]*?)<\/\1>/gm,"<$1>$2"],[/<([a-z]+) style="font-style: italic;">([\w\W]*?)<\/\1>/gm,"<$1>$2"],[/<([a-z]+) style="text-decoration: underline;">([\w\W]*?)<\/\1>/gm,"<$1>$2"],[/<([a-z]+) style="text-decoration: line-through;">([\w\W]*?)<\/\1>/gm,"<$1>$2"],[/<([a-z]+) style="text-decoration: underline line-through;">([\w\W]*?)<\/\1>/gm,"<$1>$2"],[/<([a-z]+) style="(font-weight: bold; ?|font-style: italic; ?){2}">([\w\W]*?)<\/\1>/gm,"<$1>$3"],[/<([a-z]+) style="(font-weight: bold; ?|text-decoration: underline; ?){2}">([\w\W]*?)<\/\1>/gm,"<$1>$3"],[/<([a-z]+) style="(font-weight: italic; ?|text-decoration: underline; ?){2}">([\w\W]*?)<\/\1>/gm,"<$1>$3"],[/<([a-z]+) style="(font-weight: bold; ?|text-decoration: line-through; ?){2}">([\w\W]*?)<\/\1>/gm,"<$1>$3"],[/<([a-z]+) style="(font-weight: italic; ?|text-decoration: line-through; ?){2}">([\w\W]*?)<\/\1>/gm,"<$1>$3"],[/<([a-z]+) style="(font-weight: bold; ?|font-style: italic; ?|text-decoration: underline; ?){3}">([\w\W]*?)<\/\1>/gm,"<$1>$3"],[/<([a-z]+) style="(font-weight: bold; ?|font-style: italic; ?|text-decoration: line-through; ?){3}">([\w\W]*?)<\/\1>/gm,"<$1>$3"],[/<([a-z]+) style="(font-weight: bold; ?|font-style: italic; ?|text-decoration: underline line-through; ?){3}">([\w\W]*?)<\/\1>/gm,"<$1>$3"],[/

      (.*)(\n)+<\/blockquote><\/p>/i,"
      $1
      \n"],[/<\/(strong|em|ins|del|q|code)>(\s*?)<\1>/gim,"$2"],[/<(br|BR)>/g,"
      "],[/([^\s])\/>/g,"$1 />"],[/
      \s*<\/(h1|h2|h3|h4|h5|h6|ul|ol|li|p|blockquote|div)/gi,"([^\n\u000B\r\f])/gi,"\n$2"],[/
      /g,"
      "]);jsToolBar.prototype.tagsoup2xhtml=function(html){for(var reg in this.simpleCleanRegex){html=html.replace(this.simpleCleanRegex[reg][0],this.simpleCleanRegex[reg][1]);} +while(/(<[^\/!]>|<[^\/!][^>]*[^\/]>)\s*<\/[^>]*[^-]>/.test(html)){html=html.replace(/(<[^\/!]>|<[^\/!][^>]*[^\/]>)\s*<\/[^>]*[^-]>/g,"");} +html=html.replace(/<(\/?)([A-Z0-9]+)/g,function(match0,match1,match2){return"<"+match1+match2.toLowerCase();});var myRegexp=/<[^>]+((\s+\w+\s*=\s*)([^"'][\w~@+$,%\/:.#?=&;!*()-]*))[^>]*?>/;while(myRegexp.test(html)){html=html.replace(myRegexp,function(str,val1,val2,val3){var tamponRegex=new RegExp(regexpEscape(val1));return str.replace(tamponRegex,val2+'"'+val3+'"');})} +while(/(<[^>]+style=(["'])[^>]+[\s:]+)0(pt|px)(\2|\s|;)/.test(html)){html=html.replace(/(<[^>]+style=(["'])[^>]+[\s:]+)0(pt|px)(\2|\s|;)/gi,"$1"+"0$4");} +html=html.replace(/\r\n/g,"\n");html=html.replace(/^\s+/gm,'');html=html.replace(/\s+$/gm,'');return html;};jsToolBar.prototype.validBlockquote=function(){var blockElts=['address','blockquote','dl','div','fieldset','form','h1','h2','h3','h4','h5','h6','hr','ol','p','pre','table','ul'];var BQs=this.iwin.document.getElementsByTagName('blockquote');var bqChilds;for(var bq=0;bq=0;i--){if(bqChilds[i].nodeType==1&&arrayIndexOf(blockElts,bqChilds[i].tagName.toLowerCase())>=0) +{if(frag.childNodes.length>0){var p=this.iwin.document.createElement('p');p.appendChild(frag);BQs[bq].replaceChild(p,bqChilds[i+1]);frag=this.iwin.document.createDocumentFragment();}}else{if(frag.childNodes.length>0)BQs[bq].removeChild(bqChilds[i+1]);frag.insertBefore(bqChilds[i].cloneNode(true),frag.firstChild);}} +if(frag.childNodes.length>0){var p=this.iwin.document.createElement('p');p.appendChild(frag);BQs[bq].replaceChild(p,bqChilds[0]);}}};jsToolBar.prototype.removeFormatRegexp=new Array([/(<[a-z][^>]*)margin\s*:[^;]*;/mg,"$1"],[/(<[a-z][^>]*)margin-bottom\s*:[^;]*;/mg,"$1"],[/(<[a-z][^>]*)margin-left\s*:[^;]*;/mg,"$1"],[/(<[a-z][^>]*)margin-right\s*:[^;]*;/mg,"$1"],[/(<[a-z][^>]*)margin-top\s*:[^;]*;/mg,"$1"],[/(<[a-z][^>]*)padding\s*:[^;]*;/mg,"$1"],[/(<[a-z][^>]*)padding-bottom\s*:[^;]*;/mg,"$1"],[/(<[a-z][^>]*)padding-left\s*:[^;]*;/mg,"$1"],[/(<[a-z][^>]*)padding-right\s*:[^;]*;/mg,"$1"],[/(<[a-z][^>]*)padding-top\s*:[^;]*;/mg,"$1"],[/(<[a-z][^>]*)font\s*:[^;]*;/mg,"$1"],[/(<[a-z][^>]*)font-family\s*:[^;]*;/mg,"$1"],[/(<[a-z][^>]*)font-size\s*:[^;]*;/mg,"$1"],[/(<[a-z][^>]*)font-style\s*:[^;]*;/mg,"$1"],[/(<[a-z][^>]*)font-variant\s*:[^;]*;/mg,"$1"],[/(<[a-z][^>]*)font-weight\s*:[^;]*;/mg,"$1"],[/(<[a-z][^>]*)color\s*:[^;]*;/mg,"$1"]);jsToolBar.prototype.removeTextFormating=function(html){for(var reg in this.removeFormatRegexp){html=html.replace(this.removeFormatRegexp[reg][0],this.removeFormatRegexp[reg][1]);} +html=this.tagsoup2xhtml(html);html=html.replace(/style="\s*?"/mgi,'');return html;};jsToolBar.prototype.elements.blocks.wysiwyg={list:['none','p','h1','h2','h3','h4','h5','h6'],fn:function(opt){if(opt=='none'){var blockLevel=this.getBlockLevel();if(blockLevel!==null){this.replaceNodeByContent(blockLevel);} +this.iwin.focus();}else{try{this.iwin.document.execCommand('formatblock',false,'<'+opt+'>');}catch(e){};this.iwin.focus();}}};jsToolBar.prototype.elements.strong.fn.wysiwyg=function(){this.iwin.document.execCommand('bold',false,null);this.iwin.focus();};jsToolBar.prototype.elements.em.fn.wysiwyg=function(){this.iwin.document.execCommand('italic',false,null);this.iwin.focus();};jsToolBar.prototype.elements.ins.fn.wysiwyg=function(){this.iwin.document.execCommand('underline',false,null);this.iwin.focus();};jsToolBar.prototype.elements.del.fn.wysiwyg=function(){this.iwin.document.execCommand('strikethrough',false,null);this.iwin.focus();};jsToolBar.prototype.elements.quote.fn.wysiwyg=function(){var n=this.getSelectedNode();var q=this.iwin.document.createElement('q');q.appendChild(n);this.insertNode(q);};jsToolBar.prototype.elements.code.fn.wysiwyg=function(){var n=this.getSelectedNode();var code=this.iwin.document.createElement('code');code.appendChild(n);this.insertNode(code);};jsToolBar.prototype.elements.br.fn.wysiwyg=function(){var n=this.iwin.document.createElement('br');this.insertNode(n);};jsToolBar.prototype.elements.blockquote.fn.wysiwyg=function(){var n=this.getSelectedNode();var q=this.iwin.document.createElement('blockquote');q.appendChild(n);this.insertNode(q);};jsToolBar.prototype.elements.pre.fn.wysiwyg=function(){this.iwin.document.execCommand('formatblock',false,'
      ');this.iwin.focus();};jsToolBar.prototype.elements.ul.fn.wysiwyg=function(){this.iwin.document.execCommand('insertunorderedlist',false,null);this.iwin.focus();};jsToolBar.prototype.elements.ol.fn.wysiwyg=function(){this.iwin.document.execCommand('insertorderedlist',false,null);this.iwin.focus();};jsToolBar.prototype.elements.link.fn.wysiwyg=function(){var href,hreflang;var range,commonAncestorContainer;if(this.iwin.getSelection){var selection=this.iwin.getSelection();range=selection.getRangeAt(0);commonAncestorContainer=range.commonAncestorContainer;while(commonAncestorContainer.nodeType!=1){commonAncestorContainer=commonAncestorContainer.parentNode;}}else{range=this.iwin.document.selection.createRange();commonAncestorContainer=range.parentElement();}
      +var ancestorTagName=commonAncestorContainer.tagName.toLowerCase();while(ancestorTagName!='a'&&ancestorTagName!='body'){commonAncestorContainer=commonAncestorContainer.parentNode;ancestorTagName=commonAncestorContainer.tagName.toLowerCase();}
      +if(ancestorTagName=='a'){href=commonAncestorContainer.href||'';hreflang=commonAncestorContainer.hreflang||'';}
      +href=window.prompt(this.elements.link.href_prompt,href);if(ancestorTagName=='a'&&href==''){this.replaceNodeByContent(commonAncestorContainer);}
      +if(!href)return;hreflang=window.prompt(this.elements.link.hreflang_prompt,hreflang);if(ancestorTagName=='a'&&href){commonAncestorContainer.setAttribute('href',href);if(hreflang){commonAncestorContainer.setAttribute('hreflang',hreflang);}else{commonAncestorContainer.removeAttribute('hreflang');}
      +return;}
      +var n=this.getSelectedNode();var a=this.iwin.document.createElement('a');a.href=href;if(hreflang)a.setAttribute('hreflang',hreflang);a.appendChild(n);this.insertNode(a);};jsToolBar.prototype.elements.removeFormat={type:'button',title:'Remove text formating',fn:{}};jsToolBar.prototype.elements.removeFormat.disabled=!jsToolBar.prototype.can_wwg;jsToolBar.prototype.elements.removeFormat.fn.xhtml=function(){var html=this.textarea.value;html=this.removeTextFormating(html);this.textarea.value=html;};jsToolBar.prototype.elements.removeFormat.fn.wysiwyg=function(){var html=this.iwin.document.body.innerHTML;html=this.removeTextFormating(html);this.iwin.document.body.innerHTML=html;};function arrayIndexOf(aArray,aValue){if(typeof Array.indexOf=='function'){return aArray.indexOf(aValue);}else{var index=-1;var l=aArray.length;for(var i=0;i'+player+'
    • ';} +tb.elements.mp3_insert.data.player=player.replace(/>/g,'>\n');tb.elements.mp3_insert.fncall[tb.mode].call(tb);} +else if(type=='flv') +{var oplayer=$('
      '+$('#public_player').val()+'
      ');var flashvars=$("[name=FlashVars]",oplayer).val();var align=$('input[name="alignment"]:checked',insert_form).val();var title=insert_form.elements.title.value;if(title){flashvars='title='+encodeURI(title)+'&'+flashvars;} +$('object',oplayer).attr('width',$('#video_w').val());$('object',oplayer).attr('height',$('#video_h').val());flashvars=flashvars.replace(/(width=\d*)/,'width='+$('#video_w').val());flashvars=flashvars.replace(/(height=\d*)/,'height='+$('#video_h').val());$("[name=FlashVars]",oplayer).val(flashvars);var player=oplayer.html();if(align!=undefined&&align!='none'){player='
      '+player+'
      ';} +tb.elements.flv_insert.data.player=player.replace(/>/g,'>\n');tb.elements.flv_insert.fncall[tb.mode].call(tb);} +else +{tb.elements.link.data.href=tb.stripBaseURL(insert_form.elements.url.value);tb.elements.link.data.content=insert_form.elements.title.value;tb.elements.link.fncall[tb.mode].call(tb);}};function playerFormat(s){s=s.replace(/</g,'<');s=s.replace(/>/g,'>\n');s=s.replace(/&/g,'&');return s;};}); \ No newline at end of file diff --git a/v2/dotclear/admin/js/jsToolBar/popup_posts.js b/v2/dotclear/admin/js/jsToolBar/popup_posts.js new file mode 100644 index 0000000..0fbb77d --- /dev/null +++ b/v2/dotclear/admin/js/jsToolBar/popup_posts.js @@ -0,0 +1,2 @@ + +$(function(){$('#link-insert-cancel').click(function(){window.close();});$('#form-entries tr>td.maximal>a').click(function(){var tb=window.opener.the_toolbar;var data=tb.elements.link.data;data.href=tb.stripBaseURL($(this).attr('title'));tb.elements.link.fncall[tb.mode].call(tb);window.close();});}); \ No newline at end of file diff --git a/v2/dotclear/admin/js/meta-editor.js b/v2/dotclear/admin/js/meta-editor.js new file mode 100644 index 0000000..e9a3be3 --- /dev/null +++ b/v2/dotclear/admin/js/meta-editor.js @@ -0,0 +1,14 @@ + +function metaEditor(target,meta_field,meta_type){this.target=target;this.meta_field=meta_field;this.meta_type=meta_type;};metaEditor.prototype={meta_url:'',text_confirm_remove:'Are you sure you want to remove this %s?',text_add_meta:'Add a %s to this entry',text_choose:'Choose from list',text_all:'all',text_separation:'Separate each %s by comas',target:null,meta_type:null,meta_dialog:null,meta_field:null,submit_button:null,post_id:false,service_uri:'services.php',displayMeta:function(type,post_id){this.meta_type=type;this.post_id=post_id;this.target.empty();this.meta_dialog=$('');this.meta_dialog.attr('title',this.text_add_meta.replace(/%s/,this.meta_type));this.meta_dialog.attr('id','post_meta_input');this.meta_dialog.keypress(function(evt){if(evt.keyCode==13){This.addMeta(this.value);return false;} +return true;});var This=this;this.submit_button=$('');this.submit_button.click(function(){var v=This.meta_dialog.val();This.addMeta(v);return false;});this.addMetaDialog();if(this.post_id==false){this.target.append(this.meta_field);} +this.displayMetaList();},displayMetaList:function(){var li;if(this.meta_list==undefined){this.meta_list=$('
        ');this.target.prepend(this.meta_list);} +if(this.post_id==false){var meta=this.splitMetaValues(this.meta_field.val());this.meta_list.empty();for(var i=0;i'+meta[i]+'');a_remove=$('[x]');a_remove.get(0).caller=this;a_remove.get(0).meta_id=meta[i];a_remove.click(function(){this.caller.removeMeta(this.meta_id);return false;});li.append(' ').append(a_remove);this.meta_list.append(li);}}else{var This=this;var params={f:'getMeta',metaType:this.meta_type,sortby:'metaId,asc',postId:this.post_id};$.get(this.service_uri,params,function(data){data=$(data);if(data.find('rsp').attr('status')!='ok'){return;} +This.meta_list.empty();data.find('meta').each(function(){var meta_id=$(this).text();li=$('
      • '+meta_id+'
      • ');a_remove=$('[x]');a_remove.get(0).caller=This;a_remove.get(0).meta_id=meta_id;a_remove.click(function(){this.caller.removeMeta(this.meta_id);return false;});li.append(' ').append(a_remove);This.meta_list.append(li);});});}},addMetaDialog:function(){var This=this;if(this.submit_button==null){this.target.append($('

        ').append(this.meta_dialog));}else{this.target.append($('

        ').append(this.meta_dialog).append(' ').append(this.submit_button));} +var a=$(''+this.text_choose+'');a.click(function(){This.showMetaList(metaEditor.prototype.meta_type,$(this).parent());return false;});if(this.text_separation!=''){this.target.append($('

        ').addClass('form-note').append(this.text_separation.replace(/%s/,this.meta_type)));} +this.target.append($('

        ').append(a));},showMetaList:function(type,target){target.empty();target.append('...');target.addClass('addMeta');var params={f:'getMeta',metaType:this.meta_type,sortby:'metaId,asc'};if(type=='more'){params.limit='30';} +var This=this;$.get(this.service_uri,params,function(data){if($(data).find('meta').length>0){target.empty();var meta_link;$(data).find('meta').each(function(i){meta_link=$(''+$(this).text()+'');meta_link.get(0).meta_id=$(this).text();meta_link.click(function(){var v=This.splitMetaValues(This.meta_dialog.val()+','+this.meta_id);This.meta_dialog.val(v.join(','));return false;});if(i>0){target.append(', ');} +target.append(meta_link);});if(type=='more'){var a_more=$('');a_more.append(This.text_all+String.fromCharCode(160)+String.fromCharCode(187));a_more.click(function(){This.showMetaList('all',target);return false;});target.append(', ').append(a_more);}}else{target.empty();}});},addMeta:function(str){str=this.splitMetaValues(str).join(',');if(this.post_id==false){str=this.splitMetaValues(this.meta_field.val()+','+str);this.meta_field.val(str);this.meta_dialog.val('');this.displayMetaList();}else{var params={xd_check:dotclear.nonce,f:'setPostMeta',postId:this.post_id,metaType:this.meta_type,meta:str};var This=this;$.post(this.service_uri,params,function(data){if($(data).find('rsp').attr('status')=='ok'){This.meta_dialog.val('');This.displayMetaList();}else{alert($(data).find('message').text());}});}},removeMeta:function(meta_id){if(this.post_id==false){var meta=this.splitMetaValues(this.meta_field.val());for(var i=0;i=0){return this.create(document.body.scrollLeft,document.body.scrollTop)}else{return this.create(0,0)}},clientSize:function(){if(window.innerHeight>=0){return this.create(window.innerWidth,window.innerHeight)}else if(document.documentElement){return this.create(document.documentElement.clientWidth,document.documentElement.clientHeight)}else if(document.body.clientHeight>=0){return this.create(document.body.clientWidth,document.body.clientHeight)}else{return this.create(0,0)}},mousePosition:function(event){event=ToolMan.events().fix(event) +return this.create(event.clientX,event.clientY)},mouseOffset:function(event){event=ToolMan.events().fix(event) +if(event.pageX>=0||event.pageX<0){return this.create(event.pageX,event.pageY)}else if(event.clientX>=0||event.clientX<0){return this.mousePosition(event).plus(this.scrollOffset())}},_size:function(element){return this.create(element.offsetWidth,element.offsetHeight)},_offset:function(element){return this.create(element.offsetLeft,element.offsetTop)}} +function _ToolManCoordinate(factory,x,y){this.factory=factory +this.x=isNaN(x)?0:x +this.y=isNaN(y)?0:y} +_ToolManCoordinate.prototype={toString:function(){return"("+this.x+","+this.y+")"},plus:function(that){return this.factory.create(this.x+that.x,this.y+that.y)},minus:function(that){return this.factory.create(this.x-that.x,this.y-that.y)},min:function(that){return this.factory.create(Math.min(this.x,that.x),Math.min(this.y,that.y))},max:function(that){return this.factory.create(Math.max(this.x,that.x),Math.max(this.y,that.y))},constrainTo:function(one,two){var min=one.min(two) +var max=one.max(two) +return this.max(min).min(max)},distance:function(that){return Math.sqrt(Math.pow(this.x-that.x,2)+Math.pow(this.y-that.y,2))},reposition:function(element){element.style["top"]=this.y+"px" +element.style["left"]=this.x+"px"}} \ No newline at end of file diff --git a/v2/dotclear/admin/js/tool-man/core.js b/v2/dotclear/admin/js/tool-man/core.js new file mode 100644 index 0000000..7a46341 --- /dev/null +++ b/v2/dotclear/admin/js/tool-man/core.js @@ -0,0 +1,35 @@ + +var ToolMan={events:function(){if(!ToolMan._eventsFactory)throw"ToolMan Events module isn't loaded";return ToolMan._eventsFactory},css:function(){if(!ToolMan._cssFactory)throw"ToolMan CSS module isn't loaded";return ToolMan._cssFactory},coordinates:function(){if(!ToolMan._coordinatesFactory)throw"ToolMan Coordinates module isn't loaded";return ToolMan._coordinatesFactory},drag:function(){if(!ToolMan._dragFactory)throw"ToolMan Drag module isn't loaded";return ToolMan._dragFactory},dragsort:function(){if(!ToolMan._dragsortFactory)throw"ToolMan DragSort module isn't loaded";return ToolMan._dragsortFactory},helpers:function(){return ToolMan._helpers},cookies:function(){if(!ToolMan._cookieOven)throw"ToolMan Cookie module isn't loaded";return ToolMan._cookieOven},junkdrawer:function(){return ToolMan._junkdrawer}} +ToolMan._helpers={map:function(array,func){for(var i=0,n=array.length;i0)return identifier;identifier=trim(item.getAttribute("itemID")) +if(identifier!=null&&identifier.length>0)return identifier;return trim(item.innerHTML)},_itemsByID:function(list){var array=new Array() +var items=list.getElementsByTagName('li') +for(var i=0,n=items.length;isetCacheDir(DC_TPL_CACHE); +$feed_reader->setTimeout(5); +$feed_reader->setUserAgent('Dotclear - http://www.dotclear.org/'); +try { + $dc_langs = $feed_reader->parse(sprintf(DC_L10N_UPDATE_URL,DC_VERSION)); + if ($dc_langs !== false) { + $dc_langs = $dc_langs->items; + } +} catch (Exception $e) {} + +# Delete a language pack +if ($is_writable && !empty($_POST['delete']) && !empty($_POST['locale_id'])) +{ + try + { + $locale_id = $_POST['locale_id']; + if (!isset($iso_codes[$locale_id]) || !is_dir(DC_L10N_ROOT.'/'.$locale_id)) { + throw new Exception(__('No such installed language')); + } + + if ($locale_id == 'en') { + throw new Exception(__("You can't remove English language.")); + } + + if (!files::deltree(DC_L10N_ROOT.'/'.$locale_id)) { + throw new Exception(__('Permissions to delete language denied.')); + } + + http::redirect('langs.php?removed=1'); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} + +# Download a language pack +if ($is_writable && !empty($_POST['pkg_url'])) +{ + try + { + if (empty($_POST['your_pwd']) || !$core->auth->checkPassword(crypt::hmac(DC_MASTER_KEY,$_POST['your_pwd']))) { + throw new Exception(__('Password verification failed')); + } + + $url = html::escapeHTML($_POST['pkg_url']); + $dest = DC_L10N_ROOT.'/'.basename($url); + if (!preg_match('#^http://[^.]+\.dotclear\.(net|org)/.*\.zip$#',$url)) { + throw new Exception(__('Invalid language file URL.')); + } + + $client = netHttp::initClient($url,$path); + $client->setUserAgent('Dotclear - http://www.dotclear.org/'); + $client->useGzip(false); + $client->setPersistReferers(false); + $client->setOutput($dest); + $client->get($path); + + try { + $ret_code = dc_lang_install($dest); + } catch (Exception $e) { + @unlink($dest); + throw $e; + } + + @unlink($dest); + http::redirect('langs.php?added='.$ret_code); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} + +# Upload a language pack +if ($is_writable && !empty($_POST['upload_pkg'])) +{ + try + { + if (empty($_POST['your_pwd']) || !$core->auth->checkPassword(crypt::hmac(DC_MASTER_KEY,$_POST['your_pwd']))) { + throw new Exception(__('Password verification failed')); + } + + files::uploadStatus($_FILES['pkg_file']); + $dest = DC_L10N_ROOT.'/'.$_FILES['pkg_file']['name']; + if (!move_uploaded_file($_FILES['pkg_file']['tmp_name'],$dest)) { + throw new Exception(__('Unable to move uploaded file.')); + } + + try { + $ret_code = dc_lang_install($dest); + } catch (Exception $e) { + @unlink($dest); + throw $e; + } + + @unlink($dest); + http::redirect('langs.php?added='.$ret_code); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} + +/* DISPLAY Main page +-------------------------------------------------------- */ +dcPage::open(__('Languages management'), + dcPage::jsLoad('js/_langs.js') +); + +echo +'

        '.__('Languages management').'

        '; + +if (!empty($_GET['removed'])) { + echo '

        '.__('Language has been successfully deleted.').'

        '; +} + +if (!empty($_GET['added'])) { + echo '

        '. + ($_GET['added'] == 2 ? __('Language has been successfully upgraded') : __('Language has been successfully installed.')). + '

        '; +} + +echo +'

        '.__('Here you can install, upgrade or remove languages for your Dotclear '. +'installation.').'

        '. +'

        '.sprintf(__('You can change your user language in your preferences or '. +'change your blog\'s main language in your blog settings.'), +'preferences.php','blog_pref.php').'

        '; + +echo +'

        '.__('Installed languages').'

        '; + +$locales_content = scandir(DC_L10N_ROOT); +$tmp = array(); +foreach ($locales_content as $v) { + $c = ($v == '.' || $v == '..' || $v == 'en' || !is_dir(DC_L10N_ROOT.'/'.$v) || !isset($iso_codes[$v])); + + if (!$c) { + $tmp[$v] = DC_L10N_ROOT.'/'.$v; + } +} +$locales_content = $tmp; + +if (empty($locales_content)) +{ + echo '

        '.__('No additional language is installed.').'

        '; +} +else +{ + echo + ''. + ''. + ''. + ''; + + foreach ($locales_content as $k => $v) + { + $is_deletable = $is_writable && is_writable($v); + + echo + ''. + ''. + ''; + } + echo '
        '.__('Language').''.__('Action').'
        ('.$k.') '. + ''.html::escapeHTML($iso_codes[$k]).''; + + if ($is_deletable) + { + echo + '
        '. + '
        '. + $core->formNonce(). + form::hidden(array('locale_id'),html::escapeHTML($k)). + ' '. + '
        '. + '
        '; + } + + echo '
        '; +} + +echo '

        '.__('Install or upgrade languages').'

        '; + +if (!$is_writable) { + echo '

        '.sprintf(__('You can install or remove a language by adding or '. + 'removing the relevant directory in your %s folder.'),'locales').'

        '; +} + +if (!empty($dc_langs) && $is_writable) +{ + $dc_langs_combo = array(); + foreach ($dc_langs as $k => $v) { + if ($v->link && isset($iso_codes[$v->title])) { + $dc_langs_combo[html::escapeHTML('('.$v->title.') '.$iso_codes[$v->title])] = html::escapeHTML($v->link); + } + } + + echo + '
        '. + '
        '. + ''.__('Available languages').''. + '

        '.sprintf(__('You can download and install a additional language directly from Dotclear.net. '. + 'Proposed languages are based on your version: %s.'),''.DC_VERSION.'').'

        '. + '

        '. + '

        '. + ''. + $core->formNonce(). + '
        '. + '
        '; +} + +if ($is_writable) +{ + # 'Upload language pack' form + echo + '
        '. + '
        '. + ''.__('Upload a zip file').''. + '

        '.__('You can install languages by uploading zip files.').'

        '. + '

        '. + '

        '. + ''. + $core->formNonce(). + '
        '. + '
        '; +} + +dcPage::close(); + + +# Language installation function +function dc_lang_install($file) +{ + $zip = new fileUnzip($file); + $zip->getList(false,'#(^|/)(__MACOSX|\.svn|\.DS_Store|\.directory|Thumbs\.db)(/|$)#'); + + if (!preg_match('/^[a-z]{2,3}(-[a-z]{2})?$/',$zip->getRootDir())) { + throw new Exception(__('Invalid language zip file.')); + } + + if ($zip->isEmpty() || !$zip->hasFile($zip->getRootDir().'/main.po')) { + throw new Exception(__('The zip file does not appear to be a valid Dotclear language pack.')); + } + + + $target = dirname($file); + $destination = $target.'/'.$zip->getRootDir(); + $res = 1; + + if (is_dir($destination)) { + if (!files::deltree($destination)) { + throw new Exception(__('An error occurred during language upgrade.')); + } + $res = 2; + } + + $zip->unzipAll($target); + return $res; +} +?> \ No newline at end of file diff --git a/v2/dotclear/admin/media.php b/v2/dotclear/admin/media.php new file mode 100644 index 0000000..8270131 --- /dev/null +++ b/v2/dotclear/admin/media.php @@ -0,0 +1,472 @@ +auth->check('media,media_admin',$core->blog->id)) { + throw new Exception('Permission denied.'); + } + + $d = isset($_POST['d']) ? $_POST['d'] : null; + $core->media = new dcMedia($core); + $core->media->chdir($d); + $core->media->getDir(); + $dir =& $core->media->dir; + + if (empty($_FILES['Filedata'])) { + throw new Exception('No file to upload.'); + } + + files::uploadStatus($_FILES['Filedata']); + $core->media->uploadFile($_FILES['Filedata']['tmp_name'],$_FILES['Filedata']['name']); + + echo 'ok'; + } + catch (Exception $e) { + echo __('Error:').' '.__($e->getMessage()); + } + exit; +} + + +/* HTML page +-------------------------------------------------------- */ +require dirname(__FILE__).'/../inc/admin/prepend.php'; + +dcPage::check('media,media_admin'); + +$post_id = !empty($_GET['post_id']) ? (integer) $_GET['post_id'] : null; +if ($post_id) { + $post = $core->blog->getPosts(array('post_id'=>$post_id,'post_type'=>'')); + if ($post->isEmpty()) { + $post_id = null; + } + $post_title = $post->post_title; + $post_type = $post->post_type; + unset($post); +} +$d = isset($_REQUEST['d']) ? $_REQUEST['d'] : null; +$dir = null; + +$page = !empty($_GET['page']) ? $_GET['page'] : 1; +$nb_per_page = 30; + +# We are on home not comming from media manager +if ($d === null && isset($_SESSION['media_manager_dir'])) { + # We get session information + $d = $_SESSION['media_manager_dir']; +} + +if (!isset($_GET['page']) && isset($_SESSION['media_manager_page'])) { + $page = $_SESSION['media_manager_page']; +} + +# We set session information about directory and page +if ($d) { + $_SESSION['media_manager_dir'] = $d; +} else { + unset($_SESSION['media_manager_dir']); +} +if ($page != 1) { + $_SESSION['media_manager_page'] = $page; +} else { + unset($_SESSION['media_manager_page']); +} + +# Sort combo +$sort_combo = array( + __('By names, in ascending order') => 'name-asc', + __('By names, in descending order') => 'name-desc', + __('By dates, in ascending order') => 'date-asc', + __('By dates, in descending order') => 'date-desc' +); + +if (!empty($_GET['file_sort']) && in_array($_GET['file_sort'],$sort_combo)) { + $_SESSION['media_file_sort'] = $_GET['file_sort']; +} +$file_sort = !empty($_SESSION['media_file_sort']) ? $_SESSION['media_file_sort'] : null; + +$popup = (integer) !empty($_GET['popup']); + +$page_url = 'media.php?popup='.$popup.'&post_id='.$post_id; + +if ($popup) { + $open_f = array('dcPage','openPopup'); + $close_f = array('dcPage','closePopup'); +} else { + $open_f = array('dcPage','open'); + $close_f = create_function('',"dcPage::helpBlock('core_media'); dcPage::close();"); +} + +$core_media_writable = false; +try { + $core->media = new dcMedia($core); + if ($file_sort) { + $core->media->setFileSort($file_sort); + } + $core->media->chdir($d); + $core->media->getDir(); + $core_media_writable = $core->media->writable(); + $dir =& $core->media->dir; + if (!$core_media_writable) { + throw new Exception('you do not have sufficient permissions to write to this folder: '); + } +} catch (Exception $e) { + $core->error->add($e->getMessage()); +} + +# Zip download +if (!empty($_GET['zipdl']) && $core->auth->check('media_admin',$core->blog->id)) +{ + try + { + @set_time_limit(300); + $fp = fopen('php://output','wb'); + $zip = new fileZip($fp); + $zip->addExclusion('#(^|/).(.*?)_(m|s|sq|t).jpg$#'); + $zip->addDirectory($core->media->root.'/'.$d,'',true); + + header('Content-Disposition: attachment;filename='.($d ? $d : 'media').'.zip'); + header('Content-Type: application/x-zip'); + $zip->write(); + unset($zip); + exit; + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} + +# New directory +if ($dir && !empty($_POST['newdir'])) +{ + try { + $core->media->makeDir($_POST['newdir']); + http::redirect($page_url.'&d='.rawurlencode($d).'&mkdok=1'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} + +# Adding a file +if ($dir && !empty($_FILES['upfile'])) +{ + try + { + files::uploadStatus($_FILES['upfile']); + + $f_title = (isset($_POST['upfiletitle']) ? $_POST['upfiletitle'] : ''); + $f_private = (isset($_POST['upfilepriv']) ? $_POST['upfilepriv'] : false); + + $core->media->uploadFile($_FILES['upfile']['tmp_name'],$_FILES['upfile']['name'],$f_title,$f_private); + http::redirect($page_url.'&d='.rawurlencode($d).'&upok=1'); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} + + +# Removing item +if ($dir && !empty($_POST['rmyes']) && !empty($_POST['remove'])) +{ + $_POST['remove'] = rawurldecode($_POST['remove']); + + try { + $core->media->removeItem($_POST['remove']); + http::redirect($page_url.'&d='.rawurlencode($d).'&rmfok=1'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} + +# Rebuild directory +if ($dir && $core->auth->isSuperAdmin() && !empty($_POST['rebuild'])) +{ + try { + $core->media->rebuild($d); + http::redirect($page_url.'&d='.rawurlencode($d).'&rebuildok=1'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} + + +# DISPLAY confirm page for rmdir & rmfile +if ($dir && !empty($_GET['remove'])) +{ + call_user_func($open_f,__('Media manager')); + + echo '

        '.html::escapeHTML($core->blog->name).' › '.__('Media manager').' › '.__('confirm removal').'

        '; + + echo + '
        '. + '

        '.sprintf(__('Are you sure you want to remove %s?'), + html::escapeHTML($_GET['remove'])).'

        '. + '

        '. + '   '. + form::hidden('d',$d). + $core->formNonce(). + form::hidden('remove',html::escapeHTML($_GET['remove'])).'

        '. + '
        '; + + call_user_func($close_f); + exit; +} + +/* DISPLAY Main page +-------------------------------------------------------- */ +$core->auth->user_prefs->addWorkspace('interface'); +$user_ui_enhanceduploader = $core->auth->user_prefs->interface->enhanceduploader; + +call_user_func($open_f,__('Media manager'), + '". + dcPage::jsLoad('js/_media.js'). + (($user_ui_enhanceduploader && $core_media_writable) ? dcPage::jsCandyUpload(array('d='.$d)) : '') + ); + +if (!empty($_GET['mkdok'])) { + echo '

        '.__('Directory has been successfully created.').'

        '; +} + +if (!empty($_GET['upok'])) { + echo '

        '.__('Files have been successfully uploaded.').'

        '; +} + +if (!empty($_GET['rmfok'])) { + echo '

        '.__('File has been successfully removed.').'

        '; +} + +if (!empty($_GET['rmdok'])) { + echo '

        '.__('Directory has been successfully removed.').'

        '; +} + +if (!empty($_GET['rebuildok'])) { + echo '

        '.__('Directory has been successfully rebuilt.').'

        '; +} + +if (!empty($_GET['unzipok'])) { + echo '

        '.__('Zip file has been successfully extracted.').'

        '; +} + +echo '

        '.html::escapeHTML($core->blog->name).' › '; +if (!isset($core->media)) { + echo ''.__('Media manager').'

        '; +} else { + $breadcrumb = $core->media->breadCrumb(html::escapeURL($page_url).'&d=%s','%s'); + if ($breadcrumb == '') { + echo ''.__('Media manager').''; + } else { + echo ''.__('Media manager').''.' / '.$breadcrumb.''; + } +} + +if (!$dir) { + call_user_func($close_f); + exit; +} + +if ($post_id) { + echo '

        '.sprintf(__('Choose a file to attach to entry %s by clicking on %s.'), + ''.html::escapeHTML($post_title).'', + ''.__('Attach this file to entry').'').'

        '; +} +if ($popup) { + echo '

        '.sprintf(__('Choose a file to insert into entry by clicking on %s.'), + ''.__('Attach this file to entry').'').'

        '; +} + + +$items = array_values(array_merge($dir['dirs'],$dir['files'])); +if (count($items) == 0) +{ + echo '

        '.__('No file.').'

        '; +} +else +{ + $pager = new pager($page,count($items),$nb_per_page,10); + $pager->html_prev = __($pager->html_prev); + $pager->html_next = __($pager->html_next); + + echo + '
        '. + '

        '. + form::hidden(array('popup'),$popup). + form::hidden(array('post_id'),$post_id). + '

        '. + '
        '. + + '
        '. + '

        '.__('Page(s)').' : '.$pager->getLinks().'

        '; + + for ($i=$pager->index_start, $j=0; $i<=$pager->index_end; $i++, $j++) + { + echo mediaItemLine($items[$i],$j); + } + + echo + '

        '.__('Page(s)').' : '.$pager->getLinks().'

        '. + '
        '; +} + +if ($core_media_writable) +{ + echo '
        '; + + echo + '
        '. + '
        '.__('Add files').''. + '

        '.__('Please take care to publish media that you own and that are not protected by copyright.').'

        '. + '
        '. + '
        '.form::hidden(array('MAX_FILE_SIZE'),DC_MAX_UPLOAD_SIZE). + $core->formNonce().'
        '. + '

        '. + '

        '. + '

        '. + '

        '.__('To send several files at the same time, you can activate the enhanced uploader in'). + ' '.__('My preferences').'

        '. + '

        '. + form::hidden(array('d'),$d).'

        '. + '
        '. + ''. + '
        '; + + echo + '
        '. + '
        '. + '
        '. + ''.__('New directory').''. + $core->formNonce(). + '

        '. + '

        '. + form::hidden(array('d'),html::escapeHTML($d)).'

        '. + '
        '. + '
        '; + + echo '
        '; +} + +# Empty remove form (for javascript actions) +echo +'
        '. +form::hidden('rmyes',1).form::hidden('d',html::escapeHTML($d)). +form::hidden('remove',''). +$core->formNonce(). +'
        '; + +# Get zip directory +if ($core->auth->check('media_admin',$core->blog->id) && + !(count($items) == 0 || (count($items) == 1 && $items[0]->parent))) +{ + echo + '

        '. + __('Download this directory as a zip file').'

        '; +} + +call_user_func($close_f); + +/* ----------------------------------------------------- */ +function mediaItemLine($f,$i) +{ + global $core, $page_url, $popup, $post_id; + + $fname = $f->basename; + + if ($f->d) { + $link = html::escapeURL($page_url).'&d='.html::sanitizeURL($f->relname); + if ($f->parent) { + $fname = '..'; + } + } else { + $link = + 'media_item.php?id='.$f->media_id.'&popup='.$popup.'&post_id='.$post_id; + } + + $class = 'media-item media-col-'.($i%2); + + $res = + '
        '. + ''. + '
          '. + '
        • '.$fname.'
        • '; + + if (!$f->d) { + $res .= + '
        • '.$f->media_title.'
        • '. + '
        • '. + $f->media_dtstr.' - '. + files::size($f->size).' - '. + ''.__('open').''. + '
        • '; + } + + $res .= '
        •  '; + + if ($post_id && !$f->d) { + $res .= '
          '. + ' '. + form::hidden('media_id',$f->media_id). + form::hidden('post_id',$post_id). + form::hidden('attach',1). + $core->formNonce(). + '
          '; + } + + if ($popup && !$f->d) { + $res .= ''.__('Insert this file into entry').' '; + } + + if ($f->del) { + $res .= ''. + ''.__('Delete').''; + } + + $res .= '
        • '; + + if ($f->type == 'audio/mpeg3') { + $res .= '
        • '.dcMedia::mp3player($f->file_url,'index.php?pf=player_mp3.swf').'
        • '; + } + + $res .= '
        '; + + return $res; +} +?> \ No newline at end of file diff --git a/v2/dotclear/admin/media_item.php b/v2/dotclear/admin/media_item.php new file mode 100644 index 0000000..3b4ffd0 --- /dev/null +++ b/v2/dotclear/admin/media_item.php @@ -0,0 +1,528 @@ +blog->getPosts(array('post_id'=>$post_id)); + if ($post->isEmpty()) { + $post_id = null; + } + $post_title = $post->post_title; + unset($post); +} + +$file = null; +$popup = (integer) !empty($_GET['popup']); +$page_url = 'media_item.php?popup='.$popup.'&post_id='.$post_id; +$media_page_url = 'media.php?popup='.$popup.'&post_id='.$post_id; + +$id = !empty($_REQUEST['id']) ? (integer) $_REQUEST['id'] : ''; + +if ($popup) { + $open_f = array('dcPage','openPopup'); + $close_f = array('dcPage','closePopup'); +} else { + $open_f = array('dcPage','open'); + $close_f = create_function('',"dcPage::helpBlock('core_media'); dcPage::close();"); +} + +$core_media_writable = false; +try +{ + $core->media = new dcMedia($core); + + if ($id) { + $file = $core->media->getFile($id); + } + + if ($file === null) { + throw new Exception(__('Not a valid file')); + } + + $core->media->chdir(dirname($file->relname)); + $core_media_writable = $core->media->writable(); + + # Prepare directories combo box + $dirs_combo = array(); + foreach ($core->media->getRootDirs() as $v) { + if ($v->w) { + $dirs_combo['/'.$v->relname] = $v->relname; + } + } + ksort($dirs_combo); +} +catch (Exception $e) +{ + $core->error->add($e->getMessage()); +} + +# Upload a new file +if ($file && !empty($_FILES['upfile']) && $file->editable && $core_media_writable) +{ + try { + files::uploadStatus($_FILES['upfile']); + $core->media->uploadFile($_FILES['upfile']['tmp_name'],$file->basename,null,false,true); + http::redirect($page_url.'&id='.$id.'&fupl=1'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} + +# Update file +if ($file && !empty($_POST['media_file']) && $file->editable && $core_media_writable) +{ + $newFile = clone $file; + + $newFile->basename = $_POST['media_file']; + + if ($_POST['media_path']) { + $newFile->dir = $_POST['media_path']; + $newFile->relname = $_POST['media_path'].'/'.$newFile->basename; + } else { + $newFile->dir = ''; + $newFile->relname = $newFile->basename; + } + $newFile->media_title = $_POST['media_title']; + $newFile->media_dt = strtotime($_POST['media_dt']); + $newFile->media_dtstr = $_POST['media_dt']; + $newFile->media_priv = !empty($_POST['media_private']); + + try { + $core->media->updateFile($file,$newFile); + http::redirect($page_url.'&id='.$id.'&fupd=1'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} + +# Update thumbnails +if (!empty($_POST['thumbs']) && $file->media_type == 'image' && $file->editable && $core_media_writable) +{ + try { + $foo = null; + $core->media->mediaFireRecreateEvent($file); + http::redirect($page_url.'&id='.$id.'&thumbupd=1'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} + +# Unzip file +if (!empty($_POST['unzip']) && $file->type == 'application/zip' && $file->editable && $core_media_writable) +{ + try { + $unzip_dir = $core->media->inflateZipFile($file,$_POST['inflate_mode'] == 'new'); + http::redirect($media_page_url.'&d='.$unzip_dir.'&unzipok=1'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} + +# Function to get image title based on meta +function dcGetImageTitle($file,$pattern) +{ + $res = array(); + $pattern = preg_split('/\s*;;\s*/',$pattern); + $sep = ', '; + + foreach ($pattern as $v) { + if ($v == 'Title') { + $res[] = $file->media_title; + } elseif ($file->media_meta->{$v}) { + $res[] = (string) $file->media_meta->{$v}; + } elseif (preg_match('/^Date\((.+?)\)$/u',$v,$m)) { + $res[] = dt::str($m[1],$file->media_dt); + } elseif (preg_match('/^DateTimeOriginal\((.+?)\)$/u',$v,$m) && $file->media_meta->DateTimeOriginal) { + $res[] = dt::dt2str($m[1],(string) $file->media_meta->DateTimeOriginal); + } elseif (preg_match('/^separator\((.*?)\)$/u',$v,$m)) { + $sep = $m[1]; + } + } + return implode($sep,$res); +} + +/* DISPLAY Main page +-------------------------------------------------------- */ +$starting_scripts = dcPage::jsLoad('js/_media_item.js'); +if ($popup) { + $starting_scripts .= + dcPage::jsLoad('js/jsToolBar/popup_media.js'); +} +call_user_func($open_f,__('Media manager'), + $starting_scripts. + dcPage::jsDatePicker(). + dcPage::jsPageTabs() +); + +if ($file === null) { + call_user_func($close_f); + exit; +} + +if (!empty($_GET['fupd']) || !empty($_GET['fupl'])) { + echo '

        '.__('File has been successfully updated.').'

        '; +} +if (!empty($_GET['thumbupd'])) { + echo '

        '.__('Thumbnails have been successfully updated.').'

        '; +} + +echo '

        '.__('Media manager').''. +' / '.$core->media->breadCrumb(html::escapeURL($media_page_url).'&d=%s'). +''.$file->basename.'

        '; + +# Insertion popup +if ($popup) +{ + $media_desc = $file->media_title; + + echo + '
        '. + '
        '; + + if ($file->media_type == 'image') + { + $media_type = 'image'; + $media_desc = dcGetImageTitle($file,$core->blog->settings->system->media_img_title_pattern); + if ($media_desc == $file->basename) { + $media_desc = ''; + } + + echo + '

        '.__('Image size:').'

        '; + + $s_checked = false; + echo '

        '; + foreach (array_reverse($file->media_thumb) as $s => $v) { + $s_checked = ($s == 'm'); + echo '
        '; + } + $s_checked = (!isset($file->media_thumb['m'])); + echo '
        '; + echo '

        '; + + + echo '

        '.__('Image alignment').'

        '; + $i_align = array( + 'none' => array(__('None'),1), + 'left' => array(__('Left'),0), + 'right' => array(__('Right'),0), + 'center' => array(__('Center'),0) + ); + + echo '

        '; + foreach ($i_align as $k => $v) { + echo '
        '; + } + echo '

        '; + + echo + '

        '.__('Image insertion').'

        '. + '

        '. + '
        '. + ''. + '

        '; + } + elseif ($file->type == 'audio/mpeg3') + { + $media_type = 'mp3'; + + echo '

        '.__('MP3 disposition').'

        '. + '

        '.__("Please note that you cannot insert mp3 files with visual editor.").'

        '; + + $i_align = array( + 'none' => array(__('None'),0), + 'left' => array(__('Left'),0), + 'right' => array(__('Right'),0), + 'center' => array(__('Center'),1) + ); + + echo '

        '; + foreach ($i_align as $k => $v) { + echo '
        '; + } + + $public_player_style = unserialize($core->blog->settings->themes->mp3player_style); + $public_player = dcMedia::mp3player($file->file_url,$core->blog->getQmarkURL().'pf=player_mp3.swf',$public_player_style); + echo form::hidden('public_player',html::escapeHTML($public_player)); + echo '

        '; + } + elseif ($file->type == 'video/x-flv' || $file->type == 'video/mp4' || $file->type == 'video/x-m4v') + { + $media_type = 'flv'; + + echo + '

        '.__("Please note that you cannot insert video files with visual editor.").'

        '; + + echo + '

        '.__('Video size').'

        '. + '

        '; + + echo '

        '.__('Video disposition').'

        '; + + $i_align = array( + 'none' => array(__('None'),0), + 'left' => array(__('Left'),0), + 'right' => array(__('Right'),0), + 'center' => array(__('Center'),1) + ); + + echo '

        '; + foreach ($i_align as $k => $v) { + echo '
        '; + } + + $public_player_style = unserialize($core->blog->settings->themes->flvplayer_style); + $public_player = dcMedia::flvplayer($file->file_url,$core->blog->getQmarkURL().'pf=player_flv.swf',$public_player_style); + echo form::hidden('public_player',html::escapeHTML($public_player)); + echo '

        '; + } + else + { + $media_type = 'default'; + echo '

        '.__('Media item will be inserted as a link.').'

        '; + } + + echo + '

        '.__('Cancel').' - '. + ''.__('Insert').''. + form::hidden(array('type'),html::escapeHTML($media_type)). + form::hidden(array('title'),html::escapeHTML($file->media_title)). + form::hidden(array('description'),html::escapeHTML($media_desc)). + form::hidden(array('url'),$file->file_url). + '

        '; + + echo '
        '; +} + +echo +'
        '. +'

        '; + +echo +'
        '; + +if ($file->media_image) +{ + $thumb_size = !empty($_GET['size']) ? $_GET['size'] : 's'; + + if (!isset($core->media->thumb_sizes[$thumb_size]) && $thumb_size != 'o') { + $thumb_size = 's'; + } + + echo '

        '.__('Available sizes:').' '; + foreach (array_reverse($file->media_thumb) as $s => $v) + { + $strong_link = ($s == $thumb_size) ? '%s' : '%s'; + printf($strong_link,''.$core->media->thumb_sizes[$s][2].' | '); + } + echo ''.__('original').''; + echo '

        '; + + if (isset($file->media_thumb[$thumb_size])) { + echo '

        '; + } elseif ($thumb_size == 'o') { + $S = getimagesize($file->file); + $class = ($S[1] > 500) ? ' class="overheight"' : ''; + unset($S); + echo '

        '; + } +} + +if ($file->type == 'audio/mpeg3') +{ + echo dcMedia::mp3player($file->file_url,'index.php?pf=player_mp3.swf'); +} + +if ($file->type == 'video/x-flv' || $file->type == 'video/mp4' || $file->type == 'video/x-m4v') +{ + echo dcMedia::flvplayer($file->file_url,'index.php?pf=player_flv.swf'); +} + +echo +'

        '.__('Media details').'

        '. +'
          '. + '
        • '.__('File owner:').' '.$file->media_user.'
        • '. + '
        • '.__('File type:').' '.$file->type.'
        • '. + '
        • '.__('File size:').' '.files::size($file->size).'
        • '. + '
        • '.__('File URL:').' '.$file->file_url.'
        • '. +'
        '; + +if (empty($_GET['find_posts'])) +{ + echo + '

        '. + __('Show entries containing this media').'

        '; +} +else +{ + echo '

        '.__('Entries containing this media').'

        '; + $params = array( + 'post_type' => '', + 'from' => 'LEFT OUTER JOIN '.$core->prefix.'post_media PM ON P.post_id = PM.post_id ', + 'sql' => 'AND ('. + 'PM.media_id = '.(integer) $id.' '. + "OR post_content_xhtml LIKE '%".$core->con->escape($file->relname)."%' ". + "OR post_excerpt_xhtml LIKE '%".$core->con->escape($file->relname)."%' " + ); + + if ($file->media_image) + { # We look for thumbnails too + if (preg_match('#^http(s)?://#',$core->blog->settings->system->public_url)) { + $media_root = $core->blog->settings->system->public_url; + } else { + $media_root = $core->blog->host.path::clean($core->blog->settings->system->public_url).'/'; + } + foreach ($file->media_thumb as $v) { + $v = preg_replace('/^'.preg_quote($media_root,'/').'/','',$v); + $params['sql'] .= "OR post_content_xhtml LIKE '%".$core->con->escape($v)."%' "; + $params['sql'] .= "OR post_excerpt_xhtml LIKE '%".$core->con->escape($v)."%' "; + } + } + + $params['sql'] .= ') '; + + $rs = $core->blog->getPosts($params); + + if ($rs->isEmpty()) + { + echo '

        '.__('No entry seems contain this media.').'

        '; + } + else + { + echo '
          '; + while ($rs->fetch()) { + echo '
        • '. + $rs->post_title.''. + ($rs->post_type != 'post' ? ' ('.html::escapeHTML($rs->post_type).')' : ''). + ' - '.dt::dt2str(__('%Y-%m-%d %H:%M'),$rs->post_dt).'
        • '; + } + echo '
        '; + } +} + +if ($file->type == 'image/jpeg') +{ + echo '

        '.__('Image details').'

        '; + + if (count($file->media_meta) == 0) + { + echo '

        '.__('No detail').'

        '; + } + else + { + echo '
          '; + foreach ($file->media_meta as $k => $v) + { + if ((string) $v) { + echo '
        • '.$k.': '.html::escapeHTML($v).'
        • '; + } + } + echo '
        '; + } +} + +if ($file->editable && $core_media_writable) +{ + if ($file->media_type == 'image') + { + echo + '
        '. + '
        '.__('Update thumbnails').''. + '

        '.__('This will create or update thumbnails for this image.').'

        '. + '

        '. + form::hidden(array('id'),$id). + $core->formNonce().'

        '. + '
        '; + } + + if ($file->type == 'application/zip') + { + $inflate_combo = array( + __('Extract in a new directory') => 'new', + __('Extract in current directory') => 'current' + ); + + echo + '
        '. + '
        '.__('Extract archive').''. + '
          '. + '
        • '.__('Extract in a new directory').' : '. + __('This will extract archive in a new directory that should not exist yet.').'
        • '. + '
        • '.__('Extract in current directory').' : '. + __('This will extract archive in current directory and will overwrite existing files or directory.').'
        • '. + '
        '. + '

        '. + ''. + form::hidden(array('id'),$id). + $core->formNonce().'

        '. + '
        '; + } + + echo + '
        '. + '
        '.__('Change media properties').''. + '

        '. + '

        '. + '

        '. + '

        '. + '

        '. + '

        '. + form::hidden(array('id'),$id). + $core->formNonce().'

        '. + '
        '; + + echo + '
        '. + '
        '.__('Change file').''. + '
        '.form::hidden(array('MAX_FILE_SIZE'),DC_MAX_UPLOAD_SIZE).'
        '. + '

        '. + '

        '. + form::hidden(array('id'),$id). + $core->formNonce().'

        '. + '
        '; + + # --BEHAVIOR-- adminMediaItemForm + $core->callBehavior('adminMediaItemForm',$file); +} + +echo +'
        '. +'
        '; + +call_user_func($close_f); +?> \ No newline at end of file diff --git a/v2/dotclear/admin/permissions.php b/v2/dotclear/admin/permissions.php new file mode 100644 index 0000000..a0dd0a6 --- /dev/null +++ b/v2/dotclear/admin/permissions.php @@ -0,0 +1,160 @@ +userExists($u)) { + $users[] = $u; + } + } +} + +# Check blogs +if (!empty($_REQUEST['blog_id']) && is_array($_REQUEST['blog_id'])) +{ + foreach ($_REQUEST['blog_id'] as $b) + { + if ($core->blogExists($b)) { + $blogs[] = $b; + } + } +} + +# Update permissions +if (!empty($_POST['upd_perm']) && !empty($users) && !empty($blogs)) +{ + $redir = 'permissions.php?upd=1'; + + try + { + if (empty($_POST['your_pwd']) || !$core->auth->checkPassword(crypt::hmac(DC_MASTER_KEY,$_POST['your_pwd']))) { + throw new Exception(__('Password verification failed')); + } + + foreach ($users as $u) + { + foreach ($blogs as $b) + { + $set_perms = array(); + + if (!empty($_POST['perm'][$b])) + { + foreach ($_POST['perm'][$b] as $perm_id => $v) + { + if ($v) { + $set_perms[$perm_id] = true; + } + } + } + + $core->setUserBlogPermissions($u, $b, $set_perms, true); + } + + $redir .= '&user_id[]='.$u; + } + + foreach ($blogs as $b) { + $redir .= '&blog_id[]='.$b; + } + http::redirect($redir); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} + + + +if (empty($blogs) || empty($users)) { + $core->error->add(__('No blog or user given.')); +} + + +/* DISPLAY +-------------------------------------------------------- */ +dcPage::open(__('permissions'), + dcPage::jsLoad('js/_permissions.js') +); + +echo '

        '.__('Users').''.__('Permissions').'

        '; + +if (!empty($_GET['upd'])) { + echo '

        '.__('The permissions have been successfully updated.').'

        '; +} + +if (!empty($blogs) && !empty($users)) +{ + $perm_form = ''; + + if (count($users) == 1) { + $user_perm = $core->getUserPermissions($users[0]); + } + + foreach ($users as $u) { + $user_list[] = ''.$u.''; + } + + echo '

        '.sprintf(__('You are about to change permissions on the following blogs for users %s.'), + implode(', ',$user_list)); + + echo '

        '; + + foreach ($blogs as $b) + { + echo '

        '.html::escapeHTML($b).''. + form::hidden(array('blog_id[]'),$b).'

        '; + + foreach ($core->auth->getPermissionsTypes() as $perm_id => $perm) + { + $checked = false; + + if (count($users) == 1) { + $checked = isset($user_perm[$b]['p'][$perm_id]) && $user_perm[$b]['p'][$perm_id]; + } + + echo + '

        '; + } + } + + echo + '
        '.__('Validate permissions').''. + '

        '. + '
        '. + '

        '. + $core->formNonce(); + + foreach ($users as $u) { + echo form::hidden(array('user_id[]'),$u); + } + + echo form::hidden('upd_perm',1).'

        '; +} + +dcPage::close(); +?> \ No newline at end of file diff --git a/v2/dotclear/admin/permissions_blog.php b/v2/dotclear/admin/permissions_blog.php new file mode 100644 index 0000000..3757788 --- /dev/null +++ b/v2/dotclear/admin/permissions_blog.php @@ -0,0 +1,196 @@ + 'B.blog_id', +__('Blog name') => 'blog_name' +); + +$order_combo = array( +__('Descending') => 'desc', +__('Ascending') => 'asc' +); + +$q = !empty($_GET['q']) ? $_GET['q'] : ''; +$sortby = !empty($_GET['sortby']) ? $_GET['sortby'] : 'blog_id'; +$order = !empty($_GET['order']) ? $_GET['order'] : 'asc'; + + +# Check users +if (!empty($_REQUEST['user_id']) && is_array($_REQUEST['user_id'])) +{ + foreach ($_REQUEST['user_id'] as $u) + { + if ($core->userExists($u)) { + $users[] = $u; + } + } +} + +if (empty($users)) +{ + $core->error->add(__('No blog or user given.')); +} +else +{ + $page = !empty($_GET['page']) ? $_GET['page'] : 1; + $nb_per_page = 30; + + if (!empty($_GET['nb']) && (integer) $_GET['nb'] > 0) { + $nb_per_page = $_GET['nb']; + } + + $show_filters = false; + + # - Search filter + if ($q) { + $params['q'] = $q; + $show_filters = true; + } + + # - Sortby and order filter + if ($sortby !== '' && in_array($sortby,$sortby_combo)) { + if ($order !== '' && in_array($order,$order_combo)) { + $params['order'] = $sortby.' '.$order; + $show_filters = true; + } + } + + $params['limit'] = array((($page-1)*$nb_per_page),$nb_per_page); + + try { + $rs = $core->getBlogs($params); + $counter = $core->getBlogs($params,1); + $nb_blog = $counter->f(0); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} + +/* DISPLAY +-------------------------------------------------------- */ +$starting_script = dcPage::jsLoad('js/_permissions_blog.js'); +if (!$show_filters) { + $starting_script .= dcPage::jsLoad('js/filter-controls.js'); +} +dcPage::open(__('choose a blog'),$starting_script); + +echo '

        '.__('Users').''.__('Choose a blog').'

        '; + +if (!$core->error->flag()) +{ + $hidden_fields = ''; + foreach ($users as $u) { + $hidden_fields .= form::hidden(array('user_id[]'),$u); + } + + if (!$show_filters) { + echo '

        '.__('Filters').'

        '; + } + + echo + '
        '. + '
        '.__('Filters').''. + + '
        '. + '

        '. + '

        '. + '
        '. + + '
        '. + '

        '. + '

        '. + ''. + $hidden_fields.'

        '. + '
        '. + + '
        '. //Opera sucks + '
        '. + '
        '; + + echo + '

        '. + sprintf(__('Choose one or more blogs to which you want to give permissions to users %s.'), + ''.implode(', ',$users).'').'

        '; + + # Show blogs + if ($nb_blog == 0) + { + echo '

        '.__('No blog').'

        '; + } + else + { + $pager = new pager($page,$nb_blog,$nb_per_page,10); + $pager->var_page = 'page'; + + echo '

        '.__('Page(s)').' : '.$pager->getLinks().'

        '; + + echo + '
        '. + ''. + ''. + ''. + ''. + ''. + ''; + + while ($rs->fetch()) { + echo blogLine($rs); + } + + echo + '
        '.__('Blog ID').''.__('Blog name').''.__('Entries').''.__('Status').'
        '. + + '

        '. + + '

        '. + $hidden_fields. + $core->formNonce().'

        '. + '
        '; + + echo '

        '.__('Page(s)').' : '.$pager->getLinks().'

        '; + } +} + +dcPage::close(); + +function blogLine($rs) +{ + global $core; + + $img_status = $rs->blog_status == 1 ? 'check-on' : 'check-off'; + $txt_status = $GLOBALS['core']->getBlogStatus($rs->blog_status); + $img_status = sprintf('%2$s',$img_status,$txt_status); + + return + ''. + ''. + form::checkbox(array('blog_id[]'),$rs->blog_id,'','','',false,'title="'.__('select').' '.$rs->blog_id.'"').''. + ''.$rs->blog_id.''. + ''.html::escapeHTML($rs->blog_name).''. + ''.$core->countBlogPosts($rs->blog_id).''. + ''.$img_status.''. + ''; +} +?> \ No newline at end of file diff --git a/v2/dotclear/admin/plugin.php b/v2/dotclear/admin/plugin.php new file mode 100644 index 0000000..cea46d5 --- /dev/null +++ b/v2/dotclear/admin/plugin.php @@ -0,0 +1,91 @@ +plugins->moduleExists($p)) { + $p_file = $core->plugins->moduleRoot($p).'/index.php'; +} + +if (file_exists($p_file)) +{ + # Loading plugin + $p_info = $core->plugins->getModules($p); + + $p_url = 'plugin.php?p='.$p; + + $p_title = 'no content - plugin'; + $p_head = ''; + $p_content = '

        '.__('No content found on this plugin.').'

        '; + + ob_start(); + include $p_file; + $res = ob_get_contents(); + ob_end_clean(); + + if (preg_match('|(.*?)(.*?)|ms',$m[1],$mt)) { + $p_title = $mt[1]; + } + + if (preg_match_all('|(.*?)|ms',$m[1],$ms)) { + foreach ($ms[1] as $v) { + $p_head .= $v."\n"; + } + } + + if (preg_match_all('|(.*?)|ms',$m[1],$ms)) { + foreach ($ms[1] as $v) { + $p_head .= $v."\n"; + } + } + + if (preg_match_all('|()|ms',$m[1],$ms)) { + foreach ($ms[1] as $v) { + $p_head .= $v."\n"; + } + } + } + + if (preg_match('|(.+)|ms',$res,$m)) { + $p_content = $m[1]; + } + + call_user_func($open_f,$p_title,$p_head); + echo $p_content; + call_user_func($close_f); +} +else +{ + call_user_func($open_f,__('Plugin not found')); + + echo '

        '.__('Plugin not found').'

        '; + + echo '

        '.__('The plugin you reached does not exist or does not have an admin page.').'

        '; + + call_user_func($close_f); +} +?> \ No newline at end of file diff --git a/v2/dotclear/admin/plugins.php b/v2/dotclear/admin/plugins.php new file mode 100644 index 0000000..cdc7a61 --- /dev/null +++ b/v2/dotclear/admin/plugins.php @@ -0,0 +1,364 @@ +plugins->moduleExists($plugin_id)) { + throw new Exception(__('No such plugin.')); + } + + $plugin = $core->plugins->getModules($plugin_id); + $plugin['id'] = $plugin_id; + + if (!preg_match('!^'.$p_path_pat.'!', $plugin['root'])) { + throw new Exception(__('You don\'t have permissions to delete this plugin.')); + } + + # --BEHAVIOR-- pluginBeforeDelete + $core->callBehavior('pluginsBeforeDelete', $plugin); + + $core->plugins->deleteModule($plugin_id); + + # --BEHAVIOR-- pluginAfterDelete + $core->callBehavior('pluginsAfterDelete', $plugin); + } + else + { + $core->plugins->deleteModule($plugin_id,true); + } + + http::redirect('plugins.php?removed=1'); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } + } + # Deactivate plugin + elseif ($plugin_id && !empty($_POST['deactivate'])) + { + try + { + if (!$core->plugins->moduleExists($plugin_id)) { + throw new Exception(__('No such plugin.')); + } + + $plugin = $core->plugins->getModules($plugin_id); + $plugin['id'] = $plugin_id; + + if (!$plugin['root_writable']) { + throw new Exception(__('You don\'t have permissions to deactivate this plugin.')); + } + + $core->plugins->deactivateModule($plugin_id); + http::redirect('plugins.php'); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } + } + # Activate plugin + elseif ($plugin_id && !empty($_POST['activate'])) + { + try + { + $p = $core->plugins->getDisabledModules(); + if (!isset($p[$plugin_id])) { + throw new Exception(__('No such plugin.')); + } + $core->plugins->activateModule($plugin_id); + http::redirect('plugins.php'); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } + } + # Plugin upload + elseif ((!empty($_POST['upload_pkg']) && !empty($_FILES['pkg_file'])) || + (!empty($_POST['fetch_pkg']) && !empty($_POST['pkg_url']))) + { + try + { + if (empty($_POST['your_pwd']) || !$core->auth->checkPassword(crypt::hmac(DC_MASTER_KEY,$_POST['your_pwd']))) { + throw new Exception(__('Password verification failed')); + } + + if (!empty($_POST['upload_pkg'])) + { + files::uploadStatus($_FILES['pkg_file']); + + $dest = $p_path.'/'.$_FILES['pkg_file']['name']; + if (!move_uploaded_file($_FILES['pkg_file']['tmp_name'],$dest)) { + throw new Exception(__('Unable to move uploaded file.')); + } + } + else + { + $url = urldecode($_POST['pkg_url']); + $dest = $p_path.'/'.basename($url); + + try + { + $client = netHttp::initClient($url,$path); + $client->setUserAgent('Dotclear - http://www.dotclear.org/'); + $client->useGzip(false); + $client->setPersistReferers(false); + $client->setOutput($dest); + $client->get($path); + } + catch( Exception $e) + { + throw new Exception(__('An error occurred while downloading the file.')); + } + + unset($client); + } + + $ret_code = $core->plugins->installPackage($dest,$core->plugins); + http::redirect('plugins.php?added='.$ret_code); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + $default_tab = 'addplugin'; + } + } +} + +# Plugin install +$plugins_install = $core->plugins->installModules(); + +/* DISPLAY Main page +-------------------------------------------------------- */ +dcPage::open(__('Plugins management'), + dcPage::jsLoad('js/_plugins.js'). + dcPage::jsPageTabs($default_tab) +); + +echo +'

        '.__('Plugins management').'

        '; + +if (!empty($_GET['removed'])) { + echo + '

        '.__('Plugin has been successfully deleted.').'

        '; +} +if (!empty($_GET['added'])) { + echo '

        '. + ($_GET['added'] == 2 ? __('Plugin has been successfully upgraded') : __('Plugin has been successfully installed.')). + '

        '; +} + +# Plugins install messages +if (!empty($plugins_install['success'])) +{ + echo '
        '.__('Following plugins have been installed:').'
          '; + foreach ($plugins_install['success'] as $k => $v) { + echo '
        • '.$k.'
        • '; + } + echo '
        '; +} +if (!empty($plugins_install['failure'])) +{ + echo '
        '.__('Following plugins have not been installed:').'
          '; + foreach ($plugins_install['failure'] as $k => $v) { + echo '
        • '.$k.' ('.$v.')
        • '; + } + echo '
        '; +} + +# List all active plugins +echo '

        '.__('Plugins add new functionalities to Dotclear. '. +'Here you can activate or deactivate installed plugins.').'

        '; + +echo '

        '.sprintf(__('You can find additional plugins for your blog on %s.'), +'Dotaddict').' '; + +if ($is_writable) { + echo __('To install or upgrade a plugin you generally just need to upload it '. + 'in "Install or upgrade a plugin" section.'); +} else { + echo __('To install or upgrade a plugin you just need to extract it in your plugins directory.'); +} +echo '

        '; + +echo +'
        '; + +$p_available = $core->plugins->getModules(); +uasort($p_available,create_function('$a,$b','return strcasecmp($a["name"],$b["name"]);')); +if (!empty($p_available)) +{ + echo + '

        '.__('Activated plugins').'

        '. + ''. + ''. + ''. + ''. + ''. + ''; + + foreach ($p_available as $k => $v) + { + $is_deletable = $is_writable && preg_match('!^'.$p_path_pat.'!',$v['root']); + $is_deactivable = $v['root_writable']; + + echo + ''. + ''. + ''. + ''. + ''. + ''; + } + echo + '
        '.__('Plugin').''.__('Version').''.__('Details').''.__('Action').'
        '.html::escapeHTML($k).''.html::escapeHTML($v['version']).''.html::escapeHTML($v['name']).' '. + '
        '.html::escapeHTML($v['desc']).'
        '; + + if ($is_deletable || $is_deactivable) + { + echo + '
        '. + '
        '. + $core->formNonce(). + form::hidden(array('plugin_id'),html::escapeHTML($k)). + ($is_deactivable ? ' ' : ''). + ($is_deletable ? ' ' : ''). + '
        '. + '
        '; + } + + echo + '
        '; +} + +$p_disabled = $core->plugins->getDisabledModules(); +uksort($p_disabled,create_function('$a,$b','return strcasecmp($a,$b);')); +if (!empty($p_disabled)) +{ + echo + '

        '.__('Deactivated plugins').'

        '. + ''. + ''. + ''. + ''; + + foreach ($p_disabled as $k => $v) + { + $is_deletable = $is_writable && preg_match('!^'.$p_path_pat.'!',$v['root']); + $is_activable = $v['root_writable']; + + echo + ''. + ''. + ''. + ''; + } + echo + '
        '.__('Plugin').''.__('Action').'
        '.html::escapeHTML($k).''; + + if ($is_deletable || $is_activable) + { + echo + '
        '. + '
        '. + $core->formNonce(). + form::hidden(array('plugin_id'),html::escapeHTML($k)). + form::hidden(array('deactivated'),1). + ($is_activable ? ' ' : ''). + ($is_deletable ? ' ' : ''). + '
        '. + '
        '; + } + + echo + '
        '; +} + +echo '
        '; + +# Add a new plugin +echo +'
        '; + +if ($is_writable) +{ + echo '

        '.__('You can install plugins by uploading or downloading zip files.').'

        '; + + # 'Upload plugin' form + echo + '
        '. + '
        '. + ''.__('Upload a zip file').''. + '

        '. + '

        '. + ''. + $core->formNonce(). + '
        '. + '
        '; + + # 'Fetch plugin' form + echo + '
        '. + '
        '. + ''.__('Download a zip file').''. + '

        '. + '

        '. + ''. + $core->formNonce(). + '
        '. + '
        '; +} +else +{ + echo + '

        '. + __('To enable this function, please give write access to your plugins directory.'). + '

        '; +} +echo '
        '; + +# --BEHAVIOR-- pluginsToolsTabs +$core->callBehavior('pluginsToolsTabs',$core); + +dcPage::close(); +?> \ No newline at end of file diff --git a/v2/dotclear/admin/popup_link.php b/v2/dotclear/admin/popup_link.php new file mode 100644 index 0000000..5f3bddd --- /dev/null +++ b/v2/dotclear/admin/popup_link.php @@ -0,0 +1,62 @@ +'.__('Add a link').''; + +# Languages combo +$rs = $core->blog->getLangs(array('order'=>'asc')); +$all_langs = l10n::getISOcodes(0,1); +$lang_combo = array('' => '', __('Most used') => array(), __('Available') => l10n::getISOcodes(1,1)); +while ($rs->fetch()) { + if (isset($all_langs[$rs->post_lang])) { + $lang_combo[__('Most used')][$all_langs[$rs->post_lang]] = $rs->post_lang; + unset($lang_combo[__('Available')][$all_langs[$rs->post_lang]]); + } else { + $lang_combo[__('Most used')][$rs->post_lang] = $rs->post_lang; + } +} +unset($all_langs); +unset($rs); + +echo +''. + +'

        '.__('Cancel').' - '. +''.__('Insert').'

        '."\n". + +''."\n"; + +dcPage::closePopup(); +?> \ No newline at end of file diff --git a/v2/dotclear/admin/popup_posts.php b/v2/dotclear/admin/popup_posts.php new file mode 100644 index 0000000..46591f4 --- /dev/null +++ b/v2/dotclear/admin/popup_posts.php @@ -0,0 +1,57 @@ +'.__('Add a link to an entry').''; + +echo '
        '. +'

        '. +'

        '. +'
        '; + +try { + $posts = $core->blog->getPosts($params); + $counter = $core->blog->getPosts($params,true); + $post_list = new adminPostMiniList($core,$posts,$counter->f(0)); +} catch (Exception $e) { + $core->error->add($e->getMessage()); +} + +echo '
        '; # I know it's not a form but we just need the ID +$post_list->display($page,$nb_per_page); +echo '
        '; + +echo '

        '.__('cancel').'

        '; + +dcPage::closePopup(); +?> \ No newline at end of file diff --git a/v2/dotclear/admin/post.php b/v2/dotclear/admin/post.php new file mode 100644 index 0000000..02493ec --- /dev/null +++ b/v2/dotclear/admin/post.php @@ -0,0 +1,624 @@ +auth->getOption('post_format'); +$post_password = ''; +$post_url = ''; +$post_lang = $core->auth->getInfo('user_lang'); +$post_title = ''; +$post_excerpt = ''; +$post_excerpt_xhtml = ''; +$post_content = ''; +$post_content_xhtml = ''; +$post_notes = ''; +$post_status = $core->auth->getInfo('user_post_status'); +$post_selected = false; +$post_open_comment = $core->blog->settings->system->allow_comments; +$post_open_tb = $core->blog->settings->system->allow_trackbacks; + +$page_title = __('New entry'); + +$can_view_page = true; +$can_edit_post = $core->auth->check('usage,contentadmin',$core->blog->id); +$can_publish = $core->auth->check('publish,contentadmin',$core->blog->id); +$can_delete = false; + +$post_headlink = ''; +$post_link = '%s'; + +$next_link = $prev_link = $next_headlink = $prev_headlink = null; + +# If user can't publish +if (!$can_publish) { + $post_status = -2; +} + +# Getting categories +$categories_combo = array(' ' => ''); +try { + $categories = $core->blog->getCategories(array('post_type'=>'post')); + while ($categories->fetch()) { + $categories_combo[] = new formSelectOption( + str_repeat('  ',$categories->level-1).($categories->level-1 == 0 ? '' : '• ').html::escapeHTML($categories->cat_title), + $categories->cat_id + ); + } +} catch (Exception $e) { } + +# Status combo +foreach ($core->blog->getAllPostStatus() as $k => $v) { + $status_combo[$v] = (string) $k; +} + +# Formaters combo +foreach ($core->getFormaters() as $v) { + $formaters_combo[$v] = $v; +} + +# Languages combo +$rs = $core->blog->getLangs(array('order'=>'asc')); +$all_langs = l10n::getISOcodes(0,1); +$lang_combo = array('' => '', __('Most used') => array(), __('Available') => l10n::getISOcodes(1,1)); +while ($rs->fetch()) { + if (isset($all_langs[$rs->post_lang])) { + $lang_combo[__('Most used')][$all_langs[$rs->post_lang]] = $rs->post_lang; + unset($lang_combo[__('Available')][$all_langs[$rs->post_lang]]); + } else { + $lang_combo[__('Most used')][$rs->post_lang] = $rs->post_lang; + } +} +unset($all_langs); +unset($rs); + + +# Get entry informations +if (!empty($_REQUEST['id'])) +{ + $params['post_id'] = $_REQUEST['id']; + + $post = $core->blog->getPosts($params); + + if ($post->isEmpty()) + { + $core->error->add(__('This entry does not exist.')); + $can_view_page = false; + } + else + { + $post_id = $post->post_id; + $cat_id = $post->cat_id; + $post_dt = date('Y-m-d H:i',strtotime($post->post_dt)); + $post_format = $post->post_format; + $post_password = $post->post_password; + $post_url = $post->post_url; + $post_lang = $post->post_lang; + $post_title = $post->post_title; + $post_excerpt = $post->post_excerpt; + $post_excerpt_xhtml = $post->post_excerpt_xhtml; + $post_content = $post->post_content; + $post_content_xhtml = $post->post_content_xhtml; + $post_notes = $post->post_notes; + $post_status = $post->post_status; + $post_selected = (boolean) $post->post_selected; + $post_open_comment = (boolean) $post->post_open_comment; + $post_open_tb = (boolean) $post->post_open_tb; + + $page_title = __('Edit entry'); + + $can_edit_post = $post->isEditable(); + $can_delete= $post->isDeletable(); + + $next_rs = $core->blog->getNextPost($post,1); + $prev_rs = $core->blog->getNextPost($post,-1); + + if ($next_rs !== null) { + $next_link = sprintf($post_link,$next_rs->post_id, + html::escapeHTML($next_rs->post_title),__('next entry').' »'); + $next_headlink = sprintf($post_headlink,'next', + html::escapeHTML($next_rs->post_title),$next_rs->post_id); + } + + if ($prev_rs !== null) { + $prev_link = sprintf($post_link,$prev_rs->post_id, + html::escapeHTML($prev_rs->post_title),'« '.__('previous entry')); + $prev_headlink = sprintf($post_headlink,'previous', + html::escapeHTML($prev_rs->post_title),$prev_rs->post_id); + } + + try { + $core->media = new dcMedia($core); + } catch (Exception $e) {} + } +} + +# Format excerpt and content +if (!empty($_POST) && $can_edit_post) +{ + $post_format = $_POST['post_format']; + $post_excerpt = $_POST['post_excerpt']; + $post_content = $_POST['post_content']; + + $post_title = $_POST['post_title']; + + $cat_id = (integer) $_POST['cat_id']; + + if (isset($_POST['post_status'])) { + $post_status = (integer) $_POST['post_status']; + } + + if (empty($_POST['post_dt'])) { + $post_dt = ''; + } else { + $post_dt = strtotime($_POST['post_dt']); + $post_dt = date('Y-m-d H:i',$post_dt); + } + + $post_open_comment = !empty($_POST['post_open_comment']); + $post_open_tb = !empty($_POST['post_open_tb']); + $post_selected = !empty($_POST['post_selected']); + $post_lang = $_POST['post_lang']; + $post_password = !empty($_POST['post_password']) ? $_POST['post_password'] : null; + + $post_notes = $_POST['post_notes']; + + if (isset($_POST['post_url'])) { + $post_url = $_POST['post_url']; + } + + $core->blog->setPostContent( + $post_id,$post_format,$post_lang, + $post_excerpt,$post_excerpt_xhtml,$post_content,$post_content_xhtml + ); +} + +# Create or update post +if (!empty($_POST) && !empty($_POST['save']) && $can_edit_post) +{ + $cur = $core->con->openCursor($core->prefix.'post'); + + $cur->post_title = $post_title; + $cur->cat_id = ($cat_id ? $cat_id : null); + $cur->post_dt = $post_dt ? date('Y-m-d H:i:00',strtotime($post_dt)) : ''; + $cur->post_format = $post_format; + $cur->post_password = $post_password; + $cur->post_lang = $post_lang; + $cur->post_title = $post_title; + $cur->post_excerpt = $post_excerpt; + $cur->post_excerpt_xhtml = $post_excerpt_xhtml; + $cur->post_content = $post_content; + $cur->post_content_xhtml = $post_content_xhtml; + $cur->post_notes = $post_notes; + $cur->post_status = $post_status; + $cur->post_selected = (integer) $post_selected; + $cur->post_open_comment = (integer) $post_open_comment; + $cur->post_open_tb = (integer) $post_open_tb; + + if (isset($_POST['post_url'])) { + $cur->post_url = $post_url; + } + + # Update post + if ($post_id) + { + try + { + # --BEHAVIOR-- adminBeforePostUpdate + $core->callBehavior('adminBeforePostUpdate',$cur,$post_id); + + $core->blog->updPost($post_id,$cur); + + # --BEHAVIOR-- adminAfterPostUpdate + $core->callBehavior('adminAfterPostUpdate',$cur,$post_id); + + http::redirect('post.php?id='.$post_id.'&upd=1'); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } + } + else + { + $cur->user_id = $core->auth->userID(); + + try + { + # --BEHAVIOR-- adminBeforePostCreate + $core->callBehavior('adminBeforePostCreate',$cur); + + $return_id = $core->blog->addPost($cur); + + # --BEHAVIOR-- adminAfterPostCreate + $core->callBehavior('adminAfterPostCreate',$cur,$return_id); + + http::redirect('post.php?id='.$return_id.'&crea=1'); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } + } +} + +if (!empty($_POST['delete']) && $can_delete) +{ + try { + # --BEHAVIOR-- adminBeforePostDelete + $core->callBehavior('adminBeforePostDelete',$post_id); + $core->blog->delPost($post_id); + http::redirect('posts.php'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} + +/* DISPLAY +-------------------------------------------------------- */ +$default_tab = 'edit-entry'; +if (!$can_edit_post) { + $default_tab = ''; +} +if (!empty($_GET['co'])) { + $default_tab = 'comments'; +} + +dcPage::open($page_title.' - '.__('Entries'), + dcPage::jsDatePicker(). + dcPage::jsToolBar(). + dcPage::jsModal(). + dcPage::jsMetaEditor(). + dcPage::jsLoad('js/_post.js'). + dcPage::jsConfirmClose('entry-form','comment-form'). + # --BEHAVIOR-- adminPostHeaders + $core->callBehavior('adminPostHeaders'). + dcPage::jsPageTabs($default_tab). + $next_headlink."\n".$prev_headlink +); + +if (!empty($_GET['upd'])) { + echo '

        '.__('Entry has been successfully updated.').'

        '; +} +elseif (!empty($_GET['crea'])) { + echo '

        '.__('Entry has been successfully created.').'

        '; +} +elseif (!empty($_GET['attached'])) { + echo '

        '.__('File has been successfully attached.').'

        '; +} +elseif (!empty($_GET['rmattach'])) { + echo '

        '.__('Attachment has been successfully removed.').'

        '; +} + +if (!empty($_GET['creaco'])) { + echo '

        '.__('Comment has been successfully created.').'

        '; + } + +# XHTML conversion +if (!empty($_GET['xconv'])) +{ + $post_excerpt = $post_excerpt_xhtml; + $post_content = $post_content_xhtml; + $post_title = $post_title_xhtml; + $post_format = 'xhtml'; + + echo '

        '.__('Don\'t forget to validate your XHTML conversion by saving your post.').'

        '; +} + +echo '

        '.html::escapeHTML($core->blog->name).' › '.''.__('Entries').''.$page_title; + + if ($post_id) { + echo ' “'.$post_title.'”'; + } +echo '

        '; + +if ($post_id && $post->post_status == 1) { + echo '

        '.__('Go to this entry on the site').'

        '; +} +if ($post_id) +{ + echo '

        '; + if ($prev_link) { echo $prev_link; } + if ($next_link && $prev_link) { echo ' - '; } + if ($next_link) { echo $next_link; } + + # --BEHAVIOR-- adminPostNavLinks + $core->callBehavior('adminPostNavLinks',isset($post) ? $post : null); + + echo '

        '; +} + +# Exit if we cannot view page +if (!$can_view_page) { + dcPage::helpBlock('core_post'); + dcPage::close(); + exit; +} + +/* Post form if we can edit post +-------------------------------------------------------- */ +if ($can_edit_post) +{ + echo '
        '; + echo '
        '; + echo '
        '; + echo '
        '; + + echo + '

        '. + + '

        '. + form::textarea('post_excerpt',50,5,html::escapeHTML($post_excerpt)). + '

        '. + + '

        '. + form::textarea('post_content',50,$core->auth->getOption('edit_size'),html::escapeHTML($post_content)). + '

        '. + + '

        '. + form::textarea('post_notes',50,5,html::escapeHTML($post_notes)). + '

        '; + + # --BEHAVIOR-- adminPostForm + $core->callBehavior('adminPostForm',isset($post) ? $post : null); + + echo + '

        '. + ($post_id ? form::hidden('id',$post_id) : ''). + ' '; + if ($post_id) { + $preview_url = + $core->blog->url.$core->url->getURLFor('preview',$core->auth->userID().'/'. + http::browserUID(DC_MASTER_KEY.$core->auth->userID().$core->auth->getInfo('user_pwd')). + '/'.$post->post_url); + echo ''.__('Preview').' '; + } + echo + ($can_delete ? '' : ''). + $core->formNonce(). + '

        '; + + echo '
        '; // End #entry-content + echo '
        '; // End #entry-wrapper + + echo '
        '; + + echo + '

        '. + + '

        '. + + '

        '. + + '

        '. + '

        '. + '

        '.($post_id && $post_format != 'xhtml' ? ''.__('Convert to XHTML').'' : '').'

        '. + + '

        '. + '

        '. + '

        '. + + '

        '. + + '

        '. + + '
        '. + '

        '. + '

        '. + __('Warning: If you set the URL manually, it may conflict with another entry.'). + '

        '. + '
        '; + + # --BEHAVIOR-- adminPostFormSidebar + $core->callBehavior('adminPostFormSidebar',isset($post) ? $post : null); + + echo '
        '; // End #entry-sidebar + + echo '
        '; + + # --BEHAVIOR-- adminPostForm + $core->callBehavior('adminPostAfterForm',isset($post) ? $post : null); + + echo '
        '; + + if ($post_id && $post->post_status == 1) { + echo '

        '. + __('Ping blogs').'

        '; + } + +} + + +/* Comments and trackbacks +-------------------------------------------------------- */ +if ($post_id) +{ + $params = array('post_id' => $post_id, 'order' => 'comment_dt ASC'); + + $comments = $core->blog->getComments(array_merge($params,array('comment_trackback'=>0))); + $trackbacks = $core->blog->getComments(array_merge($params,array('comment_trackback'=>1))); + + # Actions combo box + $combo_action = array(); + if ($can_edit_post && $core->auth->check('publish,contentadmin',$core->blog->id)) + { + $combo_action[__('publish')] = 'publish'; + $combo_action[__('unpublish')] = 'unpublish'; + $combo_action[__('mark as pending')] = 'pending'; + $combo_action[__('mark as junk')] = 'junk'; + } + + if ($can_edit_post && $core->auth->check('delete,contentadmin',$core->blog->id)) + { + $combo_action[__('Delete')] = 'delete'; + } + + # --BEHAVIOR-- adminCommentsActionsCombo + $core->callBehavior('adminCommentsActionsCombo',array(&$combo_action)); + + $has_action = !empty($combo_action) && (!$trackbacks->isEmpty() || !$comments->isEmpty()); + + echo + '
        '; + + if ($has_action) { + echo '
        '; + } + + echo '

        '.__('Trackbacks').'

        '; + + if (!$trackbacks->isEmpty()) { + showComments($trackbacks,$has_action,true); + } else { + echo '

        '.__('No trackback').'

        '; + } + + echo '

        '.__('Comments').'

        '; + if (!$comments->isEmpty()) { + showComments($comments,$has_action); + } else { + echo '

        '.__('No comment').'

        '; + } + + if ($has_action) { + echo + '
        '. + '

        '. + + '

        '. + form::combo('action',$combo_action). + form::hidden('redir','post.php?id='.$post_id.'&co=1'). + $core->formNonce(). + '

        '. + '
        '. + '
        '; + } + + echo '
        '; +} + +/* Add a comment +-------------------------------------------------------- */ +if ($post_id) +{ + echo + '
        '. + '

        '.__('Add a comment').'

        '. + + '
        '. + '
        '. + '

        '. + + '

        '. + + '

        '. + + '

        '. + form::textarea('comment_content',50,8,html::escapeHTML('')). + '

        '. + + '

        '.form::hidden('post_id',$post_id). + $core->formNonce(). + '

        '. + '
        '. + '
        '. + '
        '; +} + + +# Show comments or trackbacks +function showComments($rs,$has_action,$tb=false) +{ + echo + ''. + ''. + ''. + ''. + ''. + ''. + ''; + + while($rs->fetch()) + { + $comment_url = 'comment.php?id='.$rs->comment_id; + + $img = '%1$s'; + switch ($rs->comment_status) { + case 1: + $img_status = sprintf($img,__('published'),'check-on.png'); + break; + case 0: + $img_status = sprintf($img,__('unpublished'),'check-off.png'); + break; + case -1: + $img_status = sprintf($img,__('pending'),'check-wrn.png'); + break; + case -2: + $img_status = sprintf($img,__('junk'),'junk.png'); + break; + } + + echo + ''. + + ''. + ''. + ''. + ''. + ''. + ''. + + ''; + } + + echo '
        '.__('Author').''.__('Date').''.__('IP address').''.__('Status').' 
        '. + ($has_action ? form::checkbox(array('comments[]'),$rs->comment_id,'','','',0,'title="'.($tb ? __('select this trackback') : __('select this comment')).'"') : '').''.html::escapeHTML($rs->comment_author).''.dt::dt2str(__('%Y-%m-%d %H:%M'),$rs->comment_dt).''.$rs->comment_ip.''.$img_status.''. + '
        '; +} + +dcPage::helpBlock('core_post','core_wiki'); +dcPage::close(); +?> \ No newline at end of file diff --git a/v2/dotclear/admin/post_media.php b/v2/dotclear/admin/post_media.php new file mode 100644 index 0000000..1ed7d22 --- /dev/null +++ b/v2/dotclear/admin/post_media.php @@ -0,0 +1,79 @@ +blog->getPosts(array('post_id' => $post_id,'post_type'=>'')); +if ($rs->isEmpty()) { + exit; +} + +if ($post_id && $media_id && !empty($_POST['attach'])) +{ + $core->media = new dcMedia($core); + $core->media->addPostMedia($post_id,$media_id); + http::redirect($core->getPostAdminURL($rs->post_type,$post_id,false)); +} + +try { + $core->media = new dcMedia($core); + $f = $core->media->getPostMedia($post_id,$media_id); + if (empty($f)) { + $post_id = $media_id = null; + throw new Exception(__('This attachment does not exist')); + } + $f = $f[0]; +} catch (Exception $e) { + $core->error->add($e->getMessage()); +} + +# Remove a media from en +if (($post_id && $media_id) || $core->error->flag()) +{ + if (!empty($_POST['remove'])) + { + $core->media->removePostMedia($post_id,$media_id); + http::redirect($core->getPostAdminURL($rs->post_type,$post_id,false).'&rmattach=1'); + } + elseif (isset($_POST['post_id'])) { + http::redirect($core->getPostAdminURL($rs->post_type,$post_id,false)); + } + + if (!empty($_GET['remove'])) + { + dcPage::open(__('Remove attachment')); + + echo '

        '.__('Attachment').' › '.__('confirm removal').'

        '; + + echo + '
        '. + '

        '.__('Are you sure you want to remove this attachment?').'

        '. + '

        '. + '   '. + form::hidden('post_id',$post_id). + form::hidden('media_id',$media_id). + $core->formNonce().'

        '. + '
        '; + + dcPage::close(); + exit; + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/admin/posts.php b/v2/dotclear/admin/posts.php new file mode 100644 index 0000000..f861074 --- /dev/null +++ b/v2/dotclear/admin/posts.php @@ -0,0 +1,324 @@ +blog->getCategories(array('post_type'=>'post')); +} catch (Exception $e) { + $core->error->add($e->getMessage()); +} + +# Getting authors +try { + $users = $core->blog->getPostsUsers(); +} catch (Exception $e) { + $core->error->add($e->getMessage()); +} + +# Getting dates +try { + $dates = $core->blog->getDates(array('type'=>'month')); +} catch (Exception $e) { + $core->error->add($e->getMessage()); +} + +# Getting langs +try { + $langs = $core->blog->getLangs(); +} catch (Exception $e) { + $core->error->add($e->getMessage()); +} + +# Creating filter combo boxes +if (!$core->error->flag()) +{ + # Filter form we'll put in html_block + $users_combo = $categories_combo = array(); + $users_combo['-'] = $categories_combo['-'] = ''; + while ($users->fetch()) + { + $user_cn = dcUtils::getUserCN($users->user_id,$users->user_name, + $users->user_firstname,$users->user_displayname); + + if ($user_cn != $users->user_id) { + $user_cn .= ' ('.$users->user_id.')'; + } + + $users_combo[$user_cn] = $users->user_id; + } + + $categories_combo[__('None')] = 'NULL'; + while ($categories->fetch()) { + $categories_combo[str_repeat('  ',$categories->level-1).($categories->level-1 == 0 ? '' : '• '). + html::escapeHTML($categories->cat_title). + ' ('.$categories->nb_post.')'] = $categories->cat_id; + } + + $status_combo = array( + '-' => '' + ); + foreach ($core->blog->getAllPostStatus() as $k => $v) { + $status_combo[$v] = (string) $k; + } + + $selected_combo = array( + '-' => '', + __('selected') => '1', + __('not selected') => '0' + ); + + # Months array + $dt_m_combo['-'] = ''; + while ($dates->fetch()) { + $dt_m_combo[dt::str('%B %Y',$dates->ts())] = $dates->year().$dates->month(); + } + + $lang_combo['-'] = ''; + while ($langs->fetch()) { + $lang_combo[$langs->post_lang] = $langs->post_lang; + } + + $sortby_combo = array( + __('Date') => 'post_dt', + __('Title') => 'post_title', + __('Category') => 'cat_title', + __('Author') => 'user_id', + __('Status') => 'post_status', + __('Selected') => 'post_selected' + ); + + $order_combo = array( + __('Descending') => 'desc', + __('Ascending') => 'asc' + ); +} + +# Actions combo box +$combo_action = array(); +if ($core->auth->check('publish,contentadmin',$core->blog->id)) +{ + $combo_action[__('Status')] = array( + __('Publish') => 'publish', + __('Unpublish') => 'unpublish', + __('Schedule') => 'schedule', + __('Mark as pending') => 'pending' + ); +} +$combo_action[__('Mark')] = array( + __('Mark as selected') => 'selected', + __('Mark as unselected') => 'unselected' +); +$combo_action[__('Change')] = array(__('Change category') => 'category'); +if ($core->auth->check('admin',$core->blog->id)) +{ + $combo_action[__('Change')] = array_merge($combo_action[__('Change')], + array(__('Change author') => 'author')); +} +if ($core->auth->check('delete,contentadmin',$core->blog->id)) +{ + $combo_action[__('Delete')] = array(__('Delete') => 'delete'); +} + +# --BEHAVIOR-- adminPostsActionsCombo +$core->callBehavior('adminPostsActionsCombo',array(&$combo_action)); + +/* Get posts +-------------------------------------------------------- */ +$user_id = !empty($_GET['user_id']) ? $_GET['user_id'] : ''; +$cat_id = !empty($_GET['cat_id']) ? $_GET['cat_id'] : ''; +$status = isset($_GET['status']) ? $_GET['status'] : ''; +$selected = isset($_GET['selected']) ? $_GET['selected'] : ''; +$month = !empty($_GET['month']) ? $_GET['month'] : ''; +$lang = !empty($_GET['lang']) ? $_GET['lang'] : ''; +$sortby = !empty($_GET['sortby']) ? $_GET['sortby'] : 'post_dt'; +$order = !empty($_GET['order']) ? $_GET['order'] : 'desc'; + +$show_filters = false; + +$page = !empty($_GET['page']) ? (integer) $_GET['page'] : 1; +$nb_per_page = 30; + +if (!empty($_GET['nb']) && (integer) $_GET['nb'] > 0) { + if ($nb_per_page != $_GET['nb']) { + $show_filters = true; + } + $nb_per_page = (integer) $_GET['nb']; +} + +$params['limit'] = array((($page-1)*$nb_per_page),$nb_per_page); +$params['no_content'] = true; + +# - User filter +if ($user_id !== '' && in_array($user_id,$users_combo)) { + $params['user_id'] = $user_id; + $show_filters = true; +} else { + $user_id=''; +} + +# - Categories filter +if ($cat_id !== '' && in_array($cat_id,$categories_combo)) { + $params['cat_id'] = $cat_id; + $show_filters = true; +} else { + $cat_id=''; +} + +# - Status filter +if ($status !== '' && in_array($status,$status_combo)) { + $params['post_status'] = $status; + $show_filters = true; +} else { + $status=''; +} + +# - Selected filter +if ($selected !== '' && in_array($selected,$selected_combo)) { + $params['post_selected'] = $selected; + $show_filters = true; +} else { + $selected=''; +} + +# - Month filter +if ($month !== '' && in_array($month,$dt_m_combo)) { + $params['post_month'] = substr($month,4,2); + $params['post_year'] = substr($month,0,4); + $show_filters = true; +} else { + $month=''; +} + +# - Lang filter +if ($lang !== '' && in_array($lang,$lang_combo)) { + $params['post_lang'] = $lang; + $show_filters = true; +} else { + $lang=''; +} + +# - Sortby and order filter +if ($sortby !== '' && in_array($sortby,$sortby_combo)) { + if ($order !== '' && in_array($order,$order_combo)) { + $params['order'] = $sortby.' '.$order; + } else { + $order='desc'; + } + + if ($sortby != 'post_dt' || $order != 'desc') { + $show_filters = true; + } +} else { + $sortby='post_dt'; + $order='desc'; +} + +# Get posts +try { + $posts = $core->blog->getPosts($params); + $counter = $core->blog->getPosts($params,true); + $post_list = new adminPostList($core,$posts,$counter->f(0)); +} catch (Exception $e) { + $core->error->add($e->getMessage()); +} + +/* DISPLAY +-------------------------------------------------------- */ +$starting_script = dcPage::jsLoad('js/_posts_list.js'); +if (!$show_filters) { + $starting_script .= dcPage::jsLoad('js/filter-controls.js'); +} + +dcPage::open(__('Entries'),$starting_script); + +if (!$core->error->flag()) +{ + echo + '

        '.html::escapeHTML($core->blog->name).' › '.__('Entries').'

        '. + '

        '.__('New entry').'

        '; + + if (!$show_filters) { + echo '

        '. + __('Filters').'

        '; + } + + echo + '
        '. + '
        '.__('Filters').''. + '
        '. + '
        '. + ' '. + ' '. + ' '. + '
        '. + + '
        '. + ' '. + ' '. + ' '. + '
        '. + + '
        '. + '

        '. + '

        '. + '

        '. + '

        '. + '
        '. + '
        '. + '
        '. //Opera sucks + '
        '. + '
        '; + + # Show posts + $post_list->display($page,$nb_per_page, + '
        '. + + '%s'. + + '
        '. + '

        '. + + '

        '. + form::combo('action',$combo_action). + '

        '. + form::hidden(array('user_id'),$user_id). + form::hidden(array('cat_id'),$cat_id). + form::hidden(array('status'),$status). + form::hidden(array('selected'),$selected). + form::hidden(array('month'),$month). + form::hidden(array('lang'),$lang). + form::hidden(array('sortby'),$sortby). + form::hidden(array('order'),$order). + form::hidden(array('page'),$page). + form::hidden(array('nb'),$nb_per_page). + $core->formNonce(). + '
        '. + '
        ' + ); +} + +dcPage::helpBlock('core_posts'); +dcPage::close(); +?> diff --git a/v2/dotclear/admin/posts_actions.php b/v2/dotclear/admin/posts_actions.php new file mode 100644 index 0000000..e2e03d8 --- /dev/null +++ b/v2/dotclear/admin/posts_actions.php @@ -0,0 +1,259 @@ + $v) { + $entries[$k] = (integer) $v; + } + + $params['sql'] = 'AND P.post_id IN('.implode(',',$entries).') '; + + if (!isset($_POST['full_content']) || empty($_POST['full_content'])) { + $params['no_content'] = true; + } + + if (isset($_POST['post_type'])) { + $params['post_type'] = $_POST['post_type']; + } + + $posts = $core->blog->getPosts($params); + + # --BEHAVIOR-- adminPostsActions + $core->callBehavior('adminPostsActions',$core,$posts,$action,$redir); + + if (preg_match('/^(publish|unpublish|schedule|pending)$/',$action)) + { + switch ($action) { + case 'unpublish' : $status = 0; break; + case 'schedule' : $status = -1; break; + case 'pending' : $status = -2; break; + default : $status = 1; break; + } + + try + { + while ($posts->fetch()) { + $core->blog->updPostStatus($posts->post_id,$status); + } + + http::redirect($redir); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } + } + elseif ($action == 'selected' || $action == 'unselected') + { + try + { + while ($posts->fetch()) { + $core->blog->updPostSelected($posts->post_id,$action == 'selected'); + } + + http::redirect($redir); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } + } + elseif ($action == 'delete') + { + try + { + while ($posts->fetch()) { + # --BEHAVIOR-- adminBeforePostDelete + $core->callBehavior('adminBeforePostDelete',$posts->post_id); + $core->blog->delPost($posts->post_id); + } + + http::redirect($redir); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } + + } + elseif ($action == 'category' && isset($_POST['new_cat_id'])) + { + try + { + while ($posts->fetch()) + { + $new_cat_id = (integer) $_POST['new_cat_id']; + $core->blog->updPostCategory($posts->post_id,$new_cat_id); + } + http::redirect($redir); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } + } + elseif ($action == 'author' && isset($_POST['new_auth_id']) + && $core->auth->check('admin',$core->blog->id)) + { + $new_user_id = $_POST['new_auth_id']; + + try + { + if ($core->getUser($new_user_id)->isEmpty()) { + throw new Exception(__('This user does not exist')); + } + + while ($posts->fetch()) + { + $cur = $core->con->openCursor($core->prefix.'post'); + $cur->user_id = $new_user_id; + $cur->update('WHERE post_id = '.(integer) $posts->post_id); + } + + http::redirect($redir); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } + } +} + +/* DISPLAY +-------------------------------------------------------- */ +dcPage::open( + __('Entries'), + dcPage::jsMetaEditor(). + # --BEHAVIOR-- adminBeforePostDelete + $core->callBehavior('adminPostsActionsHeaders') +); + +if (!isset($action)) { + dcPage::close(); + exit; +} + +$hidden_fields = ''; +while ($posts->fetch()) { + $hidden_fields .= form::hidden(array('entries[]'),$posts->post_id); +} + +if (isset($_POST['redir']) && strpos($_POST['redir'],'://') === false) +{ + $hidden_fields .= form::hidden(array('redir'),html::escapeURL($_POST['redir'])); +} +else +{ + $hidden_fields .= + form::hidden(array('user_id'),$_POST['user_id']). + form::hidden(array('cat_id'),$_POST['cat_id']). + form::hidden(array('status'),$_POST['status']). + form::hidden(array('selected'),$_POST['selected']). + form::hidden(array('month'),$_POST['month']). + form::hidden(array('lang'),$_POST['lang']). + form::hidden(array('sortby'),$_POST['sortby']). + form::hidden(array('order'),$_POST['order']). + form::hidden(array('page'),$_POST['page']). + form::hidden(array('nb'),$_POST['nb']); +} + +if (isset($_POST['post_type'])) { + $hidden_fields .= form::hidden(array('post_type'),$_POST['post_type']); +} + +# --BEHAVIOR-- adminPostsActionsContent +$core->callBehavior('adminPostsActionsContent',$core,$action,$hidden_fields); + +if ($action == 'category') +{ + echo '

        '.__('Change category for entries').'

        '; + + # categories list + # Getting categories + $categories_combo = array(' ' => ''); + try { + $categories = $core->blog->getCategories(array('post_type'=>'post')); + while ($categories->fetch()) { + $categories_combo[] = new formSelectOption( + str_repeat('  ',$categories->level-1). + ($categories->level-1 == 0 ? '' : '• ').html::escapeHTML($categories->cat_title), + $categories->cat_id + ); + } + } catch (Exception $e) { } + + echo + '
        '. + '

        '; + + echo + $hidden_fields. + $core->formNonce(). + form::hidden(array('action'),'category'). + '

        '. + '
        '; +} +elseif ($action == 'author' && $core->auth->check('admin',$core->blog->id)) +{ + echo '

        '.__('Change author for entries').'

        '; + + echo + '
        '. + '

        '; + + echo + $hidden_fields. + $core->formNonce(). + form::hidden(array('action'),'author'). + '

        '. + '
        '; +} + +echo '

        '.__('back').'

        '; + +dcPage::close(); +?> \ No newline at end of file diff --git a/v2/dotclear/admin/preferences.php b/v2/dotclear/admin/preferences.php new file mode 100644 index 0000000..30420ab --- /dev/null +++ b/v2/dotclear/admin/preferences.php @@ -0,0 +1,631 @@ +auth->getInfo('user_name'); +$user_firstname = $core->auth->getInfo('user_firstname'); +$user_displayname = $core->auth->getInfo('user_displayname'); +$user_email = $core->auth->getInfo('user_email'); +$user_url = $core->auth->getInfo('user_url'); +$user_lang = $core->auth->getInfo('user_lang'); +$user_tz = $core->auth->getInfo('user_tz'); +$user_post_status = $core->auth->getInfo('user_post_status'); + +$user_options = $core->auth->getOptions(); + +$core->auth->user_prefs->addWorkspace('dashboard'); +$user_dm_doclinks = $core->auth->user_prefs->dashboard->doclinks; +$user_dm_dcnews = $core->auth->user_prefs->dashboard->dcnews; +$user_dm_quickentry = $core->auth->user_prefs->dashboard->quickentry; + +$core->auth->user_prefs->addWorkspace('accessibility'); +$user_acc_nodragdrop = $core->auth->user_prefs->accessibility->nodragdrop; + +$core->auth->user_prefs->addWorkspace('interface'); +$user_ui_enhanceduploader = $core->auth->user_prefs->interface->enhanceduploader; +if ($core->auth->isSuperAdmin()) { + $user_ui_hide_std_favicon = $core->auth->user_prefs->interface->hide_std_favicon; +} +$user_ui_iconset = @$core->auth->user_prefs->interface->iconset; +$user_ui_nofavmenu = $core->auth->user_prefs->interface->nofavmenu; + +$default_tab = !empty($_GET['tab']) ? html::escapeHTML($_GET['tab']) : 'user-profile'; + +if (!empty($_GET['append']) || !empty($_GET['removed']) || !empty($_GET['neworder']) || + !empty($_GET['replaced']) || !empty($_POST['appendaction']) || !empty($_POST['removeaction'])) { + $default_tab = 'user-favorites'; +} elseif (!empty($_GET['updated'])) { + $default_tab = 'user-options'; +} +if (($default_tab != 'user-profile') && ($default_tab != 'user-options') && ($default_tab != 'user-favorites')) { + $default_tab = 'user-profile'; +} + +foreach ($core->getFormaters() as $v) { + $formaters_combo[$v] = $v; +} + +foreach ($core->blog->getAllPostStatus() as $k => $v) { + $status_combo[$v] = $k; +} + +$iconsets_combo = array(__('Default') => ''); +$iconsets_root = dirname(__FILE__).'/images/iconset/'; +if (is_dir($iconsets_root) && is_readable($iconsets_root)) { + if (($d = @dir($iconsets_root)) !== false) { + while (($entry = $d->read()) !== false) { + if ($entry != '.' && $entry != '..' && is_dir($iconsets_root.'/'.$entry)) { + $iconsets_combo[$entry] = $entry; + } + } + } +} + +# Language codes +$langs = l10n::getISOcodes(1,1); +foreach ($langs as $k => $v) { + $lang_avail = $v == 'en' || is_dir(DC_L10N_ROOT.'/'.$v); + $lang_combo[] = new formSelectOption($k,$v,$lang_avail ? 'avail10n' : ''); +} + +# Add or update user +if (isset($_POST['user_name'])) +{ + try + { + $pwd_check = !empty($_POST['cur_pwd']) && $core->auth->checkPassword(crypt::hmac(DC_MASTER_KEY,$_POST['cur_pwd'])); + + if ($core->auth->allowPassChange() && !$pwd_check && $user_email != $_POST['user_email']) { + throw new Exception(__('If you want to change your email or password you must provide your current password.')); + } + + $cur = $core->con->openCursor($core->prefix.'user'); + + $cur->user_name = $user_name = $_POST['user_name']; + $cur->user_firstname = $user_firstname = $_POST['user_firstname']; + $cur->user_displayname = $user_displayname = $_POST['user_displayname']; + $cur->user_email = $user_email = $_POST['user_email']; + $cur->user_url = $user_url = $_POST['user_url']; + $cur->user_lang = $user_lang = $_POST['user_lang']; + $cur->user_tz = $user_tz = $_POST['user_tz']; + + $cur->user_options = new ArrayObject($user_options); + + if ($core->auth->allowPassChange() && !empty($_POST['new_pwd'])) + { + if (!$pwd_check) { + throw new Exception(__('If you want to change your email or password you must provide your current password.')); + } + + if ($_POST['new_pwd'] != $_POST['new_pwd_c']) { + throw new Exception(__("Passwords don't match")); + } + + $cur->user_pwd = $_POST['new_pwd']; + } + + # --BEHAVIOR-- adminBeforeUserUpdate + $core->callBehavior('adminBeforeUserProfileUpdate',$cur,$core->auth->userID()); + + # Udate user + $core->updUser($core->auth->userID(),$cur); + + # --BEHAVIOR-- adminAfterUserUpdate + $core->callBehavior('adminAfterUserProfileUpdate',$cur,$core->auth->userID()); + + http::redirect('preferences.php?upd=1'); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} + +# Update user options +if (isset($_POST['user_post_format'])) +{ + try + { + $cur = $core->con->openCursor($core->prefix.'user'); + + $cur->user_name = $user_name; + $cur->user_firstname = $user_firstname; + $cur->user_displayname = $user_displayname; + $cur->user_email = $user_email; + $cur->user_url = $user_url; + $cur->user_lang = $user_lang; + $cur->user_tz = $user_tz; + + $cur->user_post_status = $user_post_status = $_POST['user_post_status']; + + $user_options['edit_size'] = (integer) $_POST['user_edit_size']; + if ($user_options['edit_size'] < 1) { + $user_options['edit_size'] = 10; + } + $user_options['post_format'] = $_POST['user_post_format']; + $user_options['enable_wysiwyg'] = !empty($_POST['user_wysiwyg']); + + $cur->user_options = new ArrayObject($user_options); + + # --BEHAVIOR-- adminBeforeUserUpdate + $core->callBehavior('adminBeforeUserUpdate',$cur,$core->auth->userID()); + + # Update user prefs + $core->auth->user_prefs->dashboard->put('doclinks',!empty($_POST['user_dm_doclinks']),'boolean'); + $core->auth->user_prefs->dashboard->put('dcnews',!empty($_POST['user_dm_dcnews']),'boolean'); + $core->auth->user_prefs->dashboard->put('quickentry',!empty($_POST['user_dm_quickentry']),'boolean'); + $core->auth->user_prefs->accessibility->put('nodragdrop',!empty($_POST['user_acc_nodragdrop']),'boolean'); + $core->auth->user_prefs->interface->put('enhanceduploader',!empty($_POST['user_ui_enhanceduploader']),'boolean'); + if ($core->auth->isSuperAdmin()) { + # Applied to all users + $core->auth->user_prefs->interface->put('hide_std_favicon',!empty($_POST['user_ui_hide_std_favicon']),'boolean',null,true,true); + } + $core->auth->user_prefs->interface->put('iconset',(!empty($_POST['user_ui_iconset']) ? $_POST['user_ui_iconset'] : '')); + $core->auth->user_prefs->interface->put('nofavmenu',!empty($_POST['user_ui_nofavmenu']),'boolean'); + + # Udate user + $core->updUser($core->auth->userID(),$cur); + + # --BEHAVIOR-- adminAfterUserUpdate + $core->callBehavior('adminAfterUserUpdate',$cur,$core->auth->userID()); + + http::redirect('preferences.php?updated=1'); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} + +# Add selected favorites +if (!empty($_POST['appendaction'])) +{ + try { + if (empty($_POST['append'])) { + throw new Exception(__('No favorite selected')); + } + + $ws = $core->auth->user_prefs->addWorkspace('favorites'); + $user_favs = $ws->DumpLocalPrefs(); + $count = count($user_favs); + foreach ($_POST['append'] as $k => $v) + { + try { + $found = false; + foreach ($user_favs as $f) { + $f = unserialize($f['value']); + if ($f['name'] == $v) { + $found = true; + break; + } + } + if (!$found) { + $uid = sprintf("u%03s",$count); + $fav = array('name' => $_fav[$v][0],'title' => $_fav[$v][1],'url' => $_fav[$v][2],'small-icon' => $_fav[$v][3], + 'large-icon' => $_fav[$v][4],'permissions' => $_fav[$v][5],'id' => $_fav[$v][6],'class' => $_fav[$v][7]); + $core->auth->user_prefs->favorites->put($uid,serialize($fav),'string'); + $count++; + } + } catch (Exception $e) { + $core->error->add($e->getMessage()); + break; + } + } + + if (!$core->error->flag()) { + http::redirect('preferences.php?append=1'); + } + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} + +# Delete selected favorites +if (!empty($_POST['removeaction'])) +{ + try { + if (empty($_POST['remove'])) { + throw new Exception(__('No favorite selected')); + } + + $ws = $core->auth->user_prefs->addWorkspace('favorites'); + foreach ($_POST['remove'] as $k => $v) + { + try { + $core->auth->user_prefs->favorites->drop($v); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + break; + } + } + // Update pref_id values + try { + $user_favs = $ws->DumpLocalPrefs(); + $core->auth->user_prefs->favorites->dropAll(); + $count = 0; + foreach ($user_favs as $k => $v) + { + $uid = sprintf("u%03s",$count); + $f = unserialize($v['value']); + $fav = array('name' => $f['name'],'title' => $f['title'],'url' => $f['url'],'small-icon' => $f['small-icon'], + 'large-icon' => $f['large-icon'],'permissions' => $f['permissions'],'id' => $f['id'],'class' => $f['class']); + $core->auth->user_prefs->favorites->put($uid,serialize($fav),'string'); + $count++; + } + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } + + if (!$core->error->flag()) { + http::redirect('preferences.php?removed=1'); + } + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} + +# Order favs +$order = array(); +if (empty($_POST['favs_order']) && !empty($_POST['order'])) { + $order = $_POST['order']; + asort($order); + $order = array_keys($order); +} elseif (!empty($_POST['favs_order'])) { + $order = explode(',',$_POST['favs_order']); +} + +if (!empty($_POST['saveorder']) && !empty($order)) +{ + try { + $ws = $core->auth->user_prefs->addWorkspace('favorites'); + $user_favs = $ws->DumpLocalPrefs(); + $core->auth->user_prefs->favorites->dropAll(); + $count = 0; + foreach ($order as $i => $k) { + $uid = sprintf("u%03s",$count); + $f = unserialize($user_favs[$k]['value']); + $fav = array('name' => $f['name'],'title' => $f['title'],'url' => $f['url'],'small-icon' => $f['small-icon'], + 'large-icon' => $f['large-icon'],'permissions' => $f['permissions'],'id' => $f['id'],'class' => $f['class']); + $core->auth->user_prefs->favorites->put($uid,serialize($fav),'string'); + $count++; + } + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } + + if (!$core->error->flag()) { + http::redirect('preferences.php?&neworder=1'); + } +} + +# Replace default favorites by current set (super admin only) +if (!empty($_POST['replace']) && $core->auth->isSuperAdmin()) { + try { + $ws = $core->auth->user_prefs->addWorkspace('favorites'); + $user_favs = $ws->DumpLocalPrefs(); + $core->auth->user_prefs->favorites->dropAll(true); + $count = 0; + foreach ($user_favs as $k => $v) + { + $uid = sprintf("g%03s",$count); + $f = unserialize($v['value']); + $fav = array('name' => $f['name'],'title' => $f['title'],'url' => $f['url'],'small-icon' => $f['small-icon'], + 'large-icon' => $f['large-icon'],'permissions' => $f['permissions'],'id' => $f['id'],'class' => $f['class']); + $core->auth->user_prefs->favorites->put($uid,serialize($fav),'string',null,null,true); + $count++; + } + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } + + if (!$core->error->flag()) { + http::redirect('preferences.php?&replaced=1'); + } +} + +/* DISPLAY +-------------------------------------------------------- */ +dcPage::open($page_title, + dcPage::jsLoad('js/_preferences.js'). + ($user_acc_nodragdrop ? '' : dcPage::jsLoad('js/_preferences-dragdrop.js')). + dcPage::jsLoad('js/jquery/jquery-ui-1.8.12.custom.min.js'). + dcPage::jsPageTabs($default_tab). + dcPage::jsConfirmClose('user-form'). + + # --BEHAVIOR-- adminPreferencesHeaders + $core->callBehavior('adminPreferencesHeaders') +); + +if (!empty($_GET['upd'])) { + echo '

        '.__('Personal information has been successfully updated.').'

        '; +} +if (!empty($_GET['updated'])) { + echo '

        '.__('Personal options has been successfully updated.').'

        '; +} +if (!empty($_GET['append'])) { + echo '

        '.__('Favorites have been successfully added.').'

        '; +} +if (!empty($_GET['neworder'])) { + echo '

        '.__('Favorites have been successfully updated.').'

        '; +} +if (!empty($_GET['removed'])) { + echo '

        '.__('Favorites have been successfully removed.').'

        '; +} +if (!empty($_GET['replaced'])) { + echo '

        '.__('Default favorites have been successfully updated.').'

        '; +} + +echo '

        '.html::escapeHTML($core->blog->name).' › '.$page_title.'

        '; + +# User profile +echo '
        '; + +echo +'
        '. +'
        '.__('My profile').''. +'
        '. +'
        '. +'

        '. + +'

        '. + +'

        '. + +'

        '. + +'

        '. + +'
        '. + +'
        '. + +'

        '. + +'

        '. + +'
        '. +'
        '. +'
        '. //Opera sucks +'
        '; + +if ($core->auth->allowPassChange()) +{ + echo + '
        '. + ''.__('Change your password').''. + + '

        '. + + '

        '. + '
        '. + + '

        '.__('If you have changed this user email or password you must provide your current password to save these modifications.').'

        '. + '

        '; +} + +echo +'

        '. +$core->formNonce(). +'

        '. +'
        '; + +echo '
        '; + +# User options : some from actual user profile, dashboard modules, ... +echo '
        '; + +echo +'
        '. +'
        '.__('My options').''. + +'

        '. + +'

        '. + +'

        '. + +'

        '. + +'

        '. + +'

        '; + +if (count($iconsets_combo) > 1) { + echo + '

        '; +} else { + form::hidden('user_ui_iconset',''); +} + +if ($core->auth->isSuperAdmin()) { + echo + '

        '. + '

        '.__('This will be applied for all users').'

        '; +} + +echo +'
        '. //Opera sucks +'
        '; + +echo +'
        '.__('Accessibility options').''. + +'

        '. + +'

        '.__('Numeric fields will allow to type the elements\' ordering number.').'

        '. +'
        '; + +echo +'
        '.__('Dashboard modules').''. + +'

        '. + +'

        '. + +'

        '. + +'
        '. //Opera sucks +'
        '; + +# --BEHAVIOR-- adminPreferencesForm +$core->callBehavior('adminPreferencesForm',$core); + +echo +'

        '. +$core->formNonce(). +'

        '. +'
        '; + +echo '
        '; + +# User favorites +echo '
        '; +$ws = $core->auth->user_prefs->addWorkspace('favorites'); +echo '
        '; +echo '
        '; +echo '
        '; +echo '
        '.__('My favorites').''; + +$count = 0; +foreach ($ws->dumpPrefs() as $k => $v) { + // User favorites only + if (!$v['global']) { + $fav = unserialize($v['value']); + if (($fav['permissions'] == '*') || $core->auth->check($fav['permissions'],$core->blog->id)) { + if ($count == 0) echo '
          '; + $count++; + echo '
        • '. + ' '. + form::field(array('order['.$k.']'),2,3,$count,'position','',false,'title="'.sprintf(__('position of %s'),$fav['title']).'"'). + form::hidden(array('dynorder[]','dynorder-'.$k.''),$k). + ''. + '
        • '; + } + } +} +if ($count > 0) echo '
        '; +if ($count > 0) { + echo + '
        '. + '

        '.form::hidden('favs_order',''). + $core->formNonce(). + ' '. + + '

        '. + + ($core->auth->isSuperAdmin() ? + '
        '. + '

        '.__('If you are a super administrator, you may define this set of favorites to be used by default on all blogs of this installation:').'

        '. + '

        ' : + ''). + '

        '. + '
        '; +} else { + echo + '

        '.__('Currently no personal favorites.').'

        '; +} + +echo '
        '; + +echo '

        '.__('Default favorites').'

        '; +echo '

        '.__('Those favorites are displayed when My Favorites list is empty.').'

        '; +$count = 0; +foreach ($ws->dumpPrefs() as $k => $v) { + // Global favorites only + if ($v['global']) { + $fav = unserialize($v['value']); + if (($fav['permissions'] == '*') || $core->auth->check($fav['permissions'],$core->blog->id)) { + if ($count == 0) echo '
          '; + $count++; + echo '
        • '. + ' '.__($fav['title']).'
        • '; + } + } +} +if ($count > 0) echo '
        '; +echo '
        '; +echo '
        '; +echo '
        '; +# Available favorites +echo '
        '.__('Available favorites').''; +$count = 0; +$array = $_fav; +function cmp($a,$b) { + if (__($a[1]) == __($b[1])) { + return 0; + } + return (__($a[1]) < __($b[1])) ? -1 : 1; +} +$array=$array->getArrayCopy(); +uasort($array,'cmp'); +foreach ($array as $k => $fav) { + if (($fav[5] == '*') || $core->auth->check($fav[5],$core->blog->id)) { + if ($count == 0) echo '
          '; + $count++; + echo '
        • '.''.'
        • '; + } +} +if ($count > 0) echo '
        '; +echo +'

        '. +$core->formNonce(). +'

        '; +echo '
        '; +echo '
        '; +echo '
        '; # Two-cols +echo '
        '; +echo '
        '; # user-favorites + +dcPage::helpBlock('core_user_pref'); +dcPage::close(); +?> \ No newline at end of file diff --git a/v2/dotclear/admin/search.php b/v2/dotclear/admin/search.php new file mode 100644 index 0000000..a6fc234 --- /dev/null +++ b/v2/dotclear/admin/search.php @@ -0,0 +1,180 @@ +blog->getPosts($params); + $counter = $core->blog->getPosts($params,true); + $post_list = new adminPostList($core,$posts,$counter->f(0)); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } + } + # Get comments + elseif ($qtype == 'c') + { + $starting_scripts .= dcPage::jsLoad('js/_comments.js'); + + $params['search'] = $q; + $params['limit'] = array((($page-1)*$nb_per_page),$nb_per_page); + $params['no_content'] = true; + $params['order'] = 'comment_dt DESC'; + + try { + $comments = $core->blog->getComments($params); + $counter = $core->blog->getComments($params,true); + $comment_list = new adminCommentList($core,$comments,$counter->f(0)); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } + } +} + + +dcPage::open(__('Search'),$starting_scripts); + +echo +'

        '.html::escapeHTML($core->blog->name).' › '.__('Search').'

        '. +'
        '. +'

        '.__('Search options').'

        '. +'

        '.form::field('q',30,255,html::escapeHTML($q)).'

        '. +'

        '. +'

        '. +'

        '. +'
        '. +'
        '; + +if ($q && !$core->error->flag()) +{ + $redir = html::escapeHTML($_SERVER['REQUEST_URI']); + + # Show posts + if ($qtype == 'p') + { + # Actions combo box + $combo_action = array(); + if ($core->auth->check('publish,contentadmin',$core->blog->id)) + { + $combo_action[__('publish')] = 'publish'; + $combo_action[__('unpublish')] = 'unpublish'; + $combo_action[__('schedule')] = 'schedule'; + $combo_action[__('mark as pending')] = 'pending'; + } + $combo_action[__('change category')] = 'category'; + if ($core->auth->check('admin',$core->blog->id)) { + $combo_action[__('change author')] = 'author'; + } + if ($core->auth->check('delete,contentadmin',$core->blog->id)) + { + $combo_action[__('Delete')] = 'delete'; + } + + # --BEHAVIOR-- adminPostsActionsCombo + $core->callBehavior('adminPostsActionsCombo',array(&$combo_action)); + + if ($counter->f(0) > 0) { + printf('

        '. + ($counter->f(0) == 1 ? __('%d entry found') : __('%d entries found')). + '

        ',$counter->f(0)); + } + + $post_list->display($page,$nb_per_page, + '
        '. + + '%s'. + + '
        '. + '

        '. + + '

        '. + form::combo(array('action','action1'),$combo_action). + '

        '. + form::hidden('redir',preg_replace('/%/','%%',$redir)). + $core->formNonce(). + '
        '. + '
        ' + ); + } + # Show posts + elseif ($qtype == 'c') + { + # Actions combo box + $combo_action = array(); + if ($core->auth->check('publish,contentadmin',$core->blog->id)) + { + $combo_action[__('publish')] = 'publish'; + $combo_action[__('unpublish')] = 'unpublish'; + $combo_action[__('mark as pending')] = 'pending'; + $combo_action[__('mark as junk')] = 'junk'; + } + if ($core->auth->check('delete,contentadmin',$core->blog->id)) + { + $combo_action[__('Delete')] = 'delete'; + } + + if ($counter->f(0) > 0) { + printf('

        '. + ($counter->f(0) == 1 ? __('%d comment found') : __('%d comments found')). + '

        ',$counter->f(0)); + } + + $comment_list->display($page,$nb_per_page, + '
        '. + + '%s'. + + '
        '. + '

        '. + + '

        '. + form::combo(array('action','action2'),$combo_action). + '

        '. + form::hidden('redir',preg_replace('/%/','%%',$redir)). + $core->formNonce(). + '
        '. + '
        ' + ); + } +} + + +dcPage::close(); +?> \ No newline at end of file diff --git a/v2/dotclear/admin/services.php b/v2/dotclear/admin/services.php new file mode 100644 index 0000000..1d1a301 --- /dev/null +++ b/v2/dotclear/admin/services.php @@ -0,0 +1,395 @@ +rest->addFunction('getPostById',array('dcRestMethods','getPostById')); +$core->rest->addFunction('getCommentById',array('dcRestMethods','getCommentById')); +$core->rest->addFunction('quickPost',array('dcRestMethods','quickPost')); +$core->rest->addFunction('validatePostMarkup',array('dcRestMethods','validatePostMarkup')); +$core->rest->addFunction('getZipMediaContent',array('dcRestMethods','getZipMediaContent')); +$core->rest->addFunction('getMeta',array('dcRestMethods','getMeta')); +$core->rest->addFunction('delMeta',array('dcRestMethods','delMeta')); +$core->rest->addFunction('setPostMeta',array('dcRestMethods','setPostMeta')); +$core->rest->addFunction('searchMeta',array('dcRestMethods','searchMeta')); + +$core->rest->serve(); + +/* Common REST methods */ +class dcRestMethods +{ + public static function getPostById($core,$get) + { + if (empty($get['id'])) { + throw new Exception('No post ID'); + } + + $params = array('post_id' => (integer) $get['id']); + + if (isset($get['post_type'])) { + $params['post_type'] = $get['post_type']; + } + + $rs = $core->blog->getPosts($params); + + if ($rs->isEmpty()) { + throw new Exception('No post for this ID'); + } + + $rsp = new xmlTag('post'); + $rsp->id = $rs->post_id; + + $rsp->blog_id($rs->blog_id); + $rsp->user_id($rs->user_id); + $rsp->cat_id($rs->cat_id); + $rsp->post_dt($rs->post_dt); + $rsp->post_creadt($rs->post_creadt); + $rsp->post_upddt($rs->post_upddt); + $rsp->post_format($rs->post_format); + $rsp->post_url($rs->post_url); + $rsp->post_lang($rs->post_lang); + $rsp->post_title($rs->post_title); + $rsp->post_excerpt($rs->post_excerpt); + $rsp->post_excerpt_xhtml($rs->post_excerpt_xhtml); + $rsp->post_content($rs->post_content); + $rsp->post_content_xhtml($rs->post_content_xhtml); + $rsp->post_notes($rs->post_notes); + $rsp->post_status($rs->post_status); + $rsp->post_selected($rs->post_selected); + $rsp->post_open_comment($rs->post_open_comment); + $rsp->post_open_tb($rs->post_open_tb); + $rsp->nb_comment($rs->nb_comment); + $rsp->nb_trackback($rs->nb_trackback); + $rsp->user_name($rs->user_name); + $rsp->user_firstname($rs->user_firstname); + $rsp->user_displayname($rs->user_displayname); + $rsp->user_email($rs->user_email); + $rsp->user_url($rs->user_url); + $rsp->cat_title($rs->cat_title); + $rsp->cat_url($rs->cat_url); + + $rsp->post_display_content($rs->getContent(true)); + $rsp->post_display_excerpt($rs->getExcerpt(true)); + + $metaTag = new xmlTag('meta'); + if (($meta = @unserialize($rs->post_meta)) !== false) + { + foreach ($meta as $K => $V) + { + foreach ($V as $v) { + $metaTag->$K($v); + } + } + } + $rsp->post_meta($metaTag); + + return $rsp; + } + + public static function getCommentById($core,$get) + { + if (empty($get['id'])) { + throw new Exception('No comment ID'); + } + + $rs = $core->blog->getComments(array('comment_id' => (integer) $get['id'])); + + if ($rs->isEmpty()) { + throw new Exception('No comment for this ID'); + } + + $rsp = new xmlTag('post'); + $rsp->id = $rs->comment_id; + + $rsp->comment_dt($rs->comment_dt); + $rsp->comment_upddt($rs->comment_upddt); + $rsp->comment_author($rs->comment_author); + $rsp->comment_site($rs->comment_site); + $rsp->comment_content($rs->comment_content); + $rsp->comment_trackback($rs->comment_trackback); + $rsp->comment_status($rs->comment_status); + $rsp->post_title($rs->post_title); + $rsp->post_url($rs->post_url); + $rsp->post_id($rs->post_id); + $rsp->post_dt($rs->post_dt); + $rsp->user_id($rs->user_id); + + $rsp->comment_display_content($rs->getContent(true)); + + if ($core->auth->userID()) { + $rsp->comment_ip($rs->comment_ip); + $rsp->comment_email($rs->comment_email); + $rsp->comment_spam_disp(dcAntispam::statusMessage($rs)); + } + + return $rsp; + } + + public static function quickPost($core,$get,$post) + { + $cur = $core->con->openCursor($core->prefix.'post'); + + $cur->post_title = !empty($post['post_title']) ? $post['post_title'] : ''; + $cur->user_id = $core->auth->userID(); + $cur->post_content = !empty($post['post_content']) ? $post['post_content'] : ''; + $cur->cat_id = !empty($post['cat_id']) ? (integer) $post['cat_id'] : null; + $cur->post_format = !empty($post['post_format']) ? $post['post_format'] : 'xhtml'; + $cur->post_lang = !empty($post['post_lang']) ? $post['post_lang'] : ''; + $cur->post_status = !empty($post['post_status']) ? (integer) $post['post_status'] : 0; + $cur->post_open_comment = (integer) $core->blog->settings->system->allow_comments; + $cur->post_open_tb = (integer) $core->blog->settings->system->allow_trackbacks; + + # --BEHAVIOR-- adminBeforePostCreate + $core->callBehavior('adminBeforePostCreate',$cur); + + $return_id = $core->blog->addPost($cur); + + # --BEHAVIOR-- adminAfterPostCreate + $core->callBehavior('adminAfterPostCreate',$cur,$return_id); + + $rsp = new xmlTag('post'); + $rsp->id = $return_id; + + $post = $core->blog->getPosts(array('post_id' => $return_id)); + + $rsp->post_status = $post->post_status; + $rsp->post_url = $post->getURL(); + return $rsp; + } + + public static function validatePostMarkup($core,$get,$post) + { + if (!isset($post['excerpt'])) { + throw new Exception('No entry excerpt'); + } + + if (!isset($post['content'])) { + throw new Exception('No entry content'); + } + + if (empty($post['format'])) { + throw new Exception('No entry format'); + } + + if (!isset($post['lang'])) { + throw new Exception('No entry lang'); + } + + $excerpt = $post['excerpt']; + $excerpt_xhtml = ''; + $content = $post['content']; + $content_xhtml = ''; + $format = $post['format']; + $lang = $post['lang']; + + $core->blog->setPostContent(0,$format,$lang,$excerpt,$excerpt_xhtml,$content,$content_xhtml); + + $rsp = new xmlTag('result'); + + $v = htmlValidator::validate($excerpt_xhtml.$content_xhtml); + + $rsp->valid($v['valid']); + $rsp->errors($v['errors']); + + return $rsp; + } + + public static function getZipMediaContent($core,$get,$post) + { + if (empty($get['id'])) { + throw new Exception('No media ID'); + } + + $id = (integer) $get['id']; + + if (!$core->auth->check('media,media_admin',$core->blog)) { + throw new Exception('Permission denied'); + } + + $core->media = new dcMedia($core); + $file = $core->media->getFile($id); + + if ($file === null || $file->type != 'application/zip' || !$file->editable) { + throw new Exception('Not a valid file'); + } + + $rsp = new xmlTag('result'); + $content = $core->media->getZipContent($file); + + foreach ($content as $k => $v) { + $rsp->file($k); + } + + return $rsp; + } + + public static function getMeta($core,$get) + { + $postid = !empty($get['postId']) ? $get['postId'] : null; + $limit = !empty($get['limit']) ? $get['limit'] : null; + $metaId = !empty($get['metaId']) ? $get['metaId'] : null; + $metaType = !empty($get['metaType']) ? $get['metaType'] : null; + + $sortby = !empty($get['sortby']) ? $get['sortby'] : 'meta_type,asc'; + + $rs = $core->meta->getMetadata(array( + 'meta_type' => $metaType, + 'limit' => $limit, + 'meta_id' => $metaId, + 'post_id' => $postid)); + $rs = $core->meta->computeMetaStats($rs); + + $sortby = explode(',',$sortby); + $sort = $sortby[0]; + $order = isset($sortby[1]) ? $sortby[1] : 'asc'; + + switch ($sort) { + case 'metaId': + $sort = 'meta_id_lower'; + break; + case 'count': + $sort = 'count'; + break; + case 'metaType': + $sort = 'meta_type'; + break; + default: + $sort = 'meta_type'; + } + + $rs->sort($sort,$order); + + $rsp = new xmlTag(); + + while ($rs->fetch()) + { + $metaTag = new xmlTag('meta'); + $metaTag->type = $rs->meta_type; + $metaTag->uri = rawurlencode($rs->meta_id); + $metaTag->count = $rs->count; + $metaTag->percent = $rs->percent; + $metaTag->roundpercent = $rs->roundpercent; + $metaTag->CDATA($rs->meta_id); + + $rsp->insertNode($metaTag); + } + + return $rsp; + } + + public static function setPostMeta($core,$get,$post) + { + if (empty($post['postId'])) { + throw new Exception('No post ID'); + } + + if (empty($post['meta']) && $post['meta'] != '0') { + throw new Exception('No meta'); + } + + if (empty($post['metaType'])) { + throw new Exception('No meta type'); + } + + # Get previous meta for post + $post_meta = $core->meta->getMetadata(array( + 'meta_type' => $post['metaType'], + 'post_id' => $post['postId'])); + $pm = array(); + while ($post_meta->fetch()) { + $pm[] = $post_meta->meta_id; + } + + foreach ($core->meta->splitMetaValues($post['meta']) as $m) + { + if (!in_array($m,$pm)) { + $core->meta->setPostMeta($post['postId'],$post['metaType'],$m); + } + } + + return true; + } + + public static function delMeta($core,$get,$post) + { + if (empty($post['postId'])) { + throw new Exception('No post ID'); + } + + if (empty($post['metaId']) && $post['metaId'] != '0') { + throw new Exception('No meta ID'); + } + + if (empty($post['metaType'])) { + throw new Exception('No meta type'); + } + + $core->meta->delPostMeta($post['postId'],$post['metaType'],$post['metaId']); + + return true; + } + + public static function searchMeta($core,$get) + { + $q = !empty($get['q']) ? $get['q'] : null; + $metaType = !empty($get['metaType']) ? $get['metaType'] : null; + + $sortby = !empty($get['sortby']) ? $get['sortby'] : 'meta_type,asc'; + + $rs = $core->meta->getMetadata(array('meta_type' => $metaType)); + $rs = $core->meta->computeMetaStats($rs); + + $sortby = explode(',',$sortby); + $sort = $sortby[0]; + $order = isset($sortby[1]) ? $sortby[1] : 'asc'; + + switch ($sort) { + case 'metaId': + $sort = 'meta_id_lower'; + break; + case 'count': + $sort = 'count'; + break; + case 'metaType': + $sort = 'meta_type'; + break; + default: + $sort = 'meta_type'; + } + + $rs->sort($sort,$order); + + $rsp = new xmlTag(); + + while ($rs->fetch()) + { + if (preg_match('/'.$q.'/i',$rs->meta_id)) { + $metaTag = new xmlTag('meta'); + $metaTag->type = $rs->meta_type; + $metaTag->uri = rawurlencode($rs->meta_id); + $metaTag->count = $rs->count; + $metaTag->percent = $rs->percent; + $metaTag->roundpercent = $rs->roundpercent; + $metaTag->CDATA($rs->meta_id); + + $rsp->insertNode($metaTag); + } + } + + return $rsp; + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/admin/style/add.png b/v2/dotclear/admin/style/add.png new file mode 100644 index 0000000000000000000000000000000000000000..dab4ead233b8fc4fa87a1ef2fdde5cfa15cfac21 GIT binary patch literal 1113 zcmbVLO-K|`93N3gB+;l#c6p6`S?kGg4UIyOHk5IggNinF^)2k8sCrG$ z58}a0uc#u!uXq^0YgmL$QC;1xrKm-S!6+Qp%^1D$YJ~>67NZA388%}jU_tMx*s#CS zmscxARnX|}^PtNWiGTsI0$ihHI-(n+tGXiDd)EvNst{a^(c4Z9X0jlGYzRVr)~B*z z7KAxJ7YIfokxsy~9Lumg!|^^YA_jPoWx>uv6Kl3MCg$YSjxBPE(FKexkzvZ^vcDYg zBYT|T1VQjLc-}`4K4;3rit96-_L_nW9o5z?tRoY6ipnUOz%iP5x*dXHWiq?Mrn8eM zk}}3sEQa&5jA3|jRnZR4!9Q;7iFWc+7G!eJK@+x0>M_<{Ba__iZ^#1@Z^VnXPKu(G zWTZ|Q(8OsuMw35&P1i`40?}Y99^ey_kYqV7E=WNkCB?&1AejinLp6=PxKSw-mE+N< zB=9MYOR`ctCn>HP+m@2H<)rs95Ze(Asn6ROOk)21VRO^6j0b%46 zkOdO`Auynu8Y(+pakgWXp{-9sEoCDERI@AUdszQ>)Z1L`e=^1pXBe+F{%V!l73n{3 zyW9BWusb@?B=cgE!8rXTe2om%iEM8^d8+c_*yU+3ey?-xeaFmd$Mv<7Q_s)dc++k# zo|}EwIsaj6Yb&+Ti3xrM~8w+%iR@q?(4?PrR<&D(6VoKb7^Gm*TPmK XOI4mW8i$A0U2oXa$v$~0er5VMqWNal literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/style/candyUpload/cancel.png b/v2/dotclear/admin/style/candyUpload/cancel.png new file mode 100644 index 0000000000000000000000000000000000000000..b1a59471c3f21f2329931fe4a589a861c2b36d19 GIT binary patch literal 309 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=%3?!FCJ6-`&%*9TgAsieWw;%dH0CE)rd_r9R z|NsB*-@o7Q-~WF1?)CinZ|2W`J#XIqgoOL?@mCED&M+{D@#={J6*H9t`33)Hc)H!d z3&`Uv@Q5sCVBi)4Va7{$>;3=*#Y$WwN}P*Q6H7Al^Atidb5j|N4fG96^$jdmhR^R+>#4|r8huuglz u;=QMdC4aJ7^QN50^v`E@TsZvrqI~=ssfn9+&+G&m&*16m=d#Wzp$P!Nf^V<@ literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/style/candyUpload/loader.png b/v2/dotclear/admin/style/candyUpload/loader.png new file mode 100644 index 0000000000000000000000000000000000000000..267f54111eae4c93e3629b643bb5a61609e2769c GIT binary patch literal 858 zcmV-g1Eu_lP)RGReGUQd7@Bypi^|BM|q!9a-l6z7Pj;M8 zbDc_Yo<($OmUh?a+pkTnMiS$N^6@taF|GMmPl!uH*S?kZ|hkTqqGJ7$bPWsE*!jXGVBDq@Q|UXCtYk11Y@Fj|c#Uy3wgi8@(}CRmFl zU57MQi6d5sB~^$bRE8o|h9y&mAXJ4URD&f^gdS6YB~*bZQh_2?fGksgCr^SLPJbLt zfErAH8B2W`N_`hidLT=C8%TQMgsr<02XvbSad^jWnpw_ zZ*Cw|X>DZyGC40WH7_tY@MYc30003kNklUHWeNNLtF5Z;u+0Us$1 zKHu0jRryJ6@K@~7Vm4_S^0yA9ow6KB*D!TPJ$a;SxS-uas?#-GQbRHA>l&`58U}fi7AzZCsS>Jir4~tLR`Oo{Q_iWzR2GJq=Y?P978H@B_&9(E=~~PQDNXP ZU|?=xU|j9!cmgQR;OXk;vd$@?2>^wZBV7Oh literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/style/dc_logo.png b/v2/dotclear/admin/style/dc_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..d7204e2b08d01128e9a67cbdcc62a24633f6a134 GIT binary patch literal 825 zcmV-91IGM`P)Cd?|Nr&%^n!zf)z;Rm ztgQ9*^gu+(w&394jE#-U%gc3kcDlQ|iHeEq>*{}i zfNX7Sla!O4ot@$0;l#wm*x1*wv9N{vnsfjF0&+=2K~#9!?3sy|GcVHpg%pWDs*oPFM-aJqLp#&m5mjBGE9@MF_;uF$`T?VbF+OF#=t6 zv08TAkCBxy9-8@Jlt1^*x(sKIQ>W=tQH7eaq|32l1Xm_Cp_rvdNzV)f7UP=Vd+7~NW!-TSug5i47jih@oFei@r z_gpY&3O63AGbfi*n$&f1{}V>bhG&f2Mw9N@fHRB;In^>EMf7ZJgP~dmNUCDh2Ewvx z!<{fJKy5iR8GD}GCK#cK+_Nrx6$jPr+@3e~8Yq=Awb(o_RlpfG!JzzVg)@~LZ#mRp zXLN~aB23&jNDB)e3kLTJ@>6#)ypl)E@CXKVB2^?6`0RQ!VVkTtb;&GR8>O3f>8y*| zsraQ?yRXg4GvUT*=9`g4s+Bo{1F|;39+yLWKUIGt{1LMFr zFb<6WALI8fFkZ(!V7$ID#*_cY`15mQ6XP!IuK)u8a8?(dzEu+Y00000NkvXXu0mjf DU7m%; literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/style/dc_logo_small.png b/v2/dotclear/admin/style/dc_logo_small.png new file mode 100644 index 0000000000000000000000000000000000000000..3ec22c9191c0c829235729a9afd298082fcba919 GIT binary patch literal 839 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 N002ovPDHLkV1naWGX4Mn literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/style/drag.png b/v2/dotclear/admin/style/drag.png new file mode 100644 index 0000000000000000000000000000000000000000..28410fcf92bcb7d0df3e26e36bf508bb6e098395 GIT binary patch literal 611 zcmV-p0-XJcP)K6@CDXY!T=( zzrm1_F*u1cckZ3%<+K#1BGVr}gM zdDbC>KnMZf?Xtf9o+L^8SXIS<5@SR)Vy$6&dxyQfZ?v+E!Z`}(Xm>gs9DHYM>l4N# zsP_066*)XSR%_GC*;E4}kd_iwR^DKZ;mNb-jE!9<&kNFY_B4{0<`xO?wD?N)05C&^x$002ovPDHLkV1m;I5^ewh literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/style/farbtastic/farbtastic.css b/v2/dotclear/admin/style/farbtastic/farbtastic.css new file mode 100644 index 0000000..07d953f --- /dev/null +++ b/v2/dotclear/admin/style/farbtastic/farbtastic.css @@ -0,0 +1,33 @@ +.farbtastic { + position: relative; +} +.farbtastic * { + position: absolute; + cursor: crosshair; +} +.farbtastic, .farbtastic .wheel { + width: 195px; + height: 195px; +} +.farbtastic .color, .farbtastic .overlay { + top: 47px; + left: 47px; + width: 101px; + height: 101px; +} +.farbtastic .wheel { + background: url(wheel.png) no-repeat; + width: 195px; + height: 195px; +} +.farbtastic .overlay { + background: url(mask.png) no-repeat; +} +.farbtastic .marker { + width: 17px; + height: 17px; + margin: -8px 0 0 -8px; + overflow: hidden; + background: url(marker.png) no-repeat; +} + diff --git a/v2/dotclear/admin/style/farbtastic/marker.png b/v2/dotclear/admin/style/farbtastic/marker.png new file mode 100644 index 0000000000000000000000000000000000000000..db7da5560eb0ee83f8192aebfdbdd391f94c9dcf GIT binary patch literal 614 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 literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/style/grid.png b/v2/dotclear/admin/style/grid.png new file mode 100644 index 0000000000000000000000000000000000000000..cf9402d8adecb487701a55a7ebe22bd23564883e GIT binary patch literal 202 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 LNkvXXu0mjf)S&N? literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/style/install/process_warning.png b/v2/dotclear/admin/style/install/process_warning.png new file mode 100644 index 0000000000000000000000000000000000000000..b1dbe7d168688f5540f12e1c3de0c7c0a5e9add8 GIT binary patch literal 4937 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 Hu0mjf2x&U# literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/style/install/w-logo.png b/v2/dotclear/admin/style/install/w-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..7295297cd320a482a6ae27d0e736cdf72d70cec3 GIT binary patch literal 1615 zcmV-V2C(^wP)QGEnMZUhf%gDa)@b8|Uncv>s_xJXs zrKE<1fX>d$udb@+=jE1_k*21ix3;s6jfmIQ)bH=^#>T^8Vq$%Nf6B_r=I7>-k&K#~ zn{94v&C9{Py0L0(Y}3@!t*)(JU|)1~b+@;-gM)wF-Q2{%xR8>O>FMU#*U*-imw|(W zVq;^Bjg9p6_2S{()Y8h;)z#3=#M02mwX>_<+}GgW+S}UGpq`kDiiOwJ&A`FIz`?-h z=Hq5(W`~G~cX)WAqN00zd9}8-Y;JC=tgOn*%j)Xt>+9)sb#kt(rKhEy*4ERQmy&*c zcUM_i|NsB_wC%|N00jFGmNG<0m+^UAU}V8J^8j;FP~1I&MF7~eYKUm|4}jUVVl@u*!)d4RHl>Xz5rfJvrL+O*J>VUr&m=C)D z9BNpu@3h|%_-S>(S*+>fP@{5vu4xByR;(m=|1ihaKAaCUZ7N4m6~S5VTjX!;VYMIN zH#zp;`5qr$_5-|IgvrqbK6C}7YuvR}}nTO}jX{9jxKr3~t88{|`PK zoIhVt>|uYkFW}P;MU-d{)78F!H|Kw7lnftU6#aPx!Dr*%YWnwMx7+>FSC4Mh1MiJz zD%fVLXZ2dmGVrhgK+W6;?xNe!jpg8G4S z-~j*b8At*N90usKx|8W(2~B(+M$htJTrx40wc=%rv?NS_GDc z3N-L-usp^g@|>T=f{AYQ^80EC7r^`jhj|#;YBb6wAWjf>FFzTL+XZ-yQAf`FQgA;O zL%IM*+>A4^4llPp_KL^}3LPLuW<=$q8=ph;CF_4H2X{GcvMMM6N3W%(%qo6tb6YQ> z)#0||GfG?zL69VpT2fiUxKvwh_cLV&iA?5xZ!DqTIbzW`#FT6SP ziol3X9JTf4B#hYI2D4op{Gnfxi*^EEbuguvXhs;^<7-FeUbss-L~#UBezqgt_y*4Y z^;d#_l!ClRqNh~1lM-)VfN+@sMkv$*NXm`*I&hQ^TfDRYU94+sO`*ed@+QFH?1i4G0zXxeFLixEqos*vIMOVBrKmZf=@k{b z#uV=jg9PrtbL(BNpv4nLJ`bVHqXfTHP7=!w8iAH0G%!y(bg1~5E3Zdr-LQt>8295* zrkIV_j&7vZ<9XP{Iv6jL<|QyQ<&H8`k`pEQsI61UX1MS9b9O#oI-E~!epq(Y!!j=S z`HadZm|S_iq28Ry*(de9JhIvgz0;m#o#HX8-NEklBcV5kCgXAO>j~kDeTa0}aoqr+ z)DaTpPWGh+D0vuPJ3HC#Z~3dwNp&PO=JIrle?d6DOezPyhw`5Q0{~0>Rj?xr*xvvE N002ovPDHLkV1naWGX4Mn literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/style/jsToolBar/bt_bquote.png b/v2/dotclear/admin/style/jsToolBar/bt_bquote.png new file mode 100644 index 0000000000000000000000000000000000000000..bb6be88d2f96346012b1ab114f07a444e426d9ee GIT binary patch literal 261 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAf3?x51|2hvyF&8^|hH!9j+JSPRm`9SRG|P;5uBe^Ql40p%HW%rT$G=inv$8Q z;FejGTAp8&U98|6v3sJH3Q(=Fr;B3dH r_3{R8_7YjMk9EybP0l+XkKU!zYW literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/style/jsToolBar/bt_br.png b/v2/dotclear/admin/style/jsToolBar/bt_br.png new file mode 100644 index 0000000000000000000000000000000000000000..717ff6cfd854e477355cd699005f991bbc86dac6 GIT binary patch literal 243 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAf3?x51|2hvyF&8^|hH!9j+QJYD@<);T3K0RT6!MF0Q* literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/style/jsToolBar/bt_clean.png b/v2/dotclear/admin/style/jsToolBar/bt_clean.png new file mode 100644 index 0000000000000000000000000000000000000000..3973a2c3066464f889896da9b4c11b74fa5fa70e GIT binary patch literal 576 zcmV-G0>AxxN#00003b3#c}2nYz< z;ZNWI008h%OjJcJAPM^8Xy(XFq>oKnUtH|!-iV2ny1KHddjwE60lc3t|Nq3$!kk`Q zRFi&Kd~#YvI4RVsc(Sjd;Lv}SOa%Y=sg{U&(ZjJLD>ncC|8HPIGcz;X)QZJ{K8A#Z zxTt*k+-z1oAK1*W(YQskV;QQVm9dX$@1)VFg*RKEn*2clH%*>hN&VC^&Lfg)o|M_qn>vRMF000Jb zQchF<|NsC00JFcOzW@LL32;bRa{vGf5&!@T5&_cPe*6Fc02XvbSad^jWnpw_Z*Cw| zX>DZyFflJMI4>|XdUF6G0000WbVXQnQ*UN;cVTj608L?Ia&K*AWNBd_Mrm?ocW-iQ zb0AGvyOAm+0001oNkl#(k<>Gga7Gc7ck)nW)7Fwk7UXgAmD*1?- zn`QK$!8;-MT+OL9r6oh!W?b)Wnj^{5*w_%-mE414DfS z3w;BVs$vEupb7<$is1aTlJdl&R0iL~|zDqh}{#lRDf#3 zJzX3_IA$jA;AZD>F$`_?KIb%pm4}CCPr@@%w!6~O3TIa9l)t~%V!-gTe~DWM4fqSJW3 literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/style/jsToolBar/bt_del.png b/v2/dotclear/admin/style/jsToolBar/bt_del.png new file mode 100644 index 0000000000000000000000000000000000000000..87c3c6604b2e97dc6b8025b08527e592f04a26b1 GIT binary patch literal 351 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc3?z4jzqJQa%*9TgAsieWw;%dH0CJ53d_r7- z^qW`rCQs^$2oKiQ);xFiP+4g{A0O|=^~*dxT+`Ch?%ux8(p+<3-xgUJX)7!9MGI#L z`5w^%YGW!1@(cdY@N~O@7m&wU;1OBOz`!j8!i<;h*8Kqrij}xVlsFfqCYEI8=P86_ z=B6?j80s5X=o^?+6*DLSRVaW|1m~xflqVLYGWaGY7v<-srer26xMdclmgg5`7c2Ni z?4GEl0#uvs>Eak7ae3*5(|m^vcw7SS&r%DP=KBACtB!yubB@4fo341yeJXXwL$$Xg z<~w^&<1ucuvvgy;BlBG3z|jJika{0^!Ow3b-0w}lE|>X~>4h!N>x&gqapDbY|D;a) jvgL8vgkSytYtG76Ph#dy`?zy2&`JhRS3j3^P6%y{W;-5;Q!Scz*yiE~kEVo7Fxo?nB7grmi9 hy1$0%y@>)04F6{cv!Bj>_7rFqgQu&X%Q~loCII%_U2OmW literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/style/jsToolBar/bt_img.png b/v2/dotclear/admin/style/jsToolBar/bt_img.png new file mode 100644 index 0000000000000000000000000000000000000000..b991a527aa2d7cb8274152b4f7db01846e564112 GIT binary patch literal 899 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc3?z4jzqJQa%*9TgAsieWw;%dHU|?Wu2=EDU z1qvVdSX#6mQ1j)k}Go|ts9zhGJJ|NsA&>^Xht?1Ps6`GNHpw_TXp zyXtsMOJLf}w2*{+X$3X=yeFB{c1hUT&pGm6D|&bJ{DYZm_pCkjBz5kl7r#$-uRa%$ zq#ID=;!=GnZRX6`mzEy5xcPcC~X=mR4yb{qDu9vV%G*EQs zgE>yc*NlygHy^xGJ9X36llPk!A9XG}ZRTfm`1Zp$ukK08%1>EycHi-R6BZuHo3K?- zOiD>j!@d1TWMZ*j{hhR#XYzVtHXl3Nz5aUcjKdtf>{^<7ItknF+_|Q5G3E*|4suI^ z{DOf&K{vplyX}fM&|=O4kH}&M25un`X1sK_?hjBAI6tkVJh3R1!8b9vC_gtfB{NaMEwd=KJijQrSiv`9_e3of zpxVoxE{-7*my=H%WRm#6k<}sk;>u#KuHDirZqMAkLy_WZ|FG8TIy}`cuQ)o#aSVtn-7{Uotv|6-n4sKzs|@w798B;v#_XAes@A`Aa~-9 zgjGF0kyGcd(&P|%ZsfqS)8g>zLJiMhPGMBm*Z2R106fG(}YjZTW+eYz2EX7}# zBD!;Vy)SRlo@(s#@ZOhDA5Z?k$CJChnH#!tO}G`{uB*)H{#b`i#qr;a9|nTT6SGvy0fr%dE3Oro{`1hzI|J=V`WI`l8&xc*O0ubwi%nYY@EMxcY0}mU|`^zSNHz^ z|8MS|bmZdtwmJI~>sRM?ZeFzc+`G@GO+2zHCheTM;<&z3(zc_U7H&S=v+!VQ^ZJW- zHa2$6n!EnEZ9rlFvh{!dzWe^`zJ+68boGk8`}SnCtg`UQYn-*iF{I?t>wUGIbEm95 zTGYF(Z}E|%=e9QXE}FIGl&^HdX`pKbN`m}?fwm(9h6l>Al0Z4m0*}aI1_o{+5N5n| zx9$&6P^`o?qQtoGlds7@p!MOd1szt~a)Mk|J!)%W zOTPdAs!OC*%dhx4@yTZtwSAxPFH2kgrCsf9%C(G*W~Va@3h&;&u-ET&MEB-L77_k7 z{v3@4n>A}w=6rT~_(OEA|89#i8TN%XF5kjVrAsJ%S)K4?@$7D`hP_VHYHkZOa38Yq vf9J@M%5nd+TI(%y-VoapG3Im2p47?9Jdji@HB(pubRdJLtDnm{r-UW|&l>1o literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/style/jsToolBar/bt_ins.png b/v2/dotclear/admin/style/jsToolBar/bt_ins.png new file mode 100644 index 0000000000000000000000000000000000000000..f690b90d4f94b31315c4a6f7c8a011d3af305c3d GIT binary patch literal 308 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAd3?%E9GuQzs=3*z$5DpHG+YkL80J#PMJ|V6^ z`pv6*EzLC%;lWl`<_Gp|*|>h$-fqJ=X&JzUe$(qv_%CyJ@g z2I^rd3Gxg6&+v4+ffta+S>O>_%)r1c1j3A$?$-SQ3W}AuMwB=gr6!hS=I1GdWag$a z7#QjsSm+y=R24HQ0aYk~R0QXzm6RtIr84*?CKu)Brlw>jD!649rIzOxWfv>>M(m!b zr2z0KOr60h&AL?HX@;=~>rx>_pNsL9 p&kW2vmL*!bH!!kD6z&#hV`x;9cy(l#s{qg_22WQ%mvv4FO#uJIUXK6( literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/style/jsToolBar/bt_link.png b/v2/dotclear/admin/style/jsToolBar/bt_link.png new file mode 100644 index 0000000000000000000000000000000000000000..07a2b0e5bddac5c7f5cf627f891e50fe64a32fce GIT binary patch literal 833 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc3?z4jzqJQa%*9TgAsieWw;%dHU|?V@4DbnY z6_QbT`uKX$-iYezYH61xN3QR7s5$cO+qcMwkj%AvrcUXxceFk5v2^vSg%{pD=TR&1 znyFmBcJ=n{+tX)kiC)xUS9rjpyh74bw`FeOl{dR)ZoHhoX=2#aHEC&SItkmiU6^WY zY<&CXxj9Gv14Tp>9Rgd=7c4n!8eA~@(o!I>5A|;8pRXIadF`&##%X7!tT{XXO6sAr z51#zEXP@_E(#d`aJNs2T=e~J$uY3LVJ9n~w5wM8l3n?(Ii9 z7M3jAa!M~@)#ig&-u}GeSAXaK|Nr;yT)cPho}sbzi)XjBqId5*zOT8t+0Dma#&;pm z@B<&})~;Q-L1;G39Sl%JcLl9{OBmRXcqo?nz*tl%55d!m*KQ0-Mu7sn8Z@MMGIOcEbB zc1^#f9=(VwZPTgUoYPyQl(~0Rdx-ruT-nL-M3Iv#Y-iPH5BHT_md1xzd4+v18U3(G z?Fm*o`=BXkn~{{8*Q-81t4E#%j(;u8#8B#=bM8pU+L^JdwXvR!d4IZU%!G@M ze)?u7><=5-M2Ai57R=h6x6p5$Sb1BTn}eHA9Z$%GnA_f}4VKNa9L7$Ij1%wigq`5n ze42}gXUpe}fi1sd6`8qOHgIhE?V`+*`q@;`VH&gI3`xQBjBFqGa5ye75Yc${fTNP( Y-@aIjLe{0hKo2r_y85}Sb4q9e04Ly+QK$!8;-MT+OL9r6oh!W?b)Wnj^ z{5*w_%-mE414DfS3w;BVs$vEupb7<$is1aTlJdl&R0iL~|zDqh}{#lRDf#rJY5_^IHHq({Qu9)%u~<)=()nKg$!rd9v*iv^Z92e@Sp8dz4Oz1 g%s2TbeqlCbsGMc`zR~Z`I-pJlPgg&ebxsLQ0DVDCO#lD@ literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/style/jsToolBar/bt_paragraph.png b/v2/dotclear/admin/style/jsToolBar/bt_paragraph.png new file mode 100644 index 0000000000000000000000000000000000000000..5de086ecf20245f05569becf2def4153790d6828 GIT binary patch literal 295 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAd3?%E9GuQzs=3*z$5DpHG+YkL80J$mwJ|V6^ z`sw5AWu^I>H?A-?Hdawl3JmnUee;}v0RQo$yAuKD>8!cHX*u%e{N|{{R1f=FFMZ zs}`1)mfpK_ap}^fFP`1@^Yx632Dzu^B2Pq!O*0ePGS9+AZi4BSE>%y{W;-5&-97QqtN zh>{3jAFJg2T)o7U{G?R9irfMQ8~cia#N_PM5{0DH^vpb4B?ScqC56lsTcvPQUjyF) z=hTc$kE){7;3~h6MhJ1(0FE1>4w)RIJnirk#MVyg;UC9s)RKsHENUr7P1 zq$Jx`$q{6kLWFOCf^&XRs)C80p>DE)v5A6-nVylkk)^qrjzVx^iGo*Ro`R9Nf{}p% zkT9|`G_*1?1Ud!`l`9GBGM0zyk)Oennz|zM-ChKHOxWMjN1@m2**QVo82cNPd2f9mM-?nMJAP`9;~q z3eLgCHXxlSiV(IU^ryNcmZaK&!b2B`jLbp|jjc>9txV0Mkn}?op=tNcPsvQHglV_X zH89aNG7T{_wK6cbGPQ(iM^XgUZlezh2&8}khdRhlXySwdEF~EpUInE^IpAnXN!Cxz zNzF~oD=7wsnIUSJr6gOW!ks3@Lky**B{}~E>VYMO7^rXnCt6T;2+7P%WiT+*H?Yt*FsUkLPy(uu0jUVi zPb(=;EJ|g-lBQ=|a|4x&Gd*1#LnOj;&%YLGQV?iMoYtxtxb2FKidyg8|F+8(am(JD zf4*ij57R%D177EhydI@AWxW^v%e}K{x`e-i{=_qJM^ZBn{pQR&9m%u*wDD6T*WG&2 zQcJf#tJa)z`JAnJh;*9e)hmIWPd}Ec+)Z6_LLhcl-9gh3<+*#ldLK^qDp;SO^TEN? ugq`WdPQI6BNu}kvFQfz)tarN1d+%Kx@2c3)+24SUWbkzLb6Mw<&;$U$sl*Zh literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/style/jsToolBar/bt_pre.png b/v2/dotclear/admin/style/jsToolBar/bt_pre.png new file mode 100644 index 0000000000000000000000000000000000000000..b765759a6b9d242d0013d9e4a6579961300a42bd GIT binary patch literal 244 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAj3?#R^_xk}U=3*z$5DpHG+YkL80J&@dJ|V6^ z`pv6*2U1J+0a;8XL4Lvi8J=!8@B;EU3p^r=85p>QK$!8;-MT+OL9r6oh!W?b)Wnj^ z{5*w_%-mE414DfS3w;BVs$vEupb7<$is1aTlJdl&R0iL~|zDqh}{#lRDfzVJzX3_IHHq({Qu9)tXEUv%Xs+iO=*dD?+g-l?3O-pKlwm`yhfe; bb~%Pb3Da%wR@r?7YGUwo^>bP0l+XkK?Hx*6 literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/style/jsToolBar/bt_quote.png b/v2/dotclear/admin/style/jsToolBar/bt_quote.png new file mode 100644 index 0000000000000000000000000000000000000000..6cd98e118f5a14a707a636ec105a843149ba8aa3 GIT binary patch literal 322 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAd3?%E9GuQzs=3*z$5DpHG+YkL80J-V`J|V6^ z`sw5AGiS~W4D>yIbhnC%QdehFS!w>}jVo^7JZEfdoR|>(=G8p`@BNuTrMx9Ue!>5d z0E6udr8b}hXMsm#F#`j)5C}6~x?A@LC@5Cq8d2h0l$uzQnV+W+l9`*zU|^_kV4-hd zQdP{L1XQ5_QW2b=R#Ki=l*-_nm|T>fo0^iDsNj}alvbz##9pI7yO^$>2?DzAdj=aBeIx*fm;ZK886+f`vVjdD{+k|aV|5mEPyne2&QB{TPb^Ah@J&oE%Fj(r$xKvm%PdMQ&o9a@R`8A3 zJyA;qs5ZjW#W6(U^4bZz#TpcNobxlEDk}W@f8AQK$!8;-MT+OL9r6oh!W?b)Wnj^ z{5*w_%-mE414DfS3w;BVs$vEupb7<$is1aTlJdl&R0iL~|zDqh}{#lRDfz#JY5_^IHHq({Qu9)Z1j)k2){I!gq+jO|BX2!l`CW- p:first-child { + margin-top: 0; +} \ No newline at end of file diff --git a/v2/dotclear/admin/style/jsToolBar/resize.png b/v2/dotclear/admin/style/jsToolBar/resize.png new file mode 100644 index 0000000000000000000000000000000000000000..1b212709db2a3bf3158b90a32a15aed916f10d27 GIT binary patch literal 1267 zcmcIk&ubGw6y6w-7%8X+527%v2QTiOqC=I%|WFH3tpT8g#9qEiRU`Moa+gGEPzK_PmJ1C2_<_V4S$Ih(;m2 zTN0O&WN5p-fhvB;kS?o|rQ~#^&&ygtD;DN&p(f?%F7=RBK$@aJrx8^px(bUKHL;up zYlL>2Y*tq%Ibl{3cR3FT#{GU@?&oAb>|nK6EMi5&nkGSn6zzMQ#*!D^7?T|GR9R$& zPQV@CLkTZ!`Fp%1ib_({4%oz#tSkNr%49}{RvvQ(`1dldvsyU(;Nxtyl2!0%N0$%rRr@em&Uyu}C z((_eGmyEL|jWEntq%2X~=}X)b!I&tI36Ru~uC&GuN%3!$+wz azZZe}S^Djp7tdeAH=(xDsJ>i&`1lV+B|r@T literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/style/magnifier.png b/v2/dotclear/admin/style/magnifier.png new file mode 100644 index 0000000000000000000000000000000000000000..1578a8d114883a5e0fc8a9f47636f9f4a9c2eaa0 GIT binary patch literal 499 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJbFq_W2nPqp?T7vkfZWLeJ|V8t z<0ZCU`O>oN($wh-H=KHLbb89&tz9Q>f4ung`|kFD89VMDz5Dg^tA{lUE-WoHJh!Cm z?yH|4U)+0fdiA=KFLs@OarVL21Gm0hUDq~o#fe>0Qm#G!e*ewSnG4rHIXHKHwZq=) zpEsR*H)r?#Gc(hUF0X(5?$_LOrO)r4?Y;Wp(471mum0S6{iki!^>feuuRs4`PjBd{ zCDs4`|L1+-o(puIVM&l*Fpx_UV342XrwG){S>O>_%)r3)0fZTy)|kuy3M!PiMwA5S zr_xx+VCIcSU z2f1CVeNq?9wYt)~;DKt~z5g%Q80--^KVL0=+m?3Qs>DR4=P`5bA7uMFzF6>0N~79_ zwL@@fP{vlyf{n){Ce2|Ncra(N`OmG)nw~OI_nk~N9(+Asb@M>Vo)}RfhUbUVa(8)e zN>N^>6t|`Q?4sO~|8{eG^N!EgdzyGxJN$3P000>X1^@s6#OZ}&00004b3#c}2nYxW zdCT>+0It+AA0fgdn@SyCFOaBSQa55M+P5T&}Coy#OSAi%1eo zO- zU~Fv6js4qH@_0PL?RJaU*jR!8EKylmDK|5ICA+aFlJXhw9hr>EyyAP{)Z z%{;x`ZvUonBhu2+#Q69)i3Du;;q^`B(O&52g?(dVV+am}7=nz9jED&|91e%r-j+cK zO-@d}O-f3-g7x#jLFq+bU*C0B4dYu@Ru-mQR8%Aq6BGYqlxwxMwP9W4IHA+oQO&Ad)!H^FP4ZXyBj*65m1#Ws7 z&-(iMFolGKggs-L$Vk9n?lJ1Lx3|-i(8|h+2k!;IaY@2Zk%S4{9~L9g#KeSz6#;28DhUO zo{U6hN#@%AJ5p6uB}4TYQczG(hqW8JggI=^FD@<)(;KhX`@i~@Ms9AdSYKb4WjZ=K z`cCEJC*X)pO|#Q=b#+eUW`iN1%bA&(5fkL(0mMYJY4pxUydrKRN| z4&%{7YiVgoU>FIf(_xbar;~)N*KXFWQI~&Gj!;Q9mnthxX6?C^cv;=uU@m3DVzWTYP_Uf~VqxF;i@ zKSBlv2S-)>nPd*C4D~T__)(3ot+uwdFTVJqxVShmF%iSChYufq_uY59ckk}#=s14-cyMrVSXh`$Cfm4i zzl;K3I!UW|;4golS078X8w^r*G9wY0RfzrX+1ty@7sK~kyo=+UEB zu3Q-%9sTB;Z*Jed?dRur`t<4Z=g)U{cRzjlw5X`4wzhU+Vq$7)N~hB?nM?+QAruN} zG@4i}Zfa_>TCJac`stG=PkMTKT3TB6?%kV{lT%$?U0+`x6B833AFos@<#PG*<;yJ= z%Z(d16bc23qGMxYLqkIe2?-4i4X&=PB9SN{Ai&AV35Ma`-rlsdwB+REuCA^vTehU8 zreCc+qzD881VP;0-MziNuU)$~JUpDApMU1enf2?}`}p`AK782O**PmK zi_7Jfl$31WzWvmxQ=Xol<>lo|mMp2PthBec$F=|K5C0cxLUeLcRHQOGKc(4S-#bEybuI zGO!wCy1IBd2LQq0OGE%F8W)>cZm!;bodA)GvBpKPh3nxe2-Kkxk+fF0(0@?JYcNw_ z9#r+C3AD9m3hNpBx&aG;ND{afw?#s9&s33saD0sbBsu5H$56-9`A&{(g>_)4f`!2B zfk;F@B&Wb#qqlEH+sWaKFz*4vWmADxany$S)tb{}Og1`9Ncd6!j%Q>s!>nJ#!ZKdO z(`6_l8I}`XPz2vPLXf6NP6bT|k%J;eU!Siq3!6Mw`u(F%KHQOryb4kUon@}(c&DzZ zGf^BbmOo@MHNI_ zjymgSwI=3wSdn&z1&MHt@@k}`p6`UF^|mYSovAjeg?`8b0}u@rGf09rYSh?K*S=}B z9=#q5VQr=3#~6lPvVaKXfcgB&2i4pEqaGN>Ao=j5(k>jNxZl0Od! z&hZtA%|iQ}bVmgM^7+`RB$24z%p%?L*U9j7b&3}x-LT)*c9J|Sjv;VrEGKg=*J~;$ zfQw9)A#jQkA8i3B$f%TTU{8}&l~ENSxcR%>JoQ($Jq*73&-sO2U$ zVE>xFdMCT3FV+QtbNl7~DVja*i9ghWSm1w4ScMH1ogQq7aL@-P-5 zUcEqAGz_JGjmHU>x=@A><^Mf)I^ilB?nFvm61&Gl$xSUk2rP!bet zd<(Em5$j@u_E6=YFVMxN%5OHq`~t|H3>$uy6#HOS2>;Zs@k<{^&tg=ITGqLT0|K8*TG?}42ACa6z7@r%v*EYY> z*y&KGD4w}Wp%O&nNUy70-awkm5sHSF5r78+owPkhKQZtW}5bC}VfD%_?9-oGB_J|*Z`sjj-7iYuG zJdvaVu|MxPby!8vu!<%JPR@?q4_;f!Is_C~qaw8=czh~48VwE}ZZ95EfRVyrpZqcC zKop$3#G5fZ?*uB$Xai0y%Z;wPL?jJmt2{f&?98muotnfEV+hX+@l%&0AbaPdK7u^| z0B8q&G7={8i31cWM);a;z|dVtdT?!j+}UrsWv`SV@xnrixoW;+a^M~l;_0};18g?% zw!WQ%V2FgiXJw%Xqm(!*U+pR~QV z2qwgjmHHiT2Zd+u&UMn8_!IC|Mh&vDF;^FQYznA1A@-Yc?Vu(DWk+i!?i3IOn}s6! zq5bJ4ARu)2DvGV9Z1m^Ufw7y?nE-|Dm%lytOeK$hBv1+jc*Hc)yhg*9nz=r<3;6&P zQU`eyZC~ehtQsNutl{dSUt9OOun7`UD@5rptZ1?aL;AvB5UCz0k7f-_e2|q@gKDXWIMRgQ#Ua_VH(Y3r4$3M0je0P?cIW<8}BFK;k>`Am7MdKlzNS1MkBbC&9JWpKyo2oKWGpJ$~*09(H$xmg*kF1UkX4p z_M%t_2`%;Z$~kBPB_iJ>A;8~J;tK@!dZp6LGEpKw1Y=u+Vn;8MkgSYnoT`LEL?Q_c zNS2Z$K-Ah5@vebp*$ojL6HY9Q)t+f)i(W{rspLilhU_u=aA;8)P_mI?K@beuKYtzs1j#q$ z&NB;f8mxdL=K$dRnDn&{$E&!rGO}$>T)_6!+PMB|=?6GWkPu7AU7H+wpc)yG1nD?= z4tRp2Ejr@8VF3$FqZ$+5gH; z2v}2zuJjS^F%k;`d^8YOR)avAkOJEPjJMg{)7OkjLQrh~nj`>P=*f7UW}Y)beQjC5 zM)p9?8ng5=ZbS*fXqm6aC@5xRSaMIh#_f&ZFU^p6M2Gk+c!ncUWwIaiD3RFYHRV^a zoavdP6f*q=(%z2>P3# f!Q+M6P$=gM+!TBx5?Gm+$9DBQ392Hbz-n+d*DVM&9$| zm-vh*-9&jZqW9hLjq+Xj>H$U%x;T zZKAVONU`Sa4zl}*nvisVbvO!zm6U!Y;+;pqoZ-^1x@A3_5sH70;Hn}aR@k+Z$d@S_ zcxgv_%ANyklqo4{iR!R9WTQZ&wcQ_)NdV+9sedNjI97FB;|@oVv(N=;g)}M~c@}v5 zlbKFB0Fz#=lJND7B9no22AN1iZ`9zs4zY!cK{iQ53vY&}OB9K%45ZP5%+eMK59hIg zfyjll=vDaI)`IhZ2Bsg#fd4WEY?{Q@lSBi>8yFTdNz)q4^g&y9U;FZvETsO&{0Z zQk5Z}>}6lO^x&FKU!{=VBY`ZyBjv_~Kk!wgWUVk`^2Ms*@hKVwg3d%I(}e6*A*VQ4sv* zM9;yhNa4?Wq4V2-Z3 zcQD|~k35(k`d}oHno18^GA%0Y@>wHeO8R>U>T)~t!qkLtFw$yEP8Ee)yxOdBjqhX# z49pT6sOA`uUpml{H?UwW2iB{nivN~GU{Yh=nw(wPEU!9bc!EF{6`F;jHfkDX0;GY( zH9R67pH4hJEPU7cjR`*A;w!OGTlVA0IVJMlD6>Gg(SR29O%k=^<#R`e?t9zx4sTLF z3xqC=P6(cN%y2>!Wc0UlV6)xVz@L1$Z+d8-#x7TsxTABwfG-zLo_heWLs2AP`__{m zT1@Q1usbM@v zFIW3RvQlSbcDXuVllEdF(zcF4T9WwFi|13uYQe#Y@}K1Q6?eXKzO! zp|H+~hltvsCpL36JYEfjOGL4@SsBSbGrd`IV0Ns~=3^G>#r*(?oVa+{Ji~Hc+mBy@ zK;khS9MoD#fv=ioQFuuU=PgV$9TnX(_^gUnD3(5b`{Ij=B>SK3gVROK9i5W{A&Npq z_SIt+00Q@(6Rp$7*t<{!Y|>PGR{Oja0%YQAlds3@LuVgxFzLXDQ?Yn{$%^D&#T^XOew8*zRka0-`LX%7?-)!B4GF?v{=BQW`41y=lb0%Q_C*t zBb5qr_B2SO&+`o1a`LMYZZ2Qxym;)O?S4APtzehtG8I^`Val8|-9|q%!nS@t34#UDf*3uLv7#)dH7#A&`|t`ykxc{lEuS zPqUg9muNkgJNhA)&YX}5p2-+wPcQjyua5>X!{S80h^n*)&1$#fe&_OQ1sXD@4VS;E z**k_YHeX4keS+#KgYWOR{wb%=e-Zhf5p+x z;9UJRKYhcdBRI}b^O;BeU+dBSXT~`kDNzbMj$tUsE~hAD6850Ele}!#h*!3#T*EG4 zh8;c?W!Dl45W~;$^L16sd1=oSU;)r0 zs}LmCT1wEp^7buiSns>kUOfOWGS*T)E85u+dF3$=(|%KWOtY6^pl>6c`TxVAhD83G zIQw7X*qkyxp4BnE)FBmj|Mi#~&2GU%w%`q~Tg3UROH=(yqHImbXRf?5k9XoB0LnNG z7Ux{v>*c}QY015EodIO@-Yx}YMlHMWwz~8=kL0*+=e=v1m$A8t-$1ukp872|hj5vD24R25r+S->WdHpJ6z^o; z>=mA8nKQS8r1ztFE^O)PZaR5JOMa4tS8aPj-!X$jS_hJo67e^tx74Pf{5tJ5;$2ysG(SfC~8F zvNSRXIocRi&gWCM-r0RJYp=!Ty^RicX&s103*dK(UpTz_q457v=v)X3@8!OIMl@^r zB4&tD*iSSGy&@tO&zpW$$%*$`G(njWQVc}#(n}w#&&RaRxRBJ2JmNgh`#UyPA-Lng z-?Y1nQDX;$<^XE@KRqN~QHZtyg*D0p>{z(Nwai*8h=T1PnP0y3VR;+*mV0=PB~nwT zhlN2StRx0xtP+h#+Xo))wcsZ>6~pAy>F&oz)R;Oz`Ae|PtWOpNly*hU3H~$p|juX`wfun+&v@ey!hMA zM&SjV$7S{E;=m^tI!sYb`UcH0C4o!C;P9>is8^+PAN2#K7+S5V__QP8bBxctl@-AR z33QhCs;_S{qK56G^Y`IpL{gHt5Ao9BwYQ4yk6)VL%PBTAnQt?^i}Lclnr zxD-=E_p#lk1P)z-7o`(QM2W*DSA98gwu`u=TDPx!VO25DJZ>Q(q7ZT41 zMG2feW`t~r6FRgsrMQ@b8+8~_)%x}8Hoy3xGN)wOR2gqRF6124rMAU|oYEDD6&Esk zj;e;VRk)B^wnbG&X_RIV$CU_4A=zBT_2IMDm%9RqIb9#m@A@k-7WrZ{q4U-pb*MieKQZOwNbBn zt?@tV=fCp=`2PAxpRJ!z#_72T;RPg9X09BaYal7@as@94UnPVnST$l4X1clv+`4C( z&KfedZx0V&NBgqB!w@)0f~TWv7@0?zHEn+(UaPg;_v!u816iv1OvhNhV9=8o8U=TS zrWGRzRYaX4*#{YMVXzm1rN zhwtjm+*Y7q#nQP&3!k!f^VSG2+qrYk`^}<@X6E9E7&-=?W({7dmM&YoZspvIRq4{g z)A-}v3L~3X-nQSXpnH=&)Dzh1M z6@hz7<^%HOdTEj&U07OM#L#XqE2NEE-_i1!6Rt}-l-e6*;bdaj7zv2&F;`7ANY&P> z4uGHCbXsr0pohTD8F_=;wr3RjTWN4&-8=dwB~(=CN@|lWi(%Co?sho{`58n9xYsvt z`|N#&`@bgyqjN&OE4-p-SJBxXa$g;mVmrH7%nI2Tr!8jULclCha`A?_m#MX^`D;e! zh|nOb@hg47*1R}J_x9N!@eIf!mCDt%R4)=ZK4A+8B~7AaX;h6RO9n6VA3u1VbS>QH(Oq1JVqRRQJ5v?|SX%T*5=sV@X*j%0b4>iglnSo-W+m|G5op(k~ zI3U|9>#t}IV;{@8KLn&S7m9oBPS;?p!aPt^oLe_|(#wU63}^oZtku#)#nv(Q+>OuL zKeAu^9-^RMiIgs@ekZb9pRz9CccR$v4Jo0&60!2aw{M$E5i28LjtCad5+&N@WWN#m zV3vqt0NHETI>yC`aUy$t|KePxC$~ePh>W&zZtxo)7z~#~#UtQJ1pvA7;=LX{9kTK% zW9};beeHFdDB-Eb-6c~|`@QY~YAXr2`fjW+<#y<^y!255pI6lPa0GI5DaZix*KHZB zLO|r>$HcaQsud@Q$C}~1zkoGbnAqs&G_#W8n^*K7kfC$Lb>&o6dFF~lVFQq~taLsG zdoNGqwzG>~E0P1SOCG+1&7{bj;8(Og-xf&NG_!_@Mn9;gXZz)cvoY2MfHf+*Q5`bA z#A!~6K92+9jb!--o-loHki>3fFcQ9`wh~F!HlyccZi>wPW2V z;yI;+2;c%vAJ1Ez%h5-JVM=G`q;fN-oLoOf9r9v^6y5}DU`{a{~2TUE%QNnlxy-+>!2Kr7WNTT zu%;~9*^W?rej OhM#~I&wK(i`}3bHw&zm- literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/style/modal/modal.css b/v2/dotclear/admin/style/modal/modal.css new file mode 100644 index 0000000..8524e7c --- /dev/null +++ b/v2/dotclear/admin/style/modal/modal.css @@ -0,0 +1,52 @@ +div.jq-modal { + line-height: 1; + background: #fff; +} +div.jq-modal-container { + padding: 1px; + position: relative; +} +div.jq-modal-content { + position: relative; + overflow: auto; +} +div.jq-modal-closer { + position: absolute; + top: -12px; + right: -12px; + width: 25px; + height: 25px; +} +div.jq-modal-closer a { + display: block; + text-indent: -5000px; + width: 25px; + height: 25px; + outline: none; + border: none; +} + +/* modalImage */ +div.jq-modal-content img { + display: block; +} +span.jq-modal-legend { + display: block; + padding: 3px 0; +} +a.jq-modal-next, a.jq-modal-prev { + display: block; + position: absolute; + top: 0; + width: 50%; + bottom: 0; + outline: none; + border: none; + text-indent: -5000px; +} +a.jq-modal-next { + right: 0; +} +a.jq-modal-prev { + left: 0; +} \ No newline at end of file diff --git a/v2/dotclear/admin/style/msg-error.png b/v2/dotclear/admin/style/msg-error.png new file mode 100644 index 0000000000000000000000000000000000000000..43894f10d6456ab103a3c075a40eb46fc4a6a39a GIT binary patch literal 4159 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 JPDHLkV1k%<`Gx=h literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/style/msg-std.png b/v2/dotclear/admin/style/msg-std.png new file mode 100644 index 0000000000000000000000000000000000000000..3b6e1072d5e6a03465d5117633a06924097492b2 GIT binary patch literal 1135 zcmV-#1d#iQP)FVU=g##jss#)7IqSdHpY^fVRwBaxDgMm@U;E~0u(EGqFDS1RS4z*XUQxRlKXttf zwjVs?Z&)<=WTzi&(@L)a=>*c9+ zWX@t6SgjO+*5tH@Af?G9dHJd3OWwa}g7;1iKiAXIu{*Vn%UOyDC%rAtW)iOgR%kZ=YKtxc$(BeM&!W>`yI>Ja~DRkuV zm7+VJ=TegF+`ekrt25*2nIA75K2{8aV9!L7G8QMKB1Fa#8A~}e^mm4=oY%$tLI+#! zSVC!Xf>dBC%eW9l+Qj*{)1@4M1wT@rP6-r6UynK$I z{~9Or0&1B-#8J%*B2e&yH-MqG5^ekPh<|r?_xa4pKx{2)8UcxQ%n5vo`G8O>s%grF zT1pTEFr&ntQgjBsT#VwuUF+8jw`5QZ!@H`+4%Cck=}BxI8y57iabYk0ogvmaK0kY& z)1@+VwQeDBfJKy6>LFmbr3X$}T23=+*0!icI5s}X&Y#XQT8;6vX4CBhki=B2Yr#gg z-mA#k!L}a6)^-_p^*b?=8LSf=b^BzJP;o+FEy}qTY>Wk%(?(D+cFbMl(xuihFsHzR zLI(h+FP11-;TB_BO4JmEDzy=$&YjDw6S&gfrj*l+M;7;?Ro(R6=tW}fk;}|%C;(ci zlhfzsVc(_)My$vQBf@NTzYm{Xy3PkR^$iZ*5*Isgsz;=)};&R$>;cUs>0W!V~nO|dRH}SzvbX#5AMA# z0lA_9C*lkp!6t)kagbQiQ%wpr*@`cv?SmaPzuPX2-hbd$8%qsbVx$ep5uA zM(I2VO{{86Q)9#K4|4e(2Ohrn%+=y35y4lg02F}`$N|0u15_71zV)8&``163o8Q06 z>j-;M%5zCFkxi7&lu!J4;J1%<9|p7sdB6fG5CIcLq}C+JQ@?$AAOJkT6VMKlhJ)82 zSB)SB$SDYQy;8QJ8FinE5lOE5CjS?rZw&c&@;82iBF{NF6X5^=002ovPDHLkV1oZX B7fb*E literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/style/package.png b/v2/dotclear/admin/style/package.png new file mode 100644 index 0000000000000000000000000000000000000000..f138df426616a114de712f4094c77ddebec62d97 GIT binary patch literal 771 zcmV+e1N{7nP)(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ;iAh93RCwB?l1pn{WfX>=wZDBi&DkNXCh?M^rxCm%g_c$jqyxta3IPW}JL$wp zi_)LbnLY!M9qP0o%q^7y-voGKN*6QG-Nt&q(Ue;*6yzj#j zGvohE3{Vu?FI83b74TM)B;o4i%ODYTUAa8Zf0>z?J@1^Osw?_0_fb^odyP?jSmx?N^wXK|5ZFu1p{ zv^4leRTDGgiFPYI?JTrypbagfqTuaQr|9+OP_wf$)6=6o&(E95(+mtl*hv8Rrojxn z_e|tnj-NO|&_E<^K8{nWFg##jV;d2{fHt(Wt;c&$2m#-CgcOOB>W}rWscoIqJ;Raw z+?aux?sjr6;-A%3T;%8+>YyPINy6{zm$-WW%;{Uh?|v%%qj!QRY7(cl4Tily&jYKBxaxl+R&v5 zQ(!`?9q%>XOAtapgAzg@w1K8+==YBjCo$f8L?h}pW#m)JHly&NxwCeAFF{?`IOmAt zv8(r-o@Jlf^hw>-!A6av(E!xMmwLFlx0a(RWwb524!V=nbByQ zL(vrd&b$2iaD)FgBGxuweKSgqWUu@P5XB;-X?m@yDl5y9q9_2EnmSAzCv0v%;^g5E zcyIbMR)#QKOK!iAA3L48Y$+B&9LVD0;;SDmEPT<)vN_B|qDVwU%nVaSh@@<)t#5B! z8m->{`{u3h@B9ip1eV3^|KTxI*{A(u2c!Ux2LM{CNbV6Px5oeg002ovPDHLkV1kst BWAp$3 literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/style/page-bg.png b/v2/dotclear/admin/style/page-bg.png new file mode 100644 index 0000000000000000000000000000000000000000..a048e81318ef31d2db442383a749b11760b8c5f0 GIT binary patch literal 1254 zcmcIkzi-n(6u#1`grG{mzjR6MEPMV|@f~hCny}Rf4eed1(PJX(vzA}@&mIVOJ z)K;sT!XAj3otPBs!!I{q2{Rcj)~rk>^X}8#kK#DJv1ToO`}*O<^JlLYets983&HBW z2!M-Mk~#6_{o~)ld7Uq9^9F129tkN}a9ESVWjCZf7Iq?7Y2**zE+qeSmKctQQb<5uG*oGs`m$PP!1=ypUz}V~h5sphz%8A83aU%()A-q$P`c-e& zH(-T@6c%JPXDj&vEX>MUQ8S9Ow_t;Cc!&5UOgUgX%n8=R?;t3g1Oai3J3K}vCpedXX6i}J92>V-=n-CaJ<_Hq@Y^ODIsaK-ziRO; z#Ir=hcX?d;u$5=B8R>o|^nKE^OfvQ3a8CR_F4d|FR_1~2+&+Kqpt6zy_%nE^A9bh2 OH&9zzuO2Nvdh!Q!$2|=I literal 0 HcmV?d00001 diff --git a/v2/dotclear/admin/style/warning.png b/v2/dotclear/admin/style/warning.png new file mode 100644 index 0000000000000000000000000000000000000000..5765d0c2eac8ee167c4fd2bff30faaff0b2dfae4 GIT binary patch literal 678 zcmV;X0$KfuP)Lk~?TrQ4of|Irov>Y)Cf7WJQ#y*ouXPg(yN$P>5LC z*rgK!Vx?#kh>ch%X$;tiNCN46R7$iFvCt-9A&Q9@#3Z`A+1=dd8H<~}n1_Wp-8nPo zH|k$j!R6b$0`1O9YzXyL*ZK=bLqNsO7* zUQr{HK#{I94-l_J`0*tgE`xaM z*)h>Kx)^UrVds_QX^qT`jSLz)*tL|_>pQgG+`~3&XzXQ4MCNU>GBCdFM*^shS0>Vw zOF*`LwU}ZV5R74__i+D3hUbC}09T|ND5sgF=Gdw3p<{#I`M#n#C?cjB*!g#h@w3ZM zYL5Zm0Siblog->getPosts($params); + + if ($post->isEmpty()) { + $core->error->add(__('This entry does not exist or is not published')); + $can_view_page = false; + } else { + $TB = new dcTrackback($core); + $tb_excerpt = $post->post_excerpt_xhtml.' '.$post->post_content_xhtml; + $post_title = $post->post_title; + $post_url = $post->getURL(); + } +} +else +{ + $core->error->add(__('This entry does not exist.')); + $can_view_page = false; +} + +# Change excerpt +if (!empty($_POST['tb_excerpt'])) { + $tb_excerpt = $_POST['tb_excerpt']; +} + +# Sanitize excerpt +$tb_excerpt = html::clean($tb_excerpt); +$tb_excerpt = html::decodeEntities($tb_excerpt); +$tb_excerpt = text::cutString(html::escapeHTML($tb_excerpt),255); +$tb_excerpt = preg_replace('/\s+/ms',' ',$tb_excerpt); + +# Send pings +if ($post && !$post->isEmpty() && !empty($_POST['tb_urls'])) +{ + $tb_urls = $_POST['tb_urls']; + $tb_urls = str_replace("\r",'',$tb_urls); + + $post_title = html::escapeHTML(trim(html::clean($post_title))); + + foreach (explode("\n",$tb_urls) as $tb_url) + { + try { + $TB->ping($tb_url,$id,$post_title,$tb_excerpt,$post_url); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } + } + + if (!$core->error->flag()) { + http::redirect('trackbacks.php?id='.$id.'&sent=1'); + } +} + +$page_title = __('Ping blogs'); + +/* DISPLAY +-------------------------------------------------------- */ +dcPage::open($page_title,dcPage::jsLoad('js/_trackbacks.js')); + +# Exit if we cannot view page +if (!$can_view_page) { + dcPage::close(); + exit; +} + +if (!empty($_GET['sent'])) { + echo '

        '.__('All pings sent.').'

        '; +} + +echo '

        '.html::escapeHTML($core->blog->name).' › '.$page_title.'

        '; + +echo '

        '. + sprintf(__('Back to "%s"'),html::escapeHTML($post->post_title)).'

        '; + +echo +'

        '. +html::escapeHTML($post->post_title).'

        '. +'
        '. +($post->post_excerpt_xhtml ? $post->post_excerpt_xhtml.'
        ' : ''). +$post->post_content_xhtml. +'
        '; + +if (!empty($_GET['auto'])) { + flush(); + $tb_urls = implode("\n",$TB->discover($post->post_excerpt_xhtml.' '.$post->post_content_xhtml)); +} else { + $auto_link = ''. + __('Auto discover ping URLs').''; +} + +echo +'

        '.__('Ping blogs').'

        '. +'
        '. +'

        '. + +'

        '. + +'

        '.form::hidden('id',$id). +$core->formNonce(). +'  '. +$auto_link.'

        '. +'
        '; + +$pings = $TB->getPostPings($id); + +if (!$pings->isEmpty()) +{ + echo '

        '.__('Previously sent pings').'

        '; + + echo '
          '; + while ($pings->fetch()) { + echo + '
        • '.dt::dt2str(__('%Y-%m-%d %H:%M'),$pings->ping_dt).' - '. + $pings->ping_url.'
        • '; + } + echo '
        '; +} + +dcPage::close(); +?> \ No newline at end of file diff --git a/v2/dotclear/admin/update.php b/v2/dotclear/admin/update.php new file mode 100644 index 0000000..4759c85 --- /dev/null +++ b/v2/dotclear/admin/update.php @@ -0,0 +1,222 @@ +Access denied'; + dcPage::close(); + exit; +} + +$updater = new dcUpdate(DC_UPDATE_URL,'dotclear',DC_UPDATE_VERSION,DC_TPL_CACHE.'/versions'); +$new_v = $updater->check(DC_VERSION); +$zip_file = $new_v ? DC_BACKUP_PATH.'/'.basename($updater->getFileURL()) : ''; +$version_info = $new_v ? $updater->getInfoURL() : ''; + +# Hide "update me" message +if (!empty($_GET['hide_msg'])) { + $updater->setNotify(false); + http::redirect('index.php'); +} + +$p_url = 'update.php'; + +$step = isset($_GET['step']) ? $_GET['step'] : ''; +$step = in_array($step,array('check','download','backup','unzip')) ? $step : ''; + +$archives = array(); +foreach (files::scanDir(DC_BACKUP_PATH) as $v) { + if (preg_match('/backup-([0-9A-Za-z\.-]+).zip/',$v)) { + $archives[] = $v; + } +} + +# Revert or delete backup file +if (!empty($_POST['backup_file']) && in_array($_POST['backup_file'],$archives)) +{ + $b_file = $_POST['backup_file']; + + try + { + if (!empty($_POST['b_del'])) + { + if (!@unlink(DC_BACKUP_PATH.'/'.$b_file)) { + throw new Exception(sprintf(__('Unable to delete file %s'),html::escapeHTML($b_file))); + } + http::redirect($p_url); + } + + if (!empty($_POST['b_revert'])) + { + $zip = new fileUnzip(DC_BACKUP_PATH.'/'.$b_file); + $zip->unzipAll(DC_BACKUP_PATH.'/'); + @unlink(DC_BACKUP_PATH.'/'.$b_file); + http::redirect($p_url); + } + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} + +# Upgrade process +if ($new_v && $step) +{ + try + { + $updater->setForcedFiles('inc/digests'); + + switch ($step) + { + case 'check': + $updater->checkIntegrity(DC_ROOT.'/inc/digests',DC_ROOT); + http::redirect($p_url.'?step=download'); + break; + case 'download': + $updater->download($zip_file); + if (!$updater->checkDownload($zip_file)) { + throw new Exception( + sprintf(__('Downloaded Dotclear archive seems to be corrupted. '. + 'Try download it again.'),'href="'.$p_url.'?step=download"') + ); + } + http::redirect($p_url.'?step=backup'); + break; + case 'backup': + $updater->backup( + $zip_file, 'dotclear/inc/digests', + DC_ROOT, DC_ROOT.'/inc/digests', + DC_BACKUP_PATH.'/backup-'.DC_VERSION.'.zip' + ); + http::redirect($p_url.'?step=unzip'); + break; + case 'unzip': + $updater->performUpgrade( + $zip_file, 'dotclear/inc/digests', 'dotclear', + DC_ROOT, DC_ROOT.'/inc/digests' + ); + break; + } + } + catch (Exception $e) + { + $msg = $e->getMessage(); + + if ($e->getCode() == dcUpdate::ERR_FILES_CHANGED) + { + $msg = + __('The following files of your Dotclear installation '. + 'have been modified so we won\'t try to update your installation. '. + 'Please try to update manually.'); + } + elseif ($e->getCode() == dcUpdate::ERR_FILES_UNREADABLE) + { + $msg = + sprintf(__('The following files of your Dotclear installation are not readable. '. + 'Please fix this or try to make a backup file named %s manually.'), + 'backup-'.DC_VERSION.'.zip'); + } + elseif ($e->getCode() == dcUpdate::ERR_FILES_UNWRITALBE) + { + $msg = + __('The following files of your Dotclear installation cannot be written. '. + 'Please fix this or try to update manually.'); + } + + if (isset($e->bad_files)) { + $msg .= + '
        • '. + implode('
        • ',$e->bad_files). + '
        '; + } + + $core->error->add($msg); + + $core->callBehavior('adminDCUpdateException',$e); + } +} + +/* DISPLAY Main page +-------------------------------------------------------- */ +dcPage::open(__('Dotclear update')); + +if (!$core->error->flag()) { + echo '

        '.__('Dotclear update').'

        '; +} + +if (!$step) +{ + if (empty($new_v)) + { + echo '

        '.__('No newer Dotclear version available.').'

        '; + } + else + { + echo + '

        '.sprintf(__('Dotclear %s is available.'),$new_v). + ($version_info ? ' ('.__('information about this version').')' : ''). + '

        '. + + '

        '.__('To upgrade your Dotclear installation simply click on the following button. '. + 'A backup file of your current installation will be created in your root directory.').'

        '. + '
        '. + '

        '. + '

        '. + '
        '; + } + + if (!empty($archives)) + { + echo + '

        '.__('Update backup files').'

        '. + '

        '.__('The following files are backups of previously updates. '. + 'You can revert your previous installation or delete theses files.').'

        '; + + echo '
        '; + + foreach ($archives as $v) { + echo + '

        '; + } + + echo + '

        '.__('Please note that reverting your Dotclear version may have some '. + 'unwanted side-effects. Consider reverting only if you experience strong issues with this new version.').' '. + sprintf(__('You should not revert to version prior to last one (%s).'),end($archives)). + '

        '. + '

        '. + ''. + $core->formNonce().'

        '. + '
        '; + } +} +elseif ($step == 'unzip' && !$core->error->flag()) +{ + echo + '

        '. + __("Congratulations, you're one click away from the end of the update."). + ' '.__('Finish the update.').''. + '

        '; +} + +dcPage::close(); +?> \ No newline at end of file diff --git a/v2/dotclear/admin/user.php b/v2/dotclear/admin/user.php new file mode 100644 index 0000000..3af0c90 --- /dev/null +++ b/v2/dotclear/admin/user.php @@ -0,0 +1,331 @@ +auth->getInfo('user_lang'); +$user_tz = $core->auth->getInfo('user_tz'); +$user_post_status = ''; + +$user_options = $core->userDefaults(); + +foreach ($core->getFormaters() as $v) { + $formaters_combo[$v] = $v; +} + +foreach ($core->blog->getAllPostStatus() as $k => $v) { + $status_combo[$v] = $k; +} + +# Language codes +$langs = l10n::getISOcodes(1,1); +foreach ($langs as $k => $v) { + $lang_avail = $v == 'en' || is_dir(DC_L10N_ROOT.'/'.$v); + $lang_combo[] = new formSelectOption($k,$v,$lang_avail ? 'avail10n' : ''); +} + +# Get user if we have an ID +if (!empty($_REQUEST['id'])) +{ + try { + $rs = $core->getUser($_REQUEST['id']); + + $user_id = $rs->user_id; + $user_super = $rs->user_super; + $user_pwd = $rs->user_pwd; + $user_change_pwd = $rs->user_change_pwd; + $user_name = $rs->user_name; + $user_firstname = $rs->user_firstname; + $user_displayname = $rs->user_displayname; + $user_email = $rs->user_email; + $user_url = $rs->user_url; + $user_lang = $rs->user_lang; + $user_tz = $rs->user_tz; + $user_post_status = $rs->user_post_status; + + $user_options = array_merge($user_options,$rs->options()); + + $page_title = $user_id; + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} + +# Add or update user +if (isset($_POST['user_name'])) +{ + try + { + if (empty($_POST['your_pwd']) || !$core->auth->checkPassword(crypt::hmac(DC_MASTER_KEY,$_POST['your_pwd']))) { + throw new Exception(__('Password verification failed')); + } + + $cur = $core->con->openCursor($core->prefix.'user'); + + $cur->user_id = $_POST['user_id']; + $cur->user_super = $user_super = !empty($_POST['user_super']) ? 1 : 0; + $cur->user_name = $user_name = $_POST['user_name']; + $cur->user_firstname = $user_firstname = $_POST['user_firstname']; + $cur->user_displayname = $user_displayname = $_POST['user_displayname']; + $cur->user_email = $user_email = $_POST['user_email']; + $cur->user_url = $user_url = $_POST['user_url']; + $cur->user_lang = $user_lang = $_POST['user_lang']; + $cur->user_tz = $user_tz = $_POST['user_tz']; + $cur->user_post_status = $user_post_status = $_POST['user_post_status']; + + if ($cur->user_id == $core->auth->userID() && $core->auth->isSuperAdmin()) { + // force super_user to true if current user + $cur->user_super = $user_super = true; + } + if ($core->auth->allowPassChange()) { + $cur->user_change_pwd = !empty($_POST['user_change_pwd']) ? 1 : 0; + } + + if (!empty($_POST['new_pwd'])) { + if ($_POST['new_pwd'] != $_POST['new_pwd_c']) { + throw new Exception(__("Passwords don't match")); + } else { + $cur->user_pwd = $_POST['new_pwd']; + } + } + + $user_options['post_format'] = $_POST['user_post_format']; + $user_options['edit_size'] = (integer) $_POST['user_edit_size']; + + if ($user_options['edit_size'] < 1) { + $user_options['edit_size'] = 10; + } + + $cur->user_options = new ArrayObject($user_options); + + # Udate user + if ($user_id) + { + # --BEHAVIOR-- adminBeforeUserUpdate + $core->callBehavior('adminBeforeUserUpdate',$cur,$user_id); + + $new_id = $core->updUser($user_id,$cur); + + # --BEHAVIOR-- adminAfterUserUpdate + $core->callBehavior('adminAfterUserUpdate',$cur,$new_id); + + if ($user_id == $core->auth->userID() && + $user_id != $new_id) { + $core->session->destroy(); + } + + http::redirect('user.php?id='.$new_id.'&upd=1'); + } + # Add user + else + { + if ($core->getUsers(array('user_id' => $cur->user_id),true)->f(0) > 0) { + throw new Exception(sprintf(__('User "%s" already exists.'),html::escapeHTML($cur->user_id))); + } + + # --BEHAVIOR-- adminBeforeUserCreate + $core->callBehavior('adminBeforeUserCreate',$cur); + + $new_id = $core->addUser($cur); + + # --BEHAVIOR-- adminAfterUserCreate + $core->callBehavior('adminAfterUserCreate',$cur,$new_id); + + if (!empty($_POST['saveplus'])) { + http::redirect('user.php?add=1'); + } else { + http::redirect('user.php?id='.$new_id.'&add=1'); + } + } + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} + + +/* DISPLAY +-------------------------------------------------------- */ +dcPage::open($page_title, + dcPage::jsConfirmClose('user-form'). + + # --BEHAVIOR-- adminUserHeaders + $core->callBehavior('adminUserHeaders') +); + +if (!empty($_GET['upd'])) { + echo '

        '.__('User has been successfully updated.').'

        '; +} + +if (!empty($_GET['add'])) { + echo '

        '.__('User has been successfully created.').'

        '; +} + +echo '

        '.__('Users').''.$page_title.'

        '; + +if ($user_id == $core->auth->userID()) { + echo + '

        '.__('Warning:').' '. + __('If you change your username, you will have to log in again.').'

        '; +} + +echo +'
        '. +'
        '.__('User information').''. +'
        '. +'
        '. +'

        '. +'

        '.__('At least 2 characters using letters, numbers or symbols.').'

        '. + +'

        '. +'

        '.__('Password must contain at least 6 characters.').'

        '. + +'

        '. + +'

        '. + +'

        '. + +'

        '. + +'

        '. +'

        '.__('Mandatory for password recovering procedure.').'

        '. +'
        '. + +'
        '. +'

        '. +'

        '. + +'

        '. + +'

        '. + +'

        '. + +'

        '; + +if ($core->auth->allowPassChange()) { + echo + '

        '; +} + +$super_disabled = $user_super && $user_id == $core->auth->userID(); + +echo +'

        '. +'
        '. +'
        '. +'
        '; + +# --BEHAVIOR-- adminUserForm +$core->callBehavior('adminUserForm',isset($rs) ? $rs : null); + +echo +'

        '. +'

        '. +($user_id != '' ? '' : ' '). +($user_id != '' ? form::hidden('id',$user_id) : ''). +$core->formNonce(). +'

        '. + +'
        '; + +if ($user_id) +{ + echo '

        '.__('Permissions').'

        '; + + $permissions = $core->getUserPermissions($user_id); + $perm_types = $core->auth->getPermissionsTypes(); + + if (count($permissions) == 0) + { + echo '

        '.__('No permissions.').'

        '; + } + else + { + foreach ($permissions as $k => $v) + { + if (count($v['p']) > 0) + { + echo '

        '. + html::escapeHTML($v['name']).' ('.html::escapeHTML($k).') - '. + '' + .__('Change permissions').'

        '; + + echo '
          '; + foreach ($v['p'] as $p => $V) { + if (isset($perm_types[$p])) { + echo '
        • '.__($perm_types[$p]).'
        • '; + } + } + echo '
        '; + } + } + } + + echo + '

        '. + __('Add new permissions').'

        '. + '
        '; +} + +dcPage::helpBlock('core_user'); +dcPage::close(); +?> \ No newline at end of file diff --git a/v2/dotclear/admin/users.php b/v2/dotclear/admin/users.php new file mode 100644 index 0000000..2f61820 --- /dev/null +++ b/v2/dotclear/admin/users.php @@ -0,0 +1,174 @@ +callBehavior('adminBeforeUserDelete',$u); + if ($u != $core->auth->userID()) { + $core->delUser($u); + } + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } + } + if (!$core->error->flag()) { + http::redirect('users.php?del=1'); + } +} + + +# Creating filter combo boxes +$sortby_combo = array( +__('Username') => 'U.user_id', +__('Last Name') => 'user_name', +__('First Name') => 'user_firstname', +__('Display name') => 'user_displayname', +__('Number of entries') => 'nb_post' +); + +$order_combo = array( +__('Descending') => 'desc', +__('Ascending') => 'asc' +); + +# Actions combo box +$combo_action = array( + __('Set permissions') => 'setpermissions', + __('Delete') => 'deleteuser' +); + +# --BEHAVIOR-- adminUsersActionsCombo +$core->callBehavior('adminUsersActionsCombo',array(&$combo_action)); + + +# Get users +$page = !empty($_GET['page']) ? $_GET['page'] : 1; +$nb_per_page = 30; + +if (!empty($_GET['nb']) && (integer) $_GET['nb'] > 0) { + $nb_per_page = $_GET['nb']; +} + +$q = !empty($_GET['q']) ? $_GET['q'] : ''; +$sortby = !empty($_GET['sortby']) ? $_GET['sortby'] : 'user_id'; +$order = !empty($_GET['order']) ? $_GET['order'] : 'asc'; + +$params['limit'] = array((($page-1)*$nb_per_page),$nb_per_page); + +$show_filters = false; + +# - Search filter +if ($q) { + $params['q'] = $q; + $show_filters = true; +} + +# - Sortby and order filter +if ($sortby !== '' && in_array($sortby,$sortby_combo)) { + if ($order !== '' && in_array($order,$order_combo)) { + $params['order'] = $sortby.' '.$order; + $show_filters = true; + } +} + +try { + $rs = $core->getUsers($params); + $counter = $core->getUsers($params,1); + $user_list = new adminUserList($core,$rs,$counter->f(0)); +} catch (Exception $e) { + $core->error->add($e->getMessage()); +} + + +/* DISPLAY +-------------------------------------------------------- */ +$starting_script = dcPage::jsLoad('js/_users.js'); +if (!$show_filters) { + $starting_script .= dcPage::jsLoad('js/filter-controls.js'); +} + +dcPage::open(__('users'),$starting_script); + +if (!$core->error->flag()) +{ + if (!empty($_GET['del'])) { + echo '

        '.__('User has been successfully removed.').'

        '; + } + + echo + '

        '.__('Users').'

        '. + '

        '.__('Create a new user').'

        '; + + if (!$show_filters) { + echo '

        '.__('Filters').'

        '; + } + + echo + '
        '. + '
        '.__('Filters').''. + + '
        '. + '

        '. + '

        '. + '
        '. + + '
        '. + '

        '. + '

        '. + '

        '. + '
        '. + + '
        '. //Opera sucks + '
        '. + '
        '; + + # Show users + $user_list->display($page,$nb_per_page, + '
        '. + + '%s'. + + '
        '. + '

        '. + + '

        '. + ''. + '

        '. + '
        '. + '
        ' + ); +} + +dcPage::close(); +?> \ No newline at end of file diff --git a/v2/dotclear/admin/xmlrpc.php b/v2/dotclear/admin/xmlrpc.php new file mode 100644 index 0000000..75195f3 --- /dev/null +++ b/v2/dotclear/admin/xmlrpc.php @@ -0,0 +1,35 @@ +plugins->loadModules(DC_PLUGINS_ROOT); + +# Start XML-RPC server +$server = new dcXmlRpc($core,$blog_id); +$server->serve(); +?> \ No newline at end of file diff --git a/v2/dotclear/cache/.htaccess b/v2/dotclear/cache/.htaccess new file mode 100644 index 0000000..14249c5 --- /dev/null +++ b/v2/dotclear/cache/.htaccess @@ -0,0 +1 @@ +Deny from all \ No newline at end of file diff --git a/v2/dotclear/db/.htaccess b/v2/dotclear/db/.htaccess new file mode 100644 index 0000000..14249c5 --- /dev/null +++ b/v2/dotclear/db/.htaccess @@ -0,0 +1 @@ +Deny from all \ No newline at end of file diff --git a/v2/dotclear/inc/.htaccess b/v2/dotclear/inc/.htaccess new file mode 100644 index 0000000..14249c5 --- /dev/null +++ b/v2/dotclear/inc/.htaccess @@ -0,0 +1 @@ +Deny from all \ No newline at end of file diff --git a/v2/dotclear/inc/admin/class.dc.menu.php b/v2/dotclear/inc/admin/class.dc.menu.php new file mode 100644 index 0000000..9a016dd --- /dev/null +++ b/v2/dotclear/inc/admin/class.dc.menu.php @@ -0,0 +1,88 @@ +id = $id; + $this->title = $title; + $this->itemSpace = $itemSpace; + $this->items = array(); + } + + public function addItem($title,$url,$img,$active,$show=true,$id=null,$class=null) + { + if($show) { + $this->items[] = $this->itemDef($title,$url,$img,$active,$id,$class); + } + } + + public function prependItem($title,$url,$img,$active,$show=true,$id=null,$class=null) + { + if ($show) { + array_unshift($this->items,$this->itemDef($title,$url,$img,$active,$id,$class)); + } + } + + public function draw() + { + if (count($this->items) == 0) { + return ''; + } + + $res = + '
        '. + ($this->title ? '

        '.$this->title.'

        ' : ''). + '
          '."\n"; + + for ($i=0; $iitems); $i++) + { + if ($i+1 < count($this->items) && $this->itemSpace != '') { + $res .= preg_replace('|$|',$this->itemSpace.'',$this->items[$i]); + $res .= "\n"; + } else { + $res .= $this->items[$i]."\n"; + } + } + + $res .= '
        '."\n"; + + return $res; + } + + protected function itemDef($title,$url,$img,$active,$id=null,$class=null) + { + if (is_array($url)) { + $link = $url[0]; + $ahtml = (!empty($url[1])) ? ' '.$url[1] : ''; + } else { + $link = $url; + $ahtml = ''; + } + + $img = dc_admin_icon_url($img); + + return + ''. + + ''.$title.''."\n"; + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/admin/lib.dc.page.php b/v2/dotclear/inc/admin/lib.dc.page.php new file mode 100644 index 0000000..a3b013a --- /dev/null +++ b/v2/dotclear/inc/admin/lib.dc.page.php @@ -0,0 +1,709 @@ +blog && $core->auth->check($permissions,$core->blog->id)) + { + return; + } + + if (session_id()) { + $core->session->destroy(); + } + http::redirect(DC_AUTH_PAGE); + } + + # Check super admin + public static function checkSuper() + { + global $core; + + if (!$core->auth->isSuperAdmin()) + { + if (session_id()) { + $core->session->destroy(); + } + http::redirect(DC_AUTH_PAGE); + } + } + + # Top of admin page + public static function open($title='', $head='') + { + global $core; + + # List of user's blogs + if ($core->auth->blog_count == 1 || $core->auth->blog_count > 20) + { + $blog_box = + __('Blog:').' '. + html::escapeHTML($core->blog->name).''; + + if ($core->auth->blog_count > 20) { + $blog_box .= ' - '.__('Change blog').''; + } + } + else + { + $rs_blogs = $core->getBlogs(array('order'=>'LOWER(blog_name)','limit'=>20)); + $blogs = array(); + while ($rs_blogs->fetch()) { + $blogs[html::escapeHTML($rs_blogs->blog_name.' - '.$rs_blogs->blog_url)] = $rs_blogs->blog_id; + } + $blog_box = + ''. + ''; + } + + $safe_mode = isset($_SESSION['sess_safe_mode']) && $_SESSION['sess_safe_mode']; + + # Display + header('Content-Type: text/html; charset=UTF-8'); + echo + ''."\n". + ''."\n". + "\n". + ' '."\n". + ' '.$title.' - '.html::escapeHTML($core->blog->name).' - '.html::escapeHTML(DC_VENDOR_NAME).' - '.DC_VERSION.''."\n". + + ' '."\n". + ' '."\n". + + self::jsLoadIE7(). + ' '."\n"; + if (l10n::getTextDirection($GLOBALS['_lang']) == 'rtl') { + echo + ' '."\n"; + } + + $core->auth->user_prefs->addWorkspace('interface'); + $user_ui_hide_std_favicon = $core->auth->user_prefs->interface->hide_std_favicon; + if (!$user_ui_hide_std_favicon) { + echo ''; + } + + echo + self::jsCommon(). + $head; + + # --BEHAVIOR-- adminPageHTMLHead + $core->callBehavior('adminPageHTMLHead'); + + echo + "\n". + ''."\n". + + ''; + + echo + '
        '."\n". + '
        '."\n". + '
        '."\n"; + + # Safe mode + if ($safe_mode) + { + echo + '

        '.__('Safe mode').'

        '. + '

        '.__('You are in safe mode. All plugins have been temporarily disabled. Remind to log out then log in again normally to get back all functionalities').'

        '. + '
        '; + } + + if ($core->error->flag()) { + echo + '
        '.__('Errors:').''. + $core->error->toHTML(). + '
        '; + } + } + + public static function close() + { + $menu =& $GLOBALS['_menu']; + + echo + "
        \n". // End of #content + "
        \n". // End of #main + + ''."\n". // End of #main-menu + ''."\n". + "
        \n"; // End of #wrapper + + if (defined('DC_DEV') && DC_DEV === true) { + echo self::debugInfo(); + } + + echo + ''; + } + + public static function openPopup($title='', $head='') + { + global $core; + + # Display + header('Content-Type: text/html; charset=UTF-8'); + echo + ''."\n". + ''."\n". + "\n". + ' '."\n". + ' '.$title.' - '.html::escapeHTML($core->blog->name).' - '.html::escapeHTML(DC_VENDOR_NAME).' - '.DC_VERSION.''."\n". + + ' '."\n". + ' '."\n". + + self::jsLoadIE7(). + ' '."\n"; + if (l10n::getTextDirection($GLOBALS['_lang']) == 'rtl') { + echo + ' '."\n"; + } + + echo + self::jsCommon(). + $head; + + # --BEHAVIOR-- adminPageHTMLHead + $core->callBehavior('adminPageHTMLHead'); + + echo + "\n". + ''."\n". + + '

        '.DC_VENDOR_NAME.'

        '."\n"; + + echo + '
        '."\n". + '
        '."\n". + '
        '."\n"; + + if ($core->error->flag()) { + echo + '
        '.__('Errors:').''. + $core->error->toHTML(). + '
        '; + } + } + + public static function closePopup() + { + echo + "
        \n". // End of #content + "
        \n". // End of #main + ''."\n". + "
        \n". // End of #wrapper + ''; + } + + private static function debugInfo() + { + $global_vars = implode(', ',array_keys($GLOBALS)); + + $res = + '
        '. + '

        memory usage: '.memory_get_usage().' ('.files::size(memory_get_usage()).')

        '; + + if (function_exists('xdebug_get_profiler_filename')) + { + $res .= '

        Elapsed time: '.xdebug_time_index().' seconds

        '; + + $prof_file = xdebug_get_profiler_filename(); + if ($prof_file) { + $res .= '

        Profiler file : '.xdebug_get_profiler_filename().'

        '; + } else { + $prof_url = http::getSelfURI(); + $prof_url .= (strpos($prof_url,'?') === false) ? '?' : '&'; + $prof_url .= 'XDEBUG_PROFILE'; + $res .= '

        Trigger profiler

        '; + } + + /* xdebug configuration: + zend_extension = /.../xdebug.so + xdebug.auto_trace = On + xdebug.trace_format = 0 + xdebug.trace_options = 1 + xdebug.show_mem_delta = On + xdebug.profiler_enable = 0 + xdebug.profiler_enable_trigger = 1 + xdebug.profiler_output_dir = /tmp + xdebug.profiler_append = 0 + xdebug.profiler_output_name = timestamp + */ + } + + $res .= + '

        Global vars: '.$global_vars.'

        '. + '
        '; + + return $res; + } + + public static function help($page,$index='') + { + # Deprecated but we keep this for plugins. + } + + public static function helpBlock() + { + $args = func_get_args(); + if (empty($args)) { + return; + }; + + global $__resources; + if (empty($__resources['help'])) { + return; + } + + $content = ''; + foreach ($args as $v) + { + if (is_object($v) && isset($v->content)) { + $content .= $v->content; + continue; + } + + if (!isset($__resources['help'][$v])) { + continue; + } + $f = $__resources['help'][$v]; + if (!file_exists($f) || !is_readable($f)) { + continue; + } + + $fc = file_get_contents($f); + if (preg_match('|]*?>(.*?)|ms',$fc,$matches)) { + $content .= $matches[1]; + } else { + $content .= $fc; + } + } + + if (trim($content) == '') { + return; + } + + echo + '

        '.__('Help').'

        '. + $content. + '
        '; + } + + public static function jsLoad($src) + { + $escaped_src = html::escapeHTML($src); + if (!isset(self::$loaded_js[$escaped_src])) { + self::$loaded_js[$escaped_src]=true; + return ''."\n"; + } + } + + public static function jsVar($n,$v) + { + return $n." = '".html::escapeJS($v)."';\n"; + } + + public static function jsCommon() + { + return + self::jsLoad('js/jquery/jquery.js'). + self::jsLoad('js/jquery/jquery.biscuit.js'). + self::jsLoad('js/jquery/jquery.bgFade.js'). + self::jsLoad('js/common.js'). + self::jsLoad('js/prelude.js'). + + '\n"; + } + + public static function jsLoadIE7() + { + return + ''."\n"; + } + + public static function jsConfirmClose() + { + $args = func_get_args(); + if (count($args) > 0) { + foreach ($args as $k => $v) { + $args[$k] = "'".html::escapeJS($v)."'"; + } + $args = implode(',',$args); + } else { + $args = ''; + } + + return + self::jsLoad('js/confirm-close.js'). + '\n"; + } + + public static function jsPageTabs($default=null) + { + if ($default) { + $default = "'".html::escapeJS($default)."'"; + } + + return + self::jsLoad('js/jquery/jquery.pageTabs.js'). + '\n"; + } + + public static function jsModal() + { + return + ''."\n". + self::jsLoad('js/jquery/jquery.modal.js'). + '\n"; + } + + public static function jsColorPicker() + { + return + ''."\n". + self::jsLoad('js/jquery/jquery.farbtastic.js'). + self::jsLoad('js/color-picker.js'); + } + + public static function jsDatePicker() + { + return + ''."\n". + self::jsLoad('js/date-picker.js'). + '\n"; + } + + public static function jsToolBar() + { + $res = + ''. + ''; + + if (isset($GLOBALS['core']->auth) && $GLOBALS['core']->auth->getOption('enable_wysiwyg')) { + $res .= ''; + } + + $res .= + ''. + '\n"; + + return $res; + } + + public static function jsCandyUpload($params=array(),$base_url=null) + { + if (!$base_url) { + $base_url = path::clean(dirname(preg_replace('/(\?.*$)?/','',$_SERVER['REQUEST_URI']))).'/'; + } + + $params = array_merge($params,array( + 'sess_id='.session_id(), + 'sess_uid='.$_SESSION['sess_browser_uid'], + 'xd_check='.$GLOBALS['core']->getNonce() + )); + + return + ''."\n". + self::jsLoad('js/jquery/jquery.candyUpload.js'). + + '\n"; + } + + public static function jsToolMan() + { + return + ''. + ''. + ''. + ''. + ''. + ''. + ''; + } + + public static function jsMetaEditor() + { + return + ''; + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/admin/lib.pager.php b/v2/dotclear/inc/admin/lib.pager.php new file mode 100644 index 0000000..488e091 --- /dev/null +++ b/v2/dotclear/inc/admin/lib.pager.php @@ -0,0 +1,420 @@ +core =& $core; + $this->rs =& $rs; + $this->rs_count = $rs_count; + $this->html_prev = __('«prev.'); + $this->html_next = __('next»'); + } +} + +class adminPostList extends adminGenericList +{ + public function display($page,$nb_per_page,$enclose_block='') + { + if ($this->rs->isEmpty()) + { + echo '

        '.__('No entry').'

        '; + } + else + { + $pager = new pager($page,$this->rs_count,$nb_per_page,10); + $pager->html_prev = $this->html_prev; + $pager->html_next = $this->html_next; + $pager->var_page = 'page'; + + $html_block = + ''. + ''. + ''. + ''. + ''. + ''. + ''. + ''. + '%s
        '.__('Title').''.__('Date').''.__('Category').''.__('Author').''.__('Comments').''.__('Trackbacks').''.__('Status').'
        '; + + if ($enclose_block) { + $html_block = sprintf($enclose_block,$html_block); + } + + echo '

        '.__('Page(s)').' : '.$pager->getLinks().'

        '; + + $blocks = explode('%s',$html_block); + + echo $blocks[0]; + + while ($this->rs->fetch()) + { + echo $this->postLine(); + } + + echo $blocks[1]; + + echo '

        '.__('Page(s)').' : '.$pager->getLinks().'

        '; + } + } + + private function postLine() + { + if ($this->core->auth->check('categories',$this->core->blog->id)) { + $cat_link = '%s'; + } else { + $cat_link = '%2$s'; + } + + if ($this->rs->cat_title) { + $cat_title = sprintf($cat_link,$this->rs->cat_id, + html::escapeHTML($this->rs->cat_title)); + } else { + $cat_title = __('None'); + } + + $img = '%1$s'; + switch ($this->rs->post_status) { + case 1: + $img_status = sprintf($img,__('published'),'check-on.png'); + break; + case 0: + $img_status = sprintf($img,__('unpublished'),'check-off.png'); + break; + case -1: + $img_status = sprintf($img,__('scheduled'),'scheduled.png'); + break; + case -2: + $img_status = sprintf($img,__('pending'),'check-wrn.png'); + break; + } + + $protected = ''; + if ($this->rs->post_password) { + $protected = sprintf($img,__('protected'),'locker.png'); + } + + $selected = ''; + if ($this->rs->post_selected) { + $selected = sprintf($img,__('selected'),'selected.png'); + } + + $attach = ''; + $nb_media = $this->rs->countMedia(); + if ($nb_media > 0) { + $attach_str = $nb_media == 1 ? __('%d attachment') : __('%d attachments'); + $attach = sprintf($img,sprintf($attach_str,$nb_media),'attach.png'); + } + + $res = ''; + + $res .= + ''. + form::checkbox(array('entries[]'),$this->rs->post_id,'','','',!$this->rs->isEditable()).''. + ''. + html::escapeHTML($this->rs->post_title).''. + ''.dt::dt2str(__('%Y-%m-%d %H:%M'),$this->rs->post_dt).''. + ''.$cat_title.''. + ''.$this->rs->user_id.''. + ''.$this->rs->nb_comment.''. + ''.$this->rs->nb_trackback.''. + ''.$img_status.' '.$selected.' '.$protected.' '.$attach.''. + ''; + + return $res; + } +} + +class adminPostMiniList extends adminGenericList +{ + public function display($page,$nb_per_page,$enclose_block='') + { + if ($this->rs->isEmpty()) + { + echo '

        '.__('No entry').'

        '; + } + else + { + $pager = new pager($page,$this->rs_count,$nb_per_page,10); + $pager->html_prev = $this->html_prev; + $pager->html_next = $this->html_next; + $pager->var_page = 'page'; + + $html_block = + ''. + ''. + ''. + ''. + ''. + '%s
        '.__('Title').''.__('Date').''.__('Author').''.__('Status').'
        '; + + if ($enclose_block) { + $html_block = sprintf($enclose_block,$html_block); + } + + echo '

        '.__('Page(s)').' : '.$pager->getLinks().'

        '; + + $blocks = explode('%s',$html_block); + + echo $blocks[0]; + + while ($this->rs->fetch()) + { + echo $this->postLine(); + } + + echo $blocks[1]; + + echo '

        '.__('Page(s)').' : '.$pager->getLinks().'

        '; + } + } + + private function postLine() + { + $img = '%1$s'; + switch ($this->rs->post_status) { + case 1: + $img_status = sprintf($img,__('published'),'check-on.png'); + break; + case 0: + $img_status = sprintf($img,__('unpublished'),'check-off.png'); + break; + case -1: + $img_status = sprintf($img,__('scheduled'),'scheduled.png'); + break; + case -2: + $img_status = sprintf($img,__('pending'),'check-wrn.png'); + break; + } + + $protected = ''; + if ($this->rs->post_password) { + $protected = sprintf($img,__('protected'),'locker.png'); + } + + $selected = ''; + if ($this->rs->post_selected) { + $selected = sprintf($img,__('selected'),'selected.png'); + } + + $attach = ''; + $nb_media = $this->rs->countMedia(); + if ($nb_media > 0) { + $attach_str = $nb_media == 1 ? __('%d attachment') : __('%d attachments'); + $attach = sprintf($img,sprintf($attach_str,$nb_media),'attach.png'); + } + + $res = ''; + + $res .= + ''. + html::escapeHTML($this->rs->post_title).''. + ''.dt::dt2str(__('%Y-%m-%d %H:%M'),$this->rs->post_dt).''. + ''.$this->rs->user_id.''. + ''.$img_status.' '.$selected.' '.$protected.' '.$attach.''. + ''; + + return $res; + } +} + +class adminCommentList extends adminGenericList +{ + public function display($page,$nb_per_page,$enclose_block='') + { + if ($this->rs->isEmpty()) + { + echo '

        '.__('No comment').'

        '; + } + else + { + $pager = new pager($page,$this->rs_count,$nb_per_page,10); + $pager->html_prev = $this->html_prev; + $pager->html_next = $this->html_next; + $pager->var_page = 'page'; + + $html_block = + ''. + ''. + ''. + ''. + ''. + ''. + ''. + '%s
        '.__('Title').''.__('Date').''.__('Author').''.__('Type').''.__('Status').' 
        '; + + if ($enclose_block) { + $html_block = sprintf($enclose_block,$html_block); + } + + echo '

        '.__('Page(s)').' : '.$pager->getLinks().'

        '; + + $blocks = explode('%s',$html_block); + + echo $blocks[0]; + + while ($this->rs->fetch()) + { + echo $this->commentLine(); + } + + echo $blocks[1]; + + echo '

        '.__('Page(s)').' : '.$pager->getLinks().'

        '; + } + } + + private function commentLine() + { + global $author, $status, $sortby, $order, $nb_per_page; + + $author_url = + 'comments.php?n='.$nb_per_page. + '&status='.$status. + '&sortby='.$sortby. + '&order='.$order. + '&author='.rawurlencode($this->rs->comment_author); + + $post_url = $this->core->getPostAdminURL($this->rs->post_type,$this->rs->post_id); + + $comment_url = 'comment.php?id='.$this->rs->comment_id; + + $comment_dt = + dt::dt2str($this->core->blog->settings->system->date_format.' - '. + $this->core->blog->settings->system->time_format,$this->rs->comment_dt); + + $img = '%1$s'; + switch ($this->rs->comment_status) { + case 1: + $img_status = sprintf($img,__('published'),'check-on.png'); + break; + case 0: + $img_status = sprintf($img,__('unpublished'),'check-off.png'); + break; + case -1: + $img_status = sprintf($img,__('pending'),'check-wrn.png'); + break; + case -2: + $img_status = sprintf($img,__('junk'),'junk.png'); + break; + } + + $comment_author = html::escapeHTML($this->rs->comment_author); + if (mb_strlen($comment_author) > 20) { + $comment_author = mb_strcut($comment_author,0,17).'...'; + } + + $res = ''; + + $res .= + ''. + form::checkbox(array('comments[]'),$this->rs->comment_id,'','','',0).''. + ''. + html::escapeHTML($this->rs->post_title).''. + ($this->rs->post_type != 'post' ? ' ('.html::escapeHTML($this->rs->post_type).')' : '').''. + ''.dt::dt2str(__('%Y-%m-%d %H:%M'),$this->rs->comment_dt).''. + ''.$comment_author.''. + ''.($this->rs->comment_trackback ? __('trackback') : __('comment')).''. + ''.$img_status.''. + ''. + ''; + + $res .= ''; + + return $res; + } +} + +class adminUserList extends adminGenericList +{ + public function display($page,$nb_per_page,$enclose_block='') + { + if ($this->rs->isEmpty()) + { + echo '

        '.__('No user').'

        '; + } + else + { + $pager = new pager($page,$this->rs_count,$nb_per_page,10); + $pager->html_prev = $this->html_prev; + $pager->html_next = $this->html_next; + $pager->var_page = 'page'; + + $html_block = + ''. + ''. + ''. + ''. + ''. + ''. + '%s
        '.__('Username').''.__('First Name').''.__('Last Name').''.__('Display name').''.__('Entries').'
        '; + + if ($enclose_block) { + $html_block = sprintf($enclose_block,$html_block); + } + + echo '

        '.__('Page(s)').' : '.$pager->getLinks().'

        '; + + $blocks = explode('%s',$html_block); + + echo $blocks[0]; + + while ($this->rs->fetch()) + { + echo $this->userLine(); + } + + echo $blocks[1]; + + echo '

        '.__('Page(s)').' : '.$pager->getLinks().'

        '; + } + } + + private function userLine() + { + $img = '%1$s'; + $img_status = ''; + + $p = $this->core->getUserPermissions($this->rs->user_id); + + if (isset($p[$this->core->blog->id]['p']['admin'])) { + $img_status = sprintf($img,__('admin'),'admin.png'); + } + if ($this->rs->user_super) { + $img_status = sprintf($img,__('superadmin'),'superadmin.png'); + } + return + ''. + ''.form::hidden(array('nb_post[]'),(integer) $this->rs->nb_post). + form::checkbox(array('user_id[]'),$this->rs->user_id).''. + ''. + $this->rs->user_id.' '.$img_status.''. + ''.$this->rs->user_firstname.''. + ''.$this->rs->user_name.''. + ''.$this->rs->user_displayname.''. + ''. + $this->rs->nb_post.''. + ''; + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/admin/prepend.php b/v2/dotclear/inc/admin/prepend.php new file mode 100644 index 0000000..b1413c5 --- /dev/null +++ b/v2/dotclear/inc/admin/prepend.php @@ -0,0 +1,376 @@ +plugins->moduleExists($matches[1])) { + return false; + } + } + } + return true; +} + +function dc_prepare_url($url) { + + $u = str_replace(array('?','&'),array('\?','&'),$url); + return (!strpos($u,'\?') ? + '/'.$u.'$/' : + (!strpos($u,'&') ? + '/'.$u.'(\?.*)?$/' : + '/'.$u.'(&.*)?$/')); +} + +function dc_load_locales() { + global $_lang, $core; + + $_lang = $core->auth->getInfo('user_lang'); + $_lang = preg_match('/^[a-z]{2}(-[a-z]{2})?$/',$_lang) ? $_lang : 'en'; + + if (l10n::set(dirname(__FILE__).'/../../locales/'.$_lang.'/date') === false && $_lang != 'en') { + l10n::set(dirname(__FILE__).'/../../locales/en/date'); + } + l10n::set(dirname(__FILE__).'/../../locales/'.$_lang.'/main'); + l10n::set(dirname(__FILE__).'/../../locales/'.$_lang.'/plugins'); +} + +function dc_admin_icon_url($img) +{ + global $core; + + $core->auth->user_prefs->addWorkspace('interface'); + $user_ui_iconset = @$core->auth->user_prefs->interface->iconset; + if (($user_ui_iconset) && ($img)) { + $icon = false; + if ((preg_match('/^images\/menu\/(.+)$/',$img,$m)) || + (preg_match('/^index\.php\?pf=(.+)$/',$img,$m))) { + if ($m[1]) { + $icon = path::real(dirname(__FILE__).'/../../admin/images/iconset/'.$user_ui_iconset.'/'.$m[1],false); + if ($icon !== false) { + $allow_types = array('png','jpg','jpeg','gif'); + if (is_file($icon) && is_readable($icon) && in_array(files::getExtension($icon),$allow_types)) { + return DC_ADMIN_URL.'images/iconset/'.$user_ui_iconset.'/'.$m[1]; + } + } + } + } + } + return $img; +} + +if (defined('DC_AUTH_SESS_ID') && defined('DC_AUTH_SESS_UID')) +{ + # We have session information in constants + $_COOKIE[DC_SESSION_NAME] = DC_AUTH_SESS_ID; + + if (!$core->auth->checkSession(DC_AUTH_SESS_UID)) { + throw new Exception('Invalid session data.'); + } + + # Check nonce from POST requests + if (!empty($_POST)) + { + if (empty($_POST['xd_check']) || !$core->checkNonce($_POST['xd_check'])) { + throw new Exception('Precondition Failed.'); + } + } + + if (empty($_SESSION['sess_blog_id'])) { + throw new Exception('Permission denied.'); + } + + # Loading locales + dc_load_locales(); + + $core->setBlog($_SESSION['sess_blog_id']); + if (!$core->blog->id) { + throw new Exception('Permission denied.'); + } +} +elseif ($core->auth->sessionExists()) +{ + # If we have a session we launch it now + try { + if (!$core->auth->checkSession()) + { + # Avoid loop caused by old cookie + $p = $core->session->getCookieParameters(false,-600); + $p[3] = '/'; + call_user_func_array('setcookie',$p); + + http::redirect('auth.php'); + } + } catch (Exception $e) { + __error(__('Database error') + ,__('There seems to be no Session table in your database. Is Dotclear completly installed?') + ,20); + } + + # Check nonce from POST requests + if (!empty($_POST)) + { + if (empty($_POST['xd_check']) || !$core->checkNonce($_POST['xd_check'])) { + http::head(412); + header('Content-Type: text/plain'); + echo 'Precondition Failed'; + exit; + } + } + + + if (!empty($_REQUEST['switchblog']) + && $core->auth->getPermissions($_REQUEST['switchblog']) !== false) + { + $_SESSION['sess_blog_id'] = $_REQUEST['switchblog']; + if (isset($_SESSION['media_manager_dir'])) { + unset($_SESSION['media_manager_dir']); + } + if (isset($_SESSION['media_manager_page'])) { + unset($_SESSION['media_manager_page']); + } + + # Removing switchblog from URL + $redir = $_SERVER['REQUEST_URI']; + $redir = preg_replace('/switchblog=(.*?)(&|$)/','',$redir); + $redir = preg_replace('/\?$/','',$redir); + http::redirect($redir); + exit; + } + + # Check blog to use and log out if no result + if (isset($_SESSION['sess_blog_id'])) + { + if ($core->auth->getPermissions($_SESSION['sess_blog_id']) === false) { + unset($_SESSION['sess_blog_id']); + } + } + else + { + if (($b = $core->auth->findUserBlog($core->auth->getInfo('user_default_blog'))) !== false) { + $_SESSION['sess_blog_id'] = $b; + unset($b); + } + } + + # Loading locales + dc_load_locales(); + + if (isset($_SESSION['sess_blog_id'])) { + $core->setBlog($_SESSION['sess_blog_id']); + } else { + $core->session->destroy(); + http::redirect('auth.php'); + } + +/* + # Check add to my fav fired + if (!empty($_REQUEST['add-favorite'])) { + $redir = $_SERVER['REQUEST_URI']; + # Extract admin page from URI + # TO BE COMPLETED + } +*/ +} + +if ($core->auth->userID() && $core->blog !== null) +{ + # Loading resources and help files + $locales_root = dirname(__FILE__).'/../../locales/'; + require $locales_root.'/en/resources.php'; + if (($f = l10n::getFilePath($locales_root,'resources.php',$_lang))) { + require $f; + } + unset($f); + + if (($hfiles = @scandir($locales_root.$_lang.'/help')) !== false) + { + foreach ($hfiles as $hfile) { + if (preg_match('/^(.*)\.html$/',$hfile,$m)) { + $GLOBALS['__resources']['help'][$m[1]] = $locales_root.$_lang.'/help/'.$hfile; + } + } + } + unset($hfiles,$locales_root); + + $core->auth->user_prefs->addWorkspace('interface'); + $user_ui_nofavmenu = $core->auth->user_prefs->interface->nofavmenu; + + # Standard favorites + $_fav = new ArrayObject(); + + # [] : Title, URL, small icon, large icon, permissions, id, class + # NB : '*' in permissions means any, null means super admin only + + $_fav['prefs'] = new ArrayObject(array('prefs','My preferences','preferences.php', + 'images/menu/user-pref.png','images/menu/user-pref-b.png', + '*',null,null)); + + $_fav['new_post'] = new ArrayObject(array('new_post','New entry','post.php', + 'images/menu/edit.png','images/menu/edit-b.png', + 'usage,contentadmin',null,'menu-new-post')); + $_fav['posts'] = new ArrayObject(array('posts','Entries','posts.php', + 'images/menu/entries.png','images/menu/entries-b.png', + 'usage,contentadmin',null,null)); + $_fav['comments'] = new ArrayObject(array('comments','Comments','comments.php', + 'images/menu/comments.png','images/menu/comments-b.png', + 'usage,contentadmin',null,null)); + $_fav['search'] = new ArrayObject(array('search','Search','search.php', + 'images/menu/search.png','images/menu/search-b.png', + 'usage,contentadmin',null,null)); + $_fav['categories'] = new ArrayObject(array('categories','Categories','categories.php', + 'images/menu/categories.png','images/menu/categories-b.png', + 'categories',null,null)); + $_fav['media'] = new ArrayObject(array('media','Media manager','media.php', + 'images/menu/media.png','images/menu/media-b.png', + 'media,media_admin',null,null)); + $_fav['blog_pref'] = new ArrayObject(array('blog_pref','Blog settings','blog_pref.php', + 'images/menu/blog-pref.png','images/menu/blog-pref-b.png', + 'admin',null,null)); + $_fav['blog_theme'] = new ArrayObject(array('blog_theme','Blog appearance','blog_theme.php', + 'images/menu/themes.png','images/menu/blog-theme-b.png', + 'admin',null,null)); + + $_fav['blogs'] = new ArrayObject(array('blogs','Blogs','blogs.php', + 'images/menu/blogs.png','images/menu/blogs-b.png', + 'usage,contentadmin',null,null)); + $_fav['users'] = new ArrayObject(array('users','Users','users.php', + 'images/menu/users.png','images/menu/users-b.png', + null,null,null)); + $_fav['plugins'] = new ArrayObject(array('plugins','Plugins','plugins.php', + 'images/menu/plugins.png','images/menu/plugins-b.png', + null,null,null)); + $_fav['langs'] = new ArrayObject(array('langs','Languages','langs.php', + 'images/menu/langs.png','images/menu/langs-b.png', + null,null,null)); + + # Menus creation + $_menu['Dashboard'] = new dcMenu('dashboard-menu',null); + if (!$user_ui_nofavmenu) + $_menu['Favorites'] = new dcMenu('favorites-menu','My favorites'); + $_menu['Blog'] = new dcMenu('blog-menu','Blog'); + $_menu['System'] = new dcMenu('system-menu','System'); + $_menu['Plugins'] = new dcMenu('plugins-menu','Plugins'); + + # Loading plugins + $core->plugins->loadModules(DC_PLUGINS_ROOT,'admin',$_lang); + + # Loading favorites info from plugins + $core->callBehavior('adminDashboardFavs', $core, $_fav); + + # Set menu titles + + $_menu['System']->title = __('System'); + $_menu['Blog']->title = __('Blog'); + $_menu['Plugins']->title = __('Plugins'); + if (!$user_ui_nofavmenu) + $_menu['Favorites']->title = __('My favorites'); + +/* + if (!preg_match('/index.php$/',$_SERVER['REQUEST_URI'])) { + # Admin index can't be add in fav's + $_menu['Dashboard']->prependItem(__('Add this page to my favorites'),'#','images/menu/add_to_favorites.png', + false,$core->auth->check('usage,contentadmin',$core->blog->id),'fav-add'); + } +*/ + $_menu['Blog']->prependItem(__('Blog appearance'),'blog_theme.php','images/menu/themes.png', + preg_match('/blog_theme.php(\?.*)?$/',$_SERVER['REQUEST_URI']), + $core->auth->check('admin',$core->blog->id)); + $_menu['Blog']->prependItem(__('Blog settings'),'blog_pref.php','images/menu/blog-pref.png', + preg_match('/blog_pref.php(\?.*)?$/',$_SERVER['REQUEST_URI']), + $core->auth->check('admin',$core->blog->id)); + $_menu['Blog']->prependItem(__('Media manager'),'media.php','images/menu/media.png', + preg_match('/media(_item)?.php(\?.*)?$/',$_SERVER['REQUEST_URI']), + $core->auth->check('media,media_admin',$core->blog->id)); + $_menu['Blog']->prependItem(__('Categories'),'categories.php','images/menu/categories.png', + preg_match('/categories.php(\?.*)?$/',$_SERVER['REQUEST_URI']), + $core->auth->check('categories',$core->blog->id)); + $_menu['Blog']->prependItem(__('Search'),'search.php','images/menu/search.png', + preg_match('/search.php(\?.*)?$/',$_SERVER['REQUEST_URI']), + $core->auth->check('usage,contentadmin',$core->blog->id)); + $_menu['Blog']->prependItem(__('Comments'),'comments.php','images/menu/comments.png', + preg_match('/comments.php(\?.*)?$/',$_SERVER['REQUEST_URI']), + $core->auth->check('usage,contentadmin',$core->blog->id)); + $_menu['Blog']->prependItem(__('Entries'),'posts.php','images/menu/entries.png', + preg_match('/posts.php(\?.*)?$/',$_SERVER['REQUEST_URI']), + $core->auth->check('usage,contentadmin',$core->blog->id)); + $_menu['Blog']->prependItem(__('New entry'),'post.php','images/menu/edit.png', + preg_match('/post.php$/',$_SERVER['REQUEST_URI']), + $core->auth->check('usage,contentadmin',$core->blog->id),'menu-new-post'); + + $_menu['System']->prependItem(__('Updates'),'update.php','images/menu/update.png', + preg_match('/update.php(\?.*)?$/',$_SERVER['REQUEST_URI']), + $core->auth->isSuperAdmin() && is_readable(DC_DIGESTS)); + $_menu['System']->prependItem(__('Languages'),'langs.php','images/menu/langs.png', + preg_match('/langs.php(\?.*)?$/',$_SERVER['REQUEST_URI']), + $core->auth->isSuperAdmin()); + $_menu['System']->prependItem(__('Plugins'),'plugins.php','images/menu/plugins.png', + preg_match('/plugins.php(\?.*)?$/',$_SERVER['REQUEST_URI']), + $core->auth->isSuperAdmin()); + $_menu['System']->prependItem(__('Users'),'users.php','images/menu/users.png', + preg_match('/users.php$/',$_SERVER['REQUEST_URI']), + $core->auth->isSuperAdmin()); + $_menu['System']->prependItem(__('Blogs'),'blogs.php','images/menu/blogs.png', + preg_match('/blogs.php$/',$_SERVER['REQUEST_URI']), + $core->auth->isSuperAdmin() || + $core->auth->check('usage,contentadmin',$core->blog->id) && $core->auth->blog_count > 1); + + if (!$user_ui_nofavmenu) { + // Set favorites menu + $ws = $core->auth->user_prefs->addWorkspace('favorites'); + $count = 0; + foreach ($ws->dumpPrefs() as $k => $v) { + // User favorites only + if (!$v['global']) { + $fav = unserialize($v['value']); + if (dc_valid_fav($fav['url'])) { + $count++; + $_menu['Favorites']->addItem(__($fav['title']),$fav['url'],$fav['small-icon'], + preg_match(dc_prepare_url($fav['url']),$_SERVER['REQUEST_URI']), + (($fav['permissions'] == '*') || $core->auth->check($fav['permissions'],$core->blog->id)),$fav['id'],$fav['class']); + } + } + } + if (!$count) { + // Global favorites if any + foreach ($ws->dumpPrefs() as $k => $v) { + $fav = unserialize($v['value']); + if (dc_valid_fav($fav['url'])) { + $count++; + $_menu['Favorites']->addItem(__($fav['title']),$fav['url'],$fav['small-icon'], + preg_match(dc_prepare_url($fav['url']),$_SERVER['REQUEST_URI']), + (($fav['permissions'] == '*') || $core->auth->check($fav['permissions'],$core->blog->id)),$fav['id'],$fav['class']); + } + } + } + if (!$count) { + // No user or global favorites, add "new entry" fav + $_menu['Favorites']->addItem(__('New entry'),'post.php','images/menu/edit.png', + preg_match('/post.php$/',$_SERVER['REQUEST_URI']), + $core->auth->check('usage,contentadmin',$core->blog->id),'menu-new-post',null); + } + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/config.php.in b/v2/dotclear/inc/config.php.in new file mode 100644 index 0000000..65bea68 --- /dev/null +++ b/v2/dotclear/inc/config.php.in @@ -0,0 +1,70 @@ + \ No newline at end of file diff --git a/v2/dotclear/inc/core/class.dc.auth.php b/v2/dotclear/inc/core/class.dc.auth.php new file mode 100644 index 0000000..60eedc0 --- /dev/null +++ b/v2/dotclear/inc/core/class.dc.auth.php @@ -0,0 +1,632 @@ +core =& $core; + $this->con =& $core->con; + $this->blog_table = $core->prefix.'blog'; + $this->user_table = $core->prefix.'user'; + $this->perm_table = $core->prefix.'permissions'; + + $this->perm_types = array( + 'admin' => __('administrator'), + 'usage' => __('manage their own entries and comments'), + 'publish' => __('publish entries and comments'), + 'delete' => __('delete entries and comments'), + 'contentadmin' => __('manage all entries and comments'), + 'categories' => __('manage categories'), + 'media' => __('manage their own media items'), + 'media_admin' => __('manage all media items') + ); + } + + /// @name Credentials and user permissions + //@{ + /** + * Checks if user exists and can log in. $pwd argument is optionnal + * while you may need to check user without password. This method will create + * credentials and populate all needed object properties. + * + * @param string $user_id User ID + * @param string $pwd User password + * @param string $user_key User key check + * @param boolean $check_blog checks if user is associated to a blog or not. + * @return boolean + */ + public function checkUser($user_id, $pwd=null, $user_key=null, $check_blog=true) + { + # Check user and password + $strReq = 'SELECT user_id, user_super, user_pwd, user_change_pwd, '. + 'user_name, user_firstname, user_displayname, user_email, '. + 'user_url, user_default_blog, user_options, '. + 'user_lang, user_tz, user_post_status, user_creadt, user_upddt '. + 'FROM '.$this->con->escapeSystem($this->user_table).' '. + "WHERE user_id = '".$this->con->escape($user_id)."' "; + + try { + $rs = $this->con->select($strReq); + } catch (Exception $e) { + $err = $e->getMessage(); + return false; + } + + if ($rs->isEmpty()) { + return false; + } + + $rs->extend('rsExtUser'); + + if ($pwd != '') + { + if (crypt::hmac(DC_MASTER_KEY,$pwd) != $rs->user_pwd) { + sleep(rand(2,5)); + return false; + } + } + elseif ($user_key != '') + { + if (http::browserUID(DC_MASTER_KEY.$rs->user_id.$rs->user_pwd) != $user_key) { + return false; + } + } + + $this->user_id = $rs->user_id; + $this->user_change_pwd = (boolean) $rs->user_change_pwd; + $this->user_admin = (boolean) $rs->user_super; + + $this->user_info['user_pwd'] = $rs->user_pwd; + $this->user_info['user_name'] = $rs->user_name; + $this->user_info['user_firstname'] = $rs->user_firstname; + $this->user_info['user_displayname'] = $rs->user_displayname; + $this->user_info['user_email'] = $rs->user_email; + $this->user_info['user_url'] = $rs->user_url; + $this->user_info['user_default_blog'] = $rs->user_default_blog; + $this->user_info['user_lang'] = $rs->user_lang; + $this->user_info['user_tz'] = $rs->user_tz; + $this->user_info['user_post_status'] = $rs->user_post_status; + $this->user_info['user_creadt'] = $rs->user_creadt; + $this->user_info['user_upddt'] = $rs->user_upddt; + + $this->user_info['user_cn'] = dcUtils::getUserCN($rs->user_id, $rs->user_name, + $rs->user_firstname, $rs->user_displayname); + + $this->user_options = array_merge($this->core->userDefaults(),$rs->options()); + + $this->user_prefs = new dcPrefs($this->core,$this->user_id); + + # Get permissions on blogs + if ($check_blog && ($this->findUserBlog() === false)) { + return false; + } + return true; + } + + /** + * This method only check current user password. + * + * @param string $pwd User password + * @return boolean + */ + public function checkPassword($pwd) + { + if (!empty($this->user_info['user_pwd'])) { + return $pwd == $this->user_info['user_pwd']; + } + + return false; + } + + /** + * This method checks if user session cookie exists + * + * @return boolean + */ + public function sessionExists() + { + return isset($_COOKIE[DC_SESSION_NAME]); + } + + /** + * This method checks user session validity. + * + * @return boolean + */ + public function checkSession($uid=null) + { + $this->core->session->start(); + + # If session does not exist, logout. + if (!isset($_SESSION['sess_user_id'])) { + $this->core->session->destroy(); + return false; + } + + # Check here for user and IP address + $this->checkUser($_SESSION['sess_user_id']); + $uid = $uid ? $uid : http::browserUID(DC_MASTER_KEY); + + $user_can_log = $this->userID() !== null && $uid == $_SESSION['sess_browser_uid']; + + if (!$user_can_log) { + $this->core->session->destroy(); + return false; + } + + return true; + } + + /** + * Checks if user must change his password in order to login. + * + * @return boolean + */ + public function mustChangePassword() + { + return $this->user_change_pwd; + } + + /** + * Checks if user is super admin + * + * @return boolean + */ + public function isSuperAdmin() + { + return $this->user_admin; + } + + /** + * Checks if user has permissions given in $permissions for blog + * $blog_id. $permissions is a coma separated list of + * permissions. + * + * @param string $permissions Permissions list + * @param string $blog_id Blog ID + * @return boolean + */ + public function check($permissions,$blog_id) + { + if ($this->user_admin) { + return true; + } + + $p = explode(',',$permissions); + $b = $this->getPermissions($blog_id); + + if ($b != false) + { + if (isset($b['admin'])) { + return true; + } + + foreach ($p as $v) + { + if (isset($b[$v])) { + return true; + } + } + } + + return false; + } + + /** + * Returns true if user is allowed to change its password. + * + * @return boolean + */ + public function allowPassChange() + { + return $this->allow_pass_change; + } + //@} + + /// @name User code handlers + //@{ + public function getUserCode() + { + $code = + pack('a32',$this->userID()). + pack('H*',crypt::hmac(DC_MASTER_KEY,$this->getInfo('user_pwd'))); + return bin2hex($code); + } + + public function checkUserCode($code) + { + $code = @pack('H*',$code); + + $user_id = trim(@pack('a32',substr($code,0,32))); + $pwd = @unpack('H40hex',substr($code,32,40)); + + if ($user_id === false || $pwd === false) { + return false; + } + + $pwd = $pwd['hex']; + + $strReq = 'SELECT user_id, user_pwd '. + 'FROM '.$this->user_table.' '. + "WHERE user_id = '".$this->con->escape($user_id)."' "; + + $rs = $this->con->select($strReq); + + if ($rs->isEmpty()) { + return false; + } + + if (crypt::hmac(DC_MASTER_KEY,$rs->user_pwd) != $pwd) { + return false; + } + + return $rs->user_id; + } + //@} + + + /// @name Sudo + //@{ + /** + * Calls $f function with super admin rights. + * Returns the function result. + * + * @param callback $f Callback function + * @return mixed + */ + public function sudo($f) + { + if (!is_callable($f)) { + throw new Exception($f.' function doest not exist'); + } + + $args = func_get_args(); + array_shift($args); + + if ($this->user_admin) { + $res = call_user_func_array($f,$args); + } else { + $this->user_admin = true; + try { + $res = call_user_func_array($f,$args); + $this->user_admin = false; + } catch (Exception $e) { + $this->user_admin = false; + throw $e; + } + } + + return $res; + } + //@} + + /// @name User information and options + //@{ + /** + * Returns user permissions for a blog as an array which looks like: + * + * - [blog_id] + * - [permission] => true + * - ... + * + * @param string $blog_id Blog ID + * @return array + */ + public function getPermissions($blog_id) + { + if (isset($this->blogs[$blog_id])) { + return $this->blogs[$blog_id]; + } + + if ($this->blog_count === null) { + $this->blog_count = $this->core->getBlogs(array(),true)->f(0); + } + + if ($this->user_admin) { + $strReq = 'SELECT blog_id '. + 'from '.$this->blog_table.' '. + "WHERE blog_id = '".$this->con->escape($blog_id)."' "; + $rs = $this->con->select($strReq); + + $this->blogs[$blog_id] = $rs->isEmpty() ? false : array('admin' => true); + + return $this->blogs[$blog_id]; + } + + $strReq = 'SELECT permissions '. + 'FROM '.$this->perm_table.' '. + "WHERE user_id = '".$this->con->escape($this->user_id)."' ". + "AND blog_id = '".$this->con->escape($blog_id)."' ". + "AND (permissions LIKE '%|usage|%' OR permissions LIKE '%|admin|%' OR permissions LIKE '%|contentadmin|%') "; + $rs = $this->con->select($strReq); + + $this->blogs[$blog_id] = $rs->isEmpty() ? false : $this->parsePermissions($rs->permissions); + + return $this->blogs[$blog_id]; + } + + public function findUserBlog($blog_id=null) + { + if ($blog_id && $this->getPermissions($blog_id) !== false) + { + return $blog_id; + } + else + { + if ($this->user_admin) + { + $strReq = 'SELECT blog_id '. + 'FROM '.$this->blog_table.' '. + 'ORDER BY blog_id ASC '. + $this->con->limit(1); + } + else + { + $strReq = 'SELECT blog_id '. + 'FROM '.$this->perm_table.' '. + "WHERE user_id = '".$this->con->escape($this->user_id)."' ". + "AND (permissions LIKE '%|usage|%' OR permissions LIKE '%|admin|%' OR permissions LIKE '%|contentadmin|%') ". + 'ORDER BY blog_id ASC '. + $this->con->limit(1); + } + + $rs = $this->con->select($strReq); + if (!$rs->isEmpty()) { + return $rs->blog_id; + } + } + + return false; + } + + /** + * Returns current user ID + * + * @return string + */ + public function userID() + { + return $this->user_id; + } + + /** + * Returns information about a user . + * + * @param string $n Information name + * @return string + */ + public function getInfo($n) + { + if (isset($this->user_info[$n])) { + return $this->user_info[$n]; + } + + return null; + } + + /** + * Returns a specific user option + * + * @param string $n Option name + * @return string + */ + public function getOption($n) + { + if (isset($this->user_options[$n])) { + return $this->user_options[$n]; + } + return null; + } + + /** + * Returns all user options in an associative array. + * + * @return array + */ + public function getOptions() + { + return $this->user_options; + } + //@} + + /// @name Permissions + //@{ + /** + * Returns an array with permissions parsed from the string $level + * + * @param string $level Permissions string + * @return array + */ + public function parsePermissions($level) + { + $level = preg_replace('/^\|/','',$level); + $level = preg_replace('/\|$/','',$level); + + $res = array(); + foreach (explode('|',$level) as $v) { + $res[$v] = true; + } + return $res; + } + + /** + * Returns perm_types property content. + * + * @return array + */ + public function getPermissionsTypes() + { + return $this->perm_types; + } + + /** + * Adds a new permission type. + * + * @param string $name Permission name + * @param string $title Permission title + */ + public function setPermissionType($name,$title) + { + $this->perm_types[$name] = $title; + } + //@} + + /// @name Password recovery + //@{ + /** + * Add a recover key to a specific user identified by its email and + * password. + * + * @param string $user_id User ID + * @param string $user_email User Email + * @return string + */ + public function setRecoverKey($user_id,$user_email) + { + $strReq = 'SELECT user_id '. + 'FROM '.$this->user_table.' '. + "WHERE user_id = '".$this->con->escape($user_id)."' ". + "AND user_email = '".$this->con->escape($user_email)."' "; + + $rs = $this->con->select($strReq); + + if ($rs->isEmpty()) { + throw new Exception(__('That user does not exist in the database.')); + } + + $key = md5(uniqid()); + + $cur = $this->con->openCursor($this->user_table); + $cur->user_recover_key = $key; + + $cur->update("WHERE user_id = '".$this->con->escape($user_id)."'"); + + return $key; + } + + /** + * Creates a new user password using recovery key. Returns an array: + * + * - user_email + * - user_id + * - new_pass + * + * @param string $recover_key Recovery key + * @return array + */ + public function recoverUserPassword($recover_key) + { + $strReq = 'SELECT user_id, user_email '. + 'FROM '.$this->user_table.' '. + "WHERE user_recover_key = '".$this->con->escape($recover_key)."' "; + + $rs = $this->con->select($strReq); + + if ($rs->isEmpty()) { + throw new Exception(__('That key does not exist in the database.')); + } + + $new_pass = crypt::createPassword(); + + $cur = $this->con->openCursor($this->user_table); + $cur->user_pwd = crypt::hmac(DC_MASTER_KEY,$new_pass); + $cur->user_recover_key = null; + + $cur->update("WHERE user_recover_key = '".$this->con->escape($recover_key)."'"); + + return array('user_email' => $rs->user_email, 'user_id' => $rs->user_id, 'new_pass' => $new_pass); + } + //@} + + /** @name User management callbacks + This 3 functions only matter if you extend this class and use + DC_AUTH_CLASS constant. + These are called after core user management functions. + Could be useful if you need to add/update/remove stuff in your + LDAP directory or other third party authentication database. + */ + //@{ + + /** + * Called after core->addUser + * @see dcCore::addUser + * @param cursor $cur User cursor + */ + public function afterAddUser($cur) {} + + /** + * Called after core->updUser + * @see dcCore::updUser + * @param string $id User ID + * @param cursor $cur User cursor + */ + public function afterUpdUser($id,$cur) {} + + /** + * Called after core->delUser + * @see dcCore::delUser + * @param string $id User ID + */ + public function afterDelUser($id) {} + //@} +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/core/class.dc.blog.php b/v2/dotclear/inc/core/class.dc.blog.php new file mode 100644 index 0000000..3509c3f --- /dev/null +++ b/v2/dotclear/inc/core/class.dc.blog.php @@ -0,0 +1,2089 @@ +dcCore
        Dotclear core reference + @param id string Blog ID + */ + public function __construct($core, $id) + { + $this->con =& $core->con; + $this->prefix = $core->prefix; + $this->core =& $core; + + if (($b = $this->core->getBlog($id)) !== false) + { + $this->id = $id; + $this->uid = $b->blog_uid; + $this->name = $b->blog_name; + $this->desc = $b->blog_desc; + $this->url = $b->blog_url; + $this->host = preg_replace('|^([a-z]{3,}://)(.*?)/.*$|','$1$2',$this->url); + $this->creadt = strtotime($b->blog_creadt); + $this->upddt = strtotime($b->blog_upddt); + $this->status = $b->blog_status; + + $this->settings = new dcSettings($this->core,$this->id); + + $this->themes_path = path::fullFromRoot($this->settings->system->themes_path,DC_ROOT); + $this->public_path = path::fullFromRoot($this->settings->system->public_path,DC_ROOT); + + $this->post_status['-2'] = __('pending'); + $this->post_status['-1'] = __('scheduled'); + $this->post_status['0'] = __('unpublished'); + $this->post_status['1'] = __('published'); + + $this->comment_status['-2'] = __('junk'); + $this->comment_status['-1'] = __('pending'); + $this->comment_status['0'] = __('unpublished'); + $this->comment_status['1'] = __('published'); + + # --BEHAVIOR-- coreBlogConstruct + $this->core->callBehavior('coreBlogConstruct',$this); + } + } + + /// @name Common public methods + //@{ + /** + Returns blog URL ending with a question mark. + */ + public function getQmarkURL() + { + if (substr($this->url,-1) != '?') { + return $this->url.'?'; + } + + return $this->url; + } + + /** + Returns an entry status name given to a code. Status are translated, never + use it for tests. If status code does not exist, returns unpublished. + + @param s integer Status code + @return string Blog status name + */ + public function getPostStatus($s) + { + if (isset($this->post_status[$s])) { + return $this->post_status[$s]; + } + return $this->post_status['0']; + } + + /** + Returns an array of available entry status codes and names. + + @return array Simple array with codes in keys and names in value + */ + public function getAllPostStatus() + { + return $this->post_status; + } + + /** + Returns an array of available comment status codes and names. + + @return array Simple array with codes in keys and names in value + */ + public function getAllCommentStatus() + { + return $this->comment_status; + } + + /** + Disallows entries password protection. You need to set it to + false while serving a public blog. + + @param v boolean + */ + public function withoutPassword($v) + { + $this->without_password = (boolean) $v; + } + //@} + + /// @name Triggers methods + //@{ + /** + Updates blog last update date. Should be called every time you change + an element related to the blog. + */ + public function triggerBlog() + { + $cur = $this->con->openCursor($this->prefix.'blog'); + + $cur->blog_upddt = date('Y-m-d H:i:s'); + + $cur->update("WHERE blog_id = '".$this->con->escape($this->id)."' "); + + # --BEHAVIOR-- coreBlogAfterTriggerBlog + $this->core->callBehavior('coreBlogAfterTriggerBlog',$cur); + } + + /** + Updates comment and trackback counters in post table. Should be called + every time a comment or trackback is added, removed or changed its status. + + @param id integer Comment ID + @param del boolean If comment is delete, set this to true + */ + public function triggerComment($id,$del=false) + { + $id = (integer) $id; + + $strReq = 'SELECT post_id, comment_trackback '. + 'FROM '.$this->prefix.'comment '. + 'WHERE comment_id = '.$id.' '; + + $rs = $this->con->select($strReq); + + $post_id = $rs->post_id; + $tb = (boolean) $rs->comment_trackback; + + $strReq = 'SELECT COUNT(post_id) '. + 'FROM '.$this->prefix.'comment '. + 'WHERE post_id = '.(integer) $post_id.' '. + 'AND comment_trackback = '.(integer) $tb.' '. + 'AND comment_status = 1 '; + + if ($del) { + $strReq .= 'AND comment_id <> '.$id.' '; + } + + $rs = $this->con->select($strReq); + + $cur = $this->con->openCursor($this->prefix.'post'); + + if ($rs->isEmpty()) { + return; + } + + if ($tb) { + $cur->nb_trackback = (integer) $rs->f(0); + } else { + $cur->nb_comment = (integer) $rs->f(0); + } + + $cur->update('WHERE post_id = '.(integer) $post_id); + } + //@} + + /// @name Categories management methods + //@{ + public function categories() + { + if (!($this->categories instanceof dcCategories)) { + $this->categories = new dcCategories($this->core); + } + + return $this->categories; + } + + /** + Retrieves categories. $params is an associative array which can + take the following parameters: + + - post_type: Get only entries with given type (default "post") + - cat_url: filter on cat_url field + - cat_id: filter on cat_id field + - start: start with a given category + - level: categories level to retrieve + + @param params array Parameters + @return record + */ + public function getCategories($params=array()) + { + $c_params = array(); + if (isset($params['post_type'])) { + $c_params['post_type'] = $params['post_type']; + unset($params['post_type']); + } + $counter = $this->getCategoriesCounter($c_params); + + $without_empty = $this->core->auth->userID() == false; # For public display + + $start = isset($params['start']) ? (integer) $params['start'] : 0; + $l = isset($params['level']) ? (integer) $params['level'] : 0; + + $rs = $this->categories()->getChildren($start,null,'desc'); + + # Get each categories total posts count + $data = array(); + $stack = array(); + $level = 0; + $cols = $rs->columns(); + while ($rs->fetch()) + { + $nb_post = isset($counter[$rs->cat_id]) ? (integer) $counter[$rs->cat_id] : 0; + + if ($rs->level > $level) { + $nb_total = $nb_post; + $stack[$rs->level] = (integer) $nb_post; + } elseif ($rs->level == $level) { + $nb_total = $nb_post; + $stack[$rs->level] += $nb_post; + } else { + $nb_total = $stack[$rs->level+1] + $nb_post; + if (isset($stack[$rs->level])) { + $stack[$rs->level] += $nb_total; + } else { + $stack[$rs->level] = $nb_total; + } + unset($stack[$rs->level+1]); + } + + if ($nb_total == 0 && $without_empty) { + continue; + } + + $level = $rs->level; + + $t = array(); + foreach ($cols as $c) { + $t[$c] = $rs->f($c); + } + $t['nb_post'] = $nb_post; + $t['nb_total'] = $nb_total; + + if ($l == 0 || ($l > 0 && $l == $rs->level)) { + array_unshift($data,$t); + } + } + + # We need to apply filter after counting + if (isset($params['cat_id']) && $params['cat_id'] !== '') + { + $found = false; + foreach ($data as $v) { + if ($v['cat_id'] == $params['cat_id']) { + $found = true; + $data = array($v); + break; + } + } + if (!$found) { + $data = array(); + } + } + + if (isset($params['cat_url']) && ($params['cat_url'] !== '') + && !isset($params['cat_id'])) + { + $found = false; + foreach ($data as $v) { + if ($v['cat_url'] == $params['cat_url']) { + $found = true; + $data = array($v); + break; + } + } + if (!$found) { + $data = array(); + } + } + + return staticRecord::newFromArray($data); + } + + /** + Retrieves a category by its ID. + + @param id integer Category ID + @return record + */ + public function getCategory($id) + { + return $this->getCategories(array('cat_id' => $id)); + } + + /** + Retrieves parents of a given category. + + @param id integer Category ID + @return record + */ + public function getCategoryParents($id) + { + return $this->categories()->getParents($id); + } + + /** + Retrieves first parent of a given category. + + @param id integer Category ID + @return record + */ + public function getCategoryParent($id) + { + return $this->categories()->getParent($id); + } + + /** + Retrieves all category's first children + + @param id integer Category ID + @return record + */ + public function getCategoryFirstChildren($id) + { + return $this->getCategories(array('start' => $id,'level' => $id == 0 ? 1 : 2)); + } + + private function getCategoriesCounter($params=array()) + { + $strReq = + 'SELECT C.cat_id, COUNT(P.post_id) AS nb_post '. + 'FROM '.$this->prefix.'category AS C '. + 'JOIN '.$this->prefix."post P ON (C.cat_id = P.cat_id AND P.blog_id = '".$this->con->escape($this->id)."' ) ". + "WHERE C.blog_id = '".$this->con->escape($this->id)."' "; + + if (!$this->core->auth->userID()) { + $strReq .= 'AND P.post_status = 1 '; + } + + if (!empty($params['post_type'])) { + $strReq .= 'AND P.post_type '.$this->con->in($params['post_type']); + } + + $strReq .= 'GROUP BY C.cat_id '; + + $rs = $this->con->select($strReq); + $counters = array(); + while ($rs->fetch()) { + $counters[$rs->cat_id] = $rs->nb_post; + } + + return $counters; + } + + /** + Creates a new category. Takes a cursor as input and returns the new category + ID. + + @param cur cursor Category cursor + @return integer New category ID + */ + public function addCategory($cur,$parent=0) + { + if (!$this->core->auth->check('categories',$this->id)) { + throw new Exception(__('You are not allowed to add categories')); + } + + $url = array(); + if ($parent != 0) + { + $rs = $this->getCategory($parent); + if ($rs->isEmpty()) { + $url = array(); + } else { + $url[] = $rs->cat_url; + } + } + + if ($cur->cat_url == '') { + $url[] = text::tidyURL($cur->cat_title,false); + } else { + $url[] = $cur->cat_url; + } + + $cur->cat_url = implode('/',$url); + + $this->getCategoryCursor($cur); + $cur->blog_id = (string) $this->id; + + # --BEHAVIOR-- coreBeforeCategoryCreate + $this->core->callBehavior('coreBeforeCategoryCreate',$this,$cur); + + $this->categories()->addNode($cur,$parent); + + # --BEHAVIOR-- coreAfterCategoryCreate + $this->core->callBehavior('coreAfterCategoryCreate',$this,$cur); + $this->triggerBlog(); + + return $cur->cat_id; + } + + /** + Updates an existing category. + + @param id integer Category ID + @param cur cursor Category cursor + */ + public function updCategory($id,$cur) + { + if (!$this->core->auth->check('categories',$this->id)) { + throw new Exception(__('You are not allowed to update categories')); + } + + if ($cur->cat_url == '') + { + $url = array(); + $rs = $this->categories()->getParents($id); + while ($rs->fetch()) { + if ($rs->index() == $rs->count()-1) { + $url[] = $rs->cat_url; + } + } + + + $url[] = text::tidyURL($cur->cat_title,false); + $cur->cat_url = implode('/',$url); + } + + $this->getCategoryCursor($cur,$id); + + # --BEHAVIOR-- coreBeforeCategoryUpdate + $this->core->callBehavior('coreBeforeCategoryUpdate',$this,$cur); + + $cur->update( + 'WHERE cat_id = '.(integer) $id.' '. + "AND blog_id = '".$this->con->escape($this->id)."' "); + + # --BEHAVIOR-- coreAfterCategoryUpdate + $this->core->callBehavior('coreAfterCategoryUpdate',$this,$cur); + + $this->triggerBlog(); + } + + /** + DEPRECATED METHOD. Use dcBlog::setCategoryParent and dcBlog::moveCategory + instead. + + @param id integer Category ID + @param order integer Category position + */ + public function updCategoryOrder($id,$order) + { + return; + } + + /** + Set a category parent + + @param id integer Category ID + @param parent integer Parent Category ID + */ + public function setCategoryParent($id,$parent) + { + $this->categories()->setNodeParent($id,$parent); + $this->triggerBlog(); + } + + /** + Set category position + + @param id integer Category ID + @param sibling integer Sibling Category ID + @param move integer Order (before|after) + */ + public function setCategoryPosition($id,$sibling,$move) + { + $this->categories()->setNodePosition($id,$sibling,$move); + $this->triggerBlog(); + } + + /** + Deletes a category. + + @param id integer Category ID + */ + public function delCategory($id) + { + if (!$this->core->auth->check('categories',$this->id)) { + throw new Exception(__('You are not allowed to delete categories')); + } + + $strReq = 'SELECT COUNT(post_id) AS nb_post '. + 'FROM '.$this->prefix.'post '. + 'WHERE cat_id = '.(integer) $id.' '. + "AND blog_id = '".$this->con->escape($this->id)."' "; + + $rs = $this->con->select($strReq); + + if ($rs->nb_post > 0) { + throw new Exception(__('This category is not empty.')); + } + + $this->categories()->deleteNode($id,true); + $this->triggerBlog(); + } + + /** + Reset categories order and relocate them to first level + */ + public function resetCategoriesOrder() + { + if (!$this->core->auth->check('categories',$this->id)) { + throw new Exception(__('You are not allowed to reset categories order')); + } + + $this->categories()->resetOrder(); + $this->triggerBlog(); + } + + private function checkCategory($title,$url,$id=null) + { + $strReq = 'SELECT cat_id '. + 'FROM '.$this->prefix.'category '. + "WHERE cat_url = '".$this->con->escape($url)."' ". + "AND blog_id = '".$this->con->escape($this->id)."' "; + + if ($id !== null) { + $strReq .= 'AND cat_id <> '.(integer) $id.' '; + } + + $rs = $this->con->select($strReq); + + if (!$rs->isEmpty()) { + throw new Exception(__('Category URL must be unique.')); + } + } + + private function getCategoryCursor($cur,$id=null) + { + if ($cur->cat_title == '') { + throw new Exception(__('You must provide a category title')); + } + + # If we don't have any cat_url, let's do one + if ($cur->cat_url == '') { + $cur->cat_url = text::tidyURL($cur->cat_title,false); + } + + # Still empty ? + if ($cur->cat_url == '') { + throw new Exception(__('You must provide a category URL')); + } else { + $cur->cat_url = text::tidyURL($cur->cat_url,true); + } + + # Check if title or url are unique + $this->checkCategory($cur->cat_title,$cur->cat_url,$id); + + if ($cur->cat_desc !== null) { + $cur->cat_desc = $this->core->HTMLfilter($cur->cat_desc); + } + } + //@} + + /// @name Entries management methods + //@{ + /** + Retrieves entries. $params is an array taking the following + optionnal parameters: + + - no_content: Don't retrieve entry content (excerpt and content) + - post_type: Get only entries with given type (default "post", array for many types and '' for no type) + - post_id: (integer) Get entry with given post_id + - post_url: Get entry with given post_url field + - user_id: (integer) Get entries belonging to given user ID + - cat_id: (string or array) Get entries belonging to given category ID + - cat_id_not: deprecated (use cat_id with "id ?not" instead) + - cat_url: (string or array) Get entries belonging to given category URL + - cat_url_not: deprecated (use cat_url with "url ?not" instead) + - post_status: (integer) Get entries with given post_status + - post_selected: (boolean) Get select flaged entries + - post_year: (integer) Get entries with given year + - post_month: (integer) Get entries with given month + - post_day: (integer) Get entries with given day + - post_lang: Get entries with given language code + - search: Get entries corresponding of the following search string + - columns: (array) More columns to retrieve + - sql: Append SQL string at the end of the query + - from: Append SQL string after "FROM" statement in query + - order: Order of results (default "ORDER BY post_dt DES") + - limit: Limit parameter + - sql_only : return the sql request instead of results. Only ids are selected + + Please note that on every cat_id or cat_url, you can add ?not to exclude + the category and ?sub to get subcategories. + + @param params array Parameters + @param count_only boolean Only counts results + @return record A record with some more capabilities or the SQL request + */ + public function getPosts($params=array(),$count_only=false) + { + # --BEHAVIOR-- coreBlogBeforeGetPosts + $params = new ArrayObject($params); + $this->core->callBehavior('coreBlogBeforeGetPosts',$params); + + if ($count_only) + { + $strReq = 'SELECT count(P.post_id) '; + } + elseif (!empty($params['sql_only'])) + { + $strReq = 'SELECT P.post_id '; + } + else + { + if (!empty($params['no_content'])) { + $content_req = ''; + } else { + $content_req = + 'post_excerpt, post_excerpt_xhtml, '. + 'post_content, post_content_xhtml, post_notes, '; + } + + if (!empty($params['columns']) && is_array($params['columns'])) { + $content_req .= implode(', ',$params['columns']).', '; + } + + $strReq = + 'SELECT P.post_id, P.blog_id, P.user_id, P.cat_id, post_dt, '. + 'post_tz, post_creadt, post_upddt, post_format, post_password, '. + 'post_url, post_lang, post_title, '.$content_req. + 'post_type, post_meta, post_status, post_selected, post_position, '. + 'post_open_comment, post_open_tb, nb_comment, nb_trackback, '. + 'U.user_name, U.user_firstname, U.user_displayname, U.user_email, '. + 'U.user_url, '. + 'C.cat_title, C.cat_url, C.cat_desc '; + } + + $strReq .= + 'FROM '.$this->prefix.'post P '. + 'INNER JOIN '.$this->prefix.'user U ON U.user_id = P.user_id '. + 'LEFT OUTER JOIN '.$this->prefix.'category C ON P.cat_id = C.cat_id '; + + if (!empty($params['from'])) { + $strReq .= $params['from'].' '; + } + + $strReq .= + "WHERE P.blog_id = '".$this->con->escape($this->id)."' "; + + if (!$this->core->auth->check('contentadmin',$this->id)) { + $strReq .= 'AND ((post_status = 1 '; + + if ($this->without_password) { + $strReq .= 'AND post_password IS NULL '; + } + $strReq .= ') '; + + if ($this->core->auth->userID()) { + $strReq .= "OR P.user_id = '".$this->con->escape($this->core->auth->userID())."')"; + } else { + $strReq .= ') '; + } + } + + #Adding parameters + if (isset($params['post_type'])) + { + if (is_array($params['post_type']) || $params['post_type'] != '') { + $strReq .= 'AND post_type '.$this->con->in($params['post_type']); + } + } + else + { + $strReq .= "AND post_type = 'post' "; + } + + if (isset($params['post_id']) && $params['post_id'] !== '') { + if (is_array($params['post_id'])) { + array_walk($params['post_id'],create_function('&$v,$k','if($v!==null){$v=(integer)$v;}')); + } else { + $params['post_id'] = array((integer) $params['post_id']); + } + $strReq .= 'AND P.post_id '.$this->con->in($params['post_id']); + } + + if (isset($params['post_url']) && $params['post_url'] !== '') { + $strReq .= "AND post_url = '".$this->con->escape($params['post_url'])."' "; + } + + if (!empty($params['user_id'])) { + $strReq .= "AND U.user_id = '".$this->con->escape($params['user_id'])."' "; + } + + if (isset($params['cat_id']) && $params['cat_id'] !== '') + { + if (!is_array($params['cat_id'])) { + $params['cat_id'] = array($params['cat_id']); + } + if (!empty($params['cat_id_not'])) { + array_walk($params['cat_id'],create_function('&$v,$k','$v=$v." ?not";')); + } + $strReq .= 'AND '.$this->getPostsCategoryFilter($params['cat_id'],'cat_id').' '; + } + elseif (isset($params['cat_url']) && $params['cat_url'] !== '') + { + if (!is_array($params['cat_url'])) { + $params['cat_url'] = array($params['cat_url']); + } + if (!empty($params['cat_url_not'])) { + array_walk($params['cat_url'],create_function('&$v,$k','$v=$v." ?not";')); + } + $strReq .= 'AND '.$this->getPostsCategoryFilter($params['cat_url'],'cat_url').' '; + } + + /* Other filters */ + if (isset($params['post_status'])) { + $strReq .= 'AND post_status = '.(integer) $params['post_status'].' '; + } + + if (isset($params['post_selected'])) { + $strReq .= 'AND post_selected = '.(integer) $params['post_selected'].' '; + } + + if (!empty($params['post_year'])) { + $strReq .= 'AND '.$this->con->dateFormat('post_dt','%Y').' = '. + "'".sprintf('%04d',$params['post_year'])."' "; + } + + if (!empty($params['post_month'])) { + $strReq .= 'AND '.$this->con->dateFormat('post_dt','%m').' = '. + "'".sprintf('%02d',$params['post_month'])."' "; + } + + if (!empty($params['post_day'])) { + $strReq .= 'AND '.$this->con->dateFormat('post_dt','%d').' = '. + "'".sprintf('%02d',$params['post_day'])."' "; + } + + if (!empty($params['post_lang'])) { + $strReq .= "AND P.post_lang = '".$this->con->escape($params['post_lang'])."' "; + } + + if (!empty($params['search'])) + { + $words = text::splitWords($params['search']); + + if (!empty($words)) + { + # --BEHAVIOR-- corePostSearch + if ($this->core->hasBehavior('corePostSearch')) { + $this->core->callBehavior('corePostSearch',$this->core,array(&$words,&$strReq,&$params)); + } + + if ($words) + { + foreach ($words as $i => $w) { + $words[$i] = "post_words LIKE '%".$this->con->escape($w)."%'"; + } + $strReq .= 'AND '.implode(' AND ',$words).' '; + } + } + } + + if (!empty($params['sql'])) { + $strReq .= $params['sql'].' '; + } + + if (!$count_only) + { + if (!empty($params['order'])) { + $strReq .= 'ORDER BY '.$this->con->escape($params['order']).' '; + } else { + $strReq .= 'ORDER BY post_dt DESC '; + } + } + + if (!$count_only && !empty($params['limit'])) { + $strReq .= $this->con->limit($params['limit']); + } + + if (!empty($params['sql_only'])) { + return $strReq; + } + + $rs = $this->con->select($strReq); + $rs->core = $this->core; + $rs->_nb_media = array(); + $rs->extend('rsExtPost'); + + # --BEHAVIOR-- coreBlogGetPosts + $this->core->callBehavior('coreBlogGetPosts',$rs); + + return $rs; + } + + /** + Returns a record with post id, title and date for next or previous post + according to the post ID. + $dir could be 1 (next post) or -1 (previous post). + + @param post_id integer Post ID + @param dir integer Search direction + @param restrict_to_category boolean Restrict to post with same category + @param restrict_to_lang boolean Restrict to post with same lang + @return record + */ + public function getNextPost($post,$dir,$restrict_to_category=false, $restrict_to_lang=false) + { + $dt = $post->post_dt; + $post_id = (integer) $post->post_id; + + if($dir > 0) { + $sign = '>'; + $order = 'ASC'; + } + else { + $sign = '<'; + $order = 'DESC'; + } + + $params['post_type'] = $post->post_type; + $params['limit'] = 1; + $params['order'] = 'post_dt '.$order.', P.post_id '.$order; + $params['sql'] = + 'AND ( '. + " (post_dt = '".$this->con->escape($dt)."' AND P.post_id ".$sign." ".$post_id.") ". + " OR post_dt ".$sign." '".$this->con->escape($dt)."' ". + ') '; + + if ($restrict_to_category) { + $params['sql'] .= $post->cat_id ? 'AND P.cat_id = '.(integer) $post->cat_id.' ' : 'AND P.cat_id IS NULL '; + } + + if ($restrict_to_lang) { + $params['sql'] .= $post->post_lang ? 'AND P.post_lang = \''. $this->con->escape($post->post_lang) .'\' ': 'AND P.post_lang IS NULL '; + } + + $rs = $this->getPosts($params); + + if ($rs->isEmpty()) { + return null; + } + + return $rs; + } + + /** + Retrieves different languages and post count on blog, based on post_lang + field. $params is an array taking the following optionnal + parameters: + + - post_type: Get only entries with given type (default "post", '' for no type) + - lang: retrieve post count for selected lang + - order: order statement (default post_lang DESC) + + @param params array Parameters + @return record + */ + public function getLangs($params=array()) + { + $strReq = 'SELECT COUNT(post_id) as nb_post, post_lang '. + 'FROM '.$this->prefix.'post '. + "WHERE blog_id = '".$this->con->escape($this->id)."' ". + "AND post_lang <> '' ". + "AND post_lang IS NOT NULL "; + + if (!$this->core->auth->check('contentadmin',$this->id)) { + $strReq .= 'AND ((post_status = 1 '; + + if ($this->without_password) { + $strReq .= 'AND post_password IS NULL '; + } + $strReq .= ') '; + + if ($this->core->auth->userID()) { + $strReq .= "OR user_id = '".$this->con->escape($this->core->auth->userID())."')"; + } else { + $strReq .= ') '; + } + } + + if (isset($params['post_type'])) { + if ($params['post_type'] != '') { + $strReq .= "AND post_type = '".$this->con->escape($params['post_type'])."' "; + } + } else { + $strReq .= "AND post_type = 'post' "; + } + + if (isset($params['lang'])) { + $strReq .= "AND post_lang = '".$this->con->escape($params['lang'])."' "; + } + + $strReq .= 'GROUP BY post_lang '; + + $order = 'desc'; + if (!empty($params['order']) && preg_match('/^(desc|asc)$/i',$params['order'])) { + $order = $params['order']; + } + $strReq .= 'ORDER BY post_lang '.$order.' '; + + return $this->con->select($strReq); + } + + /** + Returns a record with all distinct blog dates and post count. + $params is an array taking the following optionnal parameters: + + - type: (day|month|year) Get days, months or years + - year: (integer) Get dates for given year + - month: (integer) Get dates for given month + - day: (integer) Get dates for given day + - cat_id: (integer) Category ID filter + - cat_url: Category URL filter + - post_lang: lang of the posts + - next: Get date following match + - previous: Get date before match + - order: Sort by date "ASC" or "DESC" + + @param params array Parameters array + @return record + */ + public function getDates($params=array()) + { + $dt_f = '%Y-%m-%d'; + $dt_fc = '%Y%m%d'; + if (isset($params['type'])) { + if ($params['type'] == 'year') { + $dt_f = '%Y-01-01'; + $dt_fc = '%Y0101'; + } elseif ($params['type'] == 'month') { + $dt_f = '%Y-%m-01'; + $dt_fc = '%Y%m01'; + } + } + $dt_f .= ' 00:00:00'; + $dt_fc .= '000000'; + + $cat_field = $catReq = $limit = ''; + + if (isset($params['cat_id']) && $params['cat_id'] !== '') { + $catReq = 'AND P.cat_id = '.(integer) $params['cat_id'].' '; + $cat_field = ', C.cat_url '; + } elseif (isset($params['cat_url']) && $params['cat_url'] !== '') { + $catReq = "AND C.cat_url = '".$this->con->escape($params['cat_url'])."' "; + $cat_field = ', C.cat_url '; + } + if (!empty($params['post_lang'])) { + $catReq = 'AND P.post_lang = \''. $params['post_lang'].'\' '; + } + + $strReq = 'SELECT DISTINCT('.$this->con->dateFormat('post_dt',$dt_f).') AS dt '. + $cat_field. + ',COUNT(P.post_id) AS nb_post '. + 'FROM '.$this->prefix.'post P LEFT JOIN '.$this->prefix.'category C '. + 'ON P.cat_id = C.cat_id '. + "WHERE P.blog_id = '".$this->con->escape($this->id)."' ". + $catReq; + + if (!$this->core->auth->check('contentadmin',$this->id)) { + $strReq .= 'AND ((post_status = 1 '; + + if ($this->without_password) { + $strReq .= 'AND post_password IS NULL '; + } + $strReq .= ') '; + + if ($this->core->auth->userID()) { + $strReq .= "OR P.user_id = '".$this->con->escape($this->core->auth->userID())."')"; + } else { + $strReq .= ') '; + } + } + + if (!empty($params['post_type'])) { + $strReq .= "AND post_type ".$this->con->in($params['post_type'])." "; + } else { + $strReq .= "AND post_type = 'post' "; + } + + if (!empty($params['year'])) { + $strReq .= 'AND '.$this->con->dateFormat('post_dt','%Y')." = '".sprintf('%04d',$params['year'])."' "; + } + + if (!empty($params['month'])) { + $strReq .= 'AND '.$this->con->dateFormat('post_dt','%m')." = '".sprintf('%02d',$params['month'])."' "; + } + + if (!empty($params['day'])) { + $strReq .= 'AND '.$this->con->dateFormat('post_dt','%d')." = '".sprintf('%02d',$params['day'])."' "; + } + + # Get next or previous date + if (!empty($params['next']) || !empty($params['previous'])) + { + if (!empty($params['next'])) { + $pdir = ' > '; + $params['order'] = 'asc'; + $dt = $params['next']; + } else { + $pdir = ' < '; + $params['order'] = 'desc'; + $dt = $params['previous']; + } + + $dt = date('YmdHis',strtotime($dt)); + + $strReq .= 'AND '.$this->con->dateFormat('post_dt',$dt_fc).$pdir."'".$dt."' "; + $limit = $this->con->limit(1); + } + + $strReq .= 'GROUP BY dt '.$cat_field; + + $order = 'desc'; + if (!empty($params['order']) && preg_match('/^(desc|asc)$/i',$params['order'])) { + $order = $params['order']; + } + + $strReq .= + 'ORDER BY dt '.$order.' '. + $limit; + + $rs = $this->con->select($strReq); + $rs->extend('rsExtDates'); + return $rs; + } + + /** + Creates a new entry. Takes a cursor as input and returns the new entry + ID. + + @param cur cursor Post cursor + @return integer New post ID + */ + public function addPost($cur) + { + if (!$this->core->auth->check('usage,contentadmin',$this->id)) { + throw new Exception(__('You are not allowed to create an entry')); + } + + $this->con->writeLock($this->prefix.'post'); + try + { + # Get ID + $rs = $this->con->select( + 'SELECT MAX(post_id) '. + 'FROM '.$this->prefix.'post ' + ); + + $cur->post_id = (integer) $rs->f(0) + 1; + $cur->blog_id = (string) $this->id; + $cur->post_creadt = date('Y-m-d H:i:s'); + $cur->post_upddt = date('Y-m-d H:i:s'); + $cur->post_tz = $this->core->auth->getInfo('user_tz'); + + # Post excerpt and content + $this->getPostContent($cur,$cur->post_id); + + $this->getPostCursor($cur); + + $cur->post_url = $this->getPostURL($cur->post_url,$cur->post_dt,$cur->post_title,$cur->post_id); + + if (!$this->core->auth->check('publish,contentadmin',$this->id)) { + $cur->post_status = -2; + } + + # --BEHAVIOR-- coreBeforePostCreate + $this->core->callBehavior('coreBeforePostCreate',$this,$cur); + + $cur->insert(); + $this->con->unlock(); + } + catch (Exception $e) + { + $this->con->unlock(); + throw $e; + } + + # --BEHAVIOR-- coreAfterPostCreate + $this->core->callBehavior('coreAfterPostCreate',$this,$cur); + + $this->triggerBlog(); + + return $cur->post_id; + } + + /** + Updates an existing post. + + @param id integer Post ID + @param cur cursor Post cursor + */ + public function updPost($id,$cur) + { + if (!$this->core->auth->check('usage,contentadmin',$this->id)) { + throw new Exception(__('You are not allowed to update entries')); + } + + $id = (integer) $id; + + if (empty($id)) { + throw new Exception(__('No such entry ID')); + } + + # Post excerpt and content + $this->getPostContent($cur,$id); + + $this->getPostCursor($cur); + + if ($cur->post_url !== null) { + $cur->post_url = $this->getPostURL($cur->post_url,$cur->post_dt,$cur->post_title,$id); + } + + if (!$this->core->auth->check('publish,contentadmin',$this->id)) { + $cur->unsetField('post_status'); + } + + $cur->post_upddt = date('Y-m-d H:i:s'); + + #If user is only "usage", we need to check the post's owner + if (!$this->core->auth->check('contentadmin',$this->id)) + { + $strReq = 'SELECT post_id '. + 'FROM '.$this->prefix.'post '. + 'WHERE post_id = '.$id.' '. + "AND user_id = '".$this->con->escape($this->core->auth->userID())."' "; + + $rs = $this->con->select($strReq); + + if ($rs->isEmpty()) { + throw new Exception(__('You are not allowed to edit this entry')); + } + } + + # --BEHAVIOR-- coreBeforePostUpdate + $this->core->callBehavior('coreBeforePostUpdate',$this,$cur); + + $cur->update('WHERE post_id = '.$id.' '); + + # --BEHAVIOR-- coreAfterPostUpdate + $this->core->callBehavior('coreAfterPostUpdate',$this,$cur); + + $this->triggerBlog(); + } + + /** + Updates post status. + + @param id integer Post ID + @param status integer Post status + */ + public function updPostStatus($id,$status) + { + if (!$this->core->auth->check('publish,contentadmin',$this->id)) { + throw new Exception(__('You are not allowed to change this entry status')); + } + + $id = (integer) $id; + $status = (integer) $status; + + #If user can only publish, we need to check the post's owner + if (!$this->core->auth->check('contentadmin',$this->id)) + { + $strReq = 'SELECT post_id '. + 'FROM '.$this->prefix.'post '. + 'WHERE post_id = '.$id.' '. + "AND blog_id = '".$this->con->escape($this->id)."' ". + "AND user_id = '".$this->con->escape($this->core->auth->userID())."' "; + + $rs = $this->con->select($strReq); + + if ($rs->isEmpty()) { + throw new Exception(__('You are not allowed to change this entry status')); + } + } + + $cur = $this->con->openCursor($this->prefix.'post'); + + $cur->post_status = $status; + $cur->post_upddt = date('Y-m-d H:i:s'); + + $cur->update( + 'WHERE post_id = '.$id.' '. + "AND blog_id = '".$this->con->escape($this->id)."' " + ); + $this->triggerBlog(); + } + + public function updPostSelected($id,$selected) + { + if (!$this->core->auth->check('usage,contentadmin',$this->id)) { + throw new Exception(__('You are not allowed to change this entry category')); + } + + $id = (integer) $id; + $selected = (boolean) $selected; + + # If user is only usage, we need to check the post's owner + if (!$this->core->auth->check('contentadmin',$this->id)) + { + $strReq = 'SELECT post_id '. + 'FROM '.$this->prefix.'post '. + 'WHERE post_id = '.$id.' '. + "AND blog_id = '".$this->con->escape($this->id)."' ". + "AND user_id = '".$this->con->escape($this->core->auth->userID())."' "; + + $rs = $this->con->select($strReq); + + if ($rs->isEmpty()) { + throw new Exception(__('You are not allowed to mark this entry as selected')); + } + } + + $cur = $this->con->openCursor($this->prefix.'post'); + + $cur->post_selected = (integer) $selected; + $cur->post_upddt = date('Y-m-d H:i:s'); + + $cur->update( + 'WHERE post_id = '.$id.' '. + "AND blog_id = '".$this->con->escape($this->id)."' " + ); + $this->triggerBlog(); + } + + /** + Updates post category. $cat_id can be null. + + @param id integer Post ID + @param cat_id integer Category ID + */ + public function updPostCategory($id,$cat_id) + { + if (!$this->core->auth->check('usage,contentadmin',$this->id)) { + throw new Exception(__('You are not allowed to change this entry category')); + } + + $id = (integer) $id; + $cat_id = (integer) $cat_id; + + # If user is only usage, we need to check the post's owner + if (!$this->core->auth->check('contentadmin',$this->id)) + { + $strReq = 'SELECT post_id '. + 'FROM '.$this->prefix.'post '. + 'WHERE post_id = '.$id.' '. + "AND blog_id = '".$this->con->escape($this->id)."' ". + "AND user_id = '".$this->con->escape($this->core->auth->userID())."' "; + + $rs = $this->con->select($strReq); + + if ($rs->isEmpty()) { + throw new Exception(__('You are not allowed to change this entry category')); + } + } + + $cur = $this->con->openCursor($this->prefix.'post'); + + $cur->cat_id = ($cat_id ? $cat_id : null); + $cur->post_upddt = date('Y-m-d H:i:s'); + + $cur->update( + 'WHERE post_id = '.$id.' '. + "AND blog_id = '".$this->con->escape($this->id)."' " + ); + $this->triggerBlog(); + } + + /** + Deletes a post. + + @param id integer Post ID + */ + public function delPost($id) + { + if (!$this->core->auth->check('delete,contentadmin',$this->id)) { + throw new Exception(__('You are not allowed to delete entries')); + } + + $id = (integer) $id; + + if (empty($id)) { + throw new Exception(__('No such entry ID')); + } + + #If user can only delete, we need to check the post's owner + if (!$this->core->auth->check('contentadmin',$this->id)) + { + $strReq = 'SELECT post_id '. + 'FROM '.$this->prefix.'post '. + 'WHERE post_id = '.$id.' '. + "AND blog_id = '".$this->con->escape($this->id)."' ". + "AND user_id = '".$this->con->escape($this->core->auth->userID())."' "; + + $rs = $this->con->select($strReq); + + if ($rs->isEmpty()) { + throw new Exception(__('You are not allowed to delete this entry')); + } + } + + + $strReq = 'DELETE FROM '.$this->prefix.'post '. + 'WHERE post_id = '.$id.' '. + "AND blog_id = '".$this->con->escape($this->id)."' "; + + $this->con->execute($strReq); + $this->triggerBlog(); + } + + /** + Publishes all entries flaged as "scheduled". + */ + public function publishScheduledEntries() + { + $strReq = 'SELECT post_id, post_dt, post_tz '. + 'FROM '.$this->prefix.'post '. + 'WHERE post_status = -1 '. + "AND blog_id = '".$this->con->escape($this->id)."' "; + + $rs = $this->con->select($strReq); + + $now = dt::toUTC(time()); + $to_change = new ArrayObject(); + + if ($rs->isEmpty()) { + return; + } + + while ($rs->fetch()) + { + # Now timestamp with post timezone + $now_tz = $now + dt::getTimeOffset($rs->post_tz,$now); + + # Post timestamp + $post_ts = strtotime($rs->post_dt); + + # If now_tz >= post_ts, we publish the entry + if ($now_tz >= $post_ts) { + $to_change[] = (integer) $rs->post_id; + } + } + if (count($to_change)) + { + # --BEHAVIOR-- coreBeforeScheduledEntriesPublish + $this->core->callBehavior('coreBeforeScheduledEntriesPublish',$this,$to_change); + + $strReq = + 'UPDATE '.$this->prefix.'post SET '. + 'post_status = 1 '. + "WHERE blog_id = '".$this->con->escape($this->id)."' ". + 'AND post_id '.$this->con->in((array)$to_change).' '; + $this->con->execute($strReq); + $this->triggerBlog(); + + # --BEHAVIOR-- coreAfterScheduledEntriesPublish + $this->core->callBehavior('coreAfterScheduledEntriesPublish',$this,$to_change); + } + + } + + /** + Retrieves all users having posts on current blog. + + @param post_type string post_type filter (post) + @return record + */ + public function getPostsUsers($post_type='post') + { + $strReq = 'SELECT P.user_id, user_name, user_firstname, '. + 'user_displayname, user_email '. + 'FROM '.$this->prefix.'post P, '.$this->prefix.'user U '. + 'WHERE P.user_id = U.user_id '. + "AND blog_id = '".$this->con->escape($this->id)."' "; + + if ($post_type) { + $strReq .= "AND post_type = '".$this->con->escape($post_type)."' "; + } + + $strReq .= 'GROUP BY P.user_id, user_name, user_firstname, user_displayname, user_email '; + + return $this->con->select($strReq); + } + + private function getPostsCategoryFilter($arr,$field='cat_id') + { + $field = $field == 'cat_id' ? 'cat_id' : 'cat_url'; + + $sub = array(); + $not = array(); + $queries = array(); + + foreach ($arr as $v) + { + $v = trim($v); + $args = preg_split('/\s*[?]\s*/',$v,-1,PREG_SPLIT_NO_EMPTY); + $id = array_shift($args); + $args = array_flip($args); + + if (isset($args['not'])) { $not[$id] = 1; } + if (isset($args['sub'])) { $sub[$id] = 1; } + if ($field == 'cat_id') { + if (preg_match('/^null$/i',$id)) { + $queries[$id] = 'P.cat_id IS NULL'; + } + else { + $queries[$id] = 'P.cat_id = '.(integer) $id; + } + } else { + $queries[$id] = "C.cat_url = '".$this->con->escape($id)."' "; + } + } + + if (!empty($sub)) { + $rs = $this->con->select( + 'SELECT cat_id, cat_url, cat_lft, cat_rgt FROM '.$this->prefix.'category '. + "WHERE blog_id = '".$this->con->escape($this->id)."' ". + 'AND '.$field.' '.$this->con->in(array_keys($sub)) + ); + + while ($rs->fetch()) { + $queries[$rs->f($field)] = '(C.cat_lft BETWEEN '.$rs->cat_lft.' AND '.$rs->cat_rgt.')'; + } + } + + # Create queries + $sql = array( + 0 => array(), # wanted categories + 1 => array() # excluded categories + ); + + foreach ($queries as $id => $q) { + $sql[(integer) isset($not[$id])][] = $q; + } + + $sql[0] = implode(' OR ',$sql[0]); + $sql[1] = implode(' OR ',$sql[1]); + + if ($sql[0]) { + $sql[0] = '('.$sql[0].')'; + } else { + unset($sql[0]); + } + + if ($sql[1]) { + $sql[1] = '(P.cat_id IS NULL OR NOT('.$sql[1].'))'; + } else { + unset($sql[1]); + } + + return implode(' AND ',$sql); + } + + private function getPostCursor($cur,$post_id=null) + { + if ($cur->post_title == '') { + throw new Exception(__('No entry title')); + } + + if ($cur->post_content == '') { + throw new Exception(__('No entry content')); + } + + if ($cur->post_password === '') { + $cur->post_password = null; + } + + if ($cur->post_dt == '') { + $offset = dt::getTimeOffset($this->core->auth->getInfo('user_tz')); + $now = time() + $offset; + $cur->post_dt = date('Y-m-d H:i:00',$now); + } + + $post_id = is_int($post_id) ? $post_id : $cur->post_id; + + if ($cur->post_content_xhtml == '') { + throw new Exception(__('No entry content')); + } + + # Words list + if ($cur->post_title !== null && $cur->post_excerpt_xhtml !== null + && $cur->post_content_xhtml !== null) + { + $words = + $cur->post_title.' '. + $cur->post_excerpt_xhtml.' '. + $cur->post_content_xhtml; + + $cur->post_words = implode(' ',text::splitWords($words)); + } + } + + private function getPostContent($cur,$post_id) + { + $post_excerpt = $cur->post_excerpt; + $post_excerpt_xhtml = $cur->post_excerpt_xhtml; + $post_content = $cur->post_content; + $post_content_xhtml = $cur->post_content_xhtml; + + $this->setPostContent( + $post_id,$cur->post_format,$cur->post_lang, + $post_excerpt,$post_excerpt_xhtml, + $post_content,$post_content_xhtml + ); + + $cur->post_excerpt = $post_excerpt; + $cur->post_excerpt_xhtml = $post_excerpt_xhtml; + $cur->post_content = $post_content; + $cur->post_content_xhtml = $post_content_xhtml; + } + + /** + Creates post HTML content, taking format and lang into account. + + @param post_id integer Post ID + @param format string Post format + @param lang string Post lang + @param excerpt string Post excerpt + @param[out] excerpt_xhtml string Post excerpt HTML + @param content string Post content + @param[out] content_xhtml string Post content HTML + */ + public function setPostContent($post_id,$format,$lang,&$excerpt,&$excerpt_xhtml,&$content,&$content_xhtml) + { + if ($format == 'wiki') + { + $this->core->initWikiPost(); + $this->core->wiki2xhtml->setOpt('note_prefix','pnote-'.$post_id); + if (strpos($lang,'fr') === 0) { + $this->core->wiki2xhtml->setOpt('active_fr_syntax',1); + } + } + + if ($excerpt) { + $excerpt_xhtml = $this->core->callFormater($format,$excerpt); + $excerpt_xhtml = $this->core->HTMLfilter($excerpt_xhtml); + } else { + $excerpt_xhtml = ''; + } + + if ($content) { + $content_xhtml = $this->core->callFormater($format,$content); + $content_xhtml = $this->core->HTMLfilter($content_xhtml); + } else { + $content_xhtml = ''; + } + + # --BEHAVIOR-- coreAfterPostContentFormat + $this->core->callBehavior('coreAfterPostContentFormat',array( + 'excerpt' => &$excerpt, + 'content' => &$content, + 'excerpt_xhtml' => &$excerpt_xhtml, + 'content_xhtml' => &$content_xhtml + )); + } + + /** + Returns URL for a post according to blog setting post_url_format. + It will try to guess URL and append some figures if needed. + + @param url string Origin URL, could be empty + @param post_dt string Post date (in YYYY-MM-DD HH:mm:ss) + @param post_title string Post title + @param post_id integer Post ID + @return string result URL + */ + public function getPostURL($url,$post_dt,$post_title,$post_id) + { + $url = trim($url); + + $url_patterns = array( + '{y}' => date('Y',strtotime($post_dt)), + '{m}' => date('m',strtotime($post_dt)), + '{d}' => date('d',strtotime($post_dt)), + '{t}' => text::tidyURL($post_title), + '{id}' => (integer) $post_id + ); + + # If URL is empty, we create a new one + if ($url == '') + { + # Transform with format + $url = str_replace( + array_keys($url_patterns), + array_values($url_patterns), + $this->settings->system->post_url_format + ); + } + else + { + $url = text::tidyURL($url); + } + + # Let's check if URL is taken... + $strReq = 'SELECT post_url FROM '.$this->prefix.'post '. + "WHERE post_url = '".$this->con->escape($url)."' ". + 'AND post_id <> '.(integer) $post_id. ' '. + "AND blog_id = '".$this->con->escape($this->id)."' ". + 'ORDER BY post_url DESC'; + + $rs = $this->con->select($strReq); + + if (!$rs->isEmpty()) + { + if ($this->con->driver() == 'mysql') { + $clause = "REGEXP '^".$this->con->escape($url)."[0-9]+$'"; + } elseif ($this->con->driver() == 'pgsql') { + $clause = "~ '^".$this->con->escape($url)."[0-9]+$'"; + } else { + $clause = "LIKE '".$this->con->escape($url)."%'"; + } + $strReq = 'SELECT post_url FROM '.$this->prefix.'post '. + "WHERE post_url ".$clause.' '. + 'AND post_id <> '.(integer) $post_id.' '. + "AND blog_id = '".$this->con->escape($this->id)."' ". + 'ORDER BY post_url DESC '; + + $rs = $this->con->select($strReq); + $a = array(); + while ($rs->fetch()) { + $a[] = $rs->post_url; + } + + natsort($a); + $t_url = end($a); + + if (preg_match('/(.*?)([0-9]+)$/',$t_url,$m)) { + $i = (integer) $m[2]; + $url = $m[1]; + } else { + $i = 1; + } + + return $url.($i+1); + } + + # URL is empty? + if ($url == '') { + throw new Exception(__('Empty entry URL')); + } + + return $url; + } + //@} + + /// @name Comments management methods + //@{ + /** + Retrieves comments. $params is an array taking the following + optionnal parameters: + + - no_content: Don't retrieve comment content + - post_type: Get only entries with given type (default no type, array for many types) + - post_id: (integer) Get comments belonging to given post_id + - cat_id: (integer or array) Get comments belonging to entries of given category ID + - comment_id: (integer) Get comment with given ID + - comment_status: (integer) Get comments with given comment_status + - comment_trackback: (integer) Get only comments (0) or trackbacks (1) + - comment_ip: (string) Get comments with given IP address + - post_url: Get entry with given post_url field + - user_id: (integer) Get entries belonging to given user ID + - q_author: Search comments by author + - sql: Append SQL string at the end of the query + - from: Append SQL string after "FROM" statement in query + - order: Order of results (default "ORDER BY comment_dt DES") + - limit: Limit parameter + - sql_only : return the sql request instead of results. Only ids are selected + + @param params array Parameters + @param count_only boolean Only counts results + @return record A record with some more capabilities + */ + public function getComments($params=array(),$count_only=false) + { + if ($count_only) + { + $strReq = 'SELECT count(comment_id) '; + } + elseif (!empty($params['sql_only'])) + { + $strReq = 'SELECT P.post_id '; + } + else + { + if (!empty($params['no_content'])) { + $content_req = ''; + } else { + $content_req = 'comment_content, '; + } + + if (!empty($params['columns']) && is_array($params['columns'])) { + $content_req .= implode(', ',$params['columns']).', '; + } + + $strReq = + 'SELECT C.comment_id, comment_dt, comment_tz, comment_upddt, '. + 'comment_author, comment_email, comment_site, '. + $content_req.' comment_trackback, comment_status, '. + 'comment_spam_status, comment_spam_filter, comment_ip, '. + 'P.post_title, P.post_url, P.post_id, P.post_password, P.post_type, '. + 'P.post_dt, P.user_id, U.user_email, U.user_url '; + } + + $strReq .= + 'FROM '.$this->prefix.'comment C '. + 'INNER JOIN '.$this->prefix.'post P ON C.post_id = P.post_id '. + 'INNER JOIN '.$this->prefix.'user U ON P.user_id = U.user_id '; + + if (!empty($params['from'])) { + $strReq .= $params['from'].' '; + } + + $strReq .= + "WHERE P.blog_id = '".$this->con->escape($this->id)."' "; + + if (!$this->core->auth->check('contentadmin',$this->id)) { + $strReq .= 'AND ((comment_status = 1 AND P.post_status = 1 '; + + if ($this->without_password) { + $strReq .= 'AND post_password IS NULL '; + } + $strReq .= ') '; + + if ($this->core->auth->userID()) { + $strReq .= "OR P.user_id = '".$this->con->escape($this->core->auth->userID())."')"; + } else { + $strReq .= ') '; + } + } + + if (!empty($params['post_type'])) + { + $strReq .= 'AND post_type '.$this->con->in($params['post_type']); + } + + if (isset($params['post_id']) && $params['post_id'] !== '') { + $strReq .= 'AND P.post_id = '.(integer) $params['post_id'].' '; + } + + if (isset($params['cat_id']) && $params['cat_id'] !== '') { + $strReq .= 'AND P.cat_id = '.(integer) $params['cat_id'].' '; + } + + if (isset($params['comment_id']) && $params['comment_id'] !== '') { + $strReq .= 'AND comment_id = '.(integer) $params['comment_id'].' '; + } + + if (isset($params['comment_status'])) { + $strReq .= 'AND comment_status = '.(integer) $params['comment_status'].' '; + } + + if (!empty($params['comment_status_not'])) + { + $strReq .= 'AND comment_status <> '.(integer) $params['comment_status_not'].' '; + } + + if (isset($params['comment_trackback'])) { + $strReq .= 'AND comment_trackback = '.(integer) (boolean) $params['comment_trackback'].' '; + } + + if (isset($params['comment_ip'])) { + $strReq .= "AND comment_ip = '".$this->con->escape($params['comment_ip'])."' "; + } + + if (isset($params['q_author'])) { + $q_author = $this->con->escape(str_replace('*','%',strtolower($params['q_author']))); + $strReq .= "AND LOWER(comment_author) LIKE '".$q_author."' "; + } + + if (!empty($params['search'])) + { + $words = text::splitWords($params['search']); + + if (!empty($words)) + { + # --BEHAVIOR coreCommentSearch + if ($this->core->hasBehavior('coreCommentSearch')) { + $this->core->callBehavior('coreCommentSearch',$this->core,array(&$words,&$strReq,&$params)); + } + + if ($words) + { + foreach ($words as $i => $w) { + $words[$i] = "comment_words LIKE '%".$this->con->escape($w)."%'"; + } + $strReq .= 'AND '.implode(' AND ',$words).' '; + } + } + } + + if (!empty($params['sql'])) { + $strReq .= $params['sql'].' '; + } + + if (!$count_only) + { + if (!empty($params['order'])) { + $strReq .= 'ORDER BY '.$this->con->escape($params['order']).' '; + } else { + $strReq .= 'ORDER BY comment_dt DESC '; + } + } + + if (!$count_only && !empty($params['limit'])) { + $strReq .= $this->con->limit($params['limit']); + } + + if (!empty($params['sql_only'])) { + return $strReq; + } + + $rs = $this->con->select($strReq); + $rs->core = $this->core; + $rs->extend('rsExtComment'); + + # --BEHAVIOR-- coreBlogGetComments + $this->core->callBehavior('coreBlogGetComments',$rs); + + return $rs; + } + + /** + Creates a new comment. Takes a cursor as input and returns the new comment + ID. + + @param cur cursor Comment cursor + @return integer New comment ID + */ + public function addComment($cur) + { + $this->con->writeLock($this->prefix.'comment'); + try + { + # Get ID + $rs = $this->con->select( + 'SELECT MAX(comment_id) '. + 'FROM '.$this->prefix.'comment ' + ); + + $cur->comment_id = (integer) $rs->f(0) + 1; + $cur->comment_upddt = date('Y-m-d H:i:s'); + + $offset = dt::getTimeOffset($this->settings->system->blog_timezone); + $cur->comment_dt = date('Y-m-d H:i:s',time() + $offset); + $cur->comment_tz = $this->settings->system->blog_timezone; + + $this->getCommentCursor($cur); + + if ($cur->comment_ip === null) { + $cur->comment_ip = http::realIP(); + } + + # --BEHAVIOR-- coreBeforeCommentCreate + $this->core->callBehavior('coreBeforeCommentCreate',$this,$cur); + + $cur->insert(); + $this->con->unlock(); + } + catch (Exception $e) + { + $this->con->unlock(); + throw $e; + } + + # --BEHAVIOR-- coreAfterCommentCreate + $this->core->callBehavior('coreAfterCommentCreate',$this,$cur); + + $this->triggerComment($cur->comment_id); + if ($cur->comment_status != -2) { + $this->triggerBlog(); + } + return $cur->comment_id; + } + + /** + Updates an existing comment. + + @param id integer Comment ID + @param cur cursor Comment cursor + */ + public function updComment($id,$cur) + { + if (!$this->core->auth->check('usage,contentadmin',$this->id)) { + throw new Exception(__('You are not allowed to update comments')); + } + + $id = (integer) $id; + + if (empty($id)) { + throw new Exception(__('No such comment ID')); + } + + $rs = $this->getComments(array('comment_id' => $id)); + + if ($rs->isEmpty()) { + throw new Exception(__('No such comment ID')); + } + + #If user is only usage, we need to check the post's owner + if (!$this->core->auth->check('contentadmin',$this->id)) + { + if ($rs->user_id != $this->core->auth->userID()) { + throw new Exception(__('You are not allowed to update this comment')); + } + } + + $this->getCommentCursor($cur); + + $cur->comment_upddt = date('Y-m-d H:i:s'); + + if (!$this->core->auth->check('publish,contentadmin',$this->id)) { + $cur->unsetField('comment_status'); + } + + # --BEHAVIOR-- coreBeforeCommentUpdate + $this->core->callBehavior('coreBeforeCommentUpdate',$this,$cur,$rs); + + $cur->update('WHERE comment_id = '.$id.' '); + + # --BEHAVIOR-- coreAfterCommentUpdate + $this->core->callBehavior('coreAfterCommentUpdate',$this,$cur,$rs); + + $this->triggerComment($id); + $this->triggerBlog(); + } + + /** + Updates comment status. + + @param id integer Comment ID + @param status integer Comment status + */ + public function updCommentStatus($id,$status) + { + if (!$this->core->auth->check('publish,contentadmin',$this->id)) { + throw new Exception(__("You are not allowed to change this comment's status")); + } + + $cur = $this->con->openCursor($this->prefix.'comment'); + $cur->comment_status = (integer) $status; + $this->updComment($id,$cur); + } + + /** + Delete a comment + + @param id integer Comment ID + */ + public function delComment($id) + { + if (!$this->core->auth->check('delete,contentadmin',$this->id)) { + throw new Exception(__('You are not allowed to delete comments')); + } + + $id = (integer) $id; + + if (empty($id)) { + throw new Exception(__('No such comment ID')); + } + + #If user can only delete, we need to check the post's owner + if (!$this->core->auth->check('contentadmin',$this->id)) + { + $strReq = 'SELECT P.post_id '. + 'FROM '.$this->prefix.'post P, '.$this->prefix.'comment C '. + 'WHERE P.post_id = C.post_id '. + "AND P.blog_id = '".$this->con->escape($this->id)."' ". + 'AND comment_id = '.$id.' '. + "AND user_id = '".$this->con->escape($this->core->auth->userID())."' "; + + $rs = $this->con->select($strReq); + + if ($rs->isEmpty()) { + throw new Exception(__('You are not allowed to delete this comment')); + } + } + + $strReq = 'DELETE FROM '.$this->prefix.'comment '. + 'WHERE comment_id = '.$id.' '; + + $this->triggerComment($id,true); + $this->con->execute($strReq); + $this->triggerBlog(); + } + + private function getCommentCursor($cur) + { + if ($cur->comment_content !== null && $cur->comment_content == '') { + throw new Exception(__('You must provide a comment')); + } + + if ($cur->comment_author !== null && $cur->comment_author == '') { + throw new Exception(__('You must provide an author name')); + } + + if ($cur->comment_email != '' && !text::isEmail($cur->comment_email)) { + throw new Exception(__('Email address is not valid.')); + } + + if ($cur->comment_site !== null && $cur->comment_site != '') { + if (!preg_match('|^http(s?)://|',$cur->comment_site)) { + $cur->comment_site = 'http://'.$cur->comment_site; + } + } + + if ($cur->comment_status === null) { + $cur->comment_status = (integer) $this->settings->system->comments_pub; + } + + # Words list + if ($cur->comment_content !== null) + { + $cur->comment_words = implode(' ',text::splitWords($cur->comment_content)); + } + } + //@} +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/core/class.dc.categories.php b/v2/dotclear/inc/core/class.dc.categories.php new file mode 100644 index 0000000..1dacf94 --- /dev/null +++ b/v2/dotclear/inc/core/class.dc.categories.php @@ -0,0 +1,483 @@ +core =& $core; + $this->con =& $core->con; + $this->blog_id = $core->blog->id; + $this->table = $core->prefix.'category'; + $this->add_condition = array('blog_id' => "'".$this->con->escape($this->blog_id)."'"); + } + + public function getChildren($start=0,$id=null,$sort='asc',$fields=array()) + { + $fields = array_merge(array('cat_title','cat_url','cat_desc'),$fields); + return parent::getChildren($start,$id,$sort,$fields); + } + + public function getParents($id,$fields=array()) + { + $fields = array_merge(array('cat_title','cat_url','cat_desc'),$fields); + return parent::getParents($id,$fields); + } + + public function getParent($id,$fields=array()) + { + $fields = array_merge(array('cat_title','cat_url','cat_desc'),$fields); + return parent::getParent($id,$fields); + } +} + +abstract class nestedTree +{ + protected $con; + + protected $table; + protected $f_left; + protected $f_right; + protected $f_id; + + protected $add_condition = array(); + + protected $parents; + + public function __construct($con) + { + $this->con =& $con; + } + + public function getChildren($start=0,$id=null,$sort='asc',$fields=array()) + { + $fields = count($fields) > 0 ? ', C2.'.implode(', C2.',$fields) : ''; + + $sql = 'SELECT C2.'.$this->f_id.', C2.'.$this->f_left.', C2.'.$this->f_right.', COUNT(C1.'.$this->f_id.') AS level ' + . $fields.' ' + . 'FROM '.$this->table.' AS C1, '.$this->table.' AS C2 %s ' + . 'WHERE C2.'.$this->f_left.' BETWEEN C1.'.$this->f_left.' AND C1.'.$this->f_right.' ' + . ' %s ' + . $this->getCondition('AND','C2.') + . $this->getCondition('AND','C1.') + . 'GROUP BY C2.'.$this->f_id.', C2.'.$this->f_left.', C2.'.$this->f_right.' '.$fields.' ' + . ' %s ' + . 'ORDER BY C2.'.$this->f_left.' '.($sort == 'asc' ? 'ASC' : 'DESC').' '; + + $from = $where = ''; + if ($start > 0) { + $from = ', '.$this->table.' AS C3'; + $where = 'AND C3.'.$this->f_id.' = '.(integer) $start.' AND C1.'.$this->f_left.' >= C3.'.$this->f_left.' AND C1.'.$this->f_right.' <= C3.'.$this->f_right; + $where .= $this->getCondition('AND','C3.'); + } + + $having = ''; + if ($id !== null) { + $having = ' HAVING C2.'.$this->f_id.' = '.(integer) $id; + } + + $sql = sprintf($sql,$from,$where,$having); + + return $this->con->select($sql); + } + + public function getParents($id,$fields=array()) + { + $fields = count($fields) > 0 ? ', C1.'.implode(', C1.',$fields) : ''; + + return $this->con->select( + 'SELECT C1.'.$this->f_id.' '.$fields.' ' + . 'FROM '.$this->table.' C1, '.$this->table.' C2 ' + . 'WHERE C2.'.$this->f_id.' = '.(integer) $id.' ' + . 'AND C1.'.$this->f_left.' < C2.'.$this->f_left.' ' + . 'AND C1.'.$this->f_right.' > C2.'.$this->f_right.' ' + . $this->getCondition('AND','C2.') + . $this->getCondition('AND','C1.') + . 'ORDER BY C1.'.$this->f_left.' ASC ' + ); + } + + public function getParent($id,$fields=array()) + { + $fields = count($fields) > 0 ? ', C1.'.implode(', C1.',$fields) : ''; + + return $this->con->select( + 'SELECT C1.'.$this->f_id.' '.$fields.' ' + . 'FROM '.$this->table.' C1, '.$this->table.' C2 ' + . 'WHERE C2.'.$this->f_id.' = '.(integer) $id.' ' + . 'AND C1.'.$this->f_left.' < C2.'.$this->f_left.' ' + . 'AND C1.'.$this->f_right.' > C2.'.$this->f_right.' ' + . $this->getCondition('AND','C2.') + . $this->getCondition('AND','C1.') + . 'ORDER BY C1.'.$this->f_left.' DESC ' + . $this->con->limit(1) + ); + } + + /* ------------------------------------------------ + * Tree manipulations + * ---------------------------------------------- */ + public function addNode($data,$target=0) + { + if (!is_array($data) && !($data instanceof cursor)) { + throw new Exception('Invalid data block'); + } + + if (is_array($data)) + { + $D = $data; + $data = $this->con->openCursor($this->table); + foreach ($D as $k => $v) { + $data->{$k} = $v; + } + unset($D); + } + + # We want to put it at the end + $this->con->writeLock($this->table); + try + { + $rs = $this->con->select('SELECT MAX('.$this->f_id.') as n_id FROM '.$this->table); + $id = $rs->n_id; + + $rs = $this->con->select( + 'SELECT MAX('.$this->f_right.') as n_r '. + 'FROM '.$this->table. + $this->getCondition('WHERE') + ); + $last = $rs->n_r == 0 ? 1 : $rs->n_r; + + $data->{$this->f_id} = $id+1; + $data->{$this->f_left} = $last+1; + $data->{$this->f_right} = $last+2; + + $data->insert(); + $this->con->unlock(); + try { + $this->setNodeParent($id+1,$target); + return $data->{$this->f_id}; + } catch (Exception $e) {} # We don't mind error in this case + } + catch (Exception $e) + { + $this->con->unlock(); + throw $e; + } + } + + public function deleteNode($node,$keep_children=true) + { + $node = (integer) $node; + + $rs = $this->getChildren(0,$node); + if ($rs->isEmpty()) { + throw new Exception('Node does not exist.'); + } + $node_left = (integer) $rs->{$this->f_left}; + $node_right = (integer) $rs->{$this->f_right}; + + try + { + $this->con->begin(); + + if ($keep_children) + { + $this->con->execute('DELETE FROM '.$this->table.' WHERE '.$this->f_id.' = '.$node); + + $sql = 'UPDATE '.$this->table.' SET ' + . $this->f_right.' = CASE ' + . 'WHEN '.$this->f_right.' BETWEEN '.$node_left.' AND '.$node_right.' ' + . 'THEN '.$this->f_right.' - 1 ' + . 'WHEN '.$this->f_right.' > '.$node_right.' ' + . 'THEN '.$this->f_right.' - 2 ' + . 'ELSE '.$this->f_right.' ' + . 'END, ' + . $this->f_left.' = CASE ' + . 'WHEN '.$this->f_left.' BETWEEN '.$node_left.' AND '.$node_right.' ' + . 'THEN '.$this->f_left.' - 1 ' + . 'WHEN '.$this->f_left.' > '.$node_right.' ' + . 'THEN '.$this->f_left.' - 2 ' + . 'ELSE '.$this->f_left.' ' + . 'END ' + . 'WHERE '.$this->f_right.' > '.$node_left + . $this->getCondition(); + + $this->con->execute($sql); + } + else + { + $this->con->execute('DELETE FROM '.$this->table.' WHERE '.$this->f_left.' BETWEEN '.$node_left.' AND '.$node_right); + + $node_delta = $node_right - $node_left + 1; + $sql = 'UPDATE '.$this->table.' SET ' + . $this->f_left.' = CASE ' + . 'WHEN '.$this->f_left.' > '.$node_left.' ' + . 'THEN '.$this->f_left.' - ('.$node_delta.') ' + . 'ELSE '.$this->f_left.' ' + . 'END, ' + . $this->f_right.' = CASE ' + . 'WHEN '.$this->f_right.' > '.$node_left.' ' + . 'THEN '.$this->f_right.' - ('.$node_delta.') ' + . 'ELSE '.$this->f_right.' ' + . 'END ' + . 'WHERE '.$this->f_right.' > '.$node_right + . $this->getCondition(); + } + + $this->con->commit(); + } + catch (Exception $e) + { + $this->con->rollback(); + throw $e; + } + } + + public function resetOrder() + { + $rs = $this->con->select( + 'SELECT '.$this->f_id.' ' + .'FROM '.$this->table.' ' + .$this->getCondition('WHERE') + .'ORDER BY '.$this->f_left.' ASC ' + ); + + $lft = 2; + $this->con->begin(); + try + { + while ($rs->fetch()) { + $this->con->execute( + 'UPDATE '.$this->table.' SET ' + .$this->f_left.' = '.($lft++).', ' + .$this->f_right.' = '.($lft++).' ' + .'WHERE '.$this->f_id .' = '.(integer) $rs->{$this->f_id}.' ' + .$this->getCondition() + ); + } + $this->con->commit(); + } + catch (Exception $e) + { + $this->con->rollback(); + throw $e; + } + } + + public function setNodeParent($node,$target=0) + { + if ($node == $target) { + return; + } + $node = (integer) $node; + $target = (integer) $target; + + $rs = $this->getChildren(0,$node); + if ($rs->isEmpty()) { + throw new Exception('Node does not exist.'); + } + $node_left = (integer) $rs->{$this->f_left}; + $node_right = (integer) $rs->{$this->f_right}; + $node_level = (integer) $rs->level; + + if ($target > 0) + { + $rs = $this->getChildren(0,$target); + } + else + { + $rs = $this->con->select( + 'SELECT MIN('.$this->f_left.')-1 AS '.$this->f_left.', MAX('.$this->f_right.')+1 AS '.$this->f_right.', 0 AS level '. + 'FROM '.$this->table.' '. + $this->getCondition('WHERE') + ); + } + $target_left = (integer) $rs->{$this->f_left}; + $target_right = (integer) $rs->{$this->f_right}; + $target_level = (integer) $rs->level; + + if ($node_left == $target_left + || ($target_left >= $node_left && $target_left <= $node_right) + || ($node_level == $target_level+1 && $node_left > $target_left && $node_right < $target_right) + ) + { + throw new Exception('Cannot move tree'); + } + + if ($target_left < $node_left && $target_right > $node_right && $target_level < $node_level -1) + { + $sql = 'UPDATE '.$this->table.' SET ' + . $this->f_right.' = CASE ' + . 'WHEN '.$this->f_right.' BETWEEN '.($node_right+1).' AND '.($target_right-1).' ' + . 'THEN '.$this->f_right.'-('.($node_right-$node_left+1).') ' + . 'WHEN '.$this->f_left.' BETWEEN '.$node_left.' AND '.$node_right.' ' + . 'THEN '.$this->f_right.'+'.((($target_right-$node_right-$node_level+$target_level)/2)*2+$node_level-$target_level-1).' ' + . 'ELSE ' + . $this->f_right.' ' + . 'END, ' + . $this->f_left.' = CASE ' + . 'WHEN '.$this->f_left.' BETWEEN '.($node_right+1).' AND '.($target_right-1).' ' + . 'THEN '.$this->f_left.'-('.($node_right-$node_left+1).') ' + . 'WHEN '.$this->f_left.' BETWEEN '.$node_left.' AND '.$node_right.' ' + . 'THEN '.$this->f_left.'+'.((($target_right-$node_right-$node_level+$target_level)/2)*2+$node_level-$target_level-1).' ' + . 'ELSE '.$this->f_left.' ' + . 'END ' + . 'WHERE '.$this->f_left.' BETWEEN '.($target_left+1).' AND '.($target_right-1).''; + } + elseif ($target_left < $node_left) + { + $sql = 'UPDATE '.$this->table.' SET ' + . $this->f_left.' = CASE ' + . 'WHEN '.$this->f_left.' BETWEEN '.$target_right.' AND '.($node_left-1).' ' + . 'THEN '.$this->f_left.'+'.($node_right-$node_left+1).' ' + . 'WHEN '.$this->f_left.' BETWEEN '.$node_left.' AND '.$node_right.' ' + . 'THEN '.$this->f_left.'-('.($node_left-$target_right).') ' + . 'ELSE '.$this->f_left .' ' + . 'END, ' + . $this->f_right.' = CASE ' + . 'WHEN '.$this->f_right.' BETWEEN '.$target_right.' AND '.$node_left.' ' + . 'THEN '.$this->f_right.'+'.($node_right-$node_left+1).' ' + . 'WHEN '.$this->f_right.' BETWEEN '.$node_left.' AND '.$node_right.' ' + . 'THEN '.$this->f_right.'-('.($node_left-$target_right).') ' + . 'ELSE '.$this->f_right.' ' + . 'END ' + . 'WHERE ('.$this->f_left.' BETWEEN '.$target_left.' AND '.$node_right. ' ' + . 'OR '.$this->f_right.' BETWEEN '.$target_left.' AND '.$node_right.')'; + } + else + { + $sql = 'UPDATE '.$this->table.' SET ' + . $this->f_left.' = CASE ' + . 'WHEN '.$this->f_left.' BETWEEN '.$node_right.' AND '.$target_right.' ' + . 'THEN '.$this->f_left.'-'.($node_right-$node_left+1).' ' + . 'WHEN '.$this->f_left.' BETWEEN '.$node_left.' AND '.$node_right.' ' + . 'THEN '.$this->f_left.'+'.($target_right-1-$node_right).' ' + . 'ELSE '.$this->f_left.' ' + . 'END, ' + . $this->f_right.' = CASE ' + . 'WHEN '.$this->f_right.' BETWEEN '.($node_right+1).' AND '.($target_right-1).' ' + . 'THEN '.$this->f_right.'-'.($node_right-$node_left+1).' ' + . 'WHEN '.$this->f_right.' BETWEEN '.$node_left.' AND '.$node_right.' ' + . 'THEN '.$this->f_right.'+'.($target_right-1-$node_right).' ' + . 'ELSE '.$this->f_right.' ' + . 'END ' + . 'WHERE ('.$this->f_left.' BETWEEN '.$node_left.' AND '.$target_right.' ' + . 'OR '.$this->f_right.' BETWEEN '.$node_left.' AND '.$target_right.')'; + } + + $sql .= ' '.$this->getCondition(); + + $this->con->execute($sql); + } + + public function setNodePosition($nodeA,$nodeB,$position='after') + { + $nodeA = (integer) $nodeA; + $nodeB = (integer) $nodeB; + + $rs = $this->getChildren(0,$nodeA); + if ($rs->isEmpty()) { + throw new Exception('Node does not exist.'); + } + $A_left = $rs->{$this->f_left}; + $A_right = $rs->{$this->f_right}; + $A_level = $rs->level; + + $rs = $this->getChildren(0,$nodeB); + if ($rs->isEmpty()) { + throw new Exception('Node does not exist.'); + } + $B_left = $rs->{$this->f_left}; + $B_right = $rs->{$this->f_right}; + $B_level = $rs->level; + + if ($A_level != $B_level) { + throw new Exception('Cannot change position'); + } + + $rs = $this->getParents($nodeA); + $parentA = $rs->isEmpty() ? 0 : $rs->{$this->f_id}; + $rs = $this->getParents($nodeB); + $parentB = $rs->isEmpty() ? 0 : $rs->{$this->f_id}; + + if ($parentA != $parentB) { + throw new Exception('Cannot change position'); + } + + if ($position == 'before') + { + if ($A_left > $B_left) { + $sql = 'UPDATE '.$this->table.' SET ' + . $this->f_right.' = CASE WHEN '.$this->f_left.' BETWEEN '.$A_left.' AND '.$A_right.' THEN '.$this->f_right.' - ('.($A_left - $B_left).') ' + . 'WHEN '.$this->f_left.' BETWEEN '.$B_left.' AND '.($A_left - 1).' THEN '.$this->f_right.' + '.($A_right - $A_left + 1).' ELSE '.$this->f_right.' END, ' + . $this->f_left.' = CASE WHEN '.$this->f_left.' BETWEEN '.$A_left.' AND '.$A_right.' THEN '.$this->f_left.' - ('.($A_left - $B_left).') ' + . 'WHEN '.$this->f_left.' BETWEEN '.$B_left.' AND '.($A_left - 1).' THEN '.$this->f_left.' + '.($A_right - $A_left + 1).' ELSE '.$this->f_left.' END ' + . 'WHERE '.$this->f_left.' BETWEEN '.$B_left.' AND '.$A_right; + } else { + $sql = 'UPDATE '.$this->table.' SET ' + . $this->f_right.' = CASE WHEN '.$this->f_left.' BETWEEN '.$A_left.' AND '.$A_right.' THEN '.$this->f_right.' + '.(($B_left - $A_left) - ($A_right - $A_left + 1)).' ' + . 'WHEN '.$this->f_left.' BETWEEN '.($A_right + 1).' AND '.($B_left - 1).' THEN '.$this->f_right.' - ('.(($A_right - $A_left + 1)).') ELSE '.$this->f_right.' END, ' + . $this->f_left.' = CASE WHEN '.$this->f_left.' BETWEEN '.$A_left.' AND '.$A_right.' THEN '.$this->f_left.' + '.(($B_left - $A_left) - ($A_right - $A_left + 1)).' ' + . 'WHEN '.$this->f_left.' BETWEEN '.($A_right + 1).' AND '.($B_left - 1).' THEN '.$this->f_left.' - ('.($A_right - $A_left + 1).') ELSE '.$this->f_left.' END ' + . 'WHERE '.$this->f_left.' BETWEEN '.$A_left.' AND '.($B_left - 1); + } + } + else + { + if ($A_left > $B_left) { + $sql = 'UPDATE '.$this->table.' SET ' + . $this->f_right.' = CASE WHEN '.$this->f_left.' BETWEEN '.$A_left.' AND '.$A_right.' THEN '.$this->f_right.' - ('.($A_left - $B_left - ($B_right - $B_left + 1)).') ' + . 'WHEN '.$this->f_left.' BETWEEN '.($B_right + 1).' AND '.($A_left - 1).' THEN '.$this->f_right.' + '.($A_right - $A_left + 1).' ELSE '.$this->f_right.' END, ' + . $this->f_left.' = CASE WHEN '.$this->f_left.' BETWEEN '.$A_left.' AND '.$A_right.' THEN '.$this->f_left.' - ('.($A_left - $B_left - ($B_right - $B_left + 1)).') ' + . 'WHEN '.$this->f_left.' BETWEEN '.($B_right + 1).' AND '.($A_left - 1).' THEN '.$this->f_left.' + '.($A_right - $A_left + 1).' ELSE '.$this->f_left.' END ' + . 'WHERE '.$this->f_left.' BETWEEN '.($B_right + 1).' AND '.$A_right; + } else { + $sql = 'UPDATE '.$this->table.' SET ' + . $this->f_right.' = CASE WHEN '.$this->f_left.' BETWEEN '.$A_left.' AND '.$A_right.' THEN '.$this->f_right.' + '.($B_right - $A_right).' ' + . 'WHEN '.$this->f_left.' BETWEEN '.($A_right + 1).' AND '.$B_right.' THEN '.$this->f_right.' - ('.(($A_right - $A_left + 1)).') ELSE '.$this->f_right.' END, ' + . $this->f_left.' = CASE WHEN '.$this->f_left.' BETWEEN '.$A_left.' AND '.$A_right.' THEN '.$this->f_left.' + '.($B_right - $A_right).' ' + . 'WHEN '.$this->f_left.' BETWEEN '.($A_right + 1).' AND '.$B_right.' THEN '.$this->f_left.' - ('.($A_right - $A_left + 1).') ELSE '.$this->f_left.' END ' + . 'WHERE '.$this->f_left.' BETWEEN '.$A_left.' AND '.$B_right; + } + } + + $sql .= $this->getCondition(); + $this->con->execute($sql); + } + + protected function getCondition($start='AND',$prefix='') + { + if (empty($this->add_condition)) { + return ''; + } + + $w = array(); + foreach ($this->add_condition as $c => $n) { + $w[] = $prefix.$c.' = '.$n; + } + return ' '.$start.' '.implode(' AND ',$w).' '; + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/core/class.dc.core.php b/v2/dotclear/inc/core/class.dc.core.php new file mode 100644 index 0000000..d7d5acf --- /dev/null +++ b/v2/dotclear/inc/core/class.dc.core.php @@ -0,0 +1,1467 @@ +connection
        Database connection object + public $prefix; ///< string Database tables prefix + public $blog; ///< dcBlog dcBlog object + public $error; ///< dcError dcError object + public $auth; ///< dcAuth dcAuth object + public $session; ///< sessionDB sessionDB object + public $url; ///< urlHandler urlHandler object + public $wiki2xhtml; ///< wiki2xhtml wiki2xhtml object + public $plugins; ///< dcModules dcModules object + public $media; ///< dcMedia dcMedia object + public $postmedia; ///< dcPostMedia dcPostMedia object + public $rest; ///< dcRestServer dcRestServer object + public $log; ///< dcLog dcLog object + + private $versions = null; + private $formaters = array(); + private $behaviors = array(); + private $post_types = array(); + + /** + dcCore constructor inits everything related to Dotclear. It takes arguments + to init database connection. + + @param driver string Database driver name + @param host string Database hostname + @param db string Database name + @param user string Database username + @param password string Database password + @param prefix string DotClear tables prefix + @param persist boolean Persistent database connection + */ + public function __construct($driver, $host, $db, $user, $password, $prefix, $persist) + { + $this->con = dbLayer::init($driver,$host,$db,$user,$password,$persist); + + # define weak_locks for mysql + if ($this->con instanceof mysqlConnection) { + mysqlConnection::$weak_locks = true; + } + + # define searchpath for postgresql + if ($this->con instanceof pgsqlConnection) + { + $searchpath = explode ('.',$prefix,2); + if (count($searchpath) > 1) + { + $prefix = $searchpath[1]; + $sql = 'SET search_path TO '.$searchpath[0].',public;'; + $this->con->execute($sql); + } + } + + $this->prefix = $prefix; + + $this->error = new dcError(); + $this->auth = $this->authInstance(); + $this->session = new sessionDB($this->con,$this->prefix.'session',DC_SESSION_NAME,'',null,DC_ADMIN_SSL); + $this->url = new dcUrlHandlers(); + + $this->plugins = new dcModules($this); + + $this->rest = new dcRestServer($this); + + $this->meta = new dcMeta($this); + + $this->log = new dcLog($this); + + $this->addFormater('xhtml', create_function('$s','return $s;')); + $this->addFormater('wiki', array($this,'wikiTransform')); + } + + private function authInstance() + { + # You can set DC_AUTH_CLASS to whatever you want. + # Your new class *should* inherits dcAuth. + if (!defined('DC_AUTH_CLASS')) { + $c = 'dcAuth'; + } else { + $c = DC_AUTH_CLASS; + } + + if (!class_exists($c)) { + throw new Exception('Authentication class '.$c.' does not exist.'); + } + + if ($c != 'dcAuth' && !is_subclass_of($c,'dcAuth')) { + throw new Exception('Authentication class '.$c.' does not inherit dcAuth.'); + } + + return new $c($this); + } + + + /// @name Blog init methods + //@{ + /** + Sets a blog to use in blog property. + + @param id string Blog ID + */ + public function setBlog($id) + { + $this->blog = new dcBlog($this, $id); + } + + /** + Unsets blog property. + */ + public function unsetBlog() + { + $this->blog = null; + } + //@} + + + /// @name Blog status methods + //@{ + /** + Returns an array of available blog status codes and names. + + @return array Simple array with codes in keys and names in value + */ + public function getAllBlogStatus() + { + return array( + 1 => __('online'), + 0 => __('offline'), + -1 => __('removed') + ); + } + + /** + Returns a blog status name given to a code. This is intended to be + human-readable and will be translated, so never use it for tests. + If status code does not exist, returns offline. + + @param s integer Status code + @return string Blog status name + */ + public function getBlogStatus($s) + { + $r = $this->getAllBlogStatus(); + if (isset($r[$s])) { + return $r[$s]; + } + return $r[0]; + } + //@} + + /// @name Admin nonce secret methods + //@{ + + public function getNonce() + { + return crypt::hmac(DC_MASTER_KEY,session_id()); + } + + public function checkNonce($secret) + { + if (!preg_match('/^([0-9a-f]{40,})$/i',$secret)) { + return false; + } + + return $secret == crypt::hmac(DC_MASTER_KEY,session_id()); + } + + public function formNonce() + { + if (!session_id()) { + return; + } + + return form::hidden(array('xd_check'),$this->getNonce()); + } + //@} + + + /// @name Text Formatters methods + //@{ + /** + Adds a new text formater which will call the function $func to + transform text. The function must be a valid callback and takes one + argument: the string to transform. It returns the transformed string. + + @param name string Formater name + @param func callback Function to use, must be a valid and callable callback + */ + public function addFormater($name,$func) + { + if (is_callable($func)) { + $this->formaters[$name] = $func; + } + } + + /** + Returns formaters list. + + @return array An array of formaters names in values. + */ + public function getFormaters() + { + return array_keys($this->formaters); + } + + /** + If $name is a valid formater, it returns $str + transformed using that formater. + + @param name string Formater name + @param str string String to transform + @return string String transformed + */ + public function callFormater($name,$str) + { + if (isset($this->formaters[$name])) { + return call_user_func($this->formaters[$name],$str); + } + + return $str; + } + //@} + + + /// @name Behaviors methods + //@{ + /** + Adds a new behavior to behaviors stack. $func must be a valid + and callable callback. + + @param behavior string Behavior name + @param func callback Function to call + */ + public function addBehavior($behavior,$func) + { + if (is_callable($func)) { + $this->behaviors[$behavior][] = $func; + } + } + + /** + Tests if a particular behavior exists in behaviors stack. + + @param behavior string Behavior name + @return boolean + */ + public function hasBehavior($behavior) + { + return isset($this->behaviors[$behavior]); + } + + /** + Get behaviors stack (or part of). + + @param behavior string Behavior name + @return array + */ + public function getBehaviors($behavior='') + { + if (empty($this->behaviors)) return null; + + if ($behavior == '') { + return $this->behaviors; + } elseif (isset($this->behaviors[$behavior])) { + return $this->behaviors[$behavior]; + } + + return array(); + } + + /** + Calls every function in behaviors stack for a given behavior and returns + concatened result of each function. + + Every parameters added after $behavior will be pass to + behavior calls. + + @param behavior string Behavior name + @return string Behavior concatened result + */ + public function callBehavior($behavior) + { + if (isset($this->behaviors[$behavior])) + { + $args = func_get_args(); + array_shift($args); + + $res = ''; + + foreach ($this->behaviors[$behavior] as $f) { + $res .= call_user_func_array($f,$args); + } + + return $res; + } + } + //@} + + /// @name Post types URLs management + //@{ + public function getPostAdminURL($type,$post_id,$escaped=true) + { + if (!isset($this->post_types[$type])) { + $type = 'post'; + } + + $url = sprintf($this->post_types[$type]['admin_url'],$post_id); + return $escaped ? html::escapeURL($url) : $url; + } + + public function getPostPublicURL($type,$post_url,$escaped=true) + { + if (!isset($this->post_types[$type])) { + $type = 'post'; + } + + $url = sprintf($this->post_types[$type]['public_url'],$post_url); + return $escaped ? html::escapeURL($url) : $url; + } + + public function setPostType($type,$admin_url,$public_url) + { + $this->post_types[$type] = array( + 'admin_url' => $admin_url, + 'public_url' => $public_url + ); + } + + public function getPostTypes() + { + return $this->post_types; + } + //@} + + /// @name Versions management methods + //@{ + /** + Returns a given $module version. + + @param module string Module name + @return string Module version + */ + public function getVersion($module='core') + { + # Fetch versions if needed + if (!is_array($this->versions)) + { + $strReq = 'SELECT module, version FROM '.$this->prefix.'version'; + $rs = $this->con->select($strReq); + + while ($rs->fetch()) { + $this->versions[$rs->module] = $rs->version; + } + } + + if (isset($this->versions[$module])) { + return $this->versions[$module]; + } else { + return null; + } + } + + /** + Sets $version to given $module. + + @param module string Module name + @param version string Module version + */ + public function setVersion($module,$version) + { + $cur_version = $this->getVersion($module); + + $cur = $this->con->openCursor($this->prefix.'version'); + $cur->module = (string) $module; + $cur->version = (string) $version; + + if ($cur_version === null) { + $cur->insert(); + } else { + $cur->update("WHERE module='".$this->con->escape($module)."'"); + } + + $this->versions[$module] = $version; + } + + /** + Removes given $module version entry. + + @param module string Module name + */ + public function delVersion($module) + { + $strReq = + 'DELETE FROM '.$this->prefix.'version '. + "WHERE module = '".$this->con->escape($module)."' "; + + $this->con->execute($strReq); + + if (is_array($this->versions)) { + unset($this->versions[$module]); + } + } + + //@} + + /// @name Users management methods + //@{ + /** + Returns a user by its ID. + + @param id string User ID + @return record + */ + public function getUser($id) + { + $params['user_id'] = $id; + + return $this->getUsers($params); + } + + /** + Returns a users list. $params is an array with the following + optionnal parameters: + + - q: search string (on user_id, user_name, user_firstname) + - user_id: user ID + - order: ORDER BY clause (default: user_id ASC) + - limit: LIMIT clause (should be an array ![limit,offset]) + + @param params array Parameters + @param count_only boolean Only counts results + @return record + */ + public function getUsers($params=array(),$count_only=false) + { + if ($count_only) + { + $strReq = + 'SELECT count(U.user_id) '. + 'FROM '.$this->prefix.'user U '. + 'WHERE NULL IS NULL '; + } + else + { + $strReq = + 'SELECT U.user_id,user_super,user_status,user_pwd,user_change_pwd,'. + 'user_name,user_firstname,user_displayname,user_email,user_url,'. + 'user_desc, user_lang,user_tz, user_post_status,user_options, '. + 'count(P.post_id) AS nb_post '. + 'FROM '.$this->prefix.'user U '. + 'LEFT JOIN '.$this->prefix.'post P ON U.user_id = P.user_id '. + 'WHERE NULL IS NULL '; + } + + if (!empty($params['q'])) { + $q = $this->con->escape(str_replace('*','%',strtolower($params['q']))); + $strReq .= 'AND ('. + "LOWER(U.user_id) LIKE '".$q."' ". + "OR LOWER(user_name) LIKE '".$q."' ". + "OR LOWER(user_firstname) LIKE '".$q."' ". + ') '; + } + + if (!empty($params['user_id'])) { + $strReq .= "AND U.user_id = '".$this->con->escape($params['user_id'])."' "; + } + + if (!$count_only) { + $strReq .= 'GROUP BY U.user_id,user_super,user_status,user_pwd,user_change_pwd,'. + 'user_name,user_firstname,user_displayname,user_email,user_url,'. + 'user_desc, user_lang,user_tz,user_post_status,user_options '; + + if (!empty($params['order']) && !$count_only) { + $strReq .= 'ORDER BY '.$this->con->escape($params['order']).' '; + } else { + $strReq .= 'ORDER BY U.user_id ASC '; + } + } + + if (!$count_only && !empty($params['limit'])) { + $strReq .= $this->con->limit($params['limit']); + } + + $rs = $this->con->select($strReq); + $rs->extend('rsExtUser'); + return $rs; + } + + /** + Create a new user. Takes a cursor as input and returns the new user ID. + + @param cur cursor User cursor + @return string + */ + public function addUser($cur) + { + if (!$this->auth->isSuperAdmin()) { + throw new Exception(__('You are not an administrator')); + } + + if ($cur->user_id == '') { + throw new Exception(__('No user ID given')); + } + + if ($cur->user_pwd == '') { + throw new Exception(__('No password given')); + } + + $this->getUserCursor($cur); + + if ($cur->user_creadt === null) { + $cur->user_creadt = date('Y-m-d H:i:s'); + } + + $cur->insert(); + + $this->auth->afterAddUser($cur); + + return $cur->user_id; + } + + /** + Updates an existing user. Returns the user ID. + + @param id string User ID + @param cur cursor User cursor + @return string + */ + public function updUser($id,$cur) + { + $this->getUserCursor($cur); + + if (($cur->user_id !== null || $id != $this->auth->userID()) && + !$this->auth->isSuperAdmin()) { + throw new Exception(__('You are not an administrator')); + } + + $cur->update("WHERE user_id = '".$this->con->escape($id)."' "); + + $this->auth->afterUpdUser($id,$cur); + + if ($cur->user_id !== null) { + $id = $cur->user_id; + } + + # Updating all user's blogs + $rs = $this->con->select( + 'SELECT DISTINCT(blog_id) FROM '.$this->prefix.'post '. + "WHERE user_id = '".$this->con->escape($id)."' " + ); + + while ($rs->fetch()) { + $b = new dcBlog($this,$rs->blog_id); + $b->triggerBlog(); + unset($b); + } + + return $id; + } + + /** + Deletes a user. + + @param id string User ID + */ + public function delUser($id) + { + if (!$this->auth->isSuperAdmin()) { + throw new Exception(__('You are not an administrator')); + } + + if ($id == $this->auth->userID()) { + return; + } + + $rs = $this->getUser($id); + + if ($rs->nb_post > 0) { + return; + } + + $strReq = 'DELETE FROM '.$this->prefix.'user '. + "WHERE user_id = '".$this->con->escape($id)."' "; + + $this->con->execute($strReq); + + $this->auth->afterDelUser($id); + } + + /** + Checks whether a user exists. + + @param id string User ID + @return boolean + */ + public function userExists($id) + { + $strReq = 'SELECT user_id '. + 'FROM '.$this->prefix.'user '. + "WHERE user_id = '".$this->con->escape($id)."' "; + + $rs = $this->con->select($strReq); + + return !$rs->isEmpty(); + } + + /** + Returns all user permissions as an array which looks like: + + - [blog_id] + - [name] => Blog name + - [url] => Blog URL + - [p] + - [permission] => true + - ... + + @param id string User ID + @return array + */ + public function getUserPermissions($id) + { + $strReq = 'SELECT B.blog_id, blog_name, blog_url, permissions '. + 'FROM '.$this->prefix.'permissions P '. + 'INNER JOIN '.$this->prefix.'blog B ON P.blog_id = B.blog_id '. + "WHERE user_id = '".$this->con->escape($id)."' "; + + $rs = $this->con->select($strReq); + + $res = array(); + + while ($rs->fetch()) + { + $res[$rs->blog_id] = array( + 'name' => $rs->blog_name, + 'url' => $rs->blog_url, + 'p' => $this->auth->parsePermissions($rs->permissions) + ); + } + + return $res; + } + + /** + Sets user permissions. The $perms array looks like: + + - [blog_id] => '|perm1|perm2|' + - ... + + @param id string User ID + @param perms array Permissions array + */ + public function setUserPermissions($id,$perms) + { + if (!$this->auth->isSuperAdmin()) { + throw new Exception(__('You are not an administrator')); + } + + $strReq = 'DELETE FROM '.$this->prefix.'permissions '. + "WHERE user_id = '".$this->con->escape($id)."' "; + + $this->con->execute($strReq); + + foreach ($perms as $blog_id => $p) { + $this->setUserBlogPermissions($id, $blog_id, $p, false); + } + } + + /** + Sets user permissions for a given blog. $perms is an array with + permissions in values + + @param id string User ID + @param blog_id string Blog ID + @param perms array Permissions + @param delete_first boolean Delete permissions before + */ + public function setUserBlogPermissions($id, $blog_id, $perms, $delete_first=true) + { + if (!$this->auth->isSuperAdmin()) { + throw new Exception(__('You are not an administrator')); + } + + $no_perm = empty($perms); + + $perms = '|'.implode('|',array_keys($perms)).'|'; + + $cur = $this->con->openCursor($this->prefix.'permissions'); + + $cur->user_id = (string) $id; + $cur->blog_id = (string) $blog_id; + $cur->permissions = $perms; + + if ($delete_first || $no_perm) + { + $strReq = 'DELETE FROM '.$this->prefix.'permissions '. + "WHERE blog_id = '".$this->con->escape($blog_id)."' ". + "AND user_id = '".$this->con->escape($id)."' "; + + $this->con->execute($strReq); + } + + if (!$no_perm) { + $cur->insert(); + } + } + + /** + Sets a user default blog. This blog will be selected when user log in. + + @param id string User ID + @param blog_id string Blog ID + */ + public function setUserDefaultBlog($id, $blog_id) + { + $cur = $this->con->openCursor($this->prefix.'user'); + + $cur->user_default_blog = (string) $blog_id; + + $cur->update("WHERE user_id = '".$this->con->escape($id)."'"); + } + + private function getUserCursor($cur) + { + if ($cur->isField('user_id') + && !preg_match('/^[A-Za-z0-9@._-]{2,}$/',$cur->user_id)) { + throw new Exception(__('User ID must contain at least 2 characters using letters, numbers or symbols.')); + } + + if ($cur->user_url !== null && $cur->user_url != '') { + if (!preg_match('|^http(s?)://|',$cur->user_url)) { + $cur->user_url = 'http://'.$cur->user_url; + } + } + + if ($cur->isField('user_pwd')) { + if (strlen($cur->user_pwd) < 6) { + throw new Exception(__('Password must contain at least 6 characters.')); + } + $cur->user_pwd = crypt::hmac(DC_MASTER_KEY,$cur->user_pwd); + } + + if ($cur->user_lang !== null && !preg_match('/^[a-z]{2}(-[a-z]{2})?$/',$cur->user_lang)) { + throw new Exception(__('Invalid user language code')); + } + + if ($cur->user_upddt === null) { + $cur->user_upddt = date('Y-m-d H:i:s'); + } + + if ($cur->user_options !== null) { + $cur->user_options = serialize((array) $cur->user_options); + } + } + + /** + Returns user default settings in an associative array with setting names in + keys. + + @return array + */ + public function userDefaults() + { + return array( + 'edit_size' => 24, + 'enable_wysiwyg' => true, + 'post_format' => 'wiki' + ); + } + //@} + + /// @name Blog management methods + //@{ + /** + Returns all blog permissions (users) as an array which looks like: + + - [user_id] + - [name] => User name + - [firstname] => User firstname + - [displayname] => User displayname + - [super] => (true|false) super admin + - [p] + - [permission] => true + - ... + + @param id string Blog ID + @param with_super boolean Includes super admins in result + @return array + */ + public function getBlogPermissions($id,$with_super=true) + { + $strReq = + 'SELECT U.user_id AS user_id, user_super, user_name, user_firstname, '. + 'user_displayname, permissions '. + 'FROM '.$this->prefix.'user U '. + 'JOIN '.$this->prefix.'permissions P ON U.user_id = P.user_id '. + "WHERE blog_id = '".$this->con->escape($id)."' "; + + if ($with_super) { + $strReq .= + 'UNION '. + 'SELECT U.user_id AS user_id, user_super, user_name, user_firstname, '. + "user_displayname, NULL AS permissions ". + 'FROM '.$this->prefix.'user U '. + 'WHERE user_super = 1 '; + } + + $rs = $this->con->select($strReq); + + $res = array(); + + while ($rs->fetch()) + { + $res[$rs->user_id] = array( + 'name' => $rs->user_name, + 'firstname' => $rs->user_firstname, + 'displayname' => $rs->user_displayname, + 'super' => (boolean) $rs->user_super, + 'p' => $this->auth->parsePermissions($rs->permissions) + ); + } + + return $res; + } + + /** + Returns a blog of given ID. + + @param id string Blog ID + @return record + */ + public function getBlog($id) + { + $blog = $this->getBlogs(array('blog_id'=>$id)); + + if ($blog->isEmpty()) { + return false; + } + + return $blog; + } + + /** + Returns a record of blogs. $params is an array with the following + optionnal parameters: + + - blog_id: Blog ID + - q: Search string on blog_id, blog_name and blog_url + - limit: limit results + + @param params array Parameters + @param count_only boolean Count only results + @return record + */ + public function getBlogs($params=array(),$count_only=false) + { + $join = ''; // %1$s + $where = ''; // %2$s + + if ($count_only) + { + $strReq = 'SELECT count(B.blog_id) '. + 'FROM '.$this->prefix.'blog B '. + '%1$s '. + 'WHERE NULL IS NULL '. + '%2$s '; + } + else + { + $strReq = + 'SELECT B.blog_id, blog_uid, blog_url, blog_name, blog_desc, blog_creadt, '. + 'blog_upddt, blog_status '. + 'FROM '.$this->prefix.'blog B '. + '%1$s '. + 'WHERE NULL IS NULL '. + '%2$s '; + + if (!empty($params['order'])) { + $strReq .= 'ORDER BY '.$this->con->escape($params['order']).' '; + } else { + $strReq .= 'ORDER BY B.blog_id ASC '; + } + + if (!empty($params['limit'])) { + $strReq .= $this->con->limit($params['limit']); + } + } + + if ($this->auth->userID() && !$this->auth->isSuperAdmin()) + { + $join = 'INNER JOIN '.$this->prefix.'permissions PE ON B.blog_id = PE.blog_id '; + $where = + "AND PE.user_id = '".$this->con->escape($this->auth->userID())."' ". + "AND (permissions LIKE '%|usage|%' OR permissions LIKE '%|admin|%' OR permissions LIKE '%|contentadmin|%') ". + "AND blog_status IN (1,0) "; + } elseif (!$this->auth->userID()) { + $where = 'AND blog_status IN (1,0) '; + } + + if (!empty($params['blog_id'])) { + $where .= "AND B.blog_id = '".$this->con->escape($params['blog_id'])."' "; + } + + if (!empty($params['q'])) { + $params['q'] = str_replace('*','%',$params['q']); + $where .= + 'AND ('. + "LOWER(B.blog_id) LIKE '".$this->con->escape($params['q'])."' ". + "OR LOWER(B.blog_name) LIKE '".$this->con->escape($params['q'])."' ". + "OR LOWER(B.blog_url) LIKE '".$this->con->escape($params['q'])."' ". + ') '; + } + + $strReq = sprintf($strReq,$join,$where); + return $this->con->select($strReq); + } + + /** + Creates a new blog. + + @param cur cursor Blog cursor + */ + public function addBlog($cur) + { + if (!$this->auth->isSuperAdmin()) { + throw new Exception(__('You are not an administrator')); + } + + $this->getBlogCursor($cur); + + $cur->blog_creadt = date('Y-m-d H:i:s'); + $cur->blog_upddt = date('Y-m-d H:i:s'); + $cur->blog_uid = md5(uniqid()); + + $cur->insert(); + } + + /** + Updates a given blog. + + @param id string Blog ID + @param cur cursor Blog cursor + */ + public function updBlog($id,$cur) + { + $this->getBlogCursor($cur); + + $cur->blog_upddt = date('Y-m-d H:i:s'); + + $cur->update("WHERE blog_id = '".$this->con->escape($id)."'"); + } + + private function getBlogCursor($cur) + { + if ($cur->blog_id !== null + && !preg_match('/^[A-Za-z0-9._-]{2,}$/',$cur->blog_id)) { + throw new Exception(__('Blog ID must contain at least 2 characters using letters, numbers or symbols.')); + } + + if ($cur->blog_name !== null && $cur->blog_name == '') { + throw new Exception(__('No blog name')); + } + + if ($cur->blog_url !== null && $cur->blog_url == '') { + throw new Exception(__('No blog URL')); + } + + if ($cur->blog_desc !== null) { + $cur->blog_desc = html::clean($cur->blog_desc); + } + } + + /** + Removes a given blog. + @warning This will remove everything related to the blog (posts, + categories, comments, links...) + + @param id string Blog ID + */ + public function delBlog($id) + { + if (!$this->auth->isSuperAdmin()) { + throw new Exception(__('You are not an administrator')); + } + + $strReq = 'DELETE FROM '.$this->prefix.'blog '. + "WHERE blog_id = '".$this->con->escape($id)."' "; + + $this->con->execute($strReq); + } + + /** + Checks if a blog exist. + + @param id string Blog ID + @return boolean + */ + public function blogExists($id) + { + $strReq = 'SELECT blog_id '. + 'FROM '.$this->prefix.'blog '. + "WHERE blog_id = '".$this->con->escape($id)."' "; + + $rs = $this->con->select($strReq); + + return !$rs->isEmpty(); + } + + /** + Count posts on a blog + + @param id string Blog ID + @param type string Post type + @return boolean + */ + public function countBlogPosts($id,$type=null) + { + $strReq = 'SELECT COUNT(post_id) '. + 'FROM '.$this->prefix.'post '. + "WHERE blog_id = '".$this->con->escape($id)."' "; + + if ($type) { + $strReq .= "AND post_type = '".$this->con->escape($type)."' "; + } + + return $this->con->select($strReq)->f(0); + } + //@} + + /// @name HTML Filter methods + //@{ + /** + Calls HTML filter to drop bad tags and produce valid XHTML output (if + tidy extension is present). If enable_html_filter blog setting is + false, returns not filtered string. + + @param str string String to filter + @return string Filtered string. + */ + public function HTMLfilter($str) + { + if ($this->blog instanceof dcBlog && !$this->blog->settings->system->enable_html_filter) { + return $str; + } + + $filter = new htmlFilter; + $str = trim($filter->apply($str)); + return $str; + } + //@} + + /// @name wiki2xhtml methods + //@{ + private function initWiki() + { + $this->wiki2xhtml = new wiki2xhtml; + } + + /** + Returns a transformed string with wiki2xhtml. + + @param str string String to transform + @return string Transformed string + */ + public function wikiTransform($str) + { + if (!($this->wiki2xhtml instanceof wiki2xhtml)) { + $this->initWiki(); + } + return $this->wiki2xhtml->transform($str); + } + + /** + Inits wiki2xhtml property for blog post. + */ + public function initWikiPost() + { + $this->initWiki(); + + $this->wiki2xhtml->setOpts(array( + 'active_title' => 1, + 'active_setext_title' => 0, + 'active_hr' => 1, + 'active_lists' => 1, + 'active_quote' => 1, + 'active_pre' => 1, + 'active_empty' => 1, + 'active_auto_br' => 0, + 'active_auto_urls' => 0, + 'active_urls' => 1, + 'active_auto_img' => 0, + 'active_img' => 1, + 'active_anchor' => 1, + 'active_em' => 1, + 'active_strong' => 1, + 'active_br' => 1, + 'active_q' => 1, + 'active_code' => 1, + 'active_acronym' => 1, + 'active_ins' => 1, + 'active_del' => 1, + 'active_footnotes' => 1, + 'active_wikiwords' => 0, + 'active_macros' => 1, + 'parse_pre' => 1, + 'active_fr_syntax' => 0, + 'first_title_level' => 3, + 'note_prefix' => 'wiki-footnote', + 'note_str' => '

        Notes

        %s
        ' + )); + + $this->wiki2xhtml->registerFunction('url:post',array($this,'wikiPostLink')); + + # --BEHAVIOR-- coreWikiPostInit + $this->callBehavior('coreInitWikiPost',$this->wiki2xhtml); + } + + /** + Inits wiki2xhtml property for simple blog comment (basic syntax). + */ + public function initWikiSimpleComment() + { + $this->initWiki(); + + $this->wiki2xhtml->setOpts(array( + 'active_title' => 0, + 'active_setext_title' => 0, + 'active_hr' => 0, + 'active_lists' => 0, + 'active_quote' => 0, + 'active_pre' => 0, + 'active_empty' => 0, + 'active_auto_br' => 1, + 'active_auto_urls' => 1, + 'active_urls' => 0, + 'active_auto_img' => 0, + 'active_img' => 0, + 'active_anchor' => 0, + 'active_em' => 0, + 'active_strong' => 0, + 'active_br' => 0, + 'active_q' => 0, + 'active_code' => 0, + 'active_acronym' => 0, + 'active_ins' => 0, + 'active_del' => 0, + 'active_footnotes' => 0, + 'active_wikiwords' => 0, + 'active_macros' => 0, + 'parse_pre' => 0, + 'active_fr_syntax' => 0 + )); + + # --BEHAVIOR-- coreInitWikiSimpleComment + $this->callBehavior('coreInitWikiSimpleComment',$this->wiki2xhtml); + } + + /** + Inits wiki2xhtml property for blog comment. + */ + public function initWikiComment() + { + $this->initWiki(); + + $this->wiki2xhtml->setOpts(array( + 'active_title' => 0, + 'active_setext_title' => 0, + 'active_hr' => 0, + 'active_lists' => 1, + 'active_quote' => 0, + 'active_pre' => 1, + 'active_empty' => 0, + 'active_auto_br' => 1, + 'active_auto_urls' => 1, + 'active_urls' => 1, + 'active_auto_img' => 0, + 'active_img' => 0, + 'active_anchor' => 0, + 'active_em' => 1, + 'active_strong' => 1, + 'active_br' => 1, + 'active_q' => 1, + 'active_code' => 1, + 'active_acronym' => 1, + 'active_ins' => 1, + 'active_del' => 1, + 'active_footnotes' => 0, + 'active_wikiwords' => 0, + 'active_macros' => 0, + 'parse_pre' => 0, + 'active_fr_syntax' => 0 + )); + + # --BEHAVIOR-- coreInitWikiComment + $this->callBehavior('coreInitWikiComment',$this->wiki2xhtml); + } + + public function wikiPostLink($url,$content) + { + if (!($this->blog instanceof dcBlog)) { + return array(); + } + + $post_id = abs((integer) substr($url,5)); + if (!$post_id) { + return array(); + } + + $post = $this->blog->getPosts(array('post_id'=>$post_id)); + if ($post->isEmpty()) { + return array(); + } + + $res = array('url' => $post->getURL()); + $post_title = $post->post_title; + + if ($content != $url) { + $res['title'] = html::escapeHTML($post->post_title); + } + + if ($content == '' || $content == $url) { + $res['content'] = html::escapeHTML($post->post_title); + } + + if ($post->post_lang) { + $res['lang'] = $post->post_lang; + } + + return $res; + } + //@} + + /// @name Maintenance methods + //@{ + /** + Creates default settings for active blog. Optionnal parameter + defaults replaces default params while needed. + + @param defaults array Default parameters + */ + public function blogDefaults($defaults=null) + { + if (!is_array($defaults)) + { + $defaults = array( + array('allow_comments','boolean',true, + 'Allow comments on blog'), + array('allow_trackbacks','boolean',true, + 'Allow trackbacks on blog'), + array('blog_timezone','string','Europe/London', + 'Blog timezone'), + array('comments_nofollow','boolean',true, + 'Add rel="nofollow" to comments URLs'), + array('comments_pub','boolean',true, + 'Publish comments immediately'), + array('comments_ttl','integer',0, + 'Number of days to keep comments open (0 means no ttl)'), + array('copyright_notice','string','','Copyright notice (simple text)'), + array('date_format','string','%A, %B %e %Y', + 'Date format. See PHP strftime function for patterns'), + array('editor','string','', + 'Person responsible of the content'), + array('enable_html_filter','boolean',0, + 'Enable HTML filter'), + array('enable_xmlrpc','boolean',0, + 'Enable XML/RPC interface'), + array('lang','string','en', + 'Default blog language'), + array('media_exclusion','string','/\.php$/i', + 'File name exclusion pattern in media manager. (PCRE value)'), + array('media_img_m_size','integer',448, + 'Image medium size in media manager'), + array('media_img_s_size','integer',240, + 'Image small size in media manager'), + array('media_img_t_size','integer',100, + 'Image thumbnail size in media manager'), + array('media_img_title_pattern','string','Title ;; Date(%b %Y) ;; separator(, )', + 'Pattern to set image title when you insert it in a post'), + array('nb_post_per_page','integer',20, + 'Number of entries on home page and category pages'), + array('nb_post_per_feed','integer',20, + 'Number of entries on feeds'), + array('nb_comment_per_feed','integer',20, + 'Number of comments on feeds'), + array('post_url_format','string','{y}/{m}/{d}/{t}', + 'Post URL format. {y}: year, {m}: month, {d}: day, {id}: post id, {t}: entry title'), + array('public_path','string','public', + 'Path to public directory, begins with a / for a full system path'), + array('public_url','string','/public', + 'URL to public directory'), + array('robots_policy','string','INDEX,FOLLOW', + 'Search engines robots policy'), + array('short_feed_items','boolean',false, + 'Display short feed items'), + array('theme','string','default', + 'Blog theme'), + array('themes_path','string','themes', + 'Themes root path'), + array('themes_url','string','/themes', + 'Themes root URL'), + array('time_format','string','%H:%M', + 'Time format. See PHP strftime function for patterns'), + array('tpl_allow_php','boolean',false, + 'Allow PHP code in templates'), + array('tpl_use_cache','boolean',true, + 'Use template caching'), + array('trackbacks_pub','boolean',true, + 'Publish trackbacks immediately'), + array('trackbacks_ttl','integer',0, + 'Number of days to keep trackbacks open (0 means no ttl)'), + array('url_scan','string','query_string', + 'URL handle mode (path_info or query_string)'), + array('use_smilies','boolean',false, + 'Show smilies on entries and comments'), + array('wiki_comments','boolean',false, + 'Allow commenters to use a subset of wiki syntax') + ); + } + + $settings = new dcSettings($this,null); + $settings->addNamespace('system'); + + foreach ($defaults as $v) { + $settings->system->put($v[0],$v[2],$v[1],$v[3],false,true); + } + } + + /** + Recreates entries search engine index. + + @param start integer Start entry index + @param limit integer Number of entry to index + + @return integer $start and $limit sum + */ + public function indexAllPosts($start=null,$limit=null) + { + $strReq = 'SELECT COUNT(post_id) '. + 'FROM '.$this->prefix.'post'; + $rs = $this->con->select($strReq); + $count = $rs->f(0); + + $strReq = 'SELECT post_id, post_title, post_excerpt_xhtml, post_content_xhtml '. + 'FROM '.$this->prefix.'post '; + + if ($start !== null && $limit !== null) { + $strReq .= $this->con->limit($start,$limit); + } + + $rs = $this->con->select($strReq,true); + + $cur = $this->con->openCursor($this->prefix.'post'); + + while ($rs->fetch()) + { + $words = $rs->post_title.' '. $rs->post_excerpt_xhtml.' '. + $rs->post_content_xhtml; + + $cur->post_words = implode(' ',text::splitWords($words)); + $cur->update('WHERE post_id = '.(integer) $rs->post_id); + $cur->clean(); + } + + if ($start+$limit > $count) { + return null; + } + return $start+$limit; + } + + /** + Recreates comments search engine index. + + @param start integer Start comment index + @param limit integer Number of comments to index + + @return integer $start and $limit sum + */ + public function indexAllComments($start=null,$limit=null) + { + $strReq = 'SELECT COUNT(comment_id) '. + 'FROM '.$this->prefix.'comment'; + $rs = $this->con->select($strReq); + $count = $rs->f(0); + + $strReq = 'SELECT comment_id, comment_content '. + 'FROM '.$this->prefix.'comment '; + + if ($start !== null && $limit !== null) { + $strReq .= $this->con->limit($start,$limit); + } + + $rs = $this->con->select($strReq); + + $cur = $this->con->openCursor($this->prefix.'comment'); + + while ($rs->fetch()) + { + $cur->comment_words = implode(' ',text::splitWords($rs->comment_content)); + $cur->update('WHERE comment_id = '.(integer) $rs->comment_id); + $cur->clean(); + } + + if ($start+$limit > $count) { + return null; + } + return $start+$limit; + } + + /** + Reinits nb_comment and nb_trackback in post table. + */ + public function countAllComments() + { + + $updCommentReq = 'UPDATE '.$this->prefix.'post P '. + 'SET nb_comment = ('. + 'SELECT COUNT(C.comment_id) from '.$this->prefix.'comment C '. + 'WHERE C.post_id = P.post_id AND C.comment_trackback <> 1 '. + 'AND C.comment_status = 1 '. + ')'; + $updTrackbackReq = 'UPDATE '.$this->prefix.'post P '. + 'SET nb_trackback = ('. + 'SELECT COUNT(C.comment_id) from '.$this->prefix.'comment C '. + 'WHERE C.post_id = P.post_id AND C.comment_trackback = 1 '. + 'AND C.comment_status = 1 '. + ')'; + $this->con->execute($updCommentReq); + $this->con->execute($updTrackbackReq); + } + + /** + Empty templates cache directory + */ + public function emptyTemplatesCache() + { + if (is_dir(DC_TPL_CACHE.'/cbtpl')) { + files::deltree(DC_TPL_CACHE.'/cbtpl'); + } + } + //@} +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/core/class.dc.error.php b/v2/dotclear/inc/core/class.dc.error.php new file mode 100644 index 0000000..f72c251 --- /dev/null +++ b/v2/dotclear/inc/core/class.dc.error.php @@ -0,0 +1,133 @@ +\n%s\n"; + /** @var string HTML error item pattern */ + protected $html_item = "
      • %s
      • \n"; + + /** + * Object constructor. + */ + public function __construct() + { + $this->code = 0; + $this->msg = ''; + } + + /** + * Object string representation. Returns errors stack. + * + * @return string + */ + public function __toString() + { + $res = ''; + + foreach ($this->errors as $msg) + { + $res .= $msg."\n"; + } + + return $res; + } + + /** + * Adds an error to stack. + * + * @param string $msg Error message + */ + public function add($msg) + { + $this->flag = true; + $this->errors[] = $msg; + } + + /** + * Returns the value of flag property. True if errors stack is not empty + * + * @return boolean + */ + public function flag() + { + return $this->flag; + } + + /** + * Resets errors stack. + */ + public function reset() + { + $this->flag = false; + $this->errors = array(); + } + + /** + * Returns errors property. + * + * @return array + */ + public function getErrors() + { + return $this->errors; + } + + /** + * Sets list and item properties. + * + * @param string $list HTML errors list pattern + * @param string $item HTML error item pattern + */ + public function setHTMLFormat($list,$item) + { + $this->html_list = $list; + $this->html_item = $item; + } + + /** + * Returns errors stack as HTML. + * + * @return string + */ + public function toHTML() + { + $res = ''; + + if ($this->flag) + { + foreach ($this->errors as $msg) + { + $res .= sprintf($this->html_item,$msg); + } + + $res = sprintf($this->html_list,$res); + } + + return $res; + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/core/class.dc.log.php b/v2/dotclear/inc/core/class.dc.log.php new file mode 100644 index 0000000..9c93d09 --- /dev/null +++ b/v2/dotclear/inc/core/class.dc.log.php @@ -0,0 +1,204 @@ +dcCore
        dcCore instance + */ + public function __construct($core) + { + $this->core =& $core; + $this->prefix = $core->prefix; + } + + /** + Retrieves logs. $params is an array taking the following + optionnal parameters: + + - blog_id: Get logs belonging to given blog ID + - user_id: Get logs belonging to given user ID + - log_ip: Get logs belonging to given IP address + - log_table: Get logs belonging to given log table + - order: Order of results (default "ORDER BY log_dt DESC") + - limit: Limit parameter + + @param params array Parameters + @param count_only boolean Only counts results + @return record A record with some more capabilities + */ + public function getLogs($params = array(),$count_only = false) + { + if ($count_only) { + $f = 'COUNT(log_id)'; + } + else { + $f = + 'L.log_id, L.user_id, L.log_table, L.log_dt, '. + 'L.log_ip, L.log_msg, L.blog_id, U.user_name, '. + 'U.user_firstname, U.user_displayname, U.user_url'; + } + + $strReq = 'SELECT '.$f.' FROM '.$this->prefix.'log L '; + + if (!$count_only) { + $strReq .= + 'LEFT JOIN '.$this->prefix.'user U '. + 'ON U.user_id = L.user_id '; + } + + if (!empty($params['blog_id'])) { + if ($params['blog_id'] === 'all') { + $strReq .= "WHERE NULL IS NULL "; + } + else { + $strReq .= "WHERE L.blog_id = '".$this->core->con->escape($params['blog_id'])."' "; + } + } + else { + $strReq .= "WHERE L.blog_id = '".$this->core->blog->id."' "; + } + + if (!empty($params['user_id'])) { + $strReq .= 'AND L.user_id'.$this->core->con->in($params['user_id']); + } + if (!empty($params['log_ip'])) { + $strReq .= 'AND log_ip'.$this->core->con->in($params['log_ip']); + } + if (!empty($params['log_table'])) { + $strReq .= 'AND log_table'.$this->core->con->in($params['log_table']); + } + + if (!$count_only) + { + if (!empty($params['order'])) { + $strReq .= 'ORDER BY '.$this->core->con->escape($params['order']).' '; + } else { + $strReq .= 'ORDER BY log_dt DESC '; + } + } + + if (!empty($params['limit'])) { + $strReq .= $this->core->con->limit($params['limit']); + } + + $rs = $this->core->con->select($strReq); + $rs->extend('rsExtLog'); + + return $rs; + } + + /** + Creates a new log. Takes a cursor as input and returns the new log + ID. + + @param cur cursor Log cursor + @return integer New log ID + */ + public function addLog($cur) + { + $this->core->con->writeLock($this->prefix.'log'); + + try + { + # Get ID + $rs = $this->core->con->select( + 'SELECT MAX(log_id) '. + 'FROM '.$this->prefix.'log ' + ); + + $cur->log_id = (integer) $rs->f(0) + 1; + $cur->blog_id = (string) $this->core->blog->id; + $cur->log_dt = date('Y-m-d H:i:s'); + + $this->getLogCursor($cur,$cur->log_id); + + # --BEHAVIOR-- coreBeforeLogCreate + $this->core->callBehavior('coreBeforeLogCreate',$this,$cur); + + $cur->insert(); + $this->core->con->unlock(); + } + catch (Exception $e) + { + $this->core->con->unlock(); + throw $e; + } + + # --BEHAVIOR-- coreAfterLogCreate + $this->core->callBehavior('coreAfterLogCreate',$this,$cur); + + return $cur->log_id; + } + + /** + Deletes a log. + + @param id integer Log ID + */ + public function delLogs($id,$all = false) + { + $strReq = $all ? + 'TRUNCATE TABLE '.$this->prefix.'log' : + 'DELETE FROM '.$this->prefix.'log WHERE log_id'.$this->core->con->in($id); + + $this->core->con->execute($strReq); + } + + private function getLogCursor($cur,$log_id = null) + { + if ($cur->log_msg === '') { + throw new Exception(__('No log message')); + } + + if ($cur->log_table === null) { + $cur->log_table = 'none'; + } + + if ($cur->user_id === null) { + $cur->user_id = 'unknown'; + } + + if ($cur->log_dt === '' || $cur->log_dt === null) { + $cur->log_dt = date('Y-m-d H:i:s'); + } + + if ($cur->log_ip === null) { + $cur->log_ip = http::realIP(); + } + + $log_id = is_int($log_id) ? $log_id : $cur->log_id; + } +} + +class rsExtLog +{ + public static function getUserCN($rs) + { + $user = dcUtils::getUserCN($rs->user_id, $rs->user_name, + $rs->user_firstname, $rs->user_displayname); + + if ($user === 'unknown') { + $user = __('unknown'); + } + + return $user; + } +} + +?> \ No newline at end of file diff --git a/v2/dotclear/inc/core/class.dc.media.php b/v2/dotclear/inc/core/class.dc.media.php new file mode 100644 index 0000000..ded3834 --- /dev/null +++ b/v2/dotclear/inc/core/class.dc.media.php @@ -0,0 +1,1093 @@ +dcCore
        dcCore instance + protected $con; ///< connection Database connection + protected $table; ///< string Media table name + protected $type; ///< string Media type filter + protected $postmedia; + protected $file_sort = 'name-asc'; + + protected $file_handler = array(); ///< array Array of callbacks + + public $thumb_tp = '%s/.%s_%s.jpg'; ///< string Thumbnail file pattern + + /** + array Tubmnail sizes: + - m: medium image + - s: small image + - t: thumbnail image + - sq: square image + */ + public $thumb_sizes = array( + 'm' => array(448,'ratio','medium'), + 's' => array(240,'ratio','small'), + 't' => array(100,'ratio','thumbnail'), + 'sq' => array(48,'crop','square') + ); + + public $icon_img = 'images/media/%s.png'; ///< string Icon file pattern + + /** + Object constructor. + + @param core dcCore dcCore instance + @param type string Media type filter + */ + public function __construct($core,$type='') + { + $this->core =& $core; + $this->con =& $core->con; + $this->postmedia = new dcPostMedia($core); + + if ($this->core->blog == null) { + throw new Exception(__('No blog defined.')); + } + + $this->table = $this->core->prefix.'media'; + $root = $this->core->blog->public_path; + + if (preg_match('#^http(s)?://#',$this->core->blog->settings->system->public_url)) { + $root_url = rawurldecode($this->core->blog->settings->system->public_url); + } else { + $root_url = rawurldecode($this->core->blog->host.path::clean($this->core->blog->settings->system->public_url)); + } + + if (!is_dir($root)) { + throw new Exception(sprintf(__('Directory %s does not exist.'),$root)); + } + + $this->type = $type; + + parent::__construct($root,$root_url); + $this->chdir(''); + + $this->path = $this->core->blog->settings->system->public_path; + + $this->addExclusion(DC_RC_PATH); + $this->addExclusion(dirname(__FILE__).'/../'); + + $this->exclude_pattern = $core->blog->settings->system->media_exclusion; + + # Event handlers + $this->addFileHandler('image/jpeg','create',array($this,'imageThumbCreate')); + $this->addFileHandler('image/png','create',array($this,'imageThumbCreate')); + $this->addFileHandler('image/gif','create',array($this,'imageThumbCreate')); + + $this->addFileHandler('image/png','update',array($this,'imageThumbUpdate')); + $this->addFileHandler('image/jpeg','update',array($this,'imageThumbUpdate')); + $this->addFileHandler('image/gif','update',array($this,'imageThumbUpdate')); + + $this->addFileHandler('image/png','remove',array($this,'imageThumbRemove')); + $this->addFileHandler('image/jpeg','remove',array($this,'imageThumbRemove')); + $this->addFileHandler('image/gif','remove',array($this,'imageThumbRemove')); + + $this->addFileHandler('image/jpeg','create',array($this,'imageMetaCreate')); + + $this->addFileHandler('image/jpeg','recreate',array($this,'imageThumbCreate')); + $this->addFileHandler('image/png','recreate',array($this,'imageThumbCreate')); + $this->addFileHandler('image/gif','recreate',array($this,'imageThumbCreate')); + + $this->addFileHandler('image/jpeg','recreate',array($this,'imageThumbCreate')); + $this->addFileHandler('image/png','recreate',array($this,'imageThumbCreate')); + $this->addFileHandler('image/gif','recreate',array($this,'imageThumbCreate')); + + # Thumbnails sizes + $this->thumb_sizes['m'][0] = abs($core->blog->settings->system->media_img_m_size); + $this->thumb_sizes['s'][0] = abs($core->blog->settings->system->media_img_s_size); + $this->thumb_sizes['t'][0] = abs($core->blog->settings->system->media_img_t_size); + + # Thumbnails sizes names + $this->thumb_sizes['m'][2] = __($this->thumb_sizes['m'][2]); + $this->thumb_sizes['s'][2] = __($this->thumb_sizes['s'][2]); + $this->thumb_sizes['t'][2] = __($this->thumb_sizes['t'][2]); + $this->thumb_sizes['sq'][2] = __($this->thumb_sizes['sq'][2]); + + # --BEHAVIOR-- coreMediaConstruct + $this->core->callBehavior('coreMediaConstruct',$this); + } + + /** + Changes working directory. + + @param dir string Directory name. + */ + public function chdir($dir) + { + parent::chdir($dir); + $this->relpwd = preg_replace('/^'.preg_quote($this->root,'/').'\/?/','',$this->pwd); + } + + /** + Adds a new file handler for a given media type and event. + + Available events are: + - create: file creation + - update: file update + - remove: file deletion + + @param type string Media type + @param event string Event + @param function callback + */ + public function addFileHandler($type,$event,$function) + { + if (is_callable($function)) { + $this->file_handler[$type][$event][] = $function; + } + } + + protected function callFileHandler($type,$event) + { + if (!empty($this->file_handler[$type][$event])) + { + $args = func_get_args(); + array_shift($args); + array_shift($args); + + foreach ($this->file_handler[$type][$event] as $f) + { + call_user_func_array($f,$args); + } + } + } + + /** + Returns HTML breadCrumb for media manager navigation. + + @param href string URL pattern + @param last string Last item pattern + @return string HTML code + */ + public function breadCrumb($href,$last='') + { + $res = ''; + if ($this->relpwd && $this->relpwd != '.') { + $pwd = ''; + $arr = explode('/',$this->relpwd); + $count = count($arr); + foreach ($arr as $v) { + if (($last != '') && (0 === --$count)) { + $res .= sprintf($last,$v); + } else { + $pwd .= rawurlencode($v).'/'; + $res .= ''.$v.' / '; + } + } + } + return $res; + + } + + protected function fileRecord($rs) + { + if ($rs->isEmpty()) { return null; } + + if (!$this->isFileExclude($this->root.'/'.$rs->media_file) && is_file($this->root.'/'.$rs->media_file)) + { + $f = new fileItem($this->root.'/'.$rs->media_file,$this->root,$this->root_url); + + if ($this->type && $f->type_prefix != $this->type) { + return null; + } + + $meta = @simplexml_load_string($rs->media_meta); + + $f->editable = true; + $f->media_id = $rs->media_id; + $f->media_title = $rs->media_title; + $f->media_meta = $meta instanceof SimpleXMLElement ? $meta : simplexml_load_string(''); + $f->media_user = $rs->user_id; + $f->media_priv = (boolean) $rs->media_private; + $f->media_dt = strtotime($rs->media_dt); + $f->media_dtstr = dt::str('%Y-%m-%d %H:%M',$f->media_dt); + + $f->media_image = false; + + if (!$this->core->auth->check('media_admin',$this->core->blog->id) + && $this->core->auth->userID() != $f->media_user) { + $f->del = false; + $f->editable = false; + } + + $type_prefix = explode('/',$f->type); + $type_prefix = $type_prefix[0]; + + switch ($type_prefix) { + case 'image': + $f->media_image = true; + $f->media_icon = 'image'; + break; + case 'audio': + $f->media_icon = 'audio'; + break; + case 'text': + $f->media_icon = 'text'; + break; + case 'video': + $f->media_icon = 'video'; + break; + default: + $f->media_icon = 'blank'; + } + switch ($f->type) { + case 'application/msword': + case 'application/vnd.oasis.opendocument.text': + case 'application/vnd.sun.xml.writer': + case 'application/pdf': + case 'application/postscript': + $f->media_icon = 'document'; + break; + case 'application/msexcel': + case 'application/vnd.oasis.opendocument.spreadsheet': + case 'application/vnd.sun.xml.calc': + $f->media_icon = 'spreadsheet'; + break; + case 'application/mspowerpoint': + case 'application/vnd.oasis.opendocument.presentation': + case 'application/vnd.sun.xml.impress': + $f->media_icon = 'presentation'; + break; + case 'application/x-debian-package': + case 'application/x-bzip': + case 'application/x-gzip': + case 'application/x-java-archive': + case 'application/rar': + case 'application/x-redhat-package-manager': + case 'application/x-tar': + case 'application/x-gtar': + case 'application/zip': + $f->media_icon = 'package'; + break; + case 'application/octet-stream': + $f->media_icon = 'executable'; + break; + case 'application/x-shockwave-flash': + $f->media_icon = 'video'; + break; + case 'application/ogg': + $f->media_icon = 'audio'; + break; + case 'text/html': + $f->media_icon = 'html'; + break; + } + + $f->media_type = $f->media_icon; + $f->media_icon = sprintf($this->icon_img,$f->media_icon); + + # Thumbnails + $f->media_thumb = array(); + $p = path::info($f->relname); + $thumb = sprintf($this->thumb_tp,$this->root.'/'.$p['dirname'],$p['base'],'%s'); + $thumb_url = sprintf($this->thumb_tp,$this->root_url.$p['dirname'],$p['base'],'%s'); + + # Cleaner URLs + $thumb_url = preg_replace('#\./#','/',$thumb_url); + $thumb_url = preg_replace('#(?thumb_sizes as $suffix => $s) { + if (file_exists(sprintf($thumb,$suffix))) { + $f->media_thumb[$suffix] = sprintf($thumb_url,$suffix); + } + } + + if (isset($f->media_thumb['sq']) && $f->media_type == 'image') { + $f->media_icon = $f->media_thumb['sq']; + } + + return $f; + } + + return null; + } + + + public function setFileSort($type='name') + { + if (in_array($type,array('name-asc','name-desc','date-asc','date-desc'))) { + $this->file_sort = $type; + } + } + + protected function sortFileHandler($a,$b) + { + switch ($this->file_sort) + { + case 'date-asc': + if ($a->media_dt == $b->media_dt) { + return 0; + } + return ($a->media_dt < $b->media_dt) ? -1 : 1; + case 'date-desc': + if ($a->media_dt == $b->media_dt) { + return 0; + } + return ($a->media_dt > $b->media_dt) ? -1 : 1; + case 'name-desc': + return strcasecmp($b->basename,$a->basename); + case 'name-asc': + default: + return strcasecmp($a->basename,$b->basename); + } + + } + + /** + Gets current working directory content. + + @param type string Media type filter + */ + public function getDir($type=null) + { + if ($type) { + $this->type = $type; + } + + $media_dir = $this->relpwd ? $this->relpwd : '.'; + + $strReq = + 'SELECT media_file, media_id, media_path, media_title, media_meta, media_dt, '. + 'media_creadt, media_upddt, media_private, user_id '. + 'FROM '.$this->table.' '. + "WHERE media_path = '".$this->path."' ". + "AND media_dir = '".$this->con->escape($media_dir)."' "; + + if (!$this->core->auth->check('media_admin',$this->core->blog->id)) + { + $strReq .= 'AND (media_private <> 1 '; + + if ($this->core->auth->userID()) { + $strReq .= "OR user_id = '".$this->con->escape($this->core->auth->userID())."'"; + } + $strReq .= ') '; + } + + $rs = $this->con->select($strReq); + + parent::getDir(); + + $f_res = array(); + $p_dir = $this->dir; + + # If type is set, remove items from p_dir + if ($this->type) + { + foreach ($p_dir['files'] as $k => $f) { + if ($f->type_prefix != $this->type) { + unset($p_dir['files'][$k]); + } + } + } + + $f_reg = array(); + + while ($rs->fetch()) + { + # File in subdirectory, forget about it! + if (dirname($rs->media_file) != '.' && dirname($rs->media_file) != $this->relpwd) { + continue; + } + + if ($this->inFiles($rs->media_file)) + { + $f = $this->fileRecord($rs); + if ($f !== null) { + if (isset($f_reg[$rs->media_file])) + { + # That media is duplicated in the database, + # time to do a bit of house cleaning. + $this->con->execute( + 'DELETE FROM '.$this->table.' '. + "WHERE media_id = ".$this->fileRecord($rs)->media_id + ); + } else { + $f_res[] = $this->fileRecord($rs); + $f_reg[$rs->media_file] = 1; + } + } + } + elseif (!empty($p_dir['files']) && $this->relpwd == '') + { + # Physical file does not exist remove it from DB + # Because we don't want to erase everything on + # dotclear upgrade, do it only if there are files + # in directory and directory is root + $this->con->execute( + 'DELETE FROM '.$this->table.' '. + "WHERE media_path = '".$this->con->escape($this->path)."' ". + "AND media_file = '".$this->con->escape($rs->media_file)."' " + ); + $this->callFileHandler(files::getMimeType($rs->media_file),'remove',$this->pwd.'/'.$rs->media_file); + } + } + + $this->dir['files'] = $f_res; + foreach ($this->dir['dirs'] as $k => $v) { + $v->media_icon = sprintf($this->icon_img,'folder'); + } + + # Check files that don't exist in database and create them + if ($this->core->auth->check('media,media_admin',$this->core->blog->id)) + { + foreach ($p_dir['files'] as $f) + { + if (!isset($f_reg[$f->relname])) { + if (($id = $this->createFile($f->basename,null,false,null,false)) !== false) { + $this->dir['files'][] = $this->getFile($id); + } + } + } + } + usort($this->dir['files'],array($this,'sortFileHandler')); + } + + /** + Gets file by its id. Returns a filteItem object. + + @param id integer File ID + @return fileItem + */ + public function getFile($id) + { + $strReq = + 'SELECT media_id, media_path, media_title, '. + 'media_file, media_meta, media_dt, media_creadt, '. + 'media_upddt, media_private, user_id '. + 'FROM '.$this->table.' '. + "WHERE media_path = '".$this->path."' ". + 'AND media_id = '.(integer) $id.' '; + + if (!$this->core->auth->check('media_admin',$this->core->blog->id)) + { + $strReq .= 'AND (media_private <> 1 '; + + if ($this->core->auth->userID()) { + $strReq .= "OR user_id = '".$this->con->escape($this->core->auth->userID())."'"; + } + $strReq .= ') '; + } + + $rs = $this->con->select($strReq); + return $this->fileRecord($rs); + } + + /** + Returns media items attached to a blog post. Result is an array containing + fileItems objects. + + @param post_id integer Post ID + @param media_id integer Optionnal media ID + @return array Array of fileItems + */ + public function getPostMedia($post_id,$media_id=null) + { + $params = array( + 'post_id' => $post_id, + 'media_path' => $this->path + ); + if ($media_id) { + $params['media_id'] = (integer) $media_id; + } + $rs = $this->postmedia->getPostMedia($params); + + $res = array(); + + while ($rs->fetch()) { + $f = $this->fileRecord($rs); + if ($f !== null) { + $res[] = $f; + } + } + + return $res; + } + + /** + @deprecated since version 2.4 + @see dcPostMedia::addPostMedia + */ + public function addPostMedia($post_id,$media_id) + { + $this->postmedia->addPostMedia($post_id,$media_id); + } + + /** + @deprecated since version 2.4 + @see dcPostMedia::removePostMedia + */ + public function removePostMedia($post_id,$media_id) + { + $this->postmedia->removePostMedia($post_id,$media_id,"attachment"); + } + + /** + Rebuilds database items collection. Optional $pwd parameter is + the path where to start rebuild. + + @param pwd string Directory to rebuild + */ + public function rebuild($pwd='') + { + if (!$this->core->auth->isSuperAdmin()) { + throw new Exception(__('You are not a super administrator.')); + } + + $this->chdir($pwd); + parent::getDir(); + + $dir = $this->dir; + + foreach ($dir['dirs'] as $d) { + if (!$d->parent) { + $this->rebuild($d->relname,false); + } + } + + foreach ($dir['files'] as $f) { + $this->chdir(dirname($f->relname)); + $this->createFile($f->basename); + } + + $this->rebuildDB($pwd); + } + + protected function rebuildDB($pwd) + { + $media_dir = $pwd ? $pwd : '.'; + + $strReq = + 'SELECT media_file, media_id '. + 'FROM '.$this->table.' '. + "WHERE media_path = '".$this->path."' ". + "AND media_dir = '".$this->con->escape($media_dir)."' "; + + $rs = $this->con->select($strReq); + + $delReq = 'DELETE FROM '.$this->table.' '. + 'WHERE media_id IN (%s) '; + $del_ids = array(); + + while ($rs->fetch()) + { + if (!is_file($this->root.'/'.$rs->media_file)) { + $del_ids[] = (integer) $rs->media_id; + } + } + + if (!empty($del_ids)) { + $this->con->execute(sprintf($delReq,implode(',',$del_ids))); + } + } + + public function makeDir($d) + { + $d = files::tidyFileName($d); + parent::makeDir($d); + } + + /** + Creates or updates a file in database. Returns new media ID or false if + file does not exist. + + @param name string File name (relative to working directory) + @param title string File title + @param private boolean File is private + @param dt string File date + @return integer New media ID + */ + public function createFile($name,$title=null,$private=false,$dt=null,$force=true) + { + if (!$this->core->auth->check('media,media_admin',$this->core->blog->id)) { + throw new Exception(__('Permission denied.')); + } + + $file = $this->pwd.'/'.$name; + if (!file_exists($file)) { + return false; + } + + $media_file = $this->relpwd ? path::clean($this->relpwd.'/'.$name) : path::clean($name); + $media_type = files::getMimeType($name); + + $cur = $this->con->openCursor($this->table); + + $strReq = 'SELECT media_id '. + 'FROM '.$this->table.' '. + "WHERE media_path = '".$this->con->escape($this->path)."' ". + "AND media_file = '".$this->con->escape($media_file)."' "; + + $rs = $this->con->select($strReq); + + if ($rs->isEmpty()) + { + $this->con->writeLock($this->table); + try + { + $rs = $this->con->select('SELECT MAX(media_id) FROM '.$this->table); + $media_id = (integer) $rs->f(0) + 1; + + $cur->media_id = $media_id; + $cur->user_id = (string) $this->core->auth->userID(); + $cur->media_path = (string) $this->path; + $cur->media_file = (string) $media_file; + $cur->media_dir = (string) dirname($media_file); + $cur->media_creadt = date('Y-m-d H:i:s'); + $cur->media_upddt = date('Y-m-d H:i:s'); + + $cur->media_title = !$title ? (string) $name : (string) $title; + $cur->media_private = (integer) (boolean) $private; + + if ($dt) { + $cur->media_dt = (string) $dt; + } else { + $cur->media_dt = strftime('%Y-%m-%d %H:%M:%S',filemtime($file)); + } + + try { + $cur->insert(); + } catch (Exception $e) { + @unlink($name); + throw $e; + } + $this->con->unlock(); + } + catch (Exception $e) + { + $this->con->unlock(); + throw $e; + } + } + else + { + $media_id = (integer) $rs->media_id; + + $cur->media_upddt = date('Y-m-d H:i:s'); + + $cur->update('WHERE media_id = '.$media_id); + } + + $this->callFileHandler($media_type,'create',$cur,$name,$media_id,$force); + + return $media_id; + } + + /** + Updates a file in database. + + @param file fileItem Current fileItem object + @param newFile fileItem New fileItem object + */ + public function updateFile($file,$newFile) + { + if (!$this->core->auth->check('media,media_admin',$this->core->blog->id)) { + throw new Exception(__('Permission denied.')); + } + + $id = (integer) $file->media_id; + + if (!$id) { + throw new Exception('No file ID'); + } + + if (!$this->core->auth->check('media_admin',$this->core->blog->id) + && $this->core->auth->userID() != $file->media_user) { + throw new Exception(__('You are not the file owner.')); + } + + $cur = $this->con->openCursor($this->table); + + # We need to tidy newFile basename. If dir isn't empty, concat to basename + $newFile->relname = files::tidyFileName($newFile->basename); + if ($newFile->dir) { + $newFile->relname = $newFile->dir.'/'.$newFile->relname; + } + + if ($file->relname != $newFile->relname) { + $newFile->file = $this->root.'/'.$newFile->relname; + + if ($this->isFileExclude($newFile->relname)) { + throw new Exception(__('This file is not allowed.')); + } + + if (file_exists($newFile->file)) { + throw new Exception(__('New file already exists.')); + } + + $this->moveFile($file->relname,$newFile->relname); + + $cur->media_file = (string) $newFile->relname; + $cur->media_dir = (string) dirname($newFile->relname); + } + + $cur->media_title = (string) $newFile->media_title; + $cur->media_dt = (string) $newFile->media_dtstr; + $cur->media_upddt = date('Y-m-d H:i:s'); + $cur->media_private = (integer) $newFile->media_priv; + + $cur->update('WHERE media_id = '.$id); + + $this->callFileHandler($file->type,'update',$file,$newFile); + } + + /** + Uploads a file. + + @param tmp string Full path of temporary uploaded file + @param name string File name (relative to working directory) + @param title string File title + @param private boolean File is private + */ + public function uploadFile($tmp,$name,$title=null,$private=false,$overwrite=false) + { + if (!$this->core->auth->check('media,media_admin',$this->core->blog->id)) { + throw new Exception(__('Permission denied.')); + } + + $name = files::tidyFileName($name); + + parent::uploadFile($tmp,$name,$overwrite); + + return $this->createFile($name,$title,$private); + } + + /** + Creates a file from binary content. + + @param name string File name (relative to working directory) + @param bits string Binary file content + */ + public function uploadBits($name,$bits) + { + if (!$this->core->auth->check('media,media_admin',$this->core->blog->id)) { + throw new Exception(__('Permission denied.')); + } + + $name = files::tidyFileName($name); + + parent::uploadBits($name,$bits); + + return $this->createFile($name,null,null); + } + + /** + Removes a file. + + @param f fileItem fileItem object + */ + public function removeFile($f) + { + if (!$this->core->auth->check('media,media_admin',$this->core->blog->id)) { + throw new Exception(__('Permission denied.')); + } + + $media_file = $this->relpwd ? path::clean($this->relpwd.'/'.$f) : path::clean($f); + + $strReq = 'DELETE FROM '.$this->table.' '. + "WHERE media_path = '".$this->con->escape($this->path)."' ". + "AND media_file = '".$this->con->escape($media_file)."' "; + + if (!$this->core->auth->check('media_admin',$this->core->blog->id)) + { + $strReq .= "AND user_id = '".$this->con->escape($this->core->auth->userID())."'"; + } + + $this->con->execute($strReq); + + if ($this->con->changes() == 0) { + throw new Exception(__('File does not exist in the database.')); + } + + parent::removeFile($f); + + $this->callFileHandler(files::getMimeType($media_file),'remove',$f); + } + + /** + Extract zip file in current location + + @param f fileRecord fileRecord object + */ + public function inflateZipFile($f,$create_dir=true) + { + $zip = new fileUnzip($f->file); + $zip->setExcludePattern($this->exclude_pattern); + $zip->getList(false,'#(^|/)(__MACOSX|\.svn|\.DS_Store|\.directory|Thumbs\.db)(/|$)#'); + + if ($create_dir) + { + $zip_root_dir = $zip->getRootDir(); + if ($zip_root_dir != false) { + $destination = $zip_root_dir; + $target = $f->dir; + } else { + $destination = preg_replace('/\.([^.]+)$/','',$f->basename); + $target = $f->dir.'/'.$destination; + } + + if (is_dir($f->dir.'/'.$destination)) { + throw new Exception(sprintf(__('Extract destination directory %s already exists.'),dirname($f->relname).'/'.$destination)); + } + } + else + { + $target = $f->dir; + $destination = ''; + } + + $zip->unzipAll($target); + $zip->close(); + return dirname($f->relname).'/'.$destination; + } + + /** + Returns zip file content + + @param f fileRecord fileRecord object + @return array + */ + public function getZipContent($f) + { + $zip = new fileUnzip($f->file); + $list = $zip->getList(false,'#(^|/)(__MACOSX|\.svn|\.DS_Store|\.directory|Thumbs\.db)(/|$)#'); + $zip->close(); + return $list; + } + + /** + Calls file handlers registered for recreate event + + @param f fileItem fileItem object + */ + public function mediaFireRecreateEvent($f) + { + $media_type = files::getMimeType($f->basename); + $this->callFileHandler($media_type,'recreate',null,$f->basename); // Args list to be completed as necessary (Franck) + } + + /* Image handlers + ------------------------------------------------------- */ + public function imageThumbCreate($cur,$f,$force=true) + { + $file = $this->pwd.'/'.$f; + + if (!file_exists($file)) { + return false; + } + + $p = path::info($file); + $thumb = sprintf($this->thumb_tp,$p['dirname'],$p['base'],'%s'); + + try + { + $img = new imageTools(); + $img->loadImage($file); + + $w = $img->getW(); + $h = $img->getH(); + + if ($force) $this->imageThumbRemove($f); + + foreach ($this->thumb_sizes as $suffix => $s) { + $thumb_file = sprintf($thumb,$suffix); + if (!file_exists($thumb_file) && $s[0] > 0 && + ($suffix == 'sq' || $w > $s[0] || $h > $s[0])) + { + $img->resize($s[0],$s[0],$s[1]); + $img->output('jpeg',$thumb_file,80); + } + } + $img->close(); + } + catch (Exception $e) + { + if ($cur === null) { # Called only if cursor is null (public call) + throw $e; + } + } + } + + protected function imageThumbUpdate($file,$newFile) + { + if ($file->relname != $newFile->relname) + { + $p = path::info($file->relname); + $thumb_old = sprintf($this->thumb_tp,$p['dirname'],$p['base'],'%s'); + + $p = path::info($newFile->relname); + $thumb_new = sprintf($this->thumb_tp,$p['dirname'],$p['base'],'%s'); + + foreach ($this->thumb_sizes as $suffix => $s) { + try { + parent::moveFile(sprintf($thumb_old,$suffix),sprintf($thumb_new,$suffix)); + } catch (Exception $e) {} + } + } + } + + protected function imageThumbRemove($f) + { + $p = path::info($f); + $thumb = sprintf($this->thumb_tp,'',$p['base'],'%s'); + + foreach ($this->thumb_sizes as $suffix => $s) { + try { + parent::removeFile(sprintf($thumb,$suffix)); + } catch (Exception $e) {} + } + } + + protected function imageMetaCreate($cur,$f,$id) + { + $file = $this->pwd.'/'.$f; + + if (!file_exists($file)) { + return false; + } + + $xml = new xmlTag('meta'); + $meta = imageMeta::readMeta($file); + $xml->insertNode($meta); + + $c = $this->core->con->openCursor($this->table); + $c->media_meta = $xml->toXML(); + + if ($cur->media_title !== null && $cur->media_title == basename($cur->media_file)) + { + if ($meta['Title']) { + $c->media_title = $meta['Title']; + } + } + + if ($meta['DateTimeOriginal'] && $cur->media_dt === '') + { + # We set picture time to user timezone + $media_ts = strtotime($meta['DateTimeOriginal']); + if ($media_ts !== false) { + $o = dt::getTimeOffset($this->core->auth->getInfo('user_tz'),$media_ts); + $c->media_dt = dt::str('%Y-%m-%d %H:%M:%S',$media_ts+$o); + } + } + + $c->update('WHERE media_id = '.$id); + } + + /** + Returns HTML code for MP3 player + + @param url string MP3 URL to play + @param player string Player URL + @param args array Player parameters + @return string + */ + public static function mp3player($url,$player=null,$args=null) + { + if (!$player) { + $player = 'player_mp3.swf'; + } + + if (!is_array($args)) + { + $args = array( + 'showvolume' => 1, + 'loadingcolor' => 'ff9900', + 'bgcolor1' => 'eeeeee', + 'bgcolor2' => 'cccccc', + 'buttoncolor' => '0066cc', + 'buttonovercolor' => 'ff9900', + 'slidercolor1' => 'cccccc', + 'slidercolor2' => '999999', + 'sliderovercolor' => '0066cc' + ); + } + + $args['mp3'] = $url; + + if (empty($args['width'])) { + $args['width'] = 200; + } + if (empty($args['height'])) { + $args['height'] = 20; + } + + $vars = array(); + foreach ($args as $k => $v) { + $vars[] = $k.'='.$v; + } + + return + ''. + ''. + ''. + ''. + __('Embedded Audio Player'). + ''; + } + + public static function flvplayer($url,$player=null,$args=null) + { + if (!$player) { + $player = 'player_flv.swf'; + } + + if (!is_array($args)) + { + $args = array( + 'margin' => 1, + 'showvolume' => 1, + 'showtime' => 1, + 'showfullscreen' => 1, + 'buttonovercolor' => 'ff9900', + 'slidercolor1' => 'cccccc', + 'slidercolor2' => '999999', + 'sliderovercolor' => '0066cc' + ); + } + + $args['flv'] = $url; + + if (empty($args['width'])) { + $args['width'] = 400; + } + if (empty($args['height'])) { + $args['height'] = 300; + } + + $vars = array(); + foreach ($args as $k => $v) { + $vars[] = $k.'='.$v; + } + + return + ''. + ''. + ''. + ''. + ''. + __('Embedded Video Player'). + ''; + } +} +?> diff --git a/v2/dotclear/inc/core/class.dc.meta.php b/v2/dotclear/inc/core/class.dc.meta.php new file mode 100644 index 0000000..9108d44 --- /dev/null +++ b/v2/dotclear/inc/core/class.dc.meta.php @@ -0,0 +1,615 @@ +dcCore
        dcCore instance + private $con; ///< connection Database connection object + private $table; ///< string Media table name + + /** + Object constructor. + + @param core dcCore dcCore instance + */ + public function __construct($core) + { + $this->core =& $core; + $this->con =& $this->core->con; + $this->table = $this->core->prefix.'meta'; + } + + /** + Splits up comma-separated values into an array of + unique, URL-proof metadata values. + + @param str string Comma-separated metadata. + + @return Array The array of sanitized metadata + */ + public function splitMetaValues($str) + { + $res = array(); + foreach (explode(',',$str) as $i => $tag) + { + $tag = trim($tag); + $tag = self::sanitizeMetaID($tag); + + if ($tag != false) { + $res[$i] = $tag; + } + } + + return array_unique($res); + } + + /** + Make a metadata ID URL-proof. + + @param str string the metadata ID. + + @return string The sanitized metadata + */ + public static function sanitizeMetaID($str) + { + return text::tidyURL($str,false,true); + } + + /** + Converts serialized metadata (for instance in dc_post post_meta) + into a meta array. + + @param str string the serialized metadata. + + @return Array the resulting array of post meta + */ + public function getMetaArray($str) + { + $meta = @unserialize($str); + + if (!is_array($meta)) { + return array(); + } + + return $meta; + } + + /** + Converts serialized metadata (for instance in dc_post post_meta) + into a comma-separated meta list for a given type. + + @param str string the serialized metadata. + @param type string meta type to retrieve metaIDs from. + + @return string the comma-separated list of meta + */ + public function getMetaStr($str,$type) + { + $meta = $this->getMetaArray($str); + + if (!isset($meta[$type])) { + return ''; + } + + return implode(', ',$meta[$type]); + } + + /** + Converts serialized metadata (for instance in dc_post post_meta) + into a "fetchable" metadata record. + + @param str string the serialized metadata. + @param type string meta type to retrieve metaIDs from. + + @return record the meta recordset + */ + public function getMetaRecordset($str,$type) + { + $meta = $this->getMetaArray($str); + $data = array(); + + if (isset($meta[$type])) + { + foreach ($meta[$type] as $v) + { + $data[] = array( + 'meta_id' => $v, + 'meta_type' => $type, + 'meta_id_lower' => mb_strtolower($v), + 'count' => 0, + 'percent' => 0, + 'roundpercent' => 0 + ); + } + } + + return staticRecord::newFromArray($data); + } + + /** + @deprecated since version 2.2 : $core->meta is always defined + @see getMetaRecordset + static version of getMetaRecordset + */ + public static function getMetaRecord($core,$str,$type) + { + $meta = new self($core); + return $meta->getMetaRecordset($str,$type); + } + + /** + Checks whether the current user is allowed to change post meta + An exception is thrown if user is not allowed. + + @param post_id string the post_id to check. + */ + private function checkPermissionsOnPost($post_id) + { + $post_id = (integer) $post_id; + + if (!$this->core->auth->check('usage,contentadmin',$this->core->blog->id)) { + throw new Exception(__('You are not allowed to change this entry status')); + } + + #�If user can only publish, we need to check the post's owner + if (!$this->core->auth->check('contentadmin',$this->core->blog->id)) + { + $strReq = 'SELECT post_id '. + 'FROM '.$this->core->prefix.'post '. + 'WHERE post_id = '.$post_id.' '. + "AND user_id = '".$this->con->escape($this->core->auth->userID())."' "; + + $rs = $this->con->select($strReq); + + if ($rs->isEmpty()) { + throw new Exception(__('You are not allowed to change this entry status')); + } + } + } + + /** + Updates serialized post_meta information with dc_meta table information. + + @param post_id string the post_id to update. + */ + private function updatePostMeta($post_id) + { + $post_id = (integer) $post_id; + + $strReq = 'SELECT meta_id, meta_type '. + 'FROM '.$this->table.' '. + 'WHERE post_id = '.$post_id.' '; + + $rs = $this->con->select($strReq); + + $meta = array(); + while ($rs->fetch()) { + $meta[$rs->meta_type][] = $rs->meta_id; + } + + $post_meta = serialize($meta); + + $cur = $this->con->openCursor($this->core->prefix.'post'); + $cur->post_meta = $post_meta; + + $cur->update('WHERE post_id = '.$post_id); + $this->core->blog->triggerBlog(); + } + + /** + Retrieves posts corresponding to given meta criteria. + $params is an array taking the following optional parameters: + - meta_id : get posts having meta id + - meta_type : get posts having meta type + + @param params array Parameters + @param count_only boolean Only counts results + + @return record the resulting posts record + */ + public function getPostsByMeta($params=array(),$count_only=false) + { + if (!isset($params['meta_id'])) { + return null; + } + + $params['from'] = ', '.$this->table.' META '; + $params['sql'] = 'AND META.post_id = P.post_id '; + + $params['sql'] .= "AND META.meta_id = '".$this->con->escape($params['meta_id'])."' "; + + if (!empty($params['meta_type'])) { + $params['sql'] .= "AND META.meta_type = '".$this->con->escape($params['meta_type'])."' "; + unset($params['meta_type']); + } + + unset($params['meta_id']); + + return $this->core->blog->getPosts($params,$count_only); + } + + /** + Retrieves comments to posts corresponding to given meta criteria. + $params is an array taking the following optional parameters: + - meta_id : get comments to posts having meta id + - meta_type : get comments to posts having meta type + + @param params array Parameters + @param count_only boolean Only counts results + + @return record the resulting comments record + */ + public function getCommentsByMeta($params=array(),$count_only=false) + { + if (!isset($params['meta_id'])) { + return null; + } + + $params['from'] = ', '.$this->table.' META '; + $params['sql'] = 'AND META.post_id = P.post_id '; + $params['sql'] .= "AND META.meta_id = '".$this->con->escape($params['meta_id'])."' "; + + if (!empty($params['meta_type'])) { + $params['sql'] .= "AND META.meta_type = '".$this->con->escape($params['meta_type'])."' "; + unset($params['meta_type']); + } + + return $this->core->blog->getComments($params,$count_only); + } + + /** + @deprecated since 2.2. Use getMetadata and computeMetaStats instead. + Generic-purpose metadata retrieval : gets metadatas according to given + criteria. Metadata get enriched with stastistics columns (only relevant + if limit parameter is not set). Metadata are sorted by post count + descending + + @param type string if not null, get metas having the given type + @param limit string if not null, number of max fetched metas + @param meta_id string if not null, get metas having the given id + @param post_id string if not null, get metas for the given post id + + @return record the meta recordset + */ + public function getMeta($type=null,$limit=null,$meta_id=null,$post_id=null) { + $params = array(); + + if ($type != null) + $params['meta_type'] = $type; + if ($limit != null) + $params['limit'] = $limit; + if ($meta_id != null) + $params['meta_id'] = $meta_id; + if ($meta_id != null) + $params['post_id'] = $post_id; + $rs = $this->getMetadata($params, false); + return $this->computeMetaStats($rs); + } + + /** + Generic-purpose metadata retrieval : gets metadatas according to given + criteria. $params is an array taking the following + optionnal parameters: + + - type: get metas having the given type + - meta_id: if not null, get metas having the given id + - post_id: get metas for the given post id + - limit: number of max fetched metas + - order: results order (default : posts count DESC) + + @param params array Parameters + @param count_only boolean Only counts results + + @return record the resulting comments record + */ + public function getMetadata($params=array(), $count_only=false) + { + if ($count_only) { + $strReq = 'SELECT count(distinct M.meta_id) '; + } else { + $strReq = 'SELECT M.meta_id, M.meta_type, COUNT(M.post_id) as count '; + } + + $strReq .= + 'FROM '.$this->table.' M LEFT JOIN '.$this->core->prefix.'post P '. + 'ON M.post_id = P.post_id '. + "WHERE P.blog_id = '".$this->con->escape($this->core->blog->id)."' "; + + if (isset($params['meta_type'])) { + $strReq .= " AND meta_type = '".$this->con->escape($params['meta_type'])."' "; + } + + if (isset($params['meta_id'])) { + $strReq .= " AND meta_id = '".$this->con->escape($params['meta_id'])."' "; + } + + if (isset($params['post_id'])) { + $strReq .= ' AND P.post_id '.$this->con->in($params['post_id']).' '; + } + + if (!$this->core->auth->check('contentadmin',$this->core->blog->id)) { + $strReq .= 'AND ((post_status = 1 '; + + if ($this->core->blog->without_password) { + $strReq .= 'AND post_password IS NULL '; + } + $strReq .= ') '; + + if ($this->core->auth->userID()) { + $strReq .= "OR P.user_id = '".$this->con->escape($this->core->auth->userID())."')"; + } else { + $strReq .= ') '; + } + } + + if (!$count_only) { + if (!isset($params['order'])) { + $params['order'] = 'count DESC'; + } + + $strReq .= + 'GROUP BY meta_id,meta_type,P.blog_id '. + 'ORDER BY '.$params['order']; + + if (isset($params['limit'])) { + $strReq .= $this->con->limit($params['limit']); + } + } + + $rs = $this->con->select($strReq); + return $rs; + } + + /** + Computes statistics from a metadata recordset. + Each record gets enriched with lowercase name, percent and roundpercent columns + + @param rs record recordset to enrich + + @return record the enriched recordset + */ + public function computeMetaStats($rs) { + $rs_static = $rs->toStatic(); + + $max = array(); + while ($rs_static->fetch()) + { + $type = $rs_static->meta_type; + if (!isset($max[$type])) { + $max[$type] = $rs_static->count; + } else { + if ($rs_static->count > $max[$type]) { + $max[$type] = $rs_static->count; + } + } + } + + while ($rs_static->fetch()) + { + $rs_static->set('meta_id_lower',mb_strtolower($rs_static->meta_id)); + + $count = $rs_static->count; + $percent = ((integer) $rs_static->count) * 100 / $max[$rs_static->meta_type]; + + $rs_static->set('percent',(integer) round($percent)); + $rs_static->set('roundpercent',round($percent/10)*10); + } + + return $rs_static; + } + + /** + Adds a metadata to a post. + + @param post_id integer the post id + @param type string meta type + @param value integer meta value + */ + public function setPostMeta($post_id,$type,$value) + { + $this->checkPermissionsOnPost($post_id); + + $value = trim($value); + if ($value === false) { return; } + + $cur = $this->con->openCursor($this->table); + + $cur->post_id = (integer) $post_id; + $cur->meta_id = (string) $value; + $cur->meta_type = (string) $type; + + $cur->insert(); + $this->updatePostMeta((integer) $post_id); + } + + /** + Removes metadata from a post. + + @param post_id integer the post id + @param type string meta type (if null, delete all types) + @param value integer meta value (if null, delete all values) + */ + public function delPostMeta($post_id,$type=null,$meta_id=null) + { + $post_id = (integer) $post_id; + + $this->checkPermissionsOnPost($post_id); + + $strReq = 'DELETE FROM '.$this->table.' '. + 'WHERE post_id = '.$post_id; + + if ($type !== null) { + $strReq .= " AND meta_type = '".$this->con->escape($type)."' "; + } + + if ($meta_id !== null) { + $strReq .= " AND meta_id = '".$this->con->escape($meta_id)."' "; + } + + $this->con->execute($strReq); + $this->updatePostMeta((integer) $post_id); + } + + /** + Mass updates metadata for a given post_type. + + @param meta_id integer old value + @param new_meta integer new value + @param type string meta type (if null, select all types) + @param post_type integer impacted post_type (if null, select all types) + @return boolean true if at least 1 post has been impacted + */ + public function updateMeta($meta_id,$new_meta_id,$type=null,$post_type=null) + { + $new_meta_id = self::sanitizeMetaID($new_meta_id); + + if ($new_meta_id == $meta_id) { + return true; + } + + $getReq = 'SELECT M.post_id '. + 'FROM '.$this->table.' M, '.$this->core->prefix.'post P '. + 'WHERE P.post_id = M.post_id '. + "AND P.blog_id = '".$this->con->escape($this->core->blog->id)."' ". + "AND meta_id = '%s' "; + + if (!$this->core->auth->check('contentadmin',$this->core->blog->id)) { + $getReq .= "AND P.user_id = '".$this->con->escape($this->core->auth->userID())."' "; + } + if ($post_type !== null) { + $getReq .= "AND P.post_type = '".$this->con->escape($post_type)."' "; + } + + $delReq = 'DELETE FROM '.$this->table.' '. + 'WHERE post_id IN (%s) '. + "AND meta_id = '%s' "; + + $updReq = 'UPDATE '.$this->table.' '. + "SET meta_id = '%s' ". + 'WHERE post_id IN (%s) '. + "AND meta_id = '%s' "; + + if ($type !== null) { + $plus = " AND meta_type = '%s' "; + $getReq .= $plus; + $delReq .= $plus; + $updReq .= $plus; + } + + $to_update = $to_remove = array(); + + $rs = $this->con->select(sprintf($getReq,$this->con->escape($meta_id), + $this->con->escape($type))); + + while ($rs->fetch()) { + $to_update[] = $rs->post_id; + } + + if (empty($to_update)) { + return false; + } + + $rs = $this->con->select(sprintf($getReq,$new_meta_id,$type)); + while ($rs->fetch()) { + if (in_array($rs->post_id,$to_update)) { + $to_remove[] = $rs->post_id; + unset($to_update[array_search($rs->post_id,$to_update)]); + } + } + + # Delete duplicate meta + if (!empty($to_remove)) + { + $this->con->execute(sprintf($delReq,implode(',',$to_remove), + $this->con->escape($meta_id), + $this->con->escape($type))); + + foreach ($to_remove as $post_id) { + $this->updatePostMeta($post_id); + } + } + + # Update meta + if (!empty($to_update)) + { + $this->con->execute(sprintf($updReq,$this->con->escape($new_meta_id), + implode(',',$to_update), + $this->con->escape($meta_id), + $this->con->escape($type))); + + foreach ($to_update as $post_id) { + $this->updatePostMeta($post_id); + } + } + + return true; + } + + /** + Mass delete metadata for a given post_type. + + @param meta_id integer meta value + @param type string meta type (if null, select all types) + @param post_type integer impacted post_type (if null, select all types) + @return Array the list of impacted post_ids + */ + public function delMeta($meta_id,$type=null,$post_type=null) + { + $strReq = 'SELECT M.post_id '. + 'FROM '.$this->table.' M, '.$this->core->prefix.'post P '. + 'WHERE P.post_id = M.post_id '. + "AND P.blog_id = '".$this->con->escape($this->core->blog->id)."' ". + "AND meta_id = '".$this->con->escape($meta_id)."' "; + + if ($type !== null) { + $strReq .= " AND meta_type = '".$this->con->escape($type)."' "; + } + + if ($post_type !== null) { + $strReq .= " AND P.post_type = '".$this->con->escape($post_type)."' "; + } + + $rs = $this->con->select($strReq); + + if ($rs->isEmpty()) return array(); + + $ids = array(); + while ($rs->fetch()) { + $ids[] = $rs->post_id; + } + + $strReq = 'DELETE FROM '.$this->table.' '. + 'WHERE post_id IN ('.implode(',',$ids).') '. + "AND meta_id = '".$this->con->escape($meta_id)."' "; + + if ($type !== null) { + $strReq .= " AND meta_type = '".$this->con->escape($type)."' "; + } + + $rs = $this->con->execute($strReq); + + foreach ($ids as $post_id) { + $this->updatePostMeta($post_id); + } + + return $ids; + } +} +?> diff --git a/v2/dotclear/inc/core/class.dc.modules.php b/v2/dotclear/inc/core/class.dc.modules.php new file mode 100644 index 0000000..efe87e2 --- /dev/null +++ b/v2/dotclear/inc/core/class.dc.modules.php @@ -0,0 +1,563 @@ +dcCore
        dcCore instance + + /** + Object constructor. + + @param core dcCore dcCore instance + */ + public function __construct($core) + { + $this->core =& $core; + } + + /** + Loads modules. $path could be a separated list of paths + (path separator depends on your OS). + + $ns indicates if an additionnal file needs to be loaded on plugin + load, value could be: + - admin (loads module's _admin.php) + - public (loads module's _public.php) + - xmlrpc (loads module's _xmlrpc.php) + + $lang indicates if we need to load a lang file on plugin + loading. + */ + public function loadModules($path,$ns=null,$lang=null) + { + $this->path = explode(PATH_SEPARATOR,$path); + $this->ns = $ns; + + $disabled = isset($_SESSION['sess_safe_mode']) && $_SESSION['sess_safe_mode']; + $disabled = $disabled && !get_parent_class($this) ? true : false; + + foreach ($this->path as $root) + { + if (!is_dir($root) || !is_readable($root)) { + continue; + } + + if (substr($root,-1) != '/') { + $root .= '/'; + } + + if (($d = @dir($root)) === false) { + continue; + } + + while (($entry = $d->read()) !== false) + { + $full_entry = $root.'/'.$entry; + + if ($entry != '.' && $entry != '..' && is_dir($full_entry) + && file_exists($full_entry.'/_define.php')) + { + if (!file_exists($full_entry.'/_disabled') && !$disabled) + { + $this->id = $entry; + $this->mroot = $full_entry; + require $full_entry.'/_define.php'; + $this->id = null; + $this->mroot = null; + } + else + { + $this->disabled[$entry] = array( + 'root' => $full_entry, + 'root_writable' => is_writable($full_entry) + ); + } + } + } + $d->close(); + } + + # Sort plugins + uasort($this->modules,array($this,'sortModules')); + + # Load translation, _prepend and ns_file + foreach ($this->modules as $id => $m) + { + if (file_exists($m['root'].'/_prepend.php')) + { + $r = require $m['root'].'/_prepend.php'; + + # If _prepend.php file returns null (ie. it has a void return statement) + if (is_null($r)) { + continue; + } + unset($r); + } + + $this->loadModuleL10N($id,$lang,'main'); + if ($ns == 'admin') { + $this->loadModuleL10Nresources($id,$lang); + } + $this->loadNsFile($id,$ns); + } + } + + public function requireDefine($dir,$id) + { + if (file_exists($dir.'/_define.php')) { + $this->id = $id; + require $dir.'/_define.php'; + $this->id = null; + } + } + + /** + This method registers a module in modules list. You should use this to + register a new module. + + $permissions is a comma separated list of permissions for your + module. If $permissions is null, only super admin has access to + this module. + + $priority is an integer. Modules are sorted by priority and name. + Lowest priority comes first. + + @param name string Module name + @param desc string Module description + @param author string Module author name + @param version string Module version + @param properties array extra properties (currently available keys : permissions, priority) + */ + public function registerModule($name,$desc,$author,$version, $properties = array()) + { + if (!is_array($properties)) { + //Fallback to legacy registerModule parameters + $args = func_get_args(); + $properties = array(); + if (isset($args[4])) { + $properties['permissions']=$args[4]; + } + if (isset($args[5])) { + $properties['priority']= (integer)$args[5]; + } + } + $properties = array_merge( + array( + 'permissions' => null, + 'priority' => 1000 + ), $properties + ); + $permissions = $properties['permissions']; + if ($this->ns == 'admin') { + if ($permissions == '' && !$this->core->auth->isSuperAdmin()) { + return; + } elseif (!$this->core->auth->check($permissions,$this->core->blog->id)) { + return; + } + } + + if ($this->id) { + $module_exists = array_key_exists($name,$this->modules_names); + $module_overwrite = $module_exists ? version_compare($this->modules_names[$name],$version,'<') : false; + if (!$module_exists || ($module_exists && $module_overwrite)) { + $this->modules_names[$name] = $version; + $this->modules[$this->id] = array_merge( + $properties, + array( + 'root' => $this->mroot, + 'name' => $name, + 'desc' => $desc, + 'author' => $author, + 'version' => $version, + 'root_writable' => is_writable($this->mroot) + ) + ); + } + else { + $path1 = path::real($this->moduleInfo($name,'root')); + $path2 = path::real($this->mroot); + $this->errors[] = sprintf( + __('%s: in [%s] and [%s]'), + ''.$name.'', + ''.$path1.'', + ''.$path2.'' + ); + } + } + } + + public function resetModulesList() + { + $this->modules = array(); + $this->modules_names = array(); + } + + public static function installPackage($zip_file,dcModules &$modules) + { + $zip = new fileUnzip($zip_file); + $zip->getList(false,'#(^|/)(__MACOSX|\.svn|\.DS_Store|\.directory|Thumbs\.db)(/|$)#'); + + $zip_root_dir = $zip->getRootDir(); + $define = ''; + if ($zip_root_dir != false) { + $target = dirname($zip_file); + $destination = $target.'/'.$zip_root_dir; + $define = $zip_root_dir.'/_define.php'; + $has_define = $zip->hasFile($define); + } else { + $target = dirname($zip_file).'/'.preg_replace('/\.([^.]+)$/','',basename($zip_file)); + $destination = $target; + $define = '_define.php'; + $has_define = $zip->hasFile($define); + } + + if ($zip->isEmpty()) { + $zip->close(); + unlink($zip_file); + throw new Exception(__('Empty module zip file.')); + } + + if (!$has_define) { + $zip->close(); + unlink($zip_file); + throw new Exception(__('The zip file does not appear to be a valid Dotclear module.')); + } + + $ret_code = 1; + + if (is_dir($destination)) + { + # test for update + $sandbox = clone $modules; + $zip->unzip($define, $target.'/_define.php'); + + $sandbox->resetModulesList(); + $sandbox->requireDefine($target,basename($destination)); + unlink($target.'/_define.php'); + $new_modules = $sandbox->getModules(); + + if (!empty($new_modules)) + { + $tmp = array_keys($new_modules); + $id = $tmp[0]; + $cur_module = $modules->getModules($id); + if (!empty($cur_module) && $new_modules[$id]['version'] != $cur_module['version']) + { + # delete old module + if (!files::deltree($destination)) { + throw new Exception(__('An error occurred during module deletion.')); + } + $ret_code = 2; + } + else + { + $zip->close(); + unlink($zip_file); + throw new Exception(sprintf(__('Unable to upgrade "%s". (same version)'),basename($destination))); + } + } + else + { + $zip->close(); + unlink($zip_file); + throw new Exception(sprintf(__('Unable to read new _define.php file'))); + } + } + $zip->unzipAll($target); + $zip->close(); + unlink($zip_file); + return $ret_code; + } + + /** + This method installs all modules having a _install file. + + @see dcModules::installModule + */ + public function installModules() + { + $res = array('success'=>array(),'failure'=>array()); + foreach ($this->modules as $id => &$m) + { + $i = $this->installModule($id,$msg); + if ($i === true) { + $res['success'][$id] = true; + } elseif ($i === false) { + $res['failure'][$id] = $msg; + } + } + + return $res; + } + + /** + This method installs module with ID $id and having a _install + file. This file should throw exception on failure or true if it installs + successfully. + + $msg is an out parameter that handle installer message. + + @param id string Module ID + @param msg string Module installer message + @return boolean + */ + public function installModule($id,&$msg) + { + try { + $i = $this->loadModuleFile($this->modules[$id]['root'].'/_install.php'); + if ($i === true) { + return true; + } + } catch (Exception $e) { + $msg = $e->getMessage(); + return false; + } + + return null; + } + + public function deleteModule($id,$disabled=false) + { + if ($disabled) { + $p =& $this->disabled; + } else { + $p =& $this->modules; + } + + if (!isset($p[$id])) { + throw new Exception(__('No such module.')); + } + + if (!files::deltree($p[$id]['root'])) { + throw new Exception(__('Cannot remove module files')); + } + } + + public function deactivateModule($id) + { + if (!isset($this->modules[$id])) { + throw new Exception(__('No such module.')); + } + + if (!$this->modules[$id]['root_writable']) { + throw new Exception(__('Cannot deactivate plugin.')); + } + + if (@file_put_contents($this->modules[$id]['root'].'/_disabled','')) { + throw new Exception(__('Cannot deactivate plugin.')); + } + } + + public function activateModule($id) + { + if (!isset($this->disabled[$id])) { + throw new Exception(__('No such module.')); + } + + if (!$this->disabled[$id]['root_writable']) { + throw new Exception(__('Cannot activate plugin.')); + } + + if (@unlink($this->disabled[$id]['root'].'/_disabled') === false) { + throw new Exception(__('Cannot activate plugin.')); + } + } + + /** + This method will search for file $file in language + $lang for module $id. + + $file should not have any extension. + + @param id string Module ID + @param lang string Language code + @param file string File name (without extension) + */ + public function loadModuleL10N($id,$lang,$file) + { + if (!$lang || !isset($this->modules[$id])) { + return; + } + + $lfile = $this->modules[$id]['root'].'/locales/%s/%s'; + if (l10n::set(sprintf($lfile,$lang,$file)) === false && $lang != 'en') { + l10n::set(sprintf($lfile,'en',$file)); + } + } + + public function loadModuleL10Nresources($id,$lang) + { + if (!$lang || !isset($this->modules[$id])) { + return; + } + + $f = l10n::getFilePath($this->modules[$id]['root'].'/locales','resources.php',$lang); + if ($f) { + $this->loadModuleFile($f); + } + } + + /** + Returns all modules associative array or only one module if $id + is present. + + @param id string Optionnal module ID + @return array + */ + public function getModules($id=null) + { + if ($id && isset($this->modules[$id])) { + return $this->modules[$id]; + } + return $this->modules; + } + + /** + Returns true if the module with ID $id exists. + + @param id string Module ID + @return boolean + */ + public function moduleExists($id) + { + return isset($this->modules[$id]); + } + + /** + Returns all disabled modules in an array + + @return array + */ + public function getDisabledModules() + { + return $this->disabled; + } + + /** + Returns root path for module with ID $id. + + @param id string Module ID + @return string + */ + public function moduleRoot($id) + { + return $this->moduleInfo($id,'root'); + } + + /** + Returns a module information that could be: + - root + - name + - desc + - author + - version + - permissions + - priority + + @param id string Module ID + @param info string Information to retrieve + @return string + */ + public function moduleInfo($id,$info) + { + return isset($this->modules[$id][$info]) ? $this->modules[$id][$info] : null; + } + + /** + Loads namespace $ns specific files for all modules. + + @param ns string Namespace name + */ + public function loadNsFiles($ns=null) + { + foreach ($this->modules as $k => $v) { + $this->loadNsFile($k,$ns); + } + } + + /** + Loads namespace $ns specific file for module with ID + $id + + @param id string Module ID + @param ns string Namespace name + */ + public function loadNsFile($id,$ns=null) + { + switch ($ns) { + case 'admin': + $this->loadModuleFile($this->modules[$id]['root'].'/_admin.php'); + break; + case 'public': + $this->loadModuleFile($this->modules[$id]['root'].'/_public.php'); + break; + case 'xmlrpc': + $this->loadModuleFile($this->modules[$id]['root'].'/_xmlrpc.php'); + break; + } + } + + public function getErrors() + { + return $this->errors; + } + + protected function loadModuleFile($________) + { + if (!file_exists($________)) { + return; + } + + self::$_k = array_keys($GLOBALS); + + foreach (self::$_k as self::$_n) { + if (!in_array(self::$_n,self::$superglobals)) { + global ${self::$_n}; + } + } + + return require $________; + } + + private function sortModules($a,$b) + { + if ($a['priority'] == $b['priority']) { + return strcasecmp($a['name'],$b['name']); + } + + return ($a['priority'] < $b['priority']) ? -1 : 1; + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/core/class.dc.namespace.php b/v2/dotclear/inc/core/class.dc.namespace.php new file mode 100644 index 0000000..cb81f6b --- /dev/null +++ b/v2/dotclear/inc/core/class.dc.namespace.php @@ -0,0 +1,308 @@ +connection
        Database connection object + protected $table; ///< string Settings table name + protected $blog_id; ///< string Blog ID + + protected $global_settings = array(); ///< array Global settings array + protected $local_settings = array(); ///< array Local settings array + protected $settings = array(); ///< array Associative settings array + protected $ns; ///< string Current namespace + + /** + Object constructor. Retrieves blog settings and puts them in $settings + array. Local (blog) settings have a highest priority than global settings. + + @param name string ID for this namespace + */ + public function __construct(&$core, $blog_id, $name, $rs=null) + { + if (preg_match('/^[a-zA-Z][a-zA-Z0-9]+$/',$name)) { + $this->ns = $name; + } else { + throw new Exception(sprintf(__('Invalid setting dcNamespace: %s'),$name)); + } + + $this->con =& $core->con; + $this->table = $core->prefix.'setting'; + $this->blog_id =& $blog_id; + + $this->getSettings($rs); + } + + private function getSettings($rs=null) + { + if ($rs == null) { + $strReq = 'SELECT blog_id, setting_id, setting_value, '. + 'setting_type, setting_label, setting_ns '. + 'FROM '.$this->table.' '. + "WHERE (blog_id = '".$this->con->escape($this->blog_id)."' ". + 'OR blog_id IS NULL) '. + "AND setting_ns = '".$this->con->escape($this->ns)."' ". + 'ORDER BY setting_id DESC '; + + try { + $rs = $this->con->select($strReq); + } catch (Exception $e) { + trigger_error(__('Unable to retrieve settings:').' '.$this->con->error(), E_USER_ERROR); + } + } + while ($rs->fetch()) + { + if ($rs->f('setting_ns') != $this->ns){ + break; + } + $id = trim($rs->f('setting_id')); + $value = $rs->f('setting_value'); + $type = $rs->f('setting_type'); + + if ($type == 'float' || $type == 'double') { + $type = 'float'; + } elseif ($type != 'boolean' && $type != 'integer') { + $type = 'string'; + } + + settype($value,$type); + + $array = $rs->blog_id ? 'local' : 'global'; + + $this->{$array.'_settings'}[$id] = array( + 'ns' => $this->ns, + 'value' => $value, + 'type' => $type, + 'label' => (string) $rs->f('setting_label'), + 'global' => $rs->blog_id == '' + ); + } + + $this->settings = $this->global_settings; + + foreach ($this->local_settings as $id => $v) { + $this->settings[$id] = $v; + } + + return true; + } + + private function settingExists($id,$global=false) + { + $array = $global ? 'global' : 'local'; + return isset($this->{$array.'_settings'}[$id]); + } + + /** + Returns setting value if exists. + + @param n string Setting name + @return mixed + */ + public function get($n) + { + if (isset($this->settings[$n]['value'])) { + return $this->settings[$n]['value']; + } + + return null; + } + + /** + Magic __get method. + @copydoc ::get + */ + public function __get($n) + { + return $this->get($n); + } + + /** + Sets a setting in $settings property. This sets the setting for script + execution time only and if setting exists. + + @param n string Setting name + @param v mixed Setting value + */ + public function set($n,$v) + { + if (isset($this->settings[$n])) { + $this->settings[$n]['value'] = $v; + } + } + + /** + Magic __set method. + @copydoc ::set + */ + public function __set($n,$v) + { + $this->set($n,$v); + } + + /** + Creates or updates a setting. + + $type could be 'string', 'integer', 'float', 'boolean' or null. If $type is + null and setting exists, it will keep current setting type. + + $value_change allow you to not change setting. Useful if you need to change + a setting label or type and don't want to change its value. + + @param id string Setting ID + @param value mixed Setting value + @param type string Setting type + @param label string Setting label + @param value_change boolean Change setting value or not + @param global boolean Setting is global + */ + public function put($id,$value,$type=null,$label=null,$value_change=true,$global=false) + { + if (!preg_match('/^[a-zA-Z][a-zA-Z0-9_]+$/',$id)) { + throw new Exception(sprintf(__('%s is not a valid setting id'),$id)); + } + + # We don't want to change setting value + if (!$value_change) + { + if (!$global && $this->settingExists($id,false)) { + $value = $this->local_settings[$id]['value']; + } elseif ($this->settingExists($id,true)) { + $value = $this->global_settings[$id]['value']; + } + } + + # Setting type + if ($type == 'double') + { + $type = 'float'; + } + elseif ($type === null) + { + if (!$global && $this->settingExists($id,false)) { + $type = $this->local_settings[$id]['type']; + } elseif ($this->settingExists($id,true)) { + $type = $this->global_settings[$id]['type']; + } else { + $type = 'string'; + } + } + elseif ($type != 'boolean' && $type != 'integer' && $type != 'float') + { + $type = 'string'; + } + + # We don't change label + if ($label == null) + { + if (!$global && $this->settingExists($id,false)) { + $label = $this->local_settings[$id]['label']; + } elseif ($this->settingExists($id,true)) { + $label = $this->global_settings[$id]['label']; + } + } + + settype($value,$type); + + $cur = $this->con->openCursor($this->table); + $cur->setting_value = ($type == 'boolean') ? (string) (integer) $value : (string) $value; + $cur->setting_type = $type; + $cur->setting_label = $label; + + #If we are local, compare to global value + if (!$global && $this->settingExists($id,true)) + { + $g = $this->global_settings[$id]; + $same_setting = $g['ns'] == $this->ns && $g['value'] == $value + && $g['type'] == $type && $g['label'] == $label; + + # Drop setting if same value as global + if ($same_setting && $this->settingExists($id,false)) { + $this->drop($id); + } elseif ($same_setting) { + return; + } + } + + if ($this->settingExists($id,$global) && $this->ns == $this->settings[$id]['ns']) + { + if ($global) { + $where = 'WHERE blog_id IS NULL '; + } else { + $where = "WHERE blog_id = '".$this->con->escape($this->blog_id)."' "; + } + + $cur->update($where."AND setting_id = '".$this->con->escape($id)."' AND setting_ns = '".$this->con->escape($this->ns)."' "); + } + else + { + $cur->setting_id = $id; + $cur->blog_id = $global ? null : $this->blog_id; + $cur->setting_ns = $this->ns; + + $cur->insert(); + } + } + + /** + Removes an existing setting. Namespace + + @param id string Setting ID + */ + public function drop($id) + { + if (!$this->ns) { + throw new Exception(__('No namespace specified')); + } + + $strReq = 'DELETE FROM '.$this->table.' '; + + if ($this->blog_id === null) { + $strReq .= 'WHERE blog_id IS NULL '; + } else { + $strReq .= "WHERE blog_id = '".$this->con->escape($this->blog_id)."' "; + } + + $strReq .= "AND setting_id = '".$this->con->escape($id)."' "; + $strReq .= "AND setting_ns = '".$this->con->escape($this->ns)."' "; + + $this->con->execute($strReq); + } + + /** + Returns $settings property content. + + @return array + */ + public function dumpSettings() + { + return $this->settings; + } + + /** + Returns $global_settings property content. + + @return array + */ + public function dumpGlobalSettings() + { + return $this->global_settings; + } + +} +?> diff --git a/v2/dotclear/inc/core/class.dc.postmedia.php b/v2/dotclear/inc/core/class.dc.postmedia.php new file mode 100644 index 0000000..2d55a2e --- /dev/null +++ b/v2/dotclear/inc/core/class.dc.postmedia.php @@ -0,0 +1,172 @@ +dcCore
        dcCore instance + protected $con; ///< connection Database connection + protected $table; ///< string Post-Media table name + + /** + Object constructor. + + @param core dcCore dcCore instance + @param type string Media type filter + */ + public function __construct($core,$type='') + { + $this->core =& $core; + $this->con =& $core->con; + $this->table = $this->core->prefix.'post_media'; + } + + /** + Returns media items attached to a blog post. Result is an array containing + fileItems objects. + + @param post_id integer Post ID + @param media_id integer Optionnal media ID + @return array Array of fileItems + */ + public function getPostMedia($params=array()) + { + $strReq = + 'SELECT M.media_file, M.media_id, M.media_path, M.media_title, M.media_meta, M.media_dt, '. + 'M.media_creadt, M.media_upddt, M.media_private, M.user_id, PM.post_id '; + + if (!empty($params['columns']) && is_array($params['columns'])) { + $strReq .= implode(', ',$params['columns']).', '; + } + + $strReq .= + 'FROM '.$this->core->prefix.'media M '. + 'INNER JOIN '.$this->table.' PM ON (M.media_id = PM.media_id) '; + + if (!empty($params['from'])) { + $strReq .= $params['from'].' '; + } + + $where=''; + if (isset($params['post_id'])) { + $where[]="PM.post_id ".$this->con->in($params['post_id']); + } + if (isset($params['media_id'])) { + $where[]="M.media_id ".$this->con->in($params['media_id']); + } + if (isset($params['media_path'])) { + $where[]="M.media_path ".$this->con->in($params['media_path']); + } + if (isset($params['link_type'])) { + $where[]="PM.link_type ".$this->con->in($params['link_type']); + } else { + $where[]="PM.link_type='attachment'"; + } + + $strReq .= 'WHERE '.join('AND ',$where).' '; + + if (isset($params['sql'])) { + $strReq .= $params['sql']; + } + //echo $strReq; exit; + $rs = $this->con->select($strReq); + + return $rs; + } + + /** + Attaches a media to a post. + + @param post_id integer Post ID + @param media_id integer Optionnal media ID + */ + public function addPostMedia($post_id,$media_id,$link_type='attachment') + { + $post_id = (integer) $post_id; + $media_id = (integer) $media_id; + + $f = $this->getPostMedia(array('post_id'=>$post_id,'media_id'=>$media_id,'link_type'=>$link_type)); + + if (!$f->isEmpty()) { + return; + } + + $cur = $this->con->openCursor($this->table); + $cur->post_id = $post_id; + $cur->media_id = $media_id; + $cur->link_type = $link_type; + + $cur->insert(); + $this->core->blog->triggerBlog(); + } + + /** + Detaches a media from a post. + + @param post_id integer Post ID + @param media_id integer Optionnal media ID + */ + public function removePostMedia($post_id,$media_id,$link_type=null) + { + $post_id = (integer) $post_id; + $media_id = (integer) $media_id; + + $strReq = 'DELETE FROM '.$this->table.' '. + 'WHERE post_id = '.$post_id.' '. + 'AND media_id = '.$media_id.' '; + if ($link_type != null) { + $strReq .= "AND link_type = '".$this->con->escape($link_type)."'"; + } + $this->con->execute($strReq); + $this->core->blog->triggerBlog(); + } + + /** + Returns media items attached to a blog post. Result is an array containing + fileItems objects. + + @param post_id integer Post ID + @param media_id integer Optionnal media ID + @return array Array of fileItems + */ + public function getLegacyPostMedia($post_id,$media_id=null) + { + $post_id = (integer) $post_id; + + $strReq = + 'SELECT media_file, M.media_id, media_path, media_title, media_meta, media_dt, '. + 'media_creadt, media_upddt, media_private, user_id '. + 'FROM '.$this->table.' M '. + 'INNER JOIN '.$this->table_ref.' PM ON (M.media_id = PM.media_id) '. + "WHERE media_path = '".$this->path."' ". + 'AND post_id = '.$post_id.' '; + + if ($media_id) { + $strReq .= 'AND M.media_id = '.(integer) $media_id.' '; + } + + $rs = $this->con->select($strReq); + + $res = array(); + + while ($rs->fetch()) { + $f = $this->fileRecord($rs); + if ($f !== null) { + $res[] = $f; + } + } + + return $res; + } + +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/core/class.dc.prefs.php b/v2/dotclear/inc/core/class.dc.prefs.php new file mode 100644 index 0000000..f38af35 --- /dev/null +++ b/v2/dotclear/inc/core/class.dc.prefs.php @@ -0,0 +1,134 @@ +connection Database connection object + protected $table; ///< string Prefs table name + protected $user_id; ///< string User ID + + protected $workspaces = array(); ///< array Associative workspaces array + + protected $ws; ///< string Current workspace + + /** + Object constructor. Retrieves user prefs and puts them in $workspaces + array. Local (user) prefs have a highest priority than global prefs. + + @param core dcCore dcCore object + @param user_id string User ID + */ + public function __construct($core,$user_id) + { + $this->con =& $core->con; + $this->table = $core->prefix.'pref'; + $this->user_id =& $user_id; + try {$this->loadPrefs();} catch (Exception $e) { + if (version_compare($core->getVersion('core'),'2.3','>')) { + trigger_error(__('Unable to retrieve workspaces:').' '.$this->con->error(), E_USER_ERROR); + } + } + } + + /** + Retrieves all workspaces (and their prefs) from database, with one query. + */ + private function loadPrefs() + { + $strReq = 'SELECT user_id, pref_id, pref_value, '. + 'pref_type, pref_label, pref_ws '. + 'FROM '.$this->table.' '. + "WHERE user_id = '".$this->con->escape($this->user_id)."' ". + 'OR user_id IS NULL '. + 'ORDER BY pref_ws ASC, pref_id ASC'; + try { + $rs = $this->con->select($strReq); + } catch (Exception $e) { + throw $e; + } + + /* Prevent empty tables (install phase, for instance) */ + if ($rs->isEmpty()) { + return; + } + + do { + $ws = trim($rs->f('pref_ws')); + if (!$rs->isStart()) { + // we have to go up 1 step, since workspaces construction performs a fetch() + // at very first time + $rs->movePrev(); + } + $this->workspaces[$ws] = new dcWorkspace($GLOBALS['core'], $this->user_id, $ws,$rs); + } while(!$rs->isStart()); + } + + + /** + Create a new workspace. If the workspace already exists, return it without modification. + + @param ws string Workspace name + @return dcWorkspace The workspace created + */ + public function addWorkspace($ws) + { + if (!array_key_exists($ws, $this->workspaces)) { + $this->workspaces[$ws] = new dcWorkspace($GLOBALS['core'], $this->user_id, $ws); + } + return $this->workspaces[$ws]; + } + + /** + Returns full workspace with all prefs pertaining to it. + + @param ws string Workspace name + @return dcWorkspace + */ + public function get($ws) + { + if (array_key_exists($ws, $this->workspaces)) { + return $this->workspaces[$ws]; + } + + return null; + } + + /** + Magic __get method. + @copydoc ::get + */ + public function __get($n) + { + return $this->get($n); + } + + /** + Returns $workspaces property content. + + @return array + */ + public function dumpWorkspaces() + { + return $this->workspaces; + } + +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/core/class.dc.rest.php b/v2/dotclear/inc/core/class.dc.rest.php new file mode 100644 index 0000000..e9334f9 --- /dev/null +++ b/v2/dotclear/inc/core/class.dc.rest.php @@ -0,0 +1,52 @@ +dcCore dcCore instance + */ + public function __construct($core) + { + parent::__construct(); + + $this->core =& $core; + } + + /** + Rest method call. + + @param name string Method name + @param get array GET parameters copy + @param post array POST parameters copy + @return mixed Rest method result + */ + protected function callFunction($name,$get,$post) + { + if (isset($this->functions[$name])) { + return call_user_func($this->functions[$name],$this->core,$get,$post); + } + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/core/class.dc.rs.extensions.php b/v2/dotclear/inc/core/class.dc.rs.extensions.php new file mode 100644 index 0000000..ad87acf --- /dev/null +++ b/v2/dotclear/inc/core/class.dc.rs.extensions.php @@ -0,0 +1,870 @@ +boolean + */ + public static function isEditable($rs) + { + # If user is admin or contentadmin, true + if ($rs->core->auth->check('contentadmin',$rs->core->blog->id)) { + return true; + } + + # No user id in result ? false + if (!$rs->exists('user_id')) { + return false; + } + + # If user is usage and owner of the entrie + if ($rs->core->auth->check('usage',$rs->core->blog->id) + && $rs->user_id == $rs->core->auth->userID()) { + return true; + } + + return false; + } + + /** + Returns whether post is deletable + + @param rs Invisible parameter + @return boolean + */ + public static function isDeletable($rs) + { + # If user is admin, or contentadmin, true + if ($rs->core->auth->check('contentadmin',$rs->core->blog->id)) { + return true; + } + + # No user id in result ? false + if (!$rs->exists('user_id')) { + return false; + } + + # If user has delete rights and is owner of the entrie + if ($rs->core->auth->check('delete',$rs->core->blog->id) + && $rs->user_id == $rs->core->auth->userID()) { + return true; + } + + return false; + } + + /** + Returns whether post is the first one of its day. + + @param rs Invisible parameter + @return boolean + */ + public static function firstPostOfDay($rs) + { + if ($rs->isStart()) { + return true; + } + + $cdate = date('Ymd',strtotime($rs->post_dt)); + $rs->movePrev(); + $ndate = date('Ymd',strtotime($rs->post_dt)); + $rs->moveNext(); + return $ndate != $cdate; + } + + /** + Returns whether post is the last one of its day. + + @param rs Invisible parameter + @return boolean + */ + public static function lastPostOfDay($rs) + { + if ($rs->isEnd()) { + return true; + } + + $cdate = date('Ymd',strtotime($rs->post_dt)); + $rs->moveNext(); + $ndate = date('Ymd',strtotime($rs->post_dt)); + $rs->movePrev(); + return $ndate != $cdate; + } + + /** + Returns whether comments are enabled on post. + + @param rs Invisible parameter + @return boolean + */ + public static function commentsActive($rs) + { + return + $rs->core->blog->settings->system->allow_comments + && $rs->post_open_comment + && ($rs->core->blog->settings->system->comments_ttl == 0 || + time()-($rs->core->blog->settings->system->comments_ttl*86400) < $rs->getTS()); + } + + /** + Returns whether trackbacks are enabled on post. + + @param rs Invisible parameter + @return boolean + */ + public static function trackbacksActive($rs) + { + return + $rs->core->blog->settings->system->allow_trackbacks + && $rs->post_open_tb + && ($rs->core->blog->settings->system->trackbacks_ttl == 0 || + time()-($rs->core->blog->settings->system->trackbacks_ttl*86400) < $rs->getTS()); + } + + /** + Returns whether post has at least one comment. + + @param rs Invisible parameter + @return boolean + */ + public static function hasComments($rs) + { + return $rs->nb_comment > 0; + } + + /** + Returns whether post has at least one trackbacks. + + @return boolean + */ + public static function hasTrackbacks($rs) + { + return $rs->nb_trackback > 0; + } + + /** + Returns full post URL. + + @param rs Invisible parameter + @return string + */ + public static function getURL($rs) + { + return $rs->core->blog->url.$rs->core->getPostPublicURL( + $rs->post_type,html::sanitizeURL($rs->post_url) + ); + } + + /** + Returns full post category URL. + + @param rs Invisible parameter + @return string + */ + public static function getCategoryURL($rs) + { + return $rs->core->blog->url.$rs->core->url->getURLFor('category',html::sanitizeURL($rs->cat_url)); + } + + /** + Returns whether post has an excerpt. + + @param rs Invisible parameter + @return boolean + */ + public static function isExtended($rs) + { + return $rs->post_excerpt_xhtml != ''; + } + + /** + Returns post timestamp. + + @param rs Invisible parameter + @param type string (dt|upddt|creadt) defaults to post_dt + @return integer + */ + public static function getTS($rs,$type='') + { + if ($type == 'upddt') { + return strtotime($rs->post_upddt); + } elseif ($type == 'creadt') { + return strtotime($rs->post_creadt); + } else { + return strtotime($rs->post_dt); + } + } + + /** + Returns post date formating according to the ISO 8601 standard. + + @param rs Invisible parameter + @param type string (dt|upddt|creadt) defaults to post_dt + @return string + */ + public static function getISO8601Date($rs,$type='') + { + if ($type == 'upddt' || $type == 'creadt') { + return dt::iso8601($rs->getTS($type)+dt::getTimeOffset($rs->post_tz),$rs->post_tz); + } else { + return dt::iso8601($rs->getTS(),$rs->post_tz); + } + } + + /** + Returns post date formating according to RFC 822. + + @param rs Invisible parameter + @param type string (dt|upddt|creadt) defaults to post_dt + @return string + */ + public static function getRFC822Date($rs,$type='') + { + if ($type == 'upddt' || $type == 'creadt') { + return dt::rfc822($rs->getTS($type)+dt::getTimeOffset($rs->post_tz),$rs->post_tz); + } else { + return dt::rfc822($rs->getTS($type),$rs->post_tz); + } + } + + /** + Returns post date with $format as formatting pattern. If format + is empty, uses date_format blog setting. + + @param rs Invisible parameter + @param format string Date format pattern + @param type string (dt|upddt|creadt) defaults to post_dt + @return string + */ + public static function getDate($rs,$format,$type='') + { + if (!$format) { + $format = $rs->core->blog->settings->system->date_format; + } + + if ($type == 'upddt') { + return dt::dt2str($format,$rs->post_upddt,$rs->post_tz); + } elseif ($type == 'creadt') { + return dt::dt2str($format,$rs->post_creadt,$rs->post_tz); + } else { + return dt::dt2str($format,$rs->post_dt); + } + } + + /** + Returns post time with $format as formatting pattern. If format + is empty, uses time_format blog setting. + + @param rs Invisible parameter + @param format string Time format pattern + @param type string (dt|upddt|creadt) defaults to post_dt + @return string + */ + public static function getTime($rs,$format,$type='') + { + if (!$format) { + $format = $rs->core->blog->settings->system->time_format; + } + + if ($type == 'upddt') { + return dt::dt2str($format,$rs->post_upddt,$rs->post_tz); + } elseif ($type == 'creadt') { + return dt::dt2str($format,$rs->post_creadt,$rs->post_tz); + } else { + return dt::dt2str($format,$rs->post_dt); + } + } + + /** + Returns author common name using user_id, user_name, user_firstname and + user_displayname fields. + + @param rs Invisible parameter + @return string + */ + public static function getAuthorCN($rs) + { + return dcUtils::getUserCN($rs->user_id, $rs->user_name, + $rs->user_firstname, $rs->user_displayname); + } + + /** + Returns author common name with a link if he specified one in its + preferences. + + @param rs Invisible parameter + @return string + */ + public static function getAuthorLink($rs) + { + $res = '%1$s'; + $url = $rs->user_url; + if ($url) { + $res = '%1$s'; + } + + return sprintf($res,html::escapeHTML($rs->getAuthorCN()),html::escapeHTML($url)); + } + + /** + Returns author e-mail address. If $encoded is true, "@" sign is + replaced by "%40" and "." by "%2e". + + @param rs Invisible parameter + @param encoded boolean Encode address. + @return string + */ + public static function getAuthorEmail($rs,$encoded=true) + { + if ($encoded) { + return strtr($rs->user_email,array('@'=>'%40','.'=>'%2e')); + } + return $rs->user_email; + } + + /** + Returns post feed unique ID. + + @param rs Invisible parameter + @return string + */ + public static function getFeedID($rs) + { + return 'urn:md5:'.md5($rs->core->blog->uid.$rs->post_id); + + $url = parse_url($rs->core->blog->url); + $date_part = date('Y-m-d',strtotime($rs->post_creadt)); + + return 'tag:'.$url['host'].','.$date_part.':'.$rs->post_id; + } + + /** + Returns trackback RDF information block in HTML comment. + + @param rs Invisible parameter + @return string + */ + public static function getTrackbackData($rs) + { + return + "\n". + "\n"; + } + + /** + Returns post trackback full URL. + + @param rs Invisible parameter + @return string + */ + public static function getTrackbackLink($rs) + { + return $rs->core->blog->url.$rs->core->url->getURLFor('trackback',$rs->post_id); + } + + /** + Returns post content. If $absolute_urls is true, appends full + blog URL to each relative post URLs. + + @param rs Invisible parameter + @param absolute_urls boolean With absolute URLs + @return string + */ + public static function getContent($rs,$absolute_urls=false) + { + if ($absolute_urls) { + return html::absoluteURLs($rs->post_content_xhtml,$rs->getURL()); + } else { + return $rs->post_content_xhtml; + } + } + + /** + Returns post excerpt. If $absolute_urls is true, appends full + blog URL to each relative post URLs. + + @param rs Invisible parameter + @param absolute_urls boolean With absolute URLs + @return string + */ + public static function getExcerpt($rs,$absolute_urls=false) + { + if ($absolute_urls) { + return html::absoluteURLs($rs->post_excerpt_xhtml,$rs->getURL()); + } else { + return $rs->post_excerpt_xhtml; + } + } + + /** + Returns post media count using a subquery. + + @param rs Invisible parameter + @return integer + */ + public static function countMedia($rs) + { + if (isset($rs->_nb_media[$rs->index()])) + { + return $rs->_nb_media[$rs->index()]; + } + else + { + $strReq = + 'SELECT count(media_id) '. + 'FROM '.$rs->core->prefix.'post_media '. + 'WHERE post_id = '.(integer) $rs->post_id.' '; + + $res = (integer) $rs->core->con->select($strReq)->f(0); + $rs->_nb_media[$rs->index()] = $res; + return $res; + } + } +} + +/** +@ingroup DC_CORE +@brief Dotclear comment record helpers. + +This class adds new methods to database comment results. +You can call them on every record comming from dcBlog::getComments and similar +methods. + +@warning You should not give the first argument (usualy $rs) of every described +function. +*/ +class rsExtComment +{ + /** + Returns comment date with $format as formatting pattern. If + format is empty, uses date_format blog setting. + + @param rs Invisible parameter + @param format string Date format pattern + @param type string (dt|upddt) defaults to comment_dt + @return string + */ + public static function getDate($rs,$format,$type='') + { + if (!$format) { + $format = $rs->core->blog->settings->system->date_format; + } + + if ($type == 'upddt') { + return dt::dt2str($format,$rs->comment_upddt,$rs->comment_tz); + } else { + return dt::dt2str($format,$rs->comment_dt); + } + } + + /** + Returns comment time with $format as formatting pattern. If + format is empty, uses time_format blog setting. + + @param rs Invisible parameter + @param format string Date format pattern + @param type string (dt|upddt) defaults to comment_dt + @return string + */ + public static function getTime($rs,$format,$type='') + { + if (!$format) { + $format = $rs->core->blog->settings->system->time_format; + } + + if ($type == 'upddt') { + return dt::dt2str($format,$rs->comment_updt,$rs->comment_tz); + } else { + return dt::dt2str($format,$rs->comment_dt); + } + } + + /** + Returns comment timestamp. + + @param rs Invisible parameter + @param type string (dt|upddt) defaults to comment_dt + @return integer + */ + public static function getTS($rs,$type='') + { + if ($type == 'upddt') { + return strtotime($rs->comment_upddt); + } else { + return strtotime($rs->comment_dt); + } + } + + /** + Returns comment date formating according to the ISO 8601 standard. + + @param rs Invisible parameter + @param type string (dt|upddt) defaults to comment_dt + @return string + */ + public static function getISO8601Date($rs,$type='') + { + if ($type == 'upddt') { + return dt::iso8601($rs->getTS($type)+dt::getTimeOffset($rs->comment_tz),$rs->comment_tz); + } else { + return dt::iso8601($rs->getTS(),$rs->comment_tz); + } + } + + /** + Returns comment date formating according to RFC 822. + + @param rs Invisible parameter + @param type string (dt|upddt) defaults to comment_dt + @return string + */ + public static function getRFC822Date($rs,$type='') + { + if ($type == 'upddt') { + return dt::rfc822($rs->getTS($type)+dt::getTimeOffset($rs->comment_tz),$rs->comment_tz); + } else { + return dt::rfc822($rs->getTS(),$rs->comment_tz); + } + } + + /** + Returns comment content. If $absolute_urls is true, appends full + blog URL to each relative post URLs. + + @param rs Invisible parameter + @param absolute_urls boolean With absolute URLs + @return string + */ + public static function getContent($rs,$absolute_urls=false) + { + $res = $rs->comment_content; + + if ($rs->core->blog->settings->system->comments_nofollow) { + $res = preg_replace_callback('##ms',array('self','noFollowURL'),$res); + } + + if ($absolute_urls) { + $res = html::absoluteURLs($res,$rs->getPostURL()); + } + + return $res; + } + + private static function noFollowURL($m) + { + if (preg_match('/rel="nofollow"/',$m[1])) { + return $m[0]; + } + + return ''; + } + + /** + Returns comment author link to his website if he specified one. + + @param rs Invisible parameter + @return string + */ + public static function getAuthorURL($rs) + { + if (trim($rs->comment_site)) { + return trim($rs->comment_site); + } + } + + /** + Returns comment post full URL. + + @param rs Invisible parameter + @return string + */ + public static function getPostURL($rs) + { + return $rs->core->blog->url.$rs->core->getPostPublicURL( + $rs->post_type,html::sanitizeURL($rs->post_url) + ); + } + + /** + Returns comment author name in a link to his website if he specified one. + + @param rs Invisible parameter + @return string + */ + public static function getAuthorLink($rs) + { + $res = '%1$s'; + $url = $rs->getAuthorURL(); + if ($url) { + $res = '%1$s'; + } + + $nofollow = ''; + if ($rs->core->blog->settings->system->comments_nofollow) { + $nofollow = ' rel="nofollow"'; + } + + return sprintf($res,html::escapeHTML($rs->comment_author),html::escapeHTML($url),$nofollow); + } + + /** + Returns comment author e-mail address. If $encoded is true, + "@" sign is replaced by "%40" and "." by "%2e". + + @param rs Invisible parameter + @param encoded boolean Encode address. + @return string + */ + public static function getEmail($rs,$encoded=true) + { + if ($encoded) { + return strtr($rs->comment_email,array('@'=>'%40','.'=>'%2e')); + } + return $rs->comment_email; + } + + /** + Returns trackback site title if comment is a trackback. + + @param rs Invisible parameter + @return string + */ + public static function getTrackbackTitle($rs) + { + if ($rs->comment_trackback == 1 && + preg_match('|

        (.*?)

        |msU',$rs->comment_content, + $match)) { + return html::decodeEntities($match[1]); + } + } + + /** + Returns trackback content if comment is a trackback. + + @param rs Invisible parameter + @return string + */ + public static function getTrackbackContent($rs) + { + if ($rs->comment_trackback == 1) { + return preg_replace('|

        .*?

        |msU','', + $rs->comment_content); + } + } + + /** + Returns comment feed unique ID. + + @param rs Invisible parameter + @return string + */ + public static function getFeedID($rs) + { + return 'urn:md5:'.md5($rs->core->blog->uid.$rs->comment_id); + + $url = parse_url($rs->core->blog->url); + $date_part = date('Y-m-d',strtotime($rs->comment_dt)); + + return 'tag:'.$url['host'].','.$date_part.':'.$rs->comment_id; + } + + /** + Returns whether comment is from the post author. + + @param rs Invisible parameter + @return boolean + */ + public static function isMe($rs) + { + return + $rs->comment_email && $rs->comment_site && + $rs->comment_email == $rs->user_email && + $rs->comment_site == $rs->user_url; + } +} + +/** +@ingroup DC_CORE +@brief Dotclear dates record helpers. + +This class adds new methods to database dates results. +You can call them on every record comming from dcBlog::getDates. + +@warning You should not give the first argument (usualy $rs) of every described +function. +*/ +class rsExtDates +{ + /** + @param rs Invisible parameter + @return integer Date timestamp + */ + public static function ts($rs) + { + return strtotime($rs->dt); + } + + /** + @param rs Invisible parameter + @return string Date year + */ + public static function year($rs) + { + return date('Y',strtotime($rs->dt)); + } + + /** + @param rs Invisible parameter + @return string Date month + */ + public static function month($rs) + { + return date('m',strtotime($rs->dt)); + } + + /** + @param rs Invisible parameter + @return integer Date day + */ + public static function day($rs) + { + return date('d',strtotime($rs->dt)); + } + + /** + Returns date month archive full URL. + + @param rs Invisible parameter + @param core dcCore dcCore instance + @return integer + */ + public static function url($rs,$core) + { + $url = date('Y/m',strtotime($rs->dt)); + + return $core->blog->url.$core->url->getURLFor('archive',$url); + } + + /** + Returns whether date is the first of year. + + @param rs Invisible parameter + @return boolean + */ + public static function yearHeader($rs) + { + if ($rs->isStart()) { + return true; + } + + $y = $rs->year(); + $rs->movePrev(); + $py = $rs->year(); + $rs->moveNext(); + + return $y != $py; + } + + /** + Returns whether date is the last of year. + + @param rs Invisible parameter + @return boolean + */ + public static function yearFooter($rs) + { + if ($rs->isEnd()) { + return true; + } + + $y = $rs->year(); + if ($rs->moveNext()) { + $ny = $rs->year(); + $rs->movePrev(); + return $y != $ny; + } + return false; + + } +} + +/** +@ingroup DC_CORE +@brief Dotclear dates record helpers. + +This class adds new methods to database dates results. +You can call them on every record comming from dcAuth::checkUser and +dcCore::getUsers. + +@warning You should not give the first argument (usualy $rs) of every described +function. +*/ +class rsExtUser +{ + /** + Returns a user option. + + @param rs Invisible parameter + @param name string Option name + @return string + */ + public static function option($rs,$name) + { + $options = self::options($rs); + + if (isset($options[$name])) { + return $options[$name]; + } + return null; + } + + /** + Returns all user options. + + @param rs Invisible parameter + @return array + */ + public static function options($rs) + { + $options = @unserialize($rs->user_options); + if (is_array($options)) { + return $options; + } + return array(); + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/core/class.dc.settings.php b/v2/dotclear/inc/core/class.dc.settings.php new file mode 100644 index 0000000..1924085 --- /dev/null +++ b/v2/dotclear/inc/core/class.dc.settings.php @@ -0,0 +1,384 @@ +connection Database connection object + protected $table; ///< string Settings table name + protected $blog_id; ///< string Blog ID + + protected $namespaces = array(); ///< array Associative namespaces array + + protected $ns; ///< string Current namespace + + /** + Object constructor. Retrieves blog settings and puts them in $namespaces + array. Local (blog) settings have a highest priority than global settings. + + @param core dcCore dcCore object + @param blog_id string Blog ID + */ + public function __construct($core,$blog_id) + { + $this->con =& $core->con; + $this->table = $core->prefix.'setting'; + $this->blog_id =& $blog_id; + $this->loadSettings(); + } + + /** + Retrieves all namespaces (and their settings) from database, with one query. + */ + private function loadSettings() + { + $strReq = 'SELECT blog_id, setting_id, setting_value, '. + 'setting_type, setting_label, setting_ns '. + 'FROM '.$this->table.' '. + "WHERE blog_id = '".$this->con->escape($this->blog_id)."' ". + 'OR blog_id IS NULL '. + 'ORDER BY setting_ns ASC, setting_id DESC'; + try { + $rs = $this->con->select($strReq); + } catch (Exception $e) { + trigger_error(__('Unable to retrieve namespaces:').' '.$this->con->error(), E_USER_ERROR); + } + + /* Prevent empty tables (install phase, for instance) */ + if ($rs->isEmpty()) { + return; + } + + do { + $ns = trim($rs->f('setting_ns')); + if (!$rs->isStart()) { + // we have to go up 1 step, since namespaces construction performs a fetch() + // at very first time + $rs->movePrev(); + } + $this->namespaces[$ns] = new dcNamespace($GLOBALS['core'], $this->blog_id, $ns,$rs); + } while(!$rs->isStart()); + } + + + /** + Create a new namespace. If the namespace already exists, return it without modification. + + @param ns string Namespace name + @return dcNamespace The namespace created + */ + public function addNamespace($ns) + { + if (!array_key_exists($ns, $this->namespaces)) { + $this->namespaces[$ns] = new dcNamespace($GLOBALS['core'], $this->blog_id, $ns); + } + return $this->namespaces[$ns]; + } + + /** + Returns full namespace with all settings pertaining to it. + + @param ns string Namespace name + @return dcNamespace + */ + public function get($ns) + { + return $this->namespaces[$ns]; + } + + /** + Magic __get method. + @copydoc ::get + */ + public function __get($n) + { + if (!array_key_exists($n, $this->namespaces)) { + // For backward compatibility only: the developer tried to access + // a setting directly, without passing via a namespace. + $this->raiseDeprecated('old_style_get'); + return $this->getSetting($n); + } + return $this->get($n); + } + + /** + Magic __set method. + @copydoc ::set + */ + public function __set($n,$v) + { + $this->set($n,$v); + } + + /** + Returns $namespaces property content. + + @return array + */ + public function dumpNamespaces() + { + return $this->namespaces; + } + + /** + Raises a E_USER_NOTICE errror for deprecated functions. + This allows the developer to know he's been using deprecated functions. + + @param name string Name of the deprecated function that was called. + */ + private function raiseDeprecated($name) + { + if (DC_DEBUG) { + $trace = debug_backtrace(); + array_shift($trace); + $grand = array_shift($trace); + $msg = 'Deprecated function called. ('; + $msg .= 'dcSettings::'.$name . ' was called from '.$grand['file'].' ['.$grand['line'].'])'; + trigger_error($msg, E_USER_NOTICE); + } + } + + /** + @deprecated Please set your settings via $core->blog->settings->{namespace}->{setting} + + Sets a setting in $settings property. This sets the setting for script + execution time only and if setting exists. + + @param n string Setting name + @param v mixed Setting value + */ + public function set($n,$v) + { + // For backward compatibility only: the developer tried to access + // a setting directly, without passing via a namespace. + $this->raiseDeprecated('old_style_set'); + + if (!$this->ns) { + throw new Exception(__('No namespace specified')); + } + + if (isset($this->namespaces[$this->ns]->$n)) { + $this->namespaces[$this->ns]->$n['value'] = $v; + } else { + $this->namespaces[$this->ns]->$n = array( + 'ns' => $this->ns, + 'value' => $v, + 'type' => gettype($n), + 'label' => '', + 'global' => false + ); + } + } + + /** + @deprecated Please access your settings via $core->blog->settings->{namespace}->... + + Sets a working namespace. You should do this before accessing any setting. + + @param ns string Namespace name + */ + public function setNamespace($ns) + { + $this->raiseDeprecated('setNamespace'); + if (preg_match('/^[a-zA-Z][a-zA-Z0-9]+$/',$ns)) { + $this->ns = $ns; + } else { + throw new Exception(sprintf(__('Invalid setting namespace: %s'),$ns)); + } + } + + /** + @deprecated Please set your settings via $core->blog->settings->{namespace}->put() + + Creates or updates a setting. + + $type could be 'string', 'integer', 'float', 'boolean' or null. If $type is + null and setting exists, it will keep current setting type. + + $value_change allow you to not change setting. Useful if you need to change + a setting label or type and don't want to change its value. + + Don't forget to set namespace before calling this method. + + @param id string Setting ID + @param value mixed Setting value + @param type string Setting type + @param label string Setting label + @param value_change boolean Change setting value or not + @param global boolean Setting is global + */ + public function put($id,$value,$type=null,$label=null,$value_change=true,$global=false) + { + $this->raiseDeprecated('put'); + if (!$this->ns) { + throw new Exception(__('No namespace specified')); + } + if (!isset($this->namespaces[$this->ns])) { + // Create namespace if needed + $this->namespaces[$this->ns] = new dcNamespace($GLOBALS['core'], $this->blog_id, $this->ns); + } + $this->namespaces[$this->ns]->put($id, $value, $type, $label, $value_change, $global); + } + + /** + @deprecated Please get your settings via $core->blog->settings->{namespace}->{setting} + + Returns setting value if exists. + + @param n string Setting name + @return mixed + */ + public function getSetting($n) + { + if ($this->namespaces['system']->get($n) != null) { + // Give preference to system settings + return $this->namespaces['system']->get($n); + } else { + // Parse all the namespaces + foreach (array_keys($this->namespaces) as $id => $ns) { + if ($this->namespaces[$ns]->get($n) != null) { + // Return the first setting with matching name + return $this->namespaces[$ns]->get($n); + } + } + } + + return null; + } + + /** + @deprecated Please get your settings via $core->blog->settings->{namespace}->dumpSettings + + Returns all settings content. + + @return array + */ + public function dumpSettings() + { + // For backward compatibility only: the developer tried to access + // the settings directly, without passing via a namespace. + $this->raiseDeprecated('dumpSettings'); + + $settings = array(); + // Parse all the namespaces + foreach (array_keys($this->namespaces) as $id => $ns) { + $settings = array_merge($settings, $this->namespaces[$ns]->dumpSettings()); + } + + return $settings; + } + + /** + @deprecated Please get your settings via $core->blog->settings->{namespace}->dumpGlobalSettings + + Returns all global settings content. + + @return array + */ + public function dumpGlobalSettings() + { + // For backward compatibility only: the developer tried to access + // the settings directly, without passing via a namespace. + $this->raiseDeprecated('dumpGlobalSettings'); + + $settings = array(); + // Parse all the namespaces + foreach (array_keys($this->namespaces) as $id => $ns) { + $settings = array_merge($settings, $this->namespaces[$ns]->dumpGlobalSettings()); + } + + return $settings; + } + + /** + Returns a list of settings matching given criteria, for any blog. + $params is an array taking the following + optionnal parameters: + + - ns : retrieve setting from given namespace + - id : retrieve only settings corresponding to the given id + + @param params array Parameters + @return record A record + */ + public function getGlobalSettings($params=array()) + { + $strReq = "SELECT * from ".$this->table." "; + $where = array(); + if (!empty($params['ns'])) { + $where[] = "setting_ns = '".$this->con->escape($params['ns'])."'"; + } + if (!empty($params['id'])) { + $where[] = "setting_id = '".$this->con->escape($params['id'])."'"; + } + if (isset($params['blog_id'])) { + if (!empty($params['blog_id'])) { + $where[] = "blog_id = '".$this->con->escape($params['blog_id'])."'"; + } else { + $where[] = "blog_id IS NULL"; + } + } + if (count($where) != 0) { + $strReq .= " WHERE ".join(" AND ", $where); + } + $strReq .= " ORDER by blog_id"; + return $this->con->select($strReq); + } + + /** + Updates a setting from a given record + + @param rs record the setting to update + */ + public function updateSetting($rs) + { + $cur = $this->con->openCursor($this->table); + $cur->setting_id = $rs->setting_id; + $cur->setting_value = $rs->setting_value; + $cur->setting_type = $rs->setting_type; + $cur->setting_label = $rs->setting_label; + $cur->blog_id = $rs->blog_id; + $cur->setting_ns = $rs->setting_ns; + if ($cur->blog_id == null) { + $where = 'WHERE blog_id IS NULL '; + } else { + $where = "WHERE blog_id = '".$this->con->escape($cur->blog_id)."' "; + } + $cur->update($where."AND setting_id = '".$this->con->escape($cur->setting_id)."' AND setting_ns = '".$this->con->escape($cur->setting_ns)."' "); + } + + /** + Drops a setting from a given record + + @param rs record the setting to drop + @return int number of deleted records (0 if setting does not exist) + */ + public function dropSetting($rs) { + $strReq = "DELETE FROM ".$this->table.' '; + if ($rs->blog_id == null) { + $strReq .= 'WHERE blog_id IS NULL '; + } else { + $strReq .= "WHERE blog_id = '".$this->con->escape($rs->blog_id)."' "; + } + $strReq .= "AND setting_id = '".$this->con->escape($rs->setting_id)."' AND setting_ns = '".$this->con->escape($rs->setting_ns)."' "; + return $this->con->execute($strReq); + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/core/class.dc.themes.php b/v2/dotclear/inc/core/class.dc.themes.php new file mode 100644 index 0000000..fda0a05 --- /dev/null +++ b/v2/dotclear/inc/core/class.dc.themes.php @@ -0,0 +1,102 @@ +$parent is a optional value to indicate them inheritance. + If $parent is null / not set, we simply fall back to + the standard behavior, by using 'default'. + + $priority is an integer. Modules are sorted by priority and name. + Lowest priority comes first. This property is currently ignored when dealing + with themes. + + @param name string Module name + @param desc string Module description + @param author string Module author name + @param version string Module version + @param properties array extra properties (currently available keys : parent, priority, standalone_config) + */ + public function registerModule($name,$desc,$author,$version,$properties = array()) + { + if (!is_array($properties)) { + //Fallback to legacy registerModule parameters + $args = func_get_args(); + $properties = array(); + if (isset($args[4])) { + $properties['parent']=$args[4]; + } + if (isset($args[5])) { + $properties['priority']= (integer)$args[5]; + } + } + $properties = array_merge( + array( + 'parent' => null, + 'priority' => 1000, + 'standalone_config' => false + ), $properties + ); + if ($this->id) { + $this->modules[$this->id] = array_merge( + $properties, + array( + 'root' => $this->mroot, + 'name' => $name, + 'desc' => $desc, + 'author' => $author, + 'version' => $version, + 'root_writable' => is_writable($this->mroot) + ) + ); + } + } + + /** + Loads namespace $ns specific file for module with ID + $id + Note : actually, only 'public' namespace is supported with themes. + + @param id string Module ID + @param ns string Namespace name + */ + public function loadNsFile($id,$ns=null) + { + switch ($ns) { + case 'public': + $parent = $this->modules[$id]['parent']; + if ($parent) { + // This is not a real cascade - since we don't call loadNsFile -, + // thus limiting inclusion process. + // TODO : See if we have to change this. + $this->loadModuleFile($this->modules[$parent]['root'].'/_public.php'); + } + $this->loadModuleFile($this->modules[$id]['root'].'/_public.php'); + break; + } + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/core/class.dc.trackback.php b/v2/dotclear/inc/core/class.dc.trackback.php new file mode 100644 index 0000000..aaf3f64 --- /dev/null +++ b/v2/dotclear/inc/core/class.dc.trackback.php @@ -0,0 +1,404 @@ +dcCore dcCore instance + public $table; ///< string done pings table name + + /** + Object constructor + + @param core dcCore dcCore instance + */ + public function __construct($core) + { + $this->core =& $core; + $this->con =& $this->core->con; + $this->table = $this->core->prefix.'ping'; + } + + /// @name Send trackbacks + //@{ + /** + Get all pings sent for a given post. + + @param post_id integer Post ID + @return record + */ + public function getPostPings($post_id) + { + $strReq = 'SELECT ping_url, ping_dt '. + 'FROM '.$this->table.' '. + 'WHERE post_id = '.(integer) $post_id; + + return $this->con->select($strReq); + } + + /** + Sends a ping to given $url. + + @param url string URL to ping + @param post_id integer Post ID + @param post_title string Post title + @param post_excerpt string Post excerpt + @param post_url string Post URL + */ + public function ping($url,$post_id,$post_title,$post_excerpt,$post_url) + { + if ($this->core->blog === null) { + return false; + } + + $post_id = (integer) $post_id; + + # Check for previously done trackback + $strReq = 'SELECT post_id, ping_url FROM '.$this->table.' '. + 'WHERE post_id = '.$post_id.' '. + "AND ping_url = '".$this->con->escape($url)."' "; + + $rs = $this->con->select($strReq); + + if (!$rs->isEmpty()) { + throw new Exception(sprintf(__('%s has still been pinged'),$url)); + } + + $data = array( + 'title' => $post_title, + 'excerpt' => $post_excerpt, + 'url' => $post_url, + 'blog_name' => trim(html::escapeHTML(html::clean($this->core->blog->name))) + //,'__debug' => false + ); + + # Ping + try + { + $http = self::initHttp($url,$path); + $http->post($path,$data,'UTF-8'); + $res = $http->getContent(); + } + catch (Exception $e) + { + throw new Exception(__('Unable to ping URL')); + } + + $pattern = + '|.*(.*)(.*)'. + '((.*)(.*))?'. + '|msU'; + + if (!preg_match($pattern,$res,$match)) + { + throw new Exception(sprintf(__('%s is not a ping URL'),$url)); + } + + $ping_error = trim($match[1]); + $ping_msg = (!empty($match[4])) ? $match[4] : ''; + + if ($ping_error != '0') { + throw new Exception(sprintf(__('%s, ping error:'),$url).' '.$ping_msg); + } else { + # Notify ping result in database + $cur = $this->con->openCursor($this->table); + $cur->post_id = $post_id; + $cur->ping_url = $url; + $cur->ping_dt = date('Y-m-d H:i:s'); + + $cur->insert(); + } + } + //@} + + /// @name Receive trackbacks + //@{ + /** + Receives a trackback and insert it as a comment of given post. + + @param post_id integer Post ID + */ + public function receive($post_id) + { + header('Content-Type: text/xml; charset=UTF-8'); + if (empty($_POST)) { + http::head(405,'Method Not Allowed'); + echo + ''."\n". + "\n". + " 1\n". + " POST request needed\n". + ""; + return; + } + + $post_id = (integer) $post_id; + + $title = !empty($_POST['title']) ? $_POST['title'] : ''; + $excerpt = !empty($_POST['excerpt']) ? $_POST['excerpt'] : ''; + $url = !empty($_POST['url']) ? $_POST['url'] : ''; + $blog_name = !empty($_POST['blog_name']) ? $_POST['blog_name'] : ''; + $charset = ''; + $comment = ''; + + $err = false; + $msg = ''; + + if ($this->core->blog === null) + { + $err = true; + $msg = 'No blog.'; + } + elseif ($url == '') + { + $err = true; + $msg = 'URL parameter is required.'; + } + elseif ($blog_name == '') { + $err = true; + $msg = 'Blog name is required.'; + } + + if (!$err) + { + $post = $this->core->blog->getPosts(array('post_id'=>$post_id,'post_type'=>'')); + + if ($post->isEmpty()) + { + $err = true; + $msg = 'No such post.'; + } + elseif (!$post->trackbacksActive()) + { + $err = true; + $msg = 'Trackbacks are not allowed for this post or weblog.'; + } + } + + if (!$err) + { + $charset = self::getCharsetFromRequest(); + + if (!$charset) { + $charset = mb_detect_encoding($title.' '.$excerpt.' '.$blog_name, + 'UTF-8,ISO-8859-1,ISO-8859-2,ISO-8859-3,'. + 'ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,'. + 'ISO-8859-9,ISO-8859-10,ISO-8859-13,ISO-8859-14,ISO-8859-15'); + } + + if (strtolower($charset) != 'utf-8') { + $title = iconv($charset,'UTF-8',$title); + $excerpt = iconv($charset,'UTF-8',$excerpt); + $blog_name = iconv($charset,'UTF-8',$blog_name); + } + + $title = trim(html::clean($title)); + $title = html::decodeEntities($title); + $title = html::escapeHTML($title); + $title = text::cutString($title,60); + + $excerpt = trim(html::clean($excerpt)); + $excerpt = html::decodeEntities($excerpt); + $excerpt = preg_replace('/\s+/ms',' ',$excerpt); + $excerpt = text::cutString($excerpt,252); + $excerpt = html::escapeHTML($excerpt).'...'; + + $blog_name = trim(html::clean($blog_name)); + $blog_name = html::decodeEntities($blog_name); + $blog_name = html::escapeHTML($blog_name); + $blog_name = text::cutString($blog_name,60); + + $url = trim(html::clean($url)); + + if (!$blog_name) { + $blog_name = 'Anonymous blog'; + } + + $comment = + "\n". + '

        '.($title ? $title : $blog_name)."

        \n". + '

        '.$excerpt.'

        '; + + $cur = $this->core->con->openCursor($this->core->prefix.'comment'); + $cur->comment_author = (string) $blog_name; + $cur->comment_site = (string) $url; + $cur->comment_content = (string) $comment; + $cur->post_id = $post_id; + $cur->comment_trackback = 1; + $cur->comment_status = $this->core->blog->settings->system->trackbacks_pub ? 1 : -1; + $cur->comment_ip = http::realIP(); + + try + { + # --BEHAVIOR-- publicBeforeTrackbackCreate + $this->core->callBehavior('publicBeforeTrackbackCreate',$cur); + if ($cur->post_id) { + $comment_id = $this->core->blog->addComment($cur); + + # --BEHAVIOR-- publicAfterTrackbackCreate + $this->core->callBehavior('publicAfterTrackbackCreate',$cur,$comment_id); + } + } + catch (Exception $e) + { + $err = 1; + $msg = 'Something went wrong : '.$e->getMessage(); + } + } + + + $debug_trace = + " \n". + ' '.$title."\n". + ' '.$excerpt."\n". + ' '.$url."\n". + ' '.$blog_name."\n". + ' '.$charset."\n". + ' '.$comment."\n". + " \n"; + + $resp = + ''."\n". + "\n". + ' '.(integer) $err."\n"; + + if ($msg) { + $resp .= ' '.$msg."\n"; + } + + if (!empty($_POST['__debug'])) { + $resp .= $debug_trace; + } + + echo $resp.""; + } + //@} + + private static function initHttp($url,&$path) + { + $client = netHttp::initClient($url,$path); + $client->setTimeout(5); + $client->setUserAgent('Dotclear - http://www.dotclear.org/'); + $client->useGzip(false); + $client->setPersistReferers(false); + + return $client; + } + + private static function getCharsetFromRequest() + { + if (isset($_SERVER['CONTENT_TYPE'])) + { + if (preg_match('|charset=([a-zA-Z0-9-]+)|',$_SERVER['CONTENT_TYPE'],$m)) { + return $m[1]; + } + } + + return null; + } + + /// @name Trackbacks auto discovery + //@{ + /** + Returns an array containing all discovered trackbacks URLs in + $text. + + @param text string Input text + @return array + */ + public function discover($text) + { + $res = array(); + + foreach ($this->getTextLinks($text) as $link) + { + if (($url = $this->getPingURL($link)) !== null) { + $res[] = $url; + } + } + + return $res; + } + //@} + + private function getTextLinks($text) + { + $res = array(); + + # href attribute on "a" tags + if (preg_match_all('/]+)>/ms', $text, $match, PREG_SET_ORDER)) + { + for ($i = 0; $i]+)>/ms', $text, $match, PREG_SET_ORDER)) + { + for ($i = 0; $iget($path); + $page_content = $http->getContent(); + } + catch (Exception $e) + { + return false; + } + + $pattern_rdf = + '/.*?'. + ''. + '.*?<\/rdf:RDF>'. + '/msi'; + + preg_match_all($pattern_rdf,$page_content,$rdf_all,PREG_SET_ORDER); + + for ($i=0; $i \ No newline at end of file diff --git a/v2/dotclear/inc/core/class.dc.update.php b/v2/dotclear/inc/core/class.dc.update.php new file mode 100644 index 0000000..e2b5975 --- /dev/null +++ b/v2/dotclear/inc/core/class.dc.update.php @@ -0,0 +1,478 @@ + null, + 'href' => null, + 'checksum' => null, + 'info' => null, + 'notify' => true + ); + + protected $cache_ttl = '-6 hours'; + protected $forced_files = array(); + + /** + * Constructor + * + * @param url string Versions file URL + * @param subject string Subject to check + * @param version string Version type + * @param cache_dir string Directory cache path + */ + public function __construct($url,$subject,$version,$cache_dir) + { + $this->url = $url; + $this->subject = $subject; + $this->version = $version; + $this->cache_file = $cache_dir.'/'.$subject.'-'.$version; + } + + /** + * Checks for Dotclear updates. + * Returns latest version if available or false. + * + * @param version string Current version to compare + * @return string Latest version if available + */ + public function check($version) + { + $this->getVersionInfo(); + $v = $this->getVersion(); + if ($v && version_compare($version,$v,'<')) { + return $v; + } + + return false; + } + + public function getVersionInfo() + { + # Check cached file + if (is_readable($this->cache_file) && filemtime($this->cache_file) > strtotime($this->cache_ttl)) + { + $c = @file_get_contents($this->cache_file); + $c = @unserialize($c); + if (is_array($c)) { + $this->version_info = $c; + return; + } + } + + $cache_dir = dirname($this->cache_file); + $can_write = (!is_dir($cache_dir) && is_writable(dirname($cache_dir))) + || (!file_exists($this->cache_file) && is_writable($cache_dir)) + || is_writable($this->cache_file); + + # If we can't write file, don't bug host with queries + if (!$can_write) { + return; + } + + if (!is_dir($cache_dir)) { + try { + files::makeDir($cache_dir); + } catch (Exception $e) { + return; + } + } + + # Try to get latest version number + try + { + $path = ''; + $client = netHttp::initClient($this->url,$path); + if ($client !== false) { + $client->setTimeout(4); + $client->setUserAgent($_SERVER['HTTP_USER_AGENT']); + $client->get($path); + + $this->readVersion($client->getContent()); + } + } + catch (Exception $e) {} + + # Create cache + file_put_contents($this->cache_file,serialize($this->version_info)); + } + + public function getVersion() + { + return $this->version_info['version']; + } + + public function getFileURL() + { + return $this->version_info['href']; + } + + public function getInfoURL() + { + return $this->version_info['info']; + } + + public function getChecksum() + { + return $this->version_info['checksum']; + } + + public function getNotify() + { + return $this->version_info['notify']; + } + + public function getForcedFiles() + { + return $this->forced_files; + } + + public function setForcedFiles() + { + $this->forced_files = func_get_args(); + } + + /** + * Sets notification flag. + */ + public function setNotify($n) + { + + if (!is_writable($this->cache_file)) { + return; + } + + $this->version_info['notify'] = (boolean) $n; + file_put_contents($this->cache_file,serialize($this->version_info)); + } + + public function checkIntegrity($digests_file,$root) + { + if (!$digests_file) { + throw new Exception(__('Digests file not found.')); + } + + $changes = $this->md5sum($root,$digests_file); + + if (!empty($changes)) { + $e = new Exception('Some files have changed.',self::ERR_FILES_CHANGED); + $e->bad_files = $changes; + throw $e; + } + + return true; + } + + /** + * Downloads new version to destination $dest. + */ + public function download($dest) + { + $url = $this->getFileURL(); + + if (!$url) { + throw new Exception(__('No file to download')); + } + + if (!is_writable(dirname($dest))) { + throw new Exception(__('Root directory is not writable.')); + } + + try + { + $client = netHttp::initClient($url,$path); + $client->setTimeout(4); + $client->setUserAgent($_SERVER['HTTP_USER_AGENT']); + $client->useGzip(false); + $client->setPersistReferers(false); + $client->setOutput($dest); + $client->get($path); + + if ($client->getStatus() != 200) { + @unlink($dest); + throw new Exception(); + } + } + catch (Exception $e) + { + throw new Exception(__('An error occurred while downloading archive.')); + } + } + + /** + * Checks if archive was successfully downloaded. + */ + public function checkDownload($zip) + { + $cs = $this->getChecksum(); + + return $cs && is_readable($zip) && md5_file($zip) == $cs; + } + + /** + * Backups changed files before an update. + */ + public function backup($zip_file,$zip_digests,$root,$root_digests,$dest) + { + if (!is_readable($zip_file)) { + throw new Exception(__('Archive not found.')); + } + + if (!is_readable($root_digests)) { + @unlink($zip_file); + throw new Exception(__('Unable to read current digests file.')); + } + + # Stop everything if a backup already exists and can not be overrided + if (!is_writable(dirname($dest)) && !file_exists($dest)) { + throw new Exception(__('Root directory is not writable.')); + } + + if (file_exists($dest) && !is_writable($dest)) { + return false; + } + + $b_fp = @fopen($dest,'wb'); + if ($b_fp === false) { + return false; + } + + $zip = new fileUnzip($zip_file); + $b_zip = new fileZip($b_fp); + + if (!$zip->hasFile($zip_digests)) + { + @unlink($zip_file); + throw new Exception(__('Downloaded file does not seem to be a valid archive.')); + } + + $opts = FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES; + $cur_digests = file($root_digests,$opts); + $new_digests = explode("\n",$zip->unzip($zip_digests)); + $new_files = $this->getNewFiles($cur_digests,$new_digests); + $zip->close(); + unset($opts,$cur_digests,$new_digests,$zip); + + $not_readable = array(); + + if (!empty($this->forced_files)) { + $new_files = array_merge($new_files,$this->forced_files); + } + + foreach ($new_files as $file) + { + if (!$file || !file_exists($root.'/'.$file)) { + continue; + } + + try { + $b_zip->addFile($root.'/'.$file,$file); + } catch (Exception $e) { + $not_readable[] = $file; + } + } + + # If only one file is not readable, stop everything now + if (!empty($not_readable)) { + $e = new Exception('Some files are not readable.',self::ERR_FILES_UNREADABLE); + $e->bad_files = $not_readable; + throw $e; + } + + $b_zip->write(); + fclose($b_fp); + $b_zip->close(); + + return true; + } + + /** + * Upgrade process. + */ + public function performUpgrade($zip_file,$zip_digests,$zip_root,$root,$root_digests) + { + if (!is_readable($zip_file)) { + throw new Exception(__('Archive not found.')); + } + + if (!is_readable($root_digests)) { + @unlink($zip_file); + throw new Exception(__('Unable to read current digests file.')); + } + + $zip = new fileUnzip($zip_file); + + if (!$zip->hasFile($zip_digests)) + { + @unlink($zip_file); + throw new Exception(__('Downloaded file does not seem to be a valid archive.')); + } + + $opts = FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES; + $cur_digests = file($root_digests,$opts); + $new_digests = explode("\n",$zip->unzip($zip_digests)); + $new_files = self::getNewFiles($cur_digests,$new_digests); + + if (!empty($this->forced_files)) { + $new_files = array_merge($new_files,$this->forced_files); + } + + $zip_files = array(); + $not_writable = array(); + + foreach ($new_files as $file) + { + if (!$file) { + continue; + } + + if (!$zip->hasFile($zip_root.'/'.$file)) { + @unlink($zip_file); + throw new Exception(__('Incomplete archive.')); + } + + $dest = $dest_dir = $root.'/'.$file; + while (!is_dir($dest_dir = dirname($dest_dir))); + + if ((file_exists($dest) && !is_writable($dest)) || + (!file_exists($dest) && !is_writable($dest_dir))) { + $not_writable[] = $file; + continue; + } + + $zip_files[] = $file; + } + + # If only one file is not writable, stop everything now + if (!empty($not_writable)) { + $e = new Exception('Some files are not writable',self::ERR_FILES_UNWRITALBE); + $e->bad_files = $not_writable; + throw $e; + } + + # Everything's fine, we can write files, then do it now + $can_touch = function_exists('touch'); + foreach ($zip_files as $file) { + $zip->unzip($zip_root.'/'.$file, $root.'/'.$file); + if ($can_touch) { + @touch($root.'/'.$file); + } + } + @unlink($zip_file); + } + + protected function getNewFiles($cur_digests,$new_digests) + { + $cur_md5 = $cur_path = $cur_digests; + $new_md5 = $new_path = $new_digests; + + array_walk($cur_md5, array($this,'parseLine'),1); + array_walk($cur_path,array($this,'parseLine'),2); + array_walk($new_md5, array($this,'parseLine'),1); + array_walk($new_path,array($this,'parseLine'),2); + + $cur = array_combine($cur_md5,$cur_path); + $new = array_combine($new_md5,$new_path); + + return array_values(array_diff_key($new,$cur)); + } + + protected function readVersion($str) + { + try + { + $xml = new SimpleXMLElement($str,LIBXML_NOERROR); + $r = $xml->xpath("/versions/subject[@name='".$this->subject."']/release[@name='".$this->version."']"); + + if (!empty($r) && is_array($r)) + { + $r = $r[0]; + $this->version_info['version'] = isset($r['version']) ? (string) $r['version'] : null; + $this->version_info['href'] = isset($r['href']) ? (string) $r['href'] : null; + $this->version_info['checksum'] = isset($r['checksum']) ? (string) $r['checksum'] : null; + $this->version_info['info'] = isset($r['info']) ? (string) $r['info'] : null; + } + } + catch (Exception $e) + { + throw $e; + } + } + + protected function md5sum($root,$digests_file) + { + if (!is_readable($digests_file)) { + throw new Exception(__('Unable to read digests file.')); + } + + $opts = FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES; + $contents = file($digests_file,$opts); + + $changes = array(); + + foreach ($contents as $digest) + { + if (!preg_match('#^([\da-f]{32})\s+(.+?)$#',$digest,$m)) { + continue; + } + + $md5 = $m[1]; + $filename = $root.'/'.$m[2]; + + # Invalid checksum + if (!is_readable($filename) || !self::md5_check($filename, $md5)) { + $changes[] = substr($m[2],2); + } + } + + # No checksum found in digests file + if (empty($md5)) { + throw new Exception(__('Invalid digests file.')); + } + + return $changes; + } + + protected function parseLine(&$v,$k,$n) + { + if (!preg_match('#^([\da-f]{32})\s+(.+?)$#',$v,$m)) { + return; + } + + $v = $n == 1 ? md5($m[2].$m[1]) : substr($m[2],2); + } + + protected static function md5_check($filename,$md5) + { + if (md5_file($filename) == $md5) { + return true; + } else { + $filecontent = file_get_contents($filename); + $filecontent = str_replace ("\r\n","\n",$filecontent); + $filecontent = str_replace ("\r","\n",$filecontent); + if (md5($filecontent) == $md5) return true; + } + return false; + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/core/class.dc.utils.php b/v2/dotclear/inc/core/class.dc.utils.php new file mode 100644 index 0000000..cfb75c4 --- /dev/null +++ b/v2/dotclear/inc/core/class.dc.utils.php @@ -0,0 +1,53 @@ +user_id, user_name, user_firstname and + user_displayname. + + @param user_id string User ID + @param user_name string User's name + @param user_firstname string User's first name + @param user_displayname string User's display name + @return string + */ + public static function getUserCN($user_id, $user_name, $user_firstname, $user_displayname) + { + if (!empty($user_displayname)) { + return $user_displayname; + } + + if (!empty($user_name)) { + if (!empty($user_firstname)) { + return $user_firstname.' '.$user_name; + } else { + return $user_name; + } + } elseif (!empty($user_firstname)) { + return $user_firstname; + } + + return $user_id; + } +} + +?> \ No newline at end of file diff --git a/v2/dotclear/inc/core/class.dc.workspace.php b/v2/dotclear/inc/core/class.dc.workspace.php new file mode 100644 index 0000000..d5f0106 --- /dev/null +++ b/v2/dotclear/inc/core/class.dc.workspace.php @@ -0,0 +1,368 @@ +connection Database connection object + protected $table; ///< string Preferences table name + protected $user_id; ///< string User ID + + protected $global_prefs = array(); ///< array Global prefs array + protected $local_prefs = array(); ///< array Local prefs array + protected $prefs = array(); ///< array Associative prefs array + protected $ws; ///< string Current workspace + + /** + Object constructor. Retrieves user prefs and puts them in $prefs + array. Local (user) prefs have a highest priority than global prefs. + + @param name string ID for this workspace + */ + public function __construct(&$core, $user_id, $name, $rs=null) + { + if (preg_match('/^[a-zA-Z][a-zA-Z0-9]+$/',$name)) { + $this->ws = $name; + } else { + throw new Exception(sprintf(__('Invalid dcWorkspace: %s'),$name)); + } + + $this->con =& $core->con; + $this->table = $core->prefix.'pref'; + $this->user_id =& $user_id; + + try {$this->getPrefs($rs);} catch (Exception $e) { + if (version_compare($core->getVersion('core'),'2.3','>')) { + trigger_error(__('Unable to retrieve prefs:').' '.$this->con->error(), E_USER_ERROR); + } + } + } + + private function getPrefs($rs=null) + { + if ($rs == null) { + $strReq = 'SELECT user_id, pref_id, pref_value, '. + 'pref_type, pref_label, pref_ws '. + 'FROM '.$this->table.' '. + "WHERE (user_id = '".$this->con->escape($this->user_id)."' ". + 'OR user_id IS NULL) '. + "AND pref_ws = '".$this->con->escape($this->ws)."' ". + 'ORDER BY pref_id ASC '; + + try { + $rs = $this->con->select($strReq); + } catch (Exception $e) { + throw $e; + } + } + while ($rs->fetch()) + { + if ($rs->f('pref_ws') != $this->ws){ + break; + } + $id = trim($rs->f('pref_id')); + $value = $rs->f('pref_value'); + $type = $rs->f('pref_type'); + + if ($type == 'float' || $type == 'double') { + $type = 'float'; + } elseif ($type != 'boolean' && $type != 'integer') { + $type = 'string'; + } + + settype($value,$type); + + $array = $rs->user_id ? 'local' : 'global'; + + $this->{$array.'_prefs'}[$id] = array( + 'ws' => $this->ws, + 'value' => $value, + 'type' => $type, + 'label' => (string) $rs->f('pref_label'), + 'global' => $rs->user_id == '' + ); + } + + $this->prefs = $this->global_prefs; + + foreach ($this->local_prefs as $id => $v) { + $this->prefs[$id] = $v; + } + + return true; + } + + public function prefExists($id,$global=false) + { + $array = $global ? 'global' : 'local'; + return isset($this->{$array.'_prefs'}[$id]); + } + + /** + Returns pref value if exists. + + @param n string Pref name + @return mixed + */ + public function get($n) + { + if (isset($this->prefs[$n]['value'])) { + return $this->prefs[$n]['value']; + } + + return null; + } + + /** + Magic __get method. + @copydoc ::get + */ + public function __get($n) + { + return $this->get($n); + } + + /** + Sets a pref in $prefs property. This sets the pref for script + execution time only and if pref exists. + + @param n string Pref name + @param v mixed Pref value + */ + public function set($n,$v) + { + if (isset($this->prefs[$n])) { + $this->prefs[$n]['value'] = $v; + } + } + + /** + Magic __set method. + @copydoc ::set + */ + public function __set($n,$v) + { + $this->set($n,$v); + } + + /** + Creates or updates a pref. + + $type could be 'string', 'integer', 'float', 'boolean' or null. If $type is + null and pref exists, it will keep current pref type. + + $value_change allow you to not change pref. Useful if you need to change + a pref label or type and don't want to change its value. + + @param id string Pref ID + @param value mixed Pref value + @param type string Pref type + @param label string Pref label + @param value_change boolean Change pref value or not + @param global boolean Pref is global + */ + public function put($id,$value,$type=null,$label=null,$value_change=true,$global=false) + { + if (!preg_match('/^[a-zA-Z][a-zA-Z0-9_]+$/',$id)) { + throw new Exception(sprintf(__('%s is not a valid pref id'),$id)); + } + + # We don't want to change pref value + if (!$value_change) + { + if (!$global && $this->prefExists($id,false)) { + $value = $this->local_prefs[$id]['value']; + } elseif ($this->prefExists($id,true)) { + $value = $this->global_prefs[$id]['value']; + } + } + + # Pref type + if ($type == 'double') + { + $type = 'float'; + } + elseif ($type === null) + { + if (!$global && $this->prefExists($id,false)) { + $type = $this->local_prefs[$id]['type']; + } elseif ($this->prefExists($id,true)) { + $type = $this->global_prefs[$id]['type']; + } else { + $type = 'string'; + } + } + elseif ($type != 'boolean' && $type != 'integer' && $type != 'float') + { + $type = 'string'; + } + + # We don't change label + if ($label == null) + { + if (!$global && $this->prefExists($id,false)) { + $label = $this->local_prefs[$id]['label']; + } elseif ($this->prefExists($id,true)) { + $label = $this->global_prefs[$id]['label']; + } + } + + settype($value,$type); + + $cur = $this->con->openCursor($this->table); + $cur->pref_value = ($type == 'boolean') ? (string) (integer) $value : (string) $value; + $cur->pref_type = $type; + $cur->pref_label = $label; + + #If we are local, compare to global value + if (!$global && $this->prefExists($id,true)) + { + $g = $this->global_prefs[$id]; + $same_pref = $g['ws'] == $this->ws && $g['value'] == $value + && $g['type'] == $type && $g['label'] == $label; + + # Drop pref if same value as global + if ($same_pref && $this->prefExists($id,false)) { + $this->drop($id); + } elseif ($same_pref) { + return; + } + } + + if ($this->prefExists($id,$global) && $this->ws == $this->prefs[$id]['ws']) + { + if ($global) { + $where = 'WHERE user_id IS NULL '; + } else { + $where = "WHERE user_id = '".$this->con->escape($this->user_id)."' "; + } + + $cur->update($where."AND pref_id = '".$this->con->escape($id)."' AND pref_ws = '".$this->con->escape($this->ws)."' "); + } + else + { + $cur->pref_id = $id; + $cur->user_id = $global ? null : $this->user_id; + $cur->pref_ws = $this->ws; + + $cur->insert(); + } + } + + /** + Removes an existing pref. Workspace + + @param id string Pref ID + @param force_global boolean Force global pref drop + */ + public function drop($id,$force_global=false) + { + if (!$this->ws) { + throw new Exception(__('No workspace specified')); + } + + $strReq = 'DELETE FROM '.$this->table.' '; + + if (($force_global) || ($this->user_id === null)) { + $strReq .= 'WHERE user_id IS NULL '; + $global = true; + } else { + $strReq .= "WHERE user_id = '".$this->con->escape($this->user_id)."' "; + $global = false; + } + + $strReq .= "AND pref_id = '".$this->con->escape($id)."' "; + $strReq .= "AND pref_ws = '".$this->con->escape($this->ws)."' "; + + $this->con->execute($strReq); + + if ($this->prefExists($id,$global)) { + $array = $global ? 'global' : 'local'; + unset($this->{$array.'_prefs'}[$id]); + } + + $this->prefs = $this->global_prefs; + foreach ($this->local_prefs as $id => $v) { + $this->prefs[$id] = $v; + } + } + + /** + Removes all existing pref. in a Workspace + + @param force_global boolean Force global pref drop + */ + public function dropAll($force_global=false) + { + if (!$this->ws) { + throw new Exception(__('No workspace specified')); + } + + $strReq = 'DELETE FROM '.$this->table.' '; + + if (($force_global) || ($this->user_id === null)) { + $strReq .= 'WHERE user_id IS NULL '; + $global = true; + } else { + $strReq .= "WHERE user_id = '".$this->con->escape($this->user_id)."' "; + $global = false; + } + + $strReq .= "AND pref_ws = '".$this->con->escape($this->ws)."' "; + + $this->con->execute($strReq); + + $array = $global ? 'global' : 'local'; + unset($this->{$array.'_prefs'}); + $this->{$array.'_prefs'} = array(); + + $array = $global ? 'local' : 'global'; + $this->prefs = $this->{$array.'_prefs'}; + } + + /** + Returns $prefs property content. + + @return array + */ + public function dumpPrefs() + { + return $this->prefs; + } + + /** + Returns $local_prefs property content. + + @return array + */ + public function dumpLocalPrefs() + { + return $this->local_prefs; + } + + /** + Returns $global_prefs property content. + + @return array + */ + public function dumpGlobalPrefs() + { + return $this->global_prefs; + } + +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/core/class.dc.xmlrpc.php b/v2/dotclear/inc/core/class.dc.xmlrpc.php new file mode 100644 index 0000000..70a7310 --- /dev/null +++ b/v2/dotclear/inc/core/class.dc.xmlrpc.php @@ -0,0 +1,1632 @@ +core =& $core; + $this->blog_id = $blog_id; + + # Blogger methods + $this->addCallback('blogger.newPost',array($this,'blogger_newPost'), + array('string','string','string','string','string','string','integer'), + 'New post'); + + $this->addCallback('blogger.editPost',array($this,'blogger_editPost'), + array('boolean','string','string','string','string','string','integer'), + 'Edit a post'); + + $this->addCallback('blogger.getPost',array($this,'blogger_getPost'), + array('struct','string','integer','string','string'), + 'Return a posts by ID'); + + $this->addCallback('blogger.deletePost',array($this,'blogger_deletePost'), + array('string','string','string','string','string','integer'), + 'Delete a post'); + + $this->addCallback('blogger.getRecentPosts',array($this,'blogger_getRecentPosts'), + array('array','string','string','string','string','integer'), + 'Return a list of recent posts'); + + $this->addCallback('blogger.getUsersBlogs',array($this,'blogger_getUserBlogs'), + array('struct','string','string','string'), + "Return user's blog"); + + $this->addCallback('blogger.getUserInfo',array($this,'blogger_getUserInfo'), + array('struct','string','string','string'), + 'Return User Info'); + + # Metaweblog methods + $this->addCallback('metaWeblog.newPost',array($this,'mw_newPost'), + array('string','string','string','string','struct','boolean'), + 'Creates a new post, and optionnaly publishes it.'); + + $this->addCallback('metaWeblog.editPost',array($this,'mw_editPost'), + array('boolean','string','string','string','struct','boolean'), + 'Updates information about an existing entry'); + + $this->addCallback('metaWeblog.getPost',array($this,'mw_getPost'), + array('struct','string','string','string'), + 'Returns information about a specific post'); + + $this->addCallback('metaWeblog.getRecentPosts',array($this,'mw_getRecentPosts'), + array('array','string','string','string','integer'), + 'List of most recent posts in the system'); + + $this->addCallback('metaWeblog.getCategories',array($this,'mw_getCategories'), + array('array','string','string','string'), + 'List of all categories defined in the weblog'); + + $this->addCallback('metaWeblog.newMediaObject',array($this,'mw_newMediaObject'), + array('struct','string','string','string','struct'), + 'Upload a file on the web server'); + + # MovableType methods + $this->addCallback('mt.getRecentPostTitles',array($this,'mt_getRecentPostTitles'), + array('array','string','string','string','integer'), + 'List of most recent posts in the system'); + + $this->addCallback('mt.getCategoryList',array($this,'mt_getCategoryList'), + array('array','string','string','string'), + 'List of all categories defined in the weblog'); + + $this->addCallback('mt.getPostCategories',array($this,'mt_getPostCategories'), + array('array','string','string','string'), + 'List of all categories to which the post is assigned'); + + $this->addCallback('mt.setPostCategories',array($this,'mt_setPostCategories'), + array('boolean','string','string','string','array'), + 'Sets the categories for a post'); + + $this->addCallback('mt.publishPost',array($this,'mt_publishPost'), + array('boolean','string','string','string'), + 'Retrieve pings list for a post'); + + $this->addCallback('mt.supportedMethods',array($this,'listMethods'), + array(),'Retrieve information about the XML-RPC methods supported by the server.'); + + $this->addCallback('mt.supportedTextFilters',array($this,'mt_supportedTextFilters'), + array(),'Retrieve information about supported text filters.'); + + # WordPress methods + $this->addCallback('wp.getUsersBlogs',array($this,'wp_getUsersBlogs'), + array('array','string','string'), + 'Retrieve the blogs of the user.'); + + $this->addCallback('wp.getPage',array($this,'wp_getPage'), + array('struct','integer','integer','string','string'), + 'Get the page identified by the page ID.'); + + $this->addCallback('wp.getPages',array($this,'wp_getPages'), + array('array','integer','string','string','integer'), + 'Get an array of all the pages on a blog.'); + + $this->addCallback('wp.newPage',array($this,'wp_newPage'), + array('integer','integer','string','string','struct','boolean'), + 'Create a new page.'); + + $this->addCallback('wp.deletePage',array($this,'wp_deletePage'), + array('boolean','integer','string','string','integer'), + 'Removes a page from the blog.'); + + $this->addCallback('wp.editPage',array($this,'wp_editPage'), + array('boolean','integer','integer','string','string','struct','boolean'), + 'Make changes to a blog page.'); + + $this->addCallback('wp.getPageList',array($this,'wp_getPageList'), + array('array','integer','string','string'), + 'Get an array of all the pages on a blog. Just the minimum details, lighter than wp.getPages.'); + + $this->addCallback('wp.getAuthors',array($this,'wp_getAuthors'), + array('array','integer','string','string'), + 'Get an array of users for the blog.'); + + $this->addCallback('wp.getCategories',array($this,'wp_getCategories'), + array('array','integer','string','string'), + 'Get an array of available categories on a blog.'); + + $this->addCallback('wp.getTags',array($this,'wp_getTags'), + array('array','integer','string','string'), + 'Get list of all tags for the blog.'); + + $this->addCallback('wp.newCategory',array($this,'wp_newCategory'), + array('integer','integer','string','string','struct'), + 'Create a new category.'); + + $this->addCallback('wp.deleteCategory',array($this,'wp_deleteCategory'), + array('boolean','integer','string','string','integer'), + 'Delete a category with a given ID.'); + + $this->addCallback('wp.suggestCategories',array($this,'wp_suggestCategories'), + array('array','integer','string','string','string','integer'), + 'Get an array of categories that start with a given string.'); + + $this->addCallback('wp.uploadFile',array($this,'wp_uploadFile'), + array('struct','integer','string','string','struct'), + 'Upload a file'); + + $this->addCallback('wp.getPostStatusList',array($this,'wp_getPostStatusList'), + array('array','integer','string','string'), + 'Retrieve all of the post statuses.'); + + $this->addCallback('wp.getPageStatusList',array($this,'wp_getPageStatusList'), + array('array','integer','string','string'), + 'Retrieve all of the pages statuses.'); + + $this->addCallback('wp.getPageTemplates',array($this,'wp_getPageTemplates'), + array('struct','integer','string','string'), + 'Retrieve page templates.'); + + $this->addCallback('wp.getOptions',array($this,'wp_getOptions'), + array('struct','integer','string','string','array'), + 'Retrieve blog options'); + + $this->addCallback('wp.setOptions',array($this,'wp_setOptions'), + array('struct','integer','string','string','struct'), + 'Update blog options'); + + $this->addCallback('wp.getComment',array($this,'wp_getComment'), + array('struct','integer','string','string','integer'), + "Gets a comment, given it's comment ID."); + + $this->addCallback('wp.getCommentCount',array($this,'wp_getCommentCount'), + array('array','integer','string','string','integer'), + 'Retrieve comment count.'); + + $this->addCallback('wp.getComments',array($this,'wp_getComments'), + array('array','integer','string','string','struct'), + 'Gets a set of comments for a given post.'); + + $this->addCallback('wp.deleteComment',array($this,'wp_deleteComment'), + array('boolean','integer','string','string','integer'), + 'Delete a comment with given ID.'); + + $this->addCallback('wp.editComment',array($this,'wp_editComment'), + array('boolean','integer','string','string','integer','struct'), + 'Edit a comment with given ID.'); + + $this->addCallback('wp.newComment',array($this,'wp_newComment'), + array('integer','integer','string','string','integer','struct'), + 'Create a new comment for a given post ID.'); + + $this->addCallback('wp.getCommentStatusList',array($this,'wp_getCommentStatusList'), + array('array','integer','string','string'), + 'Retrieve all of the comment statuses.'); + } + + public function serve($data=false,$encoding='UTF-8') + { + parent::serve(false,$encoding); + } + + public function call($methodname,$args) + { + try { + $rsp = @parent::call($methodname,$args); + $this->debugTrace($methodname,$args,$rsp); + return $rsp; + } catch (Exception $e) { + $this->debugTrace($methodname,$args,array($e->getMessage(),$e->getCode())); + throw $e; + } + } + + private function debugTrace($methodname,$args,$rsp) + { + if (!$this->debug) { + return; + } + + if (($fp = @fopen($this->debug_file,'a')) !== false) + { + fwrite($fp,'['.date('r').']'.' '.$methodname); + + if ($this->trace_args) { + fwrite($fp,"\n- args ---\n".var_export($args,1)); + } + + if ($this->trace_response) { + fwrite($fp,"\n- response ---\n".var_export($rsp,1)); + } + fwrite($fp,"\n"); + fclose($fp); + } + } + + /* Internal methods + --------------------------------------------------- */ + private function setUser($user_id,$pwd) + { + if ($this->core->auth->userID() == $user_id) { + return true; + } + + if ($this->core->auth->checkUser($user_id,$pwd) !== true) { + throw new Exception('Login error'); + } + + return true; + } + + private function setBlog() + { + if (!$this->blog_id) { + throw new Exception('No blog ID given.'); + } + + if ($this->blog_loaded) { + return true; + } + + $this->core->setBlog($this->blog_id); + $this->blog_loaded = true; + + if (!$this->core->blog->id) { + $this->core->blog = null; + throw new Exception('Blog does not exist.'); + } + + if (!$this->core->blog->settings->system->enable_xmlrpc || + !$this->core->auth->check('usage,contentadmin',$this->core->blog->id)) { + $this->core->blog = null; + throw new Exception('Not enough permissions on this blog.'); + } + + foreach ($this->core->plugins->getModules() as $id => $m) { + $this->core->plugins->loadNsFile($id,'xmlrpc'); + } + + return true; + } + + private function getPostRS($post_id,$user,$pwd,$post_type='post') + { + $this->setUser($user,$pwd); + $this->setBlog(); + $rs = $this->core->blog->getPosts(array( + 'post_id' => (integer) $post_id, + 'post_type' => $post_type + )); + + if ($rs->isEmpty()) { + throw new Exception('This entry does not exist'); + } + + return $rs; + } + + private function getCatID($cat_url) + { + $rs = $this->core->blog->getCategories(array('cat_url' => $cat_url)); + + return $rs->isEmpty() ? null : $rs->cat_id; + } + + /* Generic methods + --------------------------------------------------- */ + private function newPost($blog_id,$user,$pwd,$content,$struct=array(),$publish=true) + { + $this->setUser($user,$pwd); + $this->setBlog(); + + $title = !empty($struct['title']) ? $struct['title'] : ''; + $excerpt = !empty($struct['mt_excerpt']) ? $struct['mt_excerpt'] : ''; + $description = !empty($struct['description']) ? $struct['description'] : null; + $dateCreated = !empty($struct['dateCreated']) ? $struct['dateCreated'] : null; + $open_comment = isset($struct['mt_allow_comments']) ? $struct['mt_allow_comments'] : 1; + $open_tb = isset($struct['mt_allow_pings']) ? $struct['mt_allow_pings'] : 1; + + if ($description !== null) { + $content = $description; + } + + if (!$title) { + $title = text::cutString(html::clean($content),25).'...'; + } + + $excerpt_xhtml = $this->core->callFormater('xhtml',$excerpt); + $content_xhtml = $this->core->callFormater('xhtml',$content); + + if (empty($content)) { + throw new Exception('Cannot create an empty entry'); + } + + $cur = $this->core->con->openCursor($this->core->prefix.'post'); + + $cur->user_id = $this->core->auth->userID(); + $cur->post_lang = $this->core->auth->getInfo('user_lang'); + $cur->post_title = trim($title); + $cur->post_content = $content; + $cur->post_excerpt = $excerpt; + $cur->post_content_xhtml = $content_xhtml; + $cur->post_excerpt_xhtml = $excerpt_xhtml; + $cur->post_open_comment = (integer) ($open_comment == 1); + $cur->post_open_tb = (integer) ($open_tb == 1); + $cur->post_status = (integer) $publish; + $cur->post_format = 'xhtml'; + + if ($dateCreated) { + if ($dateCreated instanceof xmlrpcDate) { + $cur->post_dt = date('Y-m-d H:i:00',$dateCreated->getTimestamp()); + } elseif (is_string($dateCreated) && @strtotime($dateCreated)) { + $cur->post_dt = date('Y-m-d H:i:00',strtotime($dateCreated)); + } + } + + # Categories in an array + if (isset($struct['categories']) && is_array($struct['categories'])) + { + $categories = $struct['categories']; + $cat_id = !empty($categories[0]) ? $categories[0] : null; + + $cur->cat_id = $this->getCatID($cat_id); + } + + if (isset($struct['wp_slug'])) { + $cur->post_url = $struct['wp_slug']; + } + + if (isset($struct['wp_password'])) { + $cur->post_password = $struct['wp_password']; + } + + $cur->post_type = 'post'; + if (!empty($struct['post_type'])) { + $cur->post_type = $struct['post_type']; + } + + if ($cur->post_type == 'post') + { + # --BEHAVIOR-- xmlrpcBeforeNewPost + $this->core->callBehavior('xmlrpcBeforeNewPost',$this,$cur,$content,$struct,$publish); + + $post_id = $this->core->blog->addPost($cur); + + # --BEHAVIOR-- xmlrpcAfterNewPost + $this->core->callBehavior('xmlrpcAfterNewPost',$this,$post_id,$cur,$content,$struct,$publish); + } + elseif ($cur->post_type == 'page') + { + if (isset($struct['wp_page_order'])) { + $cur->post_position = (integer) $struct['wp_page_order']; + } + + $this->core->blog->settings->system->post_url_format = '{t}'; + + $post_id = $this->core->blog->addPost($cur); + } + else + { + throw new Exception('Invalid post type',401); + } + + return (string) $post_id; + } + + private function editPost($post_id,$user,$pwd,$content,$struct=array(),$publish=true) + { + $post_id = (integer) $post_id; + + $post_type = 'post'; + if (!empty($struct['post_type'])) { + $post_type = $struct['post_type']; + } + + $post = $this->getPostRS($post_id,$user,$pwd,$post_type); + + $title = (!empty($struct['title'])) ? $struct['title'] : ''; + $excerpt = (!empty($struct['mt_excerpt'])) ? $struct['mt_excerpt'] : ''; + $description = (!empty($struct['description'])) ? $struct['description'] : null; + $dateCreated = !empty($struct['dateCreated']) ? $struct['dateCreated'] : null; + $open_comment = (isset($struct['mt_allow_comments'])) ? $struct['mt_allow_comments'] : 1; + $open_tb = (isset($struct['mt_allow_pings'])) ? $struct['mt_allow_pings'] : 1; + + if ($description !== null) { + $content = $description; + } + + if (!$title) { + $title = text::cutString(html::clean($content),25).'...'; + } + + $excerpt_xhtml = $this->core->callFormater('xhtml',$excerpt); + $content_xhtml = $this->core->callFormater('xhtml',$content); + + if (empty($content)) { + throw new Exception('Cannot create an empty entry'); + } + + $cur = $this->core->con->openCursor($this->core->prefix.'post'); + + $cur->post_type = $post_type; + $cur->post_title = trim($title); + $cur->post_content = $content; + $cur->post_excerpt = $excerpt; + $cur->post_content_xhtml = $content_xhtml; + $cur->post_excerpt_xhtml = $excerpt_xhtml; + $cur->post_open_comment = (integer) ($open_comment == 1); + $cur->post_open_tb = (integer) ($open_tb == 1); + $cur->post_status = (integer) $publish; + $cur->post_format = 'xhtml'; + $cur->post_url = $post->post_url; + + + if ($dateCreated) { + if ($dateCreated instanceof xmlrpcDate) { + $cur->post_dt = date('Y-m-d H:i:00',$dateCreated->getTimestamp()); + } elseif (is_string($dateCreated) && @strtotime($dateCreated)) { + $cur->post_dt = date('Y-m-d H:i:00',strtotime($dateCreated)); + } + } else { + $cur->post_dt = $post->post_dt; + } + + # Categories in an array + if (isset($struct['categories']) && is_array($struct['categories'])) + { + $categories = $struct['categories']; + $cat_id = !empty($categories[0]) ? $categories[0] : null; + + $cur->cat_id = $this->getCatID($cat_id); + } + + if (isset($struct['wp_slug'])) { + $cur->post_url = $struct['wp_slug']; + } + + if (isset($struct['wp_password'])) { + $cur->post_password = $struct['wp_password']; + } + + if ($cur->post_type == 'post') + { + # --BEHAVIOR-- xmlrpcBeforeEditPost + $this->core->callBehavior('xmlrpcBeforeEditPost',$this,$post_id,$cur,$content,$struct,$publish); + + $this->core->blog->updPost($post_id,$cur); + + # --BEHAVIOR-- xmlrpcAfterEditPost + $this->core->callBehavior('xmlrpcAfterEditPost',$this,$post_id,$cur,$content,$struct,$publish); + } + elseif ($cur->post_type == 'page') + { + if (isset($struct['wp_page_order'])) { + $cur->post_position = (integer) $struct['wp_page_order']; + } + + $this->core->blog->settings->system->post_url_format = '{t}'; + + $this->core->blog->updPost($post_id,$cur); + } + else + { + throw new Exception('Invalid post type',401); + } + + return true; + } + + private function getPost($post_id,$user,$pwd,$type='mw') + { + $post_id = (integer) $post_id; + + $post = $this->getPostRS($post_id,$user,$pwd); + + $res = new ArrayObject(); + + $res['dateCreated'] = new xmlrpcDate($post->getTS()); + $res['userid'] = $post->user_id; + $res['postid'] = $post->post_id; + + if ($post->cat_id) { + $res['categories'] = array($post->cat_url); + } + + if ($type == 'blogger') { + $res['content'] = $post->post_content_xhtml; + } + + if ($type == 'mt' || $type == 'mw') { + $res['title'] = $post->post_title; + } + + if ($type == 'mw') { + $res['description'] = $post->post_content_xhtml; + $res['link'] = $res['permaLink'] = $post->getURL(); + $res['mt_excerpt'] = $post->post_excerpt_xhtml; + $res['mt_text_more'] = ''; + $res['mt_allow_comments'] = (integer) $post->post_open_comment; + $res['mt_allow_pings'] = (integer) $post->post_open_tb; + $res['mt_convert_breaks'] = ''; + $res['mt_keywords'] = ''; + } + + # --BEHAVIOR-- xmlrpcGetPostInfo + $this->core->callBehavior('xmlrpcGetPostInfo',$this,$type,array(&$res)); + + return $res; + } + + private function deletePost($post_id,$user,$pwd) + { + $post_id = (integer) $post_id; + + $this->getPostRS($post_id,$user,$pwd); + $this->core->blog->delPost($post_id); + + return true; + } + + private function getRecentPosts($blog_id,$user,$pwd,$nb_post,$type='mw') + { + $this->setUser($user,$pwd); + $this->setBlog(); + + $nb_post = (integer) $nb_post; + + if ($nb_post > 50) { + throw new Exception('Cannot retrieve more than 50 entries'); + } + + $params = array(); + $params['limit'] = $nb_post; + + $posts = $this->core->blog->getPosts($params); + + $res = array(); + while ($posts->fetch()) + { + $tres = array(); + + $tres['dateCreated'] = new xmlrpcDate($posts->getTS()); + $tres['userid'] = $posts->user_id; + $tres['postid'] = $posts->post_id; + + if ($posts->cat_id) { + $tres['categories'] = array($posts->cat_url); + } + + if ($type == 'blogger') { + $tres['content'] = $posts->post_content_xhtml; + } + + if ($type == 'mt' || $type == 'mw') { + $tres['title'] = $posts->post_title; + } + + if ($type == 'mw') { + $tres['description'] = $posts->post_content_xhtml; + $tres['link'] = $tres['permaLink'] = $posts->getURL(); + $tres['mt_excerpt'] = $posts->post_excerpt_xhtml; + $tres['mt_text_more'] = ''; + $tres['mt_allow_comments'] = (integer) $posts->post_open_comment; + $tres['mt_allow_pings'] = (integer) $posts->post_open_tb; + $tres['mt_convert_breaks'] = ''; + $tres['mt_keywords'] = ''; + } + + # --BEHAVIOR-- xmlrpcGetPostInfo + $this->core->callBehavior('xmlrpcGetPostInfo',$this,$type,array(&$tres)); + + $res[] = $tres; + } + + return $res; + } + + private function getUserBlogs($user,$pwd) + { + $this->setUser($user,$pwd); + $this->setBlog(); + + return array(array( + 'url' => $this->core->blog->url, + 'blogid' => '1', + 'blogName' => $this->core->blog->name + )); + } + + private function getUserInfo($user,$pwd) + { + $this->setUser($user,$pwd); + + return array( + 'userid' => $this->core->auth->userID(), + 'firstname' => $this->core->auth->getInfo('user_firstname'), + 'lastname' => $this->core->auth->getInfo('user_name'), + 'nickname' => $this->core->auth->getInfo('user_displayname'), + 'email' => $this->core->auth->getInfo('user_email'), + 'url' => $this->core->auth->getInfo('user_url') + ); + } + + private function getCategories($blog_id,$user,$pwd) + { + $this->setUser($user,$pwd); + $this->setBlog(); + $rs = $this->core->blog->getCategories(); + + $res = array(); + + $l = $rs->level; + $stack = array('',$rs->cat_url); + + while ($rs->fetch()) + { + $d = $rs->level - $l; + if ($d == 0) { + array_pop($stack); + $parent = end($stack); + } elseif ($d > 0) { + $parent = end($stack); + } elseif ($d < 0) { + $D = abs($d); + for ($i=0; $i<=$D; $i++) { + array_pop($stack); + } + $parent = end($stack); + } + + $res[] = array( + 'categoryId' => $rs->cat_url, + 'parentId' => $parent, + 'description' => $rs->cat_title, + 'categoryName' => $rs->cat_url, + 'htmlUrl' => $this->core->blog->url. + $this->core->url->getURLFor('category',$rs->cat_url), + 'rssUrl' => $this->core->blog->url. + $this->core->url->getURLFor('feed','category/'.$rs->cat_url.'/rss2') + ); + + $stack[] = $rs->cat_url; + $l = $rs->level; + } + + return $res; + } + + private function getPostCategories($post_id,$user,$pwd) + { + $post_id = (integer) $post_id; + + $post = $this->getPostRS($post_id,$user,$pwd); + + return array( + array( + 'categoryName' => $post->cat_url, + 'categoryId' => (string) $post->cat_url, + 'isPrimary' => true + ) + ); + } + + private function setPostCategories($post_id,$user,$pwd,$categories) + { + $post_id = (integer) $post_id; + + $post = $this->getPostRS($post_id,$user,$pwd); + + $cat_id = (!empty($categories[0]['categoryId'])) ? $categories[0]['categoryId'] : null; + + foreach($categories as $v) + { + if (isset($v['isPrimary']) && $v['isPrimary']) { + $cat_id = $v['categoryId']; + break; + } + } + + # w.bloggar sends -1 for no category. + if ($cat_id == -1) { + $cat_id = null; + } + + if ($cat_id) { + $cat_id = $this->getCatID($cat_id); + } + + $this->core->blog->updPostCategory($post_id,(integer) $cat_id); + + return true; + } + + private function publishPost($post_id,$user,$pwd) + { + $post_id = (integer) $post_id; + + $this->getPostRS($post_id,$user,$pwd); + + # --BEHAVIOR-- xmlrpcBeforePublishPost + $this->core->callBehavior('xmlrpcBeforePublishPost',$this,$post_id); + + $this->core->blog->updPostStatus($post_id,1); + + # --BEHAVIOR-- xmlrpcAfterPublishPost + $this->core->callBehavior('xmlrpcAfterPublishPost',$this,$post_id); + + return true; + } + + private function newMediaObject($blog_id,$user,$pwd,$file) + { + if (empty($file['name'])) { + throw new Exception('No file name'); + } + + if (empty($file['bits'])) { + throw new Exception('No file content'); + } + + $file_name = $file['name']; + $file_bits = $file['bits']; + + $this->setUser($user,$pwd); + $this->setBlog(); + + $media = new dcMedia($this->core); + + $dir_name = path::clean(dirname($file_name)); + $file_name = basename($file_name); + + $dir_name = preg_replace('!^/!','',$dir_name); + if ($dir_name != '') + { + $dir = explode('/',$dir_name); + $cwd = './'; + foreach ($dir as $v) + { + $v = files::tidyFileName($v); + $cwd .= $v.'/'; + $media->makeDir($v); + $media->chdir($cwd); + } + } + + $media_id = $media->uploadBits($file_name,$file_bits); + + $f = $media->getFile($media_id); + return array( + 'file' => $file_name, + 'url' => $f->file_url, + 'type' => files::getMimeType($file_name) + ); + } + + private function translateWpStatus($s) + { + $status = array( + 'draft' => -2, + 'pending' => -2, + 'private' => 0, + 'publish' => 1, + 'scheduled' => -1 + ); + + if (is_int($s)) { + $status = array_flip($status); + return isset($status[$s]) ? $status[$s] : $status[-2]; + } else { + return isset($status[$s]) ? $status[$s] : $status['pending']; + } + } + + private function translateWpCommentstatus($s) + { + $status = array( + 'hold' => -1, + 'approve' => 0, + 'spam' => -2 + ); + + if (is_int($s)) { + $status = array_flip($status); + return isset($status[$s]) ? $status[$s] : $status[0]; + } else { + return isset($status[$s]) ? $status[$s] : $status['approve']; + } + } + + private function translateWpOptions($options=array()) + { + $timezone = 0; + if ($this->core->blog->settings->system->blog_timezone) { + $timezone = dt::getTimeOffset($this->core->blog->settings->system->blog_timezone)/3600; + } + + $res = array ( + 'software_name' => array ( + 'desc' => 'Software Name', + 'readonly' => true, + 'value' => 'Dotclear' + ), + 'software_version' => array ( + 'desc' => 'Software Version', + 'readonly' => true, + 'value' => DC_VERSION + ), + 'blog_url' => array ( + 'desc' => 'Blog URL', + 'readonly' => true, + 'value' => $this->core->blog->url + ), + 'time_zone' => array ( + 'desc' => 'Time Zone', + 'readonly' => true, + 'value' => (string) $timezone + ), + 'blog_title' => array ( + 'desc' => 'Blog Title', + 'readonly' => false, + 'value' => $this->core->blog->name + ), + 'blog_tagline' => array ( + 'desc' => 'Blog Tagline', + 'readonly' => false, + 'value' => $this->core->blog->desc + ), + 'date_format' => array ( + 'desc' => 'Date Format', + 'readonly' => false, + 'value' => $this->core->blog->settings->system->date_format + ), + 'time_format' => array ( + 'desc' => 'Time Format', + 'readonly' => false, + 'value' => $this->core->blog->settings->system->time_format + ) + ); + + if (!empty($options)) + { + $r = array(); + foreach ($options as $v) { + if (isset($res[$v])) { + $r[$v] = $res[$v]; + } + } + return $r; + } + + return $res; + } + + private function getPostStatusList($blog_id,$user,$pwd) + { + $this->setUser($user,$pwd); + $this->setBlog(); + + return array( + 'draft' => 'Draft', + 'pending' => 'Pending Review', + 'private' => 'Private', + 'publish' => 'Published', + 'scheduled' => 'Scheduled' + ); + } + + private function getPageStatusList($blog_id,$user,$pwd) + { + $this->setUser($user,$pwd); + $this->setBlog(); + $this->checkPagesPermission(); + + return array( + 'draft' => 'Draft', + 'private' => 'Private', + 'published' => 'Published', + 'scheduled' => 'Scheduled' + ); + } + + private function checkPagesPermission() + { + if (!$this->core->plugins->moduleExists('pages')) { + throw new Exception('Pages management is not available on this blog.'); + } + + if (!$this->core->auth->check('pages,contentadmin',$this->core->blog->id)) { + throw new Exception('Not enough permissions to edit pages.',401); + } + } + + private function getPages($blog_id,$user,$pwd,$limit=null,$id=null) + { + $this->setUser($user,$pwd); + $this->setBlog(); + $this->checkPagesPermission(); + + $params = array( + 'post_type' => 'page', + 'order' => 'post_position ASC, post_title ASC' + ); + + if ($id) { + $params['post_id'] = (integer) $id; + } + if ($limit) { + $params['limit'] = $limit; + } + + $posts = $this->core->blog->getPosts($params); + + $res = array(); + while ($posts->fetch()) + { + $tres = array( + "dateCreated" => new xmlrpcDate($posts->getTS()), + "userid" => $posts->user_id, + "page_id" => $posts->post_id, + "page_status" => $this->translateWpStatus((integer) $posts->post_status), + "description" => $posts->post_content_xhtml, + "title" => $posts->post_title, + "link" => $posts->getURL(), + "permaLink" => $posts->getURL(), + "categories" => array(), + "excerpt" => $posts->post_excerpt_xhtml, + "text_more" => '', + "mt_allow_comments" => (integer) $posts->post_open_comment, + "mt_allow_pings" => (integer) $posts->post_open_tb, + "wp_slug" => $posts->post_url, + "wp_password" => $posts->post_password, + "wp_author" => $posts->getAuthorCN(), + "wp_page_parent_id" => 0, + "wp_page_parent_title" => '', + "wp_page_order" => $posts->post_position, + "wp_author_id" => $posts->user_id, + "wp_author_display_name" => $posts->getAuthorCN(), + "date_created_gmt" => new xmlrpcDate(dt::iso8601($posts->getTS(),$posts->post_tz)), + "custom_fields" => array(), + "wp_page_template" => 'default' + ); + + # --BEHAVIOR-- xmlrpcGetPageInfo + $this->core->callBehavior('xmlrpcGetPageInfo',$this,array(&$tres)); + + $res[] = $tres; + } + + return $res; + } + + private function newPage($blog_id,$user,$pwd,$struct,$publish) + { + $this->setUser($user,$pwd); + $this->setBlog(); + $this->checkPagesPermission(); + + $struct['post_type'] = 'page'; + + return $this->newPost($blog_id,$user,$pwd,null,$struct,$publish); + } + + private function editPage($page_id,$user,$pwd,$struct,$publish) + { + $this->setUser($user,$pwd); + $this->setBlog(); + $this->checkPagesPermission(); + + $struct['post_type'] = 'page'; + + return $this->editPost($page_id,$user,$pwd,null,$struct,$publish); + } + + private function deletePage($page_id,$user,$pwd) + { + $this->setUser($user,$pwd); + $this->setBlog(); + $this->checkPagesPermission(); + + $page_id = (integer) $page_id; + + $this->getPostRS($page_id,$user,$pwd,'page'); + $this->core->blog->delPost($page_id); + + return true; + } + + private function getAuthors($user,$pwd) + { + $this->setUser($user,$pwd); + $this->setBlog(); + + $rs = $this->core->getBlogPermissions($this->core->blog->id); + $res = array(); + + foreach($rs as $k => $v) + { + $res[] = array( + 'user_id' => $k, + 'user_login' => $k, + 'display_name' => dcUtils::getUserCN($k,$v['name'],$v['firstname'],$v['displayname']) + ); + } + return $res; + } + + private function getTags($user,$pwd) + { + $this->setUser($user,$pwd); + $this->setBlog(); + + $tags = $this->core->meta->getMeta('tag'); + $tags->sort('meta_id_lower','asc'); + + $res = array(); + $url = $this->core->blog->url. + $this->core->url->getURLFor('tag','%s'); + $f_url = $this->core->blog->url. + $this->core->url->getURLFor('tag_feed','%s'); + while ($tags->fetch()) + { + $res[] = array( + 'tag_id' => $tags->meta_id, + 'name' => $tags->meta_id, + 'count' => $tags->count, + 'slug' => $tags->meta_id, + 'html_url' => sprintf($url,$tags->meta_id), + 'rss_url' => sprintf($f_url,$tags->meta_id) + ); + } + return $res; + } + + private function newCategory($user,$pwd,$struct) + { + $this->setUser($user,$pwd); + $this->setBlog(); + + if (empty($struct['name'])) { + throw new Exception('You mus give a category name.'); + } + + $cur = $this->core->con->openCursor($this->core->prefix.'category'); + $cur->cat_title = $struct['name']; + + if (!empty($struct['slug'])) { + $cur->cat_url = $struct['slug']; + } + if (!empty($struct['category_description'])) { + $cur->cat_desc = $struct['category_description']; + if (html::clean($cur->cat_desc) == $cur->cat_desc) { + $cur->cat_desc = '

        '.$cur->cat_desc.'

        '; + } + } + + $parent = !empty($struct['category_parent']) ? (integer) $struct['category_parent'] : 0; + + $id = $this->core->blog->addCategory($cur,$parent); + $rs = $this->core->blog->getCategory($id); + return $rs->cat_url; + } + + private function deleteCategory($user,$pwd,$cat_id) + { + $this->setUser($user,$pwd); + $this->setBlog(); + + $c = $this->core->blog->getCategories(array('cat_url' => $cat_id)); + if ($c->isEmpty()) { + throw new Exception(__('This category does not exist.')); + } + $cat_id = $c->cat_id; + unset($c); + + $this->core->blog->delCategory((integer) $cat_id); + return true; + } + + private function searchCategories($user,$pwd,$category,$limit) + { + $this->setUser($user,$pwd); + $this->setBlog(); + + $strReq = 'SELECT cat_id, cat_title, cat_url '. + 'FROM '.$this->core->prefix.'category '. + "WHERE blog_id = '".$this->core->con->escape($this->core->blog->id)."' ". + "AND LOWER(cat_title) LIKE LOWER('%".$this->core->con->escape($category)."%') ". + ($limit > 0 ? $this->core->con->limit($limit) : ''); + + $rs = $this->core->con->select($strReq); + + $res = array(); + while ($rs->fetch()) + { + $res[] = array( + 'category_id' => $rs->cat_url, + 'category_name' => $rs->cat_url + ); + } + return $res; + } + + private function countComments($user,$pwd,$post_id) + { + $this->setUser($user,$pwd); + $this->setBlog(); + + $res = array( + 'approved' => 0, + 'awaiting_moderation' => 0, + 'spam' => 0, + 'total' => 0 + ); + $rs = $this->core->blog->getComments(array('post_id' => $post_id)); + + while ($rs->fetch()) { + $res['total']++; + if ($rs->comment_status == 1) { + $res['approved']++; + } elseif ($rs->comment_status == -2) { + $res['spam']++; + } else { + $res['awaiting_moderation']++; + } + } + return $res; + } + + private function getComments($user,$pwd,$struct,$id=null) + { + $this->setUser($user,$pwd); + $this->setBlog(); + + $params = array(); + + if (!empty($struct['status'])) { + $params['comment_status'] = $this->translateWpCommentstatus($struct['status']); + } + + if (!empty($struct['post_id'])) { + $params['post_id'] = (integer) $struct['post_id']; + } + + if (isset($id)) { + $params['comment_id'] = $id; + } + + $offset = !empty($struct['offset']) ? (integer) $struct['offset'] : 0; + $limit = !empty($struct['number']) ? (integer) $struct['number'] : 10; + $params['limit'] = array($offset,$limit); + + $rs = $this->core->blog->getComments($params); + $res = array(); + while ($rs->fetch()) + { + $res[] = array( + 'date_created_gmt' => new xmlrpcDate($rs->getTS()), + 'user_id' => $rs->user_id, + 'comment_id' => $rs->comment_id, + 'parent' => 0, + 'status' => $this->translateWpCommentstatus((integer) $rs->comment_status), + 'content' => $rs->comment_content, + 'link' => $rs->getPostURL().'#c'.$rs->comment_id, + 'post_id' => $rs->post_id, + 'post_title' => $rs->post_title, + 'author' => $rs->comment_author, + 'author_url' => $rs->comment_site, + 'author_email' => $rs->comment_email, + 'author_ip' => $rs->comment_ip + ); + } + return $res; + } + + private function addComment($user,$pwd,$post_id,$struct) + { + $this->setUser($user,$pwd); + $this->setBlog(); + + if (empty($struct['content'])) { + throw new Exception('Sorry, you cannot post an empty comment',401); + } + + if (is_numeric($post_id)) { + $p['post_id'] = $post_id; + } else { + $p['post_url'] = $post_id; + } + $rs = $this->core->blog->getPosts($p); + if ($rs->isEmpty()) { + throw new Exception('Sorry, no such post.',404); + } + + $cur = $this->core->con->openCursor($this->core->prefix.'comment'); + + $cur->comment_author = $this->core->auth->getInfo('user_cn'); + $cur->comment_email = $this->core->auth->getInfo('user_email'); + $cur->comment_site = $this->core->auth->getInfo('user_url'); + + $cur->comment_content = $struct['content']; + $cur->post_id = (integer) $post_id; + + $id = $this->core->blog->addComment($cur); + return $id; + } + + private function updComment($user,$pwd,$comment_id,$struct) + { + $this->setUser($user,$pwd); + $this->setBlog(); + + $cur = $this->core->con->openCursor($this->core->prefix.'comment'); + + if (isset($struct['status'])) { + $cur->comment_status = $this->translateWpCommentstatus($struct['status']); + } + + if (isset($struct['date_created_gmt'])) { + if ($struct['date_created_gmt'] instanceof xmlrpcDate) { + $cur->comment_dt = date('Y-m-d H:i:00',$struct['date_created_gmt']->getTimestamp()); + } elseif (is_string($struct['date_created_gmt']) && @strtotime($struct['date_created_gmt'])) { + $cur->comment_dt = date('Y-m-d H:i:00',strtotime($struct['date_created_gmt'])); + } + $cur->comment_dt = $struct['date_created_gmt']; + } + + if (isset($struct['content'])) { + $cur->comment_content = $struct['content']; + } + + if (isset($struct['author'])) { + $cur->comment_author = $struct['author']; + } + + if (isset($struct['author_url'])) { + $cur->comment_site = $struct['author_url']; + } + + if (isset($struct['author_email'])) { + $cur->comment_email = $struct['author_email']; + } + + $this->core->blog->updComment($comment_id,$cur); + return true; + } + + private function delComment($user,$pwd,$comment_id) + { + $this->setUser($user,$pwd); + $this->setBlog(); + + $this->core->blog->delComment($comment_id); + return true; + } + + /* Blogger methods + --------------------------------------------------- */ + public function blogger_newPost($appkey,$blogid,$username,$password,$content,$publish) + { + return $this->newPost($blogid,$username,$password,$content,array(),$publish); + } + + public function blogger_editPost($appkey,$postid,$username,$password,$content,$publish) + { + return $this->editPost($postid,$username,$password,$content,array(),$publish); + } + + public function blogger_getPost($appkey,$postid,$username,$password) + { + return $this->getPost($postid,$username,$password,'blogger'); + } + + public function blogger_deletePost($appkey,$postid,$username,$password,$publish) + { + return $this->deletePost($postid,$username,$password); + } + + public function blogger_getRecentPosts($appkey,$blogid,$username,$password,$numberOfPosts) + { + return $this->getRecentPosts($blogid,$username,$password,$numberOfPosts,'blogger'); + } + + public function blogger_getUserBlogs($appkey,$username,$password) + { + return $this->getUserBlogs($username,$password); + } + + public function blogger_getUserInfo($appkey,$username,$password) + { + return $this->getUserInfo($username,$password); + } + + + /* Metaweblog methods + ------------------------------------------------------- */ + public function mw_newPost($blogid,$username,$password,$content,$publish) + { + return $this->newPost($blogid,$username,$password,'',$content,$publish); + } + + public function mw_editPost($postid,$username,$password,$content,$publish) + { + return $this->editPost($postid,$username,$password,'',$content,$publish); + } + + public function mw_getPost($postid,$username,$password) + { + return $this->getPost($postid,$username,$password,'mw'); + } + + public function mw_getRecentPosts($blogid,$username,$password,$numberOfPosts) + { + return $this->getRecentPosts($blogid,$username,$password,$numberOfPosts,'mw'); + } + + public function mw_getCategories($blogid,$username,$password) + { + return $this->getCategories($blogid,$username,$password); + } + + public function mw_newMediaObject($blogid,$username,$password,$file) + { + return $this->newMediaObject($blogid,$username,$password,$file); + } + + /* MovableType methods + --------------------------------------------------- */ + public function mt_getRecentPostTitles($blogid,$username,$password,$numberOfPosts) + { + return $this->getRecentPosts($blogid,$username,$password,$numberOfPosts,'mt'); + } + + public function mt_getCategoryList($blogid,$username,$password) + { + return $this->getCategories($blogid,$username,$password); + } + + public function mt_getPostCategories($postid,$username,$password) + { + return $this->getPostCategories($postid,$username,$password); + } + + public function mt_setPostCategories($postid,$username,$password,$categories) + { + return $this->setPostCategories($postid,$username,$password,$categories); + } + + public function mt_publishPost($postid,$username,$password) + { + return $this->publishPost($postid,$username,$password); + } + + public function mt_supportedTextFilters() + { + return array(); + } + + /* WordPress methods + --------------------------------------------------- */ + public function wp_getUsersBlogs($username,$password) + { + return $this->getUserBlogs($username,$password); + } + + public function wp_getPage($blogid,$pageid,$username,$password) + { + $res = $this->getPages($blogid,$username,$password,null,$pageid); + + if (empty($res)) { + throw new Exception('Sorry, no such page',404); + } + + return $res[0]; + } + + public function wp_getPages($blogid,$username,$password,$num=10) + { + return $this->getPages($blogid,$username,$password,$num); + } + + public function wp_newPage($blogid,$username,$password,$content,$publish) + { + return $this->newPage($blogid,$username,$password,$content,$publish); + } + + public function wp_deletePage($blogid,$username,$password,$pageid) + { + return $this->deletePage($pageid,$username,$password); + } + + public function wp_editPage($blogid,$pageid,$username,$password,$content,$publish) + { + return $this->editPage($pageid,$username,$password,$content,$publish); + } + + public function wp_getPageList($blogid,$username,$password) + { + $A = $this->getPages($blogid,$username,$password); + $res = array(); + foreach ($A as $v) { + $res[] = array( + 'page_id' => $v['page_id'], + 'page_title' => $v['title'], + 'page_parent_id' => $v['wp_page_parent_id'], + 'dateCreated' => $v['dateCreated'], + 'date_created_gmt' => $v['date_created_gmt'] + ); + } + return $res; + } + + public function wp_getAuthors($blogid,$username,$password) + { + return $this->getAuthors($username,$password); + } + + public function wp_getCategories($blogid,$username,$password) + { + return $this->getCategories($blogid,$username,$password); + } + + public function wp_getTags($blogid,$username,$password) + { + return $this->getTags($username,$password); + } + + public function wp_newCategory($blogid,$username,$password,$content) + { + return $this->newCategory($username,$password,$content); + } + + public function wp_deleteCategory($blogid,$username,$password,$categoryid) + { + return $this->deleteCategory($username,$password,$categoryid); + } + + public function wp_suggestCategories($blogid,$username,$password,$category,$max_results=0) + { + return $this->searchCategories($username,$password,$category,$max_results); + } + + public function wp_uploadFile($blogid,$username,$password,$file) + { + return $this->newMediaObject($blogid,$username,$password,$file); + } + + public function wp_getPostStatusList($blogid,$username,$password) + { + return $this->getPostStatusList($blogid,$username,$password); + } + + public function wp_getPageStatusList($blogid,$username,$password) + { + return $this->getPostStatusList($blogid,$username,$password); + } + + public function wp_getPageTemplates($blogid,$username,$password) + { + return array('Default' => 'default'); + } + + public function wp_getOptions($blogid,$username,$password,$options=array()) + { + $this->setUser($username,$password); + $this->setBlog(); + + return $this->translateWpOptions($options); + } + + public function wp_setOptions($blogid,$username,$password,$options) + { + $this->setUser($username,$password); + $this->setBlog(); + + if (!$this->core->auth->check('admin',$this->core->blog->id)) { + throw new Exception('Not enough permissions to edit options.',401); + } + + $opt = $this->translateWpOptions(); + + $done = array(); + $blog_changes = false; + $cur = $this->core->con->openCursor($this->core->prefix.'blog'); + + $this->core->blog->settings->addNamespace('system'); + + foreach ($options as $name => $value) + { + if (!isset($opt[$name]) || $opt[$name]['readonly']) { + continue; + } + + switch ($name) + { + case 'blog_title': + $blog_changes = true; + $cur->blog_name = $value; + $done[] = $name; + break; + case 'blog_tagline': + $blog_changes = true; + $cur->blog_desc = $value; + $done[] = $name; + break; + case 'date_format': + $this->core->blog->settings->system->put('date_format',$value); + $done[] = $name; + break; + case 'time_format': + $this->core->blog->settings->system->put('time_format',$value); + $done[] = $name; + break; + } + } + + if ($blog_changes) { + $this->core->updBlog($this->core->blog->id,$cur); + $this->core->setBlog($this->core->blog->id); + } + + return $this->translateWpOptions($done); + } + + public function wp_getComment($blogid,$username,$password,$commentid) + { + $res = $this->getComments($username,$password,array(),$commentid); + + if (empty($res)) { + throw new Exception('Sorry, no such comment',404); + } + + return $res[0]; + } + + public function wp_getCommentCount($blogid,$username,$password,$postid) + { + return $this->countComments($username,$password,$postid); + } + + public function wp_getComments($blogid,$username,$password,$struct) + { + return $this->getComments($username,$password,$struct); + } + + public function wp_deleteComment($blogid,$username,$password,$commentid) + { + return $this->delComment($username,$password,$commentid); + } + + public function wp_editComment($blogid,$username,$password,$commentid,$content) + { + return $this->updComment($username,$password,$commentid,$content); + } + + public function wp_newComment($blogid,$username,$password,$postid,$content) + { + return $this->addComment($username,$password,$postid,$content); + } + + public function wp_getCommentStatusList($blogid,$username,$password) + { + $this->setUser($username,$password); + $this->setBlog(); + + return array( + 'hold' => 'Unapproved', + 'approve' => 'Approved', + 'spam' => 'Spam' + ); + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/core_error.php b/v2/dotclear/inc/core_error.php new file mode 100644 index 0000000..5bbbe73 --- /dev/null +++ b/v2/dotclear/inc/core_error.php @@ -0,0 +1,62 @@ + + + + + + + + + Dotclear - Error + + + + +
        +

        Dotclear

        +

        +
        + + \ No newline at end of file diff --git a/v2/dotclear/inc/dbschema/db-schema.php b/v2/dotclear/inc/dbschema/db-schema.php new file mode 100644 index 0000000..cb6bb22 --- /dev/null +++ b/v2/dotclear/inc/dbschema/db-schema.php @@ -0,0 +1,282 @@ +blog + ->blog_id ('varchar', 32, false) + ->blog_uid ('varchar', 32, false) + ->blog_creadt ('timestamp', 0, false, 'now()') + ->blog_upddt ('timestamp', 0, false, 'now()') + ->blog_url ('varchar', 255, false) + ->blog_name ('varchar', 255, false) + ->blog_desc ('text', 0, true) + ->blog_status ('smallint', 0, false, 1) + + ->primary('pk_blog','blog_id') + ; + +$_s->category + ->cat_id ('bigint', 0, false) + ->blog_id ('varchar', 32, false) + ->cat_title ('varchar', 255, false) + ->cat_url ('varchar', 255, false) + ->cat_desc ('text', 0, true) + ->cat_position ('integer', 0, true, 0) + ->cat_lft ('integer', 0, true) + ->cat_rgt ('integer', 0, true) + + ->primary('pk_category','cat_id') + + ->unique('uk_cat_url','cat_url','blog_id') + ; + +$_s->session + ->ses_id ('varchar', 40, false) + ->ses_time ('integer', 0, false, 0) + ->ses_start ('integer', 0, false, 0) + ->ses_value ('text', 0, false) + + ->primary('pk_session','ses_id') + ; + +$_s->setting + ->setting_id ('varchar', 255, false) + ->blog_id ('varchar', 32, true) + ->setting_ns ('varchar', 32, false, "'system'") + ->setting_value ('text', 0, true, null) + ->setting_type ('varchar', 8, false, "'string'") + ->setting_label ('text', 0, true) + + ->unique('uk_setting','setting_ns','setting_id','blog_id') + ; + +$_s->user + ->user_id ('varchar', 32, false) + ->user_super ('smallint', 0, true) + ->user_status ('smallint', 0, false, 1) + ->user_pwd ('varchar', 40, false) + ->user_change_pwd ('smallint', 0, false, 0) + ->user_recover_key ('varchar', 32, true, null) + ->user_name ('varchar', 255, true, null) + ->user_firstname ('varchar', 255, true, null) + ->user_displayname ('varchar', 255, true, null) + ->user_email ('varchar', 255, true, null) + ->user_url ('varchar', 255, true, null) + ->user_desc ('text', 0, true) + ->user_default_blog ('varchar', 32, true, null) + ->user_options ('text', 0, true) + ->user_lang ('varchar', 5, true, null) + ->user_tz ('varchar', 128, false, "'UTC'") + ->user_post_status ('smallint', 0, false, -2) + ->user_creadt ('timestamp', 0, false, 'now()') + ->user_upddt ('timestamp', 0, false, 'now()') + + ->primary('pk_user','user_id') + ; + +$_s->permissions + ->user_id ('varchar', 32, false) + ->blog_id ('varchar', 32, false) + ->permissions ('text', 0, true) + + ->primary('pk_permissions','user_id','blog_id') + ; + +$_s->post + ->post_id ('bigint', 0, false) + ->blog_id ('varchar', 32, false) + ->user_id ('varchar', 32, false) + ->cat_id ('bigint', 0, true) + ->post_dt ('timestamp', 0, false, 'now()') + ->post_tz ('varchar', 128, false, "'UTC'") + ->post_creadt ('timestamp', 0, false, 'now()') + ->post_upddt ('timestamp', 0, false, 'now()') + ->post_password ('varchar', 32, true, null) + ->post_type ('varchar', 32, false, "'post'") + ->post_format ('varchar', 32, false, "'xhtml'") + ->post_url ('varchar', 255, false) + ->post_lang ('varchar', 5, true, null) + ->post_title ('varchar', 255, true, null) + ->post_excerpt ('text', 0, true, null) + ->post_excerpt_xhtml ('text', 0, true, null) + ->post_content ('text', 0, true, null) + ->post_content_xhtml ('text', 0, false) + ->post_notes ('text', 0, true, null) + ->post_meta ('text', 0, true, null) + ->post_words ('text', 0, true, null) + ->post_status ('smallint', 0, false, 0) + ->post_selected ('smallint', 0, false, 0) + ->post_position ('integer', 0, false, 0) + ->post_open_comment ('smallint', 0, false, 0) + ->post_open_tb ('smallint', 0, false, 0) + ->nb_comment ('integer', 0, false, 0) + ->nb_trackback ('integer', 0, false, 0) + + ->primary('pk_post','post_id') + + ->unique('uk_post_url','post_url','post_type','blog_id') + ; + +$_s->media + ->media_id ('bigint', 0, false) + ->user_id ('varchar', 32, false) + ->media_path ('varchar', 255, false) + ->media_title ('varchar', 255, false) + ->media_file ('varchar', 255, false) + ->media_dir ('varchar', 255, false, "'.'") + ->media_meta ('text', 0, true, null) + ->media_dt ('timestamp', 0, false, 'now()') + ->media_creadt ('timestamp', 0, false, 'now()') + ->media_upddt ('timestamp', 0, false, 'now()') + ->media_private ('smallint', 0, false, 0) + + ->primary('pk_media','media_id') + ; + +$_s->post_media + ->media_id ('bigint', 0, false) + ->post_id ('bigint', 0, false) + ->link_type ('varchar', 32, false, "'attachment'") + + ->primary('pk_post_media','media_id','post_id','link_type') + ; + +$_s->log + ->log_id ('bigint', 0, false) + ->user_id ('varchar', 32, true) + ->blog_id ('varchar', 32, true) + ->log_table ('varchar', 255, false) + ->log_dt ('timestamp', 0, false, 'now()') + ->log_ip ('varchar', 39, false) + ->log_msg ('varchar', 255, false) + + ->primary('pk_log','log_id') + ; + +$_s->version + ->module ('varchar', 64, false) + ->version ('varchar', 32, false) + + ->primary('pk_version','module') + ; + +$_s->ping + ->post_id ('bigint', 0, false) + ->ping_url ('varchar', 255, false) + ->ping_dt ('timestamp', 0, false, 'now()') + + ->primary('pk_ping','post_id','ping_url') + ; + +$_s->comment + ->comment_id ('bigint', 0, false) + ->post_id ('bigint', 0, false) + ->comment_dt ('timestamp', 0, false, 'now()') + ->comment_tz ('varchar', 128, false, "'UTC'") + ->comment_upddt ('timestamp', 0, false, 'now()') + ->comment_author ('varchar', 255, true, null) + ->comment_email ('varchar', 255, true, null) + ->comment_site ('varchar', 255, true, null) + ->comment_content ('text', 0, true) + ->comment_words ('text', 0, true, null) + ->comment_ip ('varchar', 39, true, null) + ->comment_status ('smallint', 0, true, 0) + ->comment_spam_status ('varchar', 128, true, 0) + ->comment_spam_filter ('varchar', 32, true, null) + ->comment_trackback ('smallint', 0, false, 0) + + ->primary('pk_comment','comment_id') + ; + +$_s->meta + ->meta_id ('varchar', 255, false) + ->meta_type ('varchar', 64, false) + ->post_id ('bigint', 0, false) + + ->primary('pk_meta','meta_id','meta_type','post_id') + ; + +$_s->pref + ->pref_id ('varchar', 255, false) + ->user_id ('varchar', 32, true) + ->pref_ws ('varchar', 32, false, "'system'") + ->pref_value ('text', 0, true, null) + ->pref_type ('varchar', 8, false, "'string'") + ->pref_label ('text', 0, true) + + ->unique('uk_pref','pref_ws','pref_id','user_id') + ; + +/* References indexes +-------------------------------------------------------- */ +$_s->category->index ('idx_category_blog_id', 'btree', 'blog_id'); +$_s->category->index ('idx_category_cat_lft_blog_id', 'btree', 'blog_id', 'cat_lft'); +$_s->category->index ('idx_category_cat_rgt_blog_id', 'btree', 'blog_id', 'cat_rgt'); +$_s->setting->index ('idx_setting_blog_id', 'btree', 'blog_id'); +$_s->user->index ('idx_user_user_default_blog', 'btree', 'user_default_blog'); +$_s->permissions->index ('idx_permissions_blog_id', 'btree', 'blog_id'); +$_s->post->index ('idx_post_cat_id', 'btree', 'cat_id'); +$_s->post->index ('idx_post_user_id', 'btree', 'user_id'); +$_s->post->index ('idx_post_blog_id', 'btree', 'blog_id'); +$_s->media->index ('idx_media_user_id', 'btree', 'user_id'); +$_s->post_media->index ('idx_post_media_post_id', 'btree', 'post_id'); +$_s->post_media->index ('idx_post_media_media_id', 'btree', 'media_id'); +$_s->log->index ('idx_log_user_id', 'btree', 'user_id'); +$_s->comment->index ('idx_comment_post_id', 'btree', 'post_id'); +$_s->meta->index ('idx_meta_post_id', 'btree','post_id'); +$_s->meta->index ('idx_meta_meta_type', 'btree','meta_type'); +$_s->pref->index ('idx_pref_user_id', 'btree', 'user_id'); + +/* Performance indexes +-------------------------------------------------------- */ +$_s->comment->index ('idx_comment_post_id_dt_status', 'btree', 'post_id', 'comment_dt', 'comment_status'); +$_s->post->index ('idx_post_post_dt', 'btree', 'post_dt'); +$_s->post->index ('idx_post_post_dt_post_id', 'btree', 'post_dt','post_id'); +$_s->post->index ('idx_blog_post_post_dt_post_id', 'btree', 'blog_id','post_dt','post_id'); +$_s->post->index ('idx_blog_post_post_status', 'btree', 'blog_id','post_status'); +$_s->blog->index ('idx_blog_blog_upddt', 'btree', 'blog_upddt'); +$_s->user->index ('idx_user_user_super', 'btree', 'user_super'); + +/* Foreign keys +-------------------------------------------------------- */ +$_s->category->reference('fk_category_blog','blog_id','blog','blog_id','cascade','cascade'); +$_s->setting->reference('fk_setting_blog','blog_id','blog','blog_id','cascade','cascade'); +$_s->user->reference('fk_user_default_blog','user_default_blog','blog','blog_id','cascade','set null'); +$_s->permissions->reference('fk_permissions_blog','blog_id','blog','blog_id','cascade','cascade'); +$_s->permissions->reference('fk_permissions_user','user_id','user','user_id','cascade','cascade'); +$_s->post->reference('fk_post_category','cat_id','category','cat_id','cascade','set null'); +$_s->post->reference('fk_post_user','user_id','user','user_id','cascade','cascade'); +$_s->post->reference('fk_post_blog','blog_id','blog','blog_id','cascade','cascade'); +$_s->media->reference('fk_media_user','user_id','user','user_id','cascade','cascade'); +$_s->post_media->reference('fk_media','media_id','media','media_id','cascade','cascade'); +$_s->post_media->reference('fk_media_post','post_id','post','post_id','cascade','cascade'); +$_s->ping->reference('fk_ping_post','post_id','post','post_id','cascade','cascade'); +$_s->comment->reference('fk_comment_post','post_id','post','post_id','cascade','cascade'); +$_s->log->reference('fk_log_blog','blog_id','blog','blog_id','cascade','set null'); +$_s->meta->reference('fk_meta_post','post_id','post','post_id','cascade','cascade'); +$_s->pref->reference('fk_pref_user','user_id','user','user_id','cascade','cascade'); + +/* PostgreSQL specific indexes +-------------------------------------------------------- */ +if ($_s->driver() == 'pgsql') +{ + $_s->setting->index ('idx_setting_blog_id_null', 'btree', '(blog_id IS NULL)'); + $_s->media->index ('idx_media_media_path', 'btree', 'media_path', 'media_dir'); + $_s->pref->index ('idx_pref_user_id_null', 'btree', '(user_id IS NULL)'); +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/dbschema/upgrade-cli.php b/v2/dotclear/inc/dbschema/upgrade-cli.php new file mode 100644 index 0000000..6beaeea --- /dev/null +++ b/v2/dotclear/inc/dbschema/upgrade-cli.php @@ -0,0 +1,52 @@ +#!/usr/bin/env php +con->begin(); + try { + $changes = dotclearUpgrade($core); + } catch (Exception $e) { + $core->con->rollback(); + throw $e; + } + $core->con->commit(); + echo 'Upgrade process successfully completed ('.$changes."). \n"; + exit(0); +} +catch (Exception $e) +{ + echo $e->getMessage()."\n"; + exit(1); +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/dbschema/upgrade.php b/v2/dotclear/inc/dbschema/upgrade.php new file mode 100644 index 0000000..fc9213b --- /dev/null +++ b/v2/dotclear/inc/dbschema/upgrade.php @@ -0,0 +1,331 @@ +getVersion('core'); + + if ($version === null) { + return false; + } + + if (version_compare($version,DC_VERSION,'<') == 1 || strpos(DC_VERSION,'dev')) + { + try + { + if ($core->con->driver() == 'sqlite') { + throw new Exception(__('SQLite Database Schema cannot be upgraded.')); + } + + # Database upgrade + $_s = new dbStruct($core->con,$core->prefix); + require dirname(__FILE__).'/db-schema.php'; + + $si = new dbStruct($core->con,$core->prefix); + $changes = $si->synchronize($_s); + + /* Some other upgrades + ------------------------------------ */ + # Populate media_dir field (since 2.0-beta3.3) + if (version_compare($version,'2.0-beta3.3','<')) + { + $strReq = 'SELECT media_id, media_file FROM '.$core->prefix.'media '; + $rs_m = $core->con->select($strReq); + while($rs_m->fetch()) { + $cur = $core->con->openCursor($core->prefix.'media'); + $cur->media_dir = dirname($rs_m->media_file); + $cur->update('WHERE media_id = '.(integer) $rs_m->media_id); + } + } + + if (version_compare($version,'2.0-beta7.3','<')) + { + # Blowup becomes default theme + $strReq = 'UPDATE '.$core->prefix.'setting '. + "SET setting_value = '%s' ". + "WHERE setting_id = 'theme' ". + "AND setting_value = '%s' ". + 'AND blog_id IS NOT NULL '; + $core->con->execute(sprintf($strReq,'blueSilence','default')); + $core->con->execute(sprintf($strReq,'default','blowup')); + } + + if (version_compare($version,'2.1-alpha2-r2383','<')) + { + $schema = dbSchema::init($core->con); + $schema->dropUnique($core->prefix.'category',$core->prefix.'uk_cat_title'); + + # Reindex categories + $rs = $core->con->select( + 'SELECT cat_id, cat_title, blog_id '. + 'FROM '.$core->prefix.'category '. + 'ORDER BY blog_id ASC , cat_position ASC ' + ); + $cat_blog = $rs->blog_id; + $i = 2; + while ($rs->fetch()) { + if ($cat_blog != $rs->blog_id) { + $i = 2; + } + $core->con->execute( + 'UPDATE '.$core->prefix.'category SET ' + .'cat_lft = '.($i++).', cat_rgt = '.($i++).' '. + 'WHERE cat_id = '.(integer) $rs->cat_id + ); + $cat_blog = $rs->blog_id; + } + } + + if (version_compare($version,'2.1.6','<=')) + { + # ie7js has been upgraded + $ie7files = array ( + 'ie7-base64.php ', + 'ie7-content.htc', + 'ie7-core.js', + 'ie7-css2-selectors.js', + 'ie7-css3-selectors.js', + 'ie7-css-strict.js', + 'ie7-dhtml.js', + 'ie7-dynamic-attributes.js', + 'ie7-fixed.js', + 'ie7-graphics.js', + 'ie7-html4.js', + 'ie7-ie5.js', + 'ie7-layout.js', + 'ie7-load.htc', + 'ie7-object.htc', + 'ie7-overflow.js', + 'ie7-quirks.js', + 'ie7-server.css', + 'ie7-standard-p.js', + 'ie7-xml-extras.js' + ); + foreach ($ie7files as $f) { + @unlink(DC_ROOT.'/admin/js/ie7/'.$f); + } + } + + if (version_compare($version,'2.2-alpha1-r3043','<')) + { + # metadata has been integrated to the core. + $core->plugins->loadModules(DC_PLUGINS_ROOT); + if ($core->plugins->moduleExists('metadata')) { + $core->plugins->deleteModule('metadata'); + } + + # Tags template class has been renamed + $sqlstr = + 'SELECT blog_id, setting_id, setting_value '. + 'FROM '.$core->prefix.'setting '. + 'WHERE (setting_id = \'widgets_nav\' OR setting_id = \'widgets_extra\') '. + 'AND setting_ns = \'widgets\';'; + $rs = $core->con->select($sqlstr); + while ($rs->fetch()) { + $widgetsettings = base64_decode($rs->setting_value); + $widgetsettings = str_replace ('s:11:"tplMetadata"','s:7:"tplTags"',$widgetsettings); + $cur = $core->con->openCursor($core->prefix.'setting'); + $cur->setting_value = base64_encode($widgetsettings); + $sqlstr = 'WHERE setting_id = \''.$rs->setting_id.'\' AND setting_ns = \'widgets\' '. + 'AND blog_id ' . + ($rs->blog_id == NULL ? 'is NULL' : '= \''.$core->con->escape($rs->blog_id).'\''); + $cur->update($sqlstr); + } + } + + if (version_compare($version,'2.3','<')) + { + # Add global favorites + $init_fav = array(); + + $init_fav['new_post'] = array('new_post','New entry','post.php', + 'images/menu/edit.png','images/menu/edit-b.png', + 'usage,contentadmin',null,'menu-new-post'); + $init_fav['posts'] = array('posts','Entries','posts.php', + 'images/menu/entries.png','images/menu/entries-b.png', + 'usage,contentadmin',null,null); + $init_fav['comments'] = array('comments','Comments','comments.php', + 'images/menu/comments.png','images/menu/comments-b.png', + 'usage,contentadmin',null,null); + $init_fav['prefs'] = array('prefs','My preferences','preferences.php', + 'images/menu/user-pref.png','images/menu/user-pref-b.png', + '*',null,null); + $init_fav['blog_pref'] = array('blog_pref','Blog settings','blog_pref.php', + 'images/menu/blog-pref.png','images/menu/blog-pref-b.png', + 'admin',null,null); + $init_fav['blog_theme'] = array('blog_theme','Blog appearance','blog_theme.php', + 'images/menu/themes.png','images/menu/blog-theme-b.png', + 'admin',null,null); + + $init_fav['pages'] = array('pages','Pages','plugin.php?p=pages', + 'index.php?pf=pages/icon.png','index.php?pf=pages/icon-big.png', + 'contentadmin,pages',null,null); + $init_fav['blogroll'] = array('blogroll','Blogroll','plugin.php?p=blogroll', + 'index.php?pf=blogroll/icon-small.png','index.php?pf=blogroll/icon.png', + 'usage,contentadmin',null,null); + + $count = 0; + foreach ($init_fav as $k => $f) { + $t = array('name' => $f[0],'title' => $f[1],'url' => $f[2], 'small-icon' => $f[3], + 'large-icon' => $f[4],'permissions' => $f[5],'id' => $f[6],'class' => $f[7]); + $sqlstr = 'INSERT INTO '.$core->prefix.'pref (pref_id, user_id, pref_ws, pref_value, pref_type, pref_label) VALUES ('. + '\''.sprintf("g%03s",$count).'\',NULL,\'favorites\',\''.serialize($t).'\',\'string\',NULL);'; + $core->con->execute($sqlstr); + $count++; + } + + # A bit of housecleaning for no longer needed files + $remfiles = array ( + 'admin/style/cat-bg.png', + 'admin/style/footer-bg.png', + 'admin/style/head-logo.png', + 'admin/style/tab-bg.png', + 'admin/style/tab-c-l.png', + 'admin/style/tab-c-r.png', + 'admin/style/tab-l-l.png', + 'admin/style/tab-l-r.png', + 'admin/style/tab-n-l.png', + 'admin/style/tab-n-r.png', + 'inc/clearbricks/_common.php', + 'inc/clearbricks/common/lib.crypt.php', + 'inc/clearbricks/common/lib.date.php', + 'inc/clearbricks/common/lib.files.php', + 'inc/clearbricks/common/lib.form.php', + 'inc/clearbricks/common/lib.html.php', + 'inc/clearbricks/common/lib.http.php', + 'inc/clearbricks/common/lib.l10n.php', + 'inc/clearbricks/common/lib.text.php', + 'inc/clearbricks/common/tz.dat', + 'inc/clearbricks/common/_main.php', + 'inc/clearbricks/dblayer/class.cursor.php', + 'inc/clearbricks/dblayer/class.mysql.php', + 'inc/clearbricks/dblayer/class.pgsql.php', + 'inc/clearbricks/dblayer/class.sqlite.php', + 'inc/clearbricks/dblayer/dblayer.php', + 'inc/clearbricks/dbschema/class.dbschema.php', + 'inc/clearbricks/dbschema/class.dbstruct.php', + 'inc/clearbricks/dbschema/class.mysql.dbschema.php', + 'inc/clearbricks/dbschema/class.pgsql.dbschema.php', + 'inc/clearbricks/dbschema/class.sqlite.dbschema.php', + 'inc/clearbricks/diff/lib.diff.php', + 'inc/clearbricks/diff/lib.unified.diff.php', + 'inc/clearbricks/filemanager/class.filemanager.php', + 'inc/clearbricks/html.filter/class.html.filter.php', + 'inc/clearbricks/html.validator/class.html.validator.php', + 'inc/clearbricks/image/class.image.meta.php', + 'inc/clearbricks/image/class.image.tools.php', + 'inc/clearbricks/mail/class.mail.php', + 'inc/clearbricks/mail/class.socket.mail.php', + 'inc/clearbricks/net/class.net.socket.php', + 'inc/clearbricks/net.http/class.net.http.php', + 'inc/clearbricks/net.http.feed/class.feed.parser.php', + 'inc/clearbricks/net.http.feed/class.feed.reader.php', + 'inc/clearbricks/net.xmlrpc/class.net.xmlrpc.php', + 'inc/clearbricks/pager/class.pager.php', + 'inc/clearbricks/rest/class.rest.php', + 'inc/clearbricks/session.db/class.session.db.php', + 'inc/clearbricks/template/class.template.php', + 'inc/clearbricks/text.wiki2xhtml/class.wiki2xhtml.php', + 'inc/clearbricks/url.handler/class.url.handler.php', + 'inc/clearbricks/zip/class.unzip.php', + 'inc/clearbricks/zip/class.zip.php', + 'themes/default/tpl/.htaccess', + 'themes/default/tpl/404.html', + 'themes/default/tpl/archive.html', + 'themes/default/tpl/archive_month.html', + 'themes/default/tpl/category.html', + 'themes/default/tpl/home.html', + 'themes/default/tpl/post.html', + 'themes/default/tpl/search.html', + 'themes/default/tpl/tag.html', + 'themes/default/tpl/tags.html', + 'themes/default/tpl/user_head.html', + 'themes/default/tpl/_flv_player.html', + 'themes/default/tpl/_footer.html', + 'themes/default/tpl/_head.html', + 'themes/default/tpl/_mp3_player.html', + 'themes/default/tpl/_top.html' + ); + $remfolders = array ( + 'inc/clearbricks/common', + 'inc/clearbricks/dblayer', + 'inc/clearbricks/dbschema', + 'inc/clearbricks/diff', + 'inc/clearbricks/filemanager', + 'inc/clearbricks/html.filter', + 'inc/clearbricks/html.validator', + 'inc/clearbricks/image', + 'inc/clearbricks/mail', + 'inc/clearbricks/net', + 'inc/clearbricks/net.http', + 'inc/clearbricks/net.http.feed', + 'inc/clearbricks/net.xmlrpc', + 'inc/clearbricks/pager', + 'inc/clearbricks/rest', + 'inc/clearbricks/session.db', + 'inc/clearbricks/template', + 'inc/clearbricks/text.wiki2xhtml', + 'inc/clearbricks/url.handler', + 'inc/clearbricks/zip', + 'inc/clearbricks', + 'themes/default/tpl' + ); + + foreach ($remfiles as $f) { + @unlink(DC_ROOT.'/'.$f); + } + foreach ($remfolders as $f) { + @rmdir(DC_ROOT.'/'.$f); + } + } + + if (version_compare($version,'2.3.1','<')) + { + # Remove unecessary file + @unlink(DC_ROOT.'/'.'inc/libs/clearbricks/.hgignore'); + } + + if (version_compare($version,'2.4.0','<=')) + { + # setup media_exclusion + $strReq = 'UPDATE '.$core->prefix.'setting '. + "SET setting_value = '/\\.php\$/i' ". + "WHERE setting_id = 'media_exclusion' ". + "AND setting_value = '' "; + $core->con->execute($strReq); + } + + $core->setVersion('core',DC_VERSION); + $core->blogDefaults(); + + # Drop content from session table + $core->con->execute('DELETE FROM '.$core->prefix.'session '); + + # Empty templates cache directory + try { + $core->emptyTemplatesCache(); + } catch (Exception $e) {} + + return $changes; + } + catch (Exception $e) + { + throw new Exception(__('Something went wrong with auto upgrade:'). + ' '.$e->getMessage()); + } + } + + # No upgrade? + return false; +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/digests b/v2/dotclear/inc/digests new file mode 100644 index 0000000..df4b068 --- /dev/null +++ b/v2/dotclear/inc/digests @@ -0,0 +1,694 @@ +3a1c6cc728dddc258091a601f28a9c12 ./inc/swf/swfupload.swf +362b9537b53c8d3eb363598e5f38fb8b ./inc/swf/player_mp3.swf +9dcb71aec92e94b1b905192412a1f2a5 ./inc/swf/player_flv.swf +d7b28c9c52cf01199f8c9fe230e8b43f ./inc/core/class.dc.media.php +68523099197e276833c84c6c2376bb08 ./inc/core/class.dc.workspace.php +112f70a6b6b4eec61ad405f990b60fbf ./inc/core/class.dc.update.php +cde424b7a01df820e8bb6b0f1d9939d4 ./inc/core/class.dc.log.php +3477103ce812b71a9d38e3cf1feadb3b ./inc/core/class.dc.namespace.php +949e4e5a3746a1ad8de75dbb5a90c35a ./inc/core/class.dc.meta.php +b2aada7c5fa56c7bcf32c6cb3fae59fa ./inc/core/class.dc.categories.php +bb44cb8fbecee45fca2709969b227f85 ./inc/core/class.dc.xmlrpc.php +fad7358243930c7f22df931aba38427c ./inc/core/class.dc.error.php +a3cf40511123ed66a4a14bcf4b79faa4 ./inc/core/class.dc.utils.php +ac779916ef9504dac7771143e1352529 ./inc/core/class.dc.rest.php +6d45dad8e0afba501538e8577c57c62e ./inc/core/class.dc.themes.php +284bfc24af7741ab9439a94e45553f22 ./inc/core/class.dc.auth.php +ac5f58c6a91756d730850e1f0054f0f4 ./inc/core/class.dc.rs.extensions.php +d8b464d462e8c26fdb8314991f030dd6 ./inc/core/class.dc.trackback.php +aaaf612c3c0ba092d99bea8b65882838 ./inc/core/class.dc.settings.php +bc3fdfd02070475f7d0d2dae9d2fef0b ./inc/core/class.dc.postmedia.php +57dbe830b06b44ab46c9d800e5e68abf ./inc/core/class.dc.prefs.php +ddcf7b8ae49896902f78012fc502f765 ./inc/core/class.dc.blog.php +6a959c862a9cdba82da5ba3b73059474 ./inc/core/class.dc.modules.php +05941079cd9db9368c3debd740a85217 ./inc/core/class.dc.core.php +cb95b315558ebcb254249210637abe4b ./inc/libs/clearbricks/ext/incutio.ixr_library.php +d867d4ebc95bf8cbf8b196925c4100fc ./inc/libs/clearbricks/net/class.net.socket.php +1b89f622435faa7a75fa58a1aca3d54d ./inc/libs/clearbricks/zip/class.unzip.php +dd4bebcf0c65f78f07f2c831c1d26aa3 ./inc/libs/clearbricks/zip/class.zip.php +a0439fc6efcb19e17cd01c8530ada840 ./inc/libs/clearbricks/diff/lib.tidy.diff.php +f770aaef9206d211e158c4e956064a04 ./inc/libs/clearbricks/diff/lib.diff.php +2edbef60bcab048afb2c250e59c082df ./inc/libs/clearbricks/mail/class.socket.mail.php +4c5c63f2bb1489e3dc3bfc534f63bcc8 ./inc/libs/clearbricks/mail/class.mail.php +c1920efdf8daa2fa28db711391763e95 ./inc/libs/clearbricks/rest/class.rest.php +7dabf49811c54cd7e2e00a755a95e2da ./inc/libs/clearbricks/dblayer/class.pgsql.php +1ba018c7314f5e38484a516a9e6efbf0 ./inc/libs/clearbricks/dblayer/class.mysql.php +7ee9856ad3e4fced1869b9067b7da3ae ./inc/libs/clearbricks/dblayer/class.sqlite.php +2e3c38caefed1891cc9c268060e88a32 ./inc/libs/clearbricks/dblayer/dblayer.php +ffe21c976b615f671ffc80430ec1dfe7 ./inc/libs/clearbricks/dblayer/class.cursor.php +e7b55e965efccd72eeddb344c085156c ./inc/libs/clearbricks/dblayer/class.mysqli.php +e94f8b559d0a6d3786332bb8b5740dd1 ./inc/libs/clearbricks/html.validator/class.html.validator.php +f2940f553ad376554d9fc6df6954f1ff ./inc/libs/clearbricks/html.filter/class.html.filter.php +14d99509858d7dc753c23b5c62b80e7e ./inc/libs/clearbricks/Makefile +f2813d658120f149b4e03613df0cd8c0 ./inc/libs/clearbricks/image/class.image.tools.php +dea8c1d155c6d3cf6071bd34d105c47b ./inc/libs/clearbricks/image/class.image.meta.php +c0eb7fef8da37112c003ba0baf93bf53 ./inc/libs/clearbricks/filemanager/class.filemanager.php +bcf108d62c14d6e654b33c998bd3d1fd ./inc/libs/clearbricks/pager/class.pager.php +8a14839615beb6693b6d171852660563 ./inc/libs/clearbricks/net.http.feed/class.feed.parser.php +252485faf7459053c3f7e811493e5f30 ./inc/libs/clearbricks/net.http.feed/class.feed.reader.php +1bf1a1a82994425f03ad9f19e935d3c3 ./inc/libs/clearbricks/README +3fab7ec6ad3bc37b72d19848a3950bd9 ./inc/libs/clearbricks/net.xmlrpc/class.net.xmlrpc.php +f59dc65e4c36b47c0243eae0a60da11f ./inc/libs/clearbricks/dbschema/class.dbschema.php +4dc4e0ccd516f43cc1058f41a32536c1 ./inc/libs/clearbricks/dbschema/class.mysql.dbschema.php +0e6a54cbad7faa258e7cf3bafe95b9ca ./inc/libs/clearbricks/dbschema/class.sqlite.dbschema.php +52cb3d63686c4202f8a3e1c28b72eaf5 ./inc/libs/clearbricks/dbschema/class.dbstruct.php +19a7b770183e06433645ba6a572a6675 ./inc/libs/clearbricks/dbschema/class.mysqli.dbschema.php +3a5afc640ccd46b0eef5bce89fad58b3 ./inc/libs/clearbricks/dbschema/class.pgsql.dbschema.php +5d58ee070707b9344b74c4e95a6d8e2d ./inc/libs/clearbricks/template/class.template.php +dbe26992e25c706eb7ea798e26697401 ./inc/libs/clearbricks/_common.php +b23a438a4183cfd323342b591e88be5f ./inc/libs/clearbricks/url.handler/class.url.handler.php +e969237c3afdcbd0524bfb67ff186c2d ./inc/libs/clearbricks/debian/dirs +a165b0c48efd38c3c2725a282922c6f1 ./inc/libs/clearbricks/debian/docs +09741ea306c67f178df496044fd7d3bf ./inc/libs/clearbricks/debian/mkdcl.php +b0bd77efcf7f3ba705ca57fccd3479f7 ./inc/libs/clearbricks/debian/control +30ecf234a276835fe14c19f5a54dcbf8 ./inc/libs/clearbricks/debian/rules +771304f18d0aca7eb424be239480264e ./inc/libs/clearbricks/debian/changelog +48a24b70a0b376535542b996af517398 ./inc/libs/clearbricks/debian/compat +33c1cd6baec7ef84b905dd6fb463b871 ./inc/libs/clearbricks/debian/copyright +057af760bd008ca95cac177c5137f54d ./inc/libs/clearbricks/common/lib.form.php +b55f8d044a595684bab9423bf26cb76e ./inc/libs/clearbricks/common/lib.text.php +53f8e535da21c1f1ec0246a643d01993 ./inc/libs/clearbricks/common/tz.dat +1dcce11946a8134fe2c42680102714b2 ./inc/libs/clearbricks/common/lib.l10n.php +64979fdd95ee50b64ced5588b815cd4b ./inc/libs/clearbricks/common/lib.crypt.php +a4f3f32c32831d8585f64d160c75e144 ./inc/libs/clearbricks/common/_main.php +570ad3fc526ff54e2f76eaef8121af2d ./inc/libs/clearbricks/common/lib.date.php +a611602796b3ad3bf56dcbec23751f61 ./inc/libs/clearbricks/common/lib.html.php +bb0f2a13c46323c8aa763d4b65a849f5 ./inc/libs/clearbricks/common/lib.files.php +1e89873bfe887d73fb70a46cfea1bb66 ./inc/libs/clearbricks/common/lib.http.php +9bb79146a6ee39380f1060d0300a3702 ./inc/libs/clearbricks/net.http/class.net.http.php +084a7d997891a5a676128d571ce54e24 ./inc/libs/clearbricks/net.nntp/class.net.nntp.php +f590c41a10e8115ce381b3ae03ab8bea ./inc/libs/clearbricks/net.nntp/class.nntp.message.php +cd276c4686d956fea1fd9a56096726ba ./inc/libs/clearbricks/text.wiki2xhtml/class.wiki2xhtml.php +e75095764485b34dc522b6db59eae353 ./inc/libs/clearbricks/xmlsql/class.xmlsql.php +ca58e658d7976706bcb3bb885f229034 ./inc/libs/clearbricks/session.db/class.session.db.php +c3a41bf94dc11a1387a8f2d606111e64 ./inc/libs/clearbricks/mail.mime/class.mime.message.php +8bced09e0fb7e6fb368a62a7b2423bc3 ./inc/libs/clearbricks/mail.convert/class.mail.convert.php +d3b27e15bf5eafe2da90669e483ac645 ./inc/config.php.in +d8b13db427df79bf42abb6b11bf96c3d ./inc/admin/lib.pager.php +33e352171f3847b1545d0815e7865f53 ./inc/admin/prepend.php +f56f8e6149de6f8bef76d0b44a120826 ./inc/admin/class.dc.menu.php +e75011fa626fa363277471c4a16874e5 ./inc/admin/lib.dc.page.php +d067eb2122f08ecf9c70270a16d4c615 ./inc/dbschema/upgrade.php +9420fb50208df6b8ebf3c1430535f327 ./inc/dbschema/upgrade-cli.php +82bdc27069f8bcfe26f1d19d13098207 ./inc/dbschema/db-schema.php +209634bb0238704c4874c35d615ae59e ./inc/.htaccess +75290cb1920955fbde2e83ecdea3c7a6 ./inc/prepend.php +92f8d91038339aef6b6c2800aeffdd00 ./inc/load_plugin_file.php +f042e743a702f88bae04a0c9b4f232bc ./inc/public/lib.tpl.context.php +38032779b49d5297b2911e789e819e75 ./inc/public/prepend.php +c1a30a35f3bdc7282cd5b057a562d60c ./inc/public/lib.urlhandlers.php +2083a978f369df674fd9605344a078fb ./inc/public/rs.extension.php +9b72c7b38e24bcdb1a62b8caad592ef3 ./inc/public/class.dc.template.php +f406a856d0fef5ca16ab1fe5f6780d26 ./inc/public/default-templates/atom.xml +dc797422198ecf55648798926b333e34 ./inc/public/default-templates/404.html +cc388bc96e57726ed1e46a71de72822a ./inc/public/default-templates/rss2.xml +a7006baa75d1c133d57acbe1f559abce ./inc/public/default-templates/rss2.xsl +16bdc8783f0b0b181bca2922afa6707f ./inc/public/default-templates/_head.html +0ee80a5f6349fd4433f163e1ecd762aa ./inc/public/default-templates/category.html +94df989e651b3fab9ae5f889da8957a5 ./inc/public/default-templates/_top.html +252faf814965810e53ceaebca99110b8 ./inc/public/default-templates/rss2-comments.xml +7cbfaee006b71aa9e2ce9ff114bc30cf ./inc/public/default-templates/archive_month.html +4672a386be84c3b8aabe7f0f11eadd1f ./inc/public/default-templates/_footer.html +5e4dcd3dd0dfc2b5434ff4a47258c208 ./inc/public/default-templates/archive.html +5b02984ea641fdfafb3aeaa46d44094b ./inc/public/default-templates/_mp3_player.html +19a49738c54edd08f2551be928d263f1 ./inc/public/default-templates/atom-comments.xml +03a6321d766f1731d343db2aba6dce75 ./inc/public/default-templates/post.html +51c379d5e96b3cfff2410872ab2cdeb4 ./inc/public/default-templates/user_head.html +dbd6a409049296c74a829e3754628a01 ./inc/public/default-templates/password-form.html +89ea9bf9dc901c6f20861c915c410e33 ./inc/public/default-templates/search.html +ec603716f84156a51d557b1d4462ab05 ./inc/public/default-templates/home.html +0a7c11c048ad7c6d9acbb9a1e38c2120 ./inc/public/default-templates/_flv_player.html +d3edd069e027d9c3ad1d32595c66bf31 ./inc/core_error.php +751419260aa954499f7abaabaa882bbe ./LICENSE +2bfd05d14d13567c5d7b38b685e79bd7 ./admin/js/ie7/IE7.js +0da2f7d8d62695d582e1e8bfcb47a581 ./admin/js/ie7/IE8.js +45becbb1ba3486fa9961b9c47614d2a0 ./admin/js/ie7/blank.gif +3e8e99f729bba013ed74b23d442ce467 ./admin/js/ie7/ie7-recalc.js +1085be8f5d5a499858d18feee8d0ef8c ./admin/js/ie7/ie7-squish.js +379dffc9b9ed5ea513204c61057b77b3 ./admin/js/jsToolBar/jsToolBar.js +92c3d043218f868cf339b120dd6d51b7 ./admin/js/jsToolBar/popup_posts.js +fc39a873174acf0443ff17c8c577e929 ./admin/js/jsToolBar/popup_link.js +3446cbe53dada04cdf45882fb7952a77 ./admin/js/jsToolBar/popup_media.js +7e0a3f0bc1d42587db8637ce02838083 ./admin/js/jsToolBar/jsToolBar.dotclear.js +82d06b07d7e72577e99a8715eae90a0f ./admin/js/jsToolBar/jsToolBar.wysiwyg.js +592a3011c4e47a77856ad7df0d136bee ./admin/js/color-picker.js +9396d0f3e3ee1cefb5c2ada58f479a64 ./admin/js/_blog_pref.js +08451c09111e763c2354993025b07a66 ./admin/js/_comment.js +bb5fc73c7465d0e1e630560f39dbcc62 ./admin/js/_post.js +7f7f3ab2d5bcf53486a107df47cd5ba0 ./admin/js/common.js +db1cb95e3ef75253a1d1a31aeffe8daa ./admin/js/prelude.js +e3b5113a5cfed6a1d9dfa72834e5fb0d ./admin/js/_preferences.js +eab2d2bcceded304d2a923bc546869fc ./admin/js/_index.js +44c7923c51c9e8b5185d70078a1652cc ./admin/js/dragsort-tablerows.js +47acaf03194199a8b4421d1ef21532ec ./admin/js/_users.js +cf014d803ae8195a2473b48b1f2c92b6 ./admin/js/_langs.js +a4f58f2e708d54d966341654a1b9710f ./admin/js/filter-controls.js +c3de1b5c946d737887c495a081bc4fa3 ./admin/js/_media.js +d1c92505a8fd0fb4b2be1ccb944628e6 ./admin/js/_blog_theme.js +697881b2c6f4ba506df223db28db3a1c ./admin/js/_preferences-dragdrop.js +334a1345290da857abe41f3807c14967 ./admin/js/date-picker.js +81b61be64f338c2fd40da2bf47d2183e ./admin/js/_categories.js +49e972305f261af8830eac093dbed82f ./admin/js/confirm-close.js +dacda4414ed2d1db6b25ed16bdcc8ee9 ./admin/js/_media_item.js +10b1885ee8c7ad1c439bc3de868d4bb4 ./admin/js/_trackbacks.js +8f76e1f99874c7dd4705c1104625ca18 ./admin/js/jquery/jquery.pageTabs.js +b053c1e03164d2e6f92362ee298e5d0b ./admin/js/jquery/jquery.farbtastic.js +ce7a22089d470d15dc6a061bf7fe3d09 ./admin/js/jquery/jquery.bgFade.js +ca868f7e39985586a856b48b624c96d7 ./admin/js/jquery/jquery-ui-1.8.12.custom.min.js +33440de62785bd447fab76638ffe20cb ./admin/js/jquery/jquery.js +7f5f5bb62524a0ec4be1985031e7e141 ./admin/js/jquery/jquery.modal.js +93e11ef8585fbfa48f6dc595eb17a12c ./admin/js/jquery/jquery.biscuit.js +c9cd2dff00dac4624a45d36f42d9aa58 ./admin/js/jquery/jquery.candyUpload.js +aa314073e0ef73b815959563872f6c2e ./admin/js/_permissions.js +e6c6bad56b68af8402a30099a663ae65 ./admin/js/_posts_list.js +b46e51e327a0bb8f2711f230fc1467b0 ./admin/js/tool-man/dragsort.js +814404153ee1d350adf4bf7d1eae4cf8 ./admin/js/tool-man/core.js +6084f5f1fbcb14b085014ffa06961029 ./admin/js/tool-man/drag.js +02fba17f9a80f43ad07c55f2e092e7de ./admin/js/tool-man/coordinates.js +7d13dc9c59316624c051e6256c86bcb7 ./admin/js/tool-man/events.js +af77cd03cd87c611f1f495d6d29bab44 ./admin/js/tool-man/css.js +87aabde2f9d09bac13b8483e369cca38 ./admin/js/tool-man/cookies.js +3c34805dc9ff1c9863719c85dd804e5e ./admin/js/meta-editor.js +fd92ba025b34df5e3784ae9cca6c4f8d ./admin/js/_permissions_blog.js +eb8ddfafcf6aa8db9f55cd5f10dbe9aa ./admin/js/_comments.js +f0f861db8bed322c14508f592aeef119 ./admin/js/_plugins.js +29698c9e3ac842ca5c30abe9a69b338a ./admin/js/_category.js +d01327e2f55af880a2fb49813e48fb2e ./admin/blogs.php +ec14efc419c67fe3644ff904047b31c3 ./admin/posts_actions.php +fab2ceaf2ae5316dab402161aade8792 ./admin/blog_del.php +c9f5d46227866cadf6ebd3a05f550bd3 ./admin/update.php +ce12a0f1d02169e0e9f10a6ae88fcf82 ./admin/plugins.php +f418b7365dd285d4fca3e4c0435b4313 ./admin/popup_posts.php +a7699758a4d9927b23f8e2a62904e3cd ./admin/style/warning.png +d79076c50110cbdcc4cddf30f4df9873 ./admin/style/jsToolBar/jsToolBar.css +3e0f67a5296128dbe1857c1935f6da47 ./admin/style/jsToolBar/bt_link.png +64cdd7af332808399e65fa0538761c2d ./admin/style/jsToolBar/resize.png +6a388ba1cdeff25c79d540333b96ed27 ./admin/style/jsToolBar/bt_clean.png +a6ae01491523b9335334eea1b98c136f ./admin/style/jsToolBar/bt_img_select.png +828adda895735a8624fd819506078af7 ./admin/style/jsToolBar/bt_br.png +e5aae58c14ca63c366fe02acec03d928 ./admin/style/jsToolBar/bt_em.png +0c7181b5c37930f422fb9e6e7488c1d9 ./admin/style/jsToolBar/bt_img.png +ee7ee162173d1b91896415988e8cd006 ./admin/style/jsToolBar/bt_bquote.png +47c71f6ee3cf31296ff1f18348748754 ./admin/style/jsToolBar/bt_ins.png +e9f233c1c309337911b5b03fb9e1dbc4 ./admin/style/jsToolBar/bt_pre.png +22ad5189d9d94f9a24af5311ad06805b ./admin/style/jsToolBar/bt_paragraph.png +2ca06c1c3e80079ea378fe061e4cfdc3 ./admin/style/jsToolBar/bt_code.png +78d7a07a669055db5c3966edc31c94e4 ./admin/style/jsToolBar/bt_ol.png +a3a4c43798d387734737ed81a65eb7f9 ./admin/style/jsToolBar/bt_quote.png +94a2fd910832b31e18b4bb4e63f9aa79 ./admin/style/jsToolBar/bt_strong.png +e7e674fbd3612010f154475c449b3b79 ./admin/style/jsToolBar/bt_del.png +e43a1380a8ae14425ca9ce400dd336b7 ./admin/style/jsToolBar/bt_post.png +39f73a440303baed6920a769370091da ./admin/style/jsToolBar/bt_ul.png +5d2a95c6b6817027b7cc7413bf664991 ./admin/style/candyUpload/style.css +caa11e523e5a3ed38d90480bed5d5a73 ./admin/style/candyUpload/loader.png +0f4c059f8aceadfb2dd932e7a02ce22a ./admin/style/candyUpload/cancel.png +35a8ca87a425e1058f0f93d92a842e9a ./admin/style/msg-error.png +c85f133d357cdc134155416f5be2a5db ./admin/style/install.css +d8d0578b583b3879b3ee697fb4068648 ./admin/style/modal/modal.css +14a0936bd54fd18c22b5e7fb86ba26a3 ./admin/style/modal/loader.gif +4134330cedefac4a9075a7756ca496bd ./admin/style/modal/close.png +57d696efde30fe02acd30b46d87e930d ./admin/style/package.png +40be108b0a31181f7975eac193908b12 ./admin/style/default.css +2f7d618efdcae3859b36bbfa38fc75bf ./admin/style/page-bg.png +9c3e7b71f42e2d6c64b52fe7d46d5f16 ./admin/style/grid.png +45b045808b62976c5bfb7a701db2830b ./admin/style/dc_logo.png +003b8b1d1103cff11a707c5f80861a75 ./admin/style/default-rtl.css +5a7ae1d8c8b2343a9e5a4aebf4234392 ./admin/style/farbtastic/marker.png +2b6d304868ff398c17252b7b0a0414c4 ./admin/style/farbtastic/wheel.png +fbbd113ed6e6cf4adcab0f720b3b9b9c ./admin/style/farbtastic/farbtastic.css +c6dc921c0d6f2197793d9174b4267ca0 ./admin/style/farbtastic/mask.png +0716421681913b2cda5821b32b3360d4 ./admin/style/dotclear-logo2.png +57688345aa080a9a391efc40608ce98b ./admin/style/dotclear-logo.png +bed217c0f0423816fdfdae5f136a2aea ./admin/style/msg-std.png +b4459cd68df8a0ea2a5c12e6c655c71d ./admin/style/dc_logo_small.png +82244e6c9f6b8f3cefa0545468f40d65 ./admin/style/drag.png +a9d4db4f30e21559acf9fd825d72db27 ./admin/style/dc_bg.png +6fbf1d5cf4953ace09e5041a53d477ec ./admin/style/head-bg.png +e179e6f8a290c99a5ee77fca9c204863 ./admin/style/add.png +5625c7bc5997742b45925105fd9a4303 ./admin/style/magnifier.png +b8abd059ee85b073a27d38bba8998786 ./admin/style/iesucks.css +daa77b9f2795fce1510dd2d6b82e722a ./admin/style/info.png +37e482ed14e13a1a8a141deb0eea81f2 ./admin/style/date-picker.css +cc08cffba493e1114cc6709a7aadd2e5 ./admin/style/install/note.png +1141b61e9cea3d25ffebed4d4a2d6676 ./admin/style/install/process_warning.png +dff65577ffa614149552e2bd25800f76 ./admin/style/install/important.png +0716421681913b2cda5821b32b3360d4 ./admin/style/install/w-logo.png +5b036194b0772a23e73c88538c43737c ./admin/xmlrpc.php +cdede2ce1df3ba2299f00aeb2604a7cb ./admin/auth.php +666eb56b637e82e178a8a6bdfc2886b3 ./admin/post.php +b8d6dda0d3db7b147fe589151a1a4526 ./admin/permissions.php +860965f34e820c1ca4640b5ef9f92cae ./admin/blog.php +27619cd17f652e7d806586b6ccbbd3e2 ./admin/plugin.php +92f95f82fe97b88ccd42bd330c6844d1 ./admin/media.php +d43b3bbaf093f0e17f05269ee1d594e4 ./admin/media_item.php +f0adbe078cc42ac3ec356b1fa2cd67cd ./admin/images/plus.png +26500215140d1b0c0b947138316f00de ./admin/images/menu/blogs-b.png +3fc65469ad83784c3e11a0b0f5610fe1 ./admin/images/menu/edit.png +7b4259eae3ef9ce3c8e73cda28cdb848 ./admin/images/menu/blogs.png +ac90182e4a2ddbfec7308fd8e0e9f97f ./admin/images/menu/dashboard.png +098c84b3f910856868c291551092cdab ./admin/images/menu/favorite-b.png +6848117e186492db3baf129b00bda76a ./admin/images/menu/categories-b.png +7562fc3201a20137ca93b41a17ada1ab ./admin/images/menu/langs-b.png +accef94acd8231f145c05ad518f31953 ./admin/images/menu/update.png +76943b18b4e6486a549554a658e611c9 ./admin/images/menu/plugins.png +6c4b15fe4dec48c1f28e33706de6dae9 ./admin/images/menu/blog-theme-b.png +8aaa4c8fe97ac9c53b5e886a3bbfb971 ./admin/images/menu/favorite.png +b51b37a5d3ff0c0cb35414dea1b439b2 ./admin/images/menu/blog-pref.png +dc8df030063d8e45ad34b001274abf5b ./admin/images/menu/themes.png +a77a1960486bface242d029c7aa087d8 ./admin/images/menu/add_to_favorites.png +78a765be907724d7401647d808ca50bd ./admin/images/menu/search-b.png +304e702c190e373ab168f3e02a39bafb ./admin/images/menu/plugins-b.png +42af2e3a92f15d62697fb53fef595002 ./admin/images/menu/media.png +e724854eebb8a8050ab2948d374c8794 ./admin/images/menu/user-pref.png +223a95d65cf6eb77b3864eab41b0c205 ./admin/images/menu/entries.png +11dfd2df494996acaadd5144ef1b5f82 ./admin/images/menu/comments.png +3cdb945ceec71cece4535938d7e7b4da ./admin/images/menu/users-b.png +b88d849500404c5e1dd5e84d2cbfbdd7 ./admin/images/menu/media-b.png +6b05a6e5e8d6a802b596941de43d16b7 ./admin/images/menu/search.png +feab8bf7358c357f4cd537820fe62490 ./admin/images/menu/user-pref-b.png +1cf0eda014601a2de0ca6e2d65ce2e84 ./admin/images/menu/blog-pref-b.png +d5dcc36f898a1d7e114ee86c9706d32e ./admin/images/menu/entries-b.png +81b7b4adc7aa2f0369cf9fc17410b13d ./admin/images/menu/users.png +d7f03e538273c00dd945234ced5bc3e6 ./admin/images/menu/edit-b.png +1b080e9e7b5ddedd790423b661403a41 ./admin/images/menu/comments-b.png +b26e639aefd49983c1e519077f4982a7 ./admin/images/menu/categories.png +194eed635664d675736700fd51fb282d ./admin/images/menu/langs.png +86583b1fd690088cd78f91983aaf8575 ./admin/images/dotclear_pw.png +f8e8e34c81702d8cce1de96d628fcae3 ./admin/images/favicon.png +9f5f27a72f4c95790de10fb8acf75b37 ./admin/images/superadmin.png +50bf28433834e6d2f6f46d1b84421d2b ./admin/images/media/video.png +8e35fccfaa42070297cef723428183ba ./admin/images/media/blank.png +7e619d7762995a3c3ef9edfb3b6b4c92 ./admin/images/media/spreadsheet.png +c2b2d27914d57241d3d0e96a66ede1ca ./admin/images/media/package.png +487708f4b8f6fa0ecff78f26ded3806a ./admin/images/media/html.png +90864902424cf16cd85d2a6e54fe0272 ./admin/images/media/document.png +be57e76497791a2540d91f9149f38a6b ./admin/images/media/audio.png +6884619665a6a6a91996236dd26ad2fc ./admin/images/media/text.png +27013d32dfc30e5512ff184c2869bb3f ./admin/images/media/image.png +34f401c85ee26edfffb2c317ae2b1b54 ./admin/images/media/presentation.png +c6db076f177ccaf062d017c5db228085 ./admin/images/media/folder.png +4d8611170bd9173aa87cfbd4878ac588 ./admin/images/media/executable.png +61334007afc261a93d677bd3460ee36d ./admin/images/trash.png +21d31ef6dad45bbdd32bbe358169952b ./admin/images/selected.png +e7c196b87a5e022549b71e6f4e811d18 ./admin/images/menu_on.png +a2e73061f728066f2305c6aa5698687e ./admin/images/outgoing-blue.png +c3380a4422bb8a7e8756a6a167ddea22 ./admin/images/check-off.png +87e4a16e12e1e0761687d0cfdd7baacc ./admin/images/admin.png +355fbab6dc8dc6c779ba687bcc187fd7 ./admin/images/scheduled.png +913ff19cacf4d03fc835b4255c236c79 ./admin/images/picker.png +3ee61de988743c744af9b9224d35284b ./admin/images/minus.png +b742e51edacbf99451e12c5bb01531b0 ./admin/images/junk.png +f86e9d6679d8b27334bbb8df82b1c7d9 ./admin/images/menu_off.png +9b1093546f036f5e51069ffbef0ea7b8 ./admin/images/add.png +45c5ccf8249c5ec4800b9e0c3d34b7ca ./admin/images/check-wrn.png +02437c955382fa358b357632557a6f4e ./admin/images/attach.png +dfab5698cd3abbb30538331690413d30 ./admin/images/locker.png +c40960ead0cf335209336463cb1b37be ./admin/images/check-on.png +2b544dcc4b961ad990d0c27cce909585 ./admin/images/outgoing.png +07181f8c47f322410aea182338b031b3 ./admin/images/date-picker.png +fc080751a6ae822596cbdb54c97c4fd6 ./admin/images/edit-mini.png +93d023c510f85f951839c251814291ab ./admin/images/noscreenshot.png +1eaa6675e93550119cfee871b3fc5746 ./admin/images/logout.png +8776864d4c4505e2cc4040a418497bc9 ./admin/images/help.png +5df7e9507b256844f028f01d0716b203 ./admin/index.php +c41d2db8c410a3dfddda37a52ab14bc4 ./admin/permissions_blog.php +87c7183813aacc1661e19ec8ec601ec1 ./admin/posts.php +4ca3e3050137b781b379803b6ff8690d ./admin/comments.php +da4e5249ad11ec5f17019dc152bc8180 ./admin/popup_link.php +220ab6d14dffd7be6b77867669641327 ./admin/services.php +7e02c709544983f9a44a36d4bc853240 ./admin/search.php +80bb7019bb3ed2127bdff6545412ddbe ./admin/blog_theme.php +9b8715ae3022f2f771587bae2f7e5134 ./admin/comments_actions.php +d70e027e2672a6e22d2d84b3aabbdf63 ./admin/comment.php +12cc226c90afdea93ad0cd2057672c96 ./admin/user.php +711578a896d6ef538da5825511caa738 ./admin/dispatcher.php +04030cedae46cd04dfd74498c567bf3e ./admin/preferences.php +064eae06875333c399a798494f8e2e71 ./admin/users.php +7ec8ad91b731edcd5b5bec16f1e900b1 ./admin/install/index.php +60975a951783e28e7c4c86402a05f385 ./admin/install/check.php +64df84db3fb2189eef4b1852f58e6e17 ./admin/install/wizard.php +ed72c46169a159eff4e450c186f7bb40 ./admin/category.php +c67c2b5a1c0ad19020cc7a50c83284f7 ./admin/post_media.php +87e3874b7d8105f426d6ef7462f5f027 ./admin/blog_pref.php +39aa7e09b45b8333a8d5d8a3e3a79c22 ./admin/categories.php +ddfc2edef1e53ebc956f0d3dfd656b87 ./admin/trackbacks.php +6b9e293e1beb9a8e706c83822c9f381e ./admin/langs.php +af0e07462505de19ad85e6cd53906846 ./README +312530ddb6b46618848b0e34ebc0422c ./locales/en/date.po +fc51ec4fe28cadc83913b369fc77d65a ./locales/en/help/comments.html +018f76172ae892ae4810db02314b86fa ./locales/en/help/blog_pref.html +c25adc9f42a14527b538cb58554b1ad8 ./locales/en/help/media.html +5c9c46fede94f83bef0828264f18f596 ./locales/en/help/post.html +efc9a224297e6902a5f0efa196bc7c6f ./locales/en/help/wiki.html +a2c6ee6914d93c0f551ced12e55970f7 ./locales/en/help/categories.html +684790773f1f459104e1daf3e50fc94c ./locales/en/help/user_pref.html +649bda3d42114c8dfea967f005d304a1 ./locales/en/help/user.html +09352986157f34af6730061ce06bd8cd ./locales/en/help/posts.html +4c12ea0a98c5cd138d084ca0c91117f6 ./locales/en/public.lang.php +5a3e3ece8c26cfab6fb0a087f5a9d73a ./locales/en/date.lang.php +ccadbcf1eb0c0618b7176476b2869f5a ./locales/en/main.po +2fa421ee2b30c8d8d68682f09237a76c ./locales/en/plugins.po +ec25ff7f135839cd1cf3b1773a7b07bf ./locales/en/plugins.lang.php +166d2195addbd38c01c70151246b581c ./locales/en/resources.php +00991b192802456807b67cc5445abb82 ./locales/en/public.po +4c12ea0a98c5cd138d084ca0c91117f6 ./locales/en/main.lang.php +0b6a3799a53022c6140bec6b7fc5b2f7 ./locales/fr/date.po +0474ebce1d0524825e938908d4afa44f ./locales/fr/help/core_media.html +fdad4d76a79dabef426adbda07ad510a ./locales/fr/help/core_user_pref.html +a9f897d204180419de34dcfdc9b18f76 ./locales/fr/help/themeEditor.html +2bc53951d2998ab67979a5b1ea4f3df9 ./locales/fr/help/core_comments.html +996bbf4b20290530884d25844b1ee32d ./locales/fr/help/blowupConfig.html +ad33f702e9d1872395ac85dc8a9ff875 ./locales/fr/help/core_categories.html +6bc717490f197e5e7216b1853bf88b7d ./locales/fr/help/core_post.html +e38f790349f0accca7c63a7f76671c0c ./locales/fr/help/core_posts.html +590e7cdb6a0010defabfae0c5e1554c2 ./locales/fr/help/core_wiki.html +2150b2a08a45668b253ff05c9f74affe ./locales/fr/help/core_user.html +a02aaf58ce0bb12e3b88b828090cd9db ./locales/fr/help/core_blog_pref.html +632b94ebd8e9fa690469adea0b78cf65 ./locales/fr/public.lang.php +59b6966fb7e7945212d0daf6128628dc ./locales/fr/date.lang.php +01ba7f80a86519153e8f7c536ce8a9ee ./locales/fr/main.po +dbba5039396a650c96ee9e73e38f452f ./locales/fr/plugins.po +b85f6046043eecd1402d8201a9ccd2b7 ./locales/fr/plugins.lang.php +bfc28002a0ceb0ce48ca56781875de23 ./locales/fr/resources.php +878cd7e4ad4ec67cc8fd02072d6b1b84 ./locales/fr/public.po +38db3db98dbbe4ce8bedcbf459bb4070 ./locales/fr/main.lang.php +d4ff299dabd4b8334cc7259d0eb65b6e ./locales/README +daec700273b033301fd6c71dc29a19d7 ./index.php +33440de62785bd447fab76638ffe20cb ./themes/default/js/jquery.js +0399de1c63edf55deb1cffa811905d57 ./themes/default/js/jquery.cookie.js +b766b02a8f0e877f56c232dcd9ba736a ./themes/default/js/post.js +a802d1f382c8b22d1e6c6e28ae618498 ./themes/default/img/trackback.png +74eb29efade1edeff692446b5e6f8258 ./themes/default/img/commentmy-b.png +ef130b60877aad5a4cc8d4c5ead17317 ./themes/default/img/commentmy-t.png +f3b1ebaf5a27959228b736f87db11776 ./themes/default/img/page-bg.png +e199613e6ec2cead05b92a6f2c76e2ec ./themes/default/img/comment-b.png +90835fdf81ee294b89674795ee6ed71f ./themes/default/img/tag.png +3f7ae2737f49605199554ccac96dc748 ./themes/default/img/comment-t.png +c85f9d3ea9319236e67db78be1707478 ./themes/default/img/page-b.png +42fa213bf2a5b110afeb7552767700c6 ./themes/default/img/page-t.png +68f80507e1d6123f57c5f25f006a699f ./themes/default/img/feed.png +e4d37aac2d638c4a358a7fd4c76b2789 ./themes/default/img/attach.png +19741777bd991f387b6d01d187f9cacc ./themes/default/img/comment.png +dff6f47c5dcfce7c1a909f015f43a91b ./themes/default/img/body-bg.png +432d016389df9619e39213301f8b58d3 ./themes/default/_define.php +bb7dfb0da518903b3307a28f6c6d3a33 ./themes/default/style.css +acdc336f9249b84310c6bc541d6e66ed ./themes/default/smilies/laugh.png +e8cfd3101dc2a0cdb7a343e1b873a38f ./themes/default/smilies/cry.png +062fe26eb6105ce6bbc0d133b50c4fcc ./themes/default/smilies/confused.png +c8372d57625893f1c06a409cf1fb84d5 ./themes/default/smilies/sad.png +c1fa8d897b82f938e2abada9bfa7c2c1 ./themes/default/smilies/redface.png +f97fc26a57559afec46806aa42083d9c ./themes/default/smilies/eek.png +919a6951304ce994203f86edd3f5d359 ./themes/default/smilies/dizzy.png +5933cf36a8be5147933b6499d589eb01 ./themes/default/smilies/idea.png +d2855d2d68f6467db69219534638f4bb ./themes/default/smilies/exclam.png +93d6fed1604e9e479f65940e52884ac3 ./themes/default/smilies/lol.png +0d16e0502c576f32662ad14dfde3cf53 ./themes/default/smilies/rolleyes.png +18f5ac3609425f10e910e64d5620edda ./themes/default/smilies/cool.png +1808a6c8affe37c094a038dc983b0ffc ./themes/default/smilies/mrgreen.png +d3671aa8ccb54bbc9b89a83ba202b626 ./themes/default/smilies/smilies.txt +51b2f454563975cc4b2fcc07d31ce12d ./themes/default/smilies/alien.png +5b36ab1e0f2c2dde883a6e32cc3feebf ./themes/default/smilies/smile.png +a1650e5c1ff8e9f40ef90828011f91fa ./themes/default/smilies/normal.png +efe8138e2d0b366a9dcdbe1c6ab75eee ./themes/default/smilies/evil.png +987742e347ef66bbc2b6b9546a0aa360 ./themes/default/smilies/angry.png +83362893d53db01b5595a7e8021fcdac ./themes/default/smilies/wink.png +57a457e1818d6e9419ced9366d2e33dc ./themes/default/smilies/razz.png +9ae025a44deba07f3e3fe2c3992e5d9c ./themes/default/smilies/arrow.png +25adf8de879b3e83c12ab668bc3c983f ./themes/default/smilies/question.png +32f2a33008491d7c070d70cfc64585c0 ./themes/default/smilies/surprised.png +c75e685b085a7e188b42f995626ec3be ./themes/default/screenshot.jpg +9a32c297dc3b0deb2d6dd753003a34fa ./themes/default/print.css +45d00287e10a0f80755df82486fe5d9c ./themes/ductile/img/menu.png +a0015087cd48c18743ec0abe82093fe3 ./themes/ductile/img/sticker-contact.png +1b0f8f994562ca42560fcd2ada72c409 ./themes/ductile/img/filet.png +94d5758aa91ec3378e0cd48de4f3d479 ./themes/ductile/img/last-hline.png +6490586470558c14c3bbeb50b7aba76e ./themes/ductile/img/post-info.png +d5979fa0d9b2f8be5e1426d10ab324b0 ./themes/ductile/img/sticker-about.png +a9ba633e8a0c38c7799fddb21386bf1b ./themes/ductile/img/squares.png +f5a4ca7d53980b9f3599f44f1ee056dc ./themes/ductile/img/404.png +3addb79a8269aa09f6a481faed784cb3 ./themes/ductile/img/minus-plus.png +6b66cc73ab482165f05fa3681c3117fd ./themes/ductile/img/hline.png +f6d76b2ec5d0cc2f1fa0d7959e654659 ./themes/ductile/img/feed.png +2558233ed307b504ee5cec813ed37c9f ./themes/ductile/img/vline.png +54e2985a49ef5d1eafd019c7890d6c75 ./themes/ductile/img/sticker-feed.png +208f72649c79433f373bc2f345e31b1e ./themes/ductile/img/logo.png +9ea7bc2b06c8b9835fca914e45c3e9fd ./themes/ductile/img/menumobile.png +3830f6d401c112da3fec2d49598c110a ./themes/ductile/img/info-co.png +ee625571fee87ee28771814a7d990533 ./themes/ductile/img/download.png +d3a5600600c51388faca5764d78bb255 ./themes/ductile/tpl/_sidebar.html +5972bce8e97464802c9337e3f711a497 ./themes/ductile/tpl/404.html +5eca089dfae96ac2fbec83e0b8fecca8 ./themes/ductile/tpl/_head.html +82cac60aaee669c22cd12c2ea906120a ./themes/ductile/tpl/category.html +f0c5851b4f7864c4e867fc68422c1e7b ./themes/ductile/tpl/_top.html +646d08df01866f93c3f96e181f44f67d ./themes/ductile/tpl/page.html +04042fb7780b53434df1f3e08c188d0d ./themes/ductile/tpl/archive_month.html +acb7ffa595929e97cddd77c4e879122c ./themes/ductile/tpl/_footer.html +a1983537ec443b2820e3bcda28a2cdb6 ./themes/ductile/tpl/archive.html +34be6f864b5a87efca2c4629752ea8f5 ./themes/ductile/tpl/tag.html +f09ccea554a96b569cfd05c07b33dd4a ./themes/ductile/tpl/post.html +f4f70c7f5a9ebd5ba3deccfa85991248 ./themes/ductile/tpl/_entry-title.html +1b66d32c893660bee28650240a2a58b5 ./themes/ductile/tpl/_pagination.html +32da3358202c8a7f561e4de2c40602b9 ./themes/ductile/tpl/tags.html +1363f40218fbf611757fb0a77bf8b368 ./themes/ductile/tpl/_entry-short.html +423ed7b8edc6f7585fed258c27d8a189 ./themes/ductile/tpl/_entry-full.html +281cd5fecf15b910197cff4ce8c59c8c ./themes/ductile/tpl/search.html +a43fbe8596a6a7cea756a568e8b08418 ./themes/ductile/tpl/home.html +26bbe6713e4d3107acaf728d385f7846 ./themes/ductile/tpl/_simple-entry.html +1b496f7d9654a14a2c8fbf1048691ca5 ./themes/ductile/_define.php +f422cb4f4f3e78e9759c0f7df7e3aefe ./themes/ductile/style.css +32fb1656e65748b87fd80961720288e2 ./themes/ductile/_public.php +917671c8a29b46c280ecadc16b0c3aac ./themes/ductile/locales/en/help/help.html +464d1bec47c94bd1318a1d0b7591d69d ./themes/ductile/locales/en/main.po +f4ea1518ffbaab35d4c0a811a7a6f0e5 ./themes/ductile/locales/en/resources.php +05862e7f740b0d2693235af02dba8ae7 ./themes/ductile/locales/en/main.lang.php +60cd3466769a335e11f4ea6b6db00b32 ./themes/ductile/locales/es/main.po +85515ddcb067b706b5f96de3bd93fc7a ./themes/ductile/locales/es/main.lang.php +044617aacddd312e982a46868d5cd0c4 ./themes/ductile/locales/fr/help/help.html +21c5b93e0056a529b23a2a8100b6f131 ./themes/ductile/locales/fr/main.po +f4ea1518ffbaab35d4c0a811a7a6f0e5 ./themes/ductile/locales/fr/resources.php +a0eb02cf98df99cc5b72f1f9b85d03e4 ./themes/ductile/locales/fr/admin.lang.php +64ccfba3a4cc05b19bee205508d29de3 ./themes/ductile/locales/fr/admin.po +b0504f396485c4cdcc469bf7aa6ac72f ./themes/ductile/locales/fr/main.lang.php +b068880d9ebca0eb8ee939edf7a61fdb ./themes/ductile/_prepend.php +41268b2c9f4e7a588033689d7ff9f89c ./themes/ductile/screenshot.jpg +ac71d8654c2c0f52d9f23e5b6c70450d ./themes/ductile/ie.css +c3caa3fdd24ac661593757f9b454f291 ./themes/ductile/ductile.js +757317303623fbac21adbc8747f7b63e ./themes/ductile/_config.php +342e032b31de25bdb8d855712dfceddb ./themes/ductile/rebase.css +f1d67702b54ededa0c493fef0c7dc7f1 ./themes/ductile/mediaqueries.css +28e5e068b8b973e3d1997ba7c24205f2 ./themes/blueSilence/img/background.png +8ebf5666d9d8bac9fdeedbd17daaa348 ./themes/blueSilence/img/report.png +a58dc745b52f9bb33a44fb9ccd5a776d ./themes/blueSilence/img/rss.png +a56d97cb87cfd1970760fff3345af5d8 ./themes/blueSilence/img/tag.png +f7a34b6d7c3641b7afa0132a9723ece3 ./themes/blueSilence/img/top.jpg +f9e699b16c85dd103e725d70efdacd2f ./themes/blueSilence/img/li.png +ab2a5e87e0c395d12a221485be1ff821 ./themes/blueSilence/img/commentaire.png +4c8c6a8fe121912b6cf6a8edaa920aec ./themes/blueSilence/img/tags.png +e8bb6589fe0e7bc810acc4c350f2a54d ./themes/blueSilence/img/commentaire_bulle.png +851317b61d8b6b08d6bb58c06896df21 ./themes/blueSilence/img/attach.png +c1dda264fa5d4120717ba558f01fe652 ./themes/blueSilence/img/footer.png +986f44c4d95f0b4d30defec242f0f76d ./themes/blueSilence/img/retrolien.png +e40bfe45e815e751015bf122e16fb1f2 ./themes/blueSilence/img/sidebar_li.png +3cb85a1d74bceda7858cf0ba4431ada0 ./themes/blueSilence/_define.php +4c99f9d0bd6843a5484740269dd72770 ./themes/blueSilence/style.css +6c0c644258713357329a5bcac1f44768 ./themes/blueSilence/screenshot.jpg +449494368191ae4e7ab977c2a76ab009 ./themes/customCSS/_define.php +d41d8cd98f00b204e9800998ecf8427e ./themes/customCSS/style.css +1d1df50722b311cd831e82a6c49cef11 ./themes/customCSS/_public.php +440252bd94cc1bba46e7b660695d4bd4 ./themes/customCSS/locales/fr/main.po +59bc320d1152143f1519da7733d092ff ./themes/customCSS/locales/fr/main.lang.php +148208db11c31b1be2fa3ea96c5fe63e ./themes/customCSS/_config.php +7d3667a8583b161e345c97abf93b7d13 ./plugins/tags/js/posts_actions.js +8973e836ae4ccefef97120342b2e877c ./plugins/tags/js/jquery.autocomplete.js +8bf49851e4d1322827a052b061d0cc6a ./plugins/tags/js/post.js +deb5c791e787615f52941227f045b37e ./plugins/tags/img/loader.gif +ea424458edbdb1f6c4c01d4486019252 ./plugins/tags/img/tag-add.png +02310f9b96fbe3d9005db4c32c0edfde ./plugins/tags/_define.php +0ab37bb8c62958dadba1c01ce4daa0ae ./plugins/tags/style.css +efb60d58acef17a9f8f2f29b42b9641a ./plugins/tags/_widgets.php +769eb2e4000b8b871ef6a764e356e438 ./plugins/tags/_public.php +87d59c76efc5f658c8bdb77ad1683583 ./plugins/tags/icon.png +543aad10a48eca31afd4e8cd28b2b21e ./plugins/tags/_prepend.php +0984fac02a7059c3da6575a7f04f67bf ./plugins/tags/_admin.php +e1e298db61c4ec7e99161c9788111b4c ./plugins/tags/index.php +84845fa3256c8c15bf3a4ff613cc823b ./plugins/tags/_xmlrpc.php +c365a799f0c5c04facd507116ec18bce ./plugins/tags/tags.php +87ffbdb75c871db5411264cb4aa8c1fb ./plugins/tags/tag_posts.php +88af742960b518262cc6e6d662a408d3 ./plugins/tags/icon-big.png +b078a69a4fc6e58a804df40d6f9402ec ./plugins/tags/default-templates/tag.html +e238ea5276b7333593026d68b02f1ce5 ./plugins/tags/default-templates/tags.html +440acb22b11ba828e45fd27c60810adc ./plugins/maintenance/_define.php +2c604b5d65cc096c1f37906d596a2231 ./plugins/maintenance/icon.png +eaffdb154740265f9dae351b891e2d27 ./plugins/maintenance/locales/en/help/maintenance.html +61add6e9746aded7aab53aee9f91a147 ./plugins/maintenance/locales/en/resources.php +f8ed1b11e9fd0843d7ea40e010f3ae83 ./plugins/maintenance/locales/fr/help/maintenance.html +61add6e9746aded7aab53aee9f91a147 ./plugins/maintenance/locales/fr/resources.php +a60ed9fce76695b5d507e815555a8620 ./plugins/maintenance/_admin.php +5f391589b20df151de1e353e5d3f8253 ./plugins/maintenance/index.php +0bb6cc2229f017adedbc67642496a623 ./plugins/maintenance/icon-big.png +53fcb389435570d224759e1e87723154 ./plugins/pages/list.php +c20960611d6099a96accf85bbe5f7f67 ./plugins/pages/_define.php +dddced2207edb25a187bceb5f855bfa5 ./plugins/pages/page.php +c8744d50e0bf36cdc4613929be5f4f7a ./plugins/pages/_widgets.php +23cb01b0f5290900f359d81e0211b74d ./plugins/pages/_public.php +b1bc318e924e34522709312a12dcc5c2 ./plugins/pages/icon.png +1be0fb2eebf54bfad343c52177a80632 ./plugins/pages/locales/en/help/page.html +12a1a6fee37d25d40c03f9d7234a351c ./plugins/pages/locales/en/help/pages.html +3dce4e7363737b9d0a9b1cb80473a000 ./plugins/pages/locales/en/resources.php +cb15c560f1ce3ca28b218015de39c86e ./plugins/pages/locales/fr/help/page.html +14b6f95e1d372f013a59f022c59c28fc ./plugins/pages/locales/fr/help/pages.html +3dce4e7363737b9d0a9b1cb80473a000 ./plugins/pages/locales/fr/resources.php +bc20a848078bc49837802aa98cbdafa2 ./plugins/pages/_prepend.php +c85dc3b8e26a69a525c8d1af05b321a0 ./plugins/pages/_admin.php +e4d87532945c6948024c19d042e2b886 ./plugins/pages/index.php +d27a7d60e6ba80c4707dcffd3c2dbd5e ./plugins/pages/icon-np-big.png +31089648f09c9203bb9a9f08fa0f8d5c ./plugins/pages/icon-np.png +c14f9c44eb9edbc48e953cb1a21fb972 ./plugins/pages/icon-big.png +075d988db38c1cdfce6a1983067b57f9 ./plugins/pages/default-templates/page.html +51614d28203d0d30b54522c73020931b ./plugins/pings/lib.pings.php +b185af2e3eb0ce2a0bdb5cc86ee498c9 ./plugins/pings/_define.php +9752e15a58ed8ef93751e4db2826e4ac ./plugins/pings/icon.png +ac4b9c80e9f15d9b9f5219dfa44c1849 ./plugins/pings/_admin.php +ddbb5e077b8683fe7b5617c17c9d4520 ./plugins/pings/index.php +69ea448ef9b88ebfb3d055365de751e5 ./plugins/pings/icon-big.png +e074e70b8acc82f6b8353ae2dc240d7b ./plugins/pings/post.js +ce7e454ba349cf30c2180f82df6a0579 ./plugins/attachments/_define.php +0009b6fab4d355467d4752500c895689 ./plugins/attachments/_public.php +df2984cdf2e725a1190d4c4d1a22cd5c ./plugins/attachments/_admin.php +b0943867447d5997118b7bfc34768ce6 ./plugins/antispam/inc/class.dc.spamfilters.php +638c21bdabf86e609981ab1e511de0a5 ./plugins/antispam/inc/lib.dc.antispam.php +345e04b476c4b364769678147705bfd2 ./plugins/antispam/inc/class.dc.spamfilter.php +63d9349114f535ab0731d45302db1fa7 ./plugins/antispam/inc/lib.dc.antispam.url.php +77a77bd9ce6f79c562ecafb0f5dfff04 ./plugins/antispam/_define.php +6678a3fc8c6bcc54e7f2910e4aaeba21 ./plugins/antispam/_install.php +c28748b62667080cf3a0fbf5dd98f7b2 ./plugins/antispam/style.css +6fc18cd4a4dfa2928807c405a8b585fb ./plugins/antispam/_public.php +a48997d0567984d464981b4cde3ff125 ./plugins/antispam/icon.png +39a774a74f940ac72192d6c496a44478 ./plugins/antispam/_prepend.php +1e2deb4234391c489de45137d3e306d2 ./plugins/antispam/filters/class.dc.filter.linkslookup.php +cf86365f13c9e82063ef70f91d1b8963 ./plugins/antispam/filters/class.dc.filter.words.php +26fb77ae2996f1df9d884773aaae7f7a ./plugins/antispam/filters/class.dc.filter.ip.php +ebff2023b0e53322f6c908729df29015 ./plugins/antispam/filters/class.dc.filter.iplookup.php +b2626bad20ac045e3dcf448d9c7b32e0 ./plugins/antispam/_admin.php +316d16dea4cf1fe94cf6a8a7f149b8ec ./plugins/antispam/index.php +b82da4aa0a7b272ae5e2de8dd7359b3a ./plugins/antispam/feed.png +56dd843cb7ae5c0e71ea479c96136352 ./plugins/antispam/antispam.js +83716ca10d30c3fb0cd1c25c75518a72 ./plugins/antispam/icon-big.png +63f54624efa0c327dcc4e6a0f45e5a7b ./plugins/themeEditor/_define.php +df6d24d467b24cf0914f388864ff3000 ./plugins/themeEditor/style.css +597ea9521d22937dbce30b392c6b3d46 ./plugins/themeEditor/_admin.php +c4762effea48c7e75e20ee5936af0484 ./plugins/themeEditor/index.php +70e24bb343ebeb5c4bc427532d5866e0 ./plugins/themeEditor/class.themeEditor.php +740e05113c1d5f825eba114554e096d4 ./plugins/themeEditor/help.html +f75e3f88c0dea27c23c1b02486cf485d ./plugins/themeEditor/script.js +209634bb0238704c4874c35d615ae59e ./plugins/.htaccess +176f0818cbfc87abfd63ea4533dfa9ec ./plugins/blogroll/icon-small.png +ff5ac25482026b10a85a24dc5c95224a ./plugins/blogroll/edit.php +66eac420aa0fb1a5dd92f5f98fba453c ./plugins/blogroll/_define.php +cd90c7acf3cb672aba63312930055195 ./plugins/blogroll/class.dc.importblogroll.php +a7baf0626982efff0d58e3fda94d6aa5 ./plugins/blogroll/_install.php +4390f663a991dc993ba648786bba97f3 ./plugins/blogroll/_widgets.php +e075e330663bb96f131b7c294ba8c430 ./plugins/blogroll/_public.php +a8ff27e2e7e0e204fb06c6154c09a89d ./plugins/blogroll/icon.png +eff29112ce348cff22324fa93fccee39 ./plugins/blogroll/locales/en/help/blogroll.html +febf3b64152a0aefb523a8822998c02c ./plugins/blogroll/locales/en/resources.php +6bfc5a8bf8a197307a289f294d2b34f4 ./plugins/blogroll/locales/fr/help/blogroll.html +febf3b64152a0aefb523a8822998c02c ./plugins/blogroll/locales/fr/resources.php +f655145e14734c5eef2e40489227bc66 ./plugins/blogroll/_prepend.php +fc5215f1cfd1a630bc64516c243159c7 ./plugins/blogroll/_admin.php +a8199396024d0d87716b3e2c39290a19 ./plugins/blogroll/class.dc.blogroll.php +b5bb164e1e73648a5ebfbe91985953cf ./plugins/blogroll/index.php +a7a6b9941ea78fd2055e025f0e1a3abc ./plugins/akismet/_define.php +e77a818a2a09aaf0a7eed4d18b0d8236 ./plugins/akismet/_prepend.php +230313fe9f4089ff7f2ebb3a696be3b2 ./plugins/akismet/class.dc.filter.akismet.php +269e3aa0b8dadeee41f7c68ade7f12de ./plugins/aboutConfig/_define.php +4d78af1bbd7743a86da47683067b1eb7 ./plugins/aboutConfig/icon.png +7c9e3b0ef93fb178c44b0d22fe20e38b ./plugins/aboutConfig/_admin.php +9a9b2b40603945feafea068863a611ab ./plugins/aboutConfig/index.php +16eb7f5b6739a98fdd46606e87ceccb6 ./plugins/aboutConfig/icon-big.png +490168b1d58949a991352f3c8db587fb ./plugins/userPref/_define.php +309e06f46959a3a86b007218e5038e23 ./plugins/userPref/icon.png +c01675d280ae574977f25a082397ecbc ./plugins/userPref/_admin.php +dbec6e054ff4db968ec074772a473bd0 ./plugins/userPref/index.php +feab8bf7358c357f4cd537820fe62490 ./plugins/userPref/icon-big.png +f98d952cb1b5431498700fb3592f739d ./plugins/widgets/_define.php +d077c7c36df3ade673424af06c0b1133 ./plugins/widgets/_install.php +1c204b2811264f93c82dae9ed4e58930 ./plugins/widgets/style.css +5f05e70580892549e068ac89b0b9b168 ./plugins/widgets/widgets.js +5d2f7110de5b4de03cf013c7421e87cc ./plugins/widgets/_widgets_functions.php +7101653d4ef9b55ef29a2e5c7846d052 ./plugins/widgets/_public.php +ede434e0f2087fd062494db6cb0b0c58 ./plugins/widgets/_default_widgets.php +3ce023c7ee7afe5f25f710b11cca9a68 ./plugins/widgets/icon.png +8c9c71d3c0fcd5769bf1a8283749fe26 ./plugins/widgets/class.widgets.php +6c1794028932d3c3c7557d998ecacc40 ./plugins/widgets/_admin.php +926b5589c70fed8f09cd97025ed9e903 ./plugins/widgets/index.php +10b9dd1b33f5f2f74cc92ddac74f3423 ./plugins/widgets/icon-big.png +3b552f7e600dd6c98edc66e7e62ad1fb ./plugins/widgets/dragdrop.js +0fce40ecac55cf0fcdc7e534022bf878 ./plugins/fairTrackbacks/_define.php +15b05e4b999143220e3852ffbdaa15a6 ./plugins/fairTrackbacks/_public.php +bb7fb55037e7045678c3aa812ac4a2ec ./plugins/fairTrackbacks/_prepend.php +5c365c86f9ed6d4a9187c24a3d0b1b43 ./plugins/fairTrackbacks/class.dc.filter.fairtrackbacks.php +0fef5c3614e320bdaf2b1342c313e09a ./plugins/blowupConfig/lib/class.blowup.config.php +f57b92ae244d97ea5889240c600a23ac ./plugins/blowupConfig/_define.php +bd71a73523e30fe0d069c3813ad1bcbb ./plugins/blowupConfig/_install.php +8ac968bf6adbb5cfe1397f2e6e229ace ./plugins/blowupConfig/config.js +1a761c6c24723b5c4d5091d1b983a0eb ./plugins/blowupConfig/_public.php +80eb24ad26a2c981ede3a7c01d53b66a ./plugins/blowupConfig/_admin.php +81d1dde973bcadc1728a2eeb81e6c925 ./plugins/blowupConfig/index.php +f3b1ebaf5a27959228b736f87db11776 ./plugins/blowupConfig/alpha-img/page-bg.png +4e391773b51ea336fb0f647cb15379ef ./plugins/blowupConfig/alpha-img/comment-b.png +78e0f7cf458db47eef8b8ff7a241ac8e ./plugins/blowupConfig/alpha-img/comment-t.png +1c7448246376dc8cecee8f0479723099 ./plugins/blowupConfig/alpha-img/page-t/flamingo.png +f4c8777ac3a935e7b9f171a948a78280 ./plugins/blowupConfig/alpha-img/page-t/blank.png +68daa93bbe1ed00ff190cf851033fe93 ./plugins/blowupConfig/alpha-img/page-t/animals.png +a140e3ae9bf5dcc8c3152a315bd17cd3 ./plugins/blowupConfig/alpha-img/page-t/default.png +c1582964ea8ac500d8f1358cbc11b472 ./plugins/blowupConfig/alpha-img/page-t/typo.png +a13d367c5520f17ee7b3a2dd6cd8068f ./plugins/blowupConfig/alpha-img/page-t/roadrunner-1.png +a33e8d4310696d64bb065cddd23b5292 ./plugins/blowupConfig/alpha-img/page-t/roadrunner-2.png +c48b1a888ebd601e610a425c733367fa ./plugins/blowupConfig/alpha-img/page-t/rabbit.png +508813560e6465f057c07287ad40dd88 ./plugins/blowupConfig/alpha-img/page-t/flourish-1.png +7b79aa5c11177401d7b2cac032d09038 ./plugins/blowupConfig/alpha-img/page-t/flourish-2.png +722ad2b43138abc067ade1c4ed6d0297 ./plugins/blowupConfig/alpha-img/page-t/light-trails-1.png +ee440de20028785d2c0a4fd7b25ae060 ./plugins/blowupConfig/alpha-img/page-t/light-trails-2.png +3f9e394ed187b401c4446b77490944b6 ./plugins/blowupConfig/alpha-img/page-t/light-trails-3.png +ca76fc93ebbce051feb507869165ab6d ./plugins/blowupConfig/alpha-img/page-t/light-trails-4.png +4b3117cca2f73c47d5892684443c74fb ./plugins/blowupConfig/alpha-img/page-t/image-mask.png +ffacd6551c2bd0c863740e7c2fcc29e4 ./plugins/blowupConfig/alpha-img/page-t/butterflies.png +652d06f1c3f7057cd7ab6a01d22b72ba ./plugins/blowupConfig/alpha-img/page-b.png +52db59a23ae5743c614bf9457de0167a ./plugins/blowupConfig/alpha-img/gradient-d.png +bd908640438b6cc2088e81df0894c864 ./plugins/blowupConfig/alpha-img/gradient-l.png +d1e0bdff64011042f02910c6518b1d00 ./plugins/blowupConfig/alpha-img/gradient-m.png +81ef6980e71af45e03f56f66fa6fbd8e ./plugins/blowupConfig/help.html +b39d8c8adaaac48561c435648faa0d64 ./plugins/importExport/js/script.js +caa11e523e5a3ed38d90480bed5d5a73 ./plugins/importExport/inc/img/progress.png +425eef5d5e136de5596b0904fda02755 ./plugins/importExport/inc/flat/class.flat.export.php +ca602765dee0850af857ec8decf3a7f1 ./plugins/importExport/inc/flat/class.flat.import.php +0cadbc79aea5b10efd9ee289799cb46c ./plugins/importExport/inc/flat/class.flat.backup.php +d025a6a06fa8030c06782ec7af1d09f5 ./plugins/importExport/inc/class.dc.export.flat.php +5bb7442c4ca029a63f1897de32966115 ./plugins/importExport/inc/class.dc.ieModule.php +ddf1420b9d0a57351e8fff696c6c7580 ./plugins/importExport/inc/class.dc.import.dc1.php +e4cb3020c427f2cfa3ac0a07a5544684 ./plugins/importExport/inc/class.dc.import.wp.php +c3856ce629d23bc6c6093492250a2aa5 ./plugins/importExport/inc/class.dc.import.flat.php +5d4e8f35e0f9b124b627ccb695d050e7 ./plugins/importExport/inc/class.dc.import.feed.php +e34fedf924add536b694e3d19b67eb9e ./plugins/importExport/_define.php +ab75dcc3e4af8dfdf47a4d9144c45a15 ./plugins/importExport/style.css +cf150f4cab469116959f43e9995a3654 ./plugins/importExport/icon.png +e43b7373a9d43b4aa2025ed5b222aa3d ./plugins/importExport/locales/fr/main.po +e9a05d12aeb1c1882b57f4e3912daf76 ./plugins/importExport/locales/fr/main.lang.php +967d9452787afa167e8d4f7f08432da4 ./plugins/importExport/_prepend.php +4b3f4140098e0b3b96a34b0f4ced511d ./plugins/importExport/_admin.php +9169fd905a1a194849221947f99096f5 ./plugins/importExport/index.php +2959b999f06c95bc6582392d13a0b1f0 ./plugins/importExport/icon-big.png +a27e5d730ed8617782a740bf018f4889 ./plugins/simpleMenu/icon-small.png +823184eb803c7e35a800c23f6d11691f ./plugins/simpleMenu/_define.php +c30e0e1fa38e4ece85294b8f1e55c2b3 ./plugins/simpleMenu/_install.php +92128bc19b2eecc265dd09b9584dee88 ./plugins/simpleMenu/_widgets.php +1b09f23aec3d84b3c17f1c8a5fe2c771 ./plugins/simpleMenu/_public.php +f32140a88ecb3e8fd21ae2ed6652f07c ./plugins/simpleMenu/icon.png +5597505935e7696c6f12b180be70ee50 ./plugins/simpleMenu/locales/en/help/help.html +b4ea322bc7ec45b260c803e046d073fe ./plugins/simpleMenu/locales/en/resources.php +61d2df2c7abd41c0dbd9974596583d42 ./plugins/simpleMenu/locales/fr/help/help.html +b4ea322bc7ec45b260c803e046d073fe ./plugins/simpleMenu/locales/fr/resources.php +460286be8fc317eafd75a3ec72452690 ./plugins/simpleMenu/_admin.php +9734092f951bcf93a505bfa15e80960b ./plugins/simpleMenu/index.php +d85775470a54e974bd4a81fe9363f4b4 ./CREDITS diff --git a/v2/dotclear/inc/libs/clearbricks/Makefile b/v2/dotclear/inc/libs/clearbricks/Makefile new file mode 100644 index 0000000..f440738 --- /dev/null +++ b/v2/dotclear/inc/libs/clearbricks/Makefile @@ -0,0 +1,44 @@ +SHELL=/bin/sh + +DIST=_dist +CB=$(DIST)/clearbricks + +default: + @echo "make config or make dist" + +config: + mkdir -p ./$(CB) + + ## Copy needed files and folders + find ./ -mindepth 1 -maxdepth 1 -type d \ + -not -regex '.*svn.*' \ + -not -name '_dist' \ + -not -name 'debian' \ + -exec cp -r \{\} ./$(CB) \; + + ## Copy _common.php and README files + cp _common.php README ./$(CB)/ + + ## Remove .svn folders + find ./$(CB)/ -type d -name '.svn' -print0 | xargs -0 rm -rf + + touch config-stamp + +dist: config dist-tgz dist-zip + +deb: + cp ./README debian/README + dpkg-buildpackage -rfakeroot + +dist-tgz: + [ -f config-stamp ] + cd $(DIST) && tar cfz clearbricks-$$(grep CLEARBRICKS_VERSION clearbricks/common/_main.php | cut -d"'" -f4).tar.gz ./clearbricks + +dist-zip: + [ -f config-stamp ] + cd $(DIST) && zip -r9 clearbricks-$$(grep CLEARBRICKS_VERSION clearbricks/common/_main.php | cut -d"'" -f4).zip ./clearbricks + +clean: + [ -f config-stamp ] + rm -rf $(DIST) + rm -f config-stamp build-stamp configure-stamp diff --git a/v2/dotclear/inc/libs/clearbricks/README b/v2/dotclear/inc/libs/clearbricks/README new file mode 100644 index 0000000..4dadeec --- /dev/null +++ b/v2/dotclear/inc/libs/clearbricks/README @@ -0,0 +1,67 @@ +Clearbricks +=========== + +What is this? +------------- + +No, Clearbricks is not yet another framework. Clearbricks is not cool at all and +does not even have a nice website. It won't make you smart neither have great +ideas for you. + +Clearbricks is only about code and efficiency, consider it as a toolbox. And +please, do me a favor, don't call it a framework :-) + +How do I use it? +---------------- + +Clearbricks is about "using what we need when we need it". Pick the module(s) +you need and add it to your code. The only thing you'll always need is the +"common" directory. + +Once you're ready, you have to create a _common.php file on top of your +Clearbricks path (or wherever you want) and add $__autoload entries for your +modules. + +Take a look at the _common.php file. + +Of course, you're encouraged to use the $__autoload magic for your own classes. + +Use it with Subversion +---------------------- + +You may think that all this subdirectories is a mess. You're quite right. But +one day, you'll find it cool to use Clearbricks modules in your subversion +repository as some external properties. This day, you'll love me :-) + +Clearbricks subersion repository is located at: +https://clearbricks.org/svn + +Here is an example of using Clearbricks and dbLayer in your own subversion +repository as an external property: + +First, we create a Clearbricks root. + +$ mkdir clearbricks +$ svn add clearbricks +$ svn ci + +And now, add externals definitions + +$ cd clearbricks +$ svn propedit svn:externals . + +Your editor fires up, type: + +common https://clearbricks.org/svn/trunk/common +dblayer https://clearbricks.org/svn/trunk/dblayer + +Save and "svn up". + +Then, you can create a _common.php file wich will contain: + + + +You're done! diff --git a/v2/dotclear/inc/libs/clearbricks/_common.php b/v2/dotclear/inc/libs/clearbricks/_common.php new file mode 100644 index 0000000..cf9e6d8 --- /dev/null +++ b/v2/dotclear/inc/libs/clearbricks/_common.php @@ -0,0 +1,123 @@ + \ No newline at end of file diff --git a/v2/dotclear/inc/libs/clearbricks/common/_main.php b/v2/dotclear/inc/libs/clearbricks/common/_main.php new file mode 100644 index 0000000..c3129b3 --- /dev/null +++ b/v2/dotclear/inc/libs/clearbricks/common/_main.php @@ -0,0 +1,58 @@ + dirname(__FILE__).'/lib.crypt.php', + 'dt' => dirname(__FILE__).'/lib.date.php', + 'files' => dirname(__FILE__).'/lib.files.php', + 'path' => dirname(__FILE__).'/lib.files.php', + 'form' => dirname(__FILE__).'/lib.form.php', + 'formSelectOption' => dirname(__FILE__).'/lib.form.php', + 'html' => dirname(__FILE__).'/lib.html.php', + 'http' => dirname(__FILE__).'/lib.http.php', + 'text' => dirname(__FILE__).'/lib.text.php' +); + +# autoload for clearbricks +function cb_autoload($name) +{ + global $__autoload; + + if (isset($__autoload[$name])) { + require_once $__autoload[$name]; + } +} + +# if php version >= 5.1.2, we can benefit from spl_autoload_register, +# so other libraries can define their own independent autoload too +if (function_exists("spl_autoload_register")) { + spl_autoload_register("cb_autoload"); +} else { + # otherwise we define a classic autoload function for older php... + function __autoload($name) { + cb_autoload($name); + } +} + +# We only need l10n __() function +require_once dirname(__FILE__).'/lib.l10n.php'; + +# We set default timezone to avoid warning +dt::setTZ('UTC'); +?> \ No newline at end of file diff --git a/v2/dotclear/inc/libs/clearbricks/common/lib.crypt.php b/v2/dotclear/inc/libs/clearbricks/common/lib.crypt.php new file mode 100644 index 0000000..5975697 --- /dev/null +++ b/v2/dotclear/inc/libs/clearbricks/common/lib.crypt.php @@ -0,0 +1,77 @@ +$data, using the said $key + * and $hashfunc as hash method (sha1 or md5 are accepted.) + * + * @param string $key Hash key + * @param string $data Data + * @param string $hashfunc Hash function (md5 or sha1) + * @return string + */ + public static function hmac($key,$data,$hashfunc='sha1') + { + $blocksize=64; + if ($hashfunc != 'sha1') { + $hashfunc = 'md5'; + } + + if (strlen($key)>$blocksize) { + $key=pack('H*', $hashfunc($key)); + } + + $key=str_pad($key,$blocksize,chr(0x00)); + $ipad=str_repeat(chr(0x36),$blocksize); + $opad=str_repeat(chr(0x5c),$blocksize); + $hmac = pack('H*',$hashfunc(($key^$opad).pack('H*',$hashfunc(($key^$ipad).$data)))); + return bin2hex($hmac); + } + + /** + * Password generator + * + * Returns an 8 characters random password. + * + * @todo Add a length param + * + * @return string + */ + public static function createPassword() + { + $pwd = array(); + $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'; + $chars2 = '$!@'; + + foreach (range(0,7) as $i) { + $pwd[] = $chars[rand(0,strlen($chars)-1)]; + } + + $pos1 = array_rand(array(0,1,2,3)); + $pos2 = array_rand(array(4,5,6,7)); + $pwd[$pos1] = $chars2[rand(0,strlen($chars2)-1)]; + $pwd[$pos2] = $chars2[rand(0,strlen($chars2)-1)]; + + return implode('',$pwd); + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/libs/clearbricks/common/lib.date.php b/v2/dotclear/inc/libs/clearbricks/common/lib.date.php new file mode 100644 index 0000000..de9b28a --- /dev/null +++ b/v2/dotclear/inc/libs/clearbricks/common/lib.date.php @@ -0,0 +1,260 @@ + $v) { + $g = explode('/',$k); + $tmp[$g[0]][$k] = $v; + } + $res = $tmp; + } + } + + return $res; + } + + private static function _callback($args) + { + $b = array(1=>'_Jan',2=>'_Feb',3=>'_Mar',4=>'_Apr',5=>'_May',6=>'_Jun', + 7=>'_Jul',8=>'_Aug',9=>'_Sep',10=>'_Oct',11=>'_Nov',12=>'_Dec'); + + $B = array(1=>'January',2=>'February',3=>'March',4=>'April', + 5=>'May',6=>'June',7=>'July',8=>'August',9=>'September', + 10=>'October',11=>'November',12=>'December'); + + $a = array(1=>'_Mon',2=>'_Tue',3=>'_Wed',4=>'_Thu',5=>'_Fri', + 6=>'_Sat',0=>'_Sun'); + + $A = array(1=>'Monday',2=>'Tuesday',3=>'Wednesday',4=>'Thursday', + 5=>'Friday',6=>'Saturday',0=>'Sunday'); + + return __(${$args[1]}[(integer) $args[2]]); + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/libs/clearbricks/common/lib.files.php b/v2/dotclear/inc/libs/clearbricks/common/lib.files.php new file mode 100644 index 0000000..e957095 --- /dev/null +++ b/v2/dotclear/inc/libs/clearbricks/common/lib.files.php @@ -0,0 +1,667 @@ + 'application/vnd.oasis.opendocument.text', + 'odp' => 'application/vnd.oasis.opendocument.presentation', + 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', + + 'sxw' => 'application/vnd.sun.xml.writer', + 'sxc' => 'application/vnd.sun.xml.calc', + 'sxi' => 'application/vnd.sun.xml.impress', + + 'ppt' => 'application/mspowerpoint', + 'doc' => 'application/msword', + 'xls' => 'application/msexcel', + 'rtf' => 'application/rtf', + + 'pdf' => 'application/pdf', + 'ps' => 'application/postscript', + 'ai' => 'application/postscript', + 'eps' => 'application/postscript', + 'json' => 'application/json', + 'xml' => 'application/xml', + + 'bin' => 'application/octet-stream', + 'exe' => 'application/octet-stream', + + 'bz2' => 'application/x-bzip', + 'deb' => 'application/x-debian-package', + 'gz' => 'application/x-gzip', + 'jar' => 'application/x-java-archive', + 'rar' => 'application/rar', + 'rpm' => 'application/x-redhat-package-manager', + 'tar' => 'application/x-tar', + 'tgz' => 'application/x-gtar', + 'zip' => 'application/zip', + + 'aiff' => 'audio/x-aiff', + 'ua' => 'audio/basic', + 'mp3' => 'audio/mpeg3', + 'mid' => 'audio/x-midi', + 'midi' => 'audio/x-midi', + 'ogg' => 'application/ogg', + 'ra' => 'audio/x-pn-realaudio', + 'ram' => 'audio/x-pn-realaudio', + 'wav' => 'audio/x-wav', + 'wma' => 'audio/x-ms-wma', + + 'swf' => 'application/x-shockwave-flash', + 'swfl' => 'application/x-shockwave-flash', + + 'bmp' => 'image/bmp', + 'gif' => 'image/gif', + 'ico' => 'image/vnd.microsoft.icon', + 'jpeg' => 'image/jpeg', + 'jpg' => 'image/jpeg', + 'jpe' => 'image/jpeg', + 'png' => 'image/png', + 'svg' => 'image/svg+xml', + 'tiff' => 'image/tiff', + 'tif' => 'image/tiff', + 'xbm' => 'image/x-xbitmap', + + 'css' => 'text/css', + 'csv' => 'text/csv', + 'js' => 'text/javascript', + 'html' => 'text/html', + 'htm' => 'text/html', + 'txt' => 'text/plain', + 'rtf' => 'text/richtext', + 'rtx' => 'text/richtext', + + 'mpg' => 'video/mpeg', + 'mpeg' => 'video/mpeg', + 'mpe' => 'video/mpeg', + 'ogv' => 'video/ogg', + 'viv' => 'video/vnd.vivo', + 'vivo' => 'video/vnd.vivo', + 'qt' => 'video/quicktime', + 'mov' => 'video/quicktime', + 'mp4' => 'video/mp4', + 'm4v' => 'video/x-m4v', + 'flv' => 'video/x-flv', + 'avi' => 'video/x-msvideo', + 'wmv' => 'video/x-ms-wmv' + ); + + /** + * Directory scanning + * + * Returns a directory child files and directories. + * + * @param string $d Path to scan + * @param boolean $order Order results + * @return array + */ + public static function scandir($d,$order=false) + { + $res = array(); + $dh = @opendir($d); + + if ($dh === false) { + throw new Exception(__('Unable to open directory.')); + } + + while (($f = readdir($dh)) !== false) { + $res[] = $f; + } + closedir($dh); + + sort($res); + if ($order) { + rsort($res); + } + + return $res; + } + + /** + * File extension + * + * Returns a file extension. + * + * @param string $f File name + * @return string + */ + public static function getExtension($f) + { + $f = explode('.',basename($f)); + + if (count($f) <= 1) { return ''; } + + return strtolower($f[count($f)-1]); + } + + /** + * MIME type + * + * Returns a file MIME type, based on static var {@link $mimeType} + * + * @param string $f File name + * @return string + */ + public static function getMimeType($f) + { + $ext = self::getExtension($f); + $types = self::mimeTypes(); + + if (isset($types[$ext])) { + return $types[$ext]; + } else { + return 'text/plain'; + } + } + + /** + * MIME types + * + * Returns all defined MIME types. + * + * @return array + */ + public static function mimeTypes() + { + return self::$mimeType; + } + + /** + * New MIME types + * + * Append new MIME types to defined MIME types. + * + * @param array $tab New MIME types. + */ + public static function registerMimeTypes($tab) + { + self::$mimeType = array_merge(self::$mimeType, $tab); + } + + /** + * Is a file or directory deletable. + * + * Returns true if $f is a file or directory and is deletable. + * + * @param string $f File or directory + * @return boolean + */ + public static function isDeletable($f) + { + if (is_file($f)) { + return is_writable(dirname($f)); + } elseif (is_dir($f)) { + return (is_writable(dirname($f)) && count(files::scandir($f)) <= 2); + } + } + + /** + * Recursive removal + * + * Remove recursively a directory. + * + * @param string $dir Directory patch + * @return boolean + */ + public static function deltree($dir) + { + $current_dir = opendir($dir); + while($entryname = readdir($current_dir)) + { + if (is_dir($dir.'/'.$entryname) and ($entryname != '.' and $entryname!='..')) + { + if (!files::deltree($dir.'/'.$entryname)) { + return false; + } + } + elseif ($entryname != '.' and $entryname!='..') + { + if (!@unlink($dir.'/'.$entryname)) { + return false; + } + } + } + closedir($current_dir); + return @rmdir($dir); + } + + /** + * Touch file + * + * Set file modification time to now. + * + * @param string $f File to change + */ + public static function touch($f) + { + if (is_writable($f)) { + if (function_exists('touch')) { + @touch($f); + } else { + # Very bad hack + @file_put_contents($f,file_get_contents($f)); + } + } + } + + /** + * Directory creation. + * + * Creates directory $f. If $r is true, attempts to create needed parents + * directories. + * + * @param string $f Directory to create + * @param boolean $r Create parent directories + */ + public static function makeDir($f,$r=false) + { + if (empty($f)) { + return; + } + + if (DIRECTORY_SEPARATOR == '\\') { + $f = str_replace('/','\\',$f); + } + + if (is_dir($f)) { + return; + } + + if ($r) + { + $dir = path::real($f,false); + $dirs = array(); + + while (!is_dir($dir)) { + array_unshift($dirs,basename($dir)); + $dir = dirname($dir); + } + + foreach ($dirs as $d) + { + $dir .= DIRECTORY_SEPARATOR.$d; + if ($d != '' && !is_dir($dir)) { + self::makeDir($dir); + } + } + } + else + { + if (@mkdir($f) === false) { + throw new Exception(__('Unable to create directory.')); + } + self::inheritChmod($f); + } + } + + /** + * Mode inheritage + * + * Sets file or directory mode according to its parent. + * + * @param string $file File to change + */ + public static function inheritChmod($file) + { + if (!function_exists('fileperms') || !function_exists('chmod')) { + return false; + } + + if (self::$dir_mode != null) { + return @chmod($file,self::$dir_mode); + } else { + return @chmod($file,fileperms(dirname($file))); + } + } + + /** + * Changes file content. + * + * Writes $f_content into $f file. + * + * @param string $f File to edit + * @param string $f_content Content to write + */ + public static function putContent($f, $f_content) + { + if (file_exists($f) && !is_writable($f)) { + throw new Exception(__('File is not writable.')); + } + + $fp = @fopen($f, 'w'); + + if ($fp === false) { + throw new Exception(__('Unable to open file.')); + } + + fwrite($fp,$f_content,strlen($f_content)); + fclose($fp); + return true; + } + + /** + * Human readable file size. + * + * @param integer $size Bytes + * @return string + */ + public static function size($size) + { + $kb = 1024; + $mb = 1024 * $kb; + $gb = 1024 * $mb; + $tb = 1024 * $gb; + + if($size < $kb) { + return $size." B"; + } + else if($size < $mb) { + return round($size/$kb,2)." KB"; + } + else if($size < $gb) { + return round($size/$mb,2)." MB"; + } + else if($size < $tb) { + return round($size/$gb,2)." GB"; + } + else { + return round($size/$tb,2)." TB"; + } + } + + /** + * Converts a human readable file size to bytes. + * + * @param string $v Size + * @return integer + */ + public static function str2bytes($v) + { + $v = trim($v); + $last = strtolower(substr($v,-1,1)); + + switch($last) + { + case 'g': + $v *= 1024; + case 'm': + $v *= 1024; + case 'k': + $v *= 1024; + } + + return $v; + } + + /** + * Upload status + * + * Returns true if upload status is ok, throws an exception instead. + * + * @param array $file File array as found in $_FILES + * @return boolean + */ + public static function uploadStatus($file) + { + if (!isset($file['error'])) { + throw new Exception(__('Not an uploaded file.')); + } + + switch ($file['error']) { + case UPLOAD_ERR_OK: + return true; + case UPLOAD_ERR_INI_SIZE: + case UPLOAD_ERR_FORM_SIZE: + throw new Exception(__('The uploaded file exceeds the maximum file size allowed.')); + return false; + case UPLOAD_ERR_PARTIAL: + throw new Exception(__('The uploaded file was only partially uploaded.')); + return false; + case UPLOAD_ERR_NO_FILE: + throw new Exception(__('No file was uploaded.')); + return false; + case UPLOAD_ERR_NO_TMP_DIR: + throw new Exception(__('Missing a temporary folder.')); + return false; + case UPLOAD_ERR_CANT_WRITE: + throw new Exception(__('Failed to write file to disk.')); + return false; + default: + return true; + } + } + + # Packages generation methods + # + /** + * Recursive directory scanning + * + * Returns an array of a given directory's content. The array contains + * two arrays: dirs and files. Directory's content is fetched recursively. + * + * @param string $dirName Directory name + * @param array $contents Contents array. Leave it empty + * @return array + */ + public static function getDirList($dirName, &$contents = null) + { + if (!$contents) { + $contents = array('dirs'=> array(),'files' => array()); + } + + $exclude_list=array('.','..','.svn'); + + if (empty($res)) { + $res = array(); + } + + $dirName = preg_replace('|/$|','',$dirName); + + if (!is_dir($dirName)) { + throw new Exception(sprintf(__('%s is not a directory.'),$dirName)); + } + + $contents['dirs'][] = $dirName; + + $d = @dir($dirName); + + if ($d === false) { + throw new Exception(__('Unable to open directory.')); + } + + while($entry = $d->read()) + { + if (!in_array($entry,$exclude_list)) + { + if (is_dir($dirName.'/'.$entry)) + { + files::getDirList($dirName.'/'.$entry, $contents); + } + else + { + $contents['files'][] = $dirName.'/'.$entry; + } + } + } + $d->close(); + + return $contents; + } + + /** + * Filename cleanup + * + * Removes unwanted characters in a filename. + * + * @param string $n Filename + * @return string + */ + public static function tidyFileName($n) + { + $n = text::deaccent($n); + $n = preg_replace('/^[.]/u','',$n); + return preg_replace('/[^A-Za-z0-9._-]/u','_',$n); + } +} + +/** +* Path manipulation utilities +* +* @package Clearbricks +* @subpackage Common +*/ +class path +{ + /** + * Returns the real path of a file. + * + * If parameter $strict is true, file should exist. Returns false if + * file does not exist. + * + * @param string $p Filename + * @param boolean $strict File should exists + * @return string + */ + public static function real($p,$strict=true) + { + $os = (DIRECTORY_SEPARATOR == '\\') ? 'win' : 'nix'; + + # Absolute path? + if ($os == 'win') { + $_abs = preg_match('/^\w+:/',$p); + } else { + $_abs = substr($p,0,1) == '/'; + } + + # Standard path form + if ($os == 'win') { + $p = str_replace('\\','/',$p); + } + + # Adding root if !$_abs + if (!$_abs) { + $p = dirname($_SERVER['SCRIPT_FILENAME']).'/'.$p; + } + + # Clean up + $p = preg_replace('|/+|','/',$p); + + if (strlen($p) > 1) { + $p = preg_replace('|/$|','',$p); + } + + $_start = ''; + if ($os == 'win') { + list($_start,$p) = explode(':',$p); + $_start .= ':/'; + } else { + $_start = '/'; + } + $p = substr($p,1); + + # Go through + $P = explode('/',$p); + $res = array(); + + for ($i=0;$i 0) { + array_pop($res); + } + } else { + array_push($res,$P[$i]); + } + } + + $p = $_start.implode('/',$res); + + if ($strict && !@file_exists($p)) { + return false; + } + + return $p; + } + + /** + * Returns a clean file path + * + * @param string $p File path + * @return string + */ + public static function clean($p) + { + $p = str_replace('..','',$p); + $p = preg_replace('|/{2,}|','/',$p); + $p = preg_replace('|/$|','',$p); + + return $p; + } + + /** + * Path information + * + * Returns an array of information: + * - dirname + * - basename + * - extension + * - base (basename without extension) + * + * @param string $f File path + */ + public static function info($f) + { + $p = pathinfo($f); + $res = array(); + + $res['dirname'] = $p['dirname']; + $res['basename'] = $p['basename']; + $res['extension'] = isset($p['extension']) ? $p['extension'] : ''; + $res['base'] = preg_replace('/\.'.preg_quote($res['extension'],'/').'$/','',$res['basename']); + + return $res; + } + + /** + * Full path with root + * + * Returns a path with root concatenation unless path begins with a slash + * + * @param string $p File path + * @param string $root Root path + * @return string + */ + public static function fullFromRoot($p,$root) + { + if (substr($p,0,1) == '/') { + return $p; + } + + return $root.'/'.$p; + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/libs/clearbricks/common/lib.form.php b/v2/dotclear/inc/libs/clearbricks/common/lib.form.php new file mode 100644 index 0000000..398fe5c --- /dev/null +++ b/v2/dotclear/inc/libs/clearbricks/common/lib.form.php @@ -0,0 +1,347 @@ +'."\n"; + + $res .= self::comboOptions($data,$default); + + $res .= ''."\n"; + + return $res; + } + + private static function comboOptions($data,$default) + { + $res = ''; + $option = ''."\n"; + $optgroup = ''."\n".'%2$s'."\n"; + + foreach($data as $k => $v) + { + if (is_array($v)) { + $res .= sprintf($optgroup,$k,self::comboOptions($v,$default)); + } elseif ($v instanceof formSelectOption) { + $res .= $v->render($default); + } else { + $s = ($v == $default) ? ' selected="selected"' : ''; + $res .= sprintf($option,$v,$k,$s); + } + } + + return $res; + } + + /** + * Radio button + * + * Returns HTML code for a radio button. $nid could be a string or an array of + * name and ID. + * + * @param string|array $nid Element ID and name + * @param string $value Element value + * @param boolean $checked True if checked + * @param string $class Element class name + * @param string $tabindex Element tabindex + * @param boolean $disabled True if disabled + * @param string $extra_html Extra HTML attributes + * + * @return string + */ + public static function radio($nid, $value, $checked='', $class='', $tabindex='', + $disabled=false, $extra_html='') + { + self::getNameAndId($nid,$name,$id); + + $res = ''; + $res .= $default; + $res .= ''; + + return $res; + } + + /** + * Hidden field + * + * Returns HTML code for an hidden field. $nid could be a string or an array of + * name and ID. + * + * @param string|array $nid Element ID and name + * @param string $value Element value + * + * @return string + */ + public static function hidden($nid,$value) + { + self::getNameAndId($nid,$name,$id); + + $res = 'name = $name; + $this->value = $value; + $this->class_name = $class_name; + $this->html = $html; + } + + /** + * Option renderer + * + * Returns option HTML code + * + * @param boolean $default Option is selected + * @return string + */ + public function render($default) + { + $attr = $this->html; + $attr .= $this->class_name ? ' class="'.$this->class_name.'"' : ''; + + if ($this->value == $default) { + $attr .= ' selected="selected"'; + } + + return sprintf($this->option,$this->value,$this->name,$attr)."\n"; + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/libs/clearbricks/common/lib.html.php b/v2/dotclear/inc/libs/clearbricks/common/lib.html.php new file mode 100644 index 0000000..20aba63 --- /dev/null +++ b/v2/dotclear/inc/libs/clearbricks/common/lib.html.php @@ -0,0 +1,185 @@ + "'" + ); + + $str = str_replace(array_keys($extra),array_values($extra),$str); + + return html_entity_decode($str,ENT_QUOTES,'UTF-8'); + } + + /** + * Remove markup + * + * Removes every tags, comments, cdata from string + * + * @param string $str String to clean + * @return string + */ + public static function clean($str) + { + $str = strip_tags($str); + return $str; + } + + /** + * Javascript escape + * + * Returns a protected JavaScript string + * + * @param string $str String to protect + * @return string + */ + public static function escapeJS($str) + { + $str = htmlspecialchars($str,ENT_NOQUOTES,'UTF-8'); + $str = str_replace("'","\'",$str); + $str = str_replace('"','\"',$str); + return $str; + } + + /** + * URL escape + * + * Returns an escaped URL string for HTML content + * + * @param string $str String to escape + * @return string + */ + public static function escapeURL($str) + { + return str_replace('&','&',$str); + } + + /** + * URL sanitize + * + * Encode every parts between / in url + * + * @param string $str String to satinyze + * @return string + */ + public static function sanitizeURL($str) + { + return str_replace('%2F','/',rawurlencode($str)); + } + + /** + * Remove host in URL + * + * Removes host part in URL + * + * @param string $str URL to transform + * @return string + */ + public static function stripHostURL($url) + { + return preg_replace('|^[a-z]{3,}://.*?(/.*$)|','$1',$url); + } + + /** + * Set links to absolute ones + * + * Appends $root URL to URIs attributes in $str. + * + * @param string $str HTML to transform + * @param string $root Base URL + * @return string + */ + public static function absoluteURLs($str,$root) + { + self::$url_root = $root; + $attr = 'action|background|cite|classid|codebase|data|href|longdesc|profile|src|usemap'; + + $str = preg_replace_callback('/((?:'.$attr.')=")(.*?)(")/msu',array('self','absoluteURLHandler'),$str); + + foreach (self::$absolute_regs as $r) { + $str = preg_replace_callback($r,array('self','absoluteURLHandler'),$str); + } + + self::$url_root = null; + return $str; + } + + private static function absoluteURLHandler($m) + { + $url = $m[2]; + + $link = str_replace('%','%%',$m[1]).'%s'.str_replace('%','%%',$m[3]); + $host = preg_replace('|^([a-z]{3,}://)(.*?)/(.*)$|','$1$2',self::$url_root); + + $parse = parse_url($m[2]); + if (empty($parse['scheme'])) + { + if (strpos($url,'/') === 0) { + $url = $host.$url; + } elseif (strpos($url,'#') === 0) { + $url = self::$url_root.$url; + } elseif (preg_match('|/$|',self::$url_root)) { + $url = self::$url_root.$url; + } else { + $url = dirname(self::$url_root).'/'.$url; + } + } + + return sprintf($link,$url); + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/libs/clearbricks/common/lib.http.php b/v2/dotclear/inc/libs/clearbricks/common/lib.http.php new file mode 100644 index 0000000..7fec31a --- /dev/null +++ b/v2/dotclear/inc/libs/clearbricks/common/lib.http.php @@ -0,0 +1,452 @@ +[a-z]{2}(?:-[a-z]{2})?)(?:;q=(?P[.0-9]*))?/'; + if (preg_match_all($pattern,$_SERVER['HTTP_ACCEPT_LANGUAGE'],$acclang) !== false) + { + foreach($acclang['priority'] as $i => $p) + { + if ($p == '') $acclang['priority'][$i]=1; + } + array_multisort($acclang['priority'], SORT_DESC,$acclang['lang']); + } + return $acclang['lang']; + } else { + return $acclang; + } + } + + /** + * HTTP Cache + * + * Sends HTTP cache headers (304) according to a list of files and an optionnal. + * list of timestamps. + * + * @param array $files Files on which check mtime + * @param array $mod_ts List of timestamps + */ + public static function cache($files,$mod_ts=array()) + { + if (empty($files) || !is_array($files)) { + return; + } + + array_walk($files,create_function('&$v','$v = filemtime($v);')); + + $array_ts = array_merge($mod_ts,$files); + + rsort($array_ts); + $now = time(); + $ts = min($array_ts[0],$now); + + $since = null; + if (!empty($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { + $since = $_SERVER['HTTP_IF_MODIFIED_SINCE']; + $since = preg_replace ('/^(.*)(Mon|Tue|Wed|Thu|Fri|Sat|Sun)(.*)(GMT)(.*)/', '$2$3 GMT', $since); + $since = strtotime($since); + $since = ($since <= $now) ? $since : null; + } + + # Common headers list + $headers[] = 'Last-Modified: '.gmdate('D, d M Y H:i:s',$ts).' GMT'; + $headers[] = 'Cache-Control: must-revalidate, max-age='.abs((integer) self::$cache_max_age); + $headers[] = 'Pragma:'; + + if ($since >= $ts) + { + self::head(304,'Not Modified'); + foreach ($headers as $v) { + header($v); + } + exit; + } + else + { + header('Date: '.gmdate('D, d M Y H:i:s',$now).' GMT'); + foreach ($headers as $v) { + header($v); + } + } + } + + /** + * HTTP Etag + * + * Sends HTTP cache headers (304) according to a list of etags in client request. + * + * @param string $p_content Response page content + */ + public static function etag() + { + # We create an etag from all arguments + $args = func_get_args(); + if (empty($args)) { + return; + } + + $etag = '"'.md5(implode('',$args)).'"'; + unset($args); + + header('ETag: '.$etag); + + # Do we have a previously sent content? + if (!empty($_SERVER['HTTP_IF_NONE_MATCH'])) + { + foreach (explode(',',$_SERVER['HTTP_IF_NONE_MATCH']) as $i) + { + if (stripslashes(trim($i)) == $etag) { + self::head(304,'Not Modified'); + exit; + } + } + } + } + + /** + * HTTP Header + * + * Sends an HTTP code and message to client. + * + * @param string $code HTTP code + * @param string $msg Message + */ + public static function head($code,$msg=null) + { + $status_mode = preg_match('/cgi/',PHP_SAPI); + + if (!$msg) + { + $msg_codes = array( + 100 => 'Continue', + 101 => 'Switching Protocols', + 200 => 'OK', + 201 => 'Created', + 202 => 'Accepted', + 203 => 'Non-Authoritative Information', + 204 => 'No Content', + 205 => 'Reset Content', + 206 => 'Partial Content', + 300 => 'Multiple Choices', + 301 => 'Moved Permanently', + 302 => 'Found', + 303 => 'See Other', + 304 => 'Not Modified', + 305 => 'Use Proxy', + 307 => 'Temporary Redirect', + 400 => 'Bad Request', + 401 => 'Unauthorized', + 402 => 'Payment Required', + 403 => 'Forbidden', + 404 => 'Not Found', + 405 => 'Method Not Allowed', + 406 => 'Not Acceptable', + 407 => 'Proxy Authentication Required', + 408 => 'Request Timeout', + 409 => 'Conflict', + 410 => 'Gone', + 411 => 'Length Required', + 412 => 'Precondition Failed', + 413 => 'Request Entity Too Large', + 414 => 'Request-URI Too Long', + 415 => 'Unsupported Media Type', + 416 => 'Requested Range Not Satisfiable', + 417 => 'Expectation Failed', + 500 => 'Internal Server Error', + 501 => 'Not Implemented', + 502 => 'Bad Gateway', + 503 => 'Service Unavailable', + 504 => 'Gateway Timeout', + 505 => 'HTTP Version Not Supported' + ); + + $msg = isset($msg_codes[$code]) ? $msg_codes[$code] : '-'; + } + + if ($status_mode) { + header('Status: '.$code.' '.$msg); + } else { + header($msg, true, $code); + } + } + + /** + * Trim request + * + * Trims every value in GET, POST, REQUEST and COOKIE vars. + * Removes magic quotes if magic_quote_gpc is on. + */ + public static function trimRequest() + { + if(!empty($_GET)) { + array_walk($_GET,array('self','trimRequestInVar')); + } + if(!empty($_POST)) { + array_walk($_POST,array('self','trimRequestInVar')); + } + if(!empty($_REQUEST)) { + array_walk($_REQUEST,array('self','trimRequestInVar')); + } + if(!empty($_COOKIE)) { + array_walk($_COOKIE,array('self','trimRequestInVar')); + } + } + + /* + * + * To be deleted? + * -- saymonz, 29.04.2011 + * + //* + + private static function trimRequestHandler(&$v,$key) + { + $v = self::trimRequestInVar($v); + } + + //*/ + + private static function trimRequestInVar(&$value,$key) + { + if (is_array($value)) + { + foreach ($value as $k => &$v) + { + if (is_array($v)) { + self::trimRequestInVar($v,$k); + } else { + if (get_magic_quotes_gpc()) { + $v = stripslashes($v); + } + $v = trim($v); + } + } + } + else + { + if (get_magic_quotes_gpc()) { + $value = stripslashes($value); + } + $value = trim($value); + } + } + + /** + * Unset global variables + * + * If register_globals is on, removes every GET, POST, COOKIE, REQUEST, SERVER, + * ENV, FILES vars from GLOBALS. + */ + public static function unsetGlobals() + { + if (!ini_get('register_globals')) { + return; + } + + if (isset($_REQUEST['GLOBALS'])) { + throw new Exception('GLOBALS overwrite attempt detected'); + } + + # Variables that shouldn't be unset + $no_unset = array('GLOBALS','_GET','_POST','_COOKIE','_REQUEST', + '_SERVER','_ENV','_FILES'); + + $input = array_merge($_GET,$_POST,$_COOKIE,$_SERVER,$_ENV,$_FILES, + (isset($_SESSION) && is_array($_SESSION) ? $_SESSION : array())); + + foreach ($input as $k => $v) { + if (!in_array($k,$no_unset) && isset($GLOBALS[$k]) ) { + $GLOBALS[$k] = null; + unset($GLOBALS[$k]); + } + } + } +} +?> diff --git a/v2/dotclear/inc/libs/clearbricks/common/lib.l10n.php b/v2/dotclear/inc/libs/clearbricks/common/lib.l10n.php new file mode 100644 index 0000000..63543d0 --- /dev/null +++ b/v2/dotclear/inc/libs/clearbricks/common/lib.l10n.php @@ -0,0 +1,453 @@ + 'Afaraf', + 'ab' => 'Аҧсуа', + 'ae' => 'Avesta', + 'af' => 'Afrikaans', + 'ak' => 'Akan', + 'am' => 'አማርኛ', + 'an' => 'Aragonés', + 'ar' => '‫العربية', + 'as' => 'অসমীয়া', + 'av' => 'авар мацӀ', + 'ay' => 'Aymar aru', + 'az' => 'Azərbaycan dili', + 'ba' => 'башҡорт теле', + 'be' => 'Беларуская', + 'bg' => 'български език', + 'bh' => 'भोजपुरी', + 'bi' => 'Bislama', + 'bm' => 'Bamanankan', + 'bn' => 'বাংলা', + 'bo' => 'བོད་ཡིག', + 'br' => 'Brezhoneg', + 'bs' => 'Bosanski jezik', + 'ca' => 'Català', + 'ce' => 'нохчийн мотт', + 'ch' => 'Chamoru', + 'co' => 'Corsu', + 'cr' => 'ᓀᐦᐃᔭᐍᐏᐣ', + 'cs' => 'Česky', + 'cu' => 'ѩзыкъ Словѣньскъ', + 'cv' => 'чӑваш чӗлхи', + 'cy' => 'Cymraeg', + 'da' => 'Dansk', + 'de' => 'Deutsch', + 'dv' => '‫ދިވެހި', + 'dz' => 'རྫོང་ཁ', + 'ee' => 'Ɛʋɛgbɛ', + 'el' => 'Ελληνικά', + 'en' => 'English', + 'eo' => 'Esperanto', + 'es' => 'español', + 'et' => 'Eesti keel', + 'eu' => 'Euskara', + 'fa' => '‫فارسی', + 'ff' => 'Fulfulde', + 'fi' => 'Suomen kieli', + 'fj' => 'Vosa Vakaviti', + 'fo' => 'Føroyskt', + 'fr' => 'Français', + 'fy' => 'Frysk', + 'ga' => 'Gaeilge', + 'gd' => 'Gàidhlig', + 'gl' => 'Galego', + 'gn' => "Avañe'ẽ", + 'gu' => 'ગુજરાતી', + 'gv' => 'Ghaelg', + 'ha' => '‫هَوُسَ', + 'he' => '‫עברית', + 'hi' => 'हिन्दी', + 'ho' => 'Hiri Motu', + 'hr' => 'Hrvatski', + 'ht' => 'Kreyòl ayisyen', + 'hu' => 'Magyar', + 'hy' => 'Հայերեն', + 'hz' => 'Otjiherero', + 'ia' => 'Interlingua', + 'id' => 'Bahasa Indonesia', + 'ie' => 'Interlingue', + 'ig' => 'Igbo', + 'ii' => 'ꆇꉙ', + 'ik' => 'Iñupiaq', + 'io' => 'Ido', + 'is' => 'Íslenska', + 'it' => 'Italiano', + 'iu' => 'ᐃᓄᒃᑎᑐᑦ', + 'ja' => '日本語', + 'jv' => 'Basa Jawa', + 'ka' => 'ქართული', + 'kg' => 'KiKongo', + 'ki' => 'Gĩkũyũ', + 'kj' => 'Kuanyama', + 'kk' => 'Қазақ тілі', + 'kl' => 'Kalaallisut', + 'km' => 'ភាសាខ្មែរ', + 'kn' => 'ಕನ್ನಡ', + 'ko' => '한국어', + 'kr' => 'Kanuri', + 'ks' => 'कश्मीरी', + 'ku' => 'Kurdî', + 'kv' => 'коми кыв', + 'kw' => 'Kernewek', + 'ky' => 'кыргыз тили', + 'la' => 'Latine', + 'lb' => 'Lëtzebuergesch', + 'lg' => 'Luganda', + 'li' => 'Limburgs', + 'ln' => 'Lingála', + 'lo' => 'ພາສາລາວ', + 'lt' => 'Lietuvių kalba', + 'lu' => 'Luba-Katanga ', + 'lv' => 'Latviešu valoda', + 'mg' => 'Malagasy fiteny', + 'mh' => 'Kajin M̧ajeļ', + 'mi' => 'Te reo Māori', + 'mk' => 'македонски јазик', + 'ml' => 'മലയാളം', + 'mn' => 'Монгол', + 'mo' => 'Limba moldovenească', + 'mr' => 'मराठी', + 'ms' => 'Bahasa Melayu', + 'mt' => 'Malti', + 'my' => 'ဗမာစာ', + 'na' => 'Ekakairũ Naoero', + 'nb' => 'Norsk bokmål', + 'nd' => 'isiNdebele', + 'ne' => 'नेपाली', + 'ng' => 'Owambo', + 'nl' => 'Nederlands', + 'nl-be' => 'Nederlands (Belgium)', + 'nn' => 'Norsk nynorsk', + 'no' => 'Norsk', + 'nr' => 'Ndébélé', + 'nv' => 'Diné bizaad', + 'ny' => 'ChiCheŵa', + 'oc' => 'Occitan', + 'oj' => 'ᐊᓂᔑᓈᐯᒧᐎᓐ', + 'om' => 'Afaan Oromoo', + 'or' => 'ଓଡ଼ିଆ', + 'os' => 'Ирон æвзаг', + 'pa' => 'ਪੰਜਾਬੀ', + 'pi' => 'पाऴि', + 'pl' => 'Polski', + 'ps' => '‫پښتو', + 'pt' => 'Português', + 'pt-br' => 'Português (Brasil)', + 'qu' => 'Runa Simi', + 'rm' => 'Rumantsch grischun', + 'rn' => 'kiRundi', + 'ro' => 'Română', + 'ru' => 'Русский', + 'rw' => 'IKinyarwanda', + 'sa' => 'संस्कृतम्', + 'sc' => 'sardu', + 'sd' => 'सिन्धी', + 'se' => 'Davvisámegiella', + 'sg' => 'Yângâ tî sängö', + 'sh' => 'SrpskoHrvatski', + 'si' => 'සිංහල', + 'sk' => 'Slovenčina', + 'sl' => 'Slovenščina', + 'sm' => "Gagana fa'a Samoa", + 'sn' => 'chiShona', + 'so' => 'Soomaaliga', + 'sq' => 'Shqip', + 'sr' => 'српски језик', + 'ss' => 'SiSwati', + 'st' => 'seSotho', + 'su' => 'Basa Sunda', + 'sv' => 'Svenska', + 'sw' => 'Kiswahili', + 'ta' => 'தமிழ்', + 'te' => 'తెలుగు', + 'tg' => 'тоҷикӣ', + 'th' => 'ไทย', + 'ti' => 'ትግርኛ', + 'tk' => 'Türkmen', + 'tl' => 'Tagalog', + 'tn' => 'seTswana', + 'to' => 'faka Tonga', + 'tr' => 'Türkçe', + 'ts' => 'xiTsonga', + 'tt' => 'татарча', + 'tw' => 'Twi', + 'ty' => 'Reo Mā`ohi', + 'ug' => 'Uyƣurqə', + 'uk' => 'Українська', + 'ur' => '‫اردو', + 'uz' => "O'zbek", + 've' => 'tshiVenḓa', + 'vi' => 'Tiếng Việt', + 'vo' => 'Volapük', + 'wa' => 'Walon', + 'wo' => 'Wollof', + 'xh' => 'isiXhosa', + 'yi' => '‫ייִדיש', + 'yo' => 'Yorùbá', + 'za' => 'Saɯ cueŋƅ', + 'zh' => '中文', + 'zh-hk' => '中文 (香港)', + 'zh-tw' => '中文 (臺灣)', + 'zu' => 'isiZulu' + ); + } + + $langs = self::$langs; + if ($name_with_code) { + foreach ($langs as $k => &$v) { + $v = $k.' - '.$v; + } + } + + if ($flip) { + return array_flip($langs); + } + + return $langs; + } + + /** + * Text direction + * + * Returns text direction for a given language. + * If text direction was forced with {@link $text_direction}, returns this + * value. + * + * @param string $lang Language code + * @return string + */ + public static function getTextDirection($lang) + { + if (self::$text_direction) { + return self::$text_direction; + } + + if (preg_match('/^(ar|dv|fa|ha|he|ps|ur|yi)$/i',$lang)) { + return 'rtl'; + } + return 'ltr'; + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/libs/clearbricks/common/lib.text.php b/v2/dotclear/inc/libs/clearbricks/common/lib.text.php new file mode 100644 index 0000000..f4483cf --- /dev/null +++ b/v2/dotclear/inc/libs/clearbricks/common/lib.text.php @@ -0,0 +1,355 @@ + $p) { + $str = preg_replace('/['.$p.']/u',$r,$str); + } + + return $str; + } + + /** + * String to URL + * + * Transforms a string to a proper URL. + * + * @param string $str String to transform + * @param boolean $with_slashes Keep slashes in URL + * @return string + */ + public static function str2URL($str,$with_slashes=true) + { + $str = self::deaccent($str); + $str = preg_replace('/[^A-Za-z0-9_\s\'\:\/[\]-]/','',$str); + + return self::tidyURL($str,$with_slashes); + } + + /** + * URL cleanup + * + * @param string $str URL to tidy + * @param boolean $keep_slashes Keep slashes in URL + * @param boolean $keep_spaces Keep spaces in URL + * @return string + */ + public static function tidyURL($str,$keep_slashes=true,$keep_spaces=false) + { + $str = strip_tags($str); + $str = str_replace(array('?','&','#','=','+','<','>','"','%'),'',$str); + $str = str_replace("'",' ',$str); + $str = preg_replace('/[\s]+/u',' ',trim($str)); + + if (!$keep_slashes) { + $str = str_replace('/','-',$str); + } + + if (!$keep_spaces) { + $str = str_replace(' ','-',$str); + } + + $str = preg_replace('/[-]+/','-',$str); + + # Remove path changes in URL + $str = preg_replace('%^/%','',$str); + $str = preg_replace('%\.+/%','',$str); + + return $str; + } + + /** + * Cut string + * + * Returns a cuted string on spaced at given length $l. + * + * @param string $str String to cut + * @param integer $l Length to keep + * @return string + */ + public static function cutString($str,$l) + { + $s = preg_split('/([\s]+)/u',$str,-1,PREG_SPLIT_DELIM_CAPTURE); + + $res = ''; + $L = 0; + + if (mb_strlen($s[0]) >= $l) { + return mb_substr($s[0],0,$l); + } + + foreach ($s as $v) + { + $L = $L+mb_strlen($v); + + if ($L > $l) { + break; + } else { + $res .= $v; + } + } + + return trim($res); + } + + /** + * Split words + * + * Returns an array of words from a given string. + * + * @param string $str Words to split + * @return array + */ + public static function splitWords($str) + { + $non_word = '\x{0000}-\x{002F}\x{003A}-\x{0040}\x{005b}-\x{0060}\x{007B}-\x{007E}\x{00A0}-\x{00BF}\s'; + if (preg_match_all('/([^'.$non_word.']{3,})/msu',html::clean($str),$match)) { + foreach ($match[1] as $i => $v) { + $match[1][$i] = mb_strtolower($v); + } + return $match[1]; + } + return array(); + } + + /** + * Encoding detection + * + * Returns the encoding (in lowercase) of given $str. + * + * @param string $str String + * @return string + */ + public static function detectEncoding($str) + { + return strtolower(mb_detect_encoding($str.' ', + 'UTF-8,ISO-8859-1,ISO-8859-2,ISO-8859-3,'. + 'ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,'. + 'ISO-8859-9,ISO-8859-10,ISO-8859-13,ISO-8859-14,ISO-8859-15')); + } + + /** + * UTF8 conversions + * + * Returns an UTF-8 converted string. If $encoding is not specified, the + * function will try to detect encoding. + * + * @param string $str String to convert + * @param string $encoding Optionnal "from" encoding + * @return string + */ + public static function toUTF8($str,$encoding=null) + { + if (!$encoding) { + $encoding = self::detectEncoding($str); + } + + if ($encoding != 'utf-8') { + $str = iconv($encoding,'UTF-8',$str); + } + + return $str; + } + + /** + * Find bad UTF8 tokens + * + * Locates the first bad byte in a UTF-8 string returning it's + * byte index in the string + * PCRE Pattern to locate bad bytes in a UTF-8 string + * Comes from W3 FAQ: Multilingual Forms + * Note: modified to include full ASCII range including control chars + * + * @copyright Harry Fuecks + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html GNU LGPL 2.1 + * @link http://phputf8.sourceforge.net + * + * @param string $str String to search + * @return integer|false + */ + public static function utf8badFind($str) + { + $UTF8_BAD = + '([\x00-\x7F]'. # ASCII (including control chars) + '|[\xC2-\xDF][\x80-\xBF]'. # non-overlong 2-byte + '|\xE0[\xA0-\xBF][\x80-\xBF]'. # excluding overlongs + '|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}'. # straight 3-byte + '|\xED[\x80-\x9F][\x80-\xBF]'. # excluding surrogates + '|\xF0[\x90-\xBF][\x80-\xBF]{2}'. # planes 1-3 + '|[\xF1-\xF3][\x80-\xBF]{3}'. # planes 4-15 + '|\xF4[\x80-\x8F][\x80-\xBF]{2}'. # plane 16 + '|(.{1}))'; # invalid byte + $pos = 0; + $badList = array(); + + while (preg_match('/'.$UTF8_BAD.'/S', $str, $matches)) { + $bytes = strlen($matches[0]); + if ( isset($matches[2])) { + return $pos; + } + $pos += $bytes; + $str = substr($str,$bytes); + } + return false; + } + + /** + * UTF8 cleanup + * + * Replaces non utf8 bytes in $str by $repl. + * + * @copyright Harry Fuecks + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html GNU LGPL 2.1 + * @link http://phputf8.sourceforge.net + * + * @param string $str String to clean + * @param string $repl Replacement string + * @return string + */ + public static function cleanUTF8($str,$repl='?') + { + while (($bad_index = self::utf8badFind($str)) !== false) { + $str = substr_replace($str,$repl,$bad_index,1); + } + + return $str; + } + + /** + * BOM removal + * + * Removes BOM from the begining of a string if present. + * + * @param string $str String to clean + * @return string + */ + public static function removeBOM($str) + { + if (substr_count($str,'')) { + return str_replace('','',$str); + } + + return $str; + } + + /** + * Quoted printable conversion + * + * Encodes given str to quoted printable + * + * @param string $str String to encode + * @return string + */ + public static function QPEncode($str) + { + $res = ''; + + foreach (preg_split("/\r?\n/msu", $str) as $line) + { + $l = ''; + preg_match_all('/./',$line,$m); + + foreach ($m[0] as $c) + { + $a = ord($c); + + if ($a < 32 || $a == 61 || $a > 126) { + $c = sprintf('=%02X',$a); + } + + $l .= $c; + } + + $res .= $l."\r\n"; + } + return $res; + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/libs/clearbricks/common/tz.dat b/v2/dotclear/inc/libs/clearbricks/common/tz.dat new file mode 100644 index 0000000..09cc367 --- /dev/null +++ b/v2/dotclear/inc/libs/clearbricks/common/tz.dat @@ -0,0 +1,407 @@ +Africa/Abidjan +Africa/Accra +Africa/Addis_Ababa +Africa/Algiers +Africa/Asmera +Africa/Bamako +Africa/Bangui +Africa/Banjul +Africa/Bissau +Africa/Blantyre +Africa/Brazzaville +Africa/Bujumbura +Africa/Cairo +Africa/Casablanca +Africa/Ceuta +Africa/Conakry +Africa/Dakar +Africa/Dar_es_Salaam +Africa/Djibouti +Africa/Douala +Africa/El_Aaiun +Africa/Freetown +Africa/Gaborone +Africa/Harare +Africa/Johannesburg +Africa/Kampala +Africa/Khartoum +Africa/Kigali +Africa/Kinshasa +Africa/Lagos +Africa/Libreville +Africa/Lome +Africa/Luanda +Africa/Lubumbashi +Africa/Lusaka +Africa/Malabo +Africa/Maputo +Africa/Maseru +Africa/Mbabane +Africa/Mogadishu +Africa/Monrovia +Africa/Nairobi +Africa/Ndjamena +Africa/Niamey +Africa/Nouakchott +Africa/Ouagadougou +Africa/Porto-Novo +Africa/Sao_Tome +Africa/Timbuktu +Africa/Tripoli +Africa/Tunis +Africa/Windhoek + + +America/Adak +America/Anchorage +America/Anguilla +America/Antigua +America/Araguaina +America/Argentina/Buenos_Aires +America/Argentina/Catamarca +America/Argentina/ComodRivadavia +America/Argentina/Cordoba +America/Argentina/Jujuy +America/Argentina/La_Rioja +America/Argentina/Mendoza +America/Argentina/Rio_Gallegos +America/Argentina/San_Juan +America/Argentina/Tucuman +America/Argentina/Ushuaia +America/Aruba +America/Asuncion +America/Bahia +America/Barbados +America/Belem +America/Belize +America/Boa_Vista +America/Bogota +America/Boise +America/Cambridge_Bay +America/Campo_Grande +America/Cancun +America/Caracas +America/Cayenne +America/Cayman +America/Chicago +America/Chihuahua +America/Costa_Rica +America/Cuiaba +America/Curacao +America/Danmarkshavn +America/Dawson +America/Dawson_Creek +America/Denver +America/Detroit +America/Dominica +America/Edmonton +America/Eirunepe +America/El_Salvador +America/Fortaleza +America/Glace_Bay +America/Godthab +America/Goose_Bay +America/Grand_Turk +America/Grenada +America/Guadeloupe +America/Guatemala +America/Guayaquil +America/Guyana +America/Halifax +America/Havana +America/Hermosillo +America/Indiana/Indianapolis +America/Indiana/Knox +America/Indiana/Marengo +America/Indiana/Vevay +America/Indianapolis +America/Inuvik +America/Iqaluit +America/Jamaica +America/Juneau +America/Kentucky/Louisville +America/Kentucky/Monticello +America/La_Paz +America/Lima +America/Los_Angeles +America/Louisville +America/Maceio +America/Managua +America/Manaus +America/Martinique +America/Mazatlan +America/Menominee +America/Merida +America/Mexico_City +America/Miquelon +America/Monterrey +America/Montevideo +America/Montreal +America/Montserrat +America/Nassau +America/New_York +America/Nipigon +America/Nome +America/Noronha +America/North_Dakota/Center +America/Panama +America/Pangnirtung +America/Paramaribo +America/Phoenix +America/Port-au-Prince +America/Port_of_Spain +America/Porto_Velho +America/Puerto_Rico +America/Rainy_River +America/Rankin_Inlet +America/Recife +America/Regina +America/Rio_Branco +America/Santiago +America/Santo_Domingo +America/Sao_Paulo +America/Scoresbysund +America/Shiprock +America/St_Johns +America/St_Kitts +America/St_Lucia +America/St_Thomas +America/St_Vincent +America/Swift_Current +America/Tegucigalpa +America/Thule +America/Thunder_Bay +America/Tijuana +America/Toronto +America/Tortola +America/Vancouver +America/Whitehorse +America/Winnipeg +America/Yakutat +America/Yellowknife + + +Antarctica/Casey +Antarctica/Davis +Antarctica/DumontDUrville +Antarctica/Mawson +Antarctica/McMurdo +Antarctica/Palmer +Antarctica/Rothera +Antarctica/South_Pole +Antarctica/Syowa +Antarctica/Vostok + + +Arctic/Longyearbyen + + +Asia/Aden +Asia/Almaty +Asia/Amman +Asia/Anadyr +Asia/Aqtau +Asia/Aqtobe +Asia/Ashgabat +Asia/Baghdad +Asia/Bahrain +Asia/Baku +Asia/Bangkok +Asia/Beirut +Asia/Bishkek +Asia/Brunei +Asia/Calcutta +Asia/Choibalsan +Asia/Chongqing +Asia/Colombo +Asia/Damascus +Asia/Dhaka +Asia/Dili +Asia/Dubai +Asia/Dushanbe +Asia/Gaza +Asia/Harbin +Asia/Hong_Kong +Asia/Hovd +Asia/Irkutsk +Asia/Istanbul +Asia/Jakarta +Asia/Jayapura +Asia/Jerusalem +Asia/Kabul +Asia/Kamchatka +Asia/Karachi +Asia/Kashgar +Asia/Katmandu +Asia/Krasnoyarsk +Asia/Kuala_Lumpur +Asia/Kuching +Asia/Kuwait +Asia/Macau +Asia/Magadan +Asia/Makassar +Asia/Manila +Asia/Muscat +Asia/Nicosia +Asia/Novosibirsk +Asia/Omsk +Asia/Oral +Asia/Phnom_Penh +Asia/Pontianak +Asia/Pyongyang +Asia/Qatar +Asia/Qyzylorda +Asia/Rangoon +Asia/Riyadh +Asia/Saigon +Asia/Sakhalin +Asia/Samarkand +Asia/Seoul +Asia/Shanghai +Asia/Singapore +Asia/Taipei +Asia/Tashkent +Asia/Tbilisi +Asia/Tehran +Asia/Thimphu +Asia/Tokyo +Asia/Ulaanbaatar +Asia/Urumqi +Asia/Vientiane +Asia/Vladivostok +Asia/Yakutsk +Asia/Yekaterinburg +Asia/Yerevan + + +Atlantic/Azores +Atlantic/Bermuda +Atlantic/Canary +Atlantic/Cape_Verde +Atlantic/Faeroe +Atlantic/Jan_Mayen +Atlantic/Madeira +Atlantic/Reykjavik +Atlantic/South_Georgia +Atlantic/St_Helena +Atlantic/Stanley + + +Australia/Adelaide +Australia/Brisbane +Australia/Broken_Hill +Australia/Darwin +Australia/Hobart +Australia/Lindeman +Australia/Lord_Howe +Australia/Melbourne +Australia/Perth +Australia/Sydney + + +Europe/Amsterdam +Europe/Andorra +Europe/Athens +Europe/Belfast +Europe/Belgrade +Europe/Berlin +Europe/Bratislava +Europe/Brussels +Europe/Bucharest +Europe/Budapest +Europe/Chisinau +Europe/Copenhagen +Europe/Dublin +Europe/Gibraltar +Europe/Helsinki +Europe/Istanbul +Europe/Kaliningrad +Europe/Kiev +Europe/Lisbon +Europe/Ljubljana +Europe/London +Europe/Luxembourg +Europe/Madrid +Europe/Malta +Europe/Mariehamn +Europe/Minsk +Europe/Monaco +Europe/Moscow +Europe/Nicosia +Europe/Oslo +Europe/Paris +Europe/Prague +Europe/Riga +Europe/Rome +Europe/Samara +Europe/San_Marino +Europe/Sarajevo +Europe/Simferopol +Europe/Skopje +Europe/Sofia +Europe/Stockholm +Europe/Tallinn +Europe/Tirane +Europe/Uzhgorod +Europe/Vaduz +Europe/Vatican +Europe/Vienna +Europe/Vilnius +Europe/Warsaw +Europe/Zagreb +Europe/Zaporozhye +Europe/Zurich + + +Indian/Antananarivo +Indian/Chagos +Indian/Christmas +Indian/Cocos +Indian/Comoro +Indian/Kerguelen +Indian/Mahe +Indian/Maldives +Indian/Mauritius +Indian/Mayotte +Indian/Reunion + + +Pacific/Apia +Pacific/Auckland +Pacific/Chatham +Pacific/Easter +Pacific/Efate +Pacific/Enderbury +Pacific/Fakaofo +Pacific/Fiji +Pacific/Funafuti +Pacific/Galapagos +Pacific/Gambier +Pacific/Guadalcanal +Pacific/Guam +Pacific/Honolulu +Pacific/Johnston +Pacific/Kiritimati +Pacific/Kosrae +Pacific/Kwajalein +Pacific/Majuro +Pacific/Marquesas +Pacific/Midway +Pacific/Nauru +Pacific/Niue +Pacific/Norfolk +Pacific/Noumea +Pacific/Pago_Pago +Pacific/Palau +Pacific/Pitcairn +Pacific/Ponape +Pacific/Port_Moresby +Pacific/Rarotonga +Pacific/Saipan +Pacific/Tahiti +Pacific/Tarawa +Pacific/Tongatapu +Pacific/Truk +Pacific/Wake +Pacific/Wallis +Pacific/Yap \ No newline at end of file diff --git a/v2/dotclear/inc/libs/clearbricks/dblayer/class.cursor.php b/v2/dotclear/inc/libs/clearbricks/dblayer/class.cursor.php new file mode 100644 index 0000000..45b604f --- /dev/null +++ b/v2/dotclear/inc/libs/clearbricks/dblayer/class.cursor.php @@ -0,0 +1,258 @@ + + * openCursor('table'); + * $cur->field1 = 1; + * $cur->field2 = 'foo'; + * $cur->insert(); // Insert field ... + * + * $cur->update('WHERE field3 = 4'); // ... or update field + * ?> + *
        + * + * @see dbLayer::openCursor() + * @param dbLayer &$con Connection object + * @param string $table Table name + */ + public function __construct($con,$table) + { + $this->__con =& $con; + $this->setTable($table); + } + + /** + * Set table + * + * Changes working table and resets data + * + * @param string $table Table name + */ + public function setTable($table) + { + $this->__table = $table; + $this->__data = array(); + } + + /** + * Set field + * + * Set value $v to a field named $n. Value could be + * an string, an integer, a float, a null value or an array. + * + * If value is an array, its first value will be interpreted as a SQL + * command. String values will be automatically escaped. + * + * @see __set() + * @param string $n Field name + * @param mixed $v Field value + */ + public function setField($n,$v) + { + $this->__data[$n] = $v; + } + + /** + * Unset field + * + * Remove a field from data set. + * + * @param string $n Field name + */ + public function unsetField($n) + { + unset($this->__data[$n]); + } + + /** + * Field exists + * + * @return boolean true if field named $n exists + */ + public function isField($n) + { + return isset($this->__data[$n]); + } + + /** + * Field value + * + * @see __get() + * @return mixed value for a field named $n + */ + public function getField($n) + { + if (isset($this->__data[$n])) { + return $this->__data[$n]; + } + + return null; + } + + /** + * Set Field + * + * Magic alias for {@link setField()} + */ + public function __set($n,$v) + { + $this->setField($n,$v); + } + + /** + * Field value + * + * Magic alias for {@link getField()} + * + * @return mixed value for a field named $n + */ + public function __get($n) + { + return $this->getField($n); + } + + /** + * Empty data set + * + * Removes all data from data set + */ + public function clean() + { + $this->__data = array(); + } + + private function formatFields() + { + $data = array(); + + foreach ($this->__data as $k => $v) + { + $k = $this->__con->escapeSystem($k); + + if (is_null($v)) { + $data[$k] = 'NULL'; + } elseif (is_string($v)) { + $data[$k] = "'".$this->__con->escape($v)."'"; + } elseif (is_array($v)) { + $data[$k] = is_string($v[0]) ? "'".$this->__con->escape($v[0])."'" : $v[0]; + } else { + $data[$k] = $v; + } + } + + return $data; + } + + /** + * Get insert query + * + * Returns the generated INSERT query + * + * @return string + */ + public function getInsert() + { + $data = $this->formatFields(); + + $insReq = 'INSERT INTO '.$this->__con->escapeSystem($this->__table)." (\n". + implode(",\n",array_keys($data))."\n) VALUES (\n". + implode(",\n",array_values($data))."\n) "; + + return $insReq; + } + + /** + * Get update query + * + * Returns the generated UPDATE query + * + * @param string $where WHERE condition + * @return string + */ + public function getUpdate($where) + { + $data = $this->formatFields(); + $fields = array(); + + $updReq = 'UPDATE '.$this->__con->escapeSystem($this->__table)." SET \n"; + + foreach ($data as $k => $v) { + $fields[] = $k.' = '.$v.""; + } + + $updReq .= implode(",\n",$fields); + $updReq .= "\n".$where; + + return $updReq; + } + + /** + * Execute insert query + * + * Executes the generated INSERT query + */ + public function insert() + { + if (!$this->__table) { + throw new Exception('No table name.'); + } + + $insReq = $this->getInsert(); + + $this->__con->execute($insReq); + + return true; + } + + /** + * Execute update query + * + * Executes the generated UPDATE query + * + * @param string $where WHERE condition + */ + public function update($where) + { + if (!$this->__table) { + throw new Exception('No table name.'); + } + + $updReq = $this->getUpdate($where); + + $this->__con->execute($updReq); + + return true; + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/libs/clearbricks/dblayer/class.mysql.php b/v2/dotclear/inc/libs/clearbricks/dblayer/class.mysql.php new file mode 100644 index 0000000..5e68130 --- /dev/null +++ b/v2/dotclear/inc/libs/clearbricks/dblayer/class.mysql.php @@ -0,0 +1,253 @@ +db_post_connect($link,$database); + + return $link; + } + + /** @ignore */ + public function db_pconnect($host,$user,$password,$database) + { + if (!function_exists('mysql_pconnect')) { + throw new Exception('PHP MySQL functions are not available'); + } + + if (($link = @mysql_pconnect($host,$user,$password)) === false) { + throw new Exception('Unable to connect to database'); + } + + $this->db_post_connect($link,$database); + + return $link; + } + + /** @ignore */ + private function db_post_connect($link,$database) + { + if (@mysql_select_db($database,$link) === false) { + throw new Exception('Unable to use database '.$database); + } + + if (version_compare($this->db_version($link),'4.1','>=')) + { + $this->db_query($link,'SET NAMES utf8'); + $this->db_query($link,'SET CHARACTER SET utf8'); + $this->db_query($link,"SET COLLATION_CONNECTION = 'utf8_general_ci'"); + $this->db_query($link,"SET COLLATION_SERVER = 'utf8_general_ci'"); + $this->db_query($link,"SET CHARACTER_SET_SERVER = 'utf8'"); + $this->db_query($link,"SET CHARACTER_SET_DATABASE = 'utf8'"); + } + } + + /** @ignore */ + public function db_close($handle) + { + if (is_resource($handle)) { + mysql_close($handle); + } + } + + /** @ignore */ + public function db_version($handle) + { + if (is_resource($handle)) { + return mysql_get_server_info(); + } + return null; + } + + /** @ignore */ + public function db_query($handle,$query) + { + if (is_resource($handle)) + { + $res = @mysql_query($query,$handle); + if ($res === false) { + $e = new Exception($this->db_last_error($handle)); + $e->sql = $query; + throw $e; + } + return $res; + } + } + + /** @ignore */ + public function db_exec($handle,$query) + { + return $this->db_query($handle,$query); + } + + /** @ignore */ + public function db_num_fields($res) + { + if (is_resource($res)) { + return mysql_num_fields($res); + } + return 0; + } + + /** @ignore */ + public function db_num_rows($res) + { + if (is_resource($res)) { + return mysql_num_rows($res); + } + return 0; + } + + /** @ignore */ + public function db_field_name($res,$position) + { + if (is_resource($res)) { + return mysql_field_name($res,$position); + } + } + + /** @ignore */ + public function db_field_type($res,$position) + { + if (is_resource($res)) { + return mysql_field_type($res,$position); + } + } + + /** @ignore */ + public function db_fetch_assoc($res) + { + if (is_resource($res)) { + return mysql_fetch_assoc($res); + } + } + + /** @ignore */ + public function db_result_seek($res,$row) + { + if (is_resource($res)) { + return mysql_data_seek($res,$row); + } + } + + /** @ignore */ + public function db_changes($handle,$res) + { + if (is_resource($handle)) { + return mysql_affected_rows($handle); + } + } + + /** @ignore */ + public function db_last_error($handle) + { + if (is_resource($handle)) + { + $e = mysql_error($handle); + if ($e) { + return $e.' ('.mysql_errno($handle).')'; + } + } + return false; + } + + /** @ignore */ + public function db_escape_string($str,$handle=null) + { + if (is_resource($handle)) { + return mysql_real_escape_string($str,$handle); + } else { + return mysql_escape_string($str); + } + } + + /** @ignore */ + public function db_write_lock($table) + { + try { + $this->execute('LOCK TABLES '.$this->escapeSystem($table).' WRITE'); + } catch (Exception $e) { + # As lock is a privilege in MySQL, we can avoid errors with weak_locks static var + if (!self::$weak_locks) { + throw $e; + } + } + } + + /** @ignore */ + public function db_unlock() + { + try { + $this->execute('UNLOCK TABLES'); + } catch (Exception $e) { + if (!self::$weak_locks) { + throw $e; + } + } + } + + /** @ignore */ + public function vacuum($table) + { + $this->execute('OPTIMIZE TABLE '.$this->escapeSystem($table)); + } + + /** @ignore */ + public function dateFormat($field,$pattern) + { + $pattern = str_replace('%M','%i',$pattern); + + return 'DATE_FORMAT('.$field.','."'".$this->escape($pattern)."') "; + } + + /** @ignore */ + public function concat() + { + $args = func_get_args(); + return 'CONCAT('.implode(',',$args).')'; + } + + /** @ignore */ + public function escapeSystem($str) + { + return '`'.$str.'`'; + } + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/libs/clearbricks/dblayer/class.mysqli.php b/v2/dotclear/inc/libs/clearbricks/dblayer/class.mysqli.php new file mode 100644 index 0000000..cf6c9a7 --- /dev/null +++ b/v2/dotclear/inc/libs/clearbricks/dblayer/class.mysqli.php @@ -0,0 +1,284 @@ +db_post_connect($link,$database); + + return $link; + } + + /** @ignore */ + public function db_pconnect($host,$user,$password,$database) + { + // No pconnect wtih mysqli, below code is for comatibility + return $this->db_connect($host,$user,$password,$database); + } + + /** @ignore */ + private function db_post_connect($link,$database) + { + if (version_compare($this->db_version($link),'4.1','>=')) + { + $this->db_query($link,'SET NAMES utf8'); + $this->db_query($link,'SET CHARACTER SET utf8'); + $this->db_query($link,"SET COLLATION_CONNECTION = 'utf8_general_ci'"); + $this->db_query($link,"SET COLLATION_SERVER = 'utf8_general_ci'"); + $this->db_query($link,"SET CHARACTER_SET_SERVER = 'utf8'"); + $this->db_query($link,"SET CHARACTER_SET_DATABASE = 'utf8'"); + $link->set_charset("utf8"); + } + } + + /** @ignore */ + public function db_close($handle) + { + if ($handle instanceof MySQLi) { + mysqli_close($handle); + } + } + + /** @ignore */ + public function db_version($handle) + { + if ($handle instanceof MySQLi) { + return mysqli_get_server_info($handle); + } + return null; + } + + /** @ignore */ + public function db_query($handle,$query) + { + if ($handle instanceof MySQLi) + { + + $res = @mysqli_query($handle, $query); + if ($res === false) { + $e = new Exception($this->db_last_error($handle)); + $e->sql = $query; + throw $e; + } + return $res; + } + } + + /** @ignore */ + public function db_exec($handle,$query) + { + return $this->db_query($handle,$query); + } + + /** @ignore */ + public function db_num_fields($res) + { + if ($res instanceof MySQLi_Result) { + //return mysql_num_fields($res); + return $res->field_count; + } + return 0; + } + + /** @ignore */ + public function db_num_rows($res) + { + if ($res instanceof MySQLi_Result) { + return $res->num_rows; + } + return 0; + } + + /** @ignore */ + public function db_field_name($res,$position) + { + if ($res instanceof MySQLi_Result) { + $res->field_seek($position); + $finfo = $res->fetch_field(); + return $finfo->name; + } + } + + /** @ignore */ + public function db_field_type($res,$position) + { + if ($res instanceof MySQLi_Result) { + $res->field_seek($position); + $finfo = $res->fetch_field(); + return $this->_convert_types($finfo->type); + } + } + + /** @ignore */ + public function db_fetch_assoc($res) + { + if ($res instanceof MySQLi_Result) { + $v = $res->fetch_assoc(); + return($v === NULL) ? false : $v; + } + } + + /** @ignore */ + public function db_result_seek($res,$row) + { + if ($res instanceof MySQLi_Result) { + return $res->data_seek($row); + } + } + + /** @ignore */ + public function db_changes($handle,$res) + { + if ($handle instanceof MySQLi) { + return mysqli_affected_rows($handle); + } + } + + /** @ignore */ + public function db_last_error($handle) + { + if ($handle instanceof MySQLi) + { + $e = mysqli_error($handle); + if ($e) { + return $e.' ('.mysqli_errno($handle).')'; + } + } + return false; + } + + /** @ignore */ + public function db_escape_string($str,$handle=null) + { + if ($handle instanceof MySQLi) { + + return mysqli_real_escape_string($handle, $str); + } + return addslashes($str); + } + + /** @ignore */ + public function db_write_lock($table) + { + try { + $this->execute('LOCK TABLES '.$this->escapeSystem($table).' WRITE'); + } catch (Exception $e) { + # As lock is a privilege in MySQL, we can avoid errors with weak_locks static var + if (!self::$weak_locks) { + throw $e; + } + } + } + + /** @ignore */ + public function db_unlock() + { + try { + $this->execute('UNLOCK TABLES'); + } catch (Exception $e) { + if (!self::$weak_locks) { + throw $e; + } + } + } + + /** @ignore */ + public function vacuum($table) + { + $this->execute('OPTIMIZE TABLE '.$this->escapeSystem($table)); + } + + /** @ignore */ + public function dateFormat($field,$pattern) + { + $pattern = str_replace('%M','%i',$pattern); + + return 'DATE_FORMAT('.$field.','."'".$this->escape($pattern)."') "; + } + + /** @ignore */ + public function concat() + { + $args = func_get_args(); + return 'CONCAT('.implode(',',$args).')'; + } + + /** @ignore */ + public function escapeSystem($str) + { + return '`'.$str.'`'; + } + + protected function _convert_types($id) { + $id2type = array( + '1'=>'int', + '2'=>'int', + '3'=>'int', + '8'=>'int', + '9'=>'int', + + '16'=>'int', //BIT type recognized as unknown with mysql adapter + + '4'=>'real', + '5'=>'real', + '246'=>'real', + + '253'=>'string', + '254'=>'string', + + '10'=>'date', + '11'=>'time', + '12'=>'datetime', + '13'=>'year', + + '7'=>'timestamp', + + '252'=>'blob' + + ); + $type = 'unknown'; + + if(isset($id2type[$id])) $type = $id2type[$id]; + + return $type; + } + + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/libs/clearbricks/dblayer/class.pgsql.php b/v2/dotclear/inc/libs/clearbricks/dblayer/class.pgsql.php new file mode 100644 index 0000000..0f16b32 --- /dev/null +++ b/v2/dotclear/inc/libs/clearbricks/dblayer/class.pgsql.php @@ -0,0 +1,280 @@ +get_connection_string($host,$user,$password,$database); + + if (($link = @pg_connect($str)) === false) { + throw new Exception('Unable to connect to database'); + } + + return $link; + } + + /** @ignore */ + public function db_pconnect($host,$user,$password,$database) + { + if (!function_exists('pg_pconnect')) { + throw new Exception('PHP PostgreSQL functions are not available'); + } + + $str = $this->get_connection_string($host,$user,$password,$database); + + if (($link = @pg_pconnect($str)) === false) { + throw new Exception('Unable to connect to database'); + } + + return $link; + } + + /** @ignore */ + public function db_close($handle) + { + if (is_resource($handle)) { + pg_close($handle); + } + } + + /** @ignore */ + public function db_version($handle) + { + if (is_resource($handle)) + { + return pg_parameter_status($handle,'server_version'); + } + return null; + } + + /** @ignore */ + public function db_query($handle,$query) + { + if (is_resource($handle)) + { + $res = @pg_query($handle,$query); + if ($res === false) { + $e = new Exception($this->db_last_error($handle)); + $e->sql = $query; + throw $e; + } + return $res; + } + } + + /** @ignore */ + public function db_exec($handle,$query) + { + return $this->db_query($handle,$query); + } + + /** @ignore */ + public function db_num_fields($res) + { + if (is_resource($res)) { + return pg_num_fields($res); + } + return 0; + } + + /** @ignore */ + public function db_num_rows($res) + { + if (is_resource($res)) { + return pg_num_rows($res); + } + return 0; + } + + /** @ignore */ + public function db_field_name($res,$position) + { + if (is_resource($res)) { + return pg_field_name($res,$position); + } + } + + /** @ignore */ + public function db_field_type($res,$position) + { + if (is_resource($res)) { + return pg_field_type($res,$position); + } + } + + /** @ignore */ + public function db_fetch_assoc($res) + { + if (is_resource($res)) { + return pg_fetch_assoc($res); + } + } + + /** @ignore */ + public function db_result_seek($res,$row) + { + if (is_resource($res)) { + return pg_result_seek($res,(int) $row); + } + return false; + } + + /** @ignore */ + public function db_changes($handle,$res) + { + if (is_resource($handle) && is_resource($res)) { + return pg_affected_rows($res); + } + } + + /** @ignore */ + public function db_last_error($handle) + { + if (is_resource($handle)) { + return pg_last_error($handle); + } + return false; + } + + /** @ignore */ + public function db_escape_string($str,$handle=null) + { + return pg_escape_string($str); + } + + /** @ignore */ + public function db_write_lock($table) + { + $this->execute('BEGIN'); + $this->execute('LOCK TABLE '.$this->escapeSystem($table).' IN EXCLUSIVE MODE'); + } + + /** @ignore */ + public function db_unlock() + { + $this->execute('END'); + } + + /** @ignore */ + public function vacuum($table) + { + $this->execute('VACUUM FULL '.$this->escapeSystem($table)); + } + + /** @ignore */ + public function dateFormat($field,$pattern) + { + $rep = array( + '%d' => 'DD', + '%H' => 'HH24', + '%M' => 'MI', + '%m' => 'MM', + '%S' => 'SS', + '%Y' => 'YYYY' + ); + + $pattern = str_replace(array_keys($rep),array_values($rep),$pattern); + + return 'TO_CHAR('.$field.','."'".$this->escape($pattern)."') "; + } + + /** + * Function call + * + * Calls a PostgreSQL function an returns the result as a {@link record}. + * After $name, you can add any parameters you want to append + * them to the PostgreSQL function. You don't need to escape string in + * arguments. + * + * @param string $name Function name + * @return record + */ + public function callFunction($name) + { + $data = func_get_args(); + array_shift($data); + + foreach ($data as $k => $v) + { + if (is_null($v)) { + $data[$k] = 'NULL'; + } elseif (is_string($v)) { + $data[$k] = "'".$this->escape($v)."'"; + } elseif (is_array($v)) { + $data[$k] = $v[0]; + } else { + $data[$k] = $v; + } + } + + $req = + 'SELECT '.$name."(\n". + implode(",\n",array_values($data)). + "\n) "; + + return $this->select($req); + } + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/libs/clearbricks/dblayer/class.sqlite.php b/v2/dotclear/inc/libs/clearbricks/dblayer/class.sqlite.php new file mode 100644 index 0000000..eea52eb --- /dev/null +++ b/v2/dotclear/inc/libs/clearbricks/dblayer/class.sqlite.php @@ -0,0 +1,278 @@ +db_post_connect($link,$database); + + return $link; + } + + /** @ignore */ + public function db_pconnect($host,$user,$password,$database) + { + if (!class_exists('PDO') || !in_array('sqlite',PDO::getAvailableDrivers())) { + throw new Exception('PDO SQLite class is not available'); + } + + $link = new PDO('sqlite:'.$database,null,null,array(PDO::ATTR_PERSISTENT => true)); + $this->db_post_connect($link,$database); + + return $link; + } + + /** @ignore */ + private function db_post_connect($handle,$database) + { + if ($handle instanceof PDO) { + $this->db_exec($handle,'PRAGMA short_column_names = 1'); + $this->db_exec($handle,'PRAGMA encoding = "UTF-8"'); + $handle->sqliteCreateFunction('now',array($this,'now'),0); + } + } + + /** @ignore */ + public function db_close($handle) + { + if ($handle instanceof PDO) { + $handle = null; + $this->__link = null; + } + } + + /** @ignore */ + public function db_version($handle) + { + if ($handle instanceof PDO) { + return $handle->getAttribute(PDO::ATTR_SERVER_VERSION); + } + } + + # There is no other way than get all selected data in a staticRecord + /** @ignore */ + public function select($sql) + { + $result = $this->db_query($this->__link,$sql); + $this->__last_result =& $result; + + $info = array(); + $info['con'] =& $this; + $info['cols'] = $this->db_num_fields($result); + $info['info'] = array(); + + for ($i=0; $i<$info['cols']; $i++) { + $info['info']['name'][] = $this->db_field_name($result,$i); + $info['info']['type'][] = $this->db_field_type($result,$i); + } + + $data = array(); + while ($r = $result->fetch(PDO::FETCH_ASSOC)) + { + $R = array(); + foreach ($r as $k => $v) { + $k = preg_replace('/^(.*)\./','',$k); + $R[$k] = $v; + $R[] =& $R[$k]; + } + $data[] = $R; + } + + $info['rows'] = count($data); + $result->closeCursor(); + + return new staticRecord($data,$info); + } + + /** @ignore */ + public function db_query($handle,$query) + { + if ($handle instanceof PDO) + { + $res = $handle->query($query); + if ($res === false) { + $e = new Exception($this->db_last_error($handle)); + $e->sql = $query; + throw $e; + } + + return $res; + } + } + + /** @ignore */ + public function db_exec($handle,$query) + { + return $this->db_query($handle,$query); + } + + /** @ignore */ + public function db_num_fields($res) + { + if ($res instanceof PDOStatement) { + return $res->columnCount(); + } + return 0; + } + + /** @ignore */ + public function db_num_rows($res) + { + } + + /** @ignore */ + public function db_field_name($res,$position) + { + if ($res instanceof PDOStatement) { + $m = $res->getColumnMeta($position); + return preg_replace('/^.+\./','',$m['name']); # we said short_column_names = 1 + } + } + + /** @ignore */ + public function db_field_type($res,$position) + { + if ($res instanceof PDOStatement) { + $m = $res->getColumnMeta($position); + switch ($m['pdo_type']) { + case PDO::PARAM_BOOL: + return 'boolean'; + case PDO::PARAM_NULL: + return 'null'; + case PDO::PARAM_INT: + return 'integer'; + default: + return 'varchar'; + } + } + } + + /** @ignore */ + public function db_fetch_assoc($res) + { + } + + /** @ignore */ + public function db_result_seek($res,$row) + { + } + + /** @ignore */ + public function db_changes($handle,$res) + { + if ($res instanceof PDOStatement) { + return $res->rowCount(); + } + } + + /** @ignore */ + public function db_last_error($handle) + { + if ($handle instanceof PDO) { + $err = $handle->errorInfo(); + return $err[2].' ('.$err[1].')'; + } + return false; + } + + /** @ignore */ + public function db_escape_string($str,$handle=null) + { + if ($handle instanceof PDO) { + return trim($handle->quote($str),"'"); + } + return $str; + } + + /** @ignore */ + public function escapeSystem($str) + { + return "'".$this->escape($str)."'"; + } + + /** @ignore */ + public function begin() + { + if ($this->__link instanceof PDO) { + $this->__link->beginTransaction(); + } + } + + /** @ignore */ + public function commit() + { + if ($this->__link instanceof PDO) { + $this->__link->commit(); + } + } + + /** @ignore */ + public function rollback() + { + if ($this->__link instanceof PDO) { + $this->__link->rollBack(); + } + } + + /** @ignore */ + public function db_write_lock($table) + { + $this->execute('BEGIN EXCLUSIVE TRANSACTION'); + } + + /** @ignore */ + public function db_unlock() + { + $this->execute('END'); + } + + /** @ignore */ + public function vacuum($table) + { + $this->execute('VACUUM '.$this->escapeSystem($table)); + } + + /** @ignore */ + public function dateFormat($field,$pattern) + { + return "strftime('".$this->escape($pattern)."',".$field.') '; + } + + # Internal SQLite function that adds NOW() SQL function. + /** @ignore */ + public function now() + { + return date('Y-m-d H:i:s'); + } + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/libs/clearbricks/dblayer/dblayer.php b/v2/dotclear/inc/libs/clearbricks/dblayer/dblayer.php new file mode 100644 index 0000000..21f1b8d --- /dev/null +++ b/v2/dotclear/inc/libs/clearbricks/dblayer/dblayer.php @@ -0,0 +1,1208 @@ +$position. + * + * @param resource $res Resource result + * @param integer $position Field position + * @return string + */ + function db_field_name($res,$position); + + /** + * Field type + * + * This method should return the field type a the given position + * $position. + * + * @param resource $res Resource result + * @param integer $position Field position + * @return string + */ + function db_field_type($res,$position); + + /** + * Fetch result + * + * This method should fetch one line of result and return an associative array + * with field name as key and field value as value. + * + * @param resource $res Resource result + * @return array + */ + function db_fetch_assoc($res); + + /** + * Move result cursor + * + * This method should move result cursor on given row position $row + * and return true on success. + * + * @param resource $res Resource result + * @param integer $position Row position + * @return boolean + */ + function db_result_seek($res,$row); + + /** + * Affected rows + * + * This method should return number of rows affected by INSERT, UPDATE or + * DELETE queries. + * + * @param resource $handle Resource link + * @param resource $res Resource result + * @return integer + */ + function db_changes($handle,$res); + + /** + * Last error + * + * This method should return the last error string for the current connection. + * + * @param resource $handle Resource link + * @return string + */ + function db_last_error($handle); + + /** + * Escape string + * + * This method should return an escaped string for the current connection. + * + * @param string $str String to escape + * @param resource $handle Resource link + * @return string + */ + function db_escape_string($str,$handle=null); + + /** + * Acquiere Write lock + * + * This method should lock the given table in write access. + * + * @param string $table Table name + */ + function db_write_lock($table); + + /** + * Release lock + * + * This method should releases an acquiered lock. + */ + function db_unlock(); +} + +/** +* Database Abstraction Layer class +* +* Base class for database abstraction. Each driver extends this class and +* implements {@link i_dbLayer} interface. +* +* @package Clearbricks +* @subpackage DBLayer +*/ +class dbLayer +{ + /** @var string Driver name */ + protected $__driver = null; + + /** @var string Database version */ + protected $__version = null; + + /** @var resource Database resource link */ + protected $__link; + + /** @var resource Last result resource link */ + protected $__last_result; + + /** + * Start connection + * + * Static function to use to init database layer. Returns a object extending + * dbLayer. + * + * @param string $driver Driver name + * @param string $host Database hostname + * @param string $database Database name + * @param string $user User ID + * @param string $password Password + * @param string $persistent Persistent connection + * @return object + */ + public static function init($driver,$host,$database,$user='',$password='',$persistent=false) + { + if (file_exists(dirname(__FILE__).'/class.'.$driver.'.php')) { + require_once dirname(__FILE__).'/class.'.$driver.'.php'; + $driver_class = $driver.'Connection'; + } else { + trigger_error('Unable to load DB layer for '.$driver,E_USER_ERROR); + exit(1); + } + + return new $driver_class($host,$database,$user,$password,$persistent); + } + + /** + * @param string $host Database hostname + * @param string $database Database name + * @param string $user User ID + * @param string $password Password + * @param string $persistent Persistent connection + */ + public function __construct($host,$database,$user='',$password='',$persistent=false) + { + if ($persistent) { + $this->__link = $this->db_pconnect($host,$user,$password,$database); + } else { + $this->__link = $this->db_connect($host,$user,$password,$database); + } + + $this->__version = $this->db_version($this->__link); + $this->__database = $database; + } + + /** + * Closes database connection. + */ + public function close() + { + $this->db_close($this->__link); + } + + /** + * Returns database driver name + * + * @return string + */ + public function driver() + { + return $this->__driver; + } + + /** + * Returns database driver version + * + * @return string + */ + public function version() + { + return $this->__version; + } + + /** + * Returns current database name + * + * @return string + */ + public function database() + { + return $this->__database; + } + + /** + * Returns link resource + * + * @return resource + */ + public function link() + { + return $this->__link; + } + + /** + * Run query and get results + * + * Executes a query and return a {@link record} object. + * + * @param string $sql SQL query + * @return record + */ + public function select($sql) + { + $result = $this->db_query($this->__link,$sql); + + $this->__last_result =& $result; + + $info = array(); + $info['con'] =& $this; + $info['cols'] = $this->db_num_fields($result); + $info['rows'] = $this->db_num_rows($result); + $info['info'] = array(); + + for ($i=0; $i<$info['cols']; $i++) { + $info['info']['name'][] = $this->db_field_name($result,$i); + $info['info']['type'][] = $this->db_field_type($result,$i); + } + + return new record($result,$info); + } + + /** + * Run query + * + * Executes a query and return true if succeed + * + * @param string $sql SQL query + * @return true + */ + public function execute($sql) + { + $result = $this->db_exec($this->__link,$sql); + + $this->__last_result =& $result; + + return true; + } + + /** + * Begin transaction + * + * Begins a transaction. Transaction should be {@link commit() commited} + * or {@link rollback() rollbacked}. + */ + public function begin() + { + $this->execute('BEGIN'); + } + + /** + * Commit transaction + * + * Commits a previoulsy started transaction. + */ + public function commit() + { + $this->execute('COMMIT'); + } + + /** + * Rollback transaction + * + * Rollbacks a previously started transaction. + */ + public function rollback() + { + $this->execute('ROLLBACK'); + } + + /** + * Aquiere write lock + * + * This method lock the given table in write access. + * + * @param string $table Table name + */ + public function writeLock($table) + { + $this->db_write_lock($table); + } + + /** + * Release lock + * + * This method releases an acquiered lock. + */ + public function unlock() + { + $this->db_unlock(); + } + + /** + * Vacuum the table given in argument. + * + * @param string $table Table name + */ + public function vacuum($table) + { + } + + /** + * Changed rows + * + * Returns the number of lines affected by the last DELETE, INSERT or UPDATE + * query. + * + * @return integer + */ + public function changes() + { + return $this->db_changes($this->__link,$this->__last_result); + } + + /** + * Last error + * + * Returns the last database error or false if no error. + * + * @return string|false + */ + public function error() + { + $err = $this->db_last_error($this->__link); + + if (!$err) { + return false; + } + + return $err; + } + + /** + * Date formatting + * + * Returns a query fragment with date formater. + * + * The following modifiers are accepted: + * + * - %d : Day of the month, numeric + * - %H : Hour 24 (00..23) + * - %M : Minute (00..59) + * - %m : Month numeric (01..12) + * - %S : Seconds (00..59) + * - %Y : Year, numeric, four digits + * + * @param string $field Field name + * @param string $pattern Date format + * @return string + */ + public function dateFormat($field,$pattern) + { + return + 'TO_CHAR('.$field.','."'".$this->escape($pattern)."') "; + } + + /** + * Query Limit + * + * Returns a LIMIT query fragment. $arg1 could be an array of + * offset and limit or an integer which is only limit. If $arg2 + * is given and $arg1 is an integer, it would become limit. + * + * @param array|integer $arg1 array or integer with limit intervals + * @param array|null $arg2 integer or null + * @return string + */ + public function limit($arg1, $arg2=null) + { + if (is_array($arg1)) + { + $arg1 = array_values($arg1); + $arg2 = isset($arg1[1]) ? $arg1[1] : null; + $arg1 = $arg1[0]; + } + + if ($arg2 === null) { + $sql = ' LIMIT '.(integer) $arg1.' '; + } else { + $sql = ' LIMIT '.(integer) $arg2.' OFFSET '.(integer) $arg1.' '; + } + + return $sql; + } + + /** + * IN fragment + * + * Returns a IN query fragment where $in could be an array, a string, + * an integer or null + * + * @param array|string|integer|null $in "IN" values + * @return string + */ + public function in($in) + { + if (is_null($in)) + { + return ' IN (NULL) '; + } + elseif (is_string($in)) + { + return " IN ('".$this->escape($in)."') "; + } + elseif (is_array($in)) + { + foreach ($in as $i => $v) { + if (is_null($v)) { + $in[$i] = 'NULL'; + } elseif (is_string($v)) { + $in[$i] = "'".$this->escape($v)."'"; + } + } + return ' IN ('.implode(',',$in).') '; + } + else + { + return ' IN ( '.(integer) $in.') '; + } + } + + /** + * Concat strings + * + * Returns SQL concatenation of methods arguments. Theses arguments + * should be properly escaped when needed. + * + * @return string + */ + public function concat() + { + $args = func_get_args(); + return implode(' || ',$args); + } + + /** + * Escape string + * + * Returns SQL protected string or array values. + * + * @param string|array $i String or array to protect + * @return string|array + */ + public function escape($i) + { + if (is_array($i)) { + foreach ($i as $k => $s) { + $i[$k] = $this->db_escape_string($s,$this->__link); + } + return $i; + } + + return $this->db_escape_string($i,$this->__link); + } + + /** + * System escape string + * + * Returns SQL system protected string. + * + * @param string $str String to protect + * @return string + */ + public function escapeSystem($str) + { + return '"'.$str.'"'; + } + + /** + * Cursor object + * + * Returns a new instance of {@link cursor} class on $table for + * the current connection. + * + * @param string $table Target table + * @return cursor + */ + public function openCursor($table) + { + return new cursor($this,$table); + } +} + +/** +* Query Result Record Class +* +* This class acts as an iterator over database query result. It does not fetch +* all results on instantiation and thus, depending on database engine, should not +* fill PHP process memory. +* +* @package Clearbricks +* @subpackage DBLayer +*/ +class record implements Iterator, Countable +{ + /** @var resource Database resource link */ + protected $__link; + + /** @var resource Query result resource */ + protected $__result; + + /** @var array Result information array */ + protected $__info; + + /** @var array List of static functions that extend record */ + protected $__extend = array(); + + /** @var integer Current result position */ + protected $__index = 0; + + /** @var array Current result row content */ + protected $__row = false; + + private $__fetch = false; + + /** + * Constructor + * + * Creates class instance from result link and some informations. + * $info is an array with the following content: + * + * - con => database object instance + * - cols => number of columns + * - rows => number of rows + * - info[name] => an array with columns names + * - info[type] => an array with columns types + * + * @param resource $result Resource result + * @param array $info Information array + */ + public function __construct($result,$info) + { + $this->__result = $result; + $this->__info = $info; + $this->__link = $info['con']->link(); + $this->index(0); + } + + /** + * To staticRecord + * + * Converts this record to a {@link staticRecord} instance. + */ + public function toStatic() + { + if ($this instanceof staticRecord) { + return $this; + } + return new staticRecord($this->__result,$this->__info); + } + + /** + * Magic call + * + * Magic call function. Calls function added by {@link extend()} if exists, passing it + * self object and arguments. + * + * @return mixed + */ + public function __call($f,$args) + { + if (isset($this->__extend[$f])) + { + array_unshift($args,$this); + return call_user_func_array($this->__extend[$f],$args); + } + + trigger_error('Call to undefined method record::'.$f.'()',E_USER_ERROR); + } + + /** + * Magic get + * + * Alias for {@link field()}. + * + * @param string|integer $n Field name + * @return string + */ + public function __get($n) + { + return $this->field($n); + } + + /** + * Get field + * + * Alias for {@link field()}. + * + * @param string|integer $n Field name + * @return string + */ + public function f($n) + { + return $this->field($n); + } + + /** + * Get field + * + * Retrieve field value by its name or column position. + * + * @param string|integer $n Field name + * @return string + */ + public function field($n) + { + return $this->__row[$n]; + } + + /** + * Field exists + * + * Returns true if a field exists. + * + * @param string $n Field name + * @return string + */ + public function exists($n) + { + return isset($this->__row[$n]); + } + + /** + * Field isset + * + * Returns true if a field exists (magic method from PHP 5.1). + * + * @param string $n Field name + * @return string + */ + public function __isset($n) + { + return isset($this->__row[$n]); + } + + /** + * Extend record + * + * Extends this instance capabilities by adding all public static methods of + * $class to current instance. Class methods should take at least + * this record as first parameter. + * + * @see __call() + * + * @param string $class Class name + */ + public function extend($class) + { + if (!class_exists($class)) { + return; + } + + $c = new ReflectionClass($class); + foreach ($c->getMethods() as $m) { + if ($m->isStatic() && $m->isPublic()) { + $this->__extend[$m->name] = array($class,$m->name); + } + } + } + + /** + * Returns record extensions. + * + * @return array + */ + public function extensions() + { + return $this->__extend; + } + + private function setRow() + { + $this->__row = $this->__info['con']->db_fetch_assoc($this->__result); + + if ($this->__row !== false) + { + foreach ($this->__row as $k => $v) { + $this->__row[] =& $this->__row[$k]; + } + return true; + } + else + { + return false; + } + } + + /** + * Returns the current index position (0 is first) or move to $row if + * specified. + * + * @param integer $row Row number to move + * @return integer + */ + public function index($row=null) + { + if ($row === null) { + return $this->__index === null ? 0 : $this->__index; + } + + if ($row < 0 || $row+1 > $this->__info['rows']) { + return false; + } + + if ($this->__info['con']->db_result_seek($this->__result,(integer) $row)) + { + $this->__index = $row; + $this->setRow(); + $this->__info['con']->db_result_seek($this->__result,(integer) $row); + return true; + } + return false; + } + + /** + * One step move index + * + * This method moves index forward and return true until index is not + * the last one. You can use it to loop over record. Example: + * + * fetch()) { + * echo $rs->field1; + * } + * ?> + * + * + * @return boolean + */ + public function fetch() + { + if (!$this->__fetch) { + $this->__fetch = true; + $i = -1; + } else { + $i = $this->__index; + } + + if (!$this->index($i+1)) { + $this->__fetch = false; + $this->__index = 0; + return false; + } + + return true; + } + + /** + * Moves index to first position. + * + * @return boolean + */ + public function moveStart() + { + $this->__fetch = false; + return $this->index(0); + } + + /** + * Moves index to last position. + * + * @return boolean + */ + public function moveEnd() + { + return $this->index($this->__info['rows']-1); + } + + /** + * Moves index to next position. + * + * @return boolean + */ + public function moveNext() + { + return $this->index($this->__index+1); + } + + /** + * Moves index to previous position. + * + * @return boolean + */ + public function movePrev() + { + return $this->index($this->__index-1); + } + + /** + * @return boolean true if index is at last position + */ + public function isEnd() + { + return $this->__index+1 == $this->count(); + } + + /** + * @return boolean true if index is at first position. + */ + public function isStart() + { + return $this->__index <= 0; + } + + /** + * @return boolean true if record contains no result. + */ + public function isEmpty() + { + return $this->count() == 0; + } + + /** + * @return integer number of rows in record + */ + public function count() + { + return $this->__info['rows']; + } + + /** + * @return array array of columns, with name as key and type as value. + */ + public function columns() + { + return $this->__info['info']['name']; + } + + /** + * @return array all rows in record. + */ + public function rows() + { + return $this->getData(); + } + + /** + * All data + * + * Returns an array of all rows in record. This method is called by rows(). + * + * @return array + */ + protected function getData() + { + $res = array(); + + if ($this->count() == 0) { + return $res; + } + + $this->__info['con']->db_result_seek($this->__result,0); + while (($r = $this->__info['con']->db_fetch_assoc($this->__result)) !== false) { + foreach ($r as $k => $v) { + $r[] =& $r[$k]; + } + $res[] = $r; + } + $this->__info['con']->db_result_seek($this->__result,$this->__index); + + return $res; + } + + /** + * @return array current rows. + */ + public function row() + { + return $this->__row; + } + + /* Iterator methods */ + + /** + * @see Iterator::current + */ + public function current() { + return $this; + } + + /** + * @see Iterator::key + */ + public function key() + { + return $this->index(); + } + /** + * @see Iterator::next + */ + public function next() + { + $this->fetch(); + } + + /** + * @see Iterator::rewind + */ + public function rewind() + { + $this->moveStart(); + $this->fetch(); + } + + /** + * @see Iterator::valid + */ + public function valid () + { + return $this->__fetch; + } + +} + +/** +* Query Result Static Record Class +* +* Unlike record class, this one contains all results in an associative array. +* +* @package Clearbricks +* @subpackage DBLayer +*/ +class staticRecord extends record +{ + /** @var array Data array */ + public $__data = array(); + + private $__sortfield; + private $__sortsign; + + /** @ignore */ + public function __construct($result,$info) + { + if (is_array($result)) + { + $this->__info = $info; + $this->__data = $result; + } + else + { + parent::__construct($result,$info); + $this->__data = parent::getData(); + } + + unset($this->__link); + unset($this->__result); + } + + /** + * Static record from array + * + * Returns a new instance of object from an associative array. + * + * @param array $data Data array + * @return staticRecord + */ + public static function newFromArray($data) + { + if (!is_array($data)) { + $data = array(); + } + + $data = array_values($data); + + if (empty($data) || !is_array($data[0])) { + $cols = 0; + } else { + $cols = count($data[0]); + } + + $info = array( + 'con' => null, + 'info' => null, + 'cols' => $cols, + 'rows' => count($data) + ); + + return new self($data,$info); + } + + /** @ignore */ + public function field($n) + { + return $this->__data[$this->__index][$n]; + } + + /** @ignore */ + public function exists($n) + { + return isset($this->__data[$this->__index][$n]); + } + + /** @ignore */ + public function index($row=null) + { + if ($row === null) { + return $this->__index; + } + + if ($row < 0 || $row+1 > $this->__info['rows']) { + return false; + } + + $this->__index = $row; + return true; + } + + /** @ignore */ + public function rows() + { + return $this->__data; + } + + /** + * Changes value of a given field in the current row. + * + * @param string $n Field name + * @param string $v Field value + */ + public function set($n,$v) + { + if ($this->__index === null) { + return false; + } + + $this->__data[$this->__index][$n] = $v; + } + + /** + * Sorts values by a field in a given order. + * + * @param string $field Field name + * @param string $order Sort type (asc or desc) + */ + public function sort($field,$order='asc') + { + if (!isset($this->__data[0][$field])) { + return false; + } + + $this->__sortfield = $field; + $this->__sortsign = strtolower($order) == 'asc' ? 1 : -1; + + usort($this->__data,array($this,'sortCallback')); + + $this->__sortfield = null; + $this->__sortsign = null; + } + + private function sortCallback($a,$b) + { + $a = $a[$this->__sortfield]; + $b = $b[$this->__sortfield]; + + # Integer values + if ($a == (string) (integer) $a && $b == (string) (integer) $b) { + $a = (integer) $a; + $b = (integer) $b; + return ($a - $b) * $this->__sortsign; + } + + return strcmp($a,$b) * $this->__sortsign; + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/libs/clearbricks/dbschema/class.dbschema.php b/v2/dotclear/inc/libs/clearbricks/dbschema/class.dbschema.php new file mode 100644 index 0000000..6a6bb47 --- /dev/null +++ b/v2/dotclear/inc/libs/clearbricks/dbschema/class.dbschema.php @@ -0,0 +1,310 @@ +array + */ + function db_get_tables(); + + /** + This method should return an associative array of columns in given table + $table with column names in keys. Each line value is an array + with following values: + + - [type] data type (string) + - [len] data length (integer or null) + - [null] is null? (boolean) + - [default] default value (string) + + @param table string Table name + @return array + */ + function db_get_columns($table); + + /** + This method should return an array of keys in given table + $table. Each line value is an array with following values: + + - [name] index name (string) + - [primary] primary key (boolean) + - [unique] unique key (boolean) + - [cols] columns (array) + + @param table string Table name + @return array + */ + function db_get_keys($table); + + /** + This method should return an array of indexes in given table + $table. Each line value is an array with following values: + + - [name] index name (string) + - [type] index type (string) + - [cols] columns (array) + + @param table string Table name + @return array + */ + function db_get_indexes($table); + + /** + This method should return an array of foreign keys in given table + $table. Each line value is an array with following values: + + - [name] key name (string) + - [c_cols] child columns (array) + - [p_table] parent table (string) + - [p_cols] parent columns (array) + - [update] on update statement (string) + - [delete] on delete statement (string) + + @param table string Table name + @return array + */ + function db_get_references($table); + + function db_create_table($name,$fields); + + function db_create_field($table,$name,$type,$len,$null,$default); + + function db_create_primary($table,$name,$cols); + + function db_create_unique($table,$name,$cols); + + function db_create_index($table,$name,$type,$cols); + + function db_create_reference($name,$c_table,$c_cols,$p_table,$p_cols,$update,$delete); + + function db_alter_field($table,$name,$type,$len,$null,$default); + + function db_alter_primary($table,$name,$newname,$cols); + + function db_alter_unique($table,$name,$newname,$cols); + + function db_alter_index($table,$name,$newname,$type,$cols); + + function db_alter_reference($name,$newname,$c_table,$c_cols,$p_table,$p_cols,$update,$delete); + + function db_drop_unique($table,$name); +} + +class dbSchema +{ + protected $con; + + public function __construct($con) + { + $this->con =& $con; + } + + public static function init($con) + { + $driver = $con->driver(); + $driver_class = $driver.'Schema'; + + if (!class_exists($driver_class)) + { + if (file_exists(dirname(__FILE__).'/class.'.$driver.'.dbschema.php')) { + require dirname(__FILE__).'/class.'.$driver.'.dbschema.php'; + } else { + trigger_error('Unable to load DB schema layer for '.$driver,E_USER_ERROR); + exit(1); + } + } + + return new $driver_class($con); + } + + /** + Database data type to universal data type conversion. + + @param type string Type name + @param leng integer Field length (in/out) + @param default string Default field value (in/out) + @return string + */ + public function dbt2udt($type,&$len,&$default) + { + $c = array( + 'bool' => 'boolean', + 'int2' => 'smallint', + 'int' => 'integer', + 'int4' => 'integer', + 'int8' => 'bigint', + 'float4' => 'real', + 'double precision' => 'float', + 'float8' => 'float', + 'decimal' => 'numeric', + 'character varying' => 'varchar', + 'character' => 'char' + ); + + if (isset($c[$type])) { + return $c[$type]; + } + + return $type; + } + + /** + Universal data type to database data tye conversion. + + @param type string Type name + @param leng integer Field length (in/out) + @param default string Default field value (in/out) + @return string + */ + public function udt2dbt($type,&$len,&$default) + { + return $type; + } + + /** + Returns an array of all table names. + + @see i_dbSchema::db_get_tables + @return array + */ + public function getTables() + { + return $this->db_get_tables(); + } + + /** + Returns an array of columns (name and type) of a given table. + + @see i_dbSchema::db_get_columns + @param table string Table name + @return array + */ + public function getColumns($table) + { + return $this->db_get_columns($table); + } + + /** + Returns an array of index of a given table. + + @see i_dbSchema::db_get_keys + @param table string Table name + @return array + */ + public function getKeys($table) + { + return $this->db_get_keys($table); + } + + /** + Returns an array of indexes of a given table. + + @see i_dbSchema::db_get_index + @param table string Table name + @return array + */ + public function getIndexes($table) + { + return $this->db_get_indexes($table); + } + + /** + Returns an array of foreign keys of a given table. + + @see i_dbSchema::db_get_references + @param table string Table name + @return array + */ + public function getReferences($table) + { + return $this->db_get_references($table); + } + + public function createTable($name,$fields) + { + return $this->db_create_table($name,$fields); + } + + public function createField($table,$name,$type,$len,$null,$default) + { + return $this->db_create_field($table,$name,$type,$len,$null,$default); + } + + public function createPrimary($table,$name,$cols) + { + return $this->db_create_primary($table,$name,$cols); + } + + public function createUnique($table,$name,$cols) + { + return $this->db_create_unique($table,$name,$cols); + } + + public function createIndex($table,$name,$type,$cols) + { + return $this->db_create_index($table,$name,$type,$cols); + } + + public function createReference($name,$c_table,$c_cols,$p_table,$p_cols,$update,$delete) + { + return $this->db_create_reference($name,$c_table,$c_cols,$p_table,$p_cols,$update,$delete); + } + + public function alterField($table,$name,$type,$len,$null,$default) + { + return $this->db_alter_field($table,$name,$type,$len,$null,$default); + } + + public function alterPrimary($table,$name,$newname,$cols) + { + return $this->db_alter_primary($table,$name,$newname,$cols); + } + + public function alterUnique($table,$name,$newname,$cols) + { + return $this->db_alter_unique($table,$name,$newname,$cols); + } + + public function alterIndex($table,$name,$newname,$type,$cols) + { + return $this->db_alter_index($table,$name,$newname,$type,$cols); + } + + public function alterReference($name,$newname,$c_table,$c_cols,$p_table,$p_cols,$update,$delete) + { + return $this->db_alter_reference($name,$newname,$c_table,$c_cols,$p_table,$p_cols,$update,$delete); + } + + public function dropUnique($table,$name) + { + return $this->db_drop_unique($table,$name); + } + + public function flushStack() + { + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/libs/clearbricks/dbschema/class.dbstruct.php b/v2/dotclear/inc/libs/clearbricks/dbschema/class.dbstruct.php new file mode 100644 index 0000000..2b76012 --- /dev/null +++ b/v2/dotclear/inc/libs/clearbricks/dbschema/class.dbstruct.php @@ -0,0 +1,639 @@ +con =& $con; + $this->prefix = $prefix; + } + + public function driver() + { + return $this->con->driver(); + } + + public function table($name) + { + $this->tables[$name] = new dbStructTable($name); + return $this->tables[$name]; + } + + public function __get($name) + { + if (!isset($this->tables[$name])) { + return $this->table($name); + } + + return $this->tables[$name]; + } + + public function reverse() + { + $schema = dbSchema::init($this->con); + + # Get tables + $tables = $schema->getTables(); + + foreach ($tables as $t_name) + { + if ($this->prefix && strpos($t_name,$this->prefix) !== 0) { + continue; + } + + $t = $this->table($t_name); + + # Get columns + $cols = $schema->getColumns($t_name); + + foreach ($cols as $c_name => $col) { + $type = $schema->dbt2udt($col['type'],$col['len'],$col['default']); + $t->field($c_name,$type,$col['len'],$col['null'],$col['default'],true); + } + + # Get keys + $keys = $schema->getKeys($t_name); + + foreach ($keys as $k) + { + $args = $k['cols']; + array_unshift($args,$k['name']); + + if ($k['primary']) { + call_user_func_array(array($t,'primary'),$args); + } elseif ($k['unique']) { + call_user_func_array(array($t,'unique'),$args); + } + } + + # Get indexes + $idx = $schema->getIndexes($t_name); + foreach ($idx as $i) + { + $args = array($i['name'],$i['type']); + $args = array_merge($args,$i['cols']); + + call_user_func_array(array($t,'index'),$args); + } + + # Get foreign keys + $ref = $schema->getReferences($t_name); + foreach ($ref as $r) { + $t->reference($r['name'],$r['c_cols'],$r['p_table'],$r['p_cols'],$r['update'],$r['delete']); + } + } + } + + /** + Synchronize this schema taken from database with $schema. + + @param s dbStruct Structure to synchronize with + */ + public function synchronize($s) + { + $this->tables = array(); + $this->reverse(); + + if (!($s instanceof self)) { + throw new Exception('Invalid database schema'); + } + + $tables = $s->getTables(); + + $table_create = array(); + $key_create = array(); + $index_create = array(); + $reference_create = array(); + + $field_create = array(); + $field_update = array(); + $key_update = array(); + $index_update = array(); + $reference_update = array(); + + $got_work = false; + + $schema = dbSchema::init($this->con); + + foreach ($tables as $tname => $t) + { + if (!$this->tableExists($tname)) + { + # Table does not exist, create table + $table_create[$tname] = $t->getFields(); + + # Add keys, indexes and references + $keys = $t->getKeys(); + $indexes = $t->getIndexes(); + $references = $t->getReferences(); + + foreach ($keys as $k => $v) { + $key_create[$tname][$this->prefix.$k] = $v; + } + foreach ($indexes as $k => $v) { + $index_create[$tname][$this->prefix.$k] = $v; + } + foreach ($references as $k => $v) { + $v['p_table'] = $this->prefix.$v['p_table']; + $reference_create[$tname][$this->prefix.$k] = $v; + } + + $got_work = true; + } + else # Table exists + { + # Check new fields to create + $fields = $t->getFields(); + $db_fields = $this->tables[$tname]->getFields(); + foreach ($fields as $fname => $f) + { + if (!$this->tables[$tname]->fieldExists($fname)) + { + # Field doest not exist, create it + $field_create[$tname][$fname] = $f; + $got_work = true; + } + elseif ($this->fieldsDiffer($db_fields[$fname],$f)) + { + # Field exists and differs from db version + $field_update[$tname][$fname] = $f; + $got_work = true; + } + } + + # Check keys to add or upgrade + $keys = $t->getKeys(); + $db_keys = $this->tables[$tname]->getKeys(); + + foreach ($keys as $kname => $k) + { + if ($k['type'] == 'primary' && $this->con->driver() == 'mysql') { + $kname = 'PRIMARY'; + } else { + $kname = $this->prefix.$kname; + } + + $db_kname = $this->tables[$tname]->keyExists($kname,$k['type'],$k['cols']); + if (!$db_kname) + { + # Key does not exist, create it + $key_create[$tname][$kname] = $k; + $got_work = true; + } + elseif ($this->keysDiffer($db_kname,$db_keys[$db_kname]['cols'],$kname,$k['cols'])) + { + # Key exists and differs from db version + $key_update[$tname][$db_kname] = array_merge(array('name'=>$kname),$k); + $got_work = true; + } + } + + # Check index to add or upgrade + $idx = $t->getIndexes(); + $db_idx = $this->tables[$tname]->getIndexes(); + + foreach ($idx as $iname => $i) + { + $iname = $this->prefix.$iname; + $db_iname = $this->tables[$tname]->indexExists($iname,$i['type'],$i['cols']); + + if (!$db_iname) + { + # Index does not exist, create it + $index_create[$tname][$iname] = $i; + $got_work = true; + } + elseif ($this->indexesDiffer($db_iname,$db_idx[$db_iname],$iname,$i)) + { + # Index exists and differs from db version + $index_update[$tname][$db_iname] = array_merge(array('name'=>$iname),$i); + $got_work = true; + } + } + + # Check references to add or upgrade + $ref = $t->getReferences(); + $db_ref = $this->tables[$tname]->getReferences(); + + foreach ($ref as $rname => $r) + { + $rname = $this->prefix.$rname; + $r['p_table'] = $this->prefix.$r['p_table']; + $db_rname = $this->tables[$tname]->referenceExists($rname,$r['c_cols'],$r['p_table'],$r['p_cols']); + + if (!$db_rname) + { + # Reference does not exist, create it + $reference_create[$tname][$rname] = $r; + $got_work = true; + } + elseif ($this->referencesDiffer($db_rname,$db_ref[$db_rname],$rname,$r)) + { + $reference_update[$tname][$db_rname] = array_merge(array('name'=>$rname),$r); + $got_work = true; + } + } + } + } + + if (!$got_work) { + return; + } + + # Create tables + foreach ($table_create as $table => $fields) + { + $schema->createTable($table,$fields); + } + + # Create new fields + foreach ($field_create as $tname => $fields) + { + foreach ($fields as $fname => $f) { + $schema->createField($tname,$fname,$f['type'],$f['len'],$f['null'],$f['default']); + } + } + + # Update fields + foreach ($field_update as $tname => $fields) + { + foreach ($fields as $fname => $f) { + $schema->alterField($tname,$fname,$f['type'],$f['len'],$f['null'],$f['default']); + } + } + + # Create new keys + foreach ($key_create as $tname => $keys) + { + foreach ($keys as $kname => $k) + { + if ($k['type'] == 'primary') { + $schema->createPrimary($tname,$kname,$k['cols']); + } elseif ($k['type'] == 'unique') { + $schema->createUnique($tname,$kname,$k['cols']); + } + } + } + + # Update keys + foreach ($key_update as $tname => $keys) + { + foreach ($keys as $kname => $k) + { + if ($k['type'] == 'primary') { + $schema->alterPrimary($tname,$kname,$k['name'],$k['cols']); + } elseif ($k['type'] == 'unique') { + $schema->alterUnique($tname,$kname,$k['name'],$k['cols']); + } + } + } + + # Create indexes + foreach ($index_create as $tname => $index) + { + foreach ($index as $iname => $i) { + $schema->createIndex($tname,$iname,$i['type'],$i['cols']); + } + } + + # Update indexes + foreach ($index_update as $tname => $index) + { + foreach ($index as $iname => $i) { + $schema->alterIndex($tname,$iname,$i['name'],$i['type'],$i['cols']); + } + } + + # Create references + foreach ($reference_create as $tname => $ref) + { + foreach ($ref as $rname => $r) + { + $schema->createReference($rname,$tname,$r['c_cols'],$r['p_table'],$r['p_cols'],$r['update'],$r['delete']); + } + } + + # Update references + foreach ($reference_update as $tname => $ref) + { + foreach ($ref as $rname => $r) { + $schema->alterReference($rname,$r['name'],$tname,$r['c_cols'],$r['p_table'],$r['p_cols'],$r['update'],$r['delete']); + } + } + + # Flush execution stack + $schema->flushStack(); + + return + count($table_create) + count($key_create) + count($index_create) + + count($reference_create) + count($field_create) + count($field_update) + + count($key_update) + count($index_update) + count($reference_update); + } + + public function getTables() + { + $res = array(); + foreach ($this->tables as $t => $v) + { + $res[$this->prefix.$t] = $v; + } + + return $res; + } + + public function tableExists($name) + { + return isset($this->tables[$name]); + } + + private function fieldsDiffer($db_field,$schema_field) + { + $d_type = $db_field['type']; + $d_len = (integer) $db_field['len']; + $d_default = $db_field['default']; + $d_null = $db_field['null']; + + $s_type = $schema_field['type']; + $s_len = (integer) $schema_field['len']; + $s_default = $schema_field['default']; + $s_null = $schema_field['null']; + + return $d_type != $s_type || $d_len != $s_len || $d_default != $s_default || $d_null != $s_null; + } + + private function keysDiffer($d_name,$d_cols,$s_name,$s_cols) + { + return $d_name != $s_name || $d_cols != $s_cols; + } + + private function indexesDiffer($d_name,$d_i,$s_name,$s_i) + { + return $d_name != $s_name || $d_i['cols'] != $s_i['cols'] || $d_i['type'] != $s_i['type']; + } + + private function referencesDiffer($d_name,$d_r,$s_name,$s_r) + { + return + $d_name != $s_name || $d_r['c_cols'] != $s_r['c_cols'] + || $d_r['p_table'] != $s_r['p_table'] || $d_r['p_cols'] != $s_r['p_cols'] + || $d_r['update'] != $s_r['update'] || $d_r['delete'] != $s_r['delete']; + } +} + +class dbStructTable +{ + protected $name; + protected $has_primary = false; + + protected $fields = array(); + protected $keys = array(); + protected $indexes = array(); + protected $references = array(); + + /** + Universal data types supported by dbSchema + + SMALLINT : signed 2 bytes integer + INTEGER : signed 4 bytes integer + BIGINT : signed 8 bytes integer + REAL : signed 4 bytes floating point number + FLOAT : signed 8 bytes floating point number + NUMERIC : exact numeric type + + DATE : Calendar date (day, month and year) + TIME : Time of day + TIMESTAMP : Date and time + + CHAR : A fixed n-length character string + VARCHAR : A variable length character string + TEXT : A variable length of text + */ + protected $allowed_types = array( + 'smallint','integer','bigint','real','float','numeric', + 'date','time','timestamp', + 'char','varchar','text' + ); + + public function __construct($name) + { + $this->name = $name; + return $this; + } + + public function getFields() + { + return $this->fields; + } + + public function getKeys($primary=null) + { + return $this->keys; + } + + public function getIndexes() + { + return $this->indexes; + } + + public function getReferences() + { + return $this->references; + } + + public function fieldExists($name) + { + return isset($this->fields[$name]); + } + + public function keyExists($name,$type,$cols) + { + # Look for key with the same name + if (isset($this->keys[$name])) { + return $name; + } + + # Look for key with the same columns list and type + foreach ($this->keys as $n => $k) + { + if ($k['cols'] == $cols && $k['type'] == $type) { + # Same columns and type, return new name + return $n; + } + } + + return false; + } + + public function indexExists($name,$type,$cols) + { + # Look for key with the same name + if (isset($this->indexes[$name])) { + return $name; + } + + # Look for index with the same columns list and type + foreach ($this->indexes as $n => $i) + { + if ($i['cols'] == $cols && $i['type'] == $type) { + # Same columns and type, return new name + return $n; + } + } + + return false; + } + + public function referenceExists($name,$c_cols,$p_table,$p_cols) + { + if (isset($this->references[$name])) { + return $name; + } + + # Look for reference with same chil columns, parent table and columns + foreach ($this->references as $n => $r) + { + if ($c_cols == $r['c_cols'] && $p_table == $r['p_table'] && $p_cols == $r['p_cols']) { + # Only name differs, return new name + return $n; + } + } + + return false; + } + + public function field($name,$type,$len,$null=true,$default=false,$to_null=false) + { + $type = strtolower($type); + + if (!in_array($type,$this->allowed_types)) + { + if ($to_null) { + $type = null; + } else { + throw new Exception('Invalid data type '.$type.' in schema'); + } + } + + $this->fields[$name] = array( + 'type' => $type, + 'len' => (integer) $len, + 'default' => $default, + 'null' => (boolean) $null + ); + + return $this; + } + + public function __call($name,$args) + { + array_unshift($args,$name); + return call_user_func_array(array($this,'field'),$args); + } + + public function primary($name,$col) + { + if ($this->has_primary) { + throw new Exception(sprintf('Table %s already has a primary key',$this->name)); + } + + $cols = func_get_args(); + array_shift($cols); + + return $this->newKey('primary',$name,$cols); + } + + public function unique($name,$col) + { + $cols = func_get_args(); + array_shift($cols); + + return $this->newKey('unique',$name,$cols); + } + + public function index($name,$type,$col) + { + $cols = func_get_args(); + array_shift($cols); + array_shift($cols); + + $this->checkCols($cols); + + $this->indexes[$name] = array( + 'type' => strtolower($type), + 'cols' => $cols + ); + + return $this; + } + + public function reference($name,$c_cols,$p_table,$p_cols,$update=false,$delete=false) + { + if (!is_array($p_cols)) { + $p_cols = array($p_cols); + } + if (!is_array($c_cols)) { + $c_cols = array($c_cols); + } + + $this->checkCols($c_cols); + + $this->references[$name] = array( + 'c_cols' => $c_cols, + 'p_table' => $p_table, + 'p_cols' => $p_cols, + 'update' => $update, + 'delete' => $delete + ); + } + + protected function newKey($type,$name,$cols) + { + $this->checkCols($cols); + + $this->keys[$name] = array( + 'type' => $type, + 'cols' => $cols + ); + + if ($type == 'primary') { + $this->has_primary = true; + } + + return $this; + } + + protected function checkCols($cols) + { + foreach ($cols as $v) { + if (!preg_match('/^\(.*?\)$/',$v) && !isset($this->fields[$v])) { + throw new Exception(sprintf('Field %s does not exist in table %s',$v,$this->name)); + } + } + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/libs/clearbricks/dbschema/class.mysql.dbschema.php b/v2/dotclear/inc/libs/clearbricks/dbschema/class.mysql.dbschema.php new file mode 100644 index 0000000..51b9ce2 --- /dev/null +++ b/v2/dotclear/inc/libs/clearbricks/dbschema/class.mysql.dbschema.php @@ -0,0 +1,470 @@ +con->select($sql); + + $res = array(); + while ($rs->fetch()) { + $res[] = $rs->f(0); + } + return $res; + } + + public function db_get_columns($table) + { + $sql = 'SHOW COLUMNS FROM '.$this->con->escapeSystem($table); + $rs = $this->con->select($sql); + + $res = array(); + while ($rs->fetch()) + { + $field = trim($rs->f('Field')); + $type = trim($rs->f('Type')); + $null = strtolower($rs->f('Null')) == 'yes'; + $default = $rs->f('Default'); + + $len = null; + if (preg_match('/^(.+?)\(([\d,]+)\)$/si',$type,$m)) { + $type = $m[1]; + $len = (integer) $m[2]; + } + + if ($default != '' && !is_numeric($default)) { + $default = "'".$default."'"; + } + + $res[$field] = array( + 'type' => $type, + 'len' => $len, + 'null' => $null, + 'default' => $default + ); + } + return $res; + } + + public function db_get_keys($table) + { + $sql = 'SHOW INDEX FROM '.$this->con->escapeSystem($table); + $rs = $this->con->select($sql); + + $t = array(); + $res = array(); + while ($rs->fetch()) + { + $key_name = $rs->f('Key_name'); + $unique = $rs->f('Non_unique') == 0; + $seq = $rs->f('Seq_in_index'); + $col_name = $rs->f('Column_name'); + + if ($key_name == 'PRIMARY' || $unique) { + $t[$key_name]['cols'][$seq] = $col_name; + $t[$key_name]['unique'] = $unique; + } + } + + foreach ($t as $name => $idx) + { + ksort($idx['cols']); + + $res[] = array( + 'name' => $name, + 'primary' => $name == 'PRIMARY', + 'unique' => $idx['unique'], + 'cols' => array_values($idx['cols']) + ); + } + + return $res; + } + + public function db_get_indexes($table) + { + $sql = 'SHOW INDEX FROM '.$this->con->escapeSystem($table); + $rs = $this->con->select($sql); + + $t = array(); + $res = array(); + while ($rs->fetch()) + { + $key_name = $rs->f('Key_name'); + $unique = $rs->f('Non_unique') == 0; + $seq = $rs->f('Seq_in_index'); + $col_name = $rs->f('Column_name'); + $type = $rs->f('Index_type'); + + if ($key_name != 'PRIMARY' && !$unique) { + $t[$key_name]['cols'][$seq] = $col_name; + $t[$key_name]['type'] = $type; + } + } + + foreach ($t as $name => $idx) + { + ksort($idx['cols']); + + $res[] = array( + 'name' => $name, + 'type' => $idx['type'], + 'cols' => $idx['cols'] + ); + } + + return $res; + } + + public function db_get_references($table) + { + $sql = 'SHOW CREATE TABLE '.$this->con->escapeSystem($table); + $rs = $this->con->select($sql); + + $s = $rs->f(1); + + $res = array(); + + $n = preg_match_all('/^\s*CONSTRAINT\s+`(.+?)`\s+FOREIGN\s+KEY\s+\((.+?)\)\s+REFERENCES\s+`(.+?)`\s+\((.+?)\)(.*?)$/msi',$s,$match); + if ($n > 0) + { + foreach ($match[1] as $i => $name) + { + # Columns transformation + $t_cols = str_replace('`','',$match[2][$i]); + $t_cols = explode(',',$t_cols); + $r_cols = str_replace('`','',$match[4][$i]); + $r_cols = explode(',',$r_cols); + + # ON UPDATE|DELETE + $on = trim($match[5][$i],', '); + $on_delete = null; + $on_update = null; + if ($on != '') { + if (preg_match('/ON DELETE (.+?)(?:\s+ON|$)/msi',$on,$m)) { + $on_delete = strtolower(trim($m[1])); + } + if (preg_match('/ON UPDATE (.+?)(?:\s+ON|$)/msi',$on,$m)) { + $on_update = strtolower(trim($m[1])); + } + } + + $res[] = array ( + 'name' => $name, + 'c_cols' => $t_cols, + 'p_table' => $match[3][$i], + 'p_cols' => $r_cols, + 'update' => $on_update, + 'delete' => $on_delete + ); + } + } + return $res; + } + + public function db_create_table($name,$fields) + { + $a = array(); + + foreach ($fields as $n => $f) + { + $type = $f['type']; + $len = (integer) $f['len']; + $default = $f['default']; + $null = $f['null']; + + $type = $this->udt2dbt($type,$len,$default); + $len = $len > 0 ? '('.$len.')' : ''; + $null = $null ? 'NULL' : 'NOT NULL'; + + if ($default === null) { + $default = 'DEFAULT NULL'; + } elseif ($default !== false) { + $default = 'DEFAULT '.$default.' '; + } else { + $default = ''; + } + + $a[] = + $this->con->escapeSystem($n).' '. + $type.$len.' '.$null.' '.$default; + } + + $sql = + 'CREATE TABLE '.$this->con->escapeSystem($name)." (\n". + implode(",\n",$a). + "\n) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin "; + + $this->con->execute($sql); + } + + public function db_create_field($table,$name,$type,$len,$null,$default) + { + $type = $this->udt2dbt($type,$len,$default); + $len = (integer) $len > 0 ? '('.(integer) $len.')' : ''; + $null = $null ? 'NULL' : 'NOT NULL'; + + if ($default === null) { + $default = 'DEFAULT NULL'; + } elseif ($default !== false) { + $default = 'DEFAULT '.$default; + } else { + $default = ''; + } + + $sql = + 'ALTER TABLE '.$this->con->escapeSystem($table).' '. + 'ADD COLUMN '.$this->con->escapeSystem($name).' '. + $type.$len.' '.$null.' '.$default; + + $this->con->execute($sql); + } + + public function db_create_primary($table,$name,$cols) + { + $c = array(); + foreach ($cols as $v) { + $c[] = $this->con->escapeSystem($v); + } + + $sql = + 'ALTER TABLE '.$this->con->escapeSystem($table).' '. + 'ADD CONSTRAINT PRIMARY KEY ('.implode(',',$c).') '; + + $this->con->execute($sql); + } + + public function db_create_unique($table,$name,$cols) + { + $c = array(); + foreach ($cols as $v) { + $c[] = $this->con->escapeSystem($v); + } + + $sql = + 'ALTER TABLE '.$this->con->escapeSystem($table).' '. + 'ADD CONSTRAINT UNIQUE KEY '.$this->con->escapeSystem($name).' '. + '('.implode(',',$c).') '; + + $this->con->execute($sql); + } + + public function db_create_index($table,$name,$type,$cols) + { + $c = array(); + foreach ($cols as $v) { + $c[] = $this->con->escapeSystem($v); + } + + $sql = + 'ALTER TABLE '.$this->con->escapeSystem($table).' '. + 'ADD INDEX '.$this->con->escapeSystem($name).' USING '.$type.' '. + '('.implode(',',$c).') '; + + $this->con->execute($sql); + } + + public function db_create_reference($name,$c_table,$c_cols,$p_table,$p_cols,$update,$delete) + { + $c = array(); + $p = array(); + foreach ($c_cols as $v) { + $c[] = $this->con->escapeSystem($v); + } + foreach ($p_cols as $v) { + $p[] = $this->con->escapeSystem($v); + } + + $sql = + 'ALTER TABLE '.$this->con->escapeSystem($c_table).' '. + 'ADD CONSTRAINT '.$name.' FOREIGN KEY '. + '('.implode(',',$c).') '. + 'REFERENCES '.$this->con->escapeSystem($p_table).' '. + '('.implode(',',$p).') '; + + if ($update) { + $sql .= 'ON UPDATE '.$update.' '; + } + if ($delete) { + $sql .= 'ON DELETE '.$delete.' '; + } + + $this->con->execute($sql); + } + + public function db_alter_field($table,$name,$type,$len,$null,$default) + { + $type = $this->udt2dbt($type,$len,$default); + $len = (integer) $len > 0 ? '('.(integer) $len.')' : ''; + $null = $null ? 'NULL' : 'NOT NULL'; + + if ($default === null) { + $default = 'DEFAULT NULL'; + } elseif ($default !== false) { + $default = 'DEFAULT '.$default; + } else { + $default = ''; + } + + $sql = + 'ALTER TABLE '.$this->con->escapeSystem($table).' '. + 'CHANGE COLUMN '.$this->con->escapeSystem($name).' '.$this->con->escapeSystem($name).' '. + $type.$len.' '.$null.' '.$default; + + $this->con->execute($sql); + } + + public function db_alter_primary($table,$name,$newname,$cols) + { + $c = array(); + foreach ($cols as $v) { + $c[] = $this->con->escapeSystem($v); + } + + $sql = + 'ALTER TABLE '.$this->con->escapeSystem($table).' '. + 'DROP PRIMARY KEY, ADD PRIMARY KEY '. + '('.implode(',',$c).') '; + + $this->con->execute($sql); + } + + public function db_alter_unique($table,$name,$newname,$cols) + { + $c = array(); + foreach ($cols as $v) { + $c[] = $this->con->escapeSystem($v); + } + + $sql = + 'ALTER TABLE '.$this->con->escapeSystem($table).' '. + 'DROP INDEX '.$this->con->escapeSystem($name).', '. + 'ADD UNIQUE '.$this->con->escapeSystem($newname).' '. + '('.implode(',',$c).') '; + + $this->con->execute($sql); + } + + public function db_alter_index($table,$name,$newname,$type,$cols) + { + $c = array(); + foreach ($cols as $v) { + $c[] = $this->con->escapeSystem($v); + } + + $sql = + 'ALTER TABLE '.$this->con->escapeSystem($table).' '. + 'DROP INDEX '.$this->con->escapeSystem($name).', '. + 'ADD INDEX '.$this->con->escapeSystem($newname).' '. + 'USING '.$type.' '. + '('.implode(',',$c).') '; + + $this->con->execute($sql); + } + + public function db_alter_reference($name,$newname,$c_table,$c_cols,$p_table,$p_cols,$update,$delete) + { + $sql = + 'ALTER TABLE '.$this->con->escapeSystem($c_table).' '. + 'DROP FOREIGN KEY '.$this->con->escapeSystem($name); + + $this->con->execute($sql); + $this->createReference($newname,$c_table,$c_cols,$p_table,$p_cols,$update,$delete); + } + + public function db_drop_unique($table,$name) + { + $sql = + 'ALTER TABLE '.$this->con->escapeSystem($table).' '. + 'DROP INDEX '.$this->con->escapeSystem($name); + $this->con->execute($sql); + } + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/libs/clearbricks/dbschema/class.mysqli.dbschema.php b/v2/dotclear/inc/libs/clearbricks/dbschema/class.mysqli.dbschema.php new file mode 100644 index 0000000..719fb56 --- /dev/null +++ b/v2/dotclear/inc/libs/clearbricks/dbschema/class.mysqli.dbschema.php @@ -0,0 +1,21 @@ + \ No newline at end of file diff --git a/v2/dotclear/inc/libs/clearbricks/dbschema/class.pgsql.dbschema.php b/v2/dotclear/inc/libs/clearbricks/dbschema/class.pgsql.dbschema.php new file mode 100644 index 0000000..bf6591f --- /dev/null +++ b/v2/dotclear/inc/libs/clearbricks/dbschema/class.pgsql.dbschema.php @@ -0,0 +1,400 @@ + 'no action', + 'r' => 'restrict', + 'c' => 'cascade', + 'n' => 'set null', + 'd' => 'set default' + ); + + public function dbt2udt($type,&$len,&$default) + { + $type = parent::dbt2udt($type,$len,$default); + + return $type; + } + + public function udt2dbt($type,&$len,&$default) + { + $type = parent::udt2dbt($type,$len,$default); + + return $type; + } + + public function db_get_tables() + { + $sql = + 'SELECT table_name '. + 'FROM information_schema.tables '. + "WHERE table_schema = current_schema() "; + + $rs = $this->con->select($sql); + + $res = array(); + while ($rs->fetch()) { + $res[] = $rs->f(0); + } + return $res; + } + + public function db_get_columns($table) + { + $sql = + 'SELECT column_name, udt_name, character_maximum_length, '. + 'is_nullable, column_default '. + 'FROM information_schema.columns '. + "WHERE table_name = '".$this->con->escape($table)."' "; + + $rs = $this->con->select($sql); + + $res = array(); + while ($rs->fetch()) + { + $field = trim($rs->column_name); + $type = trim($rs->udt_name); + $null = strtolower($rs->is_nullable) == 'yes'; + $default = $rs->column_default; + $len = $rs->character_maximum_length; + + if ($len == '') { + $len = null; + } + + $default = preg_replace('/::([\w\d\s]*)$/','',$default); + + $res[$field] = array( + 'type' => $type, + 'len' => $len, + 'null' => $null, + 'default' => $default + ); + } + + return $res; + } + + public function db_get_keys($table) + { + $sql = + 'SELECT DISTINCT ON(cls.relname) cls.oid, cls.relname as idxname, indisunique::integer, indisprimary::integer, '. + 'indnatts, tab.relname as tabname, contype, amname '. + 'FROM pg_index idx '. + 'JOIN pg_class cls ON cls.oid=indexrelid '. + 'JOIN pg_class tab ON tab.oid=indrelid '. + 'LEFT OUTER JOIN pg_tablespace ta on ta.oid=cls.reltablespace '. + 'JOIN pg_namespace n ON n.oid=tab.relnamespace '. + 'JOIN pg_am am ON am.oid=cls.relam '. + "LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0') ". + 'LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid) '. + 'LEFT OUTER JOIN pg_description des ON des.objoid=con.oid '. + 'LEFT OUTER JOIN pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0) '. + "WHERE tab.relname = '".$this->con->escape($table)."' ". + "AND contype IN ('p','u') ". + 'ORDER BY cls.relname '; + + $rs = $this->con->select($sql); + + $res = array(); + while ($rs->fetch()) + { + $k = array( + 'name' => $rs->idxname, + 'primary' => (boolean) $rs->indisprimary, + 'unique' => (boolean) $rs->indisunique, + 'cols' => array() + ); + + for ($i=1; $i<=$rs->indnatts; $i++) { + $cols = $this->con->select('SELECT pg_get_indexdef('.$rs->oid.'::oid, '.$i.', true);'); + $k['cols'][] = $cols->f(0); + } + + $res[] = $k; + } + + return $res; + } + + public function db_get_indexes($table) + { + $sql = + 'SELECT DISTINCT ON(cls.relname) cls.oid, cls.relname as idxname, n.nspname, '. + 'indnatts, tab.relname as tabname, contype, amname '. + 'FROM pg_index idx '. + 'JOIN pg_class cls ON cls.oid=indexrelid '. + 'JOIN pg_class tab ON tab.oid=indrelid '. + 'LEFT OUTER JOIN pg_tablespace ta on ta.oid=cls.reltablespace '. + 'JOIN pg_namespace n ON n.oid=tab.relnamespace '. + 'JOIN pg_am am ON am.oid=cls.relam '. + "LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0') ". + 'LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid) '. + 'LEFT OUTER JOIN pg_description des ON des.objoid=con.oid '. + 'LEFT OUTER JOIN pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0) '. + "WHERE tab.relname = '".$this->con->escape($table)."' ". + 'AND conname IS NULL '. + 'ORDER BY cls.relname '; + + $rs = $this->con->select($sql); + + $res = array(); + while ($rs->fetch()) + { + $k = array( + 'name' => $rs->idxname, + 'type' => $rs->amname, + 'cols' => array() + ); + + for ($i=1; $i<=$rs->indnatts; $i++) { + $cols = $this->con->select('SELECT pg_get_indexdef('.$rs->oid.'::oid, '.$i.', true);'); + $k['cols'][] = $cols->f(0); + } + + $res[] = $k; + } + + return $res; + } + + public function db_get_references($table) + { + $sql = + 'SELECT ct.oid, conname, condeferrable, condeferred, confupdtype, '. + 'confdeltype, confmatchtype, conkey, confkey, conrelid, confrelid, cl.relname as fktab, '. + 'cr.relname as reftab '. + 'FROM pg_constraint ct '. + 'JOIN pg_class cl ON cl.oid=conrelid '. + 'JOIN pg_namespace nl ON nl.oid=cl.relnamespace '. + 'JOIN pg_class cr ON cr.oid=confrelid '. + 'JOIN pg_namespace nr ON nr.oid=cr.relnamespace '. + "WHERE contype='f' ". + "AND cl.relname = '".$this->con->escape($table)."' ". + 'ORDER BY conname '; + + $rs = $this->con->select($sql); + + $cols_sql = + 'SELECT a1.attname as conattname, a2.attname as confattname '. + 'FROM pg_attribute a1, pg_attribute a2 '. + 'WHERE a1.attrelid=%1$s::oid AND a1.attnum=%2$s '. + 'AND a2.attrelid=%3$s::oid AND a2.attnum=%4$s '; + + $res = array(); + while ($rs->fetch()) + { + $conkey = preg_replace('/[^\d]/','',$rs->conkey); + $confkey = preg_replace('/[^\d]/','',$rs->confkey); + + $k = array( + 'name' => $rs->conname, + 'c_cols' => array(), + 'p_table' => $rs->reftab, + 'p_cols' => array(), + 'update' => $this->ref_actions_map[$rs->confupdtype], + 'delete' => $this->ref_actions_map[$rs->confdeltype] + ); + + $cols = $this->con->select(sprintf($cols_sql,$rs->conrelid,$conkey,$rs->confrelid,$confkey)); + while ($cols->fetch()) { + $k['c_cols'][] = $cols->conattname; + $k['p_cols'][] = $cols->confattname; + } + + $res[] = $k; + } + + return $res; + } + + public function db_create_table($name,$fields) + { + $a = array(); + + foreach ($fields as $n => $f) + { + $type = $f['type']; + $len = (integer) $f['len']; + $default = $f['default']; + $null = $f['null']; + + $type = $this->udt2dbt($type,$len,$default); + $len = $len > 0 ? '('.$len.')' : ''; + $null = $null ? 'NULL' : 'NOT NULL'; + + if ($default === null) { + $default = 'DEFAULT NULL'; + } elseif ($default !== false) { + $default = 'DEFAULT '.$default.' '; + } else { + $default = ''; + } + + $a[] = + $n.' '. + $type.$len.' '.$null.' '.$default; + } + + $sql = + 'CREATE TABLE '.$name." (\n". + implode(",\n",$a). + "\n)"; + + $this->con->execute($sql); + } + + public function db_create_field($table,$name,$type,$len,$null,$default) + { + $type = $this->udt2dbt($type,$len,$default); + $len = $len > 0 ? '('.$len.')' : ''; + $null = $null ? 'NULL' : 'NOT NULL'; + + if ($default === null) { + $default = 'DEFAULT NULL'; + } elseif ($default !== false) { + $default = 'DEFAULT '.$default.' '; + } else { + $default = ''; + } + + $sql = + 'ALTER TABLE '.$table.' ADD COLUMN '.$name.' '. + $type.$len.' '.$null.' '.$default; + + $this->con->execute($sql); + } + + public function db_create_primary($table,$name,$cols) + { + $sql = + 'ALTER TABLE '.$table.' '. + 'ADD CONSTRAINT '.$name.' PRIMARY KEY ('.implode(",",$cols).') '; + + $this->con->execute($sql); + } + + public function db_create_unique($table,$name,$cols) + { + $sql = + 'ALTER TABLE '.$table.' '. + 'ADD CONSTRAINT '.$name.' UNIQUE ('.implode(',',$cols).') '; + + $this->con->execute($sql); + } + + public function db_create_index($table,$name,$type,$cols) + { + $sql = + 'CREATE INDEX '.$name.' ON '.$table.' USING '.$type. + '('.implode(',',$cols).') '; + + $this->con->execute($sql); + } + + public function db_create_reference($name,$c_table,$c_cols,$p_table,$p_cols,$update,$delete) + { + $sql = + 'ALTER TABLE '.$c_table.' '. + 'ADD CONSTRAINT '.$name.' FOREIGN KEY '. + '('.implode(',',$c_cols).') '. + 'REFERENCES '.$p_table.' '. + '('.implode(',',$p_cols).') '; + + if ($update) { + $sql .= 'ON UPDATE '.$update.' '; + } + if ($delete) { + $sql .= 'ON DELETE '.$delete.' '; + } + + $this->con->execute($sql); + } + + public function db_alter_field($table,$name,$type,$len,$null,$default) + { + $type = $this->udt2dbt($type,$len,$default); + $len = (integer) $len > 0 ? '('.(integer) $len.')' : ''; + + $sql = 'ALTER TABLE '.$table.' ALTER COLUMN '.$name.' TYPE '.$type.$len; + $this->con->execute($sql); + + if ($default === null) { + $default = 'SET DEFAULT NULL'; + } elseif ($default !== false) { + $default = 'SET DEFAULT '.$default; + } else { + $default = 'DROP DEFAULT'; + } + + $sql = 'ALTER TABLE '.$table.' ALTER COLUMN '.$name.' '.$default; + $this->con->execute($sql); + + $null = $null ? 'DROP NOT NULL' : 'SET NOT NULL'; + $sql = 'ALTER TABLE '.$table.' ALTER COLUMN '.$name.' '.$null; + $this->con->execute($sql); + } + + public function db_alter_primary($table,$name,$newname,$cols) + { + $sql = 'ALTER TABLE '.$table.' DROP CONSTRAINT '.$name; + $this->con->execute($sql); + + $this->createPrimary($table,$newname,$cols); + } + + public function db_alter_unique($table,$name,$newname,$cols) + { + $sql = 'ALTER TABLE '.$table.' DROP CONSTRAINT '.$name; + $this->con->execute($sql); + + $this->createUnique($table,$newname,$cols); + } + + public function db_alter_index($table,$name,$newname,$type,$cols) + { + $sql = 'DROP INDEX '.$name; + $this->con->execute($sql); + + $this->createIndex($table,$newname,$type,$cols); + } + + public function db_alter_reference($name,$newname,$c_table,$c_cols,$p_table,$p_cols,$update,$delete) + { + $sql = 'ALTER TABLE '.$c_table.' DROP CONSTRAINT '.$name; + $this->con->execute($sql); + + $this->createReference($newname,$c_table,$c_cols,$p_table,$p_cols,$update,$delete); + } + + public function db_drop_unique($table,$name) + { + $sql = 'ALTER TABLE '.$table.' DROP CONSTRAINT '.$name; + $this->con->execute($sql); + } + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/libs/clearbricks/dbschema/class.sqlite.dbschema.php b/v2/dotclear/inc/libs/clearbricks/dbschema/class.sqlite.dbschema.php new file mode 100644 index 0000000..2ab7279 --- /dev/null +++ b/v2/dotclear/inc/libs/clearbricks/dbschema/class.sqlite.dbschema.php @@ -0,0 +1,514 @@ +table_stack as $table => $def) + { + $sql = 'CREATE TABLE '.$table." (\n".implode(",\n",$def)."\n)\n "; + $this->con->execute($sql); + } + + foreach ($this->x_stack as $x) + { + $this->con->execute($x); + } + } + + public function db_get_tables() + { + $res = array(); + $sql = "SELECT * FROM sqlite_master WHERE type = 'table'"; + $rs = $this->con->select($sql); + + $res = array(); + while ($rs->fetch()) { + $res[] = $rs->tbl_name; + } + + return $res; + } + + public function db_get_columns($table) + { + $sql = 'PRAGMA table_info('.$this->con->escapeSystem($table).')'; + $rs = $this->con->select($sql); + + $res = array(); + while ($rs->fetch()) + { + $field = trim($rs->name); + $type = trim($rs->type); + $null = trim($rs->notnull) == 0; + $default = trim($rs->dflt_value); + + $len = null; + if (preg_match('/^(.+?)\(([\d,]+)\)$/si',$type,$m)) { + $type = $m[1]; + $len = (integer) $m[2]; + } + + $res[$field] = array( + 'type' => $type, + 'len' => $len, + 'null' => $null, + 'default' => $default + ); + } + return $res; + } + + public function db_get_keys($table) + { + $t = array(); + $res = array(); + + # Get primary keys first + $sql = "SELECT sql FROM sqlite_master WHERE type='table' AND name='".$this->con->escape($table)."'"; + $rs = $this->con->select($sql); + + if ($rs->isEmpty()) { + return array(); + } + + # Get primary keys + $n = preg_match_all('/^\s*CONSTRAINT\s+([^,]+?)\s+PRIMARY\s+KEY\s+\((.+?)\)/msi',$rs->sql,$match); + if ($n > 0) + { + foreach ($match[1] as $i => $name) + { + $cols = preg_split('/\s*,\s*/',$match[2][$i]); + $res[] = array( + 'name' => $name, + 'primary' => true, + 'unique' => false, + 'cols' => $cols + ); + } + } + + # Get unique keys + $n = preg_match_all('/^\s*CONSTRAINT\s+([^,]+?)\s+UNIQUE\s+\((.+?)\)/msi',$rs->sql,$match); + if ($n > 0) + { + foreach ($match[1] as $i => $name) + { + $cols = preg_split('/\s*,\s*/',$match[2][$i]); + $res[] = array( + 'name' => $name, + 'primary' => false, + 'unique' => true, + 'cols' => $cols + ); + } + } + + return $res; + } + + public function db_get_indexes($table) + { + $sql = 'PRAGMA index_list('.$this->con->escapeSystem($table).')'; + $rs = $this->con->select($sql); + + $res = array(); + while ($rs->fetch()) + { + if (preg_match('/^sqlite_/',$rs->name)) { + continue; + } + + $idx = $this->con->select('PRAGMA index_info('.$this->con->escapeSystem($rs->name).')'); + $cols = array(); + while ($idx->fetch()) { + $cols[] = $idx->name; + } + + $res[] = array( + 'name' => $rs->name, + 'type' => 'btree', + 'cols' => $cols + ); + } + + return $res; + } + + public function db_get_references($table) + { + $sql = 'SELECT * FROM sqlite_master WHERE type=\'trigger\' AND tbl_name = \'%1$s\' AND name LIKE \'%2$s_%%\' '; + $res = array(); + + # Find constraints on table + $bir = $this->con->select(sprintf($sql,$this->con->escape($table),'bir')); + $bur = $this->con->select(sprintf($sql,$this->con->escape($table),'bur')); + + if ($bir->isEmpty() || $bur->isempty()) { + return $res; + } + + while ($bir->fetch()) + { + # Find child column and parent table and column + if (!preg_match('/FROM\s+(.+?)\s+WHERE\s+(.+?)\s+=\s+NEW\.(.+?)\s*?\) IS\s+NULL/msi',$bir->sql,$m)) { + continue; + } + + $c_col = $m[3]; + $p_table = $m[1]; + $p_col = $m[2]; + + # Find on update + $on_update = 'restrict'; + $aur = $this->con->select(sprintf($sql,$this->con->escape($p_table),'aur')); + while ($aur->fetch()) + { + if (!preg_match('/AFTER\s+UPDATE/msi',$aur->sql)) { + continue; + } + + if (preg_match('/UPDATE\s+'.$table.'\s+SET\s+'.$c_col.'\s*=\s*NEW.'.$p_col. + '\s+WHERE\s+'.$c_col.'\s*=\s*OLD\.'.$p_col.'/msi',$aur->sql)) { + $on_update = 'cascade'; + break; + } + + if (preg_match('/UPDATE\s+'.$table.'\s+SET\s+'.$c_col.'\s*=\s*NULL'. + '\s+WHERE\s+'.$c_col.'\s*=\s*OLD\.'.$p_col.'/msi',$aur->sql)) { + $on_update = 'set null'; + break; + } + } + + # Find on delete + $on_delete = 'restrict'; + $bdr = $this->con->select(sprintf($sql,$this->con->escape($p_table),'bdr')); + while ($bdr->fetch()) + { + if (!preg_match('/BEFORE\s+DELETE/msi',$bdr->sql)) { + continue; + } + + if (preg_match('/DELETE\s+FROM\s+'.$table.'\s+WHERE\s+'.$c_col.'\s*=\s*OLD\.'.$p_col.'/msi',$bdr->sql)) { + $on_delete = 'cascade'; + break; + } + + if (preg_match('/UPDATE\s+'.$table.'\s+SET\s+'.$c_col.'\s*=\s*NULL'. + '\s+WHERE\s+'.$c_col.'\s*=\s*OLD\.'.$p_col.'/msi',$bdr->sql)) { + $on_update = 'set null'; + break; + } + } + + $res[] = array( + 'name' => substr($bir->name,4), + 'c_cols' => array($c_col), + 'p_table' => $p_table, + 'p_cols' => array($p_col), + 'update' => $on_update, + 'delete' => $on_delete + ); + } + + return $res; + } + + public function db_create_table($name,$fields) + { + $a = array(); + + foreach ($fields as $n => $f) + { + $type = $f['type']; + $len = (integer) $f['len']; + $default = $f['default']; + $null = $f['null']; + + $type = $this->udt2dbt($type,$len,$default); + $len = $len > 0 ? '('.$len.')' : ''; + $null = $null ? 'NULL' : 'NOT NULL'; + + if ($default === null) { + $default = 'DEFAULT NULL'; + } elseif ($default !== false) { + $default = 'DEFAULT '.$default.' '; + } else { + $default = ''; + } + + $a[] = $n.' '.$type.$len.' '.$null.' '.$default; + } + + $this->table_stack[$name][] = implode(",\n",$a); + $this->table_hist[$name] = $fields; + } + + public function db_create_field($table,$name,$type,$len,$null,$default) + { + $type = $this->udt2dbt($type,$len,$default); + $len = $len > 0 ? '('.$len.')' : ''; + $null = $null ? 'NULL' : 'NOT NULL'; + + if ($default === null) { + $default = 'DEFAULT NULL'; + } elseif ($default !== false) { + $default = 'DEFAULT '.$default.' '; + } else { + $default = ''; + } + + $sql = + 'ALTER TABLE '.$this->con->escapeSystem($table).' '. + 'ADD COLUMN '.$this->con->escapeSystem($name).' '. + $type.$len.' '.$null.' '.$default; + + $this->con->execute($sql); + } + + public function db_create_primary($table,$name,$cols) + { + $this->table_stack[$table][] = 'CONSTRAINT '.$name.' PRIMARY KEY ('.implode(',',$cols).') '; + } + + public function db_create_unique($table,$name,$cols) + { + $this->table_stack[$table][] = 'CONSTRAINT '.$name.' UNIQUE ('.implode(',',$cols).') '; + } + + public function db_create_index($table,$name,$type,$cols) + { + $this->x_stack[] = 'CREATE INDEX '.$name.' ON '.$table.' ('.implode(',',$cols).') '; + } + + public function db_create_reference($name,$c_table,$c_cols,$p_table,$p_cols,$update,$delete) + { + if (!isset($this->table_hist[$c_table])) { + return; + } + + if (count($c_cols) > 1 || count($p_cols) > 1) { + throw new Exception('SQLite UDBS does not support multiple columns foreign keys'); + } + + $c_col = $c_cols[0]; + $p_col = $p_cols[0]; + + $update = strtolower($update); + $delete = strtolower($delete); + + $cnull = $this->table_hist[$c_table][$c_col]['null']; + + # Create constraint + $this->x_stack[] = + 'CREATE TRIGGER bir_'.$name."\n". + 'BEFORE INSERT ON '.$c_table."\n". + "FOR EACH ROW BEGIN\n". + ' SELECT RAISE(ROLLBACK,\'insert on table "'.$c_table.'" violates foreign key constraint "'.$name.'"\')'."\n". + ' WHERE '. + ($cnull ? 'NEW.'.$c_col." IS NOT NULL\n AND " : ''). + '(SELECT '.$p_col.' FROM '.$p_table.' WHERE '.$p_col.' = NEW.'.$c_col.") IS NULL;\n". + "END;\n"; + + # Update constraint + $this->x_stack[] = + 'CREATE TRIGGER bur_'.$name."\n". + 'BEFORE UPDATE ON '.$c_table."\n". + "FOR EACH ROW BEGIN\n". + ' SELECT RAISE(ROLLBACK,\'update on table "'.$c_table.'" violates foreign key constraint "'.$name.'"\')'."\n". + ' WHERE '. + ($cnull ? 'NEW.'.$c_col." IS NOT NULL\n AND " : ''). + '(SELECT '.$p_col.' FROM '.$p_table.' WHERE '.$p_col.' = NEW.'.$c_col.") IS NULL;\n". + "END;\n"; + + # ON UPDATE + if ($update == 'cascade') + { + $this->x_stack[] = + 'CREATE TRIGGER aur_'.$name."\n". + 'AFTER UPDATE ON '.$p_table."\n". + "FOR EACH ROW BEGIN\n". + ' UPDATE '.$c_table.' SET '.$c_col.' = NEW.'.$p_col.' WHERE '.$c_col.' = OLD.'.$p_col.";\n". + "END;\n"; + } + elseif ($update == 'set null') + { + $this->x_stack[] = + 'CREATE TRIGGER aur_'.$name."\n". + 'AFTER UPDATE ON '.$p_table."\n". + "FOR EACH ROW BEGIN\n". + ' UPDATE '.$c_table.' SET '.$c_col.' = NULL WHERE '.$c_col.' = OLD.'.$p_col.";\n". + "END;\n"; + } + else # default on restrict + { + $this->x_stack[] = + 'CREATE TRIGGER burp_'.$name."\n". + 'BEFORE UPDATE ON '.$p_table."\n". + "FOR EACH ROW BEGIN\n". + ' SELECT RAISE (ROLLBACK,\'update on table "'.$p_table.'" violates foreign key constraint "'.$name.'"\')'."\n". + ' WHERE (SELECT '.$c_col.' FROM '.$c_table.' WHERE '.$c_col.' = OLD.'.$p_col.") IS NOT NULL;\n". + "END;\n"; + } + + # ON DELETE + if ($delete == 'cascade') + { + $this->x_stack[] = + 'CREATE TRIGGER bdr_'.$name."\n". + 'BEFORE DELETE ON '.$p_table."\n". + "FOR EACH ROW BEGIN\n". + ' DELETE FROM '.$c_table.' WHERE '.$c_col.' = OLD.'.$p_col.";\n". + "END;\n"; + } + elseif ($delete == 'set null') + { + $this->x_stack[] = + 'CREATE TRIGGER bdr_'.$name."\n". + 'BEFORE DELETE ON '.$p_table."\n". + "FOR EACH ROW BEGIN\n". + ' UPDATE '.$c_table.' SET '.$c_col.' = NULL WHERE '.$c_col.' = OLD.'.$p_col.";\n". + "END;\n"; + } + else + { + $this->x_stack[] = + 'CREATE TRIGGER bdr_'.$name."\n". + 'BEFORE DELETE ON '.$p_table."\n". + "FOR EACH ROW BEGIN\n". + ' SELECT RAISE (ROLLBACK,\'delete on table "'.$p_table.'" violates foreign key constraint "'.$name.'"\')'."\n". + ' WHERE (SELECT '.$c_col.' FROM '.$c_table.' WHERE '.$c_col.' = OLD.'.$p_col.") IS NOT NULL;\n". + "END;\n"; + } + } + + public function db_alter_field($table,$name,$type,$len,$null,$default) + { + $type = $this->udt2dbt($type,$len,$default); + if ($type != 'integer' && $type != 'text' && $type != 'timestamp') { + throw new Exception('SQLite fields cannot be changed.'); + } + } + + public function db_alter_primary($table,$name,$newname,$cols) + { + throw new Exception('SQLite primary key cannot be changed.'); + } + + public function db_alter_unique($table,$name,$newname,$cols) + { + throw new Exception('SQLite unique index cannot be changed.'); + } + + public function db_alter_index($table,$name,$newname,$type,$cols) + { + $this->con->execute('DROP INDEX IF EXISTS '.$name); + $this->con->execute('CREATE INDEX '.$newname.' ON '.$table.' ('.implode(',',$cols).') '); + } + + public function db_alter_reference($name,$newname,$c_table,$c_cols,$p_table,$p_cols,$update,$delete) + { + $this->con->execute('DROP TRIGGER IF EXISTS bur_'.$name); + $this->con->execute('DROP TRIGGER IF EXISTS burp_'.$name); + $this->con->execute('DROP TRIGGER IF EXISTS bir_'.$name); + $this->con->execute('DROP TRIGGER IF EXISTS aur_'.$name); + $this->con->execute('DROP TRIGGER IF EXISTS bdr_'.$name); + + $this->table_hist[$c_table] = $this->db_get_columns($c_table); + $this->db_create_reference($newname,$c_table,$c_cols,$p_table,$p_cols,$update,$delete); + } + + public function db_drop_unique($table,$name) + { + throw new Exception('SQLite unique index cannot be removed.'); + } + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/libs/clearbricks/debian/changelog b/v2/dotclear/inc/libs/clearbricks/debian/changelog new file mode 100644 index 0000000..01eeb48 --- /dev/null +++ b/v2/dotclear/inc/libs/clearbricks/debian/changelog @@ -0,0 +1,466 @@ +libclearbricks (0.8-22) unstable; urgency=low ; svnrev=165 + + * SVN Revision 152 - olivier, on Mon, 30 Jun 2008 15:04:18 +0200 + New debian changelog + + * SVN Revision 153 - olivier, on Thu, 03 Jul 2008 21:12:19 +0200 + SQLite with PDO and SQLite 3 only. + + * SVN Revision 154 - olivier, on Fri, 11 Jul 2008 14:48:43 +0200 + Bug fix with TZ file load. + + * SVN Revision 155 - olivier, on Wed, 16 Jul 2008 15:55:11 +0200 + Minor performances tweaks. + + * SVN Revision 156 - olivier, on Wed, 16 Jul 2008 16:11:17 +0200 + Added getTypes() in urlHandler. + + * SVN Revision 157 - olivier, on Wed, 16 Jul 2008 18:11:01 +0200 + Added support for inline HTML in wiki2xhtml + + * SVN Revision 158 - olivier, on Wed, 16 Jul 2008 18:22:00 +0200 + Description error in wiki2xhtml + + * SVN Revision 159 - olivier, on Thu, 17 Jul 2008 12:51:08 +0200 + Added ?> in lib.crypt.php + + * SVN Revision 160 - olivier, on Thu, 17 Jul 2008 16:13:25 +0200 + Always force a new connection for mysql dblayer. + + * SVN Revision 161 - olivier, on Sun, 20 Jul 2008 16:41:36 +0200 + Added l10n::getTextDirection() method. + + * SVN Revision 162 - olivier, on Sun, 20 Jul 2008 18:35:31 +0200 + l10n::getISOcodes returns now native langue names. + + * SVN Revision 163 - olivier, on Mon, 21 Jul 2008 15:02:59 +0200 + Init content in htmlFilter::aply() + + * SVN Revision 164 - olivier, on Mon, 21 Jul 2008 15:16:15 +0200 + Basic scheme instead of BASIC. + + * SVN Revision 165 - olivier, on Wed, 30 Jul 2008 18:35:08 +0200 + Typo fix in filemanager. + + -- Olivier Meunier Wed, 06 Aug 2008 14:36:17 +0200 + +libclearbricks (0.8-21) unstable; urgency=low ; svnrev=151 + + * SVN Revision 142 - olivier, on Tue, 13 May 2008 14:26:02 +0200 + New debian changelog + + * SVN Revision 143 - olivier, on Mon, 02 Jun 2008 14:45:13 +0200 + In imageTools::memoryAllocate, multiply by 8 instead of 5 + + * SVN Revision 144 - olivier, on Tue, 03 Jun 2008 14:57:26 +0200 + Fixed sorting bug in filemanager + + * SVN Revision 145 - olivier, on Wed, 04 Jun 2008 09:15:57 +0200 + Fixed a minor bug in imageTools when image size becomes zero. + + * SVN Revision 146 - olivier, on Fri, 06 Jun 2008 10:30:46 +0200 + "'" is a space in text::tidyURL + + * SVN Revision 147 - olivier, on Fri, 06 Jun 2008 10:54:59 +0200 + Added filemanager::getPwd() and filemanager::writable() methods. + + * SVN Revision 148 - olivier, on Fri, 06 Jun 2008 14:11:34 +0200 + Removed dead line in feedReader. + + * SVN Revision 149 - olivier, on Mon, 16 Jun 2008 09:25:37 +0200 + Changed longdesc by title in wiki2xhtml. + + * SVN Revision 150 - olivier, on Thu, 19 Jun 2008 17:50:31 +0200 + Added languages in lib.l10n.php + + * SVN Revision 151 - olivier, on Wed, 25 Jun 2008 18:04:43 +0200 + Fixed bugs in l10n and url.handler. + + -- Olivier Meunier Mon, 30 Jun 2008 15:03:33 +0200 + +libclearbricks (0.8-20) unstable; urgency=low ; svnrev=141 + + * SVN Revision 121 - olivier, on Tue, 26 Feb 2008 10:20:48 +0100 + New debian changelog + + * SVN Revision 122 - olivier, on Wed, 27 Feb 2008 09:13:52 +0100 + Fixed seconds reading in fileUnzip + + * SVN Revision 124 - olivier, on Wed, 27 Feb 2008 11:22:23 +0100 + Added fileZip class + + * SVN Revision 126 - olivier, on Wed, 27 Feb 2008 14:03:43 +0100 + More memory for fileUnzip + + * SVN Revision 128 - olivier, on Sun, 02 Mar 2008 14:10:07 +0100 + Fixed time offset output for RFC822 dates. + + * SVN Revision 129 - olivier, on Sun, 02 Mar 2008 14:10:56 +0100 + Tweak in fileUnzip to handle directories in central. + + * SVN Revision 131 - olivier, on Fri, 21 Mar 2008 11:25:28 +0100 + Changed all chmod($file,fileperms(dirname($file))) calls with new files::inheritChmod() static method. + Some minor fixes. + + * SVN Revision 132 - olivier, on Fri, 21 Mar 2008 11:26:33 +0100 + Added files::inheritChmod() calls in filemanager uploadFile() and uploadBits() methods. + Closes #177. + + * SVN Revision 133 - olivier, on Fri, 04 Apr 2008 15:23:51 +0200 + Added translation support in l10n::getISOcodes() + + * SVN Revision 134 - olivier, on Fri, 04 Apr 2008 17:45:23 +0200 + Added template::blockExists(), template::valueExists() and template::tagExists() methods. + + * SVN Revision 135 - olivier, on Thu, 17 Apr 2008 17:54:27 +0200 + filemanager::exclude_list is now a regexp list and handles file upload. + + * SVN Revision 136 - olivier, on Fri, 18 Apr 2008 10:29:17 +0200 + Reverted to revision 134 + + * SVN Revision 137 - olivier, on Fri, 18 Apr 2008 11:41:03 +0200 + Added fileManager::$exclude_pattern property. This works only for files. + + * SVN Revision 138 - pep, on Wed, 23 Apr 2008 02:10:08 +0200 + Should fix problems when sending mail (/r/n or /n header terminator) + + * SVN Revision 139 - olivier, on Wed, 23 Apr 2008 18:07:03 +0200 + memory_get_usage test. + + * SVN Revision 140 - olivier, on Thu, 24 Apr 2008 11:34:02 +0200 + Fix a bug in html::absoluteURLs() + + * SVN Revision 141 - olivier, on Wed, 07 May 2008 15:44:15 +0200 + Added X-Forwarded-For support in netHttp + + -- Olivier Meunier Tue, 13 May 2008 14:04:11 +0200 + +libclearbricks (0.8-18) unstable; urgency=low ; svnrev=120 + + * SVN Revision 109 - olivier, on Tue, 19 Feb 2008 12:50:10 +0100 + New debian changelog + + * SVN Revision 110 - olivier, on Thu, 21 Feb 2008 01:23:59 +0100 + Fixed a bug and added getRootDir method in fileUnzip + + * SVN Revision 112 - olivier, on Thu, 21 Feb 2008 02:18:58 +0100 + Added isEmpty and hasFile methods in fileUnzip + + * SVN Revision 114 - olivier, on Thu, 21 Feb 2008 12:03:01 +0100 + Created text::deaccent and applied this method in text::str2URL and files::tidyFileName + + * SVN Revision 116 - olivier, on Thu, 21 Feb 2008 16:47:25 +0100 + Try to handle memory usage in imageTools. + Add a grey background on alpha channel of PNG images for resize method. + Destroy image resource in close method. + + * SVN Revision 118 - olivier, on Sat, 23 Feb 2008 19:16:15 +0100 + Fix with files::registerMimeTypes + + * SVN Revision 119 - olivier, on Mon, 25 Feb 2008 11:36:41 +0100 + fileUnzip - Added a better way to recognize directories and tries + to increase memory limit if needed. + + -- Olivier Meunier Tue, 26 Feb 2008 10:19:58 +0100 + +libclearbricks (0.8-17) unstable; urgency=low ; svnrev=108 + + * SVN Revision 108 - olivier, on Tue, 19 Feb 2008 10:25:56 +0100 + New debian changelog + + -- Olivier Meunier Tue, 19 Feb 2008 12:47:49 +0100 + +libclearbricks (0.8-14) unstable; urgency=low ; svnrev=107 + + * SVN Revision 63 - mik, on Fri, 06 Jul 2007 13:19:43 +0200 + last version + + * SVN Revision 64 - olivier, on Fri, 13 Jul 2007 12:07:00 +0200 + May have fixed some bugs in UDBS synchronize process. + + * SVN Revision 65 - olivier, on Thu, 26 Jul 2007 10:08:11 +0200 + HTML validator class + + * SVN Revision 66 - olivier, on Thu, 26 Jul 2007 10:17:29 +0200 + HTML validator documentation update + + * SVN Revision 67 - olivier, on Fri, 27 Jul 2007 16:36:30 +0200 + Fixed a serious bug with tidy in HTML Filter + + * SVN Revision 68 - olivier, on Fri, 27 Jul 2007 16:40:40 +0200 + Better way to fix tidy issue in HTML Filter + + * SVN Revision 69 - olivier, on Sat, 28 Jul 2007 10:32:28 +0200 + You can now add some patterns for html::absoluteURLHandler() + + * SVN Revision 70 - olivier, on Mon, 30 Jul 2007 11:22:32 +0200 + Try to read php://input if HTTP_RAW_POST_DATA is empty in net.xmlrpc. + + * SVN Revision 71 - olivier, on Tue, 21 Aug 2007 10:00:58 +0200 + Allow some specific index to exist in DB and Schema. Typo fixes in comments and messages. + + * SVN Revision 72 - biou, on Sun, 02 Sep 2007 11:58:16 +0200 + text::cutString now works in utf-8 + (possible problems with trackbacks) + thx sasha for detecting the bug + + * SVN Revision 73 - olivier, on Thu, 20 Sep 2007 15:22:36 +0200 + Changed some properties scope + + * SVN Revision 76 - olivier, on Wed, 07 Nov 2007 15:06:38 +0100 + Fixed a bug with timezone offset in ISO8601 and RFC822 dates + + * SVN Revision 89 - olivier, on Sat, 01 Dec 2007 12:01:23 +0100 + Changed require by require_once in dbLayer::init + + * SVN Revision 92 - olivier, on Tue, 11 Dec 2007 22:53:56 +0100 + Fixed realIP() code. + + * SVN Revision 94 - biou, on Sat, 29 Dec 2007 11:41:47 +0100 + ability to register new mime types + + * SVN Revision 95 - biou, on Wed, 09 Jan 2008 11:10:26 +0100 + autoload upgraded to use spl_autoload_register (with backward compat) + + * SVN Revision 96 - olivier, on Tue, 15 Jan 2008 16:11:37 +0100 + Changed the way we sort items in filemanager + + * SVN Revision 98 - olivier, on Fri, 15 Feb 2008 15:43:35 +0100 + Added unzip class + + * SVN Revision 100 - olivier, on Fri, 15 Feb 2008 22:31:39 +0100 + Changed getFilesList() and added getDirsList() in fileUnzip class. + + * SVN Revision 101 - olivier, on Fri, 15 Feb 2008 22:50:25 +0100 + Don't append zip file basename to target in unzipAll (fileUnzip) + + * SVN Revision 102 - olivier, on Fri, 15 Feb 2008 23:12:12 +0100 + Moved exclude condition from unzipAll() to getList() in fileUnzip. + + * SVN Revision 103 - olivier, on Sat, 16 Feb 2008 00:40:16 +0100 + Removed files::makePackage and files::installPackage. + + * SVN Revision 104 - olivier, on Mon, 18 Feb 2008 14:00:42 +0100 + Fix in urlHandler class + + * SVN Revision 106 - olivier, on Mon, 18 Feb 2008 15:58:57 +0100 + Added cleanFileName() in fileUnzip class. + + -- Olivier Meunier Tue, 19 Feb 2008 10:24:09 +0100 + +libclearbricks (0.8-13) unstable; urgency=low ; svnrev=62 + + * SVN Revision 61 - mik, on Mon, 02 Jul 2007 11:10:18 +0200 + last version changelog + + * SVN Revision 62 - olivier, on Fri, 06 Jul 2007 13:14:27 +0200 + Fixed a bug in socketMail::getFrom() + + -- Olivier Meunier Fri, 06 Jul 2007 13:18:46 +0200 + +libclearbricks (0.8-12) unstable; urgency=low ; svnrev=60 + + * SVN Revision 53 - pep, on Sun, 03 Jun 2007 12:31:25 +0200 + Changed the way we obtain current TZ + + * SVN Revision 54 - olivier, on Mon, 11 Jun 2007 10:46:06 +0200 + Changed default values in sessionDB constructor + + * SVN Revision 55 - pep, on Tue, 12 Jun 2007 19:51:21 +0200 + Fixed a bug + + * SVN Revision 56 - biou, on Wed, 13 Jun 2007 14:24:02 +0200 + permits file creation with putContent + + * SVN Revision 57 - biou, on Thu, 21 Jun 2007 17:15:06 +0200 + added a consistency check on the moveFile method + + * SVN Revision 58 - olivier, on Thu, 28 Jun 2007 16:03:35 +0200 + Added video/x-flv in lib.files + + * SVN Revision 59 - olivier, on Mon, 02 Jul 2007 10:29:10 +0200 + Fixed bugs in socketMail::getFrom + + * SVN Revision 60 - mik, on Mon, 02 Jul 2007 11:07:16 +0200 + export LANG=C before svn commands + + -- Olivier Meunier Mon, 02 Jul 2007 11:09:40 +0200 + +libclearbricks (0.8-11) unstable; urgency=low ; svnrev=52 + + * SVN Revision 36 - olivier, on Thu, 15 Feb 2007 19:02:26 +0100 + Fixed redirect bug in netHttp + + * SVN Revision 37 - olivier, on Sun, 18 Feb 2007 18:08:32 +0100 + Added default timezone in common/_main.php + + * SVN Revision 38 - olivier, on Sun, 18 Feb 2007 18:17:22 +0100 + Changed template::getData() code. + + * SVN Revision 39 - olivier, on Sun, 18 Feb 2007 22:20:26 +0100 + template::getData() optim. + + * SVN Revision 40 - olivier, on Mon, 19 Feb 2007 11:02:48 +0100 + Added strict_check mode in xmlrpcServer. Default to false. + + * SVN Revision 41 - olivier, on Mon, 19 Feb 2007 11:24:51 +0100 + Removed l10n::getHtmlFile() and added l10n::getFilePath(). + + * SVN Revision 42 - olivier, on Fri, 23 Feb 2007 14:00:39 +0100 + Fixed a bug with starting dot lines in nntp class. + + * SVN Revision 43 - pep, on Fri, 23 Feb 2007 16:43:40 +0100 + Small fix : seems better ... + + * SVN Revision 44 - olivier, on Mon, 26 Feb 2007 14:35:56 +0100 + Forgot 'class' attribute for 'a' tag. + + * SVN Revision 45 - pep, on Wed, 28 Feb 2007 02:50:48 +0100 + Shouldn't inflate incoming content when use_gzip = false + + * SVN Revision 46 - olivier, on Wed, 21 Mar 2007 16:33:28 +0100 + * New dbSchema classes collection. + * Removed getTables() and getColumns() method from dbLayer(). + * Added a database() method in dbLayer returning current database in use. + + * SVN Revision 47 - olivier, on Wed, 21 Mar 2007 23:58:02 +0100 + Returns changes count in dbStruct::synchronize(). + + * SVN Revision 48 - olivier, on Fri, 30 Mar 2007 17:30:22 +0200 + Added a static property (https_scheme_on_443) to force https scheme if port is 443 + in http::getHost(). + + * SVN Revision 49 - olivier, on Mon, 02 Apr 2007 13:35:06 +0200 + added http::browserUID. + + * SVN Revision 50 - olivier, on Mon, 02 Apr 2007 14:52:44 +0200 + Allow secure session cookies + + * SVN Revision 51 - olivier, on Mon, 02 Apr 2007 14:57:20 +0200 + Added cookie_domain for session + + * SVN Revision 52 - olivier, on Tue, 17 Apr 2007 17:53:44 +0200 + Signature fix in mail.convert + + -- Olivier Meunier Thu, 19 Apr 2007 16:06:54 +0200 + +libclearbricks (0.8-10) unstable; urgency=low ; svnrev=35 + + * SVN Revision 33 - mik, on Thu, 01 Feb 2007 18:39:56 +0100 + Romuald:gruik pour display de la date en fonction de la timezone + + * SVN Revision 34 - olivier, on Mon, 05 Feb 2007 11:05:25 +0100 + Timezone display in dt::str and dt::dt2str + + * SVN Revision 35 - olivier, on Mon, 05 Feb 2007 16:22:59 +0100 + net.xmlrpc + + -- Olivier Meunier Mon, 05 Feb 2007 17:50:20 +0100 + +libclearbricks (0.8-9) unstable; urgency=low ; svnrev=32 + + * SVN Revision 30 - olivier, on Thu, 25 Jan 2007 16:53:01 +0100 + Implemented status_string in netHttp + + * SVN Revision 31 - olivier, on Wed, 31 Jan 2007 13:53:10 +0100 + NEWNEWS implementation in netNntp::getNewArticles(). + + * SVN Revision 32 - olivier, on Wed, 31 Jan 2007 19:32:05 +0100 + Fix in net.nntp + + -- Olivier Meunier Wed, 31 Jan 2007 19:36:08 +0100 + +libclearbricks (0.8-8) unstable; urgency=low ; svnrev=29 + + * SVN Revision 28 - olivier, on Thu, 25 Jan 2007 10:31:20 +0100 + Can now specify a port for postgresql connection. + + * SVN Revision 29 - olivier, on Thu, 25 Jan 2007 14:47:15 +0100 + Fix in text::QPEncode() static method + + -- Olivier Meunier Thu, 25 Jan 2007 15:31:25 +0100 + +libclearbricks (0.8-7) unstable; urgency=low ; svnrev=27 + + * SVN Revision 26 - olivier, on Wed, 17 Jan 2007 16:57:51 +0100 + Chmod on feed cache file + + * SVN Revision 27 - olivier, on Wed, 17 Jan 2007 16:58:09 +0100 + Chmod on template cache file + + -- Olivier Meunier Wed, 17 Jan 2007 16:59:11 +0100 + +libclearbricks (0.8-6) unstable; urgency=low ; svnrev=25 + + * SVN Revision 25 - olivier, on Wed, 17 Jan 2007 16:22:49 +0100 + Fixed chmod bug. + + -- Olivier Meunier Wed, 17 Jan 2007 16:23:25 +0100 + +libclearbricks (0.8-5) unstable; urgency=low ; svnrev=24 + + * SVN Revision 24 - olivier, on Tue, 16 Jan 2007 16:13:10 +0100 + New debian changelog + + -- Olivier Meunier Wed, 17 Jan 2007 14:26:32 +0100 + +libclearbricks (0.8-4) unstable; urgency=low ; svnrev=23 + + * SVN Revision 18 - mik, on Fri, 12 Jan 2007 13:33:59 +0100 + libclearbricks' readme in the package + + * SVN Revision 19 - mik, on Fri, 12 Jan 2007 13:36:13 +0100 + empty so removed + + * SVN Revision 20 - mik, on Mon, 15 Jan 2007 18:24:05 +0100 + README file copied in debian dir + + * SVN Revision 21 - olivier, on Tue, 16 Jan 2007 15:17:05 +0100 + Test .svn dir before mkdcl.php launch + + * SVN Revision 22 - olivier, on Tue, 16 Jan 2007 15:48:04 +0100 + Fix in files::touch() method + + * SVN Revision 23 - olivier, on Tue, 16 Jan 2007 16:12:02 +0100 + Zend hash del key or index fix. + + -- Olivier Meunier Tue, 16 Jan 2007 16:12:50 +0100 + +libclearbricks (0.8-3) unstable; urgency=low ; svnrev=17 + + * SVN Revision 13 - olivier, on Wed, 10 Jan 2007 00:51:10 +0100 + Makefile and Debian package for clearbricks + + * SVN Revision 14 - olivier, on Wed, 10 Jan 2007 16:27:08 +0100 + Clearbricks Debian packager + + * SVN Revision 15 - olivier, on Thu, 11 Jan 2007 14:44:42 +0100 + Test if database functions exist on dblayer driver load. + + * SVN Revision 16 - olivier, on Fri, 12 Jan 2007 01:30:36 +0100 + Fixed Windows bug in files::makeDir. + + * SVN Revision 17 - olivier, on Fri, 12 Jan 2007 01:57:56 +0100 + Fixed an issue with recursive files::makeDir and open_basedir. + + -- Olivier Meunier Fri, 12 Jan 2007 13:34:21 +0100 + +libclearbricks (0.8-2) unstable; urgency=low ; svnrev=12 + + * SVN Revision 10 - olivier, on Tue, 09 Jan 2007 13:53:03 +0100 + Added default HTTP Status Messages in http::head() + + * SVN Revision 11 - olivier, on Tue, 09 Jan 2007 16:46:09 +0100 + Added clearbricks version number. + + * SVN Revision 12 - olivier, on Wed, 10 Jan 2007 00:17:53 +0100 + Fixed PHP 5.0 compatibilty issue \o/ + + -- Olivier Meunier Wed, 10 Jan 2007 16:24:31 +0100 + +libclearbricks (0.8-1) unstable; urgency=low ; svnrev=9 + + First upstream release + + -- Olivier Meunier Tue, 09 Jan 2007 16:50:12 +0100 + diff --git a/v2/dotclear/inc/libs/clearbricks/debian/compat b/v2/dotclear/inc/libs/clearbricks/debian/compat new file mode 100644 index 0000000..b8626c4 --- /dev/null +++ b/v2/dotclear/inc/libs/clearbricks/debian/compat @@ -0,0 +1 @@ +4 diff --git a/v2/dotclear/inc/libs/clearbricks/debian/control b/v2/dotclear/inc/libs/clearbricks/debian/control new file mode 100644 index 0000000..f371d2c --- /dev/null +++ b/v2/dotclear/inc/libs/clearbricks/debian/control @@ -0,0 +1,14 @@ +Source: libclearbricks +Section: web +Priority: optional +Maintainer: Olivier Meunier +Build-Depends: debhelper (>= 4.0.0), php5-cli +Standards-Version: 3.6.1 + +Package: libclearbricks +Architecture: all +Depends: ${misc:Depends}, php5-cli | php5-cgi | libapache2-mod-php5 | libapache-mod-php5 +Suggests: php5-pgsql | php5-sqlite | php5-mysql, php5-gd, php5-tidy +Description: libclearbricks is a set of PHP classes and utilities + Clearbricks is not yet another PHP framework. Clearbricks is only + about code and efficiency, consider it as a toolbox. diff --git a/v2/dotclear/inc/libs/clearbricks/debian/copyright b/v2/dotclear/inc/libs/clearbricks/debian/copyright new file mode 100644 index 0000000..235ba0d --- /dev/null +++ b/v2/dotclear/inc/libs/clearbricks/debian/copyright @@ -0,0 +1,27 @@ +This is Clearbricks, written and maintained by Olivier Meunier <> +on Fri, 29 Dec 2006 16:55:20 +0200. + +The original source can always be found at: + http://clearbricks.org/ + +Copyright (C) 2006 Olivier Meunier + +License: + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this package; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. + +On Debian systems, the complete text of the GNU General +Public License can be found in `/usr/share/common-licenses/GPL'. diff --git a/v2/dotclear/inc/libs/clearbricks/debian/dirs b/v2/dotclear/inc/libs/clearbricks/debian/dirs new file mode 100644 index 0000000..67ddb20 --- /dev/null +++ b/v2/dotclear/inc/libs/clearbricks/debian/dirs @@ -0,0 +1 @@ +usr/lib/clearbricks diff --git a/v2/dotclear/inc/libs/clearbricks/debian/docs b/v2/dotclear/inc/libs/clearbricks/debian/docs new file mode 100644 index 0000000..e845566 --- /dev/null +++ b/v2/dotclear/inc/libs/clearbricks/debian/docs @@ -0,0 +1 @@ +README diff --git a/v2/dotclear/inc/libs/clearbricks/debian/mkdcl.php b/v2/dotclear/inc/libs/clearbricks/debian/mkdcl.php new file mode 100644 index 0000000..39688c7 --- /dev/null +++ b/v2/dotclear/inc/libs/clearbricks/debian/mkdcl.php @@ -0,0 +1,198 @@ +#!/usr/bin/env php +f)) { + throw new Exception('No changelog file found'); + } + } + + private function readLastRevision() + { + $f = file($this->f); + $res = array(); + $done = false; + + foreach ($f as $v) + { + $v = rtrim($v,"\n"); + + # First line of a change + if (strpos($v,' ') !== 0 && trim($v) != '') + { + if ($done) { + break; + } + + $done = true; + $res = $this->getPackageInfo($v,$res[$i]); + } + # Maintainer information + elseif (strpos($v,' --') === 0) + { + $res['maintainer'] = $this->getMaintainerInfo($v); + } + # Changelog + elseif (strpos($v,' ') === 0) + { + $res['changelog'] .= $v."\n"; + } + } + + return $res; + } + + public function writeChangelog() + { + $ch = $this->readLastRevision(); + + # Get debian revision + $rev = 1; + if (preg_match('/^(.*)-(\d+)$/',$ch['version'],$m)) { + $ch['version'] = $m[1]; + $rev = $m[2]; + } + $rev++; + + # Get SVN revision + $svnrev = isset($ch['keywords']['svnrev']) ? (integer) $ch['keywords']['svnrev'] : 1; + + # Get current SVN revision + $currev = svnInfo::getCurrentRevision(); + if ($currev <= $svnrev) { + return; + } + + $changelog = ''; + $changes = svnInfo::getChangeLog($svnrev+1,$currev); + foreach ($changes as $k => $v) + { + $changelog .= + ' * SVN Revision '.$k.' - '.$v['author']. + ', on '.date('r',strtotime($v['date']))."\n". + ' '.trim(preg_replace('/\n/ms',"\n ",$v['msg']))."\n\n"; + + } + + $res = + $ch['package'].' ('.$ch['version'].'-'.$rev.') '.$ch['dist'].'; urgency='.$ch['keywords']['urgency']. + ' ; svnrev='.$currev. + "\n\n". + rtrim($changelog)."\n\n". + ' -- '.$ch['maintainer']['name'].' <'.$ch['maintainer']['email'].'> '.date('r')."\n". + "\n"; + + $old_changelog = file_get_contents($this->f); + $fp = fopen($this->f,'wb'); + fwrite($fp,$res.$old_changelog); + fclose($fp); + } + + private function getPackageInfo($l) + { + $res = array( + 'package' => '', + 'version' => '', + 'dist' => '', + 'keywords' => '', + 'changelog' => '', + 'maintainer' => array() + ); + + $l = explode(';',$l); + + # Info + $info = array_shift($l); + $res['package'] = strtok($info,' '); + $res['version'] = strtok('()'); + $res['dist'] = trim(strtok(';')); + + # Keywords + foreach ($l as $v) { + $v = explode('=',$v); + if (count($v) == 2) { + $res['keywords'][trim($v[0])] = trim($v[1]); + } + } + + return $res; + } + + private function getMaintainerInfo($l) + { + $res = array( + 'name' => '', + 'email' => '', + 'date' => '' + ); + + if (preg_match('/^ -- (.+?) <(.+?)> (.+?)$/',$l,$m)) { + $res['name'] = $m[1]; + $res['email'] = $m[2]; + $res['date'] = $m[3]; + } + + return $res; + } +} + +class svnInfo +{ + public static function getCurrentRevision() + { + $info = `LANG=C svn info --xml`; + + $x = @simplexml_load_string($info); + if (!$x) { + throw new Exception('Unable to get current SVN revision'); + } + + $rev = $x->entry->commit['revision']; + + if (!$rev) { + throw new Exception('Last revision number is invalid'); + } + + return (integer) $rev; + } + + public static function getChangeLog($fromrev,$torev) + { + $log = `LANG=C svn log --xml -r $fromrev:$torev`; + + $x = @simplexml_load_string($log); + if (!$x) { + throw new Exception('Unable to open SVN log'); + } + + $res = array(); + foreach ($x->logentry as $change) + { + $res[(integer) $change['revision']] = array( + 'author' => (string) $change->author, + 'date' => (string) $change->date, + 'msg' => trim((string) $change->msg) + ); + } + + return $res; + } +} + +# Main +try +{ + $ch = new debianChangelog(); + $ch->writeChangelog(); +} +catch (Exception $e) +{ + fwrite(STDERR,$e->getMessage()."\n"); + exit(1); +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/libs/clearbricks/debian/rules b/v2/dotclear/inc/libs/clearbricks/debian/rules new file mode 100644 index 0000000..5f5f3e9 --- /dev/null +++ b/v2/dotclear/inc/libs/clearbricks/debian/rules @@ -0,0 +1,62 @@ +#!/usr/bin/make -f +# -*- makefile -*- + +DEST=debian/dotclear/usr/share/dotclear + +configure: configure-stamp +configure-stamp: + dh_testdir + # Add here commands to configure the package. + + touch configure-stamp + +build: build-stamp + +build-stamp: configure-stamp + dh_testdir + + # Add here commands to compile the package. + $(MAKE) config + touch build-stamp + +clean: + dh_testdir + dh_testroot + rm -f build-stamp configure-stamp + + # Add here commands to clean up after the build process. + -$(MAKE) clean + + dh_clean + +install: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + + cp -af $(CURDIR)/_dist/clearbricks $(CURDIR)/debian/libclearbricks/usr/lib/ + +# Build architecture-independent files here. +binary-indep: build install +# We have nothing to do by default. + +# Build architecture-dependent files here. +binary-arch: build install + dh_testdir + dh_testroot + dh_installchangelogs + dh_installdocs + dh_installexamples + dh_installman + dh_link + dh_strip + dh_compress + dh_fixperms + dh_installdeb + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install configure diff --git a/v2/dotclear/inc/libs/clearbricks/diff/lib.diff.php b/v2/dotclear/inc/libs/clearbricks/diff/lib.diff.php new file mode 100644 index 0000000..ccc62f3 --- /dev/null +++ b/v2/dotclear/inc/libs/clearbricks/diff/lib.diff.php @@ -0,0 +1,366 @@ +0); + $end_reached = false; + + # Find LCS length + for ($D = 0; $D < $cx+$cy+1 && !$end_reached; $D++) + { + for ($k = -$D; $k <= $D; $k += 2) + { + $x = ($k == -$D || $k != $D && $V[$k-1] < $V[$k+1]) + ? $V[$k+1] : $V[$k-1]+1; + $y = $x-$k; + + while ($x < $cx && $y < $cy && $src[$x] == $dst[$y]) + { + $x++; $y++; + } + + $V[$k] = $x; + + if ($x == $cx && $y == $cy) { + $end_reached = true; + break; + } + } + $stack[] = $V; + } + $D--; + + # Recover edit path + $res = array(); + for ($D = $D; $D > 0; $D--) + { + $V = array_pop($stack); + $cx = $x; + $cy = $y; + + # Try right diagonal + $k++; + $x = array_key_exists($k,$V) ? $V[$k] : 0; + $y = $x-$k; + $y++; + + while ($x < $cx && $y < $cy + && isset($src[$x]) && isset($dst[$y]) && $src[$x] == $dst[$y]) + { + $x++; $y++; + } + + if ($x == $cx && $y == $cy) { + $x = $V[$k]; + $y = $x-$k; + + $res[] = array('i',$x,$y); + continue; + } + + # Right diagonal wasn't the solution, use left diagonal + $k -= 2; + $x = $V[$k]; + $y = $x-$k; + $res[] = array('d',$x,$y); + } + + return array_reverse($res); + } + + /** + * Returns unified diff from source $src to destination $dst. + * + * @param string $src Original data + * @param string $dst New data + * @param string $ctx Context length + * @return string + */ + public static function uniDiff($src,$dst,$ctx=2) + { + list($src,$dst) = array(explode("\n",$src),explode("\n",$dst)); + $cx = count($src); $cy = count($dst); + + $ses = diff::SES($src,$dst); + $res = ''; + + $pos_x = 0; + $pos_y = 0; + $old_lines = 0; + $new_lines = 0; + $buffer = ''; + + foreach ($ses as $cmd) + { + list($cmd,$x,$y) = array($cmd[0],$cmd[1],$cmd[2]); + + # New chunk + if ($x-$pos_x > 2*$ctx || $pos_x == 0 && $x > $ctx) + { + # Footer for current chunk + for ($i = 0; $buffer && $i < $ctx; $i++) + { + $buffer .= sprintf(self::$us_ctx,$src[$pos_x+$i]); + } + + # Header for current chunk + $res .= sprintf(self::$us_range, + $pos_x+1-$old_lines,$old_lines+$i, + $pos_y+1-$new_lines,$new_lines+$i + ).$buffer; + + $pos_x = $x; + $pos_y = $y; + $old_lines = 0; + $new_lines = 0; + $buffer = ''; + + # Header for next chunk + for ($i = $ctx; $i > 0 ; $i--) + { + $buffer .= sprintf(self::$us_ctx,$src[$pos_x-$i]); + $old_lines++; + $new_lines++; + } + } + + # Context + while ($x > $pos_x) + { + $old_lines++; + $new_lines++; + $buffer .= sprintf(self::$us_ctx,$src[$pos_x]); + $pos_x++; + $pos_y++; + } + # Deletion + if ($cmd == 'd') { + $old_lines++; + $buffer .= sprintf(self::$us_del,$src[$x]); + $pos_x++; + } + # Insertion + elseif ($cmd == 'i') { + $new_lines++; + $buffer .= sprintf(self::$us_ins,$dst[$y]); + $pos_y++; + } + } + + # Remaining chunk + if ($buffer) + { + # Footer + for ($i = 0; $i < $ctx; $i++) + { + if (!isset($src[$pos_x+$i])) { + break; + } + $buffer .= sprintf(self::$us_ctx,$src[$pos_x+$i]); + } + + # Header for current chunk + $res .= sprintf(self::$us_range, + $pos_x+1-$old_lines,$old_lines+$i, + $pos_y+1-$new_lines,$new_lines+$i + ).$buffer; + } + return $res; + } + + /** + * Applies a unified patch to a piece of text. + * Throws an exception on invalid or not applicable diff. + * + * @param string $src Source text + * @param string $diff Patch to apply + * @return string + */ + public static function uniPatch($src,$diff) + { + $dst = array(); + $src = explode("\n",$src); + $diff = explode("\n",$diff); + + $t = count($src); + $old_length = $new_length = 0; + + foreach ($diff as $line) + { + # New chunk + if (preg_match(self::$up_range,$line,$m)) { + $m[1]--; $m[3]--; + + if ($m[1] > $t) { + throw new Exception(__('Bad range')); + } + + if ($t - count($src) > $m[1]) { + throw new Exception(__('Invalid range')); + } + + while ($t - count($src) < $m[1]) + { + $dst[] = array_shift($src); + } + + if (count($dst) !== $m[3]) { + throw new Exception(__('Invalid line number')); + } + + if ($old_length || $new_length) { + throw new Exception(__('Chunk is out of range')); + } + + $old_length = (integer) $m[2]; + $new_length = (integer) $m[4]; + } + # Context + elseif (preg_match(self::$up_ctx,$line,$m)) { + if (array_shift($src) !== $m[1]) { + throw new Exception(__('Bad context')); + } + $dst[] = $m[1]; + $old_length--; + $new_length--; + } + # Addition + elseif (preg_match(self::$up_ins,$line,$m)) { + $dst[] = $m[1]; + $new_length--; + } + # Deletion + elseif (preg_match(self::$up_del,$line,$m)) { + if (array_shift($src) !== $m[1]) { + throw new Exception(__('Bad context (in deletion)')); + } + $old_length--; + } + elseif ($line == '') { + continue; + } + else { + throw new Exception(__('Invalid diff format')); + } + } + + if ($old_length || $new_length) { + throw new Exception(__('Chunk is out of range')); + } + + return implode("\n",array_merge($dst,$src)); + } + + /** + * Throws an exception on invalid unified diff. + * + * @param string $diff Diff text to check + */ + public static function uniCheck($diff) + { + $diff = explode("\n",$diff); + + $cur_line = 1; $ins_lines = 0; + + # Chunk length + $old_length = $new_length = 0; + + foreach ($diff as $line) + { + # New chunk + if (preg_match(self::$up_range,$line,$m)) { + if ($cur_line > $m[1]) { + throw new Exception(__('Invalid range')); + } + while ($cur_line < $m[1]) + { + $ins_lines++; $cur_line++; + } + if ($ins_lines+1 != $m[3]) { + throw new Exception(__('Invalid line number')); + } + + if ($old_length || $new_length) { + throw new Exception(__('Chunk is out of range')); + } + + $old_length = $m[2]; + $new_length = $m[4]; + } + # Context + elseif (preg_match(self::$up_ctx,$line,$m)) { + $ins_lines++; $cur_line++; + $old_length--; + $new_length--; + } + # Addition + elseif (preg_match(self::$up_ins,$line,$m)) { + $ins_lines++; + $new_length--; + } + # Deletion + elseif (preg_match(self::$up_del,$line,$m)) { + $cur_line++; + $old_length--; + } + # Skip empty lines + elseif ($line == '') { + continue; + } + # Unrecognized diff format + else { + throw new Exception(__('Invalid diff format')); + } + } + + if ($old_length || $new_length) { + throw new Exception(__('Chunk is out of range')); + } + } +} + +?> \ No newline at end of file diff --git a/v2/dotclear/inc/libs/clearbricks/diff/lib.tidy.diff.php b/v2/dotclear/inc/libs/clearbricks/diff/lib.tidy.diff.php new file mode 100644 index 0000000..3885797 --- /dev/null +++ b/v2/dotclear/inc/libs/clearbricks/diff/lib.tidy.diff.php @@ -0,0 +1,353 @@ +up_range,$udiff,$context); + + $chunks = preg_split($this->up_range,$udiff,-1,PREG_SPLIT_NO_EMPTY); + + foreach ($chunks as $k => $chunk) + { + $tidy_chunk = new tidyDiffChunk(); + $tidy_chunk->setRange( + (int) $context[1][$k], + (int) $context[2][$k], + (int) $context[3][$k], + (int) $context[4][$k] + ); + + $old_line = (int) $context[1][$k]; + $new_line = (int) $context[3][$k]; + + foreach (explode("\n",$chunk) as $line) + { + # context + if (preg_match($this->up_ctx,$line,$m)) { + $tidy_chunk->addLine('context',array($old_line,$new_line),$m[1]); + $old_line++; + $new_line++; + } + # insertion + if (preg_match($this->up_ins,$line,$m)) { + $tidy_chunk->addLine('insert',array($old_line,$new_line),$m[1]); + $new_line++; + } + # deletion + if (preg_match($this->up_del,$line,$m)) { + $tidy_chunk->addLine('delete',array($old_line,$new_line),$m[1]); + $old_line++; + } + } + + if ($inline_changes) { + $tidy_chunk->findInsideChanges(); + } + + array_push($this->__data,$tidy_chunk); + } + } + + /** + * All chunks + * + * Returns all chunks defined. + * + * @return array + */ + public function getChunks() + { + return $this->__data; + } +} + +/** +* TIDY diff chunk +* +* A diff chunk representation. Used by a TIDY diff. +* +* @package Clearbricks +* @subpackage Diff +*/ +class tidyDiffChunk +{ + /** @var array Chunk information array */ + protected $__info; + /** @var array Chunk data array */ + protected $__data; + + /** + * Constructor + * + * Creates and initializes a chunk representation for a TIDY diff. + */ + public function __construct() + { + $this->__info = array( + 'context' => 0, + 'delete' => 0, + 'insert' => 0, + 'range' => array( + 'start' => array(), + 'end' => array() + ) + ); + $this->__data = array(); + } + + /** + * Set chunk range + * + * Sets chunk range in TIDY chunk object. + * + * @param integer $line_start Old start line number + * @param integer $offest_start Old offset number + * @param integer $line_end new start line number + * @param integer $offset_end New offset number + */ + public function setRange($line_start,$offest_start,$line_end,$offset_end) + { + if (is_int($line_start) && is_int($offest_start) && is_int($line_end) && is_int($offset_end)) + { + $this->__info['range']['start'] = array($line_start,$offest_start); + $this->__info['range']['end'] = array($line_end,$offset_end); + } + } + + /** + * Add line + * + * Adds TIDY line object for TIDY chunk object. + * + * @param string $type Tine type + * @param array $lines Line number for old and new context + * @param string $content Line content + */ + public function addLine($type,$lines,$content) + { + $tidy_line = new tidyDiffLine($type,$lines,$content); + + if (!is_null($tidy_line)) { + array_push($this->__data,$tidy_line); + $this->__info[$type]++; + } + } + + /** + * All lines + * + * Returns all lines defined. + * + * @return array + */ + public function getLines() + { + return $this->__data; + } + + /** + * Chunk information + * + * Returns chunk information according to the given name, null otherwise. + * + * @param string $n Info name + * @return string + */ + public function getInfo($n) + { + return array_key_exists($n,$this->__info) ? $this->__info[$n] : null; + } + + /** + * Find changes + * + * Finds changes inside lines for each groups of diff lines. Wraps changes + * by string \0 and \1 + */ + public function findInsideChanges() + { + $groups = $this->getGroups(); + + foreach ($groups as $group) { + $middle = count($group) / 2; + for ($i = 0; $i < $middle; $i++) { + $from = $group[$i]; + $to = $group[$i + $middle]; + $threshold = $this->getChangeExtent($from->content,$to->content); + + if ($threshold['start'] != 0 || $threshold['end'] != 0) + { + $start = $threshold['start']; + $end = $threshold['end'] + strlen($from->content); + $offset = $end - $start; + $from->overwrite( + substr($from->content,0,$start).'\0'. + substr($from->content,$start,$offset).'\1'. + substr($from->content,$end,strlen($from->content)) + ); + $end = $threshold['end'] + strlen($to->content); + $offset = $end - $start; + $to->overwrite( + substr($to->content,0,$start).'\0'. + substr($to->content,$start,$offset).'\1'. + substr($to->content,$end,strlen($to->content)) + ); + } + } + } + } + + private function getGroups() + { + $res = $group = array(); + $allowed_types = array('delete','insert'); + $delete = $insert = 0; + + foreach ($this->__data as $k => $line) { + if (in_array($line->type,$allowed_types)) { + array_push($group,$line); + ${$line->type}++; + } else { + if ($delete === $insert && count($group) > 0) { + array_push($res,$group); + } + $delete = $insert = 0; + $group = array(); + } + } + if ($delete === $insert && count($group) > 0) { + array_push($res,$group); + } + + return $res; + } + + private function getChangeExtent($str1,$str2) + { + $start = 0; + $limit = min(strlen($str1), strlen($str2)); + while ($start < $limit and $str1[$start] === $str2[$start]) { + $start++; + } + + $end = -1; + $limit = $limit - $start; + + while (-$end <= $limit && $str1[strlen($str1) + $end] === $str2[strlen($str2) + $end]) { + $end--; + } + + return array('start' => $start,'end' => $end +1); + } +} + +/** +* TIDY diff line +* +* A diff line representation. Used by a TIDY chunk. +* +* @package Clearbricks +* @subpackage Diff +*/ +class tidyDiffLine +{ + /** @var string Line type */ + protected $type; + /** @var array Line number for old and new context */ + protected $lines; + /** @var string Line content */ + protected $content; + + /** + * Constructor + * + * Creates a line representation for a tidy chunk. Returns a new object if + * all parameters are fine, null otherwise. + * + * @param string $type Tine type + * @param array $lines Line number for old and new context + * @param string $content Line content + * @return object + */ + public function __construct($type,$lines,$content) + { + $allowed_type = array('context','delete','insert'); + + if (in_array($type,$allowed_type) && is_array($lines) && is_string($content)) { + $this->type = $type; + $this->lines = $lines; + $this->content = $content; + + return $this; + } + + return null; + } + + /** + * Magic get + * + * Returns field content according to the given name, null otherwise. + * + * @param string $n Field name + * @return string + */ + public function __get($n) + { + return isset($n,$this) ? $this->{$n} : null; + } + + /** + * Overwrite + * + * Overwrites content for the current line. + * + * @param string $content Line content + */ + public function overwrite($content) + { + if (is_string($content)) { + $this->content = $content; + } + } +} + +?> \ No newline at end of file diff --git a/v2/dotclear/inc/libs/clearbricks/ext/incutio.ixr_library.php b/v2/dotclear/inc/libs/clearbricks/ext/incutio.ixr_library.php new file mode 100644 index 0000000..7a5ead1 --- /dev/null +++ b/v2/dotclear/inc/libs/clearbricks/ext/incutio.ixr_library.php @@ -0,0 +1,856 @@ + htmlspecialchars) + Site: http://scripts.incutio.com/xmlrpc/ + Manual: http://scripts.incutio.com/xmlrpc/manual.php + Made available under the Artistic License: http://www.opensource.org/licenses/artistic-license.php +*/ + + +class IXR_Value +{ + public $data; + public $type; + + function IXR_Value ($data, $type = false) { + $this->data = $data; + if (!$type) { + $type = $this->calculateType(); + } + $this->type = $type; + if ($type == 'struct') { + /* Turn all the values in the array in to new IXR_Value objects */ + foreach ($this->data as $key => $value) { + $this->data[$key] = new IXR_Value($value); + } + } + if ($type == 'array') { + for ($i = 0, $j = count($this->data); $i < $j; $i++) { + $this->data[$i] = new IXR_Value($this->data[$i]); + } + } + } + function calculateType() { + if ($this->data === true || $this->data === false) { + return 'boolean'; + } + if (is_integer($this->data)) { + return 'int'; + } + if (is_double($this->data)) { + return 'double'; + } + // Deal with IXR object types base64 and date + if (is_object($this->data) && $this->data instanceof IXR_Date) { + return 'date'; + } + if (is_object($this->data) && $this->data instanceof IXR_Base64) { + return 'base64'; + } + // If it is a normal PHP object convert it in to a struct + if (is_object($this->data)) { + + $this->data = get_object_vars($this->data); + return 'struct'; + } + if (!is_array($this->data)) { + return 'string'; + } + /* We have an array - is it an array or a struct ? */ + if ($this->isStruct($this->data)) { + return 'struct'; + } else { + return 'array'; + } + } + function getXml() { + /* Return XML for this value */ + switch ($this->type) { + case 'boolean': + return ''.(($this->data) ? '1' : '0').''; + break; + case 'int': + return ''.$this->data.''; + break; + case 'double': + return ''.$this->data.''; + break; + case 'string': + return ''.htmlspecialchars($this->data).''; + break; + case 'array': + $return = ''."\n"; + foreach ($this->data as $item) { + $return .= ' '.$item->getXml()."\n"; + } + $return .= ''; + return $return; + break; + case 'struct': + $return = ''."\n"; + foreach ($this->data as $name => $value) { + $return .= " $name"; + $return .= $value->getXml()."\n"; + } + $return .= ''; + return $return; + break; + case 'date': + case 'base64': + return $this->data->getXml(); + break; + } + return false; + } + function isStruct($array) { + /* Nasty function to check if an array is a struct or not */ + $expected = 0; + foreach ($array as $key => $value) { + if ((string)$key != (string)$expected) { + return true; + } + $expected++; + } + return false; + } +} + + +class IXR_Message +{ + public $brutxml; + public $message; + public $messageType; // methodCall / methodResponse / fault + public $faultCode; + public $faultString; + public $methodName; + public $params; + // Current variable stacks + public $_arraystructs = array(); // The stack used to keep track of the current array/struct + public $_arraystructstypes = array(); // Stack keeping track of if things are structs or array + public $_currentStructName = array(); // A stack as well + public $_param; + public $_value; + public $_currentTag; + public $_currentTagContents; + // The XML parser + public $_parser; + function IXR_Message ($message) { + $this->brutxml = $this->message = $message; + } + function parse() { + // first remove the XML declaration + $this->message = preg_replace('/<\?xml(.*)?\?'.'>/', '', $this->message); + if (trim($this->message) == '') { + return false; + } + $this->_parser = xml_parser_create(); + // Set XML parser to take the case of tags in to account + xml_parser_set_option($this->_parser, XML_OPTION_CASE_FOLDING, false); + // Set XML parser callback functions + xml_set_object($this->_parser, $this); + xml_set_element_handler($this->_parser, 'tag_open', 'tag_close'); + xml_set_character_data_handler($this->_parser, 'cdata'); + if (!xml_parse($this->_parser, $this->message)) { + /* die(sprintf('XML error: %s at line %d', + xml_error_string(xml_get_error_code($this->_parser)), + xml_get_current_line_number($this->_parser))); */ + return false; + } + xml_parser_free($this->_parser); + // Grab the error messages, if any + if ($this->messageType == 'fault') { + $this->faultCode = $this->params[0]['faultCode']; + $this->faultString = $this->params[0]['faultString']; + } + return true; + } + function tag_open($parser, $tag, $attr) { + $this->currentTag = $tag; + switch($tag) { + case 'methodCall': + case 'methodResponse': + case 'fault': + $this->messageType = $tag; + break; + /* Deal with stacks of arrays and structs */ + case 'data': // data is to all intents and puposes more interesting than array + $this->_arraystructstypes[] = 'array'; + $this->_arraystructs[] = array(); + break; + case 'struct': + $this->_arraystructstypes[] = 'struct'; + $this->_arraystructs[] = array(); + break; + } + } + function cdata($parser, $cdata) { + $this->_currentTagContents .= $cdata; + } + function tag_close($parser, $tag) { + $valueFlag = false; + switch($tag) { + case 'int': + case 'i4': + $value = (int)trim($this->_currentTagContents); + $this->_currentTagContents = ''; + $valueFlag = true; + break; + case 'double': + $value = (double)trim($this->_currentTagContents); + $this->_currentTagContents = ''; + $valueFlag = true; + break; + case 'string': + $value = (string)trim($this->_currentTagContents); + $this->_currentTagContents = ''; + $valueFlag = true; + break; + case 'dateTime.iso8601': + $value = new IXR_Date(trim($this->_currentTagContents)); + // $value = $iso->getTimestamp(); + $this->_currentTagContents = ''; + $valueFlag = true; + break; + case 'value': + // "If no type is indicated, the type is string." + if (trim($this->_currentTagContents) != '') { + $value = (string)$this->_currentTagContents; + $this->_currentTagContents = ''; + $valueFlag = true; + } + break; + case 'boolean': + $value = (boolean)trim($this->_currentTagContents); + $this->_currentTagContents = ''; + $valueFlag = true; + break; + case 'base64': + $value = base64_decode($this->_currentTagContents); + $this->_currentTagContents = ''; + $valueFlag = true; + break; + /* Deal with stacks of arrays and structs */ + case 'data': + case 'struct': + $value = array_pop($this->_arraystructs); + array_pop($this->_arraystructstypes); + $valueFlag = true; + break; + case 'member': + array_pop($this->_currentStructName); + break; + case 'name': + $this->_currentStructName[] = trim($this->_currentTagContents); + $this->_currentTagContents = ''; + break; + case 'methodName': + $this->methodName = trim($this->_currentTagContents); + $this->_currentTagContents = ''; + break; + } + if ($valueFlag) { + /* + if (!is_array($value) && !is_object($value)) { + $value = trim($value); + } + */ + if (count($this->_arraystructs) > 0) { + // Add value to struct or array + if ($this->_arraystructstypes[count($this->_arraystructstypes)-1] == 'struct') { + // Add to struct + $this->_arraystructs[count($this->_arraystructs)-1][$this->_currentStructName[count($this->_currentStructName)-1]] = $value; + } else { + // Add to array + $this->_arraystructs[count($this->_arraystructs)-1][] = $value; + } + } else { + // Just add as a paramater + $this->params[] = $value; + } + } + } +} + + +class IXR_Server +{ + public $data; + public $callbacks = array(); + public $message; + public $capabilities; + function IXR_Server($callbacks = false, $data = false) { + $this->setCapabilities(); + if ($callbacks) { + $this->callbacks = $callbacks; + } + $this->setCallbacks(); + $this->serve($data); + } + function head($code,$msg) + { + $status_mode = preg_match('/cgi/',php_sapi_name()); + + if ($status_mode) { + header('Status: '.$code.' '.$msg); + } else { + if (version_compare(phpversion(),'4.3.0','>=')) { + header($msg, TRUE, $code); + } else { + header('HTTP/1.x '.$code.' '.$msg); + } + } + } + function serve($data = false, $encoding='ISO-8859-1') { + if (!$data) { + global $HTTP_RAW_POST_DATA; + if (!$HTTP_RAW_POST_DATA) { + $this->head(405,'Method Not Allowed'); + header('Content-Type: text/plain'); + echo 'XML-RPC server accepts POST requests only.'; + exit; + } + $data = $HTTP_RAW_POST_DATA; + } + $this->message = new IXR_Message($data); + if (!$this->message->parse()) { + $this->error(-32700, 'parse error. not well formed'); + } + if ($this->message->messageType != 'methodCall') { + $this->error(-32600, 'server error. invalid xml-rpc. not conforming to spec. Request must be a methodCall'); + } + $result = $this->call($this->message->methodName, $this->message->params); + // Is the result an error? + if ($result instanceof IXR_Error) { + $this->error($result); + } + // Encode the result + $r = new IXR_Value($result); + $resultxml = $r->getXml(); + // Create the XML + $xml = << + + + + $resultxml + + + + + +EOD; + // Send it + $this->output($xml,$encoding); + } + function call($methodname, $args) { + if (!$this->hasMethod($methodname)) { + return new IXR_Error(-32601, 'server error. requested method '.$methodname.' does not exist.'); + } + $method = $this->callbacks[$methodname]; + // Perform the callback and send the response + if (count($args) == 1) { + // If only one paramater just send that instead of the whole array + $args = $args[0]; + } + // Are we dealing with a function or a method? + if (substr($method, 0, 5) == 'this:') { + // It's a class method - check it exists + $method = substr($method, 5); + if (!method_exists($this, $method)) { + return new IXR_Error(-32601, 'server error. requested class method "'.$method.'" does not exist.'); + } + // Call the method + $result = $this->$method($args); + } else { + // It's a function - does it exist? + if (!function_exists($method)) { + return new IXR_Error(-32601, 'server error. requested function "'.$method.'" does not exist.'); + } + // Call the function + $result = $method($args); + } + return $result; + } + + function error($error, $message = false) { + // Accepts either an error object or an error code and message + if ($message && !is_object($error)) { + $error = new IXR_Error($error, $message); + } + $this->output($error->getXml()); + } + function output($xml,$encoding='ISO-8859-1') { + $xml = ''."\n".$xml; + $length = strlen($xml); + header('Connection: close'); + header('Content-Length: '.$length); + header('Content-Type: text/xml'); + header('Date: '.date('r')); + echo $xml; + exit; + } + function hasMethod($method) { + return in_array($method, array_keys($this->callbacks)); + } + function setCapabilities() { + // Initialises capabilities array + $this->capabilities = array( + 'xmlrpc' => array( + 'specUrl' => 'http://www.xmlrpc.com/spec', + 'specVersion' => 1 + ), + 'faults_interop' => array( + 'specUrl' => 'http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php', + 'specVersion' => 20010516 + ), + 'system.multicall' => array( + 'specUrl' => 'http://www.xmlrpc.com/discuss/msgReader$1208', + 'specVersion' => 1 + ) + ); + } + function getCapabilities($args) { + return $this->capabilities; + } + function setCallbacks() { + $this->callbacks['system.getCapabilities'] = 'this:getCapabilities'; + $this->callbacks['system.listMethods'] = 'this:listMethods'; + $this->callbacks['system.multicall'] = 'this:multiCall'; + } + function listMethods($args) { + // Returns a list of methods - uses array_reverse to ensure user defined + // methods are listed before server defined methods + return array_reverse(array_keys($this->callbacks)); + } + function multiCall($methodcalls) { + // See http://www.xmlrpc.com/discuss/msgReader$1208 + $return = array(); + foreach ($methodcalls as $call) { + $method = $call['methodName']; + $params = $call['params']; + if ($method == 'system.multicall') { + $result = new IXR_Error(-32600, 'Recursive calls to system.multicall are forbidden'); + } else { + $result = $this->call($method, $params); + } + if ($result instanceof IXR_Error) { + $return[] = array( + 'faultCode' => $result->code, + 'faultString' => $result->message + ); + } else { + $return[] = array($result); + } + } + return $return; + } +} + +class IXR_Request { + public $method; + public $args; + public $xml; + function IXR_Request($method, $args) { + $this->method = $method; + $this->args = $args; + $this->xml = << + +{$this->method} + + +EOD; + foreach ($this->args as $arg) { + $this->xml .= ''; + $v = new IXR_Value($arg); + $this->xml .= $v->getXml(); + $this->xml .= "\n"; + } + $this->xml .= ''; + } + function getLength() { + return strlen($this->xml); + } + function getXml() { + return $this->xml; + } +} + + +class IXR_Client { + public $server; + public $port; + public $path; + public $useragent; + protected $proxy_host; + protected $proxy_port; + public $timeout = 10; + public $response; + public $message = false; + public $debug = false; + // Storage place for an error message + public $error = false; + function IXR_Client($server, $path = false, $port = 80) { + if (!$path) { + // Assume we have been given a URL instead + $bits = parse_url($server); + $this->server = $bits['host']; + $this->port = isset($bits['port']) ? $bits['port'] : 80; + $this->path = isset($bits['path']) ? $bits['path'] : '/'; + // Make absolutely sure we have a path + if (!$this->path) { + $this->path = '/'; + } + } else { + $this->server = $server; + $this->path = $path; + $this->port = $port; + } + $this->useragent = 'The Incutio XML-RPC PHP Library'; + + if (defined('HTTP_PROXY_HOST') && defined('HTTP_PROXY_PORT')) { + $this->setProxy(HTTP_PROXY_HOST,HTTP_PROXY_PORT); + } + } + function setProxy($host,$port='8080') + { + $this->proxy_host = $host; + $this->proxy_port = $port; + } + function query() { + $args = func_get_args(); + $method = array_shift($args); + $request = new IXR_Request($method, $args); + $length = $request->getLength(); + $xml = $request->getXml(); + $r = "\r\n"; + $request = "POST {$this->path} HTTP/1.0$r"; + $request .= "Host: {$this->server}$r"; + $request .= "Content-Type: text/xml$r"; + $request .= "User-Agent: {$this->useragent}$r"; + $request .= "Content-length: {$length}$r$r"; + $request .= $xml; + // Now send the request + if ($this->debug) { + echo '
        '.htmlspecialchars($request)."\n
        \n\n"; + } + + if ($this->proxy_host && $this->proxy_port) { + $host = $this->proxy_host; + $port = $this->proxy_port; + } else { + $host = $this->server; + $port = $this->port; + } + + $fp = @fsockopen($host, $port, $errno, $errstr, $this->timeout); + if (!$fp) { + $this->error = new IXR_Error(-32300, 'transport error - could not open socket'); + return false; + } + socket_set_timeout($fp, $this->timeout); + fputs($fp, $request); + $contents = ''; + $gotFirstLine = false; + $gettingHeaders = true; + while (!feof($fp)) { + $line = fgets($fp, 4096); + if (!$gotFirstLine) { + // Check line for '200' + if (strstr($line, '200') === false) { + $this->error = new IXR_Error(-32300, 'transport error - HTTP status code was not 200'); + return false; + } + $gotFirstLine = true; + } + if (trim($line) == '') { + $gettingHeaders = false; + } + if (!$gettingHeaders) { + $contents .= trim($line)."\n"; + } + } + if ($this->debug) { + echo '
        '.htmlspecialchars($contents)."\n
        \n\n"; + } + // Now parse what we've got back + $this->message = new IXR_Message($contents); + if (!$this->message->parse()) { + // XML error + $this->error = new IXR_Error(-32700, 'parse error. not well formed'); + return false; + } + // Is the message a fault? + if ($this->message->messageType == 'fault') { + $this->error = new IXR_Error($this->message->faultCode, $this->message->faultString); + return false; + } + // Message must be OK + return true; + } + function getResponse() { + // methodResponses can only have one param - return that + return $this->message->params[0]; + } + function isError() { + return (is_object($this->error)); + } + function getErrorCode() { + return $this->error->code; + } + function getErrorMessage() { + return $this->error->message; + } +} + + +class IXR_Error { + public $code; + public $message; + function IXR_Error($code, $message) { + $this->code = $code; + $this->message = $message; + } + function getXml() { + $xml = << + + + + + faultCode + {$this->code} + + + faultString + {$this->message} + + + + + + +EOD; + return $xml; + } +} + + +class IXR_Date { + public $year; + public $month; + public $day; + public $hour; + public $minute; + public $second; + function IXR_Date($time) { + // $time can be a PHP timestamp or an ISO one + if (is_numeric($time)) { + $this->parseTimestamp($time); + } else { + $this->parseTimestamp(strtotime($time)); + } + } + function parseTimestamp($timestamp) { + $this->year = date('Y', $timestamp); + $this->month = date('m', $timestamp); + $this->day = date('d', $timestamp); + $this->hour = date('H', $timestamp); + $this->minute = date('i', $timestamp); + $this->second = date('s', $timestamp); + $this->ts = $timestamp; + } + + function getIso() { + return $this->year.$this->month.$this->day.'T'.$this->hour.':'.$this->minute.':'.$this->second; + } + function getXml() { + return ''.$this->getIso().''; + } + function getTimestamp() { + return mktime($this->hour, $this->minute, $this->second, $this->month, $this->day, $this->year); + } +} + + +class IXR_Base64 { + public $data; + function IXR_Base64($data) { + $this->data = $data; + } + function getXml() { + return ''.base64_encode($this->data).''; + } +} + + +class IXR_IntrospectionServer extends IXR_Server { + public $signatures; + public $help; + function IXR_IntrospectionServer() { + $this->setCallbacks(); + $this->setCapabilities(); + $this->capabilities['introspection'] = array( + 'specUrl' => 'http://xmlrpc.usefulinc.com/doc/reserved.html', + 'specVersion' => 1 + ); + $this->addCallback( + 'system.methodSignature', + 'this:methodSignature', + array('array', 'string'), + 'Returns an array describing the return type and required parameters of a method' + ); + $this->addCallback( + 'system.getCapabilities', + 'this:getCapabilities', + array('struct'), + 'Returns a struct describing the XML-RPC specifications supported by this server' + ); + $this->addCallback( + 'system.listMethods', + 'this:listMethods', + array('array'), + 'Returns an array of available methods on this server' + ); + $this->addCallback( + 'system.methodHelp', + 'this:methodHelp', + array('string', 'string'), + 'Returns a documentation string for the specified method' + ); + } + function addCallback($method, $callback, $args, $help) { + $this->callbacks[$method] = $callback; + $this->signatures[$method] = $args; + $this->help[$method] = $help; + } + function call($methodname, $args) { + // Make sure it's in an array + if ($args && !is_array($args)) { + $args = array($args); + } + // Over-rides default call method, adds signature check + if (!$this->hasMethod($methodname)) { + return new IXR_Error(-32601, 'server error. requested method "'.$this->message->methodName.'" not specified.'); + } + $method = $this->callbacks[$methodname]; + $signature = $this->signatures[$methodname]; + $returnType = array_shift($signature); + // Check the number of arguments + if (count($args) != count($signature)) { + // print 'Num of args: '.count($args).' Num in signature: '.count($signature); + return new IXR_Error(-32602, 'server error. wrong number of method parameters'); + } + // Check the argument types + $ok = true; + $argsbackup = $args; + for ($i = 0, $j = count($args); $i < $j; $i++) { + $arg = array_shift($args); + $type = array_shift($signature); + switch ($type) { + case 'int': + case 'i4': + if (is_array($arg) || !is_int($arg)) { + $ok = false; + } + break; + case 'base64': + case 'string': + if (!is_string($arg)) { + $ok = false; + } + break; + case 'boolean': + if ($arg !== false && $arg !== true) { + $ok = false; + } + break; + case 'float': + case 'double': + if (!is_float($arg)) { + $ok = false; + } + break; + case 'date': + case 'dateTime.iso8601': + if ($arg instanceof IXR_Date) { + $ok = false; + } + break; + } + if (!$ok) { + return new IXR_Error(-32602, 'server error. invalid method parameters'); + } + } + // It passed the test - run the "real" method call + return parent::call($methodname, $argsbackup); + } + function methodSignature($method) { + if (!$this->hasMethod($method)) { + return new IXR_Error(-32601, 'server error. requested method "'.$method.'" not specified.'); + } + // We should be returning an array of types + $types = $this->signatures[$method]; + $return = array(); + foreach ($types as $type) { + switch ($type) { + case 'string': + $return[] = 'string'; + break; + case 'int': + case 'i4': + $return[] = 42; + break; + case 'double': + $return[] = 3.1415; + break; + case 'dateTime.iso8601': + $return[] = new IXR_Date(time()); + break; + case 'boolean': + $return[] = true; + break; + case 'base64': + $return[] = new IXR_Base64('base64'); + break; + case 'array': + $return[] = array('array'); + break; + case 'struct': + $return[] = array('struct' => 'struct'); + break; + } + } + return $return; + } + function methodHelp($method) { + return $this->help[$method]; + } +} + + +class IXR_ClientMulticall extends IXR_Client { + public $calls = array(); + function IXR_ClientMulticall($server, $path = false, $port = 80) { + parent::IXR_Client($server, $path, $port); + $this->useragent = 'The Incutio XML-RPC PHP Library (multicall client)'; + } + function addCall() { + $args = func_get_args(); + $methodName = array_shift($args); + $struct = array( + 'methodName' => $methodName, + 'params' => $args + ); + $this->calls[] = $struct; + } + function query() { + // Prepare multicall, then call the parent::query() method + return parent::query('system.multicall', $this->calls); + } +} + +?> \ No newline at end of file diff --git a/v2/dotclear/inc/libs/clearbricks/filemanager/class.filemanager.php b/v2/dotclear/inc/libs/clearbricks/filemanager/class.filemanager.php new file mode 100644 index 0000000..103f1b2 --- /dev/null +++ b/v2/dotclear/inc/libs/clearbricks/filemanager/class.filemanager.php @@ -0,0 +1,618 @@ +array(),'files'=>array()); + + /** + * Constructor + * + * New filemanage istance. Note that filemanage is a jail in given root + * path. You won't be able to access files outside {@link $root} path with + * the object's methods. + * + * @param string $root Root path + * @param string $root_url Root URL + */ + public function __construct($root,$root_url='') + { + $this->root = $this->pwd = path::real($root); + $this->root_url = $root_url; + + if (!preg_match('#/$#',$this->root_url)) { + $this->root_url = $this->root_url.'/'; + } + + if (!$this->root) { + throw new Exception('Invalid root directory.'); + } + } + + /** + * Change directory + * + * Changes working directory. $dir is relative to instance {@link $root} + * directory. + * + * @param string $dir Directory + */ + public function chdir($dir) + { + $realdir = path::real($this->root.'/'.path::clean($dir)); + if (!$realdir || !is_dir($realdir)) { + throw new Exception('Invalid directory.'); + } + + if ($this->isExclude($realdir)) { + throw new Exception('Directory is excluded.'); + } + + $this->pwd = $realdir; + } + + /** + * Get working directory + * + * Returns working directory path. + * + * @return string + */ + public function getPwd() + { + return $this->pwd; + } + + /** + * Current directory is writable + * + * @return boolean true if working directory is writable + */ + public function writable() + { + if (!$this->pwd) { + return false; + } + + return is_writable($this->pwd); + } + + /** + * Add exclusion + * + * Appends an exclusion to exclusions list. $f should be a regexp. + * + * @see $exclude_list + * @param string $f Exclusion regexp + */ + public function addExclusion($f) + { + if (is_array($f)) + { + foreach ($f as $v) { + if (($V = path::real($v)) !== false) { + $this->exclude_list[] = $V; + } + } + } + elseif (($F = path::real($f)) !== false) + { + $this->exclude_list[] = $F; + } + } + + /** + * Path is excluded + * + * Returns true if path (file or directory) $f is excluded. $f path is + * relative to {@link $root} path. + * + * @see $exclude_list + * @param string $f Path to match + * @return boolean + */ + protected function isExclude($f) + { + foreach ($this->exclude_list as $v) + { + if (strpos($f,$v) === 0) { + return true; + } + } + + return false; + } + + /** + * File is excluded + * + * Returns true if file $f is excluded. $f path is relative to {@link $root} + * path. + * + * @see $exclude_pattern + * @param string $f File to match + * @return boolean + */ + protected function isFileExclude($f) + { + if (!$this->exclude_pattern) { + return false; + } + + return preg_match($this->exclude_pattern,$f); + } + + /** + * Item in jail + * + * Returns true if file or directory $f is in jail (ie. not outside the + * {@link $root} directory). + * + * @param string $f Path to match + * @return boolean + */ + protected function inJail($f) + { + $f = path::real($f); + + if ($f !== false) { + return preg_match('|^'.preg_quote($this->root,'|').'|',$f); + } + + return false; + } + + /** + * File in files + * + * Returns true if file $f is in files array of {@link $dir}. + * + * @param string $f File to match + * @return boolean + */ + public function inFiles($f) + { + foreach ($this->dir['files'] as $v) { + if ($v->relname == $f) { + return true; + } + } + return false; + } + + /** + * Directory list + * + * Creates list of items in working directory and append it to {@link $dir} + * + * @uses sortHandler() + * @uses fileItem + */ + public function getDir() + { + $dir = path::clean($this->pwd); + + $dh = @opendir($dir); + + if ($dh === false) { + throw new Exception('Unable to read directory.'); + } + + $d_res = $f_res = array(); + + while (($file = readdir($dh)) !== false) + { + $fname = $dir.'/'.$file; + + if ($this->inJail($fname) && !$this->isExclude($fname)) + { + if (is_dir($fname) && $file != '.') { + $tmp = new fileItem($fname,$this->root,$this->root_url); + if ($file == '..') { + $tmp->parent = true; + } + $d_res[] = $tmp; + } + + if (is_file($fname) && strpos($file,'.') !== 0 && !$this->isFileExclude($file)) { + $f_res[] = new fileItem($fname,$this->root,$this->root_url); + } + } + } + closedir($dh); + + $this->dir = array('dirs'=>$d_res,'files'=>$f_res); + usort($this->dir['dirs'],array($this,'sortHandler')); + usort($this->dir['files'],array($this,'sortHandler')); + } + + /** + * Root directories + * + * Returns an array of directory under {@link $root} directory. + * + * @uses fileItem + * @return array + */ + public function getRootDirs() + { + $d = files::getDirList($this->root); + + $dir = array(); + + foreach ($d['dirs'] as $v) { + $dir[] = new fileItem($v,$this->root,$this->root_url); + } + + return $dir; + } + + /** + * Upload file + * + * Move $tmp file to its final destination $dest and + * returns the destination file path. + * $dest should be in jail. This method will throw exception + * if the file cannot be written. + * + * You should first verify upload status, with {@link files::uploadStatus()} + * or PHP native functions. + * + * @see files::uploadStatus() + * @param string $tmp Temporary uploaded file path + * @param string $dest Destination file + * @param string $overwrite overwrite mode + * @return string Destination real path + */ + public function uploadFile($tmp,$dest,$overwrite=false) + { + $dest = $this->pwd.'/'.path::clean($dest); + + if ($this->isFileExclude($dest)) { + throw new Exception(__('Uploading this file is not allowed.')); + } + + if (!$this->inJail(dirname($dest))) { + throw new Exception(__('Destination directory is not in jail.')); + } + + if (!$overwrite && file_exists($dest)) { + throw new Exception(__('File already exists.')); + } + + if (!is_writable(dirname($dest))) { + throw new Exception(__('Cannot write in this directory.')); + } + + if (@move_uploaded_file($tmp,$dest) === false) { + throw new Exception(__('An error occurred while writing the file.')); + } + + files::inheritChmod($dest); + return path::real($dest); + } + + /** + * Upload file by bits + * + * Creates a new file $dest with contents of $bits and + * return the destination file path. + * $dest should be in jail. This method will throw exception + * if file cannot be written. + * + * @param string $bits Destination file content + * @param string $dest Destination file + * @return string Destination real path + */ + public function uploadBits($name,$bits) + { + $dest = $this->pwd.'/'.path::clean($name); + + if ($this->isFileExclude($dest)) { + throw new Exception(__('Uploading this file is not allowed.')); + } + + if (!$this->inJail(dirname($dest))) { + throw new Exception(__('Destination directory is not in jail.')); + } + + if (!is_writable(dirname($dest))) { + throw new Exception(__('Cannot write in this directory.')); + } + + $fp = @fopen($dest,'wb'); + if ($fp === false) { + throw new Exception(__('An error occurred while writing the file.')); + } + + fwrite($fp,$bits); + fclose($fp); + files::inheritChmod($dest); + + return path::real($dest); + } + + /** + * New directory + * + * Creates a new directory $d relative to working directory. + * + * @param string $d Directory name + */ + public function makeDir($d) + { + files::makeDir($this->pwd.'/'.path::clean($d)); + } + + /** + * Move file + * + * Moves a file $s to a new destination $d. Both + * $s and $d are relative to {@link $root}. + * + * @param string $s Source file + * @param string $d Destination file + */ + public function moveFile($s,$d) + { + $s = $this->root.'/'.path::clean($s); + $d = $this->root.'/'.path::clean($d); + + if (($s = path::real($s)) === false) { + throw new Exception(__('Source file does not exist.')); + } + + $dest_dir = path::real(dirname($d)); + + if (!$this->inJail($s)) { + throw new Exception(__('File is not in jail.')); + } + if (!$this->inJail($dest_dir)) { + throw new Exception(__('File is not in jail.')); + } + + if (!is_writable($dest_dir)) { + throw new Exception(__('Destination directory is not writable.')); + } + + if (@rename($s,$d) === false) { + throw new Exception(__('Unable to rename file.')); + } + } + + /** + * Remove item + * + * Removes a file or directory $f which is relative to working + * directory. + * + * @param string $f Path to remove + */ + public function removeItem($f) + { + $file = path::real($this->pwd.'/'.path::clean($f)); + + if (is_file($file)) { + $this->removeFile($f); + } elseif (is_dir($file)) { + $this->removeDir($f); + } + } + + /** + * Remove item + * + * Removes a file $f which is relative to working directory. + * + * @param string $f File to remove + */ + public function removeFile($f) + { + $f = path::real($this->pwd.'/'.path::clean($f)); + + if (!$this->inJail($f)) { + throw new Exception(__('File is not in jail.')); + } + + if (!files::isDeletable($f)) { + throw new Exception(__('File cannot be removed.')); + } + + if (@unlink($f) === false) { + throw new Exception(__('File cannot be removed.')); + } + } + + /** + * Remove item + * + * Removes a directory $d which is relative to working directory. + * + * @param string $d Directory to remove + */ + public function removeDir($d) + { + $d = path::real($this->pwd.'/'.path::clean($d)); + + if (!$this->inJail($d)) { + throw new Exception(__('Directory is not in jail.')); + } + + if (!files::isDeletable($d)) { + throw new Exception(__('Directory cannot be removed.')); + } + + if (@rmdir($d) === false) { + throw new Exception(__('Directory cannot be removed.')); + } + } + + /** + * SortHandler + * + * This method is called by {@link getDir()} to sort files. Can be overrided + * in inherited classes. + * + * @param fileItem $a fileItem object + * @param fileItem $b fileItem object + * @return integer + */ + protected function sortHandler($a,$b) + { + if ($a->parent && !$b->parent || !$a->parent && $b->parent) { + return ($a->parent) ? -1 : 1; + } + return strcasecmp($a->basename,$b->basename); + } +} + +/** +* File item +* +* File item class used by {@link filemanager}. In this class {@link $file} could +* be either a file or a directory. +* +* @package Clearbricks +* @subpackage Filemanager +*/ +class fileItem +{ + /** @var string Complete path to file */ + public $file; + + /** @var string File basename */ + public $basename; + + /** @var string File directory name */ + public $dir; + + /** @var string File URL */ + public $file_url; + + /** @var string File directory URL */ + public $dir_url; + + /** @var string File extension */ + public $extension; + + /** @var string File path relative to $root given in constructor */ + public $relname; + + /** @var boolean Parent directory (ie. "..") */ + public $parent = false; + + + /** @var string File MimeType. See {@link files::getMimeType()}. */ + public $type; + + /** @var integer File modification timestamp */ + public $mtime; + + /** @var integer File size */ + public $size; + + /** @var integer File permissions mode */ + public $mode; + + /** @var integer File owner ID */ + public $uid; + + /** @var integer File group ID */ + public $gid; + + /** @var boolean True if file or directory is writable */ + public $w; + + /** @var boolean True if file is a directory */ + public $d; + + /** @var boolean True if file file is executable or directory is traversable */ + public $x; + + /** @var boolean True if file is a file */ + public $f; + + /** @var boolean True if file or directory is deletable */ + public $del; + + /** + * Constructor + * + * Creates an instance of fileItem object. + * + * @param string $file Absolute file or directory path + * @param string $root File root path + * @param string $root_url File root URL + */ + public function __construct($file,$root,$root_url='') + { + $file = path::real($file); + $stat = stat($file); + $path = path::info($file); + + $rel = preg_replace('/^'.preg_quote($root,'/').'\/?/','',$file); + + $this->file = $file; + $this->basename = $path['basename']; + $this->dir = $path['dirname']; + $this->relname = $rel; + + $this->file_url = str_replace('%2F','/',rawurlencode($rel)); + $this->file_url = $root_url.$this->file_url; + + $this->dir_url = dirname($this->file_url); + $this->extension = $path['extension']; + + $this->mtime = $stat[9]; + $this->size = $stat[7]; + $this->mode = $stat[2]; + $this->uid = $stat[4]; + $this->gid = $stat[5]; + $this->w = is_writable($file); + $this->d = is_dir($file); + $this->f = is_file($file); + if ($this->d) { + $this->x = file_exists($file.'/.'); + } else { + $this->x = false; + } + $this->del = files::isDeletable($file); + + $this->type = $this->d ? null : files::getMimeType($file); + $this->type_prefix = preg_replace('/^(.+?)\/.+$/','$1',$this->type); + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/libs/clearbricks/html.filter/class.html.filter.php b/v2/dotclear/inc/libs/clearbricks/html.filter/class.html.filter.php new file mode 100644 index 0000000..cbe6c86 --- /dev/null +++ b/v2/dotclear/inc/libs/clearbricks/html.filter/class.html.filter.php @@ -0,0 +1,676 @@ +parser = xml_parser_create('UTF-8'); + xml_set_object($this->parser,$this); + xml_set_element_handler($this->parser, 'tag_open', 'tag_close'); + xml_set_character_data_handler($this->parser, 'cdata'); + xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, false); + + $this->removeTags( + 'applet','base','basefont','body','center','dir','font', + 'frame','frameset','head','html','isindex', + 'link','menu','meta','noframes','script','style' + ); + + $this->removeAttributes( + 'onclick','ondblclick','onfocus','onkeydown','onkeypress', + 'onkeyup','onload','onmousedown','onmousemove','onmouseout', + 'onmouseover','onmouseup','onreset','onselect','onsubmit', + 'onunload' + ); + } + + /** + * Append tags + * + * Appends tags to remove. Each method argument is a tag. Example: + * + * + * removeTags('frame','script'); + * ?> + * + */ + public function removeTags() + { + foreach ($this->argsArray(func_get_args()) as $tag) { + $this->removed_tags[] = $tag; + } + } + + /** + * Append attributes + * + * Appends attributes to remove. Each method argument is an attribute. Example: + * + * + * removeAttributes('onclick','onunload'); + * ?> + * + */ + public function removeAttributes() + { + foreach ($this->argsArray(func_get_args()) as $a) { + $this->removed_attrs[] = $a; + } + } + + /** + * Append attributes for tags + * + * Appends attributes to remove from specific tags. Each method argument is + * an array of tags with attributes. Example: + * + * + * removeTagAttributes(array('a' => array('src','title'))); + * ?> + * + */ + public function removeTagAttributes($tag) + { + $args = $this->argsArray(func_get_args()); + array_shift($args); + + foreach ($args as $a) { + $this->removed_tag_attrs[$tag][] = $a; + } + } + + /** + * Known tags + * + * Creates a list of known tags. + * + * @param array $t Tags array + */ + public function setTags($t) + { + if (is_array($t)) { + $this->tags = $t; + } + } + + /** + * Apply filter + * + * This method applies filter on given $str string. It will first + * try to use tidy extension if exists and then apply the filter. + * + * @param string $str String to filter + * @return string Filtered string + */ + public function apply($str) + { + if (extension_loaded('tidy') && class_exists('tidy')) + { + $config = array( + 'doctype' => 'strict', + 'drop-proprietary-attributes' => true, + 'drop-font-tags' => true, + 'escape-cdata' => true, + 'indent' => false, + 'join-classes' => false, + 'join-styles' => true, + 'lower-literals' => true, + 'output-xhtml' => true, + 'show-body-only' => true, + 'wrap' => 80 + ); + + $str = '

        tt

        '.$str; // Fixes a big issue + + $tidy = new tidy; + $tidy->parseString($str, $config, 'utf8'); + $tidy->cleanRepair(); + + $str = (string) $tidy; + + $str = preg_replace('#^

        tt

        \s?#','',$str); + } + else + { + $str = $this->miniTidy($str); + } + + # Removing open comments, open CDATA and processing instructions + $str = preg_replace('%%msu','',$str); + $str = str_replace(' + $fc = preg_replace('/(^\s*)?/ms','',$fc); + + # Compile blocks + foreach ($this->blocks as $b => $f) { + $pattern = sprintf($this->tag_block,preg_quote($b,'#')); + + $fc = preg_replace_callback('#'.$pattern.'#ms', + array($this,'compileBlock'),$fc); + } + + # Compile values + foreach ($this->values as $v => $f) { + $pattern = sprintf($this->tag_value,preg_quote($v,'#')); + + $fc = preg_replace_callback('#'.$pattern.'#ms', + array($this,'compileValue'),$fc); + } + + return $fc; + } + + protected function compileBlock($match) + { + $b = $match[1]; + $content = $match[3]; + $attr = $this->getAttrs($match[2]); + + # Call block function + return call_user_func($this->blocks[$b],$attr,$content); + } + + protected function compileValue($match) + { + $v = $match[1]; + $attr = isset($match[2]) ? $this->getAttrs($match[2]) : array(); + $str_attr = isset($match[2]) ? $match[2] : null; + + return call_user_func($this->values[$v],$attr,ltrim($str_attr)); + } + + protected function getAttrs($str) + { + $res = array(); + if (preg_match_all('|([a-zA-Z0-9_:-]+)="([^"]*)"|ms',$str,$m) > 0) { + foreach ($m[1] as $i => $v) { + $res[$v] = $m[2][$i]; + } + } + return $res; + } +} +?> diff --git a/v2/dotclear/inc/libs/clearbricks/text.wiki2xhtml/class.wiki2xhtml.php b/v2/dotclear/inc/libs/clearbricks/text.wiki2xhtml/class.wiki2xhtml.php new file mode 100644 index 0000000..5af2363 --- /dev/null +++ b/v2/dotclear/inc/libs/clearbricks/text.wiki2xhtml/class.wiki2xhtml.php @@ -0,0 +1,1305 @@ + Added ``inline html`` support +# +# 3.2.5 +# => Changed longdesc by title in images +# +# 3.2.4 +# => Auto links +# => Code cleanup +# +# 3.2.3 +# Olivier +# => PHP5 Strict +# +# 3.2.2 +# Olivier +# => Changement de la gestion des URL spéciales +# +# 3.2.1 +# Olivier +# => Changement syntaxe des macros +# +# 3.2 +# Olivier +# => Changement de fonctionnement des macros +# => Passage de fonctions externes pour les macros et les mots wiki +# +# 3.1d +# Jérôme Lipowicz +# => antispam +# Olivier +# => centrage d'image +# +# 3.1c +# Olivier +# => Possibilité d'échaper les | dans les marqueurs avec \ +# +# 3.1b +# Nicolas Chachereau +# => Changement de regexp pour la correction syntaxique +# +# 3.1a +# Olivier +# => Bug du Call-time pass-by-reference +# +# 3.1 +# Olivier +# => Ajout des macros «««..»»» +# => Ajout des blocs vides øøø +# => Ajout du niveau de titre paramétrable +# => Option de blocage du parseur dans les
        +#			=> Titres au format setext (experimental, désactivé)
        +#
        +# 3.0
        +# Olivier		=> Récriture du parseur inline, plus d'erreur XHTML
        +#			=> Ajout d'une vérification d'intégrité pour les listes
        +#			=> Les acronymes sont maintenant dans un fichier texte
        +#			=> Ajout d'un tag images ((..)), del --..-- et ins ++..++
        +#			=> Plus possible de faire des liens JS [lien|javascript:...]
        +#			=> Ajout des notes de bas de page §§...§§
        +#			=> Ajout des mots wiki
        +#
        +# 2.5
        +# Olivier		=> Récriture du code, plus besoin du saut de ligne entre blocs !=
        +#
        +# 2.0
        +# Stephanie	=> correction des PCRE et ajout de fonctionnalités
        +# Mathieu 	=> ajout du strip-tags, implementation des options, reconnaissance automatique d'url, etc.
        +# Olivier		=> chagement de active_link en active_urls
        +#			=> ajout des options pour les blocs
        +#			=> intégration de l'aide dans le code, avec les options
        +#			=> début de quelque chose pour la reconnaissance auto d'url (avec Mat)
        +
        +# TODO :
        +# Mathieu	=> active_wiki_urls (modifier wikiParseUrl ?)
        +# 		=> active_auto_urls
        +#
        +# *		=> ajouter des options.
        +# 		=> trouver un meilleur nom pour active_link ? (pour le jour ou ca sera tellement une usine
        +#		   a gaz que on generera des tags  :)
        +#
        +
        +# Wiki2xhtml
        +
        +class wiki2xhtml
        +{
        +	public $__version__ = '3.2.6';
        +	
        +	public $T;
        +	public $opt;
        +	public $line;
        +	public $acro_table;
        +	public $foot_notes;
        +	public $macros;
        +	public $functions;
        +	
        +	public $tags;
        +	public $open_tags;
        +	public $close_tags;
        +	public $custom_tags = array();
        +	public $all_tags;
        +	public $tag_pattern;
        +	public $escape_table;
        +	public $allowed_inline = array();
        +	
        +	function __construct()
        +	{
        +		# Mise en place des options
        +		$this->setOpt('active_title',1);		# Activation des titres !!!
        +		$this->setOpt('active_setext_title',0);	# Activation des titres setext (EXPERIMENTAL)
        +		$this->setOpt('active_hr',1);			# Activation des 
        + $this->setOpt('active_lists',1); # Activation des listes + $this->setOpt('active_quote',1); # Activation du
        + $this->setOpt('active_pre',1); # Activation du
        +		$this->setOpt('active_empty',1);		# Activation du bloc vide øøø
        +		$this->setOpt('active_auto_urls',0);	# Activation de la reconnaissance d'url
        +		$this->setOpt('active_auto_br',0);	# Activation du saut de ligne automatique (dans les paragraphes)
        +		$this->setOpt('active_antispam',1);	# Activation de l'antispam pour les emails
        +		$this->setOpt('active_urls',1);		# Activation des liens []
        +		$this->setOpt('active_auto_img',1);	# Activation des images automatiques dans les liens []
        +		$this->setOpt('active_img',1);		# Activation des images (())
        +		$this->setOpt('active_anchor',1);		# Activation des ancres ~...~
        +		$this->setOpt('active_em',1);			# Activation du  ''...''
        +		$this->setOpt('active_strong',1);		# Activation du  __...__
        +		$this->setOpt('active_br',1);			# Activation du 
        %%% + $this->setOpt('active_q',1); # Activation du {{...}} + $this->setOpt('active_code',1); # Activation du @@...@@ + $this->setOpt('active_acronym',1); # Activation des acronymes + $this->setOpt('active_ins',1); # Activation des ins ++..++ + $this->setOpt('active_del',1); # Activation des del --..-- + $this->setOpt('active_inline_html',1); # Activation du HTML inline ``...`` + $this->setOpt('active_footnotes',1); # Activation des notes de bas de page + $this->setOpt('active_wikiwords',0); # Activation des mots wiki + $this->setOpt('active_macros',1); # Activation des macros /// /// + + $this->setOpt('parse_pre',1); # Parser l'intérieur de blocs
         ?
        +		
        +		$this->setOpt('active_fr_syntax',1);	# Corrections syntaxe FR
        +		
        +		$this->setOpt('first_title_level',3);	# Premier niveau de titre 
        +		
        +		$this->setOpt('note_prefix','wiki-footnote');
        +		$this->setOpt('note_str','

        Notes

        %s
        '); + $this->setOpt('note_str_single','

        Note

        %s
        '); + $this->setOpt('words_pattern', + '((?setOpt('auto_url_pattern', + '%(?setOpt('acronyms_file',dirname(__FILE__).'/acronyms.txt'); + + $this->acro_table = $this->__getAcronyms(); + $this->foot_notes = array(); + $this->functions = array(); + $this->macros = array(); + + $this->registerFunction('macro:html',array($this,'__macroHTML')); + } + + function setOpt($option, $value) + { + $this->opt[$option] = $value; + } + + function setOpts($options) + { + if (!is_array($options)) { + return; + } + + foreach ($options as $k => $v) { + $this->opt[$k] = $v; + } + } + + function getOpt($option) + { + return (!empty($this->opt[$option])) ? $this->opt[$option] : false; + } + + function registerFunction($type,$name) + { + if (is_callable($name)) { + $this->functions[$type] = $name; + } + } + + function transform($in) + { + # Initialisation des tags + $this->__initTags(); + $this->foot_notes = array(); + + # Récupération des macros + if ($this->getOpt('active_macros')) { + $in = preg_replace('#^///(.*?)///($|\r)#mse',"\\\$this->__getMacro('\\1')",$in); + } + + # Vérification du niveau de titre + if ($this->getOpt('first_title_level') > 4) { + $this->setOpt('first_title_level',4); + } + + $res = str_replace("\r", '', $in); + + $escape_pattern = array(); + + # traitement des titres à la setext + if ($this->getOpt('active_setext_title') && $this->getOpt('active_title')) { + $res = preg_replace('/^(.*)\n[=]{5,}$/m','!!!$1',$res); + $res = preg_replace('/^(.*)\n[-]{5,}$/m','!!$1',$res); + } + + # Transformation des mots Wiki + if ($this->getOpt('active_wikiwords') && $this->getOpt('words_pattern')) { + $res = preg_replace('/'.$this->getOpt('words_pattern').'/msu','¶¶¶$1¶¶¶',$res); + } + + # Transformation des URLs automatiques + if ($this->getOpt('active_auto_urls')) + { + $active_urls = $this->getOpt('active_urls'); + + $this->setOpt('active_urls',1); + $this->__initTags(); + + # If urls are not active, escape URLs tags + if (!$active_urls) + { + $res = preg_replace( + '%(?tags['a'])).'])%msU', + '\\\$1',$res + ); + } + + # Transforms urls while preserving tags. + $tree = preg_split($this->tag_pattern,$res,-1,PREG_SPLIT_DELIM_CAPTURE); + foreach ($tree as &$leaf) { + $leaf = preg_replace($this->getOpt('auto_url_pattern'),'[$1$2]',$leaf); + } + unset($leaf); + $res = implode($tree); + + + } + + $this->T = explode("\n",$res); + $this->T[] = ''; + + # Parse les blocs + $res = $this->__parseBlocks(); + + # Line break + if ($this->getOpt('active_br')) { + $res = preg_replace('/(?', $res); + $escape_pattern[] = '%%%'; + } + + # Nettoyage des \s en trop + $res = preg_replace('/([\s]+)(<\/p>|<\/li>|<\/pre>)/u', '$2', $res); + $res = preg_replace('/(
      • )([\s]+)/u', '$1', $res); + + # On vire les escapes + if (!empty($escape_pattern)) { + $res = preg_replace('/\\\('.implode('|',$escape_pattern).')/','$1',$res); + } + + # On vire les ¶¶¶MotWiki¶¶¶ qui sont resté (dans les url...) + if ($this->getOpt('active_wikiwords') && $this->getOpt('words_pattern')) { + $res = preg_replace('/¶¶¶'.$this->getOpt('words_pattern').'¶¶¶/msu','$1',$res); + } + + # On remet les macros + if ($this->getOpt('active_macros')) { + $res = preg_replace('/^##########MACRO#([0-9]+)#$/mse','\$this->__putMacro("$1")',$res); + } + + # Auto line break dans les paragraphes + if ($this->getOpt('active_auto_br')) { + $res = preg_replace_callback('%(

        )(.*?)(

        )%msu',array($this,'__autoBR'),$res); + } + + # On ajoute les notes + if (count($this->foot_notes) > 0) + { + $res_notes = ''; + $i = 1; + foreach ($this->foot_notes as $k => $v) { + $res_notes .= "\n".'

        ['.$i.'] '.$v.'

        '; + $i++; + } + $res .= sprintf("\n".(count($this->foot_notes) > 1 ? $this->getOpt('note_str') : $this->getOpt('note_str_single'))."\n",$res_notes); + } + + return $res; + } + + /* PRIVATE + --------------------------------------------------- */ + + function __initTags() + { + $tags = array( + 'em' => array("''","''"), + 'strong' => array('__','__'), + 'acronym' => array('??','??'), + 'a' => array('[',']'), + 'img' => array('((','))'), + 'q' => array('{{','}}'), + 'code' => array('@@','@@'), + 'anchor' => array('~','~'), + 'del' => array('--','--'), + 'ins' => array('++','++'), + 'inline' => array('``','``'), + 'note' => array('$$','$$'), + 'word' => array('¶¶¶','¶¶¶') + ); + $this->linetags = array( + 'empty' => 'øøø', + 'title' => '([!]{1,4})', + 'hr' => '[-]{4}[- ]', + 'quote' => '(>|;:)', + 'lists' => '([*#]+)', + 'pre' => '[ ]{1}' + ); + + $this->tags = array_merge($tags,$this->custom_tags); + + # Suppression des tags selon les options + if (!$this->getOpt('active_urls')) { + unset($this->tags['a']); + } + if (!$this->getOpt('active_img')) { + unset($this->tags['img']); + } + if (!$this->getOpt('active_anchor')) { + unset($this->tags['anchor']); + } + if (!$this->getOpt('active_em')) { + unset($this->tags['em']); + } + if (!$this->getOpt('active_strong')) { + unset($this->tags['strong']); + } + if (!$this->getOpt('active_q')) { + unset($this->tags['q']); + } + if (!$this->getOpt('active_code')) { + unset($this->tags['code']); + } + if (!$this->getOpt('active_acronym')) { + unset($this->tags['acronym']); + } + if (!$this->getOpt('active_ins')) { + unset($this->tags['ins']); + } + if (!$this->getOpt('active_del')) { + unset($this->tags['del']); + } + if (!$this->getOpt('active_inline_html')) { + unset($this->tags['inline']); + } + if (!$this->getOpt('active_footnotes')) { + unset($this->tags['note']); + } + if (!$this->getOpt('active_wikiwords')) { + unset($this->tags['word']); + } + + # Suppression des tags de début de ligne selon les options + if (!$this->getOpt('active_empty')) { + unset($this->linetags['empty']); + } + if (!$this->getOpt('active_title')) { + unset($this->linetags['title']); + } + if (!$this->getOpt('active_hr')) { + unset($this->linetags['hr']); + } + if (!$this->getOpt('active_quote')) { + unset($this->linetags['quote']); + } + if (!$this->getOpt('active_lists')) { + unset($this->linetags['lists']); + } + if (!$this->getOpt('active_pre')) { + unset($this->linetags['pre']); + } + + $this->open_tags = $this->__getTags(); + $this->close_tags = $this->__getTags(false); + $this->all_tags = $this->__getAllTags(); + $this->tag_pattern = $this->__getTagsPattern(); + + $this->escape_table = $this->all_tags; + array_walk($this->escape_table,create_function('&$a','$a = \'\\\\\'.$a;')); + } + + function __getTags($open=true) + { + $res = array(); + foreach ($this->tags as $k => $v) { + $res[$k] = ($open) ? $v[0] : $v[1]; + } + return $res; + } + + function __getAllTags() + { + $res = array(); + foreach ($this->tags as $v) { + $res[] = $v[0]; + $res[] = $v[1]; + } + return array_values(array_unique($res)); + } + + function __getTagsPattern($escape=false) + { + $res = $this->all_tags; + array_walk($res,create_function('&$a','$a = preg_quote($a,"/");')); + + if (!$escape) { + return '/(?T); + + for ($i=0; $i<$max; $i++) + { + $pre_mode = $mode; + $pre_type = $type; + $end = ($i+1 == $max); + + $line = $this->__getLine($i,$type,$mode); + + if ($type != 'pre' || $this->getOpt('parse_pre')) { + $line = $this->__inlineWalk($line); + } + + $res .= $this->__closeLine($type,$mode,$pre_type,$pre_mode); + $res .= $this->__openLine($type,$mode,$pre_type,$pre_mode); + + # P dans les blockquotes + if ($type == 'blockquote' && trim($line) == '' && $pre_type == $type) { + $res .= "

        \n

        "; + } + + # Correction de la syntaxe FR dans tous sauf pre et hr + # Sur idée de Christophe Bonijol + # Changement de regex (Nicolas Chachereau) + if ($this->getOpt('active_fr_syntax') && $type != null && $type != 'pre' && $type != 'hr') { + $line = preg_replace('%[ ]+([:?!;\x{00BB}](\s|$))%u',' $1',$line); + $line = preg_replace('%(\x{00AB})[ ]+%u','$1 ',$line); + } + + $res .= $line; + } + + return trim($res); + } + + function __getLine($i,&$type,&$mode) + { + $pre_type = $type; + $pre_mode = $mode; + $type = $mode = null; + + if (empty($this->T[$i])) { + return false; + } + + $line = htmlspecialchars($this->T[$i],ENT_NOQUOTES); + + # Ligne vide + if (empty($line)) + { + $type = null; + } + elseif ($this->getOpt('active_empty') && preg_match('/^øøø(.*)$/',$line,$cap)) + { + $type = null; + $line = trim($cap[1]); + } + # Titre + elseif ($this->getOpt('active_title') && preg_match('/^([!]{1,4})(.*)$/',$line,$cap)) + { + $type = 'title'; + $mode = strlen($cap[1]); + $line = trim($cap[2]); + } + # Ligne HR + elseif ($this->getOpt('active_hr') && preg_match('/^[-]{4}[- ]*$/',$line)) + { + $type = 'hr'; + $line = null; + } + # Blockquote + elseif ($this->getOpt('active_quote') && preg_match('/^(>|;:)(.*)$/',$line,$cap)) + { + $type = 'blockquote'; + $line = trim($cap[2]); + } + # Liste + elseif ($this->getOpt('active_lists') && preg_match('/^([*#]+)(.*)$/',$line,$cap)) + { + $type = 'list'; + $mode = $cap[1]; + $valid = true; + + # Vérification d'intégrité + $dl = ($type != $pre_type) ? 0 : strlen($pre_mode); + $d = strlen($mode); + $delta = $d-$dl; + + if ($delta < 0 && strpos($pre_mode,$mode) !== 0) { + $valid = false; + } + if ($delta > 0 && $type == $pre_type && strpos($mode,$pre_mode) !== 0) { + $valid = false; + } + if ($delta == 0 && $mode != $pre_mode) { + $valid = false; + } + if ($delta > 1) { + $valid = false; + } + + if (!$valid) { + $type = 'p'; + $mode = null; + $line = '
        '.$line; + } else { + $line = trim($cap[2]); + } + } + # Préformaté + elseif ($this->getOpt('active_pre') && preg_match('/^[ ]{1}(.*)$/',$line,$cap)) + { + $type = 'pre'; + $line = $cap[1]; + } + # Paragraphe + else { + $type = 'p'; + if (preg_match('/^\\\((?:('.implode('|',$this->linetags).')).*)$/',$line,$cap)) { + $line = $cap[1]; + } + $line = trim($line); + } + + return $line; + } + + function __openLine($type,$mode,$pre_type,$pre_mode) + { + $open = ($type != $pre_type); + + if ($open && $type == 'p') + { + return "\n

        "; + } + elseif ($open && $type == 'blockquote') + { + return "\n

        "; + } + elseif (($open || $mode != $pre_mode) && $type == 'title') + { + $fl = $this->getOpt('first_title_level'); + $fl = $fl+3; + $l = $fl-$mode; + return "\n'; + } + elseif ($open && $type == 'pre') + { + return "\n

        ";
        +		}
        +		elseif ($open && $type == 'hr')
        +		{
        +			return "\n
        "; + } + elseif ($type == 'list') + { + $dl = ($open) ? 0 : strlen($pre_mode); + $d = strlen($mode); + $delta = $d-$dl; + $res = ''; + + if($delta > 0) { + if(substr($mode, -1, 1) == '*') { + $res .= "
          \n"; + } else { + $res .= "
            \n"; + } + } elseif ($delta < 0) { + $res .= "\n"; + for($j = 0; $j < abs($delta); $j++) { + if (substr($pre_mode,(0 - $j - 1), 1) == '*') { + $res .= "
        \n
      • \n"; + } else { + $res .= "\n\n"; + } + } + } else { + $res .= "\n"; + } + + return $res."
      • "; + } + else + { + return null; + } + } + + function __closeLine($type,$mode,$pre_type,$pre_mode) + { + $close = ($type != $pre_type); + + if ($close && $pre_type == 'p') + { + return "

        \n"; + } + elseif ($close && $pre_type == 'blockquote') + { + return "

      • \n"; + } + elseif (($close || $mode != $pre_mode) && $pre_type == 'title') + { + $fl = $this->getOpt('first_title_level'); + $fl = $fl+3; + $l = $fl-$pre_mode; + return '\n"; + } + elseif ($close && $pre_type == 'pre') + { + return "
        \n"; + } + elseif ($close && $pre_type == 'list') + { + $res = ''; + for($j = 0; $j < strlen($pre_mode); $j++) { + if(substr($pre_mode,(0 - $j - 1), 1) == '*') { + $res .= "\n"; + } else { + $res .= "\n"; + } + } + return $res; + } + else + { + return "\n"; + } + } + + + /* Inline + --------------------------------------------------- */ + function __inlineWalk($str,$allow_only=null) + { + $tree = preg_split($this->tag_pattern,$str,-1,PREG_SPLIT_DELIM_CAPTURE); + + $res = ''; + for ($i=0; $iopen_tags)) && + ($allow_only == null || in_array(array_search($tree[$i],$this->open_tags),$allow_only))) + { + $tag = array_search($tree[$i],$this->open_tags); + $tag_type = 'open'; + + if (($tidy = $this->__makeTag($tree,$tag,$i,$i,$attr,$tag_type)) !== false) + { + if ($tag != '') { + $res .= '<'.$tag.$attr; + $res .= ($tag_type == 'open') ? '>' : ' />'; + } + $res .= $tidy; + } + else + { + $res .= $tree[$i]; + } + } + else + { + $res .= $tree[$i]; + } + } + + # Suppression des echappements + $res = str_replace($this->escape_table,$this->all_tags,$res); + + return $res; + } + + function __makeTag(&$tree,&$tag,$position,&$j,&$attr,&$type) + { + $res = ''; + $closed = false; + + $itag = $this->close_tags[$tag]; + + # Recherche fermeture + for ($i=$position+1;$i__parseLink($res,$tag,$attr,$type); + break; + case 'img': + $type = 'close'; + $res = $this->__parseImg($res,$attr); + break; + case 'acronym': + $res = $this->__parseAcronym($res,$attr); + break; + case 'q': + $res = $this->__parseQ($res,$attr); + break; + case 'anchor': + $tag = 'a'; + $res = $this->__parseAnchor($res,$attr); + break; + case 'note': + $tag = ''; + $res = $this->__parseNote($res); + break; + case 'inline': + $tag = ''; + $res = $this->__parseInlineHTML($res); + break; + case 'word': + $res = $this->parseWikiWord($res,$tag,$attr,$type); + break; + default : + $res = $this->__inlineWalk($res); + break; + } + + if ($type == 'open' && $tag != '') { + $res .= ''; + } + $j = $i; + break; + } + } + + return $res; + } + else + { + return false; + } + } + + function __splitTagsAttr($str) + { + $res = preg_split('/(? $v) { + $res[$k] = str_replace("\|",'|',$v); + } + + return $res; + } + + # Antispam (Jérôme Lipowicz) + function __antiSpam($str) + { + $encoded = bin2hex($str); + $encoded = chunk_split($encoded, 2, '%'); + $encoded = '%'.substr($encoded, 0, strlen($encoded) - 1); + return $encoded; + } + + function __parseLink($str,&$tag,&$attr,&$type) + { + $n_str = $this->__inlineWalk($str,array('acronym','img')); + $data = $this->__splitTagsAttr($n_str); + $no_image = false; + + # Only URL in data + if (count($data) == 1) + { + $url = trim($str); + $content = strlen($url) > 35 ? substr($url,0,35).'...' : $url; + $lang = ''; + $title = $url; + } + elseif (count($data) > 1) + { + $url = trim($data[1]); + $content = $data[0]; + $lang = (!empty($data[2])) ? $this->protectAttr($data[2],true) : ''; + $title = (!empty($data[3])) ? $data[3] : ''; + $no_image = (!empty($data[4])) ? (boolean) $data[4] : false; + } + + # Remplacement si URL spéciale + $this->__specialUrls($url,$content,$lang,$title); + + # On vire les   dans l'url + $url = str_replace(' ',' ',$url); + + if (preg_match('/^(.+)[.](gif|jpg|jpeg|png)$/', $url) && !$no_image && $this->getOpt('active_auto_img')) + { + # On ajoute les dimensions de l'image si locale + # Idée de Stephanie + $img_size = null; + if (!preg_match('#[a-zA-Z]+://#', $url)) { + if (preg_match('#^/#',$url)) { + $path_img = $_SERVER['DOCUMENT_ROOT'] . $url; + } else { + $path_img = $url; + } + + $img_size = @getimagesize($path_img); + } + + $attr = ' src="'.$this->protectAttr($this->protectUrls($url)).'"'. + $attr .= (count($data) > 1) ? ' alt="'.$this->protectAttr($content).'"' : ' alt=""'; + $attr .= ($lang) ? ' lang="'.$lang.'"' : ''; + $attr .= ($title) ? ' title="'.$this->protectAttr($title).'"' : ''; + $attr .= (is_array($img_size)) ? ' '.$img_size[3] : ''; + + $tag = 'img'; + $type = 'close'; + return null; + } + else + { + if ($this->getOpt('active_antispam') && preg_match('/^mailto:/',$url)) { + $content = $content == $url ? preg_replace('%^mailto:%','',$content) : $content; + $url = 'mailto:'.$this->__antiSpam(substr($url,7)); + + } + + $attr = ' href="'.$this->protectAttr($this->protectUrls($url)).'"'; + $attr .= ($lang) ? ' hreflang="'.$lang.'"' : ''; + $attr .= ($title) ? ' title="'.$this->protectAttr($title).'"' : ''; + + return $content; + } + } + + function __specialUrls(&$url,&$content,&$lang,&$title) + { + foreach ($this->functions as $k => $v) + { + if (strpos($k,'url:') === 0 && strpos($url,substr($k,4)) === 0) + { + $res = call_user_func($v,$url,$content); + + $url = isset($res['url']) ? $res['url'] : $url; + $content = isset($res['content']) ? $res['content'] : $content; + $lang = isset($res['lang']) ? $res['lang'] : $lang; + $title = isset($res['title']) ? $res['title'] : $title; + + break; + } + } + } + + function __parseImg($str,&$attr) + { + $data = $this->__splitTagsAttr($str); + + $alt = ''; + $url = $data[0]; + if (!empty($data[1])) { + $alt = $data[1]; + } + + $attr = ' src="'.$this->protectAttr($this->protectUrls($url)).'"'; + $attr .= ' alt="'.$this->protectAttr($alt).'"'; + + if (!empty($data[2])) { + $data[2] = strtoupper($data[2]); + if ($data[2] == 'G' || $data[2] == 'L') { + $attr .= ' style="float:left; margin: 0 1em 1em 0;"'; + } elseif ($data[2] == 'D' || $data[2] == 'R') { + $attr .= ' style="float:right; margin: 0 0 1em 1em;"'; + } elseif ($data[2] == 'C') { + $attr .= ' style="display:block; margin:0 auto;"'; + } + } + + if (!empty($data[3])) { + $attr .= ' title="'.$this->protectAttr($data[3]).'"'; + } + + return null; + } + + function __parseQ($str,&$attr) + { + $str = $this->__inlineWalk($str); + $data = $this->__splitTagsAttr($str); + + $content = $data[0]; + $lang = (!empty($data[1])) ? $this->protectAttr($data[1],true) : ''; + + $attr .= (!empty($lang)) ? ' lang="'.$lang.'"' : ''; + $attr .= (!empty($data[2])) ? ' cite="'.$this->protectAttr($this->protectUrls($data[2])).'"' : ''; + + return $content; + } + + function __parseAnchor($str,&$attr) + { + $name = $this->protectAttr($str,true); + + if ($name != '') { + $attr = ' name="'.$name.'"'; + } + return null; + } + + function __parseNote($str) + { + $i = count($this->foot_notes)+1; + $id = $this->getOpt('note_prefix').'-'.$i; + $this->foot_notes[$id] = $this->__inlineWalk($str); + return '\['.$i.'\]'; + } + + function __parseInlineHTML($str) + { + return str_replace(array('>','<'),array('>','<'),$str); + } + + # Obtenir un acronyme + function __parseAcronym($str,&$attr) + { + $data = $this->__splitTagsAttr($str); + + $acronym = $data[0]; + $title = $lang = ''; + + if (count($data) > 1) + { + $title = $data[1]; + $lang = (!empty($data[2])) ? $this->protectAttr($data[2],true) : ''; + } + + if ($title == '' && !empty($this->acro_table[$acronym])) { + $title = $this->acro_table[$acronym]; + } + + $attr = ($title) ? ' title="'.$this->protectAttr($title).'"' : ''; + $attr .= ($lang) ? ' lang="'.$lang.'"' : ''; + + return $acronym; + } + + # Définition des acronymes, dans le fichier acronyms.txt + function __getAcronyms() + { + $file = $this->getOpt('acronyms_file'); + $res = array(); + + if (file_exists($file)) + { + if (($fc = @file($file)) !== false) + { + foreach ($fc as $v) + { + $v = trim($v); + if ($v != '') + { + $p = strpos($v,':'); + $K = (string) trim(substr($v,0,$p)); + $V = (string) trim(substr($v,($p+1))); + + if ($K) { + $res[$K] = $V; + } + } + } + } + } + + return $res; + } + + # Mots wiki (pour héritage) + function parseWikiWord($str,&$tag,&$attr,&$type) + { + $tag = $attr = ''; + + if (isset($this->functions['wikiword'])) { + return call_user_func($this->functions['wikiword'],$str); + } + + return $str; + } + + /* Protection des attributs */ + function protectAttr($str,$name=false) + { + if ($name && !preg_match('/^[A-Za-z][A-Za-z0-9_:.-]*$/',$str)) { + return ''; + } + + return str_replace(array("'",'"'),array(''','"'),$str); + } + + /* Protection des urls */ + function protectUrls($str) + { + if (preg_match('/^javascript:/',$str)) { + $str = '#'; + } + + return $str; + } + + /* Auto BR */ + function __autoBR($m) + { + return $m[1].str_replace("\n","
        \n",$m[2]).$m[3]; + } + + /* Macro + --------------------------------------------------- */ + function __getMacro($s) + { + $this->macros[] = str_replace('\"','"',$s); + return 'øøø##########MACRO#'.(count($this->macros)-1).'#'; + } + + function __putMacro($id) + { + $id = (integer) $id; + if (isset($this->macros[$id])) + { + $content = str_replace("\r",'',$this->macros[$id]); + + $c = explode("\n",$content); + + # première ligne, premier mot + $fl = trim($c[0]); + $fw = $fl; + + if ($fl) { + if (strpos($fl,' ') !== false) { + $fw = substr($fl,0,strpos($fl,' ')); + } + $content = implode("\n",array_slice($c,1)); + } + + if ($c[0] == "\n") { + $content = implode("\n",array_slice($c,1)); + } + + if ($fw) + { + if (isset($this->functions['macro:'.$fw])) + { + return call_user_func($this->functions['macro:'.$fw],$content,$fl); + } + } + + # Si on n'a rien pu faire, on retourne le tout sous + # forme de
        +			return '
        '.htmlspecialchars($this->macros[$id]).'
        '; + } + + return null; + } + + function __macroHTML($s) + { + return $s; + } + + /* Aide et debug + --------------------------------------------------- */ + function help() + { + $help['b'] = array(); + $help['i'] = array(); + + $help['b'][] = 'Laisser une ligne vide entre chaque bloc de même nature.'; + $help['b'][] = 'Paragraphe : du texte et une ligne vide'; + + if ($this->getOpt('active_title')) { + $help['b'][] = 'Titre : !!!, !!, '. + '! pour des titres plus ou moins importants'; + } + + if ($this->getOpt('active_hr')) { + $help['b'][] = 'Trait horizontal : ----'; + } + + if ($this->getOpt('active_lists')) { + $help['b'][] = 'Liste : ligne débutant par * ou '. + '#. Il est possible de mélanger les listes '. + '(*#*) pour faire des listes de plusieurs niveaux. '. + 'Respecter le style de chaque niveau'; + } + + if ($this->getOpt('active_pre')) { + $help['b'][] = 'Texte préformaté : espace devant chaque ligne de texte'; + } + + if ($this->getOpt('active_quote')) { + $help['b'][] = 'Bloc de citation : > ou '. + ';: devant chaque ligne de texte'; + } + + if ($this->getOpt('active_fr_syntax')) { + $help['i'][] = 'La correction de ponctuation est active. Un espace '. + 'insécable remplacera automatiquement tout espace '. + 'précédant les marques ";","?",":" et "!".'; + } + + if ($this->getOpt('active_em')) { + $help['i'][] = 'Emphase : deux apostrophes \'\'texte\'\''; + } + + if ($this->getOpt('active_strong')) { + $help['i'][] = 'Forte emphase : deux soulignés __texte__'; + } + + if ($this->getOpt('active_br')) { + $help['i'][] = 'Retour forcé à la ligne : %%%'; + } + + if ($this->getOpt('active_ins')) { + $help['i'][] = 'Insertion : deux plus ++texte++'; + } + + if ($this->getOpt('active_del')) { + $help['i'][] = 'Suppression : deux moins --texte--'; + } + + if ($this->getOpt('active_urls')) { + $help['i'][] = 'Lien : [url], [nom|url], '. + '[nom|url|langue] ou [nom|url|langue|titre].'; + + $help['i'][] = 'Image : comme un lien mais avec une extension d\'image.'. + '
        Pour désactiver la reconnaissance d\'image mettez 0 dans un dernier '. + 'argument. Par exemple [image|image.gif||0] fera un lien vers l\'image au '. + 'lieu de l\'afficher.'. + '
        Il est conseillé d\'utiliser la nouvelle syntaxe.'; + } + + if ($this->getOpt('active_img')) { + $help['i'][] = 'Image (nouvelle syntaxe) : '. + '((url|texte alternatif)), '. + '((url|texte alternatif|position)) ou '. + '((url|texte alternatif|position|description longue)). '. + '
        La position peut prendre les valeur L ou G (gauche), R ou D (droite) ou C (centré).'; + } + + if ($this->getOpt('active_anchor')) { + $help['i'][] = 'Ancre : ~ancre~'; + } + + if ($this->getOpt('active_acronym')) { + $help['i'][] = 'Acronyme : ??acronyme?? ou '. + '??acronyme|titre??'; + } + + if ($this->getOpt('active_q')) { + $help['i'][] = 'Citation : {{citation}}, '. + '{{citation|langue}} ou {{citation|langue|url}}'; + } + + if ($this->getOpt('active_code')) { + $help['i'][] = 'Code : @@code ici@@'; + } + + if ($this->getOpt('active_footnotes')) { + $help['i'][] = 'Note de bas de page : $$Corps de la note$$'; + } + + $res = '
        '; + + $res .= '
        Blocs
        '; + if (count($help['b']) > 0) + { + $res .= '
        • '; + $res .= implode(' ;
        • ', $help['b']); + $res .= '.
        '; + } + $res .= '
        '; + + $res .= '
        Éléments en ligne
        '; + if (count($help['i']) > 0) + { + $res .= '
        • '; + $res .= implode(' ;
        • ', $help['i']); + $res .= '.
        '; + } + $res .= '
        '; + + $res .= '
        '; + + return $res; + } + + /* + function debug() + { + $mode = $type = null; + $max = count($this->T); + + $res = + ''. + ''; + + for ($i=0; $i<$max; $i++) + { + $pre_mode = $mode; + $pre_type = $type; + + $line = $this->__getLine($i,$type,$mode); + + $res .= + ''. + ''; + + } + $res .= '
        p-modep-typemodetypechaine
        '.$pre_mode.''.$pre_type.''.$mode.''.$type.''.$line.'
        '; + + return $res; + } + //*/ +} + +?> \ No newline at end of file diff --git a/v2/dotclear/inc/libs/clearbricks/url.handler/class.url.handler.php b/v2/dotclear/inc/libs/clearbricks/url.handler/class.url.handler.php new file mode 100644 index 0000000..0c99b3c --- /dev/null +++ b/v2/dotclear/inc/libs/clearbricks/url.handler/class.url.handler.php @@ -0,0 +1,229 @@ +mode = $mode; + } + + public function register($type,$url,$representation,$handler) + { + $this->types[$type] = array( + 'url' => $url, + 'representation' => $representation, + 'handler' => $handler + ); + } + + public function registerDefault($handler) + { + $this->default_handler = $handler; + } + + public function registerError($handler) + { + array_unshift($this->error_handlers,$handler); + } + + public function unregister($type) + { + if (isset($this->types[$type])) { + unset($this->types[$type]); + } + } + + public function getTypes() + { + return $this->types; + } + + public function getBase($type) + { + if (isset($this->types[$type])) { + return $this->types[$type]['url']; + } + return null; + } + + public function getDocument() + { + $type = $args = ''; + + if ($this->mode == 'path_info') + { + $part = substr($_SERVER['PATH_INFO'],1); + } + else + { + $part = ''; + + $qs = $this->parseQueryString(); + + # Recreates some _GET and _REQUEST pairs + if (!empty($qs)) + { + foreach ($_GET as $k => $v) { + if (isset($_REQUEST[$k])) { + unset($_REQUEST[$k]); + } + } + $_GET = $qs; + $_REQUEST = array_merge($qs,$_REQUEST); + + list($k,$v) = each($qs); + if ($v === null) { + $part = $k; + unset($_GET[$k]); + unset($_REQUEST[$k]); + } + } + } + + $_SERVER['URL_REQUEST_PART'] = $part; + + $this->getArgs($part,$type,$args); + + if (!$type) + { + $this->type = 'default'; + $this->callDefaultHandler($args); + } + else + { + $this->type = $type; + $this->callHandler($type,$args); + } + } + + public function getArgs($part,&$type,&$args) + { + if ($part == '') { + $type = null; + $args = null; + return; + } + + $this->sortTypes(); + + foreach ($this->types as $k => $v) + { + $repr = $v['representation']; + if ($repr == $part) { + $type = $k; + $args = null; + return; + } + elseif (preg_match('#'.$repr.'#',$part,$m)) + { + $type = $k; + $args = isset($m[1]) ? $m[1] : null; + return; + } + } + + # No type, pass args to default + $args = $part; + } + + public function callHandler($type,$args) + { + if (!isset($this->types[$type])) { + throw new Exception('Unknown URL type'); + } + + $handler = $this->types[$type]['handler']; + if (!is_callable($handler)) { + throw new Exception('Unable to call function'); + } + try { + call_user_func($handler,$args); + } catch (Exception $e) { + foreach ($this->error_handlers as $err_handler) { + if (call_user_func($err_handler,$args,$type,$e) === true) { + return; + } + } + # propagate exception, as it has not been processed by handlers + throw $e; + } + } + + public function callDefaultHandler($args) + { + if (!is_callable($this->default_handler)) { + throw new Exception('Unable to call function'); + } + + try { + call_user_func($this->default_handler,$args); + } catch (Exception $e) { + foreach ($this->error_handlers as $err_handler) { + if (call_user_func($err_handler,$args,'default',$e) === true) { + return; + } + } + # propagate exception, as it has not been processed by handlers + throw $e; + } + + } + + protected function parseQueryString() + { + if (!empty($_SERVER['QUERY_STRING'])) + { + $q = explode('&',$_SERVER['QUERY_STRING']); + $T = array(); + foreach ($q as $v) + { + $t = explode('=',$v,2); + + $t[0] = rawurldecode($t[0]); + if (!isset($t[1])) { + $T[$t[0]] = null; + } else { + $T[$t[0]] = urldecode($t[1]); + } + } + + return $T; + } + return array(); + } + + protected function sortTypes() + { + foreach ($this->types as $k => $v) { + $r[$k] = $v['url']; + } + array_multisort($r,SORT_DESC,$this->types); + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/libs/clearbricks/xmlsql/class.xmlsql.php b/v2/dotclear/inc/libs/clearbricks/xmlsql/class.xmlsql.php new file mode 100644 index 0000000..e69ed3a --- /dev/null +++ b/v2/dotclear/inc/libs/clearbricks/xmlsql/class.xmlsql.php @@ -0,0 +1,180 @@ +con =& $con; + $this->xml = $xml; + + $schema = dbSchema::init($this->con); + $this->tables = $schema->getTables(); + unset($schema); + } + + public function replace($str,$rep) + { + $this->xml = str_replace($str,$rep,$this->xml); + } + + public function execute($version=0) + { + $this->test_version = $version; + + $x = @simplexml_load_string($this->xml); + if (!$x) { + throw new Exception('Unable to load XML file.'); + } + + $this->parseNode($x); + } + + protected function parseNode($node) + { + foreach ($node->children() as $n) + { + switch (dom_import_simplexml($n)->nodeName) + { + case 'test': + $this->performTest($n); + break; + case 'action': + $this->performAction($n); + break; + } + } + } + + protected function performTest($node) + { + /* Test like: + ... + */ + if (isset($node['type']) && (string) $node['type'] == 'table') + { + $test['result'] = in_array($node['name'],$this->tables); + $test['label'] = 'Table %s does not exists'; + $test['string'] = (string) $node['name']; + + $xtest = $node; + } + /* Test syntax: + ... + */ + elseif (isset($node['type']) && (string) $node['type'] == 'column') + { + $c = explode('.',$node['name']); + + if (count($c) != 2) { + return false; + + } + + list($table,$col) = $c; + + $rs = $this->con->getColumns($table); + + $test['result'] = isset($rs[$col]); + $test['label'] = 'Column %s does not exists'; + $test['string'] = (string) $node['name']; + + $xtest = $node; + } + /* Test syntax: + ... + */ + elseif (isset($node['type']) && (string) $node['type'] == 'version') + { + $comp = isset($node['comp']) ? $node['comp'] : '>'; + $test['result'] = version_compare($node['name'],$this->test_version,$comp); + $test['label'] = 'Version %s is too low'; + $test['string'] = (string) $node['name']; + + $xtest = $node; + } + + # End tests + if (isset($xtest)) + { + if ($xtest['eq'] == 'neq') { + $test['result'] = !$test['result']; + } + + if (isset($xtest['alert'])) { + $test['alert'] = (boolean) (integer) $xtest['alert']; + } else { + $test['alert'] = false; + } + + if (isset($xtest['label'])) { + $test['label'] = (string) $xtest['label']; + } + if (isset($xtest['string'])) { + $test['string'] = (string) $xtest['string']; + } + unset($xtest); + + # Test false + if (!$test['result']) + { + if ($test['alert']) { + throw new Exception(sprintf($test['label'],$test['string'])); + } + } + # Test true + else + { + $this->parseNode($node); + } + } + else + { + return false; + } + } + + protected function performAction($node) + { + $req = trim((string) $node); + if ($req) + { + try { + $this->con->execute($req); + } catch (Exception $e) { + if ($node['silent'] != 1) { + throw $e; + } + } + } + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/libs/clearbricks/zip/class.unzip.php b/v2/dotclear/inc/libs/clearbricks/zip/class.unzip.php new file mode 100644 index 0000000..09cc081 --- /dev/null +++ b/v2/dotclear/inc/libs/clearbricks/zip/class.unzip.php @@ -0,0 +1,541 @@ +file_name = $file_name; + } + + public function __destruct() + { + $this->close(); + } + + public function close() + { + if ($this->fp) { + fclose($this->fp); + $this->fp = null; + } + + if ($this->memory_limit) { + ini_set('memory_limit',$this->memory_limit); + } + } + + public function getList($stop_on_file=false,$exclude=false) + { + if (!empty($this->compressed_list)) { + return $this->compressed_list; + } + + if (!$this->loadFileListByEOF($stop_on_file,$exclude)) { + if(!$this->loadFileListBySignatures($stop_on_file,$exclude)) { + return false; + } + } + + return $this->compressed_list; + } + + public function unzipAll($target) + { + if (empty($this->compressed_list)) { + $this->getList(); + } + + foreach ($this->compressed_list as $k => $v) + { + if ($v['is_dir']) { + continue; + } + + $this->unzip($k,$target.'/'.$k); + } + } + + public function unzip($file_name,$target=false) + { + if (empty($this->compressed_list)) { + $this->getList($file_name); + } + + if (!isset($this->compressed_list[$file_name])) { + throw new Exception(sprintf(__('File %s is not compressed in the zip.'),$file_name)); + } + if ($this->isFileExcluded($file_name)) { + return; + } + $details =& $this->compressed_list[$file_name]; + + if ($details['is_dir']) { + throw new Exception(sprintf(__('Trying to unzip a folder name %s'),$file_name)); + } + + if (!$details['uncompressed_size']) { + return $this->putContent('',$target); + } + + if ($target) { + $this->testTargetDir(dirname($target)); + } + + fseek($this->fp(),$details['contents_start_offset']); + + $this->memoryAllocate($details['compressed_size']); + return $this->uncompress( + fread($this->fp(), $details['compressed_size']), + $details['compression_method'], + $details['uncompressed_size'], + $target + ); + } + + public function getFilesList() + { + if (empty($this->compressed_list)) { + $this->getList(); + } + + $res = array(); + foreach ($this->compressed_list as $k => $v) { + if (!$v['is_dir']) { + $res[] = $k; + } + } + return $res; + } + + public function getDirsList() + { + if (empty($this->compressed_list)) { + $this->getList(); + } + + $res = array(); + foreach ($this->compressed_list as $k => $v) { + if ($v['is_dir']) { + $res[] = substr($k,0,-1); + } + } + return $res; + } + + public function getRootDir() + { + if (empty($this->compressed_list)) { + $this->getList(); + } + + $files = $this->getFilesList(); + $dirs = $this->getDirsList(); + + $root_files = 0; + $root_dirs = 0; + foreach ($files as $v) { if (strpos($v,'/') === false) { $root_files++; }} + foreach ($dirs as $v) { if (strpos($v,'/') === false) { $root_dirs++; }} + + if ($root_files == 0 && $root_dirs == 1) { + return $dirs[0]; + } else { + return false; + } + } + + public function isEmpty() + { + if (empty($this->compressed_list)) { + $this->getList(); + } + + return count($this->compressed_list) == 0; + } + + public function hasFile($f) + { + if (empty($this->compressed_list)) { + $this->getList(); + } + + return isset($this->compressed_list[$f]); + } + + public function setExcludePattern($pattern) + { + $this->exclude_pattern = $pattern; + } + + protected function fp() + { + if ($this->fp === null) { + $this->fp = @fopen($this->file_name,'rb'); + } + + if ($this->fp === false) { + throw new Exception('Unable to open file.'); + } + + return $this->fp; + } + + protected function isFileExcluded($f) + { + if (!$this->exclude_pattern) { + return false; + } + + return preg_match($this->exclude_pattern,$f); + } + + protected function putContent($content,$target=false) + { + if ($target) { + $r = @file_put_contents($target,$content); + if ($r === false) { + throw new Exception(__('Unable to write destination file.')); + } + files::inheritChmod($target); + return true; + } + return $content; + } + + protected function testTargetDir($dir) + { + if (is_dir($dir) && !is_writable($dir)) { + throw new Exception(__('Unable to write in target directory, permission denied.')); + } + + if (!is_dir($dir)) { + files::makeDir($dir,true); + } + } + + protected function uncompress($content,$mode,$size,$target=false) + { + switch ($mode) + { + case 0: + # Not compressed + $this->memoryAllocate($size*2); + return $this->putContent($content,$target); + case 1: + throw new Exception('Shrunk mode is not supported.'); + case 2: + case 3: + case 4: + case 5: + throw new Exception('Compression factor '.($mode-1).' is not supported.'); + case 6: + throw new Exception('Implode is not supported.'); + case 7: + throw new Exception('Tokenizing compression algorithm is not supported.'); + case 8: + # Deflate + if (!function_exists('gzinflate')) { + throw new Exception('Gzip functions are not available.'); + } + $this->memoryAllocate($size*2); + return $this->putContent(gzinflate($content,$size),$target); + case 9: + throw new Exception('Enhanced Deflating is not supported.'); + case 10: + throw new Exception('PKWARE Date Compression Library Impoloding is not supported.'); + case 12: + # Bzip2 + if (!function_exists('bzdecompress')) { + throw new Exception('Bzip2 functions are not available.'); + } + $this->memoryAllocate($size*2); + return $this->putContent(bzdecompress($content),$target); + case 18: + throw new Exception('IBM TERSE is not supported.'); + default: + throw new Exception('Unknown uncompress method'); + } + } + + protected function loadFileListByEOF($stop_on_file=false,$exclude=false) + { + $fp = $this->fp(); + + for ($x=0; $x<1024; $x++) + { + fseek($fp,-22-$x,SEEK_END); + $signature = fread($fp,4); + + if ($signature == $this->dir_sig_e) + { + $dir_list = array(); + + $eodir = array( + 'disk_number_this' => unpack('v', fread($fp,2)), + 'disk_number' => unpack('v', fread($fp,2)), + 'total_entries_this' => unpack('v', fread($fp,2)), + 'total_entries' => unpack('v', fread($fp,2)), + 'size_of_cd' => unpack('V', fread($fp,4)), + 'offset_start_cd' => unpack('V', fread($fp,4)) + ); + + $zip_comment_len = unpack('v', fread($fp,2)); + $eodir['zipfile_comment'] = $zip_comment_len[1] ? fread($fp,$zip_comment_len) : ''; + + $this->eo_central = array( + 'disk_number_this' => $eodir['disk_number_this'][1], + 'disk_number' => $eodir['disk_number'][1], + 'total_entries_this' => $eodir['total_entries_this'][1], + 'total_entries' => $eodir['total_entries'][1], + 'size_of_cd' => $eodir['size_of_cd'][1], + 'offset_start_cd' => $eodir['offset_start_cd'][1], + 'zipfile_comment' => $eodir['zipfile_comment'] + ); + + fseek($fp, $this->eo_central['offset_start_cd']); + $signature = fread($fp,4); + + while ($signature == $this->dir_sig) + { + $dir = array(); + $dir['version_madeby'] = unpack("v",fread($fp, 2)); # version made by + $dir['version_needed'] = unpack("v",fread($fp, 2)); # version needed to extract + $dir['general_bit_flag'] = unpack("v",fread($fp, 2)); # general purpose bit flag + $dir['compression_method'] = unpack("v",fread($fp, 2)); # compression method + $dir['lastmod_time'] = unpack("v",fread($fp, 2)); # last mod file time + $dir['lastmod_date'] = unpack("v",fread($fp, 2)); # last mod file date + $dir['crc-32'] = fread($fp,4); # crc-32 + $dir['compressed_size'] = unpack("V",fread($fp, 4)); # compressed size + $dir['uncompressed_size'] = unpack("V",fread($fp, 4)); # uncompressed size + + $file_name_len = unpack("v",fread($fp, 2)); # filename length + $extra_field_len = unpack("v",fread($fp, 2)); # extra field length + $file_comment_len = unpack("v",fread($fp, 2)); # file comment length + + $dir['disk_number_start'] = unpack("v",fread($fp, 2)); # disk number start + $dir['internal_attributes'] = unpack("v",fread($fp, 2)); # internal file attributes-byte1 + $dir['external_attributes1'] = unpack("v",fread($fp, 2)); # external file attributes-byte2 + $dir['external_attributes2'] = unpack("v",fread($fp, 2)); # external file attributes + $dir['relative_offset'] = unpack("V",fread($fp, 4)); # relative offset of local header + $dir['file_name'] = $this->cleanFileName(fread($fp, $file_name_len[1])); # filename + $dir['extra_field'] = $extra_field_len[1] ? fread($fp, $extra_field_len[1]) : ''; # extra field + $dir['file_comment'] = $file_comment_len[1] ? fread($fp, $file_comment_len[1]) : ''; # file comment + + $dir_list[$dir['file_name']] = array( + 'version_madeby' => $dir['version_madeby'][1], + 'version_needed' => $dir['version_needed'][1], + 'general_bit_flag' => str_pad(decbin($dir['general_bit_flag'][1]), 8, '0', STR_PAD_LEFT), + 'compression_method' => $dir['compression_method'][1], + 'lastmod_datetime' => $this->getTimeStamp($dir['lastmod_date'][1],$dir['lastmod_time'][1]), + 'crc-32' => str_pad(dechex(ord($dir['crc-32'][3])), 2, '0', STR_PAD_LEFT). + str_pad(dechex(ord($dir['crc-32'][2])), 2, '0', STR_PAD_LEFT). + str_pad(dechex(ord($dir['crc-32'][1])), 2, '0', STR_PAD_LEFT). + str_pad(dechex(ord($dir['crc-32'][0])), 2, '0', STR_PAD_LEFT), + 'compressed_size' => $dir['compressed_size'][1], + 'uncompressed_size' => $dir['uncompressed_size'][1], + 'disk_number_start' => $dir['disk_number_start'][1], + 'internal_attributes' => $dir['internal_attributes'][1], + 'external_attributes1' => $dir['external_attributes1'][1], + 'external_attributes2' => $dir['external_attributes2'][1], + 'relative_offset' => $dir['relative_offset'][1], + 'file_name' => $dir['file_name'], + 'extra_field' => $dir['extra_field'], + 'file_comment' => $dir['file_comment'] + ); + $signature = fread($fp, 4); + } + + foreach ($dir_list as $k => $v) + { + if ($exclude && preg_match($exclude,$k)) { + continue; + } + + $i = $this->getFileHeaderInformation($v['relative_offset']); + + $this->compressed_list[$k]['file_name'] = $k; + $this->compressed_list[$k]['is_dir'] = $v['external_attributes1'] == 16 || substr($k,-1,1) == '/'; + $this->compressed_list[$k]['compression_method'] = $v['compression_method']; + $this->compressed_list[$k]['version_needed'] = $v['version_needed']; + $this->compressed_list[$k]['lastmod_datetime'] = $v['lastmod_datetime']; + $this->compressed_list[$k]['crc-32'] = $v['crc-32']; + $this->compressed_list[$k]['compressed_size'] = $v['compressed_size']; + $this->compressed_list[$k]['uncompressed_size'] = $v['uncompressed_size']; + $this->compressed_list[$k]['lastmod_datetime'] = $v['lastmod_datetime']; + $this->compressed_list[$k]['extra_field'] = $i['extra_field']; + $this->compressed_list[$k]['contents_start_offset'] = $i['contents_start_offset']; + + if(strtolower($stop_on_file) == strtolower($k)) { + break; + } + } + return true; + } + } + return false; + } + + protected function loadFileListBySignatures($stop_on_file=false,$exclude=false) + { + $fp = $this->fp(); + fseek($fp,0); + + $return = false; + while(true) + { + $details = $this->getFileHeaderInformation(); + if (!$details) { + fseek($fp,12-4,SEEK_CUR); # 12: Data descriptor - 4: Signature (that will be read again) + $details = $this->getFileHeaderInformation(); + } + if (!$details) { + break; + } + $filename = $details['file_name']; + + if ($exclude && preg_match($exclude,$filename)) { + continue; + } + + $this->compressed_list[$filename] = $details; + $return = true; + + if (strtolower($stop_on_file) == strtolower($filename)) { + break; + } + } + + return $return; + } + + protected function getFileHeaderInformation($start_offset=false) + { + $fp = $this->fp(); + + if ($start_offset !== false) { + fseek($fp,$start_offset); + } + + $signature = fread($fp, 4); + if ($signature == $this->zip_sig) + { + # Get information about the zipped file + $file = array(); + $file['version_needed'] = unpack("v",fread($fp, 2)); # version needed to extract + $file['general_bit_flag'] = unpack("v",fread($fp, 2)); # general purpose bit flag + $file['compression_method'] = unpack("v",fread($fp, 2)); # compression method + $file['lastmod_time'] = unpack("v",fread($fp, 2)); # last mod file time + $file['lastmod_date'] = unpack("v",fread($fp, 2)); # last mod file date + $file['crc-32'] = fread($fp,4); # crc-32 + $file['compressed_size'] = unpack("V",fread($fp, 4)); # compressed size + $file['uncompressed_size'] = unpack("V",fread($fp, 4)); # uncompressed size + + $file_name_len = unpack("v",fread($fp, 2)); # filename length + $extra_field_len = unpack("v",fread($fp, 2)); # extra field length + + $file['file_name'] = $this->cleanFileName(fread($fp,$file_name_len[1])); # filename + $file['extra_field'] = $extra_field_len[1] ? fread($fp, $extra_field_len[1]) : ''; # extra field + $file['contents_start_offset'] = ftell($fp); + + # Look for the next file + fseek($fp, $file['compressed_size'][1], SEEK_CUR); + + # Mount file table + $i = array( + 'file_name' => $file['file_name'], + 'is_dir' => substr($file['file_name'],-1,1) == '/', + 'compression_method' => $file['compression_method'][1], + 'version_needed' => $file['version_needed'][1], + 'lastmod_datetime' => $this->getTimeStamp($file['lastmod_date'][1],$file['lastmod_time'][1]), + 'crc-32' => str_pad(dechex(ord($file['crc-32'][3])), 2, '0', STR_PAD_LEFT). + str_pad(dechex(ord($file['crc-32'][2])), 2, '0', STR_PAD_LEFT). + str_pad(dechex(ord($file['crc-32'][1])), 2, '0', STR_PAD_LEFT). + str_pad(dechex(ord($file['crc-32'][0])), 2, '0', STR_PAD_LEFT), + 'compressed_size' => $file['compressed_size'][1], + 'uncompressed_size' => $file['uncompressed_size'][1], + 'extra_field' => $file['extra_field'], + 'general_bit_flag' => str_pad(decbin($file['general_bit_flag'][1]), 8, '0', STR_PAD_LEFT), + 'contents_start_offset'=>$file['contents_start_offset'] + ); + return $i; + } + return false; + } + + protected function getTimeStamp($date,$time) + { + $BINlastmod_date = str_pad(decbin($date), 16, '0', STR_PAD_LEFT); + $BINlastmod_time = str_pad(decbin($time), 16, '0', STR_PAD_LEFT); + $lastmod_dateY = bindec(substr($BINlastmod_date, 0, 7))+1980; + $lastmod_dateM = bindec(substr($BINlastmod_date, 7, 4)); + $lastmod_dateD = bindec(substr($BINlastmod_date, 11, 5)); + $lastmod_timeH = bindec(substr($BINlastmod_time, 0, 5)); + $lastmod_timeM = bindec(substr($BINlastmod_time, 5, 6)); + $lastmod_timeS = bindec(substr($BINlastmod_time, 11, 5)) * 2; + + return mktime($lastmod_timeH, $lastmod_timeM, $lastmod_timeS, $lastmod_dateM, $lastmod_dateD, $lastmod_dateY); + } + + protected function cleanFileName($n) + { + $n = str_replace('../','',$n); + $n = preg_replace('#^/+#','',$n); + return $n; + } + + protected function memoryAllocate($size) + { + $mem_used = function_exists('memory_get_usage') ? @memory_get_usage() : 4000000; + $mem_limit = @ini_get('memory_limit'); + if ($mem_used && $mem_limit) + { + $mem_limit = files::str2bytes($mem_limit); + $mem_avail = $mem_limit-$mem_used-(512*1024); + $mem_needed = $size; + + if ($mem_needed > $mem_avail) + { + if (@ini_set('memory_limit',$mem_limit+$mem_needed+$mem_used) === false) { + throw new Exception(__('Not enough memory to open file.')); + } + + if (!$this->memory_limit) { + $this->memory_limit = $mem_limit; + } + } + } + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/libs/clearbricks/zip/class.zip.php b/v2/dotclear/inc/libs/clearbricks/zip/class.zip.php new file mode 100644 index 0000000..f5656e9 --- /dev/null +++ b/v2/dotclear/inc/libs/clearbricks/zip/class.zip.php @@ -0,0 +1,370 @@ +fp = $out_fp; + } + + public function __destruct() + { + $this->close(); + } + + public function close() + { + if ($this->memory_limit) { + ini_set('memory_limit',$this->memory_limit); + } + } + + public function addExclusion($reg) + { + $this->exclusions[] = $reg; + } + + public function addFile($file,$name=null) + { + $file = preg_replace('#[\\\/]+#','/',$file); + + if (!$name) { + $name = $file; + } + $name = $this->formatName($name); + + if ($this->isExcluded($name)) { + return; + } + + if (!file_exists($file) || !is_file($file)) { + throw new Exception(__('File does not exist')); + } + if (!is_readable($file)) { + throw new Exception(__('Cannot read file')); + } + + $info = stat($file); + + $this->entries[$name] = array( + 'file' => $file, + 'is_dir' => false, + 'mtime' => $info['mtime'], + 'size' => $info['size'] + ); + } + + public function addDirectory($dir,$name=null,$recursive=false) + { + $dir = preg_replace('#[\\\/]+#','/',$dir); + if (substr($dir,-1-1) != '/') { + $dir .= '/'; + } + + if (!$name && $name !== '') { + $name = $dir; + } + + if ($this->isExcluded($name)) { + return; + } + + if ($name !== '') + { + if (substr($name,-1,1) != '/') { + $name .= '/'; + } + + $name = $this->formatName($name); + + if ($name !== '') + { + $this->entries[$name] = array( + 'file' => null, + 'is_dir' => true, + 'mtime' => time(), + 'size' => 0 + ); + } + } + + if ($recursive) + { + if (!is_dir($dir)) { + throw new Exception(__('Directory does not exist')); + } + if (!is_readable($dir)) { + throw new Exception(__('Cannot read directory')); + } + + $D = dir($dir); + while (($e = $D->read()) !== false) { + if ($e == '.' || $e == '..') { + continue; + } + + if (is_dir($dir.'/'.$e)) { + $this->addDirectory($dir.$e,$name.$e,true); + } elseif (is_file($dir.'/'.$e)) { + $this->addFile($dir.$e,$name.$e); + } + } + } + } + + public function write() + { + foreach ($this->entries as $name => $v) + { + if ($v['is_dir']) { + $this->writeDirectory($name); + } else { + $this->writeFile($name,$v['file'],$v['size'],$v['mtime']); + } + } + + $ctrldir = implode('',$this->ctrl_dir); + + fwrite($this->fp, + $ctrldir. + $this->eof_ctrl_dir. + pack('v',sizeof($this->ctrl_dir)). # total # of entries "on this disk" + pack('v',sizeof($this->ctrl_dir)). # total # of entries overall + pack('V',strlen($ctrldir)). # size of central dir + pack('V',$this->old_offset). # offset to start of central dir + "\x00\x00" # .zip file comment length + ); + } + + protected function writeDirectory($name) + { + if (!isset($this->entries[$name])) { + return; + } + + $mdate = $this->makeDate(time()); + $mtime = $this->makeTime(time()); + + # Data descriptor + $data_desc = + "\x50\x4b\x03\x04". + "\x0a\x00". # ver needed to extract + "\x00\x00". # gen purpose bit flag + "\x00\x00". # compression method + pack('v',$mtime). # last mod time + pack('v',$mdate). # last mod date + pack('V',0). # crc32 + pack('V',0). # compressed filesize + pack('V',0). # uncompressed filesize + pack('v',strlen($name)). # length of pathname + pack('v',0). # extra field length + $name. # end of "local file header" segment + pack('V',0). # crc32 + pack('V',0). # compressed filesize + pack('V',0); # uncompressed filesize + + $new_offset = $this->old_offset + strlen($data_desc); + fwrite($this->fp,$data_desc); + + # Add to central record + $cdrec = + "\x50\x4b\x01\x02". + "\x00\x00". # version made by + "\x0a\x00". # version needed to extract + "\x00\x00". # gen purpose bit flag + "\x00\x00". # compression method + pack('v',$mtime). # last mod time + pack('v',$mdate). # last mod date + pack('V',0). # crc32 + pack('V',0). # compressed filesize + pack('V',0). # uncompressed filesize + pack('v',strlen($name)). # length of filename + pack('v',0). # extra field length + pack('v',0). # file comment length + pack('v',0). # disk number start + pack('v',0). # internal file attributes + pack('V',16). # external file attributes - 'directory' bit set + pack('V',$this->old_offset). # relative offset of local header + $name; + + $this->old_offset = $new_offset; + $this->ctrl_dir[] = $cdrec; + } + + protected function writeFile($name,$file,$size,$mtime) + { + if (!isset($this->entries[$name])) { + return; + } + + $size = filesize($file); + $this->memoryAllocate($size*3); + + $content = file_get_contents($file); + + $unc_len = strlen($content); + $crc = crc32($content); + $zdata = gzdeflate($content); + $c_len = strlen($zdata); + + unset($content); + + $mdate = $this->makeDate($mtime); + $mtime = $this->makeTime($mtime); + + # Data descriptor + $data_desc = + "\x50\x4b\x03\x04". + "\x14\x00". # ver needed to extract + "\x00\x00". # gen purpose bit flag + "\x08\x00". # compression method + pack('v',$mtime). # last mod time + pack('v',$mdate). # last mod date + pack('V',$crc). # crc32 + pack('V',$c_len). # compressed filesize + pack('V',$unc_len). # uncompressed filesize + pack('v',strlen($name)). # length of filename + pack('v',0). # extra field length + $name. # end of "local file header" segment + $zdata. # "file data" segment + pack('V',$crc). # crc32 + pack('V',$c_len). # compressed filesize + pack('V',$unc_len); # uncompressed filesize + + fwrite($this->fp,$data_desc); + unset($zdata); + + $new_offset = $this->old_offset + strlen($data_desc); + + # Add to central directory record + $cdrec = + "\x50\x4b\x01\x02". + "\x00\x00". # version made by + "\x14\x00". # version needed to extract + "\x00\x00". # gen purpose bit flag + "\x08\x00". # compression method + pack('v',$mtime). # last mod time + pack('v',$mdate). # last mod date + pack('V',$crc). # crc32 + pack('V',$c_len). # compressed filesize + pack('V',$unc_len). # uncompressed filesize + pack('v',strlen($name)). # length of filename + pack('v',0). # extra field length + pack('v',0). # file comment length + pack('v',0). # disk number start + pack('v',0). # internal file attributes + pack('V',32). # external file attributes - 'archive' bit set + pack('V',$this->old_offset). # relative offset of local header + $name; + + $this->old_offset = $new_offset; + $this->ctrl_dir[] = $cdrec; + } + + protected function formatName($name) + { + if (substr($name,0,1) == '/') { + $name = substr($name,1); + } + + return $name; + } + + protected function isExcluded($name) + { + foreach ($this->exclusions as $reg) { + if (preg_match($reg,$name)) { + return true; + } + } + + return false; + } + + protected function makeDate($ts) + { + $year = date('Y',$ts)-1980; + if ($year < 0) { + $year = 0; + } + + $year = sprintf('%07b',$year); + $month = sprintf('%04b',date('n',$ts)); + $day = sprintf('%05b',date('j',$ts)); + + return bindec($year.$month.$day); + } + + protected function makeTime($ts) + { + $hour = sprintf('%05b',date('G',$ts)); + $minute = sprintf('%06b',date('i',$ts)); + $second = sprintf('%05b',ceil(date('s',$ts)/2)); + + return bindec($hour.$minute.$second); + } + + protected function memoryAllocate($size) + { + $mem_used = function_exists('memory_get_usage') ? @memory_get_usage() : 4000000; + $mem_limit = @ini_get('memory_limit'); + if ($mem_used && $mem_limit) + { + $mem_limit = files::str2bytes($mem_limit); + $mem_avail = $mem_limit-$mem_used-(512*1024); + $mem_needed = $size; + + if ($mem_needed > $mem_avail) + { + if (@ini_set('memory_limit',$mem_limit+$mem_needed+$mem_used) === false) { + throw new Exception(__('Not enough memory to open file.')); + } + + if (!$this->memory_limit) { + $this->memory_limit = $mem_limit; + } + } + } + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/load_plugin_file.php b/v2/dotclear/inc/load_plugin_file.php new file mode 100644 index 0000000..033f17d --- /dev/null +++ b/v2/dotclear/inc/load_plugin_file.php @@ -0,0 +1,87 @@ + \ No newline at end of file diff --git a/v2/dotclear/inc/prepend.php b/v2/dotclear/inc/prepend.php new file mode 100644 index 0000000..bc48181 --- /dev/null +++ b/v2/dotclear/inc/prepend.php @@ -0,0 +1,286 @@ +getCode() == 0 ? + sprintf(__('

        This either means that the username and password information in '. + 'your config.php file is incorrect or we can\'t contact '. + 'the database server at "%s". This could mean your '. + 'host\'s database server is down.

        '. + '
        • Are you sure you have the correct username and password?
        • '. + '
        • Are you sure that you have typed the correct hostname?
        • '. + '
        • Are you sure that the database server is running?
        '. + '

        If you\'re unsure what these terms mean you should probably contact '. + 'your host. If you still need help you can always visit the '. + 'Dotclear Support Forums.

        '). + (DC_DEBUG ? + __('The following error was encountered while trying to read the database:').'

        • '.$e->getMessage().'
        ' : '') + ,(DC_DBHOST != '' ? DC_DBHOST : 'localhost') + ) + : '' + ,20); +} + +# If we have some __top_behaviors, we load them +if (isset($__top_behaviors) && is_array($__top_behaviors)) +{ + foreach ($__top_behaviors as $b) { + $core->addBehavior($b[0],$b[1]); + } + unset($b); +} + +http::trimRequest(); +try { + http::unsetGlobals(); +} catch (Exception $e) { + header('Content-Type: text/plain'); + echo $e->getMessage(); + exit; +} + +$core->url->registerDefault(array('dcUrlHandlers','home')); +$core->url->registerError(array('dcUrlHandlers','default404')); +$core->url->register('lang','','^([a-zA-Z]{2}(?:-[a-z]{2})?(?:/page/[0-9]+)?)$',array('dcUrlHandlers','lang')); +$core->url->register('post','post','^post/(.+)$',array('dcUrlHandlers','post')); +$core->url->register('preview','preview','^preview/(.+)$',array('dcUrlHandlers','preview')); +$core->url->register('category','category','^category/(.+)$',array('dcUrlHandlers','category')); +$core->url->register('archive','archive','^archive(/.+)?$',array('dcUrlHandlers','archive')); + +$core->url->register('feed','feed','^feed/(.+)$',array('dcUrlHandlers','feed')); +$core->url->register('trackback','trackback','^trackback/(.+)$',array('dcUrlHandlers','trackback')); +$core->url->register('rsd','rsd','^rsd$',array('dcUrlHandlers','rsd')); +$core->url->register('xmlrpc','xmlrpc','^xmlrpc/(.+)$',array('dcUrlHandlers','xmlrpc')); + +$core->setPostType('post','post.php?id=%d',$core->url->getURLFor('post','%s')); + +# Store upload_max_filesize in bytes +$u_max_size = files::str2bytes(ini_get('upload_max_filesize')); +$p_max_size = files::str2bytes(ini_get('post_max_size')); +if ($p_max_size < $u_max_size) { + $u_max_size = $p_max_size; +} +define('DC_MAX_UPLOAD_SIZE',$u_max_size); +unset($u_max_size); unset($p_max_size); + +# Shutdown +register_shutdown_function('__shutdown'); + +function __shutdown() +{ + global $__shutdown; + if (is_array($__shutdown)) { + foreach ($__shutdown as $f) { + if (is_callable($f)) { + call_user_func($f); + } + } + } + # Explicitly close session before DB connection + try { + if (session_id()) { + session_write_close(); + } + } catch (Exception $e) {} + $GLOBALS['core']->con->close(); +} + +function __error($summary,$message,$code=0) +{ + # Error codes + # 10 : no config file + # 20 : database issue + # 30 : blog is not defined + # 40 : template files creation + # 50 : no default theme + # 60 : template processing error + # 70 : blog is offline + + if (CLI_MODE) + { + trigger_error($summary,E_USER_ERROR); + exit(1); + } + else + { + if (defined('DC_ERRORFILE') && is_file(DC_ERRORFILE)) { + include DC_ERRORFILE; + } else { + include dirname(__FILE__).'/core_error.php'; + } + exit; + } +} + +function init_prepend_l10n() +{ + # Loading locales for detected language + $dlang = http::getAcceptLanguages(); + foreach($dlang as $l) + { + if ($l == 'en' || l10n::set(dirname(__FILE__).'/../locales/'.$l.'/main') !== false) { + break; + } + } +} +?> diff --git a/v2/dotclear/inc/public/class.dc.template.php b/v2/dotclear/inc/public/class.dc.template.php new file mode 100644 index 0000000..8bda8ce --- /dev/null +++ b/v2/dotclear/inc/public/class.dc.template.php @@ -0,0 +1,3095 @@ +remove_php = !$core->blog->settings->system->tpl_allow_php; + $this->use_cache = $core->blog->settings->system->tpl_use_cache; + + $this->tag_block = '|>)((?:[^<]|<(?!/?tpl:\1)|(?R))*)'; + $this->tag_value = '{{tpl:(\w+)(\s(.*?))?}}'; + + $this->core =& $core; + + # Transitional tags + $this->addValue('EntryTrackbackCount',array($this,'EntryPingCount')); + $this->addValue('EntryTrackbackData',array($this,'EntryPingData')); + $this->addValue('EntryTrackbackLink',array($this,'EntryPingLink')); + + # l10n + $this->addValue('lang',array($this,'l10n')); + + # Loops test tags + $this->addBlock('LoopPosition',array($this,'LoopPosition')); + + # Archives + $this->addBlock('Archives',array($this,'Archives')); + $this->addBlock('ArchivesHeader',array($this,'ArchivesHeader')); + $this->addBlock('ArchivesFooter',array($this,'ArchivesFooter')); + $this->addBlock('ArchivesYearHeader',array($this,'ArchivesYearHeader')); + $this->addBlock('ArchivesYearFooter',array($this,'ArchivesYearFooter')); + $this->addValue('ArchiveDate',array($this,'ArchiveDate')); + $this->addBlock('ArchiveNext',array($this,'ArchiveNext')); + $this->addBlock('ArchivePrevious',array($this,'ArchivePrevious')); + $this->addValue('ArchiveEntriesCount',array($this,'ArchiveEntriesCount')); + $this->addValue('ArchiveURL',array($this,'ArchiveURL')); + + # Blog + $this->addValue('BlogArchiveURL',array($this,'BlogArchiveURL')); + $this->addValue('BlogCopyrightNotice',array($this,'BlogCopyrightNotice')); + $this->addValue('BlogDescription',array($this,'BlogDescription')); + $this->addValue('BlogEditor',array($this,'BlogEditor')); + $this->addValue('BlogFeedID',array($this,'BlogFeedID')); + $this->addValue('BlogFeedURL',array($this,'BlogFeedURL')); + $this->addValue('BlogRSDURL',array($this,'BlogRSDURL')); + $this->addValue('BlogName',array($this,'BlogName')); + $this->addValue('BlogLanguage',array($this,'BlogLanguage')); + $this->addValue('BlogThemeURL',array($this,'BlogThemeURL')); + $this->addValue('BlogUpdateDate',array($this,'BlogUpdateDate')); + $this->addValue('BlogID',array($this,'BlogID')); + $this->addValue('BlogURL',array($this,'BlogURL')); + $this->addValue('BlogPublicURL',array($this,'BlogPublicURL')); + $this->addValue('BlogQmarkURL',array($this,'BlogQmarkURL')); + $this->addValue('BlogMetaRobots',array($this,'BlogMetaRobots')); + + # Categories + $this->addBlock('Categories',array($this,'Categories')); + $this->addBlock('CategoriesHeader',array($this,'CategoriesHeader')); + $this->addBlock('CategoriesFooter',array($this,'CategoriesFooter')); + $this->addBlock('CategoryIf',array($this,'CategoryIf')); + $this->addBlock('CategoryFirstChildren',array($this,'CategoryFirstChildren')); + $this->addBlock('CategoryParents',array($this,'CategoryParents')); + $this->addValue('CategoryFeedURL',array($this,'CategoryFeedURL')); + $this->addValue('CategoryURL',array($this,'CategoryURL')); + $this->addValue('CategoryShortURL',array($this,'CategoryShortURL')); + $this->addValue('CategoryDescription',array($this,'CategoryDescription')); + $this->addValue('CategoryTitle',array($this,'CategoryTitle')); + + # Comments + $this->addBlock('Comments',array($this,'Comments')); + $this->addValue('CommentAuthor',array($this,'CommentAuthor')); + $this->addValue('CommentAuthorDomain',array($this,'CommentAuthorDomain')); + $this->addValue('CommentAuthorLink',array($this,'CommentAuthorLink')); + $this->addValue('CommentAuthorMailMD5',array($this,'CommentAuthorMailMD5')); + $this->addValue('CommentAuthorURL',array($this,'CommentAuthorURL')); + $this->addValue('CommentContent',array($this,'CommentContent')); + $this->addValue('CommentDate',array($this,'CommentDate')); + $this->addValue('CommentTime',array($this,'CommentTime')); + $this->addValue('CommentEmail',array($this,'CommentEmail')); + $this->addValue('CommentEntryTitle',array($this,'CommentEntryTitle')); + $this->addValue('CommentFeedID',array($this,'CommentFeedID')); + $this->addValue('CommentID',array($this,'CommentID')); + $this->addBlock('CommentIf',array($this,'CommentIf')); + $this->addValue('CommentIfFirst',array($this,'CommentIfFirst')); + $this->addValue('CommentIfMe',array($this,'CommentIfMe')); + $this->addValue('CommentIfOdd',array($this,'CommentIfOdd')); + $this->addValue('CommentIP',array($this,'CommentIP')); + $this->addValue('CommentOrderNumber',array($this,'CommentOrderNumber')); + $this->addBlock('CommentsFooter',array($this,'CommentsFooter')); + $this->addBlock('CommentsHeader',array($this,'CommentsHeader')); + $this->addValue('CommentPostURL',array($this,'CommentPostURL')); + $this->addBlock('IfCommentAuthorEmail',array($this,'IfCommentAuthorEmail')); + $this->addValue('CommentHelp',array($this,'CommentHelp')); + + # Comment preview + $this->addBlock('IfCommentPreview',array($this,'IfCommentPreview')); + $this->addValue('CommentPreviewName',array($this,'CommentPreviewName')); + $this->addValue('CommentPreviewEmail',array($this,'CommentPreviewEmail')); + $this->addValue('CommentPreviewSite',array($this,'CommentPreviewSite')); + $this->addValue('CommentPreviewContent',array($this,'CommentPreviewContent')); + $this->addValue('CommentPreviewCheckRemember',array($this,'CommentPreviewCheckRemember')); + + # Entries + $this->addBlock('DateFooter',array($this,'DateFooter')); + $this->addBlock('DateHeader',array($this,'DateHeader')); + $this->addBlock('Entries',array($this,'Entries')); + $this->addBlock('EntriesFooter',array($this,'EntriesFooter')); + $this->addBlock('EntriesHeader',array($this,'EntriesHeader')); + $this->addValue('EntryExcerpt',array($this,'EntryExcerpt')); + $this->addValue('EntryAuthorCommonName',array($this,'EntryAuthorCommonName')); + $this->addValue('EntryAuthorDisplayName',array($this,'EntryAuthorDisplayName')); + $this->addValue('EntryAuthorEmail',array($this,'EntryAuthorEmail')); + $this->addValue('EntryAuthorID',array($this,'EntryAuthorID')); + $this->addValue('EntryAuthorLink',array($this,'EntryAuthorLink')); + $this->addValue('EntryAuthorURL',array($this,'EntryAuthorURL')); + $this->addValue('EntryBasename',array($this,'EntryBasename')); + $this->addValue('EntryCategory',array($this,'EntryCategory')); + $this->addBlock('EntryCategoriesBreadcrumb',array($this,'EntryCategoriesBreadcrumb')); + $this->addValue('EntryCategoryID',array($this,'EntryCategoryID')); + $this->addValue('EntryCategoryURL',array($this,'EntryCategoryURL')); + $this->addValue('EntryCategoryShortURL',array($this,'EntryCategoryShortURL')); + $this->addValue('EntryCommentCount',array($this,'EntryCommentCount')); + $this->addValue('EntryContent',array($this,'EntryContent')); + $this->addValue('EntryDate',array($this,'EntryDate')); + $this->addValue('EntryFeedID',array($this,'EntryFeedID')); + $this->addValue('EntryFirstImage',array($this,'EntryFirstImage')); + $this->addValue('EntryID',array($this,'EntryID')); + $this->addBlock('EntryIf',array($this,'EntryIf')); + $this->addValue('EntryIfFirst',array($this,'EntryIfFirst')); + $this->addValue('EntryIfOdd',array($this,'EntryIfOdd')); + $this->addValue('EntryIfSelected',array($this,'EntryIfSelected')); + $this->addValue('EntryLang',array($this,'EntryLang')); + $this->addBlock('EntryNext',array($this,'EntryNext')); + $this->addValue('EntryPingCount',array($this,'EntryPingCount')); + $this->addValue('EntryPingData',array($this,'EntryPingData')); + $this->addValue('EntryPingLink',array($this,'EntryPingLink')); + $this->addBlock('EntryPrevious',array($this,'EntryPrevious')); + $this->addValue('EntryTitle',array($this,'EntryTitle')); + $this->addValue('EntryTime',array($this,'EntryTime')); + $this->addValue('EntryURL',array($this,'EntryURL')); + + # Languages + $this->addBlock('Languages',array($this,'Languages')); + $this->addBlock('LanguagesHeader',array($this,'LanguagesHeader')); + $this->addBlock('LanguagesFooter',array($this,'LanguagesFooter')); + $this->addValue('LanguageCode',array($this,'LanguageCode')); + $this->addBlock('LanguageIfCurrent',array($this,'LanguageIfCurrent')); + $this->addValue('LanguageURL',array($this,'LanguageURL')); + + # Pagination + $this->addBlock('Pagination',array($this,'Pagination')); + $this->addValue('PaginationCounter',array($this,'PaginationCounter')); + $this->addValue('PaginationCurrent',array($this,'PaginationCurrent')); + $this->addBlock('PaginationIf',array($this,'PaginationIf')); + $this->addValue('PaginationURL',array($this,'PaginationURL')); + + # Trackbacks + $this->addValue('PingBlogName',array($this,'PingBlogName')); + $this->addValue('PingContent',array($this,'PingContent')); + $this->addValue('PingDate',array($this,'PingDate')); + $this->addValue('PingEntryTitle',array($this,'PingEntryTitle')); + $this->addValue('PingFeedID',array($this,'PingFeedID')); + $this->addValue('PingID',array($this,'PingID')); + $this->addValue('PingIfFirst',array($this,'PingIfFirst')); + $this->addValue('PingIfOdd',array($this,'PingIfOdd')); + $this->addValue('PingIP',array($this,'PingIP')); + $this->addValue('PingNoFollow',array($this,'PingNoFollow')); + $this->addValue('PingOrderNumber',array($this,'PingOrderNumber')); + $this->addValue('PingPostURL',array($this,'PingPostURL')); + $this->addBlock('Pings',array($this,'Pings')); + $this->addBlock('PingsFooter',array($this,'PingsFooter')); + $this->addBlock('PingsHeader',array($this,'PingsHeader')); + $this->addValue('PingTime',array($this,'PingTime')); + $this->addValue('PingTitle',array($this,'PingTitle')); + $this->addValue('PingAuthorURL',array($this,'PingAuthorURL')); + + # System + $this->addValue('SysBehavior',array($this,'SysBehavior')); + $this->addBlock('SysIf',array($this,'SysIf')); + $this->addBlock('SysIfCommentPublished',array($this,'SysIfCommentPublished')); + $this->addBlock('SysIfCommentPending',array($this,'SysIfCommentPending')); + $this->addBlock('SysIfFormError',array($this,'SysIfFormError')); + $this->addValue('SysFeedSubtitle',array($this,'SysFeedSubtitle')); + $this->addValue('SysFormError',array($this,'SysFormError')); + $this->addValue('SysPoweredBy',array($this,'SysPoweredBy')); + $this->addValue('SysSearchString',array($this,'SysSearchString')); + $this->addValue('SysSelfURI',array($this,'SysSelfURI')); + } + + public function getData($________) + { + # --BEHAVIOR-- tplBeforeData + if ($this->core->hasBehavior('tplBeforeData')) + { + self::$_r = $this->core->callBehavior('tplBeforeData',$this->core); + if (self::$_r) { + return self::$_r; + } + } + + parent::getData($________); + + # --BEHAVIOR-- tplAfterData + if ($this->core->hasBehavior('tplAfterData')) { + $this->core->callBehavior('tplAfterData',$this->core,self::$_r); + } + + return self::$_r; + } + + protected function compileFile($file) + { + $fc = file_get_contents($file); + + $this->compile_stack[] = $file; + + # Remove every PHP tags + if ($this->remove_php) + { + $fc = preg_replace('/<\?(?=php|=|\s).*?\?>/ms','',$fc); + } + + # Transform what could be considered as PHP short tags + $fc = preg_replace('/(<\?(?!php|=|\s))(.*?)(\?>)/ms', + '$2',$fc); + + # Remove template comments + $fc = preg_replace('/(^\s*)?/ms','',$fc); + + # Lexer part : split file into small pieces + # each array entry will be either a tag or plain text + $blocks = preg_split( + '#(]*>)|()|({{tpl:\w+[^}]*}})#msu',$fc,-1, + PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY); + + # Next : build semantic tree from tokens. + $rootNode = new tplNode(); + $node = $rootNode; + $errors = array(); + foreach ($blocks as $id => $block) { + $isblock = preg_match('#|>)||{{tpl:(\w+)(\s(.*?))?}}#ms',$block,$match); + if ($isblock == 1) { + if (substr($match[0],1,1) == '/') { + // Closing tag, check if it matches current opened node + $tag = $match[3]; + if (($node instanceof tplNodeBlock) && $node->getTag() == $tag) { + $node->setClosing(); + $node = $node->getParent(); + } else { + // Closing tag does not match opening tag + // Search if it closes a parent tag + $search = $node; + while($search->getTag() != 'ROOT' && $search->getTag() != $tag) { + $search = $search->getParent(); + } + if ($search->getTag() == $tag) { + $errors[] = sprintf( + __('Did not find closing tag for block . Content has been ignored.'), + html::escapeHTML($node->getTag())); + $search->setClosing(); + $node = $search->getParent(); + } else { + $errors[]=sprintf( + __('Unexpected closing tag found.'), + $tag);; + } + } + } elseif (substr($match[0],0,1) == '{') { + // Value tag + $tag = $match[4]; + $str_attr = ''; + $attr = array(); + if (isset($match[6])) { + $str_attr = $match[6]; + $attr = $this->getAttrs($match[6]); + } + $node->addChild(new tplNodeValue($tag,$attr,$str_attr)); + } else { + // Opening tag, create new node and dive into it + $tag = $match[1]; + $newnode = new tplNodeBlock($tag,isset($match[2])?$this->getAttrs($match[2]):array()); + $node->addChild($newnode); + $node = $newnode; + } + } else { + // Simple text + $node->addChild(new tplNodeText($block)); + } + } + + if (($node instanceof tplNodeBlock) && !$node->isClosed()) { + $errors[] = sprintf( + __('Did not find closing tag for block . Content has been ignored.'), + html::escapeHTML($node->getTag())); + } + + $err = ""; + if (count($errors) > 0) { + $err = "\n\n\n"; + } + + return $rootNode->compile($this).$err; + } + + public function compileBlockNode($tag,$attr,$content) + { + $this->current_tag = $tag; + $attr = new ArrayObject($attr); + # --BEHAVIOR-- templateBeforeBlock + $res = $this->core->callBehavior('templateBeforeBlock',$this->core,$this->current_tag,$attr); + + # --BEHAVIOR-- templateInsideBlock + $this->core->callBehavior('templateInsideBlock',$this->core,$this->current_tag,$attr,array(&$content)); + + if (isset($this->blocks[$this->current_tag])) { + $res .= call_user_func($this->blocks[$this->current_tag],$attr,$content); + } elseif ($this->unknown_block_handler != null) { + $res .= call_user_func($this->unknown_block_handler,$this->current_tag,$attr,$content); + } + + # --BEHAVIOR-- templateAfterBlock + $res .= $this->core->callBehavior('templateAfterBlock',$this->core,$this->current_tag,$attr); + + return $res; + } + + public function compileValueNode($tag,$attr,$str_attr) + { + $this->current_tag = $tag; + + $attr = new ArrayObject($attr); + # --BEHAVIOR-- templateBeforeValue + $res = $this->core->callBehavior('templateBeforeValue',$this->core,$this->current_tag,$attr); + + if (isset($this->values[$this->current_tag])) { + $res .= call_user_func($this->values[$this->current_tag],$attr,ltrim($str_attr)); + } elseif ($this->unknown_value_handler != null) { + $res .= call_user_func($this->unknown_value_handler,$this->current_tag,$attr,$str_attr); + } + + # --BEHAVIOR-- templateAfterValue + $res .= $this->core->callBehavior('templateAfterValue',$this->core,$this->current_tag,$attr); + + return $res; + } + + public function setUnknownValueHandler($callback) + { + if (is_callable($callback)) { + $this->unknown_value_handler = $callback; + } + } + + public function setUnknownBlockHandler($callback) + { + if (is_callable($callback)) { + $this->unknown_block_handler = $callback; + } + } + + public function getFilters($attr) + { + $p[0] = '0'; # encode_xml + $p[1] = '0'; # remove_html + $p[2] = '0'; # cut_string + $p[3] = '0'; # lower_case + $p[4] = '0'; # upper_case + + $p[0] = (integer) (!empty($attr['encode_xml']) || !empty($attr['encode_html'])); + $p[1] = (integer) !empty($attr['remove_html']); + + if (!empty($attr['cut_string']) && (integer) $attr['cut_string'] > 0) { + $p[2] = (integer) $attr['cut_string']; + } + + $p[3] = (integer) !empty($attr['lower_case']); + $p[4] = (integer) !empty($attr['upper_case']); + + return "context::global_filter(%s,".implode(",",$p).",'".addslashes($this->current_tag)."')"; + } + + public static function getOperator($op) + { + switch (strtolower($op)) + { + case 'or': + case '||': + return '||'; + case 'and': + case '&&': + default: + return '&&'; + } + } + + public function getSortByStr($attr,$table = null) + { + $res = array(); + + $default_order = 'desc'; + + $default_alias = array( + 'post' => array( + 'title' => 'post_title', + 'selected' => 'post_selected', + 'author' => 'user_id', + 'date' => 'post_dt', + 'id' => 'post_id', + 'comment' => 'nb_comment', + 'trackback' => 'nb_trackback' + ), + 'comment' => array( + 'author' => 'comment_author', + 'date' => 'comment_dt', + 'id' => 'comment_id' + ) + ); + + $alias = new ArrayObject(); + + # --BEHAVIOR-- templateCustomSortByAlias + $this->core->callBehavior('templateCustomSortByAlias',$alias); + + $alias = $alias->getArrayCopy(); + + if (is_array($alias)) { + foreach ($alias as $k => $v) { + if (!is_array($v)) { + $alias[$k] = array(); + } + if (!is_array($v)) { + $default_alias[$k] = array(); + } + $default_alias[$k] = array_merge($default_alias[$k],$alias[$k]); + } + } + + if (!array_key_exists($table,$default_alias)) { + return implode(', ',$res); + } + + if (isset($attr['order']) && preg_match('/^(desc|asc)$/i',$attr['order'])) { + $default_order = $attr['order']; + } + if (isset($attr['sortby'])) { + $sorts = explode(',',$attr['sortby']); + foreach ($sorts as $k => $sort) { + $order = $default_order; + if (preg_match('/([a-z]*)\s*\?(desc|asc)$/i',$sort,$matches)) { + $sort = $matches[1]; + $order = $matches[2]; + } + if (array_key_exists($sort,$default_alias[$table])) { + array_push($res,$default_alias[$table][$sort].' '.$order); + } + } + } + + if (count($res) === 0) { + array_push($res,$default_alias[$table]['date'].' '.$default_order); + } + + return implode(', ',$res); + } + + public function getAge($attr) + { + if (isset($attr['age']) && preg_match('/^(\-[0-9]+|last).*$/i',$attr['age'])) { + if (($ts = strtotime($attr['age'])) !== false) { + return dt::str('%Y-%m-%d %H:%m:%S',$ts); + } + } + return ''; + } + + /* TEMPLATE FUNCTIONS + ------------------------------------------------------- */ + + public function l10n($attr,$str_attr) + { + # Normalize content + $str_attr = preg_replace('/\s+/x',' ',$str_attr); + + return ""; + } + + public function LoopPosition($attr,$content) + { + $start = isset($attr['start']) ? (integer) $attr['start'] : '0'; + $length = isset($attr['length']) ? (integer) $attr['length'] : 'null'; + $even = isset($attr['even']) ? (integer) (boolean) $attr['even'] : 'null'; + + if ($start > 0) { + $start--; + } + + return + 'loopPosition('.$start.','.$length.','.$even.')) : ?>'. + $content. + ""; + } + + + /* Archives ------------------------------------------- */ + /*dtd + + + */ + public function Archives($attr,$content) + { + $p = "if (!isset(\$params)) \$params = array();\n"; + $p .= "\$params['type'] = 'month';\n"; + if (isset($attr['type'])) { + $p .= "\$params['type'] = '".addslashes($attr['type'])."';\n"; + } + + if (isset($attr['category'])) { + $p .= "\$params['cat_url'] = '".addslashes($attr['category'])."';\n"; + } + + if (isset($attr['post_type'])) { + $p .= "\$params['post_type'] = '".addslashes($attr['post_type'])."';\n"; + } + + if (isset($attr['post_lang'])) { + $p .= "\$params['post_lang'] = '".addslashes($attr['post_lang'])."';\n"; + } + + if (empty($attr['no_context']) && !isset($attr['category'])) + { + $p .= + 'if ($_ctx->exists("categories")) { '. + "\$params['cat_id'] = \$_ctx->categories->cat_id; ". + "}\n"; + } + + $order = 'desc'; + if (isset($attr['order']) && preg_match('/^(desc|asc)$/i',$attr['order'])) { + $p .= "\$params['order'] = '".$attr['order']."';\n "; + } + + $res = "core->callBehavior("templatePrepareParams", + array("tag" => "Archives","method" => "blog::getDates"), + $attr,$content); + $res .= '$_ctx->archives = $core->blog->getDates($params); unset($params);'."\n"; + $res .= "?>\n"; + + $res .= + 'archives->fetch()) : ?>'.$content.'archives = null; ?>'; + + return $res; + } + + /*dtd + + */ + public function ArchivesHeader($attr,$content) + { + return + "archives->isStart()) : ?>". + $content. + ""; + } + + /*dtd + + */ + public function ArchivesFooter($attr,$content) + { + return + "archives->isEnd()) : ?>". + $content. + ""; + } + + /*dtd + + */ + public function ArchivesYearHeader($attr,$content) + { + return + "archives->yearHeader()) : ?>". + $content. + ""; + } + + /*dtd + + */ + public function ArchivesYearFooter($attr,$content) + { + return + "archives->yearFooter()) : ?>". + $content. + ""; + } + + /*dtd + + + */ + public function ArchiveDate($attr) + { + $format = '%B %Y'; + if (!empty($attr['format'])) { + $format = addslashes($attr['format']); + } + + $f = $this->getFilters($attr); + return 'archives->dt)").'; ?>'; + } + + /*dtd + + */ + public function ArchiveEntriesCount($attr) + { + $f = $this->getFilters($attr); + return 'archives->nb_post').'; ?>'; + } + + /*dtd + + + */ + public function ArchiveNext($attr,$content) + { + $p = "if (!isset(\$params)) \$params = array();\n"; + $p .= "\$params['type'] = 'month';\n"; + if (isset($attr['type'])) { + $p .= "\$params['type'] = '".addslashes($attr['type'])."';\n"; + } + + if (isset($attr['post_type'])) { + $p .= "\$params['post_type'] = '".addslashes($attr['post_type'])."';\n"; + } + + if (isset($attr['post_lang'])) { + $p .= "\$params['post_lang'] = '".addslashes($attr['post_lang'])."';\n"; + } + + $p .= "\$params['next'] = \$_ctx->archives->dt;"; + + $res = "core->callBehavior("templatePrepareParams", + array("tag" => "ArchiveNext","method" => "blog::getDates"), + $attr, $content); + $res .= '$_ctx->archives = $core->blog->getDates($params); unset($params);'."\n"; + $res .= "?>\n"; + + $res .= + 'archives->fetch()) : ?>'.$content.'archives = null; ?>'; + + return $res; + } + + /*dtd + + + */ + public function ArchivePrevious($attr,$content) + { + $p = 'if (!isset($params)) $params = array();'; + $p .= "\$params['type'] = 'month';\n"; + if (isset($attr['type'])) { + $p .= "\$params['type'] = '".addslashes($attr['type'])."';\n"; + } + + if (isset($attr['post_type'])) { + $p .= "\$params['post_type'] = '".addslashes($attr['post_type'])."';\n"; + } + + if (isset($attr['post_lang'])) { + $p .= "\$params['post_lang'] = '".addslashes($attr['post_lang'])."';\n"; + } + + $p .= "\$params['previous'] = \$_ctx->archives->dt;"; + + $res = "core->callBehavior("templatePrepareParams", + array("tag" => "ArchivePrevious","method" => "blog::getDates"), + $attr, $content); + $res .= $p; + $res .= '$_ctx->archives = $core->blog->getDates($params); unset($params);'."\n"; + $res .= "?>\n"; + + $res .= + 'archives->fetch()) : ?>'.$content.'archives = null; ?>'; + + return $res; + } + + /*dtd + + */ + public function ArchiveURL($attr) + { + $f = $this->getFilters($attr); + return 'archives->url($core)').'; ?>'; + } + + + /* Blog ----------------------------------------------- */ + /*dtd + + */ + public function BlogArchiveURL($attr) + { + $f = $this->getFilters($attr); + return 'blog->url.$core->url->getURLFor("archive")').'; ?>'; + } + + /*dtd + + */ + public function BlogCopyrightNotice($attr) + { + $f = $this->getFilters($attr); + return 'blog->settings->system->copyright_notice').'; ?>'; + } + + /*dtd + + */ + public function BlogDescription($attr) + { + $f = $this->getFilters($attr); + return 'blog->desc').'; ?>'; + } + + /*dtd + + */ + public function BlogEditor($attr) + { + $f = $this->getFilters($attr); + return 'blog->settings->system->editor').'; ?>'; + } + + /*dtd + + */ + public function BlogFeedID($attr) + { + $f = $this->getFilters($attr); + return 'blog->uid').'; ?>'; + } + + /*dtd + + + */ + public function BlogFeedURL($attr) + { + $type = !empty($attr['type']) ? $attr['type'] : 'atom'; + + if (!preg_match('#^(rss2|atom)$#',$type)) { + $type = 'atom'; + } + + $f = $this->getFilters($attr); + return 'blog->url.$core->url->getURLFor("feed","'.$type.'")').'; ?>'; + } + + /*dtd + + */ + public function BlogName($attr) + { + $f = $this->getFilters($attr); + return 'blog->name').'; ?>'; + } + + /*dtd + + */ + public function BlogLanguage($attr) + { + $f = $this->getFilters($attr); + return 'blog->settings->system->lang').'; ?>'; + } + + /*dtd + + */ + public function BlogThemeURL($attr) + { + $f = $this->getFilters($attr); + return 'blog->settings->system->themes_url."/".$core->blog->settings->system->theme').'; ?>'; + } + + /*dtd + + */ + public function BlogPublicURL($attr) + { + $f = $this->getFilters($attr); + return 'blog->settings->system->public_url').'; ?>'; + } + + /*dtd + + + */ + public function BlogUpdateDate($attr) + { + $format = ''; + if (!empty($attr['format'])) { + $format = addslashes($attr['format']); + } else { + $format = '%Y-%m-%d %H:%M:%S'; + } + + $iso8601 = !empty($attr['iso8601']); + $rfc822 = !empty($attr['rfc822']); + + $f = $this->getFilters($attr); + + if ($rfc822) { + return 'blog->upddt,\$core->blog->settings->system->blog_timezone)").'; ?>'; + } elseif ($iso8601) { + return 'blog->upddt,\$core->blog->settings->system->blog_timezone)").'; ?>'; + } else { + return 'blog->upddt)").'; ?>'; + } + } + + /*dtd + + */ + public function BlogID($attr) + { + $f = $this->getFilters($attr); + return 'blog->id').'; ?>'; + } + + /*dtd + + */ + public function BlogRSDURL($attr) + { + $f = $this->getFilters($attr); + return 'blog->url.$core->url->getURLFor(\'rsd\')').'; ?>'; + } + + /*dtd + + */ + public function BlogURL($attr) + { + $f = $this->getFilters($attr); + return 'blog->url').'; ?>'; + } + + /*dtd + + */ + public function BlogQmarkURL($attr) + { + $f = $this->getFilters($attr); + return 'blog->getQmarkURL()').'; ?>'; + } + + /*dtd + + + */ + public function BlogMetaRobots($attr) + { + $robots = isset($attr['robots']) ? addslashes($attr['robots']) : ''; + return "blog->settings->system->robots_policy,'".$robots."'); ?>"; + } + + /* Categories ----------------------------------------- */ + + /*dtd + + */ + public function Categories($attr,$content) + { + $p = "if (!isset(\$params)) \$params = array();\n"; + + if (isset($attr['url'])) { + $p .= "\$params['cat_url'] = '".addslashes($attr['url'])."';\n"; + } + + if (!empty($attr['post_type'])) { + $p .= "\$params['post_type'] = '".addslashes($attr['post_type'])."';\n"; + } + + if (!empty($attr['level'])) { + $p .= "\$params['level'] = ".(integer) $attr['level'].";\n"; + } + + $res = "core->callBehavior("templatePrepareParams", + array("tag" => "Categories","method" => "blog::getCategories"), + $attr,$content); + $res .= '$_ctx->categories = $core->blog->getCategories($params);'."\n"; + $res .= "?>\n"; + $res .= 'categories->fetch()) : ?>'.$content.'categories = null; unset($params); ?>'; + + return $res; + } + + /*dtd + + */ + public function CategoriesHeader($attr,$content) + { + return + "categories->isStart()) : ?>". + $content. + ""; + } + + /*dtd + + */ + public function CategoriesFooter($attr,$content) + { + return + "categories->isEnd()) : ?>". + $content. + ""; + } + + /*dtd + + + */ + public function CategoryIf($attr,$content) + { + $if = new ArrayObject(); + $operator = isset($attr['operator']) ? $this->getOperator($attr['operator']) : '&&'; + + if (isset($attr['url'])) { + $url = addslashes(trim($attr['url'])); + if (substr($url,0,1) == '!') { + $url = substr($url,1); + $if[] = '($_ctx->categories->cat_url != "'.$url.'")'; + } else { + $if[] = '($_ctx->categories->cat_url == "'.$url.'")'; + } + } + + if (isset($attr['has_entries'])) { + $sign = (boolean) $attr['has_entries'] ? '>' : '=='; + $if[] = '$_ctx->categories->nb_post '.$sign.' 0'; + } + + if (isset($attr['has_description'])) { + $sign = (boolean) $attr['has_description'] ? '!=' : '=='; + $if[] = '$_ctx->categories->cat_desc '.$sign.' ""'; + } + + $this->core->callBehavior('tplIfConditions','CategoryIf',$attr,$content,$if); + + if (count($if) != 0) { + return ''.$content.''; + } else { + return $content; + } + } + + /*dtd + + */ + public function CategoryFirstChildren($attr,$content) + { + return + "categories = $core->blog->getCategoryFirstChildren($_ctx->categories->cat_id);'."\n". + 'while ($_ctx->categories->fetch()) : ?>'.$content.'categories = null; ?>'; + } + + /*dtd + + */ + public function CategoryParents($attr,$content) + { + return + "categories = $core->blog->getCategoryParents($_ctx->categories->cat_id);'."\n". + 'while ($_ctx->categories->fetch()) : ?>'.$content.'categories = null; ?>'; + } + + /*dtd + + + */ + public function CategoryFeedURL($attr) + { + $type = !empty($attr['type']) ? $attr['type'] : 'atom'; + + if (!preg_match('#^(rss2|atom)$#',$type)) { + $type = 'atom'; + } + + $f = $this->getFilters($attr); + return 'blog->url.$core->url->getURLFor("feed","category/".'. + '$_ctx->categories->cat_url."/'.$type.'")').'; ?>'; + } + + /*dtd + + */ + public function CategoryURL($attr) + { + $f = $this->getFilters($attr); + return 'blog->url.$core->url->getURLFor("category",'. + '$_ctx->categories->cat_url)').'; ?>'; + } + + /*dtd + + */ + public function CategoryShortURL($attr) + { + $f = $this->getFilters($attr); + return 'categories->cat_url').'; ?>'; + } + + /*dtd + + */ + public function CategoryDescription($attr) + { + $f = $this->getFilters($attr); + return 'categories->cat_desc').'; ?>'; + } + + /*dtd + + */ + public function CategoryTitle($attr) + { + $f = $this->getFilters($attr); + return 'categories->cat_title').'; ?>'; + } + + /* Entries -------------------------------------------- */ + /*dtd + + + */ + public function Entries($attr,$content) + { + $lastn = -1; + if (isset($attr['lastn'])) { + $lastn = abs((integer) $attr['lastn'])+0; + } + + $p = 'if (!isset($_page_number)) { $_page_number = 1; }'."\n"; + + if ($lastn != 0) { + if ($lastn > 0) { + $p .= "\$params['limit'] = ".$lastn.";\n"; + } else { + $p .= "\$params['limit'] = \$_ctx->nb_entry_per_page;\n"; + } + + if (!isset($attr['ignore_pagination']) || $attr['ignore_pagination'] == "0") { + $p .= "\$params['limit'] = array(((\$_page_number-1)*\$params['limit']),\$params['limit']);\n"; + } else { + $p .= "\$params['limit'] = array(0, \$params['limit']);\n"; + } + } + + if (isset($attr['author'])) { + $p .= "\$params['user_id'] = '".addslashes($attr['author'])."';\n"; + } + + if (isset($attr['category'])) { + $p .= "\$params['cat_url'] = '".addslashes($attr['category'])."';\n"; + $p .= "context::categoryPostParam(\$params);\n"; + } + + if (isset($attr['no_category']) && $attr['no_category']) { + $p .= "@\$params['sql'] .= ' AND P.cat_id IS NULL ';\n"; + $p .= "unset(\$params['cat_url']);\n"; + } + + if (!empty($attr['type'])) { + $p .= "\$params['post_type'] = preg_split('/\s*,\s*/','".addslashes($attr['type'])."',-1,PREG_SPLIT_NO_EMPTY);\n"; + } + + if (!empty($attr['url'])) { + $p .= "\$params['post_url'] = '".addslashes($attr['url'])."';\n"; + } + + if (empty($attr['no_context'])) + { + if (!isset($attr['author'])) + { + $p .= + 'if ($_ctx->exists("users")) { '. + "\$params['user_id'] = \$_ctx->users->user_id; ". + "}\n"; + } + + if (!isset($attr['category']) && (!isset($attr['no_category']) || !$attr['no_category'])) + { + $p .= + 'if ($_ctx->exists("categories")) { '. + "\$params['cat_id'] = \$_ctx->categories->cat_id; ". + "}\n"; + } + + $p .= + 'if ($_ctx->exists("archives")) { '. + "\$params['post_year'] = \$_ctx->archives->year(); ". + "\$params['post_month'] = \$_ctx->archives->month(); "; + if (!isset($attr['lastn'])) { + $p .= "unset(\$params['limit']); "; + } + $p .= + "}\n"; + + $p .= + 'if ($_ctx->exists("langs")) { '. + "\$params['post_lang'] = \$_ctx->langs->post_lang; ". + "}\n"; + + $p .= + 'if (isset($_search)) { '. + "\$params['search'] = \$_search; ". + "}\n"; + } + + $p .= "\$params['order'] = '".$this->getSortByStr($attr,'post')."';\n"; + + if (isset($attr['no_content']) && $attr['no_content']) { + $p .= "\$params['no_content'] = true;\n"; + } + + if (isset($attr['selected'])) { + $p .= "\$params['post_selected'] = ".(integer) (boolean) $attr['selected'].";"; + } + + if (isset($attr['age'])) { + $age = $this->getAge($attr); + $p .= !empty($age) ? "@\$params['sql'] .= ' AND P.post_dt > \'".$age."\'';\n" : ''; + } + + $res = "core->callBehavior("templatePrepareParams", + array("tag" => "Entries","method" => "blog::getPosts"), + $attr,$content); + $res .= '$_ctx->post_params = $params;'."\n"; + $res .= '$_ctx->posts = $core->blog->getPosts($params); unset($params);'."\n"; + $res .= "?>\n"; + $res .= + 'posts->fetch()) : ?>'.$content.'posts = null; $_ctx->post_params = null; ?>'; + + return $res; + } + + /*dtd + + */ + public function DateHeader($attr,$content) + { + return + "posts->firstPostOfDay()) : ?>". + $content. + ""; + } + + /*dtd + + */ + public function DateFooter($attr,$content) + { + return + "posts->lastPostOfDay()) : ?>". + $content. + ""; + } + + /*dtd + + + */ + public function EntryIf($attr,$content) + { + $if = new ArrayObject(); + $extended = null; + $hascategory = null; + + $operator = isset($attr['operator']) ? $this->getOperator($attr['operator']) : '&&'; + + if (isset($attr['type'])) { + $type = trim($attr['type']); + $type = !empty($type)?$type:'post'; + $if[] = '$_ctx->posts->post_type == "'.addslashes($type).'"'; + } + + if (isset($attr['url'])) { + $url = trim($attr['url']); + if (substr($url,0,1) == '!') { + $url = substr($url,1); + $if[] = '$_ctx->posts->post_url != "'.addslashes($url).'"'; + } else { + $if[] = '$_ctx->posts->post_url == "'.addslashes($url).'"'; + } + } + + if (isset($attr['category'])) { + $category = addslashes(trim($attr['category'])); + if (substr($category,0,1) == '!') { + $category = substr($category,1); + $if[] = '($_ctx->posts->cat_url != "'.$category.'")'; + } else { + $if[] = '($_ctx->posts->cat_url == "'.$category.'")'; + } + } + + if (isset($attr['first'])) { + $sign = (boolean) $attr['first'] ? '=' : '!'; + $if[] = '$_ctx->posts->index() '.$sign.'= 0'; + } + + if (isset($attr['odd'])) { + $sign = (boolean) $attr['odd'] ? '=' : '!'; + $if[] = '($_ctx->posts->index()+1)%2 '.$sign.'= 1'; + } + + if (isset($attr['extended'])) { + $sign = (boolean) $attr['extended'] ? '' : '!'; + $if[] = $sign.'$_ctx->posts->isExtended()'; + } + + if (isset($attr['selected'])) { + $sign = (boolean) $attr['selected'] ? '' : '!'; + $if[] = $sign.'(boolean)$_ctx->posts->post_selected'; + } + + if (isset($attr['has_category'])) { + $sign = (boolean) $attr['has_category'] ? '' : '!'; + $if[] = $sign.'$_ctx->posts->cat_id'; + } + + if (isset($attr['comments_active'])) { + $sign = (boolean) $attr['comments_active'] ? '' : '!'; + $if[] = $sign.'$_ctx->posts->commentsActive()'; + } + + if (isset($attr['pings_active'])) { + $sign = (boolean) $attr['pings_active'] ? '' : '!'; + $if[] = $sign.'$_ctx->posts->trackbacksActive()'; + } + + if (isset($attr['has_comment'])) { + $sign = (boolean) $attr['has_comment'] ? '' : '!'; + $if[] = $sign.'$_ctx->posts->hasComments()'; + } + + if (isset($attr['has_ping'])) { + $sign = (boolean) $attr['has_ping'] ? '' : '!'; + $if[] = $sign.'$_ctx->posts->hasTrackbacks()'; + } + + if (isset($attr['show_comments'])) { + if ((boolean) $attr['show_comments']) { + $if[] = '($_ctx->posts->hasComments() || $_ctx->posts->commentsActive())'; + } else { + $if[] = '(!$_ctx->posts->hasComments() && !$_ctx->posts->commentsActive())'; + } + } + + if (isset($attr['show_pings'])) { + if ((boolean) $attr['show_pings']) { + $if[] = '($_ctx->posts->hasTrackbacks() || $_ctx->posts->trackbacksActive())'; + } else { + $if[] = '(!$_ctx->posts->hasTrackbacks() && !$_ctx->posts->trackbacksActive())'; + } + } + + $this->core->callBehavior('tplIfConditions','EntryIf',$attr,$content,$if); + + if (count($if) != 0) { + return ''.$content.''; + } else { + return $content; + } + } + + /*dtd + + + */ + public function EntryIfFirst($attr) + { + $ret = isset($attr['return']) ? $attr['return'] : 'first'; + $ret = html::escapeHTML($ret); + + return + 'posts->index() == 0) { '. + "echo '".addslashes($ret)."'; } ?>"; + } + + /*dtd + + + */ + public function EntryIfOdd($attr) + { + $ret = isset($attr['return']) ? $attr['return'] : 'odd'; + $ret = html::escapeHTML($ret); + + return + 'posts->index()+1)%2 == 1) { '. + "echo '".addslashes($ret)."'; } ?>"; + } + + /*dtd + + + */ + public function EntryIfSelected($attr) + { + $ret = isset($attr['return']) ? $attr['return'] : 'selected'; + $ret = html::escapeHTML($ret); + + return + 'posts->post_selected) { '. + "echo '".addslashes($ret)."'; } ?>"; + } + + /*dtd + + + */ + public function EntryContent($attr) + { + $urls = '0'; + if (!empty($attr['absolute_urls'])) { + $urls = '1'; + } + + $f = $this->getFilters($attr); + + if (!empty($attr['full'])) { + return 'posts->getExcerpt('.$urls.')." ".$_ctx->posts->getContent('.$urls.')').'; ?>'; + } else { + return 'posts->getContent('.$urls.')').'; ?>'; + } + } + + /*dtd + + + */ + public function EntryExcerpt($attr) + { + $urls = '0'; + if (!empty($attr['absolute_urls'])) { + $urls = '1'; + } + + $f = $this->getFilters($attr); + return 'posts->getExcerpt('.$urls.')').'; ?>'; + } + + + /*dtd + + */ + public function EntryAuthorCommonName($attr) + { + $f = $this->getFilters($attr); + return 'posts->getAuthorCN()').'; ?>'; + } + + /*dtd + + */ + public function EntryAuthorDisplayName($attr) + { + $f = $this->getFilters($attr); + return 'posts->user_displayname').'; ?>'; + } + + /*dtd + + */ + public function EntryAuthorID($attr) + { + $f = $this->getFilters($attr); + return 'posts->user_id').'; ?>'; + } + + /*dtd + + + */ + public function EntryAuthorEmail($attr) + { + $p = 'true'; + if (isset($attr['spam_protected']) && !$attr['spam_protected']) { + $p = 'false'; + } + + $f = $this->getFilters($attr); + return 'posts->getAuthorEmail(".$p.")").'; ?>'; + } + + /*dtd + + */ + public function EntryAuthorLink($attr) + { + $f = $this->getFilters($attr); + return 'posts->getAuthorLink()').'; ?>'; + } + + /*dtd + + */ + public function EntryAuthorURL($attr) + { + $f = $this->getFilters($attr); + return 'posts->user_url').'; ?>'; + } + + /*dtd + + */ + public function EntryBasename($attr) + { + $f = $this->getFilters($attr); + return 'posts->post_url').'; ?>'; + } + + /*dtd + + */ + public function EntryCategory($attr) + { + $f = $this->getFilters($attr); + return 'posts->cat_title').'; ?>'; + } + + /*dtd + + */ + public function EntryCategoriesBreadcrumb($attr,$content) + { + return + "categories = $core->blog->getCategoryParents($_ctx->posts->cat_id);'."\n". + 'while ($_ctx->categories->fetch()) : ?>'.$content.'categories = null; ?>'; + } + + /*dtd + + */ + public function EntryCategoryID($attr) + { + $f = $this->getFilters($attr); + return 'posts->cat_id').'; ?>'; + } + + /*dtd + + */ + public function EntryCategoryURL($attr) + { + $f = $this->getFilters($attr); + return 'posts->getCategoryURL()').'; ?>'; + } + + /*dtd + + */ + public function EntryCategoryShortURL($attr) + { + $f = $this->getFilters($attr); + return 'posts->cat_url').'; ?>'; + } + + + /*dtd + + */ + public function EntryFeedID($attr) + { + $f = $this->getFilters($attr); + return 'posts->getFeedID()').'; ?>'; + } + + /*dtd + + + */ + public function EntryFirstImage($attr) + { + $size = !empty($attr['size']) ? $attr['size'] : ''; + $class = !empty($attr['class']) ? $attr['class'] : ''; + $with_category = !empty($attr['with_category']) ? 'true' : 'false'; + + return ""; + } + + /*dtd + + */ + public function EntryID($attr) + { + $f = $this->getFilters($attr); + return 'posts->post_id').'; ?>'; + } + + /*dtd + + */ + public function EntryLang($attr) + { + $f = $this->getFilters($attr); + return + 'posts->post_lang) { '. + 'echo '.sprintf($f,'$_ctx->posts->post_lang').'; '. + '} else {'. + 'echo '.sprintf($f,'$core->blog->settings->system->lang').'; '. + '} ?>'; + } + + /*dtd + + + */ + public function EntryNext($attr,$content) + { + $restrict_to_category = !empty($attr['restrict_to_category']) ? '1' : '0'; + $restrict_to_lang = !empty($attr['restrict_to_lang']) ? '1' : '0'; + + return + 'blog->getNextPost($_ctx->posts,1,'.$restrict_to_category.','.$restrict_to_lang.'); ?>'."\n". + ''. + + 'posts = $next_post; unset($next_post);'."\n". + 'while ($_ctx->posts->fetch()) : ?>'. + $content. + 'posts = null; ?>'. + "\n"; + } + + /*dtd + + + */ + public function EntryPrevious($attr,$content) + { + $restrict_to_category = !empty($attr['restrict_to_category']) ? '1' : '0'; + $restrict_to_lang = !empty($attr['restrict_to_lang']) ? '1' : '0'; + + return + 'blog->getNextPost($_ctx->posts,-1,'.$restrict_to_category.','.$restrict_to_lang.'); ?>'."\n". + ''. + + 'posts = $prev_post; unset($prev_post);'."\n". + 'while ($_ctx->posts->fetch()) : ?>'. + $content. + 'posts = null; ?>'. + "\n"; + } + + /*dtd + + */ + public function EntryTitle($attr) + { + $f = $this->getFilters($attr); + return 'posts->post_title').'; ?>'; + } + + /*dtd + + */ + public function EntryURL($attr) + { + $f = $this->getFilters($attr); + return 'posts->getURL()').'; ?>'; + } + + /*dtd + + + */ + public function EntryDate($attr) + { + $format = ''; + if (!empty($attr['format'])) { + $format = addslashes($attr['format']); + } + + $iso8601 = !empty($attr['iso8601']); + $rfc822 = !empty($attr['rfc822']); + $type = (!empty($attr['creadt']) ? 'creadt' : ''); + $type = (!empty($attr['upddt']) ? 'upddt' : $type); + + $f = $this->getFilters($attr); + + if ($rfc822) { + return 'posts->getRFC822Date('".$type."')").'; ?>'; + } elseif ($iso8601) { + return 'posts->getISO8601Date('".$type."')").'; ?>'; + } else { + return 'posts->getDate('".$format."','".$type."')").'; ?>'; + } + } + + /*dtd + + + */ + public function EntryTime($attr) + { + $format = ''; + if (!empty($attr['format'])) { + $format = addslashes($attr['format']); + } + + $type = (!empty($attr['creadt']) ? 'creadt' : ''); + $type = (!empty($attr['upddt']) ? 'upddt' : $type); + + $f = $this->getFilters($attr); + return 'posts->getTime('".$format."','".$type."')").'; ?>'; + } + + /*dtd + + */ + public function EntriesHeader($attr,$content) + { + return + "posts->isStart()) : ?>". + $content. + ""; + } + + /*dtd + + */ + public function EntriesFooter($attr,$content) + { + return + "posts->isEnd()) : ?>". + $content. + ""; + } + + /*dtd + + + */ + public function EntryCommentCount($attr) + { + $none = 'no comment'; + $one = 'one comment'; + $more = '%d comments'; + + if (isset($attr['none'])) { + $none = addslashes($attr['none']); + } + if (isset($attr['one'])) { + $one = addslashes($attr['one']); + } + if (isset($attr['more'])) { + $more = addslashes($attr['more']); + } + + if (empty($attr['count_all'])) { + $operation = '$_ctx->posts->nb_comment'; + } else { + $operation = '($_ctx->posts->nb_comment + $_ctx->posts->nb_trackback)'; + } + + return + ""; + } + + /*dtd + + + */ + public function EntryPingCount($attr) + { + $none = 'no trackback'; + $one = 'one trackback'; + $more = '%d trackbacks'; + + if (isset($attr['none'])) { + $none = addslashes($attr['none']); + } + if (isset($attr['one'])) { + $one = addslashes($attr['one']); + } + if (isset($attr['more'])) { + $more = addslashes($attr['more']); + } + + return + "posts->nb_trackback == 0) {\n". + " printf(__('".$none."'),(integer) \$_ctx->posts->nb_trackback);\n". + "} elseif (\$_ctx->posts->nb_trackback == 1) {\n". + " printf(__('".$one."'),(integer) \$_ctx->posts->nb_trackback);\n". + "} else {\n". + " printf(__('".$more."'),(integer) \$_ctx->posts->nb_trackback);\n". + "} ?>"; + } + + /*dtd + + */ + public function EntryPingData($attr) + { + return "posts->trackbacksActive()) { echo \$_ctx->posts->getTrackbackData(); } ?>\n"; + } + + /*dtd + + */ + public function EntryPingLink($attr) + { + return "posts->trackbacksActive()) { echo \$_ctx->posts->getTrackbackLink(); } ?>\n"; + } + + /* Languages -------------------------------------- */ + /*dtd + + + */ + public function Languages($attr,$content) + { + $p = "if (!isset(\$params)) \$params = array();\n"; + + if (isset($attr['lang'])) { + $p = "\$params['lang'] = '".addslashes($attr['lang'])."';\n"; + } + + $order = 'desc'; + if (isset($attr['order']) && preg_match('/^(desc|asc)$/i',$attr['order'])) { + $p .= "\$params['order'] = '".$attr['order']."';\n "; + } + + $res = "core->callBehavior("templatePrepareParams", + array("tag" => "Languages","method" => "blog::getLangs"), + $attr,$content); + $res .= '$_ctx->langs = $core->blog->getLangs($params); unset($params);'."\n"; + $res .= "?>\n"; + + $res .= + 'langs->count() > 1) : '. + 'while ($_ctx->langs->fetch()) : ?>'.$content. + 'langs = null; endif; ?>'; + + return $res; + } + + /*dtd + + */ + public function LanguagesHeader($attr,$content) + { + return + "langs->isStart()) : ?>". + $content. + ""; + } + + /*dtd + + */ + public function LanguagesFooter($attr,$content) + { + return + "langs->isEnd()) : ?>". + $content. + ""; + } + + /*dtd + + */ + public function LanguageCode($attr) + { + $f = $this->getFilters($attr); + return 'langs->post_lang').'; ?>'; + } + + /*dtd + + */ + public function LanguageIfCurrent($attr,$content) + { + return + "cur_lang == \$_ctx->langs->post_lang) : ?>". + $content. + ""; + } + + /*dtd + + */ + public function LanguageURL($attr) + { + $f = $this->getFilters($attr); + return 'blog->url.$core->url->getURLFor("lang",'. + '$_ctx->langs->post_lang)').'; ?>'; + } + + /* Pagination ------------------------------------- */ + /*dtd + + + */ + public function Pagination($attr,$content) + { + $p = "post_params;'."\n"; + $p .= $this->core->callBehavior("templatePrepareParams", + array("tag" => "Pagination","method" => "blog::getPosts"), + $attr,$content); + $p .= '$_ctx->pagination = $core->blog->getPosts($params,true); unset($params);'."\n"; + $p .= "?>\n"; + + if (isset($attr['no_context']) && $attr['no_context']) { + return $p.$content; + } + + return + $p. + 'pagination->f(0) > $_ctx->posts->count()) : ?>'. + $content. + ''; + } + + /*dtd + + */ + public function PaginationCounter($attr) + { + $f = $this->getFilters($attr); + return ''; + } + + /*dtd + + */ + public function PaginationCurrent($attr) + { + $offset = 0; + if (isset($attr['offset'])) { + $offset = (integer) $attr['offset']; + } + + $f = $this->getFilters($attr); + return ''; + } + + /*dtd + + + */ + public function PaginationIf($attr,$content) + { + $if = array(); + + if (isset($attr['start'])) { + $sign = (boolean) $attr['start'] ? '' : '!'; + $if[] = $sign.'context::PaginationStart()'; + } + + if (isset($attr['end'])) { + $sign = (boolean) $attr['end'] ? '' : '!'; + $if[] = $sign.'context::PaginationEnd()'; + } + + $this->core->callBehavior('tplIfConditions','PaginationIf',$attr,$content,$if); + + if (count($if) != 0) { + return ''.$content.''; + } else { + return $content; + } + } + + /*dtd + + + */ + public function PaginationURL($attr) + { + $offset = 0; + if (isset($attr['offset'])) { + $offset = (integer) $attr['offset']; + } + + $f = $this->getFilters($attr); + return ''; + } + + /* Comments --------------------------------------- */ + /*dtd + + + */ + public function Comments($attr,$content) + { + $p = ""; + if (empty($attr['with_pings'])) { + $p .= "\$params['comment_trackback'] = false;\n"; + } + + $lastn = 0; + if (isset($attr['lastn'])) { + $lastn = abs((integer) $attr['lastn'])+0; + } + + if ($lastn > 0) { + $p .= "\$params['limit'] = ".$lastn.";\n"; + } else { + $p .= "if (\$_ctx->nb_comment_per_page !== null) { \$params['limit'] = \$_ctx->nb_comment_per_page; }\n"; + } + + if (empty($attr['no_context'])) + { + $p .= + "if (\$_ctx->posts !== null) { ". + "\$params['post_id'] = \$_ctx->posts->post_id; ". + "\$core->blog->withoutPassword(false);\n". + "}\n"; + $p .= + 'if ($_ctx->exists("categories")) { '. + "\$params['cat_id'] = \$_ctx->categories->cat_id; ". + "}\n"; + + $p .= + 'if ($_ctx->exists("langs")) { '. + "\$params['sql'] = \"AND P.post_lang = '\".\$core->blog->con->escape(\$_ctx->langs->post_lang).\"' \"; ". + "}\n"; + } + + if (!isset($attr['order'])) { + $attr['order'] = 'asc'; + } + + $p .= "\$params['order'] = '".$this->getSortByStr($attr,'comment')."';\n"; + + if (isset($attr['no_content']) && $attr['no_content']) { + $p .= "\$params['no_content'] = true;\n"; + } + + if (isset($attr['age'])) { + $age = $this->getAge($attr); + $p .= !empty($age) ? "@\$params['sql'] .= ' AND P.post_dt > \'".$age."\'';\n" : ''; + } + + $res = "core->callBehavior("templatePrepareParams", + array("tag" => "Comments","method" => "blog::getComments"), + $attr,$content); + $res .= $p; + $res .= '$_ctx->comments = $core->blog->getComments($params); unset($params);'."\n"; + $res .= "if (\$_ctx->posts !== null) { \$core->blog->withoutPassword(true);}\n"; + + if (!empty($attr['with_pings'])) { + $res .= '$_ctx->pings = $_ctx->comments;'."\n"; + } + + $res .= "?>\n"; + + $res .= + 'comments->fetch()) : ?>'.$content.'comments = null; ?>'; + + return $res; + } + + /*dtd + + */ + public function CommentAuthor($attr) + { + $f = $this->getFilters($attr); + return 'comments->comment_author").'; ?>'; + } + + /*dtd + + */ + public function CommentAuthorDomain($attr) + { + return 'comments->comment_site); ?>'; + } + + /*dtd + + */ + public function CommentAuthorLink($attr) + { + $f = $this->getFilters($attr); + return 'comments->getAuthorLink()').'; ?>'; + } + + /*dtd + + */ + public function CommentAuthorMailMD5($attr) + { + return 'comments->comment_email) ; ?>'; + } + + /*dtd + + */ + public function CommentAuthorURL($attr) + { + $f = $this->getFilters($attr); + return 'comments->getAuthorURL()').'; ?>'; + } + + /*dtd + + + */ + public function CommentContent($attr) + { + $urls = '0'; + if (!empty($attr['absolute_urls'])) { + $urls = '1'; + } + + $f = $this->getFilters($attr); + return 'comments->getContent('.$urls.')').'; ?>'; + } + + /*dtd + + + */ + public function CommentDate($attr) + { + $format = ''; + if (!empty($attr['format'])) { + $format = addslashes($attr['format']); + } + + $iso8601 = !empty($attr['iso8601']); + $rfc822 = !empty($attr['rfc822']); + $type = (!empty($attr['upddt']) ? 'upddt' : ''); + + $f = $this->getFilters($attr); + + if ($rfc822) { + return 'comments->getRFC822Date('".$type."')").'; ?>'; + } elseif ($iso8601) { + return 'comments->getISO8601Date('".$type."')").'; ?>'; + } else { + return 'comments->getDate('".$format."','".$type."')").'; ?>'; + } + } + + /*dtd + + + */ + public function CommentTime($attr) + { + $format = ''; + if (!empty($attr['format'])) { + $format = addslashes($attr['format']); + } + $type = (!empty($attr['upddt']) ? 'upddt' : ''); + + $f = $this->getFilters($attr); + return 'comments->getTime('".$format."','".$type."')").'; ?>'; + } + + /*dtd + + + */ + public function CommentEmail($attr) + { + $p = 'true'; + if (isset($attr['spam_protected']) && !$attr['spam_protected']) { + $p = 'false'; + } + + $f = $this->getFilters($attr); + return 'comments->getEmail(".$p.")").'; ?>'; + } + + /*dtd + + */ + public function CommentEntryTitle($attr) + { + $f = $this->getFilters($attr); + return 'comments->post_title').'; ?>'; + } + + /*dtd + + */ + public function CommentFeedID($attr) + { + $f = $this->getFilters($attr); + return 'comments->getFeedID()').'; ?>'; + } + + /*dtd + + */ + public function CommentID($attr) + { + return 'comments->comment_id; ?>'; + } + + /*dtd + + + */ + public function CommentIf($attr,$content) + { + $if = array(); + $is_ping = null; + + if (isset($attr['is_ping'])) { + $sign = (boolean) $attr['is_ping'] ? '' : '!'; + $if[] = $sign.'$_ctx->comments->comment_trackback'; + } + + $this->core->callBehavior('tplIfConditions','CommentIf',$attr,$content,$if); + + if (count($if) != 0) { + return ''.$content.''; + } else { + return $content; + } + } + + /*dtd + + + */ + public function CommentIfFirst($attr) + { + $ret = isset($attr['return']) ? $attr['return'] : 'first'; + $ret = html::escapeHTML($ret); + + return + 'comments->index() == 0) { '. + "echo '".addslashes($ret)."'; } ?>"; + } + + /*dtd + + + */ + public function CommentIfMe($attr) + { + $ret = isset($attr['return']) ? $attr['return'] : 'me'; + $ret = html::escapeHTML($ret); + + return + 'comments->isMe()) { '. + "echo '".addslashes($ret)."'; } ?>"; + } + + /*dtd + + + */ + public function CommentIfOdd($attr) + { + $ret = isset($attr['return']) ? $attr['return'] : 'odd'; + $ret = html::escapeHTML($ret); + + return + 'comments->index()+1)%2) { '. + "echo '".addslashes($ret)."'; } ?>"; + } + + /*dtd + + */ + public function CommentIP($attr) + { + return 'comments->comment_ip; ?>'; + } + + /*dtd + + */ + public function CommentOrderNumber($attr) + { + return 'comments->index()+1; ?>'; + } + + /*dtd + + */ + public function CommentsFooter($attr,$content) + { + return + "comments->isEnd()) : ?>". + $content. + ""; + } + + /*dtd + + */ + public function CommentsHeader($attr,$content) + { + return + "comments->isStart()) : ?>". + $content. + ""; + } + + /*dtd + + */ + public function CommentPostURL($attr) + { + $f = $this->getFilters($attr); + return 'comments->getPostURL()').'; ?>'; + } + + /*dtd + + */ + public function IfCommentAuthorEmail($attr,$content) + { + return + "comments->comment_email) : ?>". + $content. + ""; + } + + /*dtd + + */ + public function CommentHelp($attr,$content) + { + return + "blog->settings->system->wiki_comments) {\n". + " echo __('Comments can be formatted using a simple wiki syntax.');\n". + "} else {\n". + " echo __('HTML code is displayed as text and web addresses are automatically converted.');\n". + "} ?>"; + } + + /* Comment preview -------------------------------- */ + /*dtd + + */ + public function IfCommentPreview($attr,$content) + { + return + 'comment_preview !== null && $_ctx->comment_preview["preview"]) : ?>'. + $content. + ''; + } + + /*dtd + + */ + public function CommentPreviewName($attr) + { + $f = $this->getFilters($attr); + return 'comment_preview["name"]').'; ?>'; + } + + /*dtd + + */ + public function CommentPreviewEmail($attr) + { + $f = $this->getFilters($attr); + return 'comment_preview["mail"]').'; ?>'; + } + + /*dtd + + */ + public function CommentPreviewSite($attr) + { + $f = $this->getFilters($attr); + return 'comment_preview["site"]').'; ?>'; + } + + /*dtd + + + */ + public function CommentPreviewContent($attr) + { + $f = $this->getFilters($attr); + + if (!empty($attr['raw'])) { + $co = '$_ctx->comment_preview["rawcontent"]'; + } else { + $co = '$_ctx->comment_preview["content"]'; + } + + return ''; + } + + /*dtd + + */ + public function CommentPreviewCheckRemember($attr) + { + return + "comment_preview['remember']) { echo ' checked=\"checked\"'; } ?>"; + } + + /* Trackbacks ------------------------------------- */ + /*dtd + + */ + public function PingBlogName($attr) + { + $f = $this->getFilters($attr); + return 'pings->comment_author').'; ?>'; + } + + /*dtd + + */ + public function PingContent($attr) + { + $f = $this->getFilters($attr); + return 'pings->getTrackbackContent()').'; ?>'; + } + + /*dtd + + + */ + public function PingDate($attr,$type='') + { + $format = ''; + if (!empty($attr['format'])) { + $format = addslashes($attr['format']); + } + + $iso8601 = !empty($attr['iso8601']); + $rfc822 = !empty($attr['rfc822']); + $type = (!empty($attr['upddt']) ? 'upddt' : ''); + + $f = $this->getFilters($attr); + + if ($rfc822) { + return 'pings->getRFC822Date('".$type."')").'; ?>'; + } elseif ($iso8601) { + return 'pings->getISO8601Date('".$type."')").'; ?>'; + } else { + return 'pings->getDate('".$format."','".$type."')").'; ?>'; + } + } + + /*dtd + + + */ + public function PingTime($attr) + { + $format = ''; + if (!empty($attr['format'])) { + $format = addslashes($attr['format']); + } + $type = (!empty($attr['upddt']) ? 'upddt' : ''); + + $f = $this->getFilters($attr); + return 'pings->getTime('".$format."','".$type."')").'; ?>'; + } + + /*dtd + + */ + public function PingEntryTitle($attr) + { + $f = $this->getFilters($attr); + return 'pings->post_title').'; ?>'; + } + + /*dtd + + */ + public function PingFeedID($attr) + { + $f = $this->getFilters($attr); + return 'pings->getFeedID()').'; ?>'; + } + + /*dtd + + */ + public function PingID($attr) + { + return 'pings->comment_id; ?>'; + } + + /*dtd + + + */ + public function PingIfFirst($attr) + { + $ret = isset($attr['return']) ? $attr['return'] : 'first'; + $ret = html::escapeHTML($ret); + + return + 'pings->index() == 0) { '. + "echo '".addslashes($ret)."'; } ?>"; + } + + /*dtd + + + */ + public function PingIfOdd($attr) + { + $ret = isset($attr['return']) ? $attr['return'] : 'odd'; + $ret = html::escapeHTML($ret); + + return + 'pings->index()+1)%2) { '. + "echo '".addslashes($ret)."'; } ?>"; + } + + /*dtd + + */ + public function PingIP($attr) + { + return 'pings->comment_ip; ?>'; + } + + /*dtd + + */ + public function PingNoFollow($attr) + { + return + 'blog->settings->system->comments_nofollow) { '. + 'echo \' rel="nofollow"\';'. + '} ?>'; + } + + /*dtd + + */ + public function PingOrderNumber($attr) + { + return 'pings->index()+1; ?>'; + } + + /*dtd + + */ + public function PingPostURL($attr) + { + $f = $this->getFilters($attr); + return 'pings->getPostURL()').'; ?>'; + } + + /*dtd + + + */ + public function Pings($attr,$content) + { + $p = + "if (\$_ctx->posts !== null) { ". + "\$params['post_id'] = \$_ctx->posts->post_id; ". + "\$core->blog->withoutPassword(false);\n". + "}\n"; + + $p .= "\$params['comment_trackback'] = true;\n"; + + $lastn = 0; + if (isset($attr['lastn'])) { + $lastn = abs((integer) $attr['lastn'])+0; + } + + if ($lastn > 0) { + $p .= "\$params['limit'] = ".$lastn.";\n"; + } else { + $p .= "if (\$_ctx->nb_comment_per_page !== null) { \$params['limit'] = \$_ctx->nb_comment_per_page; }\n"; + } + + if (empty($attr['no_context'])) + { + $p .= + 'if ($_ctx->exists("categories")) { '. + "\$params['cat_id'] = \$_ctx->categories->cat_id; ". + "}\n"; + + $p .= + 'if ($_ctx->exists("langs")) { '. + "\$params['sql'] = \"AND P.post_lang = '\".\$core->blog->con->escape(\$_ctx->langs->post_lang).\"' \"; ". + "}\n"; + } + + $order = 'asc'; + if (isset($attr['order']) && preg_match('/^(desc|asc)$/i',$attr['order'])) { + $order = $attr['order']; + } + + $p .= "\$params['order'] = 'comment_dt ".$order."';\n"; + + if (isset($attr['no_content']) && $attr['no_content']) { + $p .= "\$params['no_content'] = true;\n"; + } + + $res = "core->callBehavior("templatePrepareParams", + array("tag" => "Pings","method" => "blog::getComments"), + $attr,$content); + $res .= '$_ctx->pings = $core->blog->getComments($params); unset($params);'."\n"; + $res .= "if (\$_ctx->posts !== null) { \$core->blog->withoutPassword(true);}\n"; + $res .= "?>\n"; + + $res .= + 'pings->fetch()) : ?>'.$content.'pings = null; ?>'; + + return $res; + } + + /*dtd + + */ + public function PingsFooter($attr,$content) + { + return + "pings->isEnd()) : ?>". + $content. + ""; + } + + /*dtd + + */ + public function PingsHeader($attr,$content) + { + return + "pings->isStart()) : ?>". + $content. + ""; + } + + /*dtd + + */ + public function PingTitle($attr) + { + $f = $this->getFilters($attr); + return 'pings->getTrackbackTitle()').'; ?>'; + } + + /*dtd + + */ + public function PingAuthorURL($attr) + { + $f = $this->getFilters($attr); + return 'pings->getAuthorURL()').'; ?>'; + } + + # System + /*dtd + + + */ + public function SysBehavior($attr,$raw) + { + if (!isset($attr['behavior'])) { + return; + } + + $b = addslashes($attr['behavior']); + return + 'hasBehavior(\''.$b.'\')) { '. + '$core->callBehavior(\''.$b.'\',$core,$_ctx);'. + '} ?>'; + } + + /*dtd + + + */ + public function SysIf($attr,$content) + { + $if = new ArrayObject(); + $is_ping = null; + + $operator = isset($attr['operator']) ? $this->getOperator($attr['operator']) : '&&'; + + if (isset($attr['categories'])) { + $sign = (boolean) $attr['categories'] ? '!' : '='; + $if[] = '$_ctx->categories '.$sign.'== null'; + } + + if (isset($attr['posts'])) { + $sign = (boolean) $attr['posts'] ? '!' : '='; + $if[] = '$_ctx->posts '.$sign.'== null'; + } + + if (isset($attr['blog_lang'])) { + $if[] = "\$core->blog->settings->system->lang == '".addslashes($attr['blog_lang'])."'"; + } + + if (isset($attr['current_tpl'])) { + $sign = '='; + if (substr($attr['current_tpl'],0,1) == '!') { + $sign = '!'; + $attr['current_tpl'] = substr($attr['current_tpl'],1); + } + $if[] = "\$_ctx->current_tpl ".$sign."= '".addslashes($attr['current_tpl'])."'"; + } + + if (isset($attr['current_mode'])) { + $sign = '='; + if (substr($attr['current_mode'],0,1) == '!') { + $sign = '!'; + $attr['current_mode'] = substr($attr['current_mode'],1); + } + $if[] = "\$core->url->type ".$sign."= '".addslashes($attr['current_mode'])."'"; + } + + if (isset($attr['has_tpl'])) { + $sign = ''; + if (substr($attr['has_tpl'],0,1) == '!') { + $sign = '!'; + $attr['has_tpl'] = substr($attr['has_tpl'],1); + } + $if[] = $sign."\$core->tpl->getFilePath('".addslashes($attr['has_tpl'])."') !== false"; + } + + if (isset($attr['blog_id'])) { + $sign = ''; + if (substr($attr['blog_id'],0,1) == '!') { + $sign = '!'; + $attr['blog_id'] = substr($attr['blog_id'],1); + } + $if[] = $sign."(\$core->blog->id == '".addslashes($attr['blog_id'])."')"; + } + + if (isset($attr['comments_active'])) { + $sign = (boolean) $attr['comments_active'] ? '' : '!'; + $if[] = $sign.'$core->blog->settings->system->allow_comments'; + } + + if (isset($attr['pings_active'])) { + $sign = (boolean) $attr['pings_active'] ? '' : '!'; + $if[] = $sign.'$core->blog->settings->system->allow_trackbacks'; + } + + if (isset($attr['wiki_comments'])) { + $sign = (boolean) $attr['wiki_comments'] ? '' : '!'; + $if[] = $sign.'$core->blog->settings->system->wiki_comments'; + } + + if (isset($attr['search_count']) && + preg_match('/^((=|!|>|<)=|(>|<))\s*[0-9]+$/',trim($attr['search_count']))) { + $if[] = '(isset($_search_count) && $_search_count '.html::decodeEntities($attr['search_count']).')'; + } + + $this->core->callBehavior('tplIfConditions','SysIf',$attr,$content,$if); + + if (count($if) != 0) { + return ''.$content.''; + } else { + return $content; + } + } + + /*dtd + + */ + public function SysIfCommentPublished($attr,$content) + { + return + ''. + $content. + ''; + } + + /*dtd + + */ + public function SysIfCommentPending($attr,$content) + { + return + ''. + $content. + ''; + } + + /*dtd + + */ + public function SysFeedSubtitle($attr) + { + $f = $this->getFilters($attr); + return 'feed_subtitle !== null) { echo '.sprintf($f,'$_ctx->feed_subtitle').';} ?>'; + } + + /*dtd + + */ + public function SysIfFormError($attr,$content) + { + return + 'form_error !== null) : ?>'. + $content. + ''; + } + + /*dtd + + */ + public function SysFormError($attr) + { + return + 'form_error !== null) { echo $_ctx->form_error; } ?>'; + } + + public function SysPoweredBy($attr) + { + return + 'Dotclear"); ?>'; + } + + public function SysSearchString($attr) + { + $s = isset($attr['string']) ? $attr['string'] : '%1$s'; + + $f = $this->getFilters($attr); + return ''; + } + + public function SysSelfURI($attr) + { + $f = $this->getFilters($attr); + return ''; + } +} + +# Template nodes, for parsing purposes + +# Generic list node, this one may only be instanciated +# once for root element +class tplNode +{ + # Basic tree structure : links to parent, children forrest + protected $parentNode; + protected $children; + + public function __construct() { + $this->children = array(); + $this->parentNode = null; + } + + // Returns compiled block + public function compile($tpl) { + $res=''; + foreach ($this->children as $child) { + $res .= $child->compile($tpl); + } + return $res; + } + + # Add a children to current node + public function addChild ($child) { + $this->children[] = $child; + $child->setParent($this); + } + + # Defines parent for current node + protected function setParent($parent) { + $this->parentNode = $parent; + } + + # Retrieves current node parent. + # If parent is root node, null is returned + public function getParent() { + return $this->parentNode; + } + + # Current node tag + public function getTag() { + return "ROOT"; + } +} + +// Text node, for any non-tpl content +class tplNodeText extends tplNode +{ + // Simple text node, only holds its content + protected $content; + + public function __construct($text) { + parent::__construct(); + $this->content=$text; + } + + public function compile($tpl) { + return $this->content; + } + + public function getTag() { + return "TEXT"; + } +} + +// Block node, for all ... +class tplNodeBlock extends tplNode +{ + protected $attr; + protected $tag; + protected $closed; + + public function __construct($tag,$attr) { + parent::__construct(); + $this->content=''; + $this->tag = $tag; + $this->attr = $attr; + $this->closed=false; + } + public function setClosing() { + $this->closed = true; + } + public function isClosed() { + return $this->closed; + } + public function compile($tpl) { + if ($this->closed) { + $content = parent::compile($tpl); + return $tpl->compileBlockNode($this->tag,$this->attr,$content); + } else { + // if tag has not been closed, silently ignore its content... + return ''; + } + } + public function getTag() { + return $this->tag; + } +} + +// Value node, for all {{tpl:Tag}} +class tplNodeValue extends tplNode +{ + protected $attr; + protected $str_attr; + protected $tag; + + public function __construct($tag,$attr,$str_attr) { + parent::__construct(); + $this->content=''; + $this->tag = $tag; + $this->attr = $attr; + $this->str_attr = $str_attr; + } + + public function compile($tpl) { + return $tpl->compileValueNode($this->tag,$this->attr,$this->str_attr); + } + + public function getTag() { + return $this->tag; + } +} + +?> diff --git a/v2/dotclear/inc/public/default-templates/404.html b/v2/dotclear/inc/public/default-templates/404.html new file mode 100644 index 0000000..f2beeeb --- /dev/null +++ b/v2/dotclear/inc/public/default-templates/404.html @@ -0,0 +1,62 @@ + + + + + + + {{tpl:lang Document not found}} - {{tpl:BlogName encode_html="1"}} + + + + + + + + + + + + + + + + {{tpl:include src="_head.html"}} + + + +
        +{{tpl:include src="_top.html"}} + +
        + +
        +
        + +
        +

        {{tpl:lang Document not found}}

        +
        + +
        +

        {{tpl:lang The document you are looking for does not exist.}}

        +
        + +
        +
        + + + +
        + +{{tpl:include src="_footer.html"}} +
        + + \ No newline at end of file diff --git a/v2/dotclear/inc/public/default-templates/_flv_player.html b/v2/dotclear/inc/public/default-templates/_flv_player.html new file mode 100644 index 0000000..7f5b9b6 --- /dev/null +++ b/v2/dotclear/inc/public/default-templates/_flv_player.html @@ -0,0 +1,8 @@ + + + + + +{{tpl:lang Embedded Audio Player}} + \ No newline at end of file diff --git a/v2/dotclear/inc/public/default-templates/_footer.html b/v2/dotclear/inc/public/default-templates/_footer.html new file mode 100644 index 0000000..fac8db1 --- /dev/null +++ b/v2/dotclear/inc/public/default-templates/_footer.html @@ -0,0 +1,5 @@ + + +{{tpl:SysBehavior behavior="publicFooterContent"}} \ No newline at end of file diff --git a/v2/dotclear/inc/public/default-templates/_head.html b/v2/dotclear/inc/public/default-templates/_head.html new file mode 100644 index 0000000..a79816f --- /dev/null +++ b/v2/dotclear/inc/public/default-templates/_head.html @@ -0,0 +1,12 @@ + + + + + + +{{tpl:include src="user_head.html"}} +{{tpl:SysBehavior behavior="publicHeadContent"}} \ No newline at end of file diff --git a/v2/dotclear/inc/public/default-templates/_mp3_player.html b/v2/dotclear/inc/public/default-templates/_mp3_player.html new file mode 100644 index 0000000..b1a1991 --- /dev/null +++ b/v2/dotclear/inc/public/default-templates/_mp3_player.html @@ -0,0 +1,6 @@ + + + + +{{tpl:lang Embedded Audio Player}} + \ No newline at end of file diff --git a/v2/dotclear/inc/public/default-templates/_top.html b/v2/dotclear/inc/public/default-templates/_top.html new file mode 100644 index 0000000..829edae --- /dev/null +++ b/v2/dotclear/inc/public/default-templates/_top.html @@ -0,0 +1,10 @@ +
        +

        {{tpl:BlogName encode_html="1"}}

        + + + {{tpl:SysBehavior behavior="publicTopAfterContent"}} +
        + +

        {{tpl:lang To content}} | +{{tpl:lang To menu}} | +{{tpl:lang To search}}

        \ No newline at end of file diff --git a/v2/dotclear/inc/public/default-templates/archive.html b/v2/dotclear/inc/public/default-templates/archive.html new file mode 100644 index 0000000..c551449 --- /dev/null +++ b/v2/dotclear/inc/public/default-templates/archive.html @@ -0,0 +1,79 @@ + + + + + + + {{tpl:lang Archives}} - {{tpl:BlogName encode_html="1"}} + + + + + + + + + + + + + + + + + + + + + + {{tpl:include src="_head.html"}} + + + +
        +{{tpl:include src="_top.html"}} + +
        + +
        +
        + +
        +

        {{tpl:lang Archives}}

        +
        + +
        + + +

        {{tpl:ArchiveDate format="%Y"}}

        + + +
        +
        + +
        +
        + + + +
        + +{{tpl:include src="_footer.html"}} +
        + + \ No newline at end of file diff --git a/v2/dotclear/inc/public/default-templates/archive_month.html b/v2/dotclear/inc/public/default-templates/archive_month.html new file mode 100644 index 0000000..0f4b745 --- /dev/null +++ b/v2/dotclear/inc/public/default-templates/archive_month.html @@ -0,0 +1,96 @@ + + + + + + + {{tpl:lang Archives}} - {{tpl:ArchiveDate}} - {{tpl:BlogName encode_html="1"}} + + + + + + + + + + + + + + + + + + + + + + + + + + {{tpl:include src="_head.html"}} + + + +
        +{{tpl:include src="_top.html"}} + +
        + +
        +
        + + + +
        +

        {{tpl:ArchiveDate}}

        +
        + +
        + + +

        {{tpl:EntryDate}}

        + +

        {{tpl:EntryTitle encode_html="1"}}

        + + +
        +
        +
        +
        + + + +
        + +{{tpl:include src="_footer.html"}} +
        + + \ No newline at end of file diff --git a/v2/dotclear/inc/public/default-templates/atom-comments.xml b/v2/dotclear/inc/public/default-templates/atom-comments.xml new file mode 100644 index 0000000..74b4970 --- /dev/null +++ b/v2/dotclear/inc/public/default-templates/atom-comments.xml @@ -0,0 +1,47 @@ + + + + {{tpl:BlogName encode_xml="1"}}{{tpl:SysFeedSubtitle encode_xml="1"}} + - {{tpl:lang Comments}} + {{tpl:BlogDescription encode_xml="1"}} + + + {{tpl:BlogUpdateDate iso8601="1"}} + + {{tpl:BlogEditor encode_xml="1"}} + + {{tpl:BlogFeedID}} + Dotclear + + + + + + [ping] {{tpl:PingEntryTitle encode_xml="1"}} - {{tpl:PingBlogName encode_xml="1"}} + + {{tpl:PingFeedID}} + {{tpl:PingDate iso8601="1"}} + {{tpl:PingDate iso8601="1" upddt="1"}} + {{tpl:PingBlogName encode_xml="1"}} + <p><a href="{{tpl:PingAuthorURL encode_xml="1"}}">{{tpl:PingTitle encode_xml="1"}}</a></p> {{tpl:PingContent encode_xml="1"}} + + + + + + + {{tpl:CommentEntryTitle encode_xml="1"}} - {{tpl:CommentAuthor encode_xml="1"}} + + {{tpl:CommentFeedID}} + {{tpl:CommentDate iso8601="1"}} + {{tpl:CommentDate iso8601="1" upddt="1"}} + {{tpl:CommentAuthor encode_xml="1"}} + {{tpl:CommentContent absolute_urls="1" encode_xml="1"}} + + + + + \ No newline at end of file diff --git a/v2/dotclear/inc/public/default-templates/atom.xml b/v2/dotclear/inc/public/default-templates/atom.xml new file mode 100644 index 0000000..5237103 --- /dev/null +++ b/v2/dotclear/inc/public/default-templates/atom.xml @@ -0,0 +1,50 @@ + + + + {{tpl:BlogName encode_xml="1"}}{{tpl:SysFeedSubtitle encode_xml="1"}} + {{tpl:BlogDescription encode_xml="1"}} + + + {{tpl:BlogUpdateDate iso8601="1"}} + + {{tpl:BlogEditor encode_xml="1"}} + + {{tpl:BlogFeedID}} + Dotclear + + + + + {{tpl:EntryTitle encode_xml="1"}} + + {{tpl:EntryFeedID}} + {{tpl:EntryDate iso8601="1"}} + {{tpl:EntryDate iso8601="1" upddt="1"}} + {{tpl:EntryAuthorCommonName encode_xml="1"}} + + {{tpl:EntryCategory encode_html="1"}} + + {{tpl:TagID}} + + {{tpl:EntryExcerpt absolute_urls="1" encode_xml="1"}} + {{tpl:EntryContent absolute_urls="1" encode_xml="1"}} + + + + + + + + {{tpl:EntryURL}}#comment-form + {{tpl:BlogFeedURL type="atom"}}/comments/{{tpl:EntryID}} + + + + + \ No newline at end of file diff --git a/v2/dotclear/inc/public/default-templates/category.html b/v2/dotclear/inc/public/default-templates/category.html new file mode 100644 index 0000000..0d43eea --- /dev/null +++ b/v2/dotclear/inc/public/default-templates/category.html @@ -0,0 +1,167 @@ + + + + + + + {{tpl:CategoryTitle encode_html="1"}} - {{tpl:BlogName encode_html="1"}}<tpl:PaginationIf start="0"> - {{tpl:lang page}} {{tpl:PaginationCurrent}}</tpl:PaginationIf> + + + + + + + - {{tpl:lang page}} {{tpl:PaginationCurrent}}" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {{tpl:include src="_head.html"}} + + + +
        +{{tpl:include src="_top.html"}} + +
        + +
        +
        + +
        +

        {{tpl:CategoryTitle encode_html="1"}} + {{tpl:CategoryTitle encode_html="1"}}

        + {{tpl:CategoryDescription}} + + +

        {{tpl:lang Entries feed}} + + + - {{tpl:lang Comments feed}} + +

        +
        +
        + + + +
        +

        {{tpl:lang Subcategories}}

        + +
        + +
        + + +
        + +

        {{tpl:EntryDate}}

        + +

        {{tpl:EntryTitle encode_html="1"}}

        + + + + + + + + + {{tpl:SysBehavior behavior="publicEntryBeforeContent"}} + + + +
        {{tpl:EntryExcerpt}}
        +

        {{tpl:lang Continue + reading}}...

        +
        + + + +
        {{tpl:EntryContent}}
        +
        + + + {{tpl:SysBehavior behavior="publicEntryAfterContent"}} + + + + + +
        + + + +

        - + {{tpl:lang page}} {{tpl:PaginationCurrent}} {{tpl:lang of}} {{tpl:PaginationCounter}} + -

        +
        +
        +
        +
        +
        + + + +
        + +{{tpl:include src="_footer.html"}} +
        + + \ No newline at end of file diff --git a/v2/dotclear/inc/public/default-templates/home.html b/v2/dotclear/inc/public/default-templates/home.html new file mode 100644 index 0000000..df11fcd --- /dev/null +++ b/v2/dotclear/inc/public/default-templates/home.html @@ -0,0 +1,144 @@ + + + + + + + {{tpl:BlogName encode_html="1"}}<tpl:PaginationIf start="0"> - {{tpl:lang page}} {{tpl:PaginationCurrent}}</tpl:PaginationIf> + - {{tpl:lang page}} {{tpl:PaginationCurrent}}" /> + + + + + + - {{tpl:lang page}} {{tpl:PaginationCurrent}}" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {{tpl:include src="_head.html"}} + + + +
        +{{tpl:include src="_top.html"}} + +
        + +
        +
        + +
        + +

        {{tpl:EntryDate}}

        + +

        {{tpl:EntryTitle encode_html="1"}}

        + + + + + + + + + {{tpl:SysBehavior behavior="publicEntryBeforeContent"}} + + + +
        {{tpl:EntryExcerpt}}
        +

        {{tpl:lang Continue + reading}}...

        +
        + + + +
        {{tpl:EntryContent}}
        +
        + + + {{tpl:SysBehavior behavior="publicEntryAfterContent"}} + + + + + +
        + + + +

        - + {{tpl:lang page}} {{tpl:PaginationCurrent}} {{tpl:lang of}} {{tpl:PaginationCounter}} + -

        +
        +
        +
        +
        +
        + + + +
        + +{{tpl:include src="_footer.html"}} +
        + + \ No newline at end of file diff --git a/v2/dotclear/inc/public/default-templates/password-form.html b/v2/dotclear/inc/public/default-templates/password-form.html new file mode 100644 index 0000000..e462dc0 --- /dev/null +++ b/v2/dotclear/inc/public/default-templates/password-form.html @@ -0,0 +1,41 @@ + + + + + + {{tpl:lang Password needed}} - {{tpl:BlogName encode_html="1"}} + + + + + + +
        +

        {{tpl:lang Password needed}}

        + +

        {{tpl:lang You must give a password to access this area.}}

        +

        + +
        + + + \ No newline at end of file diff --git a/v2/dotclear/inc/public/default-templates/post.html b/v2/dotclear/inc/public/default-templates/post.html new file mode 100644 index 0000000..6ff773c --- /dev/null +++ b/v2/dotclear/inc/public/default-templates/post.html @@ -0,0 +1,274 @@ + + + + + + + {{tpl:EntryTitle encode_html="1"}} - {{tpl:BlogName encode_html="1"}} + + + + + + + + + + + + + + + + + + + + + + + + + + {{tpl:include src="_head.html"}} + + + + + + +
        +{{tpl:EntryPingData}} + +{{tpl:include src="_top.html"}} + +
        + +
        +
        + + + +
        +

        {{tpl:EntryTitle encode_html="1"}}

        + + + + + + + + + {{tpl:SysBehavior behavior="publicEntryBeforeContent"}} + + + +
        {{tpl:EntryExcerpt}}
        +
        + +
        {{tpl:EntryContent}}
        + + + {{tpl:SysBehavior behavior="publicEntryAfterContent"}} +
        + + + + +
        +

        {{tpl:lang Attachments}}

        +
          + +
        • + + {{tpl:include src="_mp3_player.html"/}} - + + + {{tpl:include src="_flv_player.html"/}} + + + {{tpl:AttachmentTitle}} + +
        • + +
        +
        + +
        + + + + + +
        +

        {{tpl:lang Comments}}

        +
        + +
        {{tpl:CommentOrderNumber}}. + {{tpl:lang On}} {{tpl:CommentDate}}, {{tpl:CommentTime}} + {{tpl:lang by}} {{tpl:CommentAuthorLink}}
        + +
        + + {{tpl:SysBehavior behavior="publicCommentBeforeContent"}} + + {{tpl:CommentContent}} + + + {{tpl:SysBehavior behavior="publicCommentAfterContent"}} +
        + +
        +
        + +
        +
        + + + +

        {{tpl:SysFormError}}

        +
        + + +

        {{tpl:lang Your comment has been published.}}

        +
        + + +

        {{tpl:lang Your comment has been submitted and + will be reviewed for publication.}}

        +
        + + +
        + +
        +

        {{tpl:lang Your comment}}

        +
        +
        {{tpl:CommentPreviewContent}}
        +
        +

        +
        +
        + +

        {{tpl:lang Add a comment}}

        +
        + + {{tpl:SysBehavior behavior="publicCommentFormBeforeContent"}} + +

        + +

        + +

        + +

        + +

        + +

        + +

        + +

        + +

        +

        {{tpl:CommentHelp}}

        + + + {{tpl:SysBehavior behavior="publicCommentFormAfterContent"}} +
        + +
        +

        +

        +
        +
        +
        + + + +
        +

        {{tpl:lang They posted on the same topic}}

        + + +
        + +
        {{tpl:PingOrderNumber}}. + {{tpl:lang On}} {{tpl:PingDate}}, {{tpl:PingTime}} + {{tpl:lang by}} {{tpl:PingBlogName encode_html="1"}}
        + +
        + + {{tpl:SysBehavior behavior="publicPingBeforeContent"}} + +

        {{tpl:PingTitle encode_html="1"}}

        + {{tpl:PingContent}} + + + {{tpl:SysBehavior behavior="publicPingAfterContent"}} +
        + +
        + +
        +
        +
        + + +

        {{tpl:lang Trackback URL}} : {{tpl:EntryPingLink}}

        +
        + + +

        {{tpl:lang This post's comments feed}}

        +
        +
        +
        + + + +
        + +{{tpl:include src="_footer.html"}} +
        + + diff --git a/v2/dotclear/inc/public/default-templates/rss2-comments.xml b/v2/dotclear/inc/public/default-templates/rss2-comments.xml new file mode 100644 index 0000000..ccea31b --- /dev/null +++ b/v2/dotclear/inc/public/default-templates/rss2-comments.xml @@ -0,0 +1,48 @@ + + + + + {{tpl:BlogName encode_xml="1"}}{{tpl:SysFeedSubtitle encode_xml="1"}} + - {{tpl:lang Comments}} + {{tpl:BlogURL}} + + {{tpl:BlogDescription encode_xml="1"}} + {{tpl:BlogLanguage}} + {{tpl:BlogUpdateDate rfc822="1"}} + {{tpl:BlogCopyrightNotice encode_xml="1"}} + http://blogs.law.harvard.edu/tech/rss + Dotclear + + + + + + [ping] {{tpl:PingEntryTitle encode_xml="1"}} - {{tpl:PingBlogName encode_xml="1"}} + {{tpl:PingPostURL encode_xml="1"}}#c{{tpl:PingID}} + {{tpl:PingFeedID}} + {{tpl:PingDate rfc822="1"}} + {{tpl:PingBlogName encode_xml="1"}} + + <p><a href="{{tpl:PingAuthorURL encode_xml="1"}}">{{tpl:PingTitle encode_xml="1"}}</a></p> + {{tpl:PingContent encode_xml="1"}} + + + + + + {{tpl:CommentEntryTitle encode_xml="1"}} - {{tpl:CommentAuthor encode_xml="1"}} + {{tpl:CommentPostURL encode_xml="1"}}#c{{tpl:CommentID}} + {{tpl:CommentFeedID}} + {{tpl:CommentDate rfc822="1"}} + {{tpl:CommentAuthor encode_xml="1"}} + + {{tpl:CommentContent absolute_urls="1" encode_xml="1"}} + + + + + + \ No newline at end of file diff --git a/v2/dotclear/inc/public/default-templates/rss2.xml b/v2/dotclear/inc/public/default-templates/rss2.xml new file mode 100644 index 0000000..c4ed4ba --- /dev/null +++ b/v2/dotclear/inc/public/default-templates/rss2.xml @@ -0,0 +1,49 @@ + + + + + {{tpl:BlogName encode_xml="1"}}{{tpl:SysFeedSubtitle encode_xml="1"}} + {{tpl:BlogURL}} + + {{tpl:BlogDescription encode_xml="1"}} + {{tpl:BlogLanguage}} + {{tpl:BlogUpdateDate rfc822="1"}} + {{tpl:BlogCopyrightNotice encode_xml="1"}} + http://blogs.law.harvard.edu/tech/rss + Dotclear + + + + + {{tpl:EntryTitle encode_xml="1"}} + {{tpl:EntryURL}} + {{tpl:EntryFeedID}} + {{tpl:EntryDate rfc822="1"}} + {{tpl:EntryAuthorCommonName encode_xml="1"}} + + {{tpl:EntryCategory encode_html="1"}} + + {{tpl:TagID}} + + {{tpl:EntryExcerpt absolute_urls="1" encode_xml="1"}} + {{tpl:EntryContent absolute_urls="1" encode_xml="1"}} + + + + + + + {{tpl:EntryURL}}#comment-form + {{tpl:EntryURL}}#comment-form + {{tpl:BlogFeedURL}}/comments/{{tpl:EntryID}} + + + + + + \ No newline at end of file diff --git a/v2/dotclear/inc/public/default-templates/rss2.xsl b/v2/dotclear/inc/public/default-templates/rss2.xsl new file mode 100644 index 0000000..9dcd864 --- /dev/null +++ b/v2/dotclear/inc/public/default-templates/rss2.xsl @@ -0,0 +1,120 @@ + + + + + + + + + {{tpl:lang Subscribe to}} <xsl:value-of select="/rss/channel/title"/> + + + + +
        +
        +

        +

        +
        +
        +

        {{tpl:lang What is an RSS feed?}}

        +

        {{tpl:lang RSS feed is a free blog summary. It provides content + (either posts or comments) or summaries of content, together with links + to the full versions, and other metadata. The last published items may + then be read by your favorite RSS + aggregator.}}

        +

        {{tpl:lang Subscribe}}

        +

        {{tpl:lang Simply copy the following URL into your aggregator:}}

        +

        +
        +
        + +
        + +
        + + +
        + + + +
        +

        +
        +
        +
        + +
        \ No newline at end of file diff --git a/v2/dotclear/inc/public/default-templates/search.html b/v2/dotclear/inc/public/default-templates/search.html new file mode 100644 index 0000000..2d2ba90 --- /dev/null +++ b/v2/dotclear/inc/public/default-templates/search.html @@ -0,0 +1,152 @@ + + + + + + + {{tpl:lang Search}} - {{tpl:SysSearchString encode_html="1"}} - {{tpl:BlogName encode_html="1"}}<tpl:PaginationIf start="0"> - {{tpl:lang page}} {{tpl:PaginationCurrent}}</tpl:PaginationIf> + + + + + + - {{tpl:lang page}} {{tpl:PaginationCurrent}}" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {{tpl:include src="_head.html"}} + + + +
        +{{tpl:include src="_top.html"}} + +
        + +
        +
        + +
        +

        {{tpl:lang Search}}

        + +

        {{tpl:SysSearchString encode_html="1" string="Your search for %1$s returned no result."}}

        +
        + +

        {{tpl:SysSearchString encode_html="1" string="Your search for %1$s returned %2$s result."}}

        +
        + +

        {{tpl:SysSearchString encode_html="1" string="Your search for %1$s returned %2$s results."}}

        +
        +
        + + +
        + +

        {{tpl:EntryDate}}

        + +

        {{tpl:EntryTitle encode_html="1"}}

        + + + + + + + + + {{tpl:SysBehavior behavior="publicEntryBeforeContent"}} + + + +
        {{tpl:EntryExcerpt}}
        +

        {{tpl:lang Continue + reading}}...

        +
        + + + +
        {{tpl:EntryContent}}
        +
        + + + {{tpl:SysBehavior behavior="publicEntryAfterContent"}} + + + + + +
        + + + +

        - + {{tpl:lang page}} {{tpl:PaginationCurrent}} {{tpl:lang of}} {{tpl:PaginationCounter}} + -

        +
        +
        +
        +
        +
        + + + +
        + +{{tpl:include src="_footer.html"}} +
        + + \ No newline at end of file diff --git a/v2/dotclear/inc/public/default-templates/user_head.html b/v2/dotclear/inc/public/default-templates/user_head.html new file mode 100644 index 0000000..4b380d4 --- /dev/null +++ b/v2/dotclear/inc/public/default-templates/user_head.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v2/dotclear/inc/public/lib.tpl.context.php b/v2/dotclear/inc/public/lib.tpl.context.php new file mode 100644 index 0000000..18780ad --- /dev/null +++ b/v2/dotclear/inc/public/lib.tpl.context.php @@ -0,0 +1,443 @@ +pop($name); + } else { + $this->stack[$name][] =& $var; + if ($var instanceof record) { + $this->stack['cur_loop'][] =& $var; + } + } + } + + public function __get($name) + { + if (!isset($this->stack[$name])) { + return null; + } + + $n = count($this->stack[$name]); + if ($n > 0) { + return $this->stack[$name][($n-1)]; + } + + return null; + } + + public function exists($name) + { + return isset($this->stack[$name][0]); + } + + public function pop($name) + { + if (isset($this->stack[$name])) { + $v = array_pop($this->stack[$name]); + if ($v instanceof record) { + array_pop($this->stack['cur_loop']); + } + unset($v); + } + } + + # Loop position tests + public function loopPosition($start,$length=null,$even=null) + { + if (!$this->cur_loop) { + return false; + } + + $index = $this->cur_loop->index(); + $size = $this->cur_loop->count(); + + $test = false; + if ($start >= 0) + { + $test = $index >= $start; + if ($length !== null) { + if ($length >= 0) { + $test = $test && $index < $start + $length; + } else { + $test = $test && $index < $size + $length; + } + } + } + else + { + $test = $index >= $size + $start; + if ($length !== null) { + if ($length >= 0) { + $test = $test && $index < $size + $start + $length; + } else { + $test = $test && $index < $size + $length; + } + } + } + + if ($even !== null) { + $test = $test && $index%2 == $even; + } + + return $test; + } + + + # Static methods + public static function global_filter($str, + $encode_xml, $remove_html, $cut_string, $lower_case, $upper_case ,$tag='') + { + $args = func_get_args(); + array_pop($args); + $args[0] =& $str; + + # --BEHAVIOR-- publicBeforeContentFilter + $res = $GLOBALS['core']->callBehavior('publicBeforeContentFilter',$GLOBALS['core'],$tag,$args); + + if ($remove_html) { + $str = self::remove_html($str); + $str = preg_replace('/\s+/',' ',$str); + } + + if ($encode_xml) { + $str = self::encode_xml($str); + } + + if ($cut_string) { + $str = self::cut_string($str,(integer) $cut_string); + } + + if ($lower_case) { + $str = self::lower_case($str); + } elseif ($upper_case) { + $str = self::upper_case($str); + } + + # --BEHAVIOR-- publicAfterContentFilter + $res = $GLOBALS['core']->callBehavior('publicAfterContentFilter',$GLOBALS['core'],$tag,$args); + + return $str; + } + + + public static function cut_string($str,$l) + { + return text::cutString($str,$l); + } + + public static function encode_xml($str) + { + return html::escapeHTML($str); + } + + public static function remove_html($str) + { + return html::decodeEntities(html::clean($str)); + } + + public static function lower_case($str) + { + return mb_strtolower($str); + } + + public static function upper_case($str) + { + return mb_strtoupper($str); + } + + public static function categoryPostParam(&$p) + { + $not = substr($p['cat_url'],0,1) == '!'; + if ($not) { + $p['cat_url'] = substr($p['cat_url'],1); + } + + $p['cat_url'] = preg_split('/\s*,\s*/',$p['cat_url'],-1,PREG_SPLIT_NO_EMPTY); + + foreach ($p['cat_url'] as &$v) + { + if ($not) { + $v .= ' ?not'; + } + if ($GLOBALS['_ctx']->exists('categories') && preg_match('/#self/',$v)) { + $v = preg_replace('/#self/',$GLOBALS['_ctx']->categories->cat_url,$v); + } elseif ($GLOBALS['_ctx']->exists('posts') && preg_match('/#self/',$v)) { + $v = preg_replace('/#self/',$GLOBALS['_ctx']->posts->cat_url,$v); + } + } + } + + # Static methods for pagination + public static function PaginationNbPages() + { + global $_ctx; + + if ($_ctx->pagination === null) { + return false; + } + + $nb_posts = $_ctx->pagination->f(0); + $nb_per_page = $_ctx->post_params['limit'][1]; + + $nb_pages = ceil($nb_posts/$nb_per_page); + + return $nb_pages; + } + + public static function PaginationPosition($offset=0) + { + if (isset($GLOBALS['_page_number'])) { + $p = $GLOBALS['_page_number']; + } else { + $p = 1; + } + + $p = $p+$offset; + + $n = self::PaginationNbPages(); + if (!$n) { + return $p; + } + + if ($p > $n || $p <= 0) { + return 1; + } else { + return $p; + } + } + + public static function PaginationStart() + { + if (isset($GLOBALS['_page_number'])) { + return self::PaginationPosition() == 1; + } + + return true; + } + + public static function PaginationEnd() + { + if (isset($GLOBALS['_page_number'])) { + return self::PaginationPosition() == self::PaginationNbPages(); + } + + return false; + } + + public static function PaginationURL($offset=0) + { + $args = $_SERVER['URL_REQUEST_PART']; + + $n = self::PaginationPosition($offset); + + $args = preg_replace('#(^|/)page/([0-9]+)$#','',$args); + + $url = $GLOBALS['core']->blog->url.$args; + + if ($n > 1) { + $url = preg_replace('#/$#','',$url); + $url .= '/page/'.$n; + } + + # If search param + if (!empty($_GET['q'])) { + $s = strpos($url,'?') !== false ? '&' : '?'; + $url .= $s.'q='.rawurlencode($_GET['q']); + } + return $url; + } + + # Robots policy + public static function robotsPolicy($base,$over) + { + $pol = array('INDEX' => 'INDEX','FOLLOW' => 'FOLLOW', 'ARCHIVE' => 'ARCHIVE'); + $base = array_flip(preg_split('/\s*,\s*/',$base)); + $over = array_flip(preg_split('/\s*,\s*/',$over)); + + foreach ($pol as $k => &$v) + { + if (isset($base[$k]) || isset($base['NO'.$k])) { + $v = isset($base['NO'.$k]) ? 'NO'.$k : $k; + } + if (isset($over[$k]) || isset($over['NO'.$k])) { + $v = isset($over['NO'.$k]) ? 'NO'.$k : $k; + } + } + + if ($pol['ARCHIVE'] == 'ARCHIVE') { + unset($pol['ARCHIVE']); + } + + return implode(', ',$pol); + } + + # Smilies static methods + public static function getSmilies($blog) + { + $path = array(); + if (isset($GLOBALS['__theme'])) { + $path[] = $GLOBALS['__theme']; + } + $path[] = 'default'; + $definition = $blog->themes_path.'/%s/smilies/smilies.txt'; + $base_url = $blog->settings->system->themes_url.'/%s/smilies/'; + + $res = array(); + + foreach ($path as $t) + { + if (file_exists(sprintf($definition,$t))) { + $base_url = sprintf($base_url,$t); + return self::smiliesDefinition(sprintf($definition,$t),$base_url); + } + } + return false; + } + + public static function smiliesDefinition($f,$url) + { + $def = file($f); + + $res = array(); + foreach($def as $v) + { + $v = trim($v); + if (preg_match('|^([^\t]*)[\t]+(.*)$|',$v,$matches)) + { + $r = '/(\A|[\s]+|>)('.preg_quote($matches[1],'/').')([\s]+|[<]|\Z)/ms'; + $s = '$1$3'; + $res[$r] = $s; + } + } + + return $res; + } + + public static function addSmilies($str) + { + if (!isset($GLOBALS['__smilies']) || !is_array($GLOBALS['__smilies'])) { + return $str; + } + + return preg_replace(array_keys($GLOBALS['__smilies']),array_values($GLOBALS['__smilies']),$str); + } + + # First post image helpers + public static function EntryFirstImageHelper($size,$with_category,$class="") + { + global $core, $_ctx; + + $media = new dcMedia($core); + $sizes = implode('|',array_keys($media->thumb_sizes)).'|o'; + if (!preg_match('/^'.$sizes.'$/',$size)) { + $size = 's'; + } + $p_url = $core->blog->settings->system->public_url; + $p_site = preg_replace('#^(.+?//.+?)/(.*)$#','$1',$core->blog->url); + $p_root = $core->blog->public_path; + + $pattern = '(?:'.preg_quote($p_site,'/').')?'.preg_quote($p_url,'/'); + $pattern = sprintf('/]+/msu',$pattern); + + $src = ''; + $alt = ''; + + # We first look in post content + if ($_ctx->posts) + { + $subject = $_ctx->posts->post_excerpt_xhtml.$_ctx->posts->post_content_xhtml; + if (preg_match_all($pattern,$subject,$m) > 0) + { + foreach ($m[1] as $i => $img) { + if (($src = self::ContentFirstImageLookup($p_root,$img,$size)) !== false) { + $src = $p_url.(dirname($img) != '/' ? dirname($img) : '').'/'.$src; + if (preg_match('/alt="([^"]+)"/',$m[0][$i],$malt)) { + $alt = $malt[1]; + } + break; + } + } + } + } + + # No src, look in category description if available + if (!$src && $with_category && $_ctx->categories) + { + if (preg_match_all($pattern,$_ctx->categories->cat_desc,$m) > 0) + { + foreach ($m[1] as $i => $img) { + if (($src = self::ContentFirstImageLookup($p_root,$img,$size)) !== false) { + $src = $p_url.(dirname($img) != '/' ? dirname($img) : '').'/'.$src; + if (preg_match('/alt="([^"]+)"/',$m[0][$i],$malt)) { + $alt = $malt[1]; + } + break; + } + } + }; + } + + if ($src) { + return ''.$alt.''; + } + } + + private static function ContentFirstImageLookup($root,$img,$size) + { + global $core; + + # Get base name and extension + $info = path::info($img); + $base = $info['base']; + + $media = new dcMedia($core); + $sizes = implode('|',array_keys($media->thumb_sizes)); + if (preg_match('/^\.(.+)_('.$sizes.')$/',$base,$m)) { + $base = $m[1]; + } + + $res = false; + if ($size != 'o' && file_exists($root.'/'.$info['dirname'].'/.'.$base.'_'.$size.'.jpg')) + { + $res = '.'.$base.'_'.$size.'.jpg'; + } + else + { + $f = $root.'/'.$info['dirname'].'/'.$base; + if (file_exists($f.'.'.$info['extension'])) { + $res = $base.'.'.$info['extension']; + } elseif (file_exists($f.'.jpg')) { + $res = $base.'.jpg'; + } elseif (file_exists($f.'.jpeg')) { + $res = $base.'.jpeg'; + } elseif (file_exists($f.'.png')) { + $res = $base.'.png'; + } elseif (file_exists($f.'.gif')) { + $res = $base.'.gif'; + } + } + + if ($res) { + return $res; + } + return false; + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/public/lib.urlhandlers.php b/v2/dotclear/inc/public/lib.urlhandlers.php new file mode 100644 index 0000000..7ff1f87 --- /dev/null +++ b/v2/dotclear/inc/public/lib.urlhandlers.php @@ -0,0 +1,683 @@ +callBehavior("publicGetURLFor",$type,$value); + if (!$url) { + $url = $this->getBase($type); + if ($value) { + if ($url) { + $url .= '/'; + } + $url .= $value; + } + } + return $url; + } + + public function register($type,$url,$representation,$handler) + { + $core =& $GLOBALS['core']; + $t = new ArrayObject(array($type,$url,$representation,$handler)); + $core->callBehavior("publicRegisterURL",$t); + parent::register($t[0],$t[1],$t[2],$t[3]); + } + + public static function p404() + { + throw new Exception ("Page not found",404); + } + + public static function default404($args,$type,$e) + { + if ($e->getCode() != 404) { + throw $e; + } + $_ctx =& $GLOBALS['_ctx']; + $core = $GLOBALS['core']; + + header('Content-Type: text/html; charset=UTF-8'); + http::head(404,'Not Found'); + $core->url->type = '404'; + $_ctx->current_tpl = '404.html'; + $_ctx->content_type = 'text/html'; + + echo $core->tpl->getData($_ctx->current_tpl); + + # --BEHAVIOR-- publicAfterDocument + $core->callBehavior('publicAfterDocument',$core); + exit; + } + + protected static function getPageNumber(&$args) + { + if (preg_match('#(^|/)page/([0-9]+)$#',$args,$m)) { + $n = (integer) $m[2]; + if ($n > 0) { + $args = preg_replace('#(^|/)page/([0-9]+)$#','',$args); + return $n; + } + } + + return false; + } + + protected static function serveDocument($tpl,$content_type='text/html',$http_cache=true,$http_etag=true) + { + $_ctx =& $GLOBALS['_ctx']; + $core =& $GLOBALS['core']; + + if ($_ctx->nb_entry_per_page === null) { + $_ctx->nb_entry_per_page = $core->blog->settings->system->nb_post_per_page; + } + + $tpl_file = $core->tpl->getFilePath($tpl); + + if (!$tpl_file) { + throw new Exception('Unable to find template '); + } + + $result = new ArrayObject; + + $_ctx->current_tpl = $tpl; + $_ctx->content_type = $content_type; + $_ctx->http_cache = $http_cache; + $_ctx->http_etag = $http_etag; + $core->callBehavior('urlHandlerBeforeGetData',$_ctx); + + if ($_ctx->http_cache) { + $GLOBALS['mod_files'][] = $tpl_file; + http::cache($GLOBALS['mod_files'],$GLOBALS['mod_ts']); + } + + header('Content-Type: '.$_ctx->content_type.'; charset=UTF-8'); + $result['content'] = $core->tpl->getData($_ctx->current_tpl); + $result['content_type'] = $_ctx->content_type; + $result['tpl'] = $_ctx->current_tpl; + $result['blogupddt'] = $core->blog->upddt; + + # --BEHAVIOR-- urlHandlerServeDocument + $core->callBehavior('urlHandlerServeDocument',$result); + + if ($_ctx->http_cache && $_ctx->http_etag) { + http::etag($result['content'],http::getSelfURI()); + } + echo $result['content']; + } + + public function getDocument() + { + $core =& $GLOBALS['core']; + + $type = $args = ''; + + if ($this->mode == 'path_info') + { + $part = substr($_SERVER['PATH_INFO'],1); + } + else + { + $part = ''; + + $qs = $this->parseQueryString(); + + # Recreates some _GET and _REQUEST pairs + if (!empty($qs)) + { + foreach ($_GET as $k => $v) { + if (isset($_REQUEST[$k])) { + unset($_REQUEST[$k]); + } + } + $_GET = $qs; + $_REQUEST = array_merge($qs,$_REQUEST); + + list($k,$v) = each($qs); + if ($v === null) { + $part = $k; + unset($_GET[$k]); + unset($_REQUEST[$k]); + } + } + } + + $_SERVER['URL_REQUEST_PART'] = $part; + + $this->getArgs($part,$type,$this->args); + + # --BEHAVIOR-- urlHandlerGetArgsDocument + $core->callBehavior('urlHandlerGetArgsDocument',$this); + + if (!$type) + { + $this->type = 'default'; + $this->callDefaultHandler($this->args); + } + else + { + $this->type = $type; + $this->callHandler($type,$this->args); + } + } + + public static function home($args) + { + $n = self::getPageNumber($args); + + if ($args && !$n) + { + # "Then specified URL went unrecognized by all URL handlers and + # defaults to the home page, but is not a page number. + self::p404(); + } + else + { + $core =& $GLOBALS['core']; + + if ($n) { + $GLOBALS['_page_number'] = $n; + $core->url->type = $n > 1 ? 'default-page' : 'default'; + } + + if (empty($_GET['q'])) { + self::serveDocument('home.html'); + $core->blog->publishScheduledEntries(); + } else { + self::search(); + } + } + } + + public static function search() + { + $_ctx =& $GLOBALS['_ctx']; + $core =& $GLOBALS['core']; + + $core->url->type='search'; + + $GLOBALS['_search'] = !empty($_GET['q']) ? rawurldecode($_GET['q']) : ''; + if ($GLOBALS['_search']) { + $params = new ArrayObject(array('search' => $GLOBALS['_search'])); + $core->callBehavior('publicBeforeSearchCount',$params); + $GLOBALS['_search_count'] = $core->blog->getPosts($params,true)->f(0); + } + + self::serveDocument('search.html'); + } + + public static function lang($args) + { + $_ctx =& $GLOBALS['_ctx']; + $core =& $GLOBALS['core']; + + $n = self::getPageNumber($args); + $params = new ArrayObject(array( + 'lang' => $args)); + + $core->callBehavior('publicLangBeforeGetLangs',$params,$args); + + $_ctx->langs = $core->blog->getLangs($params); + + if ($_ctx->langs->isEmpty()) { + # The specified language does not exist. + self::p404(); + } + else + { + if ($n) { + $GLOBALS['_page_number'] = $n; + } + $_ctx->cur_lang = $args; + self::home(null); + } + } + + public static function category($args) + { + $_ctx =& $GLOBALS['_ctx']; + $core =& $GLOBALS['core']; + + $n = self::getPageNumber($args); + + if ($args == '' && !$n) { + # No category was specified. + self::p404(); + } + else + { + $params = new ArrayObject(array( + 'cat_url' => $args, + 'post_type' => 'post')); + + $core->callBehavior('publicCategoryBeforeGetCategories',$params,$args); + + $_ctx->categories = $core->blog->getCategories($params); + + if ($_ctx->categories->isEmpty()) { + # The specified category does no exist. + self::p404(); + } + else + { + if ($n) { + $GLOBALS['_page_number'] = $n; + } + self::serveDocument('category.html'); + } + } + } + + public static function archive($args) + { + $_ctx =& $GLOBALS['_ctx']; + $core =& $GLOBALS['core']; + + $year = $month = $cat_url = null; + # Nothing or year and month + if ($args == '') + { + self::serveDocument('archive.html'); + } + elseif (preg_match('|^/([0-9]{4})/([0-9]{2})$|',$args,$m)) + { + $params = new ArrayObject(array( + 'year' => $m[1], + 'month' => $m[2], + 'type' => 'month')); + + $core->callBehavior('publicArchiveBeforeGetDates',$params,$args); + + $_ctx->archives = $core->blog->getDates($params); + + if ($_ctx->archives->isEmpty()) { + # There is no entries for the specified period. + self::p404(); + } + else + { + self::serveDocument('archive_month.html'); + } + } + else { + # The specified URL is not a date. + self::p404(); + } + } + + public static function post($args) + { + if ($args == '') { + # No entry was specified. + self::p404(); + } + else + { + $_ctx =& $GLOBALS['_ctx']; + $core =& $GLOBALS['core']; + + $core->blog->withoutPassword(false); + + $params = new ArrayObject(array( + 'post_url' => $args)); + + $core->callBehavior('publicPostBeforeGetPosts',$params,$args); + + $_ctx->posts = $core->blog->getPosts($params); + + $_ctx->comment_preview = new ArrayObject(); + $_ctx->comment_preview['content'] = ''; + $_ctx->comment_preview['rawcontent'] = ''; + $_ctx->comment_preview['name'] = ''; + $_ctx->comment_preview['mail'] = ''; + $_ctx->comment_preview['site'] = ''; + $_ctx->comment_preview['preview'] = false; + $_ctx->comment_preview['remember'] = false; + + $core->blog->withoutPassword(true); + + if ($_ctx->posts->isEmpty()) + { + # The specified entry does not exist. + self::p404(); + } + else + { + $post_id = $_ctx->posts->post_id; + $post_password = $_ctx->posts->post_password; + + # Password protected entry + if ($post_password != '' && !$_ctx->preview) + { + # Get passwords cookie + if (isset($_COOKIE['dc_passwd'])) { + $pwd_cookie = unserialize($_COOKIE['dc_passwd']); + } else { + $pwd_cookie = array(); + } + + # Check for match + if ((!empty($_POST['password']) && $_POST['password'] == $post_password) + || (isset($pwd_cookie[$post_id]) && $pwd_cookie[$post_id] == $post_password)) + { + $pwd_cookie[$post_id] = $post_password; + setcookie('dc_passwd',serialize($pwd_cookie),0,'/'); + } + else + { + self::serveDocument('password-form.html','text/html',false); + return; + } + } + + $post_comment = + isset($_POST['c_name']) && isset($_POST['c_mail']) && + isset($_POST['c_site']) && isset($_POST['c_content']) && + $_ctx->posts->commentsActive(); + + # Posting a comment + if ($post_comment) + { + # Spam trap + if (!empty($_POST['f_mail'])) { + http::head(412,'Precondition Failed'); + header('Content-Type: text/plain'); + echo "So Long, and Thanks For All the Fish"; + # Exits immediately the application to preserve the server. + exit; + } + + $name = $_POST['c_name']; + $mail = $_POST['c_mail']; + $site = $_POST['c_site']; + $content = $_POST['c_content']; + $preview = !empty($_POST['preview']); + + if ($content != '') + { + if ($core->blog->settings->system->wiki_comments) { + $core->initWikiComment(); + } else { + $core->initWikiSimpleComment(); + } + $content = $core->wikiTransform($content); + $content = $core->HTMLfilter($content); + } + + $_ctx->comment_preview['content'] = $content; + $_ctx->comment_preview['rawcontent'] = $_POST['c_content']; + $_ctx->comment_preview['name'] = $name; + $_ctx->comment_preview['mail'] = $mail; + $_ctx->comment_preview['site'] = $site; + + if ($preview) + { + # --BEHAVIOR-- publicBeforeCommentPreview + $core->callBehavior('publicBeforeCommentPreview',$_ctx->comment_preview); + + $_ctx->comment_preview['preview'] = true; + } + else + { + # Post the comment + $cur = $core->con->openCursor($core->prefix.'comment'); + $cur->comment_author = $name; + $cur->comment_site = html::clean($site); + $cur->comment_email = html::clean($mail); + $cur->comment_content = $content; + $cur->post_id = $_ctx->posts->post_id; + $cur->comment_status = $core->blog->settings->system->comments_pub ? 1 : -1; + $cur->comment_ip = http::realIP(); + + $redir = $_ctx->posts->getURL(); + $redir .= $core->blog->settings->system->url_scan == 'query_string' ? '&' : '?'; + + try + { + if (!text::isEmail($cur->comment_email)) { + throw new Exception(__('You must provide a valid email address.')); + } + + # --BEHAVIOR-- publicBeforeCommentCreate + $core->callBehavior('publicBeforeCommentCreate',$cur); + if ($cur->post_id) { + $comment_id = $core->blog->addComment($cur); + + # --BEHAVIOR-- publicAfterCommentCreate + $core->callBehavior('publicAfterCommentCreate',$cur,$comment_id); + } + + if ($cur->comment_status == 1) { + $redir_arg = 'pub=1'; + } else { + $redir_arg = 'pub=0'; + } + + header('Location: '.$redir.$redir_arg); + } + catch (Exception $e) + { + $_ctx->form_error = $e->getMessage(); + $_ctx->form_error; + } + } + } + + # The entry + self::serveDocument('post.html'); + } + } + } + + public static function preview($args) + { + $core = $GLOBALS['core']; + $_ctx = $GLOBALS['_ctx']; + + if (!preg_match('#^(.+?)/([0-9a-z]{40})/(.+?)$#',$args,$m)) { + # The specified Preview URL is malformed. + self::p404(); + } + else + { + $user_id = $m[1]; + $user_key = $m[2]; + $post_url = $m[3]; + if (!$core->auth->checkUser($user_id,null,$user_key)) { + # The user has no access to the entry. + self::p404(); + } + else + { + $_ctx->preview = true; + self::post($post_url); + } + } + } + + public static function feed($args) + { + $type = null; + $comments = false; + $cat_url = false; + $post_id = null; + $subtitle = ''; + + $mime = 'application/xml'; + + $_ctx =& $GLOBALS['_ctx']; + $core =& $GLOBALS['core']; + + if (preg_match('!^([a-z]{2}(-[a-z]{2})?)/(.*)$!',$args,$m)) { + $params = new ArrayObject(array('lang' => $m[1])); + + $args = $m[3]; + + $core->callBehavior('publicFeedBeforeGetLangs',$params,$args); + + $_ctx->langs = $core->blog->getLangs($params); + + if ($_ctx->langs->isEmpty()) { + # The specified language does not exist. + self::p404(); + return; + } else { + $_ctx->cur_lang = $m[1]; + } + } + + if (preg_match('#^rss2/xslt$#',$args,$m)) + { + # RSS XSLT stylesheet + self::serveDocument('rss2.xsl','text/xml'); + return; + } + elseif (preg_match('#^(atom|rss2)/comments/([0-9]+)$#',$args,$m)) + { + # Post comments feed + $type = $m[1]; + $comments = true; + $post_id = (integer) $m[2]; + } + elseif (preg_match('#^(?:category/(.+)/)?(atom|rss2)(/comments)?$#',$args,$m)) + { + # All posts or comments feed + $type = $m[2]; + $comments = !empty($m[3]); + if (!empty($m[1])) { + $cat_url = $m[1]; + } + } + else + { + # The specified Feed URL is malformed. + self::p404(); + return; + } + + if ($cat_url) + { + $params = new ArrayObject(array( + 'cat_url' => $cat_url, + 'post_type' => 'post')); + + $core->callBehavior('publicFeedBeforeGetCategories',$params,$args); + + $_ctx->categories = $core->blog->getCategories($params); + + if ($_ctx->categories->isEmpty()) { + # The specified category does no exist. + self::p404(); + return; + } + + $subtitle = ' - '.$_ctx->categories->cat_title; + } + elseif ($post_id) + { + $params = new ArrayObject(array( + 'post_id' => $post_id, + 'post_type' => '')); + + $core->callBehavior('publicFeedBeforeGetPosts',$params,$args); + + $_ctx->posts = $core->blog->getPosts($params); + + if ($_ctx->posts->isEmpty()) { + # The specified post does not exist. + self::p404(); + return; + } + + $subtitle = ' - '.$_ctx->posts->post_title; + } + + $tpl = $type; + if ($comments) { + $tpl .= '-comments'; + $_ctx->nb_comment_per_page = $core->blog->settings->system->nb_comment_per_feed; + } else { + $_ctx->nb_entry_per_page = $core->blog->settings->system->nb_post_per_feed; + $_ctx->short_feed_items = $core->blog->settings->system->short_feed_items; + } + $tpl .= '.xml'; + + if ($type == 'atom') { + $mime = 'application/atom+xml'; + } + + $_ctx->feed_subtitle = $subtitle; + + header('X-Robots-Tag: '.context::robotsPolicy($core->blog->settings->system->robots_policy,'')); + self::serveDocument($tpl,$mime); + if (!$comments && !$cat_url) { + $core->blog->publishScheduledEntries(); + } + } + + public static function trackback($args) + { + if (!preg_match('/^[0-9]+$/',$args)) { + # The specified trackback URL is not an number + self::p404(); + } else { + $tb = new dcTrackback($GLOBALS['core']); + $tb->receive($args); + } + } + + public static function rsd($args) + { + $core =& $GLOBALS['core']; + http::cache($GLOBALS['mod_files'],$GLOBALS['mod_ts']); + + header('Content-Type: text/xml; charset=UTF-8'); + echo + ''."\n". + ''."\n". + "\n". + " Dotclear\n". + " http://www.dotclear.org/\n". + ' '.html::escapeHTML($core->blog->url)."\n"; + + if ($core->blog->settings->system->enable_xmlrpc) + { + $u = sprintf(DC_XMLRPC_URL,$core->blog->url,$core->blog->id); + + echo + " \n". + ' '."\n". + ' '."\n". + ' '."\n". + ' '."\n". + " \n"; + } + + echo + "\n". + "\n"; + } + + public static function xmlrpc($args) + { + $core =& $GLOBALS['core']; + $blog_id = preg_replace('#^([^/]*).*#','$1',$args); + $server = new dcXmlRpc($core,$blog_id); + $server->serve(); + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/public/prepend.php b/v2/dotclear/inc/public/prepend.php new file mode 100644 index 0000000..29bc3a9 --- /dev/null +++ b/v2/dotclear/inc/public/prepend.php @@ -0,0 +1,156 @@ +setBlog(DC_BLOG_ID); + } catch (Exception $e) { + init_prepend_l10n(); + __error(__('Database problem') + ,DC_DEBUG ? + __('The following error was encountered while trying to read the database:').'

        • '.$e->getMessage().'
        ' : + __('Something went wrong while trying to read the database.') + ,20); + } +} + +if ($core->blog->id == null) { + __error(__('Blog is not defined.') + ,__('Did you change your Blog ID?') + ,30); +} + +if ((boolean)!$core->blog->status) { + $core->unsetBlog(); + __error(__('Blog is offline.') + ,__('This blog is offline. Please try again later.') + ,70); +} + +# Loading media +try { + $core->media = new dcMedia($core); +} catch (Exception $e) {} + +# Creating template context +$_ctx = new context(); +try { + $core->tpl = new dcTemplate(DC_TPL_CACHE,'$core->tpl',$core); +} catch (Exception $e) { + __error(__('Can\'t create template files.') + ,$e->getMessage() + ,40); +} + +# Loading locales +$_lang = $core->blog->settings->system->lang; +$_lang = preg_match('/^[a-z]{2}(-[a-z]{2})?$/',$_lang) ? $_lang : 'en'; + +if (l10n::set(dirname(__FILE__).'/../../locales/'.$_lang.'/date') === false && $_lang != 'en') { + l10n::set(dirname(__FILE__).'/../../locales/en/date'); +} +l10n::set(dirname(__FILE__).'/../../locales/'.$_lang.'/public'); +l10n::set(dirname(__FILE__).'/../../locales/'.$_lang.'/plugins'); + +# Loading plugins +try { + $core->plugins->loadModules(DC_PLUGINS_ROOT,'public',$_lang); +} catch (Exception $e) {} + +# Loading themes +$core->themes = new dcThemes($core); +$core->themes->loadModules($core->blog->themes_path); + +# Defining theme if not defined +if (!isset($__theme)) { + $__theme = $core->blog->settings->system->theme; +} + +if (!$core->themes->moduleExists($__theme)) { + $__theme = $core->blog->settings->system->theme = 'default'; +} + +$__parent_theme = $core->themes->moduleInfo($__theme,'parent'); +if ($__parent_theme) { + if (!$core->themes->moduleExists($__parent_theme)) { + $__theme = $core->blog->settings->system->theme = 'default'; + $__parent_theme = null; + } +} + +# If theme doesn't exist, stop everything +if (!$core->themes->moduleExists($__theme)) { + __error(__('Default theme not found.') + ,__('This either means you removed your default theme or set a wrong theme '. + 'path in your blog configuration. Please check theme_path value in '. + 'about:config module or reinstall default theme. ('.$__theme.')') + ,50); +} + +# Loading _public.php file for selected theme +$core->themes->loadNsFile($__theme,'public'); + +# Loading translations for selected theme +if ($__parent_theme) { + $core->themes->loadModuleL10N($__parent_theme,$_lang,'main'); +} +$core->themes->loadModuleL10N($__theme,$_lang,'main'); + +# --BEHAVIOR-- publicPrepend +$core->callBehavior('publicPrepend',$core); + +# Prepare the HTTP cache thing +$mod_files = get_included_files(); +$mod_ts = array(); +$mod_ts[] = $core->blog->upddt; + +$__theme_tpl_path = array( + $core->blog->themes_path.'/'.$__theme.'/tpl' +); +if ($__parent_theme) { + $__theme_tpl_path[] = $core->blog->themes_path.'/'.$__parent_theme.'/tpl'; +} + +$core->tpl->setPath( + $__theme_tpl_path, + dirname(__FILE__).'/default-templates', + $core->tpl->getPath()); + +$core->url->mode = $core->blog->settings->system->url_scan; + +try { + # --BEHAVIOR-- publicBeforeDocument + $core->callBehavior('publicBeforeDocument',$core); + + $core->url->getDocument(); + + # --BEHAVIOR-- publicAfterDocument + $core->callBehavior('publicAfterDocument',$core); +} catch (Exception $e) { + __error($e->getMessage() + ,__('Something went wrong while loading template file for your blog.') + ,60); +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/public/rs.extension.php b/v2/dotclear/inc/public/rs.extension.php new file mode 100644 index 0000000..4c58ae3 --- /dev/null +++ b/v2/dotclear/inc/public/rs.extension.php @@ -0,0 +1,93 @@ +addBehavior('coreBlogGetPosts',array('rsExtendPublic','coreBlogGetPosts')); +$core->addBehavior('coreBlogGetComments',array('rsExtendPublic','coreBlogGetComments')); + +class rsExtendPublic +{ + public static function coreBlogGetPosts($rs) + { + $rs->extend('rsExtPostPublic'); + } + + public static function coreBlogGetComments($rs) + { + $rs->extend('rsExtCommentPublic'); + } +} + +class rsExtPostPublic extends rsExtPost +{ + public static function getContent($rs,$absolute_urls=false) + { + # Not very nice hack but it does the job :) + if (isset($GLOBALS['_ctx']) && $GLOBALS['_ctx']->short_feed_items === true) { + $_ctx =& $GLOBALS['_ctx']; + $c = parent::getContent($rs,$absolute_urls); + $c = context::remove_html($c); + $c = context::cut_string($c,350); + + $c = + '

        '.$c.'... '. + ''.__('Read').' '. + html::escapeHTML($rs->post_title).'

        '; + + return $c; + } + + if ($rs->core->blog->settings->system->use_smilies) + { + return self::smilies(parent::getContent($rs,$absolute_urls),$rs->core->blog); + } + + return parent::getContent($rs,$absolute_urls); + } + + public static function getExcerpt($rs,$absolute_urls=false) + { + if ($rs->core->blog->settings->system->use_smilies) + { + return self::smilies(parent::getExcerpt($rs,$absolute_urls),$rs->core->blog); + } + + return parent::getExcerpt($rs,$absolute_urls); + } + + protected static function smilies($c,$blog) + { + if (!isset($GLOBALS['__smilies'])) { + $GLOBALS['__smilies'] = context::getSmilies($blog); + } + return context::addSmilies($c); + } +} + +class rsExtCommentPublic extends rsExtComment +{ + public static function getContent($rs,$absolute_urls=false) + { + if ($rs->core->blog->settings->system->use_smilies) + { + $c = parent::getContent($rs,$absolute_urls); + + if (!isset($GLOBALS['__smilies'])) { + $GLOBALS['__smilies'] = context::getSmilies($rs->core->blog); + } + return context::addSmilies($c); + } + + return parent::getContent($rs,$absolute_urls); + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/inc/swf/player_flv.swf b/v2/dotclear/inc/swf/player_flv.swf new file mode 100644 index 0000000000000000000000000000000000000000..01ec373bb1f1f48fbe17200d9f01c6ae9e8f71a4 GIT binary patch literal 12975 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 \ No newline at end of file diff --git a/v2/dotclear/locales/README b/v2/dotclear/locales/README new file mode 100644 index 0000000..d021aa6 --- /dev/null +++ b/v2/dotclear/locales/README @@ -0,0 +1 @@ +Please see http://www.dotclear.org/translate diff --git a/v2/dotclear/locales/en/date.lang.php b/v2/dotclear/locales/en/date.lang.php new file mode 100644 index 0000000..d56522b --- /dev/null +++ b/v2/dotclear/locales/en/date.lang.php @@ -0,0 +1,38 @@ + \ No newline at end of file diff --git a/v2/dotclear/locales/en/date.po b/v2/dotclear/locales/en/date.po new file mode 100644 index 0000000..16faca8 --- /dev/null +++ b/v2/dotclear/locales/en/date.po @@ -0,0 +1,116 @@ +msgid "%Y-%m-%d %H:%M" +msgstr "" + +msgid "_Jan" +msgstr "Jan" + +msgid "_Feb" +msgstr "Feb" + +msgid "_Mar" +msgstr "Mar" + +msgid "_Apr" +msgstr "Apr" + +msgid "_May" +msgstr "May" + +msgid "_Jun" +msgstr "Jun" + +msgid "_Jul" +msgstr "Jul" + +msgid "_Aug" +msgstr "Aug" + +msgid "_Sep" +msgstr "Sep" + +msgid "_Oct" +msgstr "Oct" + +msgid "_Nov" +msgstr "Nov" + +msgid "_Dec" +msgstr "Dec" + +msgid "January" +msgstr "" + +msgid "February" +msgstr "" + +msgid "March" +msgstr "" + +msgid "April" +msgstr "" + +msgid "May" +msgstr "" + +msgid "June" +msgstr "" + +msgid "July" +msgstr "" + +msgid "August" +msgstr "" + +msgid "September" +msgstr "" + +msgid "October" +msgstr "" + +msgid "November" +msgstr "" + +msgid "December" +msgstr "" + +msgid "_Mon" +msgstr "Mon" + +msgid "_Tue" +msgstr "Tue" + +msgid "_Wed" +msgstr "Wed" + +msgid "_Thu" +msgstr "Thu" + +msgid "_Fri" +msgstr "Fri" + +msgid "_Sat" +msgstr "Sat" + +msgid "_Sun" +msgstr "Sun" + +msgid "Monday" +msgstr "" + +msgid "Tuesday" +msgstr "" + +msgid "Wednesday" +msgstr "" + +msgid "Thursday" +msgstr "" + +msgid "Friday" +msgstr "" + +msgid "Saturday" +msgstr "" + +msgid "Sunday" +msgstr "" diff --git a/v2/dotclear/locales/en/help/blog_pref.html b/v2/dotclear/locales/en/help/blog_pref.html new file mode 100644 index 0000000..487a4f2 --- /dev/null +++ b/v2/dotclear/locales/en/help/blog_pref.html @@ -0,0 +1,148 @@ + + + Blog settings + + + + +

        Blog details

        +
        +
        Blog ID
        +
        Unique ID of the blog. Mandatory, can only be modified by a super administrator.
        + +
        Blog name
        +
        Name of the blog, mandatory.
        + +
        Blog URL
        +
        Complete blog URL. Mandatory, can only be modified by a super administrator.
        + +
        Blog status
        +
        +
          +
        • online: blog open to visitors
        • +
        • offline: blog closed to visitors + but open to writers.
        • +
        • removed: blog closed to both visitors and writers.
        • +
        +
        + +
        Blog description
        +
        Here you can put any description you want for your blog. This is a + simple text, without formatting.
        +
        + +

        Blog configuration

        +
        +
        Blog editor's name
        +
        Name of the person responsible for the blog. It may be the owner or the + publisher if he exists.
        + +
        Copyright notice
        +
        Note about the reproduction rights for the blog.
        + +
        Default language
        +
        Language of the blog interface. Either this language is among the avalaible ones, + and the interface will be translated, or it is not, and the interface will then + default to English.
        + +
        Blog timezone
        +
        Defines the timezone that will be used for comments and trackbacks.
        + +
        Date formats
        +
        The date format of the blog posts. See the date and time + format reference section below for further details.
        + +
        Time format
        +
        The time format of the blog posts. See the date and time + format reference section below for further details.
        + +
        Display .. entries per page
        +
        The number will be used as the limit for the number of entries + on the homepage, the first page of each category and the rss feeds.
        + +
        Leave comments open for .. days
        +
        The number of days during wich comments and trackbacks will be open + after the post publication. When empty, the comments will be kept open + indefinitly.
        + +
        Display smilies on entries and comments
        +
        Display sequences of characters as :-) or ;-) as images.
        + +
        Accept comments
        +
        Globally accepts comments on the blog. Takes precedence over the + per post setting.
        + +
        Accept trackbacks
        +
        Globally accepts trackbacks on the blog. Takes precedence over the + per post setting.
        + +
        Moderate comments and trackbacks
        +
        With such an option, comments and trackbacks will be published after + editor agreement.
        + +
        Add "nofollow" relation on comments and trackbacks links
        +
        Adds an attribute on inks in comments and trackbacks, instructing the + search bots not to follow them. This antispam features has yet to + prove its value.
        + +
        Wiki syntax for comments
        +
        Allows a subset of the wiki syntax to be used in comments.
        +
        + +

        Format reference

        +

        Some fields can be configured to format the date and time to your needs. +Here is a reference:

        + +
          +
        • %a: abreviated week day (local).
        • +
        • %A: complete week day (local).
        • +
        • %b: abbreviated month name (local).
        • +
        • %B: complete month name (local).
        • +
        • %c: default local date and time display.
        • +
        • %C: century (the year, divided by 100 and + round up beetween 00 and 99)
        • +
        • %d: numeric month day (from 01 to 31)
        • +
        • %D: identical to %m/%d/%y
        • +
        • %e: numeric month day (from 1 to 31)
        • +
        • %g: identical to %G, 2 digits.
        • +
        • %G: The year on 4 digits, according to the week number + (cf. %V). Format and value identical to %Y, except that if the number of the + week belongs to the preceding or following year, the current year + will be used instead.
        • +
        • %h: identical to %b
        • +
        • %H: digital hour of the day, 24H mode + (from 00 to 23)
        • +
        • %I: digital hour of the day, 12H mode + (from 01 to 12)
        • +
        • %j: day of the year, digital (from 001 to 366)
        • +
        • %m: month, digital (from 1 à 12)
        • +
        • %M: minute, digital
        • +
        • %n: newline character
        • +
        • %p: either `am' or `pm', according to the absolute time, + or depending of the local settings.
        • +
        • %r: the hour, a.m. and p.m. format
        • +
        • %R: the hour, 24h format
        • +
        • %S: seconds, digital
        • +
        • %t: tab character
        • +
        • %T: the current time (identical to %H:%M:%S)
        • +
        • %u: day week, digit, from 1 to 7. (1 stands for monday)
        • +
        • %U: week number, the first sundqy of the year being the + first day of the first week.
        • +
        • %V: the week numpber as defined in ISO + 8601:1988, digital, from 01 to 53. The week 1 is the first week + with more than 4 days in the current year, whose monday is the first day. + (Use %G or %g for the year elements corresponding to the number of the + week for the considered timestamp.)
        • +
        • %W: number of the week in the year, the first monday of + the year being the start of the first week
        • +
        • %w: day of the week, digital, 0 stands for sunday
        • +
        • %x: prefered format for the date without the time
        • +
        • %X: prefered format for the time without the date
        • +
        • %y: the year, two digits (from 00 to 99)
        • +
        • %Y: the year, four digits
        • +
        • %Z ou %z: timezone, name or abbreviation
        • +
        • %%: a litteral `%' character
        • +
        + + + \ No newline at end of file diff --git a/v2/dotclear/locales/en/help/categories.html b/v2/dotclear/locales/en/help/categories.html new file mode 100644 index 0000000..becd08f --- /dev/null +++ b/v2/dotclear/locales/en/help/categories.html @@ -0,0 +1,47 @@ + + + Categories + + + +

        Categories list

        +
        +
        Create a new category
        +
        Choose the name you wish to use for your new category + then click on Save to validate its creation. you may leave it at the first level or choose its parent. + To modify your category, click on its name in the list.
        + +
        Delete a category
        +
        Choose the category you wish to delete in the selection menu and click ok. + A category can be deleted only if it contains no posts.
        + +
        Reorder categories
        +
        Use this option to place all categories at the same level. + If you wish to reorder a category respectively to other categories, + click on its name and choose its parent and its position respectively to its siblings.
        +
        + +

        Modifying a category

        +
        +
        Title
        +
        Choose the name you wish to give to your category + the click on Save to validate.
        + +
        URL
        +
        DotClear creates a default url for the category, making it reachable + with a path similar to this one : + http://monblog.tld/category/My-category. You can click + on the small lock on the right to modify it according to your needs.
        + +
        Description
        +
        What's inside the description field will be shown when selecting + one of the blog's categories. You can fill it with any kind of content + (paragraphs, lists, etc.) The format used for this field is HTML.
        + +
        Move this category
        +
        You can move the category as a child of any other by choosing its parent. + You can also specify the category position respectively to its siblings by placing it before or after any of them.
        +
        + + + \ No newline at end of file diff --git a/v2/dotclear/locales/en/help/comments.html b/v2/dotclear/locales/en/help/comments.html new file mode 100644 index 0000000..83338f2 --- /dev/null +++ b/v2/dotclear/locales/en/help/comments.html @@ -0,0 +1,58 @@ + + + Comments + + + +

        Filters for comment list

        +
        +
        Type:
        +
        None, comments or trackbacks.
        + +
        Status:
        +
          +
        • junk:
        • +
        • pending:
        • +
        • unpublished: offline ;
        • +
        • published: online.
        • +
        + +
        Order by:
        +
        Choose: date, entry title, author or status, then + choose the sort order.
        + +
        Sort
        +
        Choose whether the list will be sorted in ascending or descending order.
        + +
        Comment author.
        +
        The search is not case sensitive. If you want to search only a part of + the name, you can use the * generic character.
        + +
        Comments per page :
        +
        Allows you to choose the number of comments on each page of this list.
        +
        + +

        Modify or add a comment

        +
        +
        Author:
        +
        Author name. This field is mandatory.
        + +
        Email:
        +
        Author's email address.
        + +
        Web site:
        +
        URL of the comment author's blog or website.
        + +
        Status:
        +
          +
        • junk:
        • +
        • pending:
        • +
        • unpublished: offline
        • +
        • published: online
        • +
        + +
        Comment:
        +
        Comment's content. This field is html formated.
        +
        + + diff --git a/v2/dotclear/locales/en/help/media.html b/v2/dotclear/locales/en/help/media.html new file mode 100644 index 0000000..052f40f --- /dev/null +++ b/v2/dotclear/locales/en/help/media.html @@ -0,0 +1,90 @@ + + + Media manager + + + + +

        Media list

        +

        The media manager's main page displays a list of available files (medias) +for the currently selected blog.

        + +

        You can click the icons or names of the medias in the folder or any +subfolder to display them.

        + +

        Selecting a MP3 sound file displays a player to immediately play +the file. The Flash plugin must be installed on your browser for +this player to operate.

        + +

        The images are displayed with a thumbnail when possible.

        + +

        Add files

        +
        +
        Choose a file
        +
        Here you can select one of your local files to send it on your + blog. Should the file be bigger than the maximum size, it will not be sent.
        + +
        Title
        +
        Optional title for the file you want to send.
        + +
        Private
        +
        Check this if you want the file to be private, i.e. accessible only by + its owner and not accessible from the blog.
        +
        + +

        New folder

        +

        This form allows you to create an new subfolder in the currently displayed +folder. Just choose a name for it as you would do on your own computer.

        + +

        Media details

        +

        This page displays a set of informations about the currently selected +file and allows you to perform a few operations.

        + +
        +
        File name
        +
        Change the file name of the current file.
        + +
        File title
        +
        Give a title to the file, or change the current one.
        + +
        File date
        +
        Change the file date.
        + +
        Private
        +
        Specify that the file will be hidden to anyone but its owner in the media manager.
        + +
        New directory
        +
        Allows you to move the file in another folder.
        + +
        Change file
        +
        With this form, you can replace the file while keeping all the attributes + (name, title...). As always, you have to respect the maximum file size.
        +
        + +

        A specific treatment for images

        +

        When you add an image, depending of its size, up to four versions will be made available:

        +
          +
        • square: a 48x48 pixels square thumbnail,
        • +
        • thumbnail: the image reduced to 100 pixels on its longest side.
        • +
        • small: the longuest side is reduced to 240 pixels.
        • +
        • medium: the longuest side is reduced to 500 pixels.
        • +
        • original: the original, unchanged image.
        • +
        +

        Default size for the versions thumbnail, small and medium can be modified in your blog's parameters.

        + +

        Add a file to an entry

        +

        You can easily attach a file to one of your posts. First, create a new post +and save it. Then click on "Add files to this entry" to open the media manager.

        + +

        Just click on the [+] icon (Attach this file to entry). The file will then +be attached to the post.

        + +

        The attached files will be shown on the post page, as a list beside the post content. +The MP3 files will be made available through the Flash player, so that they can easily by read by visitors.

        + +

        Podcast and broadcasting of music files

        +

        All attached files will be included in your RSS feeds, allowing for easy +podcasting of any type of file.

        + + + \ No newline at end of file diff --git a/v2/dotclear/locales/en/help/post.html b/v2/dotclear/locales/en/help/post.html new file mode 100644 index 0000000..8fa872b --- /dev/null +++ b/v2/dotclear/locales/en/help/post.html @@ -0,0 +1,125 @@ + + + Editing an entry + + + + +

        Editing an entry

        + +
        +
        Entry title
        +
        Type in the entry title. This field is mandatory.
        + +
        Excerpt
        +
        The content of this field will be shown in pages showing entries as + a list, such as the homepage or categories pages, followed by a "continue reading" + link. It will also be visible at the begining of the page showing the + whole post. Should you leave it blank, the content field will be shown + on the homepage and other entry list pages.
        + +
        Content
        +
        The content of your entry. This field is mandatory.
        + +
        Notes
        +
        This text area is for personal use, for notes or memos. What you enter here + will never be displayed on the blog..
        + +
        Category
        +
        Your entry's category. To create a new category, please see the + "categories" section. You can choose to leave + you entry without a category by selecting the blank line.
        + +
        Entry status
        +
        Allows you to choose your post's status: +
          +
        • pending: the publication status has not yet been decided.
        • +
        • scheduled: the post will be set online at the time and date + set in the Published on field.
        • +
        • unpublished: the post is offline.
        • +
        • published: the post is online.
        • +
        +
        + +
        Published on
        +
        Here you can change the post's publication date and time. If the post's + status is scheduled, it will come online at the said date and time.
        + +
        Text formating
        +
        To choose the post syntax. Wiki is a simplified syntax + and will be converted to valid xhtml ; Unless you have a perfect + understanding of xhtml, we advise you to choose the wiki syntax. + See the Wiki syntax reference for more information.
        + +
        Accept comments
        +
        Select this box to allow your visitors to comment the entry. The corresponding + global setting is to be found in the blog settings.
        + +
        Accept trackbacks
        +
        A trackback is a way to let a portion of your entry as a comment on + another blog. Select this box to allow others to trackback your entry. The + corresponding global setting is to be found in the blog settings.
        + +
        Selected entry
        +
        The selected entries will be listed on your blog menu, under the title "Best + of me".
        + +
        Entry password
        +
        You can enter a password for your entry. A password protected entry will + not be displayed on your blog, it will only be reachable to those you will + give the entry url (see the view entry link) and password.
        + +
        Basename
        +
        By clicking on its lock, you can unprotect this field and and choose another + URL for your entry. If the URL you're trying to use is already used by another + entry, a number will be added to it.
        + +
        Entry lang.
        +
        The two character language code of your entry. It defaults to your (as a + user) language but you can change it to whatever language code you want, ie. + "en" or "fr-qc". This code is used for the entry's display, no chack is made + on it.
        + +
        Attachments
        +
        The attachments are all the medias you joined to the entry. The link add + file to this entry allows you to attach other files to the entry. Remember + to save your changes before clicking on this link. For further information, + see the media manager help.
        +
        + +

        Trackback

        +

        To make a trackback, click on the Ping blogs link. +You will not see this link if your entry's status is not published.

        + +
        +
        URLs to ping
        +
        Paste here the trackback URLs you found in the posts you want to ping.
        + + +
        Send excerpt
        +
        This field defaults to your entry's first few sentences. That's wht will be + sent to the blog you're pinging, along with a link to your post. You can modify + the excerpt by editing this field.
        + + +
        Auto discover ping URLs
        +
        If your entries links specific posts and if the blog carrying those posts + is set to allow it, this tool will find the URLs to ping for you.
        +
        + +

        Comments

        +
        +
        Comment list
        +
        On the Comments tab, you can read and change the status of + your entry's comments. If you're allowed to by the blog administrator, + you will be able to set your comments online or offline, to delete them or + to mark them as junk.
        + +
        Add a comment
        +
        On the Add a comment tab, you can reply to one of your entry's + comments without leaving your blog's backend. The syntax to be used here is + plain, unlimited, xhtml. Use the fields as if you were modifying a comment.
        +
        + + + diff --git a/v2/dotclear/locales/en/help/posts.html b/v2/dotclear/locales/en/help/posts.html new file mode 100644 index 0000000..82730c6 --- /dev/null +++ b/v2/dotclear/locales/en/help/posts.html @@ -0,0 +1,65 @@ + + + Managing entries + + + + +

        Filters for the entry list

        + +
        +
        Author
        +
        Allows you to filter by author.
        + +
        Category
        +
        Filter by category.
        + +
        Status
        +
          +
        • pending: posts whose publication status has not yet + been decided.
        • +
        • scheduled: post to be set online automatically.
        • +
        • unpublished: offline posts.
        • +
        • published: online posts.
        • +
        + +
        Selected
        +
        Only the selected posts, or the non selected ones.
        + +
        Month
        +
        Filter on a specific month and year.
        + +
        Language
        +
        Filter on the different languages used on the blog.
        + +
        Order by
        +
        Defines the list order, either on the date, the title, the author, + the status or the selected status.
        + +
        Sort
        +
        Choose whether the list will be sorted in ascending or descending order.
        + +
        Entries per page
        +
        Number of entries that will be displayed on each page of the resulting + set.
        +
        + +

        Selected entry actions

        +

        If your user permission level allows it, you can perform batch operations on the +entries you select in the list.

        + +
          +
        • Publish: set the entries online.
        • +
        • Unpublish: set the entries offline.
        • +
        • Schedule: schedule the entries to be set online at their + publication date.
        • +
        • Mark as pending: erase other publication status.
        • +
        • Change category: directs you to the category list to choose a + new one for the entries.
        • +
        • Change author: allows you to change the posts' author by + entering the new author's ID.
        • +
        • Delete: suppress the posts (this operation cannot be undone).
        • +
        + + + diff --git a/v2/dotclear/locales/en/help/user.html b/v2/dotclear/locales/en/help/user.html new file mode 100644 index 0000000..fb9283c --- /dev/null +++ b/v2/dotclear/locales/en/help/user.html @@ -0,0 +1,71 @@ + + + User + + + + +

        User information

        +
        +
        User name
        +
        At least 2 characters (non accentuated characters, numbers or symbols, no white space. This field is mandatory.
        + +
        Password
        +
        Write down twice your password in the fields Password and Confirm password. The minimal password length is 6 characters. + These two fields are mandatory.
        + +
        Name, First name
        +
        If the display name is empty, the author's name will be displayed + as his Firstname and Name as set here.
        + +
        Display name
        +
        You can choose here a nickname that will be displayed in your posts instead of your name and first name.
        + +
        Email
        +
        Address that will be used to send a new password on dotclear's new password generation page.
        + +
        URL
        +
        The user's web site. If set, the author name will be displayed as + a link to the said site.
        + +
        Preferred format
        +
        To choose the prefered post syntax. Wiki is a simplified syntax + and will be converted to valid xhtml ; Unless you have a perfect + understanding of html, we advise you to choose the wiki syntax.
        + +
        Default entry status
        +
        The default entry status can be set to: +
          +
        • pending: the publication status has not yet been decided.
        • +
        • scheduled: the post will be set online at the time and date + set in the Published on field.
        • +
        • unpublished: the post is offline.
        • +
        • published: the post is online.
        • +
        +
        + +
        Entry edit field height
        +
        The height of the Entry edit field. Defaults to 24.
        + +
        User language
        +
        The language in wich one publishes his posts. If the translation exists, + the interface will also be displayed in that language.
        + +
        User timezone
        +
        That choice will define the time displayed on post publication.
        + +
        Password change required to connect
        +
        Check this box to force the new user to change his password on login.
        + +
        Super administrator
        +
        This choice will give all permissions to the user on all of your installation's blogs.
        +
        + +

        Tags

        +
        +
        Tags list format
        +
        This choice allows, in post editing page, to display all available tags + or only most used ones.
        +
        + + \ No newline at end of file diff --git a/v2/dotclear/locales/en/help/user_pref.html b/v2/dotclear/locales/en/help/user_pref.html new file mode 100644 index 0000000..a6de71b --- /dev/null +++ b/v2/dotclear/locales/en/help/user_pref.html @@ -0,0 +1,84 @@ + + + User preferences + + + + +

        My profile

        +
        +
        Name, First name
        +
        If the display name is empty, the author's name will be displayed + as his Firstname and Name as set here.
        + +
        Display name
        +
        You can choose here a nickname that will be displayed in your posts instead of your name and first name.
        + +
        Email
        +
        Address where will be sent the new comment notifications.
        + +
        URL
        +
        The user's web site. If set, the author name will be displayed as + a link to the said site.
        + +
        User language
        +
        The language in wich one publishes his posts. If the translation exists, + the interface will also be displayed in that language.
        + +
        User timezone
        +
        That choice will define the time displayed on post publication.
        + +
        Change your password
        +
        To change your password, write down twice your password in the fields + New password and Confirm password. The minimal password length is 6 characters. + If no new password is provided, the current one is kept.
        +
        +

        My options

        +
        +
        Preferred format
        +
        To choose the prefered post syntax. Wiki is a simplified syntax + and will be converted to valid xhtml ; Unless you have a perfect + understanding of html, we advise you to choose the wiki syntax.
        + +
        Default entry status
        +
        The default entry status can be set to: +
          +
        • pending: the publication status has not yet been decided.
        • +
        • scheduled: the post will be set online at the time and date + set in the Published on field.
        • +
        • unpublished: the post is offline.
        • +
        • published: the post is online.
        • +
        +
        + +
        Entry edit field height
        +
        The height of the Entry edit field. Defaults to 24.
        + +
        Enable WYSIWYG mode
        +
        Allow the use of the WYSIWYG editor for the posts and description fields.
        + +
        Activate enhanced uploader in media manager
        +
        This option allows you to upload several files at the same time on your server. + Needs the presence of Flash plugin in your browser.
        + +
        Dashboard modules
        +
        Choices made in this zone will be reflected on your blog's dashboard.
        + +
        Tags list format
        +
        This choice allows, in post editing page, to display all available tags + or only most used ones.
        +
        +

        My favorites

        +
        +
        My favorites
        +
        This zone displays the chosen favorites on the blog's dashboard. + They can be reordered with your mouse if javascript is activated in your browser. + Otherwise, a field allows to give them an ordering number. When you are finished, do not forget + to save your changes. You may also select favorites to be deleted from the list.
        + +
        Available favorites
        +
        All plugins allowing to be put as favorites are diplayed here. Check the corresponding boxes + and add them to the dashboard.
        +
        + + \ No newline at end of file diff --git a/v2/dotclear/locales/en/help/wiki.html b/v2/dotclear/locales/en/help/wiki.html new file mode 100644 index 0000000..3bf005e --- /dev/null +++ b/v2/dotclear/locales/en/help/wiki.html @@ -0,0 +1,85 @@ + + + Wiki syntax reference + + + + +

        Wiki syntax reference

        + +

        The wiki syntax is a way to enhance your text with a minimal set +of tags, studied to cover the basic needs (titles, paragraphs, quotes, +lists...)

        + +
        +
        Block elements
        +
        +
          +
        • Leave an empty line between two similar blocks.
        • +
        • Paragraph: free text, ended by an empty line if + another paragraph is to follow.
        • +
        • Title: !!! title, !! title + or ! title, allowing you to use three different levels of + heading.
        • +
        • Horizontal line: ----
        • +
        • Lists: Start each line with + * or # for unnumbered or numbered lists respectively. + List imbrication is done by mixing list markers this way: +
          +* item 1
          +** item 1.1
          +* item 2
          +*# item 2.1
          +...
          +
          +
        • +
        • Preformatted text: each line must start with a space.
        • +
        • Block quote: each line must start with a semicolon (>).
        • +
        +
        + +
        Formatting tags
        +
        +
          +
        • Emphasis: two quotes ''text''
        • +
        • Strong emphasis: two underscore __text__
        • +
        • New line: %%%
        • +
        • Insertion: two plusses ++text++
        • +
        • Deletion: two minuses --text--
        • +
        • Link: [url], [name|url], + [name|url|language] or [name|url|languagee|title]
        • +
        • Image: + ((url|alternative text)), + ((url|alternative text|position)) or + ((url|alternative text|position|long description)). +
          The position can be either L or G (left), R or D (right) or C (centered).
        • +
        • Anchor: ~anchor~
        • +
        • Acronym: ??acronym|title??
        • +
        • Inline HTML: two backquotes ``html code``
        • +
        • Inline quote: {{quote}}, + {{quote|language}} or {{quote|language|url}}
        • +
        • Code: @@code@@
        • +
        • Footnotes: $$footnote$$
        • +
        +
        + +
        Unformatted text
        +
        If you don't want one formatting character to be interpreted as such, add a +\ just before it. This way: +\[text in brackets without being a link\] +
        + +
        HTML Code
        +
        Even if you chose the wiki syntax, you may sometimes need a more +powerful formatting, i.e. HTML syntax. Do it the following way: +
        +///html
        +<p style="color:red">my text in red</p>
        +///
        +
        +
        +
        + + + + diff --git a/v2/dotclear/locales/en/main.lang.php b/v2/dotclear/locales/en/main.lang.php new file mode 100644 index 0000000..5b13df9 --- /dev/null +++ b/v2/dotclear/locales/en/main.lang.php @@ -0,0 +1,19 @@ + \ No newline at end of file diff --git a/v2/dotclear/locales/en/main.po b/v2/dotclear/locales/en/main.po new file mode 100644 index 0000000..39c6cfd --- /dev/null +++ b/v2/dotclear/locales/en/main.po @@ -0,0 +1,2785 @@ +# SOME DESCRIPTIVE TITLE. +# This file is put in the public domain. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: Dotclear 2\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-11-06 18:11+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "Dotclear has been upgraded." +msgstr "" + +msgid "Password reset" +msgstr "" + +msgid "Someone has requested to reset the password for the following site and username." +msgstr "" + +msgid "Username:" +msgstr "" + +msgid "To reset your password visit the following address, otherwise just ignore this email and nothing will happen." +msgstr "" + +#, php-format +msgid "The e-mail was sent successfully to %s." +msgstr "" + +msgid "Your new password" +msgstr "" + +msgid "Password:" +msgstr "" + +msgid "Your new password is in your mailbox." +msgstr "" + +msgid "Passwords don't match" +msgstr "" + +msgid "You didn't change your password." +msgstr "" + +msgid "You have to change your password before you can login." +msgstr "" + +msgid "In order to login, you have to change your password now." +msgstr "" + +msgid "Safe Mode can only be used for super administrators." +msgstr "" + +msgid "Wrong username or password" +msgstr "" + +msgid "Back to login screen" +msgstr "" + +msgid "Request a new password" +msgstr "" + +msgid "Email:" +msgstr "" + +msgid "recover" +msgstr "" + +msgid "Change your password" +msgstr "" + +msgid "New password:" +msgstr "" + +msgid "Confirm password:" +msgstr "" + +msgid "change" +msgstr "" + +msgid "Safe mode login" +msgstr "" + +msgid "This mode allows you to login without activating any of your plugins. This may be useful to solve compatibility problems" +msgstr "" + +msgid "Disable or delete any plugin suspected to cause trouble, then log out and log back in normally." +msgstr "" + +msgid "Remember my ID on this computer" +msgstr "" + +msgid "log in" +msgstr "" + +msgid "You must accept cookies in order to use the private area." +msgstr "" + +msgid "Get back to normal authentication" +msgstr "" + +msgid "Connection issue?" +msgstr "" + +msgid "I forgot my password" +msgstr "" + +msgid "I want to log in in safe mode" +msgstr "" + +msgid "New blog" +msgstr "" + +msgid "Blogs" +msgstr "" + +msgid "Blog ID:" +msgstr "" + +msgid "Required field" +msgstr "" + +msgid "At least 2 characters using letters, numbers or symbols." +msgstr "" + +msgid "Please note that changing your blog ID may require changes in your public index.php file." +msgstr "" + +msgid "Blog name:" +msgstr "" + +msgid "Blog URL:" +msgstr "" + +msgid "Blog description:" +msgstr "" + +msgid "Create" +msgstr "" + +msgid "No such blog ID" +msgstr "" + +msgid "Password verification failed" +msgstr "" + +msgid "Delete a blog" +msgstr "" + +msgid "Warning" +msgstr "" + +#, php-format +msgid "You are about to delete the blog %s. Every entry, comment and category will be deleted." +msgstr "" + +msgid "Please give your password to confirm the blog deletion." +msgstr "" + +msgid "Your password:" +msgstr "" + +msgid "Delete this blog" +msgstr "" + +msgid "No given blog id." +msgstr "" + +msgid "No such blog." +msgstr "" + +msgid "year/month/day/title" +msgstr "" + +msgid "year/month/title" +msgstr "" + +msgid "year/title" +msgstr "" + +msgid "title" +msgstr "" + +msgid "Title" +msgstr "" + +msgid "Title, Date" +msgstr "" + +msgid "Title, Country, Date" +msgstr "" + +msgid "Title, City, Country, Date" +msgstr "" + +msgid "I would like search engines and archivers to index and archive my blog's content." +msgstr "" + +msgid "I would like search engines and archivers to index but not archive my blog's content." +msgstr "" + +msgid "I would like to prevent search engines and archivers from indexing or archiving my blog's content." +msgstr "" + +msgid "That blog Id is already in use." +msgstr "" + +msgid "Invalid language code" +msgstr "" + +msgid "Blog settings" +msgstr "" + +msgid "Warning: except for special configurations, it is generally advised to have a trailing \"/\" in your blog URL in PATH_INFO mode." +msgstr "" + +msgid "Warning: except for special configurations, it is generally advised to have a trailing \"?\" in your blog URL in QUERY_STRING mode." +msgstr "" + +msgid "Blog has been successfully created." +msgstr "" + +msgid "Blog has been successfully updated." +msgstr "" + +msgid "Parameters" +msgstr "" + +msgid "Blog details" +msgstr "" + +msgid "URL scan method:" +msgstr "" + +msgid "Blog status:" +msgstr "" + +msgid "Blog configuration" +msgstr "" + +msgid "Blog editor name:" +msgstr "" + +msgid "Default language:" +msgstr "" + +msgid "Blog timezone:" +msgstr "" + +msgid "Copyright notice:" +msgstr "" + +msgid "New post URL format:" +msgstr "" + +msgid "Enable XML/RPC interface" +msgstr "" + +msgid "more information" +msgstr "" + +msgid "Comments and trackbacks" +msgstr "" + +msgid "Accept comments" +msgstr "" + +msgid "Moderate comments" +msgstr "" + +#, php-format +msgid "Leave comments open for %s days" +msgstr "" + +msgid "Leave blank to disable this feature." +msgstr "" + +msgid "Wiki syntax for comments" +msgstr "" + +msgid "Accept trackbacks" +msgstr "" + +msgid "Moderate trackbacks" +msgstr "" + +#, php-format +msgid "Leave trackbacks open for %s days" +msgstr "" + +msgid "Add \"nofollow\" relation on comments and trackbacks links" +msgstr "" + +msgid "Blog presentation" +msgstr "" + +msgid "Date format:" +msgstr "" + +msgid "Time format:" +msgstr "" + +msgid "Display smilies on entries and comments" +msgstr "" + +#, php-format +msgid "Display %s entries per page" +msgstr "" + +#, php-format +msgid "Display %s entries per feed" +msgstr "" + +#, php-format +msgid "Display %s comments per feed" +msgstr "" + +msgid "Truncate feeds" +msgstr "" + +msgid "Media and images" +msgstr "" + +msgid "Generated image sizes (in pixels)" +msgstr "" + +msgid "Thumbnails:" +msgstr "" + +msgid "Small:" +msgstr "" + +msgid "Medium:" +msgstr "" + +msgid "Inserted image title" +msgstr "" + +msgid "This defines image tag title when you insert it in a post from the media manager. It is retrieved from the picture's metadata." +msgstr "" + +msgid "Search engines robots policy" +msgstr "" + +msgid "Save" +msgstr "" + +msgid "XML/RPC interface" +msgstr "" + +msgid "XML/RPC interface allows you to edit your blog with an external client." +msgstr "" + +msgid "XML/RPC interface is not active. Change settings to enable it." +msgstr "" + +msgid "XML/RPC interface is active. You should set the following parameters on your XML/RPC client:" +msgstr "" + +msgid "Server URL:" +msgstr "" + +msgid "Blogging system:" +msgstr "" + +msgid "User name:" +msgstr "" + +msgid "your password" +msgstr "" + +msgid "Users" +msgstr "" + +msgid "Users on this blog" +msgstr "" + +msgid "No users" +msgstr "" + +msgid "Change permissions" +msgstr "" + +msgid "Super administrator" +msgstr "" + +msgid "You can't remove default theme." +msgstr "" + +msgid "Theme does not exist." +msgstr "" + +msgid "Unable to move uploaded file." +msgstr "" + +msgid "An error occurred while downloading the file." +msgstr "" + +#, php-format +msgid "by %s" +msgstr "" + +#, php-format +msgid "version %s" +msgstr "" + +#, php-format +msgid "(built on \"%s\")" +msgstr "" + +#, php-format +msgid "(requires \"%s\")" +msgstr "" + +msgid "Stylesheet" +msgstr "" + +msgid "Configure theme" +msgstr "" + +msgid "Blog appearance" +msgstr "" + +msgid "Theme has been successfully changed." +msgstr "" + +msgid "Theme has been successfully installed." +msgstr "" + +msgid "Theme has been successfully upgraded" +msgstr "" + +msgid "Theme has been successfully deleted." +msgstr "" + +#, php-format +msgid "You can find additional themes for your blog on %s." +msgstr "" + +msgid "To install or upgrade a theme you generally just need to upload it in \"Install or upgrade a theme\" section." +msgstr "" + +msgid "Themes" +msgstr "" + +#, php-format +msgid "You are currently using \"%s\"" +msgstr "" + +msgid "Use selected theme" +msgstr "" + +msgid "Delete selected theme" +msgstr "" + +msgid "Install or upgrade a theme" +msgstr "" + +msgid "You can install themes by uploading or downloading zip files." +msgstr "" + +msgid "Upload a zip file" +msgstr "" + +msgid "Theme zip file:" +msgstr "" + +msgid "Upload theme" +msgstr "" + +msgid "Download a zip file" +msgstr "" + +msgid "Theme zip file URL:" +msgstr "" + +msgid "Download theme" +msgstr "" + +msgid "To enable this function, please give write access to your themes directory." +msgstr "" + +msgid "Theme configuration" +msgstr "" + +msgid "back" +msgstr "" + +msgid "Last update" +msgstr "" + +msgid "Blog name" +msgstr "" + +msgid "Blog ID" +msgstr "" + +msgid "Descending" +msgstr "" + +msgid "Ascending" +msgstr "" + +msgid "List of blogs" +msgstr "" + +msgid "Blog has been successfully deleted." +msgstr "" + +msgid "Create a new blog" +msgstr "" + +msgid "Filters" +msgstr "" + +msgid "Order by:" +msgstr "" + +msgid "Sort:" +msgstr "" + +msgid "Search:" +msgstr "" + +msgid "Blogs per page" +msgstr "" + +msgid "Apply filters" +msgstr "" + +msgid "No blog" +msgstr "" + +msgid "Page(s)" +msgstr "" + +msgid "Entries" +msgstr "" + +msgid "Status" +msgstr "" + +#, php-format +msgid "Edit blog %s" +msgstr "" + +msgid "edit" +msgstr "" + +#, php-format +msgid "Switch to blog %s" +msgstr "" + +msgid "This category does not exist." +msgstr "" + +msgid "Categories" +msgstr "" + +msgid "The category has been successfully created." +msgstr "" + +msgid "The category has been successfully removed." +msgstr "" + +msgid "Categories have been successfully reordered." +msgstr "" + +msgid "The category has been successfully moved." +msgstr "" + +msgid "No category yet." +msgstr "" + +msgid "Categories list" +msgstr "" + +#, php-format +msgid "%d entries" +msgstr "" + +#, php-format +msgid "%d entry" +msgstr "" + +msgid "total:" +msgstr "" + +msgid "URL:" +msgstr "" + +msgid "Add a new category" +msgstr "" + +msgid "Title:" +msgstr "" + +msgid "Parent:" +msgstr "" + +msgid "Top level" +msgstr "" + +msgid "Remove a category" +msgstr "" + +msgid "Choose a category to remove:" +msgstr "" + +msgid "Delete" +msgstr "" + +msgid "Reorder categories" +msgstr "" + +msgid "This will relocate all categories on the top level" +msgstr "" + +msgid "Reorder" +msgstr "" + +msgid "New category" +msgstr "" + +msgid "Category has been successfully updated." +msgstr "" + +msgid "Category information" +msgstr "" + +msgid "Warning: If you set the URL manually, it may conflict with another category." +msgstr "" + +msgid "Description:" +msgstr "" + +msgid "Move this category" +msgstr "" + +msgid "Category parent" +msgstr "" + +msgid "Category sibling" +msgstr "" + +msgid "Move current category" +msgstr "" + +msgid "after" +msgstr "" + +msgid "before" +msgstr "" + +msgid "position: " +msgstr "" + +msgid "Entry does not exist." +msgstr "" + +msgid "No comment" +msgstr "" + +msgid "You can't edit this comment." +msgstr "" + +msgid "Edit comment" +msgstr "" + +msgid "Comment has been successfully updated." +msgstr "" + +#, php-format +msgid "Your comment on my blog %s" +msgstr "" + +#, php-format +msgid "" +"Hi!\n" +"\n" +"You wrote a comment on:\n" +"%s\n" +"\n" +"\n" +msgstr "" + +msgid "Send an e-mail" +msgstr "" + +msgid "IP address:" +msgstr "" + +msgid "Date:" +msgstr "" + +msgid "Author:" +msgstr "" + +msgid "Web site:" +msgstr "" + +msgid "Status:" +msgstr "" + +msgid "Comment:" +msgstr "" + +msgid "comment" +msgstr "" + +msgid "trackback" +msgstr "" + +msgid "Date" +msgstr "" + +msgid "Entry title" +msgstr "" + +msgid "Author" +msgstr "" + +msgid "publish" +msgstr "" + +msgid "unpublish" +msgstr "" + +msgid "mark as pending" +msgstr "" + +msgid "mark as junk" +msgstr "" + +msgid "Type:" +msgstr "" + +msgid "Comments per page" +msgstr "" + +msgid "Comment author:" +msgstr "" + +msgid "You have one spam comments." +msgstr "" + +msgid "Show it." +msgstr "" + +#, php-format +msgid "You have %s spam comments." +msgstr "" + +msgid "Show them." +msgstr "" + +msgid "Selected comments action:" +msgstr "" + +msgid "action: " +msgstr "" + +msgid "ok" +msgstr "" + +msgid "Comments" +msgstr "" + +#, php-format +msgid "%d comment" +msgstr "" + +#, php-format +msgid "%d comments" +msgstr "" + +msgid "New entry" +msgstr "" + +msgid "My preferences" +msgstr "" + +msgid "Documentation and support" +msgstr "" + +msgid "Latest news" +msgstr "" + +msgid "Dashboard" +msgstr "" + +msgid "Make this blog my default blog" +msgstr "" + +msgid "This blog is offline" +msgstr "" + +msgid "This blog is removed" +msgstr "" + +msgid "is not defined, you should edit your configuration file." +msgstr "" + +msgid "Following plugins have been installed:" +msgstr "" + +msgid "Following plugins have not been installed:" +msgstr "" + +#, php-format +msgid "Dotclear %s is available!" +msgstr "" + +msgid "Upgrade now" +msgstr "" + +msgid "Remind me later" +msgstr "" + +msgid "information about this version" +msgstr "" + +msgid "Some plugins are installed twice:" +msgstr "" + +msgid "Quick entry" +msgstr "" + +msgid "Content:" +msgstr "" + +msgid "Category:" +msgstr "" + +msgid "Save and publish" +msgstr "" + +#, php-format +msgid "PHP version is %s (5.0 or earlier needed)." +msgstr "" + +msgid "Multibyte string module (mbstring) is not available." +msgstr "" + +msgid "Iconv module is not available." +msgstr "" + +msgid "Output control functions are not available." +msgstr "" + +msgid "SimpleXML module is not available." +msgstr "" + +msgid "DOM XML module is not available." +msgstr "" + +msgid "PCRE engine does not support UTF-8 strings." +msgstr "" + +msgid "SPL module is not available." +msgstr "" + +#, php-format +msgid "MySQL version is %s (4.1 or earlier needed)." +msgstr "" + +msgid "MySQL InnoDB engine is not available." +msgstr "" + +#, php-format +msgid "PostgreSQL version is %s (8.0 or earlier needed)." +msgstr "" + +msgid "Please set a master key (DC_MASTER_KEY) in configuration file." +msgstr "" + +msgid "Dotclear is already installed." +msgstr "" + +msgid "Dotclear cannot be installed." +msgstr "" + +msgid "No user ID given" +msgstr "" + +msgid "User ID must contain at least 2 characters using letters, numbers or symbols." +msgstr "" + +msgid "Invalid email address" +msgstr "" + +msgid "No password given" +msgstr "" + +msgid "Password must contain at least 6 characters." +msgstr "" + +msgid "My first blog" +msgstr "" + +msgid "%A, %B %e %Y" +msgstr "" + +msgid "Welcome to Dotclear!" +msgstr "" + +msgid "This is your first entry. When you're ready to blog, log in to edit or delete it." +msgstr "" + +msgid "Dotclear Team" +msgstr "" + +msgid "" +"

        This is a comment.

        \n" +"

        To delete it, log in and view your blog's comments. Then you might remove or edit it.

        " +msgstr "" + +msgid "Dotclear Install" +msgstr "" + +msgid "show" +msgstr "" + +msgid "Dotclear installation" +msgstr "" + +#, php-format +msgid "Cache directory %s is not writable." +msgstr "" + +msgid "Errors:" +msgstr "" + +msgid "Configuration file has been successfully created." +msgstr "" + +msgid "User information" +msgstr "" + +msgid "Please provide the following information needed to create the first user." +msgstr "" + +msgid "First Name:" +msgstr "" + +msgid "Last Name:" +msgstr "" + +msgid "Username and password" +msgstr "" + +msgid "All done!" +msgstr "" + +msgid "Dotclear has been successfully installed. Here is some useful information you should keep." +msgstr "" + +msgid "Your account" +msgstr "" + +msgid "Your blog" +msgstr "" + +msgid "Blog address:" +msgstr "" + +msgid "Administration interface:" +msgstr "" + +msgid "Manage your blog now" +msgstr "" + +msgid "Installation can not be completed" +msgstr "" + +msgid "For the said reasons, Dotclear can not be installed. Please refer to the documentation to learn how to correct the problem." +msgstr "" + +#, php-format +msgid "File %s does not exist." +msgstr "" + +#, php-format +msgid "Cannot write %s file." +msgstr "" + +msgid "Dotclear installation wizard" +msgstr "" + +msgid "Welcome" +msgstr "" + +msgid "To complete your Dotclear installation and start writing on your blog, we just need to know how to access your database and who you are. Just fill this two steps wizard with this information and we will be done." +msgstr "" + +msgid "Attention:" +msgstr "" + +msgid "this wizard may not function on every host. If it does not work for you, please refer to the documentation to learn how to create the config.php file manually." +msgstr "" + +msgid "System information" +msgstr "" + +msgid "Please provide the following information needed to create your configuration file." +msgstr "" + +msgid "Database type:" +msgstr "" + +msgid "Database Host Name:" +msgstr "" + +msgid "Database Name:" +msgstr "" + +msgid "Database User Name:" +msgstr "" + +msgid "Database Password:" +msgstr "" + +msgid "Database Tables Prefix:" +msgstr "" + +msgid "Continue" +msgstr "" + +msgid "No such installed language" +msgstr "" + +msgid "You can't remove English language." +msgstr "" + +msgid "Permissions to delete language denied." +msgstr "" + +msgid "Invalid language file URL." +msgstr "" + +msgid "Languages management" +msgstr "" + +msgid "Language has been successfully deleted." +msgstr "" + +msgid "Language has been successfully installed." +msgstr "" + +msgid "Language has been successfully upgraded" +msgstr "" + +msgid "Here you can install, upgrade or remove languages for your Dotclear installation." +msgstr "" + +#, php-format +msgid "You can change your user language in your preferences or change your blog's main language in your blog settings." +msgstr "" + +msgid "Installed languages" +msgstr "" + +msgid "No additional language is installed." +msgstr "" + +msgid "Language" +msgstr "" + +msgid "Action" +msgstr "" + +msgid "Install or upgrade languages" +msgstr "" + +#, php-format +msgid "You can install or remove a language by adding or removing the relevant directory in your %s folder." +msgstr "" + +msgid "Available languages" +msgstr "" + +#, php-format +msgid "You can download and install a additional language directly from Dotclear.net. Proposed languages are based on your version: %s." +msgstr "" + +msgid "Language:" +msgstr "" + +msgid "Install language" +msgstr "" + +msgid "You can install languages by uploading zip files." +msgstr "" + +msgid "Language zip file:" +msgstr "" + +msgid "Upload language" +msgstr "" + +msgid "Invalid language zip file." +msgstr "" + +msgid "The zip file does not appear to be a valid Dotclear language pack." +msgstr "" + +msgid "An error occurred during language upgrade." +msgstr "" + +msgid "Error:" +msgstr "" + +msgid "By names, in ascending order" +msgstr "" + +msgid "By names, in descending order" +msgstr "" + +msgid "By dates, in ascending order" +msgstr "" + +msgid "By dates, in descending order" +msgstr "" + +msgid "Media manager" +msgstr "" + +msgid "confirm removal" +msgstr "" + +#, php-format +msgid "Are you sure you want to remove %s?" +msgstr "" + +msgid "Cancel" +msgstr "" + +msgid "Yes" +msgstr "" + +msgid "Directory has been successfully created." +msgstr "" + +msgid "Files have been successfully uploaded." +msgstr "" + +msgid "File has been successfully removed." +msgstr "" + +msgid "Directory has been successfully removed." +msgstr "" + +msgid "Directory has been successfully rebuilt." +msgstr "" + +msgid "Zip file has been successfully extracted." +msgstr "" + +#, php-format +msgid "Choose a file to attach to entry %s by clicking on %s." +msgstr "" + +msgid "Attach this file to entry" +msgstr "" + +#, php-format +msgid "Choose a file to insert into entry by clicking on %s." +msgstr "" + +msgid "No file." +msgstr "" + +msgid "Sort files:" +msgstr "" + +msgid "Sort" +msgstr "" + +msgid "Add files" +msgstr "" + +msgid "Please take care to publish media that you own and that are not protected by copyright." +msgstr "" + +msgid "Choose a file:" +msgstr "" + +#, php-format +msgid "Maximum size %s" +msgstr "" + +msgid "Private" +msgstr "" + +msgid "To send several files at the same time, you can activate the enhanced uploader in" +msgstr "" + +msgid "Send" +msgstr "" + +msgid "New directory" +msgstr "" + +msgid "Directory Name:" +msgstr "" + +msgid "Download this directory as a zip file" +msgstr "" + +msgid "open" +msgstr "" + +msgid "Insert this file into entry" +msgstr "" + +msgid "delete" +msgstr "" + +msgid "Not a valid file" +msgstr "" + +msgid "File has been successfully updated." +msgstr "" + +msgid "Thumbnails have been successfully updated." +msgstr "" + +msgid "Insert media item" +msgstr "" + +msgid "Image size:" +msgstr "" + +msgid "original" +msgstr "" + +msgid "Image alignment" +msgstr "" + +msgid "None" +msgstr "" + +msgid "Left" +msgstr "" + +msgid "Right" +msgstr "" + +msgid "Center" +msgstr "" + +msgid "Image insertion" +msgstr "" + +msgid "As a single image" +msgstr "" + +msgid "As a link to original image" +msgstr "" + +msgid "MP3 disposition" +msgstr "" + +msgid "Please note that you cannot insert mp3 files with visual editor." +msgstr "" + +msgid "Please note that you cannot insert video files with visual editor." +msgstr "" + +msgid "Video size" +msgstr "" + +msgid "Width:" +msgstr "" + +msgid "Height:" +msgstr "" + +msgid "Video disposition" +msgstr "" + +msgid "Media item will be inserted as a link." +msgstr "" + +msgid "Insert" +msgstr "" + +msgid "Media details" +msgstr "" + +msgid "Available sizes:" +msgstr "" + +msgid "File owner:" +msgstr "" + +msgid "File type:" +msgstr "" + +msgid "File size:" +msgstr "" + +msgid "File URL:" +msgstr "" + +msgid "Show entries containing this media" +msgstr "" + +msgid "Entries containing this media" +msgstr "" + +msgid "No entry seems contain this media." +msgstr "" + +msgid "Image details" +msgstr "" + +msgid "No detail" +msgstr "" + +msgid "Update thumbnails" +msgstr "" + +msgid "This will create or update thumbnails for this image." +msgstr "" + +msgid "Extract in a new directory" +msgstr "" + +msgid "Extract in current directory" +msgstr "" + +msgid "Extract archive" +msgstr "" + +msgid "This will extract archive in a new directory that should not exist yet." +msgstr "" + +msgid "This will extract archive in current directory and will overwrite existing files or directory." +msgstr "" + +msgid "Extract mode:" +msgstr "" + +msgid "Extract" +msgstr "" + +msgid "Change media properties" +msgstr "" + +msgid "File name:" +msgstr "" + +msgid "File title:" +msgstr "" + +msgid "File date:" +msgstr "" + +msgid "New directory:" +msgstr "" + +msgid "Change file" +msgstr "" + +msgid "No blog or user given." +msgstr "" + +msgid "permissions" +msgstr "" + +msgid "Permissions" +msgstr "" + +msgid "The permissions have been successfully updated." +msgstr "" + +#, php-format +msgid "You are about to change permissions on the following blogs for users %s." +msgstr "" + +msgid "Validate permissions" +msgstr "" + +msgid "choose a blog" +msgstr "" + +msgid "Choose a blog" +msgstr "" + +msgid "Entries per page" +msgstr "" + +#, php-format +msgid "Choose one or more blogs to which you want to give permissions to users %s." +msgstr "" + +msgid "Set permissions" +msgstr "" + +msgid "select" +msgstr "" + +msgid "No content found on this plugin." +msgstr "" + +msgid "Plugin not found" +msgstr "" + +msgid "The plugin you reached does not exist or does not have an admin page." +msgstr "" + +msgid "No such plugin." +msgstr "" + +msgid "You don't have permissions to delete this plugin." +msgstr "" + +msgid "You don't have permissions to deactivate this plugin." +msgstr "" + +msgid "Plugins management" +msgstr "" + +msgid "Plugin has been successfully deleted." +msgstr "" + +msgid "Plugin has been successfully installed." +msgstr "" + +msgid "Plugin has been successfully upgraded" +msgstr "" + +msgid "Plugins add new functionalities to Dotclear. Here you can activate or deactivate installed plugins." +msgstr "" + +#, php-format +msgid "You can find additional plugins for your blog on %s." +msgstr "" + +msgid "To install or upgrade a plugin you generally just need to upload it in \"Install or upgrade a plugin\" section." +msgstr "" + +msgid "To install or upgrade a plugin you just need to extract it in your plugins directory." +msgstr "" + +msgid "Plugins" +msgstr "" + +msgid "Activated plugins" +msgstr "" + +msgid "Plugin" +msgstr "" + +msgid "Version" +msgstr "" + +msgid "Details" +msgstr "" + +msgid "Deactivate" +msgstr "" + +msgid "Deactivated plugins" +msgstr "" + +msgid "Activate" +msgstr "" + +msgid "Install or upgrade a plugin" +msgstr "" + +msgid "You can install plugins by uploading or downloading zip files." +msgstr "" + +msgid "Plugin zip file:" +msgstr "" + +msgid "Upload plugin" +msgstr "" + +msgid "Plugin zip file URL:" +msgstr "" + +msgid "Download plugin" +msgstr "" + +msgid "To enable this function, please give write access to your plugins directory." +msgstr "" + +msgid "Add a link" +msgstr "" + +msgid "Available" +msgstr "" + +msgid "Most used" +msgstr "" + +msgid "Link URL:" +msgstr "" + +msgid "Link title:" +msgstr "" + +msgid "Link language:" +msgstr "" + +msgid "Add a link to an entry" +msgstr "" + +msgid "Search entry:" +msgstr "" + +msgid "Search" +msgstr "" + +msgid "cancel" +msgstr "" + +msgid "This entry does not exist." +msgstr "" + +msgid "Edit entry" +msgstr "" + +msgid "next entry" +msgstr "" + +msgid "previous entry" +msgstr "" + +msgid "Entry has been successfully updated." +msgstr "" + +msgid "Entry has been successfully created." +msgstr "" + +msgid "File has been successfully attached." +msgstr "" + +msgid "Attachment has been successfully removed." +msgstr "" + +msgid "Comment has been successfully created." +msgstr "" + +msgid "Don't forget to validate your XHTML conversion by saving your post." +msgstr "" + +msgid "Go to this entry on the site" +msgstr "" + +msgid "new window" +msgstr "" + +msgid "Excerpt:" +msgstr "" + +msgid "Notes:" +msgstr "" + +msgid "Preview" +msgstr "" + +msgid "Entry status:" +msgstr "" + +msgid "Published on:" +msgstr "" + +msgid "Text formating:" +msgstr "" + +msgid "Convert to XHTML" +msgstr "" + +msgid "Selected entry" +msgstr "" + +msgid "Entry lang:" +msgstr "" + +msgid "Entry password:" +msgstr "" + +msgid "Basename:" +msgstr "" + +msgid "Warning: If you set the URL manually, it may conflict with another entry." +msgstr "" + +msgid "Ping blogs" +msgstr "" + +msgid "Trackbacks" +msgstr "" + +msgid "No trackback" +msgstr "" + +msgid "Add a comment" +msgstr "" + +msgid "Name:" +msgstr "" + +msgid "IP address" +msgstr "" + +msgid "published" +msgstr "" + +msgid "unpublished" +msgstr "" + +msgid "pending" +msgstr "" + +msgid "junk" +msgstr "" + +msgid "select this comment" +msgstr "" + +msgid "select this trackback" +msgstr "" + +msgid "Edit this comment" +msgstr "" + +msgid "This attachment does not exist" +msgstr "" + +msgid "Remove attachment" +msgstr "" + +msgid "Attachment" +msgstr "" + +msgid "Are you sure you want to remove this attachment?" +msgstr "" + +msgid "selected" +msgstr "" + +msgid "not selected" +msgstr "" + +msgid "Category" +msgstr "" + +msgid "Selected" +msgstr "" + +msgid "Publish" +msgstr "" + +msgid "Unpublish" +msgstr "" + +msgid "Schedule" +msgstr "" + +msgid "Mark as pending" +msgstr "" + +msgid "Mark" +msgstr "" + +msgid "Mark as selected" +msgstr "" + +msgid "Mark as unselected" +msgstr "" + +msgid "Change" +msgstr "" + +msgid "Change category" +msgstr "" + +msgid "Change author" +msgstr "" + +msgid "Selected:" +msgstr "" + +msgid "Month:" +msgstr "" + +msgid "Lang:" +msgstr "" + +msgid "Selected entries action:" +msgstr "" + +msgid "This user does not exist" +msgstr "" + +msgid "Change category for entries" +msgstr "" + +msgid "Change author for entries" +msgstr "" + +msgid "Author ID:" +msgstr "" + +msgid "Default" +msgstr "" + +msgid "If you want to change your email or password you must provide your current password." +msgstr "" + +msgid "No favorite selected" +msgstr "" + +msgid "Personal information has been successfully updated." +msgstr "" + +msgid "Personal options has been successfully updated." +msgstr "" + +msgid "Favorites have been successfully added." +msgstr "" + +msgid "Favorites have been successfully updated." +msgstr "" + +msgid "Favorites have been successfully removed." +msgstr "" + +msgid "Default favorites have been successfully updated." +msgstr "" + +msgid "My profile" +msgstr "" + +msgid "Display name:" +msgstr "" + +msgid "User language:" +msgstr "" + +msgid "User timezone:" +msgstr "" + +msgid "If you have changed this user email or password you must provide your current password to save these modifications." +msgstr "" + +msgid "My options" +msgstr "" + +msgid "Preferred format:" +msgstr "" + +msgid "Default entry status:" +msgstr "" + +msgid "Entry edit field height:" +msgstr "" + +msgid "Enable WYSIWYG mode" +msgstr "" + +msgid "Activate enhanced uploader in media manager" +msgstr "" + +msgid "Iconset:" +msgstr "" + +msgid "Do not use standard favicon" +msgstr "" + +msgid "This will be applied for all users" +msgstr "" + +msgid "Accessibility options" +msgstr "" + +msgid "Disable javascript powered drag and drop for ordering items" +msgstr "" + +msgid "Numeric fields will allow to type the elements' ordering number." +msgstr "" + +msgid "Dashboard modules" +msgstr "" + +msgid "Display documentation links" +msgstr "" + +msgid "Display Dotclear news" +msgstr "" + +msgid "Display quick entry form" +msgstr "" + +msgid "My favorites" +msgstr "" + +#, php-format +msgid "position of %s" +msgstr "" + +msgid "Save order" +msgstr "" + +msgid "Delete selected favorites" +msgstr "" + +msgid "Are you sure you want to remove selected favorites?" +msgstr "" + +msgid "If you are a super administrator, you may define this set of favorites to be used by default on all blogs of this installation:" +msgstr "" + +msgid "Define as default favorites" +msgstr "" + +msgid "Currently no personal favorites." +msgstr "" + +msgid "Default favorites" +msgstr "" + +msgid "Those favorites are displayed when My Favorites list is empty." +msgstr "" + +msgid "Available favorites" +msgstr "" + +msgid "Add to my favorites" +msgstr "" + +msgid "Search options" +msgstr "" + +msgid "Query:" +msgstr "" + +msgid "Search entries" +msgstr "" + +msgid "Search comments" +msgstr "" + +msgid "schedule" +msgstr "" + +msgid "change category" +msgstr "" + +msgid "change author" +msgstr "" + +#, php-format +msgid "%d entries found" +msgstr "" + +#, php-format +msgid "%d entry found" +msgstr "" + +#, php-format +msgid "%d comment found" +msgstr "" + +#, php-format +msgid "%d comments found" +msgstr "" + +msgid "This entry does not exist or is not published" +msgstr "" + +msgid "All pings sent." +msgstr "" + +#, php-format +msgid "Back to \"%s\"" +msgstr "" + +msgid "Auto discover ping URLs" +msgstr "" + +msgid "URLs to ping:" +msgstr "" + +msgid "Send excerpt:" +msgstr "" + +msgid "Previously sent pings" +msgstr "" + +msgid "Dotclear update" +msgstr "" + +#, php-format +msgid "Unable to delete file %s" +msgstr "" + +#, php-format +msgid "Downloaded Dotclear archive seems to be corrupted. Try download it again." +msgstr "" + +msgid "The following files of your Dotclear installation have been modified so we won't try to update your installation. Please try to update manually." +msgstr "" + +#, php-format +msgid "The following files of your Dotclear installation are not readable. Please fix this or try to make a backup file named %s manually." +msgstr "" + +msgid "The following files of your Dotclear installation cannot be written. Please fix this or try to update manually." +msgstr "" + +msgid "No newer Dotclear version available." +msgstr "" + +#, php-format +msgid "Dotclear %s is available." +msgstr "" + +msgid "To upgrade your Dotclear installation simply click on the following button. A backup file of your current installation will be created in your root directory." +msgstr "" + +msgid "Update Dotclear" +msgstr "" + +msgid "Update backup files" +msgstr "" + +msgid "The following files are backups of previously updates. You can revert your previous installation or delete theses files." +msgstr "" + +msgid "Please note that reverting your Dotclear version may have some unwanted side-effects. Consider reverting only if you experience strong issues with this new version." +msgstr "" + +#, php-format +msgid "You should not revert to version prior to last one (%s)." +msgstr "" + +msgid "Delete selected file" +msgstr "" + +msgid "Revert to selected file" +msgstr "" + +msgid "Congratulations, you're one click away from the end of the update." +msgstr "" + +msgid "Finish the update." +msgstr "" + +msgid "new user" +msgstr "" + +#, php-format +msgid "User \"%s\" already exists." +msgstr "" + +msgid "User has been successfully updated." +msgstr "" + +msgid "User has been successfully created." +msgstr "" + +msgid "Warning:" +msgstr "" + +msgid "If you change your username, you will have to log in again." +msgstr "" + +msgid "Mandatory for password recovering procedure." +msgstr "" + +msgid "Password change required to connect" +msgstr "" + +msgid "Save and create another" +msgstr "" + +msgid "No permissions." +msgstr "" + +msgid "Add new permissions" +msgstr "" + +msgid "Username" +msgstr "" + +msgid "Last Name" +msgstr "" + +msgid "First Name" +msgstr "" + +msgid "Display name" +msgstr "" + +msgid "Number of entries" +msgstr "" + +msgid "users" +msgstr "" + +msgid "User has been successfully removed." +msgstr "" + +msgid "Create a new user" +msgstr "" + +msgid "Users per page" +msgstr "" + +msgid "Selected users action:" +msgstr "" + +msgid "Blog:" +msgstr "" + +msgid "Change blog" +msgstr "" + +msgid "Blogs:" +msgstr "" + +msgid "Go to site" +msgstr "" + +msgid "My dashboard" +msgstr "" + +#, php-format +msgid "Logout %s" +msgstr "" + +msgid "Safe mode" +msgstr "" + +msgid "You are in safe mode. All plugins have been temporarily disabled. Remind to log out then log in again normally to get back all functionalities" +msgstr "" + +#, php-format +msgid "Thank you for using %s." +msgstr "" + +msgid "Help" +msgstr "" + +msgid "uncover" +msgstr "" + +msgid "hide" +msgstr "" + +msgid "help" +msgstr "" + +msgid "no selection" +msgstr "" + +msgid "select all" +msgstr "" + +msgid "invert selection" +msgstr "" + +msgid "view entry" +msgstr "" + +#, php-format +msgid "Are you sure you want to delete selected entries (%s)?" +msgstr "" + +msgid "Are you sure you want to delete this entry?" +msgstr "" + +#, php-format +msgid "Are you sure you want to delete selected comments (%s)?" +msgstr "" + +msgid "Are you sure you want to delete this comment?" +msgstr "" + +msgid "Users with posts cannot be deleted." +msgstr "" + +#, php-format +msgid "Are you sure you want to delete selected users (%s)?" +msgstr "" + +#, php-format +msgid "Are you sure you want to delete category \"%s\"?" +msgstr "" + +msgid "Are you sure you want to reorder all categories?" +msgstr "" + +#, php-format +msgid "Are you sure you want to remove media \"%s\"?" +msgstr "" + +msgid "Are you sure you want to extract archive in current directory?" +msgstr "" + +#, php-format +msgid "Are you sure you want to remove attachment \"%s\"?" +msgstr "" + +#, php-format +msgid "Are you sure you want to delete \"%s\" language?" +msgstr "" + +#, php-format +msgid "Are you sure you want to delete \"%s\" plugin?" +msgstr "" + +msgid "Use this theme" +msgstr "" + +msgid "Remove this theme" +msgstr "" + +#, php-format +msgid "Are you sure you want to delete \"%s\" theme?" +msgstr "" + +msgid "Zip file content" +msgstr "" + +msgid "XHTML markup validator" +msgstr "" + +msgid "XHTML content is valid." +msgstr "" + +msgid "There are XHTML markup errors." +msgstr "" + +msgid "You have unsaved changes. Switch post format will loose these changes. Proceed anyway?" +msgstr "" + +msgid "Loading enhanced uploader, please wait." +msgstr "" + +msgid "You have unsaved changes." +msgstr "" + +msgid "close" +msgstr "" + +msgid "now" +msgstr "" + +msgid "visual" +msgstr "" + +msgid "source" +msgstr "" + +msgid "You can use the following shortcuts to format your text." +msgstr "" + +msgid "-- none --" +msgstr "" + +msgid "-- block format --" +msgstr "" + +msgid "Paragraph" +msgstr "" + +msgid "Level 1 header" +msgstr "" + +msgid "Level 2 header" +msgstr "" + +msgid "Level 3 header" +msgstr "" + +msgid "Level 4 header" +msgstr "" + +msgid "Level 5 header" +msgstr "" + +msgid "Level 6 header" +msgstr "" + +msgid "Strong emphasis" +msgstr "" + +msgid "Emphasis" +msgstr "" + +msgid "Inserted" +msgstr "" + +msgid "Deleted" +msgstr "" + +msgid "Inline quote" +msgstr "" + +msgid "Code" +msgstr "" + +msgid "Line break" +msgstr "" + +msgid "Blockquote" +msgstr "" + +msgid "Preformated text" +msgstr "" + +msgid "Unordered list" +msgstr "" + +msgid "Ordered list" +msgstr "" + +msgid "Link" +msgstr "" + +msgid "URL?" +msgstr "" + +msgid "Language?" +msgstr "" + +msgid "External image" +msgstr "" + +msgid "Media chooser" +msgstr "" + +msgid "Link to an entry" +msgstr "" + +msgid "Activate enhanced uploader" +msgstr "" + +msgid "Disable enhanced uploader" +msgstr "" + +msgid "File successfully uploaded." +msgstr "" + +msgid "Maximum file size allowed:" +msgstr "" + +msgid "Limit exceeded." +msgstr "" + +msgid "File size exceeds allowed limit." +msgstr "" + +msgid "Canceled." +msgstr "" + +msgid "HTTP Error:" +msgstr "" + +msgid "Choose file" +msgstr "" + +msgid "Choose files" +msgstr "" + +msgid "Clean" +msgstr "" + +msgid "Upload" +msgstr "" + +msgid "No file in queue." +msgstr "" + +msgid "1 file in queue." +msgstr "" + +#, php-format +msgid "%d files in queue." +msgstr "" + +msgid "Queue error:" +msgstr "" + +msgid "«prev." +msgstr "" + +msgid "next»" +msgstr "" + +msgid "No entry" +msgstr "" + +msgid "scheduled" +msgstr "" + +msgid "protected" +msgstr "" + +#, php-format +msgid "%d attachment" +msgstr "" + +#, php-format +msgid "%d attachments" +msgstr "" + +msgid "Type" +msgstr "" + +msgid "No user" +msgstr "" + +msgid "admin" +msgstr "" + +msgid "superadmin" +msgstr "" + +msgid "Database error" +msgstr "" + +msgid "There seems to be no Session table in your database. Is Dotclear completly installed?" +msgstr "" + +msgid "System" +msgstr "" + +msgid "Blog" +msgstr "" + +msgid "Updates" +msgstr "" + +msgid "Languages" +msgstr "" + +msgid "administrator" +msgstr "" + +msgid "manage their own entries and comments" +msgstr "" + +msgid "publish entries and comments" +msgstr "" + +msgid "delete entries and comments" +msgstr "" + +msgid "manage all entries and comments" +msgstr "" + +msgid "manage categories" +msgstr "" + +msgid "manage their own media items" +msgstr "" + +msgid "manage all media items" +msgstr "" + +msgid "That user does not exist in the database." +msgstr "" + +msgid "That key does not exist in the database." +msgstr "" + +msgid "You are not allowed to add categories" +msgstr "" + +msgid "You are not allowed to update categories" +msgstr "" + +msgid "You are not allowed to delete categories" +msgstr "" + +msgid "This category is not empty." +msgstr "" + +msgid "Category URL must be unique." +msgstr "" + +msgid "You must provide a category title" +msgstr "" + +msgid "You must provide a category URL" +msgstr "" + +msgid "You are not allowed to create an entry" +msgstr "" + +msgid "You are not allowed to update entries" +msgstr "" + +msgid "No such entry ID" +msgstr "" + +msgid "You are not allowed to edit this entry" +msgstr "" + +msgid "You are not allowed to change this entry status" +msgstr "" + +msgid "You are not allowed to change this entry category" +msgstr "" + +msgid "You are not allowed to mark this entry as selected" +msgstr "" + +msgid "You are not allowed to delete entries" +msgstr "" + +msgid "You are not allowed to delete this entry" +msgstr "" + +msgid "No entry title" +msgstr "" + +msgid "No entry content" +msgstr "" + +msgid "Empty entry URL" +msgstr "" + +msgid "You are not allowed to update comments" +msgstr "" + +msgid "No such comment ID" +msgstr "" + +msgid "You are not allowed to update this comment" +msgstr "" + +msgid "You are not allowed to change this comment's status" +msgstr "" + +msgid "You are not allowed to delete comments" +msgstr "" + +msgid "You are not allowed to delete this comment" +msgstr "" + +msgid "You must provide a comment" +msgstr "" + +msgid "You must provide an author name" +msgstr "" + +msgid "Email address is not valid." +msgstr "" + +msgid "online" +msgstr "" + +msgid "offline" +msgstr "" + +msgid "removed" +msgstr "" + +msgid "You are not an administrator" +msgstr "" + +msgid "Invalid user language code" +msgstr "" + +msgid "Blog ID must contain at least 2 characters using letters, numbers or symbols." +msgstr "" + +msgid "No blog name" +msgstr "" + +msgid "No blog URL" +msgstr "" + +msgid "No log message" +msgstr "" + +msgid "unknown" +msgstr "" + +msgid "No blog defined." +msgstr "" + +#, php-format +msgid "Directory %s does not exist." +msgstr "" + +msgid "You are not a super administrator." +msgstr "" + +msgid "Permission denied." +msgstr "" + +msgid "You are not the file owner." +msgstr "" + +msgid "This file is not allowed." +msgstr "" + +msgid "New file already exists." +msgstr "" + +msgid "File does not exist in the database." +msgstr "" + +#, php-format +msgid "Extract destination directory %s already exists." +msgstr "" + +msgid "Embedded Audio Player" +msgstr "" + +msgid "Embedded Video Player" +msgstr "" + +#, php-format +msgid "%s: in [%s] and [%s]" +msgstr "" + +msgid "Empty module zip file." +msgstr "" + +msgid "The zip file does not appear to be a valid Dotclear module." +msgstr "" + +msgid "An error occurred during module deletion." +msgstr "" + +#, php-format +msgid "Unable to upgrade \"%s\". (same version)" +msgstr "" + +msgid "Unable to read new _define.php file" +msgstr "" + +msgid "No such module." +msgstr "" + +msgid "Cannot remove module files" +msgstr "" + +msgid "Cannot deactivate plugin." +msgstr "" + +msgid "Cannot activate plugin." +msgstr "" + +#, php-format +msgid "Invalid setting dcNamespace: %s" +msgstr "" + +msgid "Unable to retrieve settings:" +msgstr "" + +#, php-format +msgid "%s is not a valid setting id" +msgstr "" + +msgid "No namespace specified" +msgstr "" + +msgid "Unable to retrieve workspaces:" +msgstr "" + +msgid "Unable to retrieve namespaces:" +msgstr "" + +#, php-format +msgid "Invalid setting namespace: %s" +msgstr "" + +#, php-format +msgid "%s has still been pinged" +msgstr "" + +msgid "Unable to ping URL" +msgstr "" + +#, php-format +msgid "%s is not a ping URL" +msgstr "" + +#, php-format +msgid "%s, ping error:" +msgstr "" + +msgid "Digests file not found." +msgstr "" + +msgid "No file to download" +msgstr "" + +msgid "Root directory is not writable." +msgstr "" + +msgid "An error occurred while downloading archive." +msgstr "" + +msgid "Archive not found." +msgstr "" + +msgid "Unable to read current digests file." +msgstr "" + +msgid "Downloaded file does not seem to be a valid archive." +msgstr "" + +msgid "Incomplete archive." +msgstr "" + +msgid "Unable to read digests file." +msgstr "" + +msgid "Invalid digests file." +msgstr "" + +#, php-format +msgid "Invalid dcWorkspace: %s" +msgstr "" + +msgid "Unable to retrieve prefs:" +msgstr "" + +#, php-format +msgid "%s is not a valid pref id" +msgstr "" + +msgid "No workspace specified" +msgstr "" + +msgid "SQLite Database Schema cannot be upgraded." +msgstr "" + +msgid "Something went wrong with auto upgrade:" +msgstr "" + +msgid "Unable to open directory." +msgstr "" + +msgid "Unable to create directory." +msgstr "" + +msgid "File is not writable." +msgstr "" + +msgid "Unable to open file." +msgstr "" + +msgid "Not an uploaded file." +msgstr "" + +msgid "The uploaded file exceeds the maximum file size allowed." +msgstr "" + +msgid "The uploaded file was only partially uploaded." +msgstr "" + +msgid "No file was uploaded." +msgstr "" + +msgid "Missing a temporary folder." +msgstr "" + +msgid "Failed to write file to disk." +msgstr "" + +#, php-format +msgid "%s is not a directory." +msgstr "" + +msgid "Bad range" +msgstr "" + +msgid "Invalid range" +msgstr "" + +msgid "Invalid line number" +msgstr "" + +msgid "Chunk is out of range" +msgstr "" + +msgid "Bad context" +msgstr "" + +msgid "Bad context (in deletion)" +msgstr "" + +msgid "Invalid diff format" +msgstr "" + +msgid "Uploading this file is not allowed." +msgstr "" + +msgid "Destination directory is not in jail." +msgstr "" + +msgid "File already exists." +msgstr "" + +msgid "Cannot write in this directory." +msgstr "" + +msgid "An error occurred while writing the file." +msgstr "" + +msgid "Source file does not exist." +msgstr "" + +msgid "File is not in jail." +msgstr "" + +msgid "Destination directory is not writable." +msgstr "" + +msgid "Unable to rename file." +msgstr "" + +msgid "File cannot be removed." +msgstr "" + +msgid "Directory is not in jail." +msgstr "" + +msgid "Directory cannot be removed." +msgstr "" + +msgid "Not enough memory to open image." +msgstr "" + +#, php-format +msgid "File %s is not compressed in the zip." +msgstr "" + +#, php-format +msgid "Trying to unzip a folder name %s" +msgstr "" + +msgid "Unable to write destination file." +msgstr "" + +msgid "Unable to write in target directory, permission denied." +msgstr "" + +msgid "Not enough memory to open file." +msgstr "" + +msgid "File does not exist" +msgstr "" + +msgid "Cannot read file" +msgstr "" + +msgid "Directory does not exist" +msgstr "" + +msgid "Cannot read directory" +msgstr "" + +msgid "Unable to connect to database" +msgstr "" + +#, php-format +msgid "

        This either means that the username and password information in your config.php file is incorrect or we can't contact the database server at \"%s\". This could mean your host's database server is down.

        • Are you sure you have the correct username and password?
        • Are you sure that you have typed the correct hostname?
        • Are you sure that the database server is running?

        If you're unsure what these terms mean you should probably contact your host. If you still need help you can always visit the Dotclear Support Forums.

        " +msgstr "" + +msgid "The following error was encountered while trying to read the database:" +msgstr "" diff --git a/v2/dotclear/locales/en/plugins.lang.php b/v2/dotclear/locales/en/plugins.lang.php new file mode 100644 index 0000000..0bb1271 --- /dev/null +++ b/v2/dotclear/locales/en/plugins.lang.php @@ -0,0 +1,45 @@ + \ No newline at end of file diff --git a/v2/dotclear/locales/en/plugins.po b/v2/dotclear/locales/en/plugins.po new file mode 100644 index 0000000..55a7780 --- /dev/null +++ b/v2/dotclear/locales/en/plugins.po @@ -0,0 +1,1573 @@ +# SOME DESCRIPTIVE TITLE. +# This file is put in the public domain. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: Dotclear 2\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-11-06 18:11+0100\n" +"PO-Revision-Date: 2011-10-25 15:52+0100\n" +"Last-Translator: Franck Paul \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "no" +msgstr "" + +msgid "yes" +msgstr "" + +msgid "Configuration successfully updated" +msgstr "" + +msgid "Settings definition successfully updated" +msgstr "" + +msgid "blog settings" +msgstr "" + +msgid "Value" +msgstr "" + +msgid "Description" +msgstr "" + +msgid "Goto:" +msgstr "" + +msgid "Ok" +msgstr "" + +msgid "global settings" +msgstr "" + +msgid "Akismet spam filter" +msgstr "" + +#, php-format +msgid "Filtered by %s." +msgstr "" + +msgid "Akismet API key:" +msgstr "" + +msgid "API key verified" +msgstr "" + +msgid "API key not verified" +msgstr "" + +msgid "Get your own API key" +msgstr "" + +msgid "Antispam" +msgstr "" + +msgid "Delete junk comments older than" +msgstr "" + +msgid "days" +msgstr "" + +msgid "IP Blacklist / Whitelist Filter" +msgstr "" + +#, php-format +msgid "Filtered by %1$s with rule %2$s." +msgstr "" + +msgid "IP address has been successfully added." +msgstr "" + +msgid "IP addresses have been successfully removed." +msgstr "" + +msgid "Blacklist" +msgstr "" + +msgid "Whitelist" +msgstr "" + +msgid "Add an IP address: " +msgstr "" + +msgid "Global IP" +msgstr "" + +msgid "Add" +msgstr "" + +msgid "No IP address in list." +msgstr "" + +msgid "IP list" +msgstr "" + +msgid "Checks sender IP address against DNSBL servers" +msgstr "" + +#, php-format +msgid "Filtered by %1$s with server %2$s." +msgstr "" + +msgid "IP Lookup servers" +msgstr "" + +msgid "Add here a coma separated list of servers." +msgstr "" + +msgid "Checks links in comments against surbl.org" +msgstr "" + +msgid "Words Blacklist" +msgstr "" + +#, php-format +msgid "Filtered by %1$s with word %2$s." +msgstr "" + +msgid "Words have been successfully added." +msgstr "" + +msgid "Word has been successfully added." +msgstr "" + +msgid "Words have been successfully removed." +msgstr "" + +msgid "Add a word " +msgstr "" + +msgid "Global word" +msgstr "" + +msgid "No word in list." +msgstr "" + +msgid "List of bad words" +msgstr "" + +msgid "Delete selected words" +msgstr "" + +msgid "Create default wordlist" +msgstr "" + +msgid "This word exists" +msgstr "" + +msgid "No description" +msgstr "" + +#, php-format +msgid "Filtered by %1$s (%2$s)" +msgstr "" + +msgid "Unknown filter." +msgstr "" + +msgid "This comment is a spam:" +msgstr "" + +#, php-format +msgid "(including %d spam comment)" +msgstr "" + +#, php-format +msgid "(including %d spam comments)" +msgstr "" + +msgid "Spam moderation" +msgstr "" + +msgid "Spam" +msgstr "" + +msgid "Ham" +msgstr "" + +msgid "Filter does not exist." +msgstr "" + +msgid "Filter has no user interface." +msgstr "" + +#, php-format +msgid "%s configuration" +msgstr "" + +msgid "Information" +msgstr "" + +msgid "Spam comments have been successfully deleted." +msgstr "" + +msgid "Junk comments:" +msgstr "" + +msgid "Published comments:" +msgstr "" + +msgid "Delete all spams" +msgstr "" + +#, php-format +msgid "All spam comments older than %s day(s) will be automatically deleted." +msgstr "" + +msgid "You can modify this duration in " +msgstr "" + +msgid "Blog preferences" +msgstr "" + +msgid "Filters configuration has been successfully saved." +msgstr "" + +msgid "Available spam filters" +msgstr "" + +msgid "Order" +msgstr "" + +msgid "Active" +msgstr "" + +msgid "Auto Del." +msgstr "" + +msgid "Filter name" +msgstr "" + +msgid "Filter configuration" +msgstr "" + +msgid "position" +msgstr "" + +msgid "Syndication" +msgstr "" + +msgid "Junk comments RSS feed" +msgstr "" + +msgid "Published comments RSS feed" +msgstr "" + +msgid "Attachments" +msgstr "" + +msgid "remove" +msgstr "" + +msgid "No attachment." +msgstr "" + +msgid "Add files to this entry" +msgstr "" + +msgid "Blogroll" +msgstr "" + +msgid "manage blogroll" +msgstr "" + +msgid "Links" +msgstr "" + +msgid "All categories" +msgstr "" + +msgid "Home page only" +msgstr "" + +msgid "You must provide a link title" +msgstr "" + +msgid "You must provide a link URL" +msgstr "" + +msgid "You need to provide a XBEL or OPML file." +msgstr "" + +msgid "File is not in XML format." +msgstr "" + +msgid "No such link or title" +msgstr "" + +msgid "Return to blogroll" +msgstr "" + +msgid "Category has been successfully updated" +msgstr "" + +msgid "Edit category" +msgstr "" + +msgid "Link has been successfully updated" +msgstr "" + +msgid "Edit link" +msgstr "" + +msgid "XFN" +msgstr "" + +msgid "_xfn_Me" +msgstr "Me" + +msgid "_xfn_Another link for myself" +msgstr "Another link for myself" + +msgid "_xfn_Friendship" +msgstr "Friendship" + +msgid "_xfn_Contact" +msgstr "Contact" + +msgid "_xfn_Acquaintance" +msgstr "Acquaintance" + +msgid "_xfn_Friend" +msgstr "Friend" + +msgid "_xfn_Physical" +msgstr "Physical" + +msgid "_xfn_Met" +msgstr "Met" + +msgid "_xfn_Professional" +msgstr "Professional" + +msgid "_xfn_Co-worker" +msgstr "Co-worker" + +msgid "_xfn_Colleague" +msgstr "Colleague" + +msgid "_xfn_Geographical" +msgstr "Geographical" + +msgid "_xfn_Co-resident" +msgstr "Co-resident" + +msgid "_xfn_Neighbor" +msgstr "Neighbor" + +msgid "_xfn_Family" +msgstr "Family" + +msgid "_xfn_Child" +msgstr "Child" + +msgid "_xfn_Parent" +msgstr "Parent" + +msgid "_xfn_Sibling" +msgstr "Sibling" + +msgid "_xfn_Spouse" +msgstr "Spouse" + +msgid "_xfn_Kin" +msgstr "Kin" + +msgid "_xfn_Romantic" +msgstr "Romantic" + +msgid "_xfn_Muse" +msgstr "Muse" + +msgid "_xfn_Crush" +msgstr "Crush" + +msgid "_xfn_Date" +msgstr "Date" + +msgid "_xfn_Sweetheart" +msgstr "Sweetheart" + +msgid "Nothing to import" +msgstr "" + +msgid "Import operation cancelled." +msgstr "" + +msgid "Items order has been successfully updated" +msgstr "" + +msgid "Items have been successfully removed." +msgstr "" + +msgid "Link has been successfully created." +msgstr "" + +msgid "category has been successfully created." +msgstr "" + +msgid "links have been successfully imported." +msgstr "" + +msgid "URL" +msgstr "" + +msgid "Lang" +msgstr "" + +msgid "select this link" +msgstr "" + +msgid "Delete selected links" +msgstr "" + +msgid "Are you sure you want to delete selected links?" +msgstr "" + +msgid "The link list is empty." +msgstr "" + +msgid "Add a new link" +msgstr "" + +msgid "Add a category" +msgstr "" + +msgid "Import links" +msgstr "" + +msgid "OPML or XBEL File:" +msgstr "" + +msgid "Import" +msgstr "" + +msgid "Light linear gradient" +msgstr "" + +msgid "Medium linear gradient" +msgstr "" + +msgid "Dark linear gradient" +msgstr "" + +msgid "Solid color" +msgstr "" + +msgid "Custom..." +msgstr "" + +msgid "Blowup configuration" +msgstr "" + +msgid "Predefined styles" +msgstr "" + +msgid "Apply code" +msgstr "" + +msgid "Choose a predefined style" +msgstr "" + +msgid "For the following reasons, images cannot be created. You won't be able to change some background properties." +msgstr "" + +msgid "Theme configuration has been successfully updated." +msgstr "" + +msgid "General" +msgstr "" + +msgid "Background color:" +msgstr "" + +msgid "Background color fill:" +msgstr "" + +msgid "Main text font:" +msgstr "" + +msgid "Main text font size:" +msgstr "" + +msgid "Main text color:" +msgstr "" + +msgid "Text line height:" +msgstr "" + +msgid "Links color:" +msgstr "" + +msgid "Visited links color:" +msgstr "" + +msgid "Focus links color:" +msgstr "" + +msgid "Page top" +msgstr "" + +msgid "Prelude color:" +msgstr "" + +msgid "Hide main title" +msgstr "" + +msgid "Main title font:" +msgstr "" + +msgid "Main title font size:" +msgstr "" + +msgid "Main title color:" +msgstr "" + +msgid "Main title alignment:" +msgstr "" + +msgid "center" +msgstr "" + +msgid "left" +msgstr "" + +msgid "right" +msgstr "" + +msgid "Main title position (x:y)" +msgstr "" + +msgid "Top image" +msgstr "" + +msgid "Choose \"Custom...\" to upload your own image." +msgstr "" + +msgid "Add your image:" +msgstr "" + +#, php-format +msgid "JPEG or PNG file, 800 pixels wide, maximum size %s" +msgstr "" + +msgid "Sidebar" +msgstr "" + +msgid "Sidebar position:" +msgstr "" + +msgid "Sidebar text font:" +msgstr "" + +msgid "Sidebar text font size:" +msgstr "" + +msgid "Sidebar text color:" +msgstr "" + +msgid "Sidebar titles font:" +msgstr "" + +msgid "Sidebar titles font size:" +msgstr "" + +msgid "Sidebar titles color:" +msgstr "" + +msgid "Sidebar 2nd level titles font:" +msgstr "" + +msgid "Sidebar 2nd level titles font size:" +msgstr "" + +msgid "Sidebar 2nd level titles color:" +msgstr "" + +msgid "Sidebar lines color:" +msgstr "" + +msgid "Sidebar links color:" +msgstr "" + +msgid "Sidebar visited links color:" +msgstr "" + +msgid "Sidebar focus links color:" +msgstr "" + +msgid "Date title font:" +msgstr "" + +msgid "Date title font size:" +msgstr "" + +msgid "Date title color:" +msgstr "" + +msgid "Entry title font:" +msgstr "" + +msgid "Entry title font size:" +msgstr "" + +msgid "Entry title color:" +msgstr "" + +msgid "Comment background color:" +msgstr "" + +msgid "Comment text color:" +msgstr "" + +msgid "My comment background color:" +msgstr "" + +msgid "My comment text color:" +msgstr "" + +msgid "Footer" +msgstr "" + +msgid "Footer font:" +msgstr "" + +msgid "Footer font size:" +msgstr "" + +msgid "Footer color:" +msgstr "" + +msgid "Footer links color:" +msgstr "" + +msgid "Footer background color:" +msgstr "" + +msgid "Additional CSS" +msgstr "" + +msgid "Configuration import / export" +msgstr "" + +msgid "You can share your configuration using the following code. To apply a configuration, paste the code, click on \"Apply code\" and save." +msgstr "" + +msgid "Copy this code:" +msgstr "" + +msgid "default" +msgstr "" + +msgid "At least one of the following functions is not available: imagecreatetruecolor, imagepng & imagecreatefrompng." +msgstr "" + +msgid "The 'public' directory does not exist." +msgstr "" + +#, php-format +msgid "The '%s' directory cannot be modified." +msgstr "" + +msgid "Unable to create images." +msgstr "" + +msgid "Invalid file type." +msgstr "" + +msgid "Uploaded image is not 800 pixels wide." +msgstr "" + +msgid "Unable to open image." +msgstr "" + +msgid "Checks trackback source for a link to the post" +msgstr "" + +msgid "Import/Export" +msgstr "" + +msgid "Flat file export" +msgstr "" + +msgid "Exports a blog or a full Dotclear installation to flat file." +msgstr "" + +msgid "Export file not found." +msgstr "" + +msgid "Export a blog" +msgstr "" + +#, php-format +msgid "This will create an export of your current blog: %s" +msgstr "" + +msgid "Export" +msgstr "" + +msgid "You may also want to download your media directory as a zip file" +msgstr "" + +msgid "Export all content" +msgstr "" + +msgid "Congratulation!" +msgstr "" + +msgid "Your blog has been successfully imported. Welcome on Dotclear 2!" +msgstr "" + +msgid "Why don't you blog this now?" +msgstr "" + +msgid "or" +msgstr "" + +msgid "visit your dashboard" +msgstr "" + +msgid "Dotclear 1.2 import" +msgstr "" + +msgid "Import a Dotclear 1.2 installation into your current blog." +msgstr "" + +#, php-format +msgid "This will import your Dotclear 1.2 content as new content in the current blog: %s." +msgstr "" + +msgid "Please note that this process will empty your categories, blogroll, entries and comments on the current blog." +msgstr "" + +msgid "Depending on the size of your blog, it could take a few minutes." +msgstr "" + +msgid "General information" +msgstr "" + +msgid "Import my blog now" +msgstr "" + +msgid "We first need some information about your old Dotclear 1.2 installation." +msgstr "" + +msgid "Entries import options" +msgstr "" + +msgid "Number of entries to import at once:" +msgstr "" + +msgid "Importing users" +msgstr "" + +msgid "Importing categories" +msgstr "" + +msgid "Importing blogroll" +msgstr "" + +#, php-format +msgid "Importing entries from %d to %d / %d" +msgstr "" + +msgid "Please read carefully" +msgstr "" + +msgid "Every newly imported user has received a random password and will need to ask for a new one by following the \"I forgot my password\" link on the login page (Their registered email address has to be valid.)" +msgstr "" + +#, php-format +msgid "Please note that Dotclear 2 has a new URL layout. You can avoid broken links by installing DC1 redirect plugin and activate it in your blog configuration." +msgstr "" + +msgid "next step" +msgstr "" + +msgid "Dotclear tables not found" +msgstr "" + +msgid "Feed import" +msgstr "" + +msgid "Imports a feed as new entries." +msgstr "" + +msgid "Cannot retrieve feed URL." +msgstr "" + +msgid "No items in feed." +msgstr "" + +msgid "Content successfully imported." +msgstr "" + +msgid "Import from a feed" +msgstr "" + +#, php-format +msgid "This will import a feed (RSS or Atom) a as new content in the current blog: %s." +msgstr "" + +msgid "Feed URL:" +msgstr "" + +msgid "Flat file import" +msgstr "" + +msgid "Imports a blog or a full Dotclear installation from flat file." +msgstr "" + +msgid "Single blog successfully imported." +msgstr "" + +msgid "Are you sure you want to import a full backup file?" +msgstr "" + +msgid "Import a single blog" +msgstr "" + +#, php-format +msgid "This will import a single blog backup as new content in the current blog: %s." +msgstr "" + +msgid "Upload a backup file" +msgstr "" + +msgid "or pick up a local file in your public directory" +msgstr "" + +msgid "Import a full backup file" +msgstr "" + +msgid "Warning: This will reset all the content of your database, except users." +msgstr "" + +msgid "WordPress import" +msgstr "" + +msgid "Import a WordPress installation into your current blog." +msgstr "" + +#, php-format +msgid "This will import your WordPress content as new content in the current blog: %s." +msgstr "" + +msgid "We first need some information about your old WordPress installation." +msgstr "" + +msgid "WordPress and Dotclear's handling of categories are quite different. You can assign several categories to a single post in WordPress. In the Dotclear world, we see it more like \"One category, several tags.\" Therefore Dotclear can only import one category per post and will chose the lowest numbered one. If you want to keep a trace of every category, you can import them as tags, with an optional prefix." +msgstr "" + +msgid "On the other hand, in WordPress, a post can not be uncategorized, and a default installation has a first category labelised \"Uncategorized\". If you did not change that category, you can just ignore it while importing your blog, as Dotclear allows you to actually keep your posts uncategorized." +msgstr "" + +msgid "Ignore the first category:" +msgstr "" + +msgid "Import lowest numbered category on posts:" +msgstr "" + +msgid "Import all categories as tags:" +msgstr "" + +msgid "Prefix such tags with:" +msgstr "" + +msgid "Content filters" +msgstr "" + +msgid "You may want to process your post and/or comment content with the following filters." +msgstr "" + +msgid "Post content formatter:" +msgstr "" + +msgid "Comment content formatter:" +msgstr "" + +msgid "WordPress tables not found" +msgstr "" + +msgid "No file to read." +msgstr "" + +msgid "File is not a DotClear backup." +msgstr "" + +msgid "File is not a single blog export." +msgstr "" + +msgid "File is not a full export." +msgstr "" + +msgid "The backup file does not appear to be well formed." +msgstr "" + +msgid "Please wait..." +msgstr "" + +msgid "Maintenance" +msgstr "" + +msgid "Optimization successful." +msgstr "" + +msgid "Comments and trackback counted." +msgstr "" + +msgid "Templates cache directory emptied." +msgstr "" + +msgid "Logs deleted." +msgstr "" + +#, php-format +msgid "Indexing entry %d to %d." +msgstr "" + +msgid "next" +msgstr "" + +msgid "Entries index done." +msgstr "" + +msgid "Back" +msgstr "" + +#, php-format +msgid "Indexing comment %d to %d." +msgstr "" + +msgid "Comments index done." +msgstr "" + +msgid "Optimize database room" +msgstr "" + +msgid "Vacuum tables" +msgstr "" + +msgid "Counters" +msgstr "" + +msgid "Reset comments and ping counters" +msgstr "" + +msgid "Search engine index" +msgstr "" + +msgid "This may take a very long time" +msgstr "" + +msgid "Index all posts" +msgstr "" + +msgid "Index all comments" +msgstr "" + +msgid "Vacuum logs" +msgstr "" + +msgid "Delete all logs" +msgstr "" + +msgid "Empty templates cache directory" +msgstr "" + +msgid "Empty directory" +msgstr "" + +msgid "Pages" +msgstr "" + +#, php-format +msgid "%d page" +msgstr "" + +#, php-format +msgid "%d pages" +msgstr "" + +msgid "manage pages" +msgstr "" + +msgid "Published on" +msgstr "" + +msgid "This page's comments feed" +msgstr "" + +msgid "You must provide a valid email address." +msgstr "" + +msgid "Page title" +msgstr "" + +msgid "Page position" +msgstr "" + +msgid "Publication date" +msgstr "" + +msgid "No page" +msgstr "" + +msgid "select this page" +msgstr "" + +msgid "Are you sure you want to delete selected pages?" +msgstr "" + +msgid "New page" +msgstr "" + +msgid "Selected pages action:" +msgstr "" + +msgid "This page does not exist." +msgstr "" + +msgid "Edit page" +msgstr "" + +msgid "next page" +msgstr "" + +msgid "previous page" +msgstr "" + +msgid "Are you sure you want to delete this page?" +msgstr "" + +msgid "Page has been successfully updated." +msgstr "" + +msgid "Page has been successfully created." +msgstr "" + +msgid "Go to this page on the site" +msgstr "" + +msgid "Page status:" +msgstr "" + +msgid "Page position:" +msgstr "" + +msgid "Page lang:" +msgstr "" + +msgid "Page password:" +msgstr "" + +msgid "Warning: If you set the URL manually, it may conflict with another page." +msgstr "" + +msgid "Add files to this page" +msgstr "" + +msgid "Pings" +msgstr "" + +msgid "Pings configuration" +msgstr "" + +msgid "Settings have been successfully updated." +msgstr "" + +msgid "Activate pings extension" +msgstr "" + +msgid "Service name:" +msgstr "" + +msgid "Service URI:" +msgstr "" + +msgid "error" +msgstr "" + +msgid "Test ping services" +msgstr "" + +msgid "Check all" +msgstr "" + +msgid "Pings:" +msgstr "" + +msgid "Simple menu" +msgstr "" + +msgid "Menu" +msgstr "" + +msgid "All months" +msgstr "" + +msgid "All tags" +msgstr "" + +msgid "Home" +msgstr "" + +msgid "Archive" +msgstr "" + +msgid "Page" +msgstr "" + +msgid "Tags" +msgstr "" + +msgid "User defined" +msgstr "" + +msgid "Label" +msgstr "" + +msgid "Recent posts" +msgstr "" + +#, php-format +msgid "Switch to %s language" +msgstr "" + +msgid "Recent Posts from this category" +msgstr "" + +msgid "Archives" +msgstr "" + +#, php-format +msgid "Posts from %s" +msgstr "" + +#, php-format +msgid "Recent posts for %s tag" +msgstr "" + +msgid "Label and URL of menu item are mandatory." +msgstr "" + +msgid "No menu items selected." +msgstr "" + +msgid "Label is mandatory." +msgstr "" + +msgid "URL is mandatory." +msgstr "" + +msgid "Menu item has been successfully added." +msgstr "" + +msgid "Menu items have been successfully removed." +msgstr "" + +msgid "Menu items have been successfully updated." +msgstr "" + +msgid "Add item" +msgstr "" + +msgid "Select type" +msgstr "" + +msgid "Type of item menu:" +msgstr "" + +msgid "Continue..." +msgstr "Continue…" + +msgid "Select language:" +msgstr "" + +msgid "Select category:" +msgstr "" + +msgid "Select month (if necessary):" +msgstr "" + +msgid "Select page:" +msgstr "" + +msgid "Select tag (if necessary):" +msgstr "" + +msgid "Label of item menu:" +msgstr "" + +msgid "Description of item menu:" +msgstr "" + +msgid "URL of item menu:" +msgstr "" + +msgid "Add this item" +msgstr "" + +msgid "Add an item" +msgstr "" + +msgid "Menu items list" +msgstr "" + +msgid "Update menu" +msgstr "" + +msgid "Delete selected menu items" +msgstr "" + +msgid "Are you sure you want to remove selected menu items?" +msgstr "" + +msgid "Currently no menu items" +msgstr "" + +msgid "Tags:" +msgstr "" + +#, php-format +msgid "Are you sure you want to remove this %s?" +msgstr "" + +#, php-format +msgid "Add a %s to this entry" +msgstr "" + +msgid "Choose from list" +msgstr "" + +msgid "all" +msgstr "" + +msgid "Tag" +msgstr "" + +msgid "used in %e - frequency %p%" +msgstr "" + +msgid "entry" +msgstr "" + +msgid "entries" +msgstr "" + +msgid "Enter tags separated by coma" +msgstr "" + +msgid "Add tags" +msgstr "" + +msgid "Remove tags" +msgstr "" + +msgid "Add tags to entries" +msgstr "" + +msgid "Tags to add:" +msgstr "" + +msgid "Remove selected tags from entries" +msgstr "" + +msgid "No tags for selected entries" +msgstr "" + +msgid "Following tags have been found in selected entries:" +msgstr "" + +msgid "short" +msgstr "" + +msgid "extended" +msgstr "" + +msgid "Tags list format:" +msgstr "" + +msgid "This tag's comments Atom feed" +msgstr "" + +msgid "This tag's entries Atom feed" +msgstr "" + +msgid "Limit (empty means no limit):" +msgstr "" + +msgid "Entries count" +msgstr "" + +msgid "Tag name" +msgstr "" + +msgid "Link to all tags:" +msgstr "" + +msgid "Edit tag" +msgstr "" + +msgid "Tag has been successfully renamed" +msgstr "" + +msgid "Back to tags list" +msgstr "" + +msgid "Actions for this tag" +msgstr "" + +msgid "Edit tag name:" +msgstr "" + +msgid "Rename" +msgstr "" + +msgid "Delete this tag:" +msgstr "" + +msgid "List of entries with this tag" +msgstr "" + +msgid "Tag has been successfully removed" +msgstr "" + +msgid "No tags on this blog." +msgstr "" + +msgid "Theme Editor" +msgstr "" + +msgid "No file" +msgstr "" + +msgid "File does not exist." +msgstr "" + +#, php-format +msgid "File %s is not readable" +msgstr "" + +#, php-format +msgid "Unable to write file %s. Please check your theme files and folders permissions." +msgstr "" + +msgid "Saving document..." +msgstr "" + +msgid "Document saved" +msgstr "" + +msgid "An error occurred:" +msgstr "" + +#, php-format +msgid "Your current theme on this blog is \"%s\"." +msgstr "" + +msgid "You can't edit default theme." +msgstr "" + +msgid "Please select a file to edit." +msgstr "" + +msgid "File editor" +msgstr "" + +#, php-format +msgid "Editing file %s" +msgstr "" + +msgid "This file is not writable. Please check your theme files permissions." +msgstr "" + +msgid "Templates files" +msgstr "" + +msgid "CSS files" +msgstr "" + +msgid "JavaScript files" +msgstr "" + +msgid "Preferences successfully updated" +msgstr "" + +msgid "Preferences definition successfully updated" +msgstr "" + +msgid "user preferences" +msgstr "" + +msgid "global preferences" +msgstr "" + +msgid "Presentation widgets" +msgstr "" + +msgid "Search engine" +msgstr "" + +msgid "Navigation links" +msgstr "" + +msgid "Selected entries" +msgstr "" + +msgid "Best of me" +msgstr "" + +msgid "Blog languages" +msgstr "" + +msgid "With entries counts" +msgstr "" + +msgid "Subscribe links" +msgstr "" + +msgid "Subscribe" +msgstr "" + +msgid "Feeds type:" +msgstr "" + +msgid "Feed reader" +msgstr "" + +msgid "Somewhere else" +msgstr "" + +msgid "Entries limit:" +msgstr "" + +msgid "Text" +msgstr "" + +msgid "Text:" +msgstr "" + +msgid "Last entries" +msgstr "" + +msgid "Uncategorized" +msgstr "" + +msgid "Tag:" +msgstr "" + +msgid "Last comments" +msgstr "" + +msgid "Comments limit:" +msgstr "" + +#, php-format +msgid "This blog's entries %s feed" +msgstr "" + +#, php-format +msgid "This blog's comments %s feed" +msgstr "" + +msgid "Entries feed" +msgstr "" + +msgid "Comments feed" +msgstr "" + +msgid "navigation" +msgstr "" + +msgid "extra" +msgstr "" + +msgid "custom" +msgstr "" + +msgid "Widgets" +msgstr "" + +msgid "Are you sure you want to reset sidebars?" +msgstr "" + +msgid "Available widgets" +msgstr "" + +msgid "Append to:" +msgstr "" + +msgid "Add widgets to sidebars" +msgstr "" + +msgid "Navigation sidebar" +msgstr "" + +msgid "Extra sidebar" +msgstr "" + +msgid "Custom sidebar" +msgstr "" + +msgid "Update sidebars" +msgstr "" + +msgid "Reset sidebars" +msgstr "" + +msgid "Use of widgets" +msgstr "" + +msgid "Widgets may be used to add various blocks of content to be displayed on your public pages. To add a widget, drag it from the Available widgets list on the left to one of the sidebars on the right of this page. You can order your widgets in a sidebar by dragging them up or down. You must update sidebars to apply your changes." +msgstr "" + +msgid "Once included in a sidebar, widgets have configuration options that you can reach by clicking on the + sign next to their name." +msgstr "" + +msgid "Reset sidebars to get back to default widgets installation." +msgstr "" + +msgid "Widget templates tags" +msgstr "" + +msgid "If you are allowed to edit your theme templates, you can directly add widgets as templates tags, with their own configuration." +msgstr "" + +msgid "To add a widget in your template, you need to write code like this:" +msgstr "" + +msgid "Widget ID" +msgstr "" + +msgid "Setting name" +msgstr "" + +msgid "Setting value" +msgstr "" + +msgid "Here are the following available widgets for your blog:" +msgstr "" + +msgid "Widget ID:" +msgstr "" + +msgid "No setting for this widget" +msgstr "" + +msgid "Setting name:" +msgstr "" + +msgid "No widget." +msgstr "" + +msgid "order" +msgstr "" + +msgid "Remove widget" +msgstr "" diff --git a/v2/dotclear/locales/en/public.lang.php b/v2/dotclear/locales/en/public.lang.php new file mode 100644 index 0000000..5b13df9 --- /dev/null +++ b/v2/dotclear/locales/en/public.lang.php @@ -0,0 +1,19 @@ + \ No newline at end of file diff --git a/v2/dotclear/locales/en/public.po b/v2/dotclear/locales/en/public.po new file mode 100644 index 0000000..74431fb --- /dev/null +++ b/v2/dotclear/locales/en/public.po @@ -0,0 +1,243 @@ +# SOME DESCRIPTIVE TITLE. +# This file is put in the public domain. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: Dotclear 2\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2008-10-13 05:22+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +# Not found strings +msgid "To content" +msgstr "" + +msgid "To menu" +msgstr "" + +msgid "To search" +msgstr "" + +msgid "By" +msgstr "" + +msgid "by" +msgstr "" + +msgid "on" +msgstr "" + +msgid "On" +msgstr "" + +msgid "Continue reading" +msgstr "" + +msgid "no comment" +msgstr "" + +msgid "one comment" +msgstr "" + +msgid "%d comments" +msgstr "" + +msgid "no trackback" +msgstr "" + +msgid "one trackback" +msgstr "" + +msgid "%d trackbacks" +msgstr "" + +msgid "no attachment" +msgstr "" + +msgid "one attachment" +msgstr "" + +msgid "%d attachments" +msgstr "" + +msgid "previous entries" +msgstr "" + +msgid "page" +msgstr "" + +msgid "of" +msgstr "" + +msgid "next entries" +msgstr "" + +msgid "Search" +msgstr "" + +msgid "Your search for %1$s returned no result." +msgstr "" + +msgid "Your search for %1$s returned %2$s result." +msgstr "" + +msgid "Your search for %1$s returned %2$s results." +msgstr "" + +msgid "Home" +msgstr "" + +msgid "All keywords" +msgstr "" + +msgid "Best of me" +msgstr "" + +msgid "Languages" +msgstr "" + +msgid "Categories" +msgstr "" + +msgid "Subcategories" +msgstr "" + +msgid "Archives" +msgstr "" + +msgid "Links" +msgstr "" + +msgid "Subscribe" +msgstr "" + +msgid "Entries feed" +msgstr "" + +msgid "Comments feed" +msgstr "" + +msgid "This blog's comments Atom feed" +msgstr "" + +msgid "This category's entries Atom feed" +msgstr "" + +msgid "This category's comments Atom feed" +msgstr "" + +msgid "This post's comments feed" +msgstr "" + +msgid "This post's comments Atom feed" +msgstr "" + +msgid "Attachments" +msgstr "" + +msgid "Permalink" +msgstr "" + +msgid "Comments" +msgstr "" + +msgid "Your comment" +msgstr "" + +msgid "Your comment has been published." +msgstr "" + +msgid "Your comment has been submitted and will be reviewed for publication." +msgstr "" + +msgid "Add a comment" +msgstr "" + +msgid "Name or nickname" +msgstr "" + +msgid "Email address" +msgstr "" + +msgid "Website" +msgstr "" + +msgid "optional" +msgstr "" + +msgid "Comment" +msgstr "" + +msgid "Comments can be formatted using a simple wiki syntax." +msgstr "" + +msgid "HTML code is displayed as text and web addresses are automatically converted." +msgstr "" + +msgid "Remember me on this blog" +msgstr "" + +msgid "preview" +msgstr "" + +msgid "send" +msgstr "" + +msgid "They posted on the same topic" +msgstr "" + +msgid "Trackback URL" +msgstr "" + +msgid "You must provide an author name" +msgstr "" + +msgid "You must provide a comment" +msgstr "" + +msgid "Email address is not valid" +msgstr "" + +msgid "Document not found" +msgstr "" + +msgid "The document you are looking for does not exist." +msgstr "" + +msgid "Powered by %s" +msgstr "" + +msgid "Subscribe to" +msgstr "" + +msgid "What is an RSS feed?" +msgstr "" + +msgid "RSS feed is a free blog summary. It provides content (either posts or comments) or summaries of content, together with links to the full versions, and other metadata. The last published items may then be read by your favorite RSS aggregator." +msgstr "" + +msgid "Simply copy the following URL into your aggregator:" +msgstr "" + +msgid "Password needed" +msgstr "" + +msgid "You must give a password to access this area." +msgstr "" + +msgid "Password:" +msgstr "" + +msgid "You must provide a valid email address." +msgstr "" + +msgid "Read" +msgstr "" diff --git a/v2/dotclear/locales/en/resources.php b/v2/dotclear/locales/en/resources.php new file mode 100644 index 0000000..52ce5ec --- /dev/null +++ b/v2/dotclear/locales/en/resources.php @@ -0,0 +1,35 @@ + 'http://dotclear.org/documentation/2.0', + 'Dotclear 2 presentation' => 'http://dotclear.org/documentation/2.0/overview/tour', + "User manual" => 'http://dotclear.org/documentation/2.0/usage', + "Installation and administration guides" => 'http://dotclear.org/documentation/2.0/admin', + "Dotclear 2 support forum" => 'http://forum.dotclear.net/' +); + +$__resources['help'] = array( + 'core_blog_pref' => dirname(__FILE__).'/help/blog_pref.html', + 'core_categories' => dirname(__FILE__).'/help/categories.html', + 'core_comments' => dirname(__FILE__).'/help/comments.html', + 'core_media' => dirname(__FILE__).'/help/media.html', + 'core_post' => dirname(__FILE__).'/help/post.html', + 'core_posts' => dirname(__FILE__).'/help/posts.html', + 'core_user_pref' => dirname(__FILE__).'/help/user_pref.html', + 'core_user' => dirname(__FILE__).'/help/user.html', + 'core_wiki' => dirname(__FILE__).'/help/wiki.html' +); +?> \ No newline at end of file diff --git a/v2/dotclear/locales/fr/date.lang.php b/v2/dotclear/locales/fr/date.lang.php new file mode 100644 index 0000000..1fbb505 --- /dev/null +++ b/v2/dotclear/locales/fr/date.lang.php @@ -0,0 +1,58 @@ + \ No newline at end of file diff --git a/v2/dotclear/locales/fr/date.po b/v2/dotclear/locales/fr/date.po new file mode 100644 index 0000000..4ea100b --- /dev/null +++ b/v2/dotclear/locales/fr/date.po @@ -0,0 +1,136 @@ +# French translation of DotClear +# Copyright (C) 2006. +# Olivier Meunier , 2006. +msgid "" +msgstr "" +"Project-Id-Version: Dotclear 2\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2008-04-15 16:27+0200\n" +"PO-Revision-Date: 2008-04-15 16:34+0100\n" +"Last-Translator: Olivier Meunier \n" +"Language-Team: \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: French\n" + +msgid "%Y-%m-%d %H:%M" +msgstr "%d/%m/%Y %H:%M" + +msgid "_Jan" +msgstr "janv." + +msgid "_Feb" +msgstr "fév." + +msgid "_Mar" +msgstr "mar." + +msgid "_Apr" +msgstr "avr." + +msgid "_May" +msgstr "mai" + +msgid "_Jun" +msgstr "juin" + +msgid "_Jul" +msgstr "juil." + +msgid "_Aug" +msgstr "août" + +msgid "_Sep" +msgstr "sept." + +msgid "_Oct" +msgstr "oct." + +msgid "_Nov" +msgstr "nov." + +msgid "_Dec" +msgstr "déc." + +msgid "January" +msgstr "janvier" + +msgid "February" +msgstr "février" + +msgid "March" +msgstr "mars" + +msgid "April" +msgstr "avril" + +msgid "May" +msgstr "mai" + +msgid "June" +msgstr "juin" + +msgid "July" +msgstr "juillet" + +msgid "August" +msgstr "août" + +msgid "September" +msgstr "septembre" + +msgid "October" +msgstr "octobre" + +msgid "November" +msgstr "novembre" + +msgid "December" +msgstr "décembre" + +msgid "_Mon" +msgstr "lun." + +msgid "_Tue" +msgstr "mar." + +msgid "_Wed" +msgstr "mer." + +msgid "_Thu" +msgstr "jeu." + +msgid "_Fri" +msgstr "ven." + +msgid "_Sat" +msgstr "sam." + +msgid "_Sun" +msgstr "dim." + +msgid "Monday" +msgstr "lundi" + +msgid "Tuesday" +msgstr "mardi" + +msgid "Wednesday" +msgstr "mercredi" + +msgid "Thursday" +msgstr "jeudi" + +msgid "Friday" +msgstr "vendredi" + +msgid "Saturday" +msgstr "samedi" + +msgid "Sunday" +msgstr "dimanche" + +#~ msgid "%A, %B %e %Y" +#~ msgstr "%A %e %B %Y" diff --git a/v2/dotclear/locales/fr/help/blowupConfig.html b/v2/dotclear/locales/fr/help/blowupConfig.html new file mode 100644 index 0000000..9d41c14 --- /dev/null +++ b/v2/dotclear/locales/fr/help/blowupConfig.html @@ -0,0 +1,71 @@ + + + + Configuration du thème Blowup + + + +

        En modifiant la configuration du thème Blowup, vous pouvez personnaliser votre +thème très facilement. Pour cela, renseignez simplement les champs de configuration +ou choisissez un style prédéfini.

        + +

        Couleurs

        + +

        Quand vous devez indiquer une valeur de couleur, celle-ci doit être au format +hexadécimal. Par exemple : "#FF0000" donnera du rouge. Vous pouvez vous aider +de la pipette à côté de chaque champs de couleur.

        +

        Si vous manquez d'inspiration vous pouvez consulter :

        + + +

        Unités de mesure

        + +

        Quand vous devez indiquer une taille, celle-ci doit être suivie d'une unité +de mesure. Par exemple : "1em". Si vous n'indiquez aucune unité, la valeur +donnée prendra des pixels comme unité par défaut.

        +

        Les unités possibles sont :

        +
          +
        • px
        • +
        • em
        • +
        • ex
        • +
        • pt
        • +
        • %
        • +
        + +

        Images d'en-tête

        + +

        Vous pouvez choisir une image d'en-tête parmi une liste de nombreuses images +afin de remplacer celle utilisée par défaut.

        + +

        En choisissant "Personnalisé..." parmi la liste d'images, vous pourrez +déposer votre propre image. Celle-ci doit être au format JPG ou PNG et +avoir une largeur exacte de 800 pixels. + +

        Si vous déposez une image au format JPG, un cadre sera ajouté autours de +l'image, ce qui n'est pas le cas avec une image au format PNG (dont la +transparence sera également préservée).

        + +

        Styles prédéfinis

        + +

        Vous pouvez choisir un style prédéfini dans la liste d'option "Styles prédéfinis". +Une fois le style choisi, vous devez valider le formulaire pour appliquer les +changements.

        + +

        Vous pouvez ensuite modifier le style prédéfini comme bon vous semble.

        + +

        Import / export de configuration

        + +

        À la fin des options de Blowup, vous pouvez afficher une zone appelée "Import +/ export de configuration". Dans cette zone de texte se trouve la configuration +en cours d'utilisation. Vous pouvez la copier pour la partager avec d'autres.

        + +

        Pour appliquer (importer) une configuration, il suffit simplement de remplacer +le contenu de la zone de texte par celui que vous voulez utiliser. N'oubliez pas +de cliquer sur "appliquer le code".

        + + + \ No newline at end of file diff --git a/v2/dotclear/locales/fr/help/core_blog_pref.html b/v2/dotclear/locales/fr/help/core_blog_pref.html new file mode 100644 index 0000000..b9a79c1 --- /dev/null +++ b/v2/dotclear/locales/fr/help/core_blog_pref.html @@ -0,0 +1,191 @@ + + + Préférences du blog + + + + +

        Informations du blog

        +
        +
        Identifiant du blog
        +
        Identifiant unique du blog. Obligatoire, ne peut être modifié que par un + super administrateur.
        + +
        Nom du blog
        +
        Nom du blog, obligatoire.
        + +
        URL du blog
        +
        URL complète du blog. Obligatoire, ne peut être modifiée que par un super + administrateur.
        + +
        Méthode de lecture de l'URL
        +
        Définit le mode de lecture de l'URL. PATH_INFO est conseillé, QUERY_STRING + doit être utilisé si le premier ne fonctionne pas. En mode PATH_INFO, l'URL du + blog doit se terminer par un "/" et en mode QUERY_STRING, par un "?".
        + +
        État du blog
        +
        +
          +
        • en ligne : blog accessible aux visiteurs
        • +
        • hors ligne : blog inaccessible aux visiteurs + mais les rédacteurs peuvent se connecter
        • +
        • supprimé : blog inaccessible aux visiteurs + comme aux rédacteurs
        • +
        +
        + +
        Description du blog
        +
        Texte libre de description du blog. Il s'agit d'un texte simple, sans + formatage quelconque.
        +
        + +

        Configuration du blog

        +
        +
        Nom de l'éditeur du blog
        +
        Nom de la personne responsable du contenu du blog. Peut être le propriétaire + ou le directeur de publication s'il existe. Information affichée dans les + informations du flux de syndication.
        + +
        Note de copyright
        +
        Note indiquant les droits de reproduction autorisés pour le blog.
        + +
        Langue par défaut
        +
        Langue de l'interface du blog. Si cette langue existe parmi les + traductions, l'interface sera traduite dans celle-ci, sinon elle apparaîtra + en Anglais.
        + +
        Fuseau horaire du blog
        +
        Définit le fuseau horaire qui sera utilisé pour dater les commentaires et + trackbacks entrant sur le blog.
        + +
        Format des dates
        +
        Indique le format de la date d'un billet sur le blog. Voir la section + "formatage des dates" pour plus détails.
        + +
        Format des heures
        +
        Indique le format de l'heure d'un billet sur le blog. Voir la section + "formatage des dates" pour plus détails.
        + +
        Laisser les commentaires ouverts durant .. jours
        +
        Permet d'indiquer le nombre de jours durant lesquels les commentaires + sont possibles sur un billet après sa publication. Aucune valeur laissera + les commentaires toujours ouverts.
        + +
        Laisser les rétroliens ouverts durant .. jours
        +
        Permet d'indiquer le nombre de jours durant lesquels les rétroliens + sont possibles sur un billet après sa publication. Aucune valeur laissera + les rétroliens toujours ouverts.
        + +
        Accepter les commentaires
        +
        Accepter globalement les commentaires sur le blog. Ce paramètre est + supérieur à celui autorisant ou non les commentaires sur un billet.
        + +
        Accepter les rétroliens
        +
        Accepter globalement les rétroliens sur le blog. Ce paramètre est + supérieur à celui autorisant ou non les rétroliens sur un billet.
        + +
        Modérer les commentaires
        +
        Si cette option est activée, les commentaires ne seront publiés qu'après + l'approbation d'un rédacteur.
        + +
        Modérer les rétroliens
        +
        Si cette option est activée, les rétroliens ne seront publiés qu'après + l'approbation d'un rédacteur.
        + +
        Ajouter la relation "nofollow" aux liens des commentaires et rétroliens
        +
        Ajoute un attribut sur les liens des commentaires et rétroliens indiquant + aux robots des moteurs de recherche de ne pas les suivre. Cette mesure + est censée permettre de lutter contre le spam mais n'a pas encore vraiment + prouvé son efficacité.
        + +
        Syntaxe wiki pour les commentaires
        +
        Autoriser quelques éléments de la syntaxe wiki dans les commentaires.
        + +
        Afficher .. billets par page
        +
        Le nombre donné sera utilisé comme limite d'affichage des billets sur la + page d'accueil et la première page de chaque catégorie.
        + +
        Afficher des émoticônes dans les billets et commentaires
        +
        Remplacer certaines suites de caractères comme :-) ou ;-) par des images.
        + +
        Afficher .. billets par flux de syndication
        +
        Le nombre donné sera utilisé comme limite d'affichage des billets dans + les flux de syndication.
        + +
        Afficher .. commentaires par flux de syndication
        +
        Le nombre donné sera utilisé comme limite d'affichage des commentaires dans + les flux de syndication.
        + +
        Tronquer le flux de syndication
        +
        Cette option permet de ne fournir qu'un extrait des billets dans les flux + de syndication.
        +
        + +

        Formatage des dates

        +

        Certains champs permettent de formater les dates avec des caractères +particuliers dont voici la définition :

        + +
          +
        • %a : nom abrégé du jour de la semaine (local).
        • +
        • %A : nom complet du jour de la semaine (local).
        • +
        • %b : nom abrégé du mois (local).
        • +
        • %B : nom complet du mois (local).
        • +
        • %c : représentation préférée pour les dates et + heures, en local.
        • +
        • %C : numéro de siècle (l'année, divisée par 100 et + arrondie entre 00 et 99)
        • +
        • %d : jour du mois en numérique (intervalle 01 à + 31)
        • +
        • %D : identique à %m/%d/%y
        • +
        • %e : numéro du jour du mois. Les chiffres sont + précédés d'un espace (de ' 1' à '31')
        • +
        • %g : identique à %G, sur 2 chiffres.
        • +
        • %G : L'année sur 4 chiffres correspondant au numéro + de semaine (voir %V). Même format et valeur que %Y, excepté que si le numéro + de la semaine appartient à l'année précédente ou suivante, l'année courante + sera utilisé à la place.
        • +
        • %h : identique à %b
        • +
        • %H : heure de la journée en numérique, et sur + 24-heures (intervalle de 00 à 23)
        • +
        • %I : heure de la journée en numérique, et sur 12- + heures (intervalle 01 à 12)
        • +
        • %j : jour de l'année, en numérique (intervalle 001 à + 366)
        • +
        • %m : mois en numérique (intervalle 1 à 12)
        • +
        • %M : minute en numérique
        • +
        • %n : newline character
        • +
        • %p : soit `am' ou `pm' en fonction de l'heure + absolue, ou en fonction des valeurs enregistrées en local.
        • +
        • %r : l'heure au format a.m. et p.m.
        • +
        • %R : l'heure au format 24h
        • +
        • %S : secondes en numérique
        • +
        • %t : tabulation
        • +
        • %T : l'heure actuelle (égal à %H:%M:%S)
        • +
        • %u : le numéro de jour dans la semaine, de 1 à 7. (1 + représente Lundi)
        • +
        • %U : numéro de semaine dans l'année, en considérant + le premier dimanche de l'année comme le premier jour de la première + semaine.
        • +
        • %V : le numéro de semaine comme défini dans l'ISO + 8601:1988, sous forme décimale, de 01 à 53. La semaine 1 est la première + semaine qui a plus de 4 jours dans l'année courante, et dont Lundi est le + premier jour. (Utilisez %G ou %g pour les éléments de l'année qui + correspondent au numéro de la semaine pour le timestamp donné.)
        • +
        • %W : numéro de semaine dans l'année, en considérant + le premier lundi de l'année comme le premier jour de la première semaine
        • +
        • %w : jour de la semaine, numérique, avec Dimanche = + 0
        • +
        • %x : format préféré de représentation de la date + sans l'heure
        • +
        • %X : format préféré de représentation de l'heure + sans la date
        • +
        • %y : l'année, numérique, sur deux chiffres (de 00 à + 99)
        • +
        • %Y : l'année, numérique, sur quatre chiffres
        • +
        • %Z ou %z : fuseau horaire, ou nom ou + abréviation
        • +
        • %% : un caractère `%' littéral
        • +
        + + + \ No newline at end of file diff --git a/v2/dotclear/locales/fr/help/core_categories.html b/v2/dotclear/locales/fr/help/core_categories.html new file mode 100644 index 0000000..002800e --- /dev/null +++ b/v2/dotclear/locales/fr/help/core_categories.html @@ -0,0 +1,50 @@ + + + Catégories + + + +

        Liste des categories

        +
        +
        Créer une nouvelle catégorie
        +
        Choisissez le nom que vous souhaitez donner à votre nouvelle catégorie + puis cliquer sur Enregistrer pour valider sa création. Vous pouvez choisir + sa catégorie parente ou la laisser au premier niveau. Pour modifier la catégorie, + cliquez sur son nom dans la liste.
        + +
        Supprimer une catégorie
        +
        Choisissez la catégorie que vous voulez supprimer et cliquez sur ok. + Une catégorie ne peut être supprimée que si elle ne contient aucun billet.
        + +
        Réordonner les catégories
        +
        Utilisez cette option pour placer toutes les catégories au même niveau. + Si vous voulez modifier l'ordre des catégories plus précisément, cliquez sur le nom de chacune d'entre elles + et choisissez sa catégorie parente ou sa position par rapport à ses voisines.
        +
        + +

        Modifier une catégorie

        +
        +
        Titre
        +
        Choisissez le nom que vous souhaitez donner à votre nouvelle catégorie + puis cliquer sur Enregistrer pour valider sa création.
        + +
        URL
        +
        DotClear crée une url par défaut de la catégorie, qui sera ainsi + accessible avec un chemin de la forme + http://monblog.tld/category/Ma-categorie. En cliquant sur le + petit verrou situé à la droite, vous pouvez la modifier comme il vous + plaira.
        + +
        Description
        +
        Le contenu de ce champ de description sera affiché lors de la sélection + d'une catégorie dans le blog. Vous pouvez le remplir avec toute forme de + contenu (paragraphes, listes, etc.) Le format du texte de la description est + HTML.
        + +
        Déplacer cette catégorie
        +
        Vous pouvez déplacer la catégorie dans n'importe quelle autre, qui deviendra sa parente. + Vous pouvez aussi spécifier sa position par rapport à ses voisines en la plaçant avant ou après l'une d'elles.
        +
        + + + \ No newline at end of file diff --git a/v2/dotclear/locales/fr/help/core_comments.html b/v2/dotclear/locales/fr/help/core_comments.html new file mode 100644 index 0000000..1fe0676 --- /dev/null +++ b/v2/dotclear/locales/fr/help/core_comments.html @@ -0,0 +1,59 @@ + + + Commentaires + + + +

        Filtres de la liste des commentaires

        +
        +
        Type :
        +
        Aucun ou commentaires ou rétroliens.
        + +
        État :
        +
          +
        • indésirable : reconnu comme spam ;
        • +
        • en attente : en attente de modération ;
        • +
        • non publié : hors ligne ;
        • +
        • publié : en ligne.
        • +
        + +
        Trier par :
        +
        Choisir : date, ou titre du billet, ou auteur ou état, puis indiquez si vous + souhaitez que les résultats s'affichent par ordre croissant ou décroissant.
        + +
        Trier
        +
        Indique l'ordre dans lequel on souhaite effectuer le tri.
        + +
        Auteur du commentaire.
        +
        Recherche indifféremment avec des minuscules ou majuscules. On peut chercher + sur une partie du nom en utilisant le caractère joker + *.
        + +
        Commentaires par page :
        +
        Détermine le nombre de commentaires affichés par page de cette liste.
        +
        + +

        Modifier ou ajouter un commentaire

        +
        +
        Auteur :
        +
        Nom de l'auteur. Ce champ est obligatoire.
        + +
        Email :
        +
        Adresse mail de l'auteur du commmentaire.
        + +
        Site web :
        +
        URL du site ou du blog de l'auteur du commentaire.
        + +
        État :
        +
          +
        • indésirable : reconnu comme spam ;
        • +
        • en attente : en attente de modération ;
        • +
        • non publié : hors ligne
        • +
        • publié : en ligne
        • +
        + +
        Commentaire :
        +
        Contenu du commentaire. Ce champ utilise la syntaxe HTML.
        +
        + + \ No newline at end of file diff --git a/v2/dotclear/locales/fr/help/core_media.html b/v2/dotclear/locales/fr/help/core_media.html new file mode 100644 index 0000000..aeb6e85 --- /dev/null +++ b/v2/dotclear/locales/fr/help/core_media.html @@ -0,0 +1,97 @@ + + + Gestionnaire de media + + + + +

        Liste des médias

        +

        La page principale du gestionnaire de médias présente la liste des fichiers +(médias) disponibles pour le blog en cours d'utilisation.

        + +

        Il est possible d'afficher les médias dans des répertoires ou sous +répertoires en cliquant sur leurs icônes ou leurs noms.

        + +

        Les fichiers son au format MP3 sont présentés avec un lecteur permettant +d'en prendre immédiatement connaissance. Ce lecteur nécessite un lecteur (ou +plugin) Flash sur votre navigateur.

        + +

        Les images sont affichées avec une miniature quand cela est possible.

        + +

        Ajouter des fichiers

        +
        +
        Choisissez un fichier
        +
        Permet de choisir un fichier sur son disque dur pour l'envoyer sur le + blog. Si le fichier dépasse la taille maximale, il ne pourra être envoyé.
        + +
        Titre
        +
        Titre optionnel du fichier à envoyer.
        + +
        Privé
        +
        Indique que le fichier envoyé n'est visible que par son propriétaire tant + qu'il n'est pas publié sur le blog.
        +
        + +

        Nouveau répertoire

        +

        Ce formulaire permet de créer un nouveau répertoire dans le répertoire en +cours d'utilisation. Indiquez simplement un nom comme vous le feriez sur votre +ordinateur.

        + +

        Détails du média

        +

        La page individuelle d'un média présente un ensemble d'informations sur +celui-ci et permet d'effectuer quelques opérations.

        + +
        +
        Nom du fichier
        +
        Changer le nom du fichier en cours.
        + +
        Titre du fichier
        +
        Changer ou donner un titre au fichier en cours.
        + +
        Date du fichier
        +
        Changer la date du fichier.
        + +
        Privé
        +
        Changer le caractère privé ou non du média.
        + +
        Nouveau répertoire
        +
        Permet de changer l'emplacement du fichier.
        + +
        Changer le fichier
        +
        Ce formulaire permet de changer le fichier tout en conservant ses + attributs (nom, titre...). Comme toujours, il ne peut dépasser la taille + maximalle indiquée.
        +
        + +

        Cas particulier des images

        +

        Lors de l'ajout d'une image, jusqu'à quatre versions de celle-ci peuvent +être disponibles (selon la taille de l'image d'origine) :

        +
          +
        • carrée : image carrée de 48 pixels de côté,
        • +
        • miniature : image réduite à 100 pixels sur son plus grand côté,
        • +
        • petite : image réduite à 240 pixels sur son plus grand côté,
        • +
        • moyenne : image réduite à 500 pixes sur son plus grand côté,
        • +
        • originale : image originale non transformée.
        • +
        +

        Les tailles par défaut des versions miniature, petite et moyenne, peuvent être modifiées dans les paramètres du blog

        + +

        Attacher un fichier à un billet

        +

        Vous pouvez attacher un fichier à un billet très facilement. Commencez par +créer un nouveau billet et enregistrez-le. Cliquez alors sur "ajouter un fichier +au billet" pour ouvrir le gestionnaire de médias.

        + +

        En cliquant sur l'icône [+] (Attacher un fichier au billet) vous pourrez +joindre le fichier à votre billet.

        + +

        Les fichiers attachés à un billet seront visibles sur la page individuelle +du billet, sous la forme d'une liste après le contenu du billet. Les fichiers +MP3 seront automatiquement accompagnés d'un lecteur en Flash permettant la +lecture directe du fichier.

        + +

        Podcast et diffusion de fichiers musicaux

        +

        Tous les fichiers attachés à un billet seront présents dans les fils RSS de +vos billets, vous permettant ainsi de réaliser des podcast de n'importe quel +type de fichier.

        + + + \ No newline at end of file diff --git a/v2/dotclear/locales/fr/help/core_post.html b/v2/dotclear/locales/fr/help/core_post.html new file mode 100644 index 0000000..418a7ec --- /dev/null +++ b/v2/dotclear/locales/fr/help/core_post.html @@ -0,0 +1,137 @@ + + + Rédaction d'un billet + + + + +

        Rédaction du billet

        + +
        +
        Titre du billet
        +
        Inscrivez le titre du billet. Ce champ est obligatoire.
        + +
        Extrait
        +
        Le contenu de ce champ s'affichera dans les pages présentant les listes de + billets telles que la page d'accueil ou le tri sur une catégorie, suivi d'un + lien « Lire la suite ». Il figurera également au début du billet dans le + contexte de l'affichage du billet seul. Si vous ne remplissez pas ce champ, le + champ Contenu sera intégralement affiché dès la page d'accueil.
        + +
        Contenu
        +
        Le contenu du billet. Ce champ est obligatoire.
        + +
        Notes
        +
        Cette zone de texte sert à la prise de notes ou pense-bête divers. Elle ne + sera jamais affichée sur le blog.
        + +
        Catégorie
        +
        La catégorie de votre billet. Pour créer une nouvelle catégorie, rendez vous + dans la section "catégories". Vous pouvez n'affecter + votre billet à aucune catégorie en choisissant la ligne vide.
        + +
        État du billet
        +
        Permet de choisir l'état du billet après enregistrement : +
          +
        • en attente : en attente de publication.
        • +
        • programmé : le billet sera mis en ligne aux date et heure + indiquées dans le champ Publié le.
        • +
        • non publié : billet hors ligne.
        • +
        • publié : billet en ligne.
        • +
        +
        + +
        Publié le
        +
        Permet de modifier la date et l'heure de publication du billet. Si vous avez + choisi le statut programmé il sera mis en ligne aux date et heure + définis dans ce champ.
        + +
        Format du texte
        +
        Permet de choisir la syntaxe de saisie du billet. Le wiki est une syntaxe + simplifiée et sera converti en xhtml valide ; à moins que vous maîtrisiez + parfaitement le xhtml nous vous conseillons de la choisir de préférence. + Consultez la référence de la syntaxe Wiki pour plus + d'informations.
        + +
        Accepter les commentaires
        +
        Cochez ou décochez la case selon que vous souhaitez permettre ou interdire + les commentaires sur le billet en particulier. L'option pour permettre ou + autoriser de façon générale les commentaires se situe dans le menu Préférences + du blog.
        + +
        Accepter les rétroliens
        +
        Un rétrolien permet de signaler un billet dans les commentaires d'un autre + blog. Cochez ou décochez la case selon que vous souhaitez permettre ou interdire + les rétroliens sur le billet. L'option pour permettre ou autoriser de façon + générale les rétroliens se situe dans le menu Préférences du blog.
        + +
        Billet sélectionné
        +
        Les billets marqués comme sélectionnés apparaîtront dans le menu de votre + blog, sous l'intitulé « A retenir ».
        + +
        Mot de passe du billet
        +
        Permet de déterminer un mot de passe d'accès à un billet dans le blog. Un + billet protégé par mot de passe ne sera visible nulle part sur votre blog, vous + pourrez en donner l'adresse à vos lecteurs en vous rendant sur le lien + voir le billet.
        + +
        URL spécifique
        +
        Ce champ permet de choisir une URL pour un billet autre que celle par défaut + après avoir cliqué sur le petit verrou placé à sa droite. Si vous essayez + d'utiliser une URL déjà existante, celle-ci se verra incrémentée d'un chiffre.
        + +
        Langue du billet
        +
        Code langue de votre billet. Par défaut, il s'agit du code de votre + langue. Vous pouvez le changer, par le code d'une autre langue, par + exemple "en", "fr-qc". Ce code est libre, il sera utilisé lors de l'affichage + des billets.
        + +
        Pièces jointes
        +
        Les pièces jointes sont tous les médias attachés au billet. Le lien + d'ajout d'une pièce jointe permet de choisir un fichier à ajouter au billet. + Pensez à sauvegarder votre billet avant de choisir une pièce jointe. Consultez + l'aide du gestionnaire de médias pour plus de détails.
        +
        + +

        Rétroliens

        +

        Pour faire un rétrolien cliquez sur le lien Faire des rétroliens. +Si vous ne voyez pas ce lien, vérifiez que votre billet est bien dans l'état +publié.

        + +
        +
        URLs à rétrolier
        +
        Indiquez ici la ou les URL que vous aurez relevé dans le billet vers lequel + vous souhaitez envoyer un rétrolien.
        + + +
        Envoyer l'extrait
        +
        Par défaut, ce champ comporte le début de votre billet. C'est ce qui sera + envoyé vers le blog que vous rétroliez avec un lien vers votre billet complet. + Vous pouvez modifier le contenu de cette "accroche" en saisissant directement le + texte de votre choix dans ce champ.
        + + +
        Découverte automatique des URLs à rétrolier
        +
        Si votre billet comporte des liens vers des billets précis et si la + plate-forme du blog destinataire est configurée pour le permettre, cette + fonction découvrira automatiquement les URLs spécifiques d'envoi de + rétrolien.
        +
        + +

        Commentaires

        +
        +
        Liste les commentaires
        +
        Depuis l'onglets Commentaires vous pouvez lire et changer l'état + des commentaires de votre billet. Suivant vos permissions, vous pouvez modifier, + mettre en ligne ou hors ligne, supprimer ou classer comme commentaire + indésirable.
        + +
        Ajouter un commentaire
        +
        Depuis l'onglet Ajouter un commentaire vous pouvez répondre + directement à un commentaire sans passer par votre blog. Cette interface vous + permet également de saisir votre commentaire en xhtml, sans limitation. Vous + devrez remplir les champs de la même manière qu'en modifiant un commentaire
        +
        + + + diff --git a/v2/dotclear/locales/fr/help/core_posts.html b/v2/dotclear/locales/fr/help/core_posts.html new file mode 100644 index 0000000..69b8cf1 --- /dev/null +++ b/v2/dotclear/locales/fr/help/core_posts.html @@ -0,0 +1,65 @@ + + + Gestion des billets + + + + +

        Filtres de la liste des billets

        + +
        +
        Auteur
        +
        Permet de filtrer les billets par auteur.
        + +
        Catégorie
        +
        Filtrer les billets par catégorie.
        + +
        État
        +
          +
        • en attente : en attente de publication.
        • +
        • programmé : le billet sera mis en ligne aux date et heure + indiquées dans le champ Publié le.
        • +
        • non publié : billet hors ligne.
        • +
        • publié : billet en ligne.
        • +
        + +
        Sélectionné
        +
        Aucun, billet marqué comme sélectionné ou non sélectionné.
        + +
        Mois
        +
        Filtre les billets d'un mois d'une année donné.
        + +
        Langue
        +
        Filtre les billets selon la langue indiquée dans le champ langue du + billet.
        + +
        Trier par
        +
        Permet de trier les résultats de filtrage selon la date, le titre, + la catégorie, l'auteur, l'état de publication ou l'état de sélection.
        + +
        Trier
        +
        Indique l'ordre dans lequel on souhaite effectuer le tri.
        + +
        Billets par page
        +
        Nombre de billets à afficher par page de résultat.
        +
        + +

        Actions par lot sur les billets

        +

        Il est possible d'effectuer un ensemble d'actions sur plusieurs billets, d'un +seul coup. Les actions possibles dépendent des permissions de l'utilisateur.

        + +
          +
        • Publier : mettre le billet en ligne,
        • +
        • Hors ligne : mettre le billet hors ligne,
        • +
        • Programmer : programmer le billet pour mise en ligne à la date de + publication,
        • +
        • En attente : en attente de publication,
        • +
        • Changer de catégorie : envoie sur la liste des catégories pour + changer celle des billets sélectionnés,
        • +
        • Changer l'auteur : permet de changer l'auteur du billet en indiquant + l'identifiant de l'utilisateur qui deviendra le nouvel auteur,
        • +
        • Supprimer : supprime le billet (cette opération est irréversible).
        • +
        + + + \ No newline at end of file diff --git a/v2/dotclear/locales/fr/help/core_user.html b/v2/dotclear/locales/fr/help/core_user.html new file mode 100644 index 0000000..9ebc52e --- /dev/null +++ b/v2/dotclear/locales/fr/help/core_user.html @@ -0,0 +1,74 @@ + + + Utilisateur + + + + +

        Informations utilisateur

        +
        +
        Nom d'utilisateur
        +
        Il doit être composé d'au moins 2 caractères (lettres non accentuées, chiffres ou symboles, pas d'espace). Ce champ est obligatoire.
        + +
        Mot de passe
        +
        Indiquez deux fois le mot de passe dans les champs Mot de passe et Confirmer le mot de + passe. Le mot de passe doit être long d'au moins 6 caractères. + Ces deux champs sont obligatoires.
        + +
        Nom, Prénom
        +
        Si le pseudonyme n'est pas renseigné, le nom de l'auteur qui sera affiché + sera composé des noms et prénoms renseignés dans ces champs.
        + +
        Pseudonyme
        +
        Vous pouvez choisir ici le nom sous lequel vos billets seront signés. S'il est renseigné, le pseudonyme se substitue au nom et au prénom.
        + +
        Email
        +
        Cette adresse sera utilisée lors de la régénération du mot de passe depuis la fenêtre d'authentification de dotclear.
        + +
        URL
        +
        Indique le site web de l'utilisateur. S'il est indiqué, le nom du rédacteur + d'un billet sera présenté comme un lien vers le site donné.
        + +
        Format d'édition préféré
        +
        Choix de la syntaxe par défaut pour la saisie des billets. Le wiki est une + syntaxe simplifiée et sera converti en xhtml valide ; à moins que vous ne + maîtrisiez parfaitement le xhtml, nous vous conseillons le choix du wiki.
        + +
        État des billets par défaut
        +
        Le statut par défaut des billets peut être déterminé à : +
          +
        • en attente : le statut de publication n'a pas encore + été décidé.
        • +
        • programmé : le billet sera mis en ligne aux date et + heure indiquées dans le champ Publié le.
        • +
        • non publié : billet hors ligne.
        • +
        • publié : billet en ligne.
        • +
        +
        + +
        Taille de la zone d'édition
        +
        Fixe la hauteur de la zone d'édtion du billet. Par défaut ce paramètre est + réglé à la valeur 24.
        + +
        Langue de l'utilisateur
        +
        Indique la langue dans laquelle on souhaite publier ses billets. Si la + traduction existe, l'interface sera également traduite dans cette langue.
        + +
        Fuseau horaire de l'utilisateur
        +
        Ce choix déterminera l'affichage de l'heure de publication des billets.
        + +
        Changement de mot de passe requis pour la connexion
        +
        Cocher cette case permettra au nouvel utilisateur de choisir par lui-même son mot de passe de connexion.
        + +
        Super administrateur
        +
        Ce choix attribuera toutes les permissions au profil utilisateur sur l'ensemble des blogs de l'installation.
        +
        + +

        Tags

        +
        +
        Format de la liste des tags
        +
        Ce choix permet, dans la page d'édition d'un billet, d'afficher tous les tags + disponibles ou seulement les plus utilisés.
        +
        + + \ No newline at end of file diff --git a/v2/dotclear/locales/fr/help/core_user_pref.html b/v2/dotclear/locales/fr/help/core_user_pref.html new file mode 100644 index 0000000..f119686 --- /dev/null +++ b/v2/dotclear/locales/fr/help/core_user_pref.html @@ -0,0 +1,91 @@ + + + Préférences utilisateur + + + + +

        Mon profil

        +
        +
        Nom, Prénom
        +
        Si le pseudonyme n'est pas renseigné, le nom de l'auteur qui sera affiché + sera composé des noms et prénoms renseignés dans ces champs.
        + +
        Pseudonyme
        +
        Vous pouvez choisir ici le nom sous lequel vos billets seront signés. S'il est renseigné, le pseudonyme se substitue au nom et au prénom.
        + +
        Email
        +
        Adresse à laquelle devront être envoyées les notifications de nouveaux + commentaires par email.
        + +
        URL
        +
        Indique le site web de l'utilisateur. S'il est indiqué, le nom du rédacteur + d'un billet sera présenté comme un lien vers le site donné.
        + +
        Langue de l'utilisateur
        +
        Indique la langue dans laquelle on souhaite publier ses billets. Si la + traduction existe, l'interface sera également traduite dans cette langue.
        + +
        Fuseau horaire de l'utilisateur
        +
        Ce choix déterminera l'affichage de l'heure de publication des billets.
        + +
        Changer le mot de passe
        +
        Pour changer votre mot de passe, indiquez deux fois le nouveau mot de passe + dans les champs Nouveau mot de passe et Confirmer le mot de + passe. Le mot de passe doit être long d'au moins 6 caractères. + Si aucun mot de passe n'est spécifié, il ne sera pas changé.
        +
        + +

        Mes options

        +
        +
        Format d'édition préféré
        +
        Choix de la syntaxe par défaut pour la saisie des billets. Le wiki est une + syntaxe simplifiée et sera converti en xhtml valide ; à moins que vous ne + maîtrisiez parfaitement le xhtml, nous vous conseillons le choix du wiki.
        + +
        État des billets par défaut
        +
        Le statut par défaut des billets peut être déterminé à : +
          +
        • en attente : le statut de publication n'a pas encore + été décidé.
        • +
        • programmé : le billet sera mis en ligne aux date et + heure indiquées dans le champ Publié le.
        • +
        • non publié : billet hors ligne.
        • +
        • publié : billet en ligne.
        • +
        +
        + +
        Taille de la zone d'édition
        +
        Fixe la hauteur de la zone d'édtion du billet. Par défaut ce paramètre est + réglé à la valeur 24.
        + +
        Activer l'éditeur visuel
        +
        Permet d'activer ou non l'éditeur visuel des billets et des catégories.
        + +
        Activer l'interface avancée du gestionnaire de médias
        +
        Cette option permet d'envoyer plusieurs fichiers à la fois sur le serveur. + Nécessite la présence du plugin Flash dans votre navigateur.
        + +
        Modules du tableau de bord
        +
        Les choix opérés dans cette zone détermineront l'affichage de + ces blocs sur le tableau de bord.
        + +
        Format de la liste de tags
        +
        Ce choix permet, dans la page d'édition d'un billet, d'afficher tous les tags + disponibles ou seulement les plus utilisés.
        +
        +

        Mes favoris

        +
        +
        Mes favoris
        +
        Cette zone affiche les favoris actuellement utilisés. Ils peuvent être réordonnés + au moyen de la souris si javascript est activé dans votre navigateur. Sinon, une case + permet d'attribuer à chaque favori un numéro d'ordre. Lorsque vous avez terminé, n'oubliez + pas d'enregistrer vos modifications. Vous pouvez aussi sélectionner les favoris à supprimer + du tableau de bord.
        + +
        Favoris disponibles
        +
        Tous les plugins permettant d'être mis en favoris sont listés ici. + Cochez les cases correspondantes aux favoris que vous souhaitez utiliser, puis ajoutez-les.
        +
        + + \ No newline at end of file diff --git a/v2/dotclear/locales/fr/help/core_wiki.html b/v2/dotclear/locales/fr/help/core_wiki.html new file mode 100644 index 0000000..1fb3b90 --- /dev/null +++ b/v2/dotclear/locales/fr/help/core_wiki.html @@ -0,0 +1,85 @@ + + + Référence de la syntaxe Wiki + + + + +

        Référence de la syntaxe Wiki

        + +

        La syntaxe Wiki est une manière d'écrire du texte avec un jeu de balises +réduit au minimum, permettant de couvrir les besoins les plus courants +(titres, paragraphes, citations, listes...).

        + +
        +
        Éléments de bloc
        +
        +
          +
        • Laissez une ligne vide entre chaque bloc de même nature.
        • +
        • Paragraphe : texte libre, terminé par une ligne + vide si suivi d'un second paragraphe.
        • +
        • Titre : !!! titre, !! titre + ou ! titre pour des titres plus ou moins importants.
        • +
        • Trait horizontal : ----
        • +
        • Listes : lignes débutant par * pour des + listes à puce ou # pour des listes numérotées. Vous pouvez faire + des listes imbriquées en mélangeant les codes de liste. Par exemple : +
          +* item 1
          +** item 1.1
          +* item 2
          +*# item 2.1
          +...
          +
          +
        • +
        • Texte préformaté : espace avant chaque ligne de texte.
        • +
        • Bloc de citation : > devant chaque + ligne de texte.
        • +
        +
        + +
        Éléments de formatage
        +
        +
          +
        • Emphase : deux apostrophes ''texte''
        • +
        • Forte emphase : deux soulignés __texte__
        • +
        • Retour forcé à la ligne : %%%
        • +
        • Insertion : deux plus ++texte++
        • +
        • Suppression : deux moins --texte--
        • +
        • Lien : [url], [nom|url], + [nom|url|langue] ou [nom|url|langue|titre]
        • +
        • Image : + ((url|texte alternatif)), + ((url|texte alternatif|position)) ou + ((url|texte alternatif|position|description longue)). +
          La position peut prendre les valeurs L ou G (gauche), R ou D (droite) ou C (centré).
        • +
        • Ancre : ~ancre~
        • +
        • Acronyme : ??acronyme|titre??
        • +
        • Code HTML en ligne: deux apostrophes inversées ``code html``
        • +
        • Citation en ligne : {{citation}}, + {{citation|langue}} ou {{citation|langue|url}}
        • +
        • Code : @@code ici@@
        • +
        • Note de bas de page : $$Corps de la note$$
        • +
        +
        + +
        Empêcher le formatage du texte
        +
        Pour insérer un caractère sans que celui-ci soit reconnu comme un caractère +de formatage, ajoutez le caractère \ avant celui-ci. Par exemple : +\[texte entre crochet qui n'est pas un lien\] +
        + +
        Insérer du code HTML
        +
        Vous pouvez ponctuellement avoir besoin d'insérer du code HTML dans votre +texte au format Wiki. Pour cela, utilisez le code suivant : +
        +///html
        +<p style="color:red">mon texte en rouge</p>
        +///
        +
        +
        +
        + + + + \ No newline at end of file diff --git a/v2/dotclear/locales/fr/help/themeEditor.html b/v2/dotclear/locales/fr/help/themeEditor.html new file mode 100644 index 0000000..b79802b --- /dev/null +++ b/v2/dotclear/locales/fr/help/themeEditor.html @@ -0,0 +1,37 @@ + + + + Éditeur de thème + + + +

        L'éditeur de thème vous permet de modifier les fichiers template, les feuilles +de style et les fichiers JavaScript de votre thème en cours d'utilisation.

        + +

        La liste des fichiers est divisée en trois parties :

        +
          +
        • Fichiers template : les templates
        • +
        • Fichiers CSS : les feuilles de style
        • +
        • Fichiers JavaScript
        • +
        + +

        Une puce jaune contre le nom de chaque fichier indique que celui-ci fait partie +du thème. Une puce rouge indique qu'il se trouve dans le thème parent. +Une puce noire indique qu'il se trouve dans le thème "default".

        + +

        Si vous modifiez un fichier se trouvant dans le thème "default", celui-ci +sera copié dans votre thème en cours d'utilisation.

        + +

        Pour modifier un fichier, cliquez sur son nom, le contenu s'affichera alors +dans une zone d'édition. Si le fichier peut-être écrit vous pourrez sauvegarder +celui-ci en cliquant sur "enregistrer".

        + +

        Les modifications sont immédiatement appliquées lors de la sauvegarde, soyez +vigilants.

        + +

        Pour éditer vos templates, n'hésitez pas à consultez la +liste des marqueurs +de template.

        + + + \ No newline at end of file diff --git a/v2/dotclear/locales/fr/main.lang.php b/v2/dotclear/locales/fr/main.lang.php new file mode 100644 index 0000000..2609024 --- /dev/null +++ b/v2/dotclear/locales/fr/main.lang.php @@ -0,0 +1,923 @@ +This is a comment.

        +

        To delete it, log in and view your blog\'s comments. Then you might remove or edit it.

        '] = '

        Ceci est un commentaire

        Pour le supprimer, connectez-vous et affichez les commentaires de votre blog. Vous pourrez alors le supprimer ou le modifier.

        '; +$GLOBALS['__l10n']['Dotclear Install'] = 'Installation de Dotclear'; +$GLOBALS['__l10n']['show'] = 'voir'; +$GLOBALS['__l10n']['Dotclear installation'] = 'Installation de Dotclear'; +$GLOBALS['__l10n']['Cache directory %s is not writable.'] = 'Le répertoire de cache %s n\'est pas accessible en écriture.'; +$GLOBALS['__l10n']['Errors:'] = 'Erreurs :'; +$GLOBALS['__l10n']['Configuration file has been successfully created.'] = 'Le fichier de configuration a été créé avec succès.'; +$GLOBALS['__l10n']['User information'] = 'Informations utilisateur'; +$GLOBALS['__l10n']['Please provide the following information needed to create the first user.'] = 'Merci de fournir les informations suivantes pour créer le premier utilisateur.'; +$GLOBALS['__l10n']['First Name:'] = 'Prénom :'; +$GLOBALS['__l10n']['Last Name:'] = 'Nom :'; +$GLOBALS['__l10n']['Username and password'] = 'Identifiant et mot de passe'; +$GLOBALS['__l10n']['All done!'] = 'Terminé !'; +$GLOBALS['__l10n']['Dotclear has been successfully installed. Here is some useful information you should keep.'] = 'Dotclear a été installé avec succès. Conservez les informations suivantes précieusement.'; +$GLOBALS['__l10n']['Your account'] = 'Votre compte'; +$GLOBALS['__l10n']['Your blog'] = 'Votre blog'; +$GLOBALS['__l10n']['Blog address:'] = 'Adresse du blog :'; +$GLOBALS['__l10n']['Administration interface:'] = 'Interface d\'administration :'; +$GLOBALS['__l10n']['Manage your blog now'] = 'Gérez votre blog'; +$GLOBALS['__l10n']['Installation can not be completed'] = 'L\'installation ne peut pas être menée à bien'; +$GLOBALS['__l10n']['For the said reasons, Dotclear can not be installed. Please refer to the documentation to learn how to correct the problem.'] = 'Pour les raisons ci-dessus, Dotclear ne peut pas être installé. Référez-vous à la documentation pour savoir comment corriger le problème.'; +$GLOBALS['__l10n']['File %s does not exist.'] = 'Le fichier %s n\'existe pas.'; +$GLOBALS['__l10n']['Cannot write %s file.'] = 'Impossible d\'écrire le fichier %s.'; +$GLOBALS['__l10n']['Dotclear installation wizard'] = 'Assistant d\'installation de Dotclear'; +$GLOBALS['__l10n']['Welcome'] = 'Bienvenue'; +$GLOBALS['__l10n']['To complete your Dotclear installation and start writing on your blog, we just need to know how to access your database and who you are. Just fill this two steps wizard with this information and we will be done.'] = 'Pour achever votre installation de Dotclear, il ne manque plus que les informations concernant votre base de données, puis vos informations personnelles. Remplissez simplement les deux formulaires suivants et vous pourrez commencer à utiliser votre blog.'; +$GLOBALS['__l10n']['Attention:'] = 'Attention :'; +$GLOBALS['__l10n']['this wizard may not function on every host. If it does not work for you, please refer to the documentation to learn how to create the config.php file manually.'] = 'cet assistant peut ne pas fonctionner chez tous les hébergeurs. Si vous rencontrez un problème, vous trouverez comment créer le fichier de configuration dans la documentation.'; +$GLOBALS['__l10n']['System information'] = 'Informations système'; +$GLOBALS['__l10n']['Please provide the following information needed to create your configuration file.'] = 'Merci de fournir les informations suivantes :'; +$GLOBALS['__l10n']['Database type:'] = 'Type de base de données :'; +$GLOBALS['__l10n']['Database Host Name:'] = 'Nom d\'hôte de la base de données :'; +$GLOBALS['__l10n']['Database Name:'] = 'Nom de la base de données :'; +$GLOBALS['__l10n']['Database User Name:'] = 'Nom d\'utilisateur de la base de données :'; +$GLOBALS['__l10n']['Database Password:'] = 'Mot de passe de la base de données :'; +$GLOBALS['__l10n']['Database Tables Prefix:'] = 'Préfixe des tables de la base de données :'; +$GLOBALS['__l10n']['Continue'] = 'Continuer'; +$GLOBALS['__l10n']['No such installed language'] = 'Cette langue n\'est pas installée'; +$GLOBALS['__l10n']['You can\'t remove English language.'] = 'Vous ne pouvez pas supprimer la langue anglaise.'; +$GLOBALS['__l10n']['Permissions to delete language denied.'] = 'Permission de supprimer la langue refusée.'; +$GLOBALS['__l10n']['Invalid language file URL.'] = 'URL de fichier de langue invalide.'; +$GLOBALS['__l10n']['Languages management'] = 'Gestion des langues'; +$GLOBALS['__l10n']['Language has been successfully deleted.'] = 'La langue a été supprimée avec succès.'; +$GLOBALS['__l10n']['Language has been successfully installed.'] = 'La langue a été installée avec succès.'; +$GLOBALS['__l10n']['Language has been successfully upgraded'] = 'La langue a été mise à jour avec succès.'; +$GLOBALS['__l10n']['Here you can install, upgrade or remove languages for your Dotclear installation.'] = 'Sur cette page, vous pouvez installer, mettre à jour ou supprimer des langues de votre installation de Dotclear.'; +$GLOBALS['__l10n']['You can change your user language in your preferences or change your blog\'s main language in your blog settings.'] = 'Vous pouvez changer votre langue d\'utilisateur dans vos préférences ou changer la langue principale de votre blog dans vos paramètres de blog.'; +$GLOBALS['__l10n']['Installed languages'] = 'Langues installées'; +$GLOBALS['__l10n']['No additional language is installed.'] = 'Aucune langue supplémentaire n\'est installée.'; +$GLOBALS['__l10n']['Language'] = 'Langue'; +$GLOBALS['__l10n']['Action'] = 'Action'; +$GLOBALS['__l10n']['Install or upgrade languages'] = 'Installer ou mettre à jour une langue'; +$GLOBALS['__l10n']['You can install or remove a language by adding or removing the relevant directory in your %s folder.'] = 'Vous pouvez installer ou supprimer une langue en ajoutant ou supprimant le répertoire correspondant dans votre répertoire %s.'; +$GLOBALS['__l10n']['Available languages'] = 'Langues disponibles'; +$GLOBALS['__l10n']['You can download and install a additional language directly from Dotclear.net. Proposed languages are based on your version: %s.'] = 'Vous pouvez télécharger et installer une langue supplémentaire directement depuis Dotclear.net. Les langues proposées sont basées sur votre version : %s.'; +$GLOBALS['__l10n']['Language:'] = 'Langue :'; +$GLOBALS['__l10n']['Install language'] = 'Installer la langue'; +$GLOBALS['__l10n']['You can install languages by uploading zip files.'] = 'Vous pouvez installer des langues en déposant des fichiers zip.'; +$GLOBALS['__l10n']['Language zip file:'] = 'Fichier zip de la langue :'; +$GLOBALS['__l10n']['Upload language'] = 'Déposer la langue'; +$GLOBALS['__l10n']['Invalid language zip file.'] = 'Fichier zip de langue invalide.'; +$GLOBALS['__l10n']['The zip file does not appear to be a valid Dotclear language pack.'] = 'Le fichier zip ne semble pas être un fichier valide de langue Dotclear.'; +$GLOBALS['__l10n']['An error occurred during language upgrade.'] = 'Une erreur est survenue durant la mise à jour de la langue.'; +$GLOBALS['__l10n']['Error:'] = 'Erreur :'; +$GLOBALS['__l10n']['By names, in ascending order'] = 'Par noms, croissants'; +$GLOBALS['__l10n']['By names, in descending order'] = 'Par noms, décroissants'; +$GLOBALS['__l10n']['By dates, in ascending order'] = 'Par dates, croissantes'; +$GLOBALS['__l10n']['By dates, in descending order'] = 'Par dates, décroissantes'; +$GLOBALS['__l10n']['Media manager'] = 'Gestionnaire de médias'; +$GLOBALS['__l10n']['confirm removal'] = 'Confirmer la suppression'; +$GLOBALS['__l10n']['Are you sure you want to remove %s?'] = 'Êtes-vous certain de vouloir supprimer %s ?'; +$GLOBALS['__l10n']['Cancel'] = 'Annuler'; +$GLOBALS['__l10n']['Yes'] = 'oui'; +$GLOBALS['__l10n']['Directory has been successfully created.'] = 'Répertoire créé avec succès.'; +$GLOBALS['__l10n']['Files have been successfully uploaded.'] = 'Fichier chargé avec succès.'; +$GLOBALS['__l10n']['File has been successfully removed.'] = 'Fichier supprimé avec succès.'; +$GLOBALS['__l10n']['Directory has been successfully removed.'] = 'Répertoire supprimé avec succès.'; +$GLOBALS['__l10n']['Directory has been successfully rebuilt.'] = 'Répertoire reconstruit avec succès.'; +$GLOBALS['__l10n']['Zip file has been successfully extracted.'] = 'Le fichier zip a été extrait avec succès.'; +$GLOBALS['__l10n']['Choose a file to attach to entry %s by clicking on %s.'] = 'Choisissez un fichier à attacher au billet %s en cliquant sur %s.'; +$GLOBALS['__l10n']['Attach this file to entry'] = 'Attacher ce fichier au billet'; +$GLOBALS['__l10n']['Choose a file to insert into entry by clicking on %s.'] = 'Choisissez un fichier à insérer dans le billet en cliquant sur %s.'; +$GLOBALS['__l10n']['No file.'] = 'Aucun fichier.'; +$GLOBALS['__l10n']['Sort files:'] = 'Trier les fichiers :'; +$GLOBALS['__l10n']['Sort'] = 'Trier'; +$GLOBALS['__l10n']['Add files'] = 'Ajouter des fichiers'; +$GLOBALS['__l10n']['Please take care to publish media that you own and that are not protected by copyright.'] = 'Veuillez prendre garde à ne publier que des médias que vous possédez ou qui ne sont pas protégés contre la copie.'; +$GLOBALS['__l10n']['Choose a file:'] = 'Choisissez un fichier :'; +$GLOBALS['__l10n']['Maximum size %s'] = 'Taille maximale %s'; +$GLOBALS['__l10n']['Private'] = 'Privé'; +$GLOBALS['__l10n']['To send several files at the same time, you can activate the enhanced uploader in'] = 'Pour envoyer plusieurs fichiers à la fois, vous pouvez activer l\'interface avancée dans'; +$GLOBALS['__l10n']['Send'] = 'Envoyer'; +$GLOBALS['__l10n']['New directory'] = 'Nouveau répertoire'; +$GLOBALS['__l10n']['Directory Name:'] = 'Nom du répertoire :'; +$GLOBALS['__l10n']['Download this directory as a zip file'] = 'Télécharger ce répertoire dans un fichier zip'; +$GLOBALS['__l10n']['open'] = 'ouvrir'; +$GLOBALS['__l10n']['Insert this file into entry'] = 'Insérer ce fichier dans le billet'; +$GLOBALS['__l10n']['delete'] = 'supprimer'; +$GLOBALS['__l10n']['Not a valid file'] = 'Fichier invalide'; +$GLOBALS['__l10n']['File has been successfully updated.'] = 'Fichier mis à jour avec succès.'; +$GLOBALS['__l10n']['Thumbnails have been successfully updated.'] = 'Les miniatures ont été mises à jour avec succès.'; +$GLOBALS['__l10n']['Insert media item'] = 'Insérer un média'; +$GLOBALS['__l10n']['Image size:'] = 'Taille de l\'image :'; +$GLOBALS['__l10n']['original'] = 'originale'; +$GLOBALS['__l10n']['Image alignment'] = 'Alignement de l\'image'; +$GLOBALS['__l10n']['None'] = 'Aucun'; +$GLOBALS['__l10n']['Left'] = 'Gauche'; +$GLOBALS['__l10n']['Right'] = 'Droite'; +$GLOBALS['__l10n']['Center'] = 'Centre'; +$GLOBALS['__l10n']['Image insertion'] = 'Insertion de l\'image'; +$GLOBALS['__l10n']['As a single image'] = 'En tant qu\'image uniquement'; +$GLOBALS['__l10n']['As a link to original image'] = 'En tant que lien vers l\'image originale'; +$GLOBALS['__l10n']['MP3 disposition'] = 'Disposition du MP3'; +$GLOBALS['__l10n']['Please note that you cannot insert mp3 files with visual editor.'] = 'Merci de noter que vous ne pouvez pas insérer de fichier mp3 avec l\'éditeur visuel.'; +$GLOBALS['__l10n']['Please note that you cannot insert video files with visual editor.'] = 'Merci de noter que vous ne pouvez pas insérer de fichier vidéo avec l\'éditeur visuel.'; +$GLOBALS['__l10n']['Video size'] = 'Taille de la vidéo'; +$GLOBALS['__l10n']['Width:'] = 'Largeur :'; +$GLOBALS['__l10n']['Height:'] = 'Hauteur :'; +$GLOBALS['__l10n']['Video disposition'] = 'Disposition de la vidéo'; +$GLOBALS['__l10n']['Media item will be inserted as a link.'] = 'Le média sera inséré en tant que lien.'; +$GLOBALS['__l10n']['Insert'] = 'Insérer'; +$GLOBALS['__l10n']['Media details'] = 'Détails du média'; +$GLOBALS['__l10n']['Available sizes:'] = 'Tailles disponibles :'; +$GLOBALS['__l10n']['File owner:'] = 'Propriétaire du fichier :'; +$GLOBALS['__l10n']['File type:'] = 'Type de fichier :'; +$GLOBALS['__l10n']['File size:'] = 'Taille du fichier :'; +$GLOBALS['__l10n']['File URL:'] = 'URL du fichier :'; +$GLOBALS['__l10n']['Show entries containing this media'] = 'Afficher les billets contenant ce média'; +$GLOBALS['__l10n']['Entries containing this media'] = 'Billets contenant ce média'; +$GLOBALS['__l10n']['No entry seems contain this media.'] = 'Aucun billet ne semble contenir ce média.'; +$GLOBALS['__l10n']['Image details'] = 'Détails de l\'image'; +$GLOBALS['__l10n']['No detail'] = 'Aucun détail'; +$GLOBALS['__l10n']['Update thumbnails'] = 'Mettre à jour les miniatures'; +$GLOBALS['__l10n']['This will create or update thumbnails for this image.'] = 'Ceci va créer ou mettre à jour les miniatures pour cette image.'; +$GLOBALS['__l10n']['Extract in a new directory'] = 'Extraire dans un nouveau répertoire'; +$GLOBALS['__l10n']['Extract in current directory'] = 'Extraire dans le répertoire actuel'; +$GLOBALS['__l10n']['Extract archive'] = 'Extraire l\'archive'; +$GLOBALS['__l10n']['This will extract archive in a new directory that should not exist yet.'] = 'Ceci va extraire l\'archive dans un nouveau répertoire qui ne doit pas encore exister.'; +$GLOBALS['__l10n']['This will extract archive in current directory and will overwrite existing files or directory.'] = 'Ceci va extraire l\'archive dans le répertoire actuel et va écraser les fichiers ou répertoires existants.'; +$GLOBALS['__l10n']['Extract mode:'] = 'Mode d\'extraction :'; +$GLOBALS['__l10n']['Extract'] = 'Extrait'; +$GLOBALS['__l10n']['Change media properties'] = 'Changer les propriétés du média'; +$GLOBALS['__l10n']['File name:'] = 'Nom du fichier :'; +$GLOBALS['__l10n']['File title:'] = 'Titre du fichier :'; +$GLOBALS['__l10n']['File date:'] = 'Date du fichier :'; +$GLOBALS['__l10n']['New directory:'] = 'Nouveau répertoire :'; +$GLOBALS['__l10n']['Change file'] = 'Changer le fichier'; +$GLOBALS['__l10n']['No blog or user given.'] = 'Vous n\'avez pas indiqué de blog ou d\'utilisateur'; +$GLOBALS['__l10n']['permissions'] = 'permissions'; +$GLOBALS['__l10n']['Permissions'] = 'Permissions'; +$GLOBALS['__l10n']['The permissions have been successfully updated.'] = 'Permissions mises à jour avec succès.'; +$GLOBALS['__l10n']['You are about to change permissions on the following blogs for users %s.'] = 'Vous allez changer les permissions des utilisateurs %s pour ces blogs.'; +$GLOBALS['__l10n']['Validate permissions'] = 'Valider les permissions'; +$GLOBALS['__l10n']['choose a blog'] = 'choisissez un blog'; +$GLOBALS['__l10n']['Choose a blog'] = 'Choisissez un blog'; +$GLOBALS['__l10n']['Entries per page'] = 'Billets par page'; +$GLOBALS['__l10n']['Choose one or more blogs to which you want to give permissions to users %s.'] = 'Choisissez un ou plusieurs blogs pour lesquels les utilisateurs suivants auront des permissions : %s.'; +$GLOBALS['__l10n']['Set permissions'] = 'définir les permissions'; +$GLOBALS['__l10n']['select'] = 'sélectionner'; +$GLOBALS['__l10n']['No content found on this plugin.'] = 'Aucun contenu pour cette extension.'; +$GLOBALS['__l10n']['Plugin not found'] = 'Extension introuvable'; +$GLOBALS['__l10n']['The plugin you reached does not exist or does not have an admin page.'] = 'L\'extension que vous essayez d\'atteindre n\'existe pas ou n\'a pas de page d\'administration.'; +$GLOBALS['__l10n']['No such plugin.'] = 'Extension inexistante.'; +$GLOBALS['__l10n']['You don\'t have permissions to delete this plugin.'] = 'Vous n\'avez pas les permissions pour effacer cette extension'; +$GLOBALS['__l10n']['You don\'t have permissions to deactivate this plugin.'] = 'Vous n\'avez pas les permissions pour désactiver cette extension.'; +$GLOBALS['__l10n']['Plugins management'] = 'Gestion des extensions'; +$GLOBALS['__l10n']['Plugin has been successfully deleted.'] = 'L\'extension a été supprimée avec succès.'; +$GLOBALS['__l10n']['Plugin has been successfully installed.'] = 'L\'extension a été installée avec succès.'; +$GLOBALS['__l10n']['Plugin has been successfully upgraded'] = 'L\'extension a été mise à jour avec succès.'; +$GLOBALS['__l10n']['Plugins add new functionalities to Dotclear. Here you can activate or deactivate installed plugins.'] = 'Les extensions ajoutent de nouvelles fonctionnalités à Dotclear. Ici, vous pouvez activer ou désactiver les extensions installées.'; +$GLOBALS['__l10n']['You can find additional plugins for your blog on %s.'] = 'Vous pouvez trouver de nouvelles extensions pour votre blog sur %s.'; +$GLOBALS['__l10n']['To install or upgrade a plugin you generally just need to upload it in "Install or upgrade a plugin" section.'] = 'Tout ce que vous avez à faire pour installer ou mettre à jour une extension est généralement de la déposer dans la section "Installer ou mettre à jour une extension".'; +$GLOBALS['__l10n']['To install or upgrade a plugin you just need to extract it in your plugins directory.'] = 'Tout ce que vous avez à faire pour installer une extension est de l\'extraire dans votre répertoire d\'extensions.'; +$GLOBALS['__l10n']['Plugins'] = 'Extensions'; +$GLOBALS['__l10n']['Activated plugins'] = 'Extensions activées'; +$GLOBALS['__l10n']['Plugin'] = 'Extension'; +$GLOBALS['__l10n']['Version'] = 'Version'; +$GLOBALS['__l10n']['Details'] = 'Détails'; +$GLOBALS['__l10n']['Deactivate'] = 'Désactiver'; +$GLOBALS['__l10n']['Deactivated plugins'] = 'Extensions désactivées'; +$GLOBALS['__l10n']['Activate'] = 'Activer'; +$GLOBALS['__l10n']['Install or upgrade a plugin'] = 'Installer ou mettre à jour une extension'; +$GLOBALS['__l10n']['You can install plugins by uploading or downloading zip files.'] = 'Vous pouvez installer des extensions en déposant ou téléchargeant des fichiers zip.'; +$GLOBALS['__l10n']['Plugin zip file:'] = 'Fichier zip de l\'extension :'; +$GLOBALS['__l10n']['Upload plugin'] = 'Déposer l\'extension'; +$GLOBALS['__l10n']['Plugin zip file URL:'] = 'URL du fichier zip de l\'extension :'; +$GLOBALS['__l10n']['Download plugin'] = 'Télécharger l\'extension'; +$GLOBALS['__l10n']['To enable this function, please give write access to your plugins directory.'] = 'Pour activer cette fonction, donnez un accès en écriture à votre répertoire d\'extensions.'; +$GLOBALS['__l10n']['Add a link'] = 'Ajouter un lien'; +$GLOBALS['__l10n']['Available'] = 'Disponible'; +$GLOBALS['__l10n']['Most used'] = 'Plus utilisées'; +$GLOBALS['__l10n']['Link URL:'] = 'URL du lien :'; +$GLOBALS['__l10n']['Link title:'] = 'Titre du lien :'; +$GLOBALS['__l10n']['Link language:'] = 'Langue du lien :'; +$GLOBALS['__l10n']['Add a link to an entry'] = 'Ajouter un lien vers un billet'; +$GLOBALS['__l10n']['Search entry:'] = 'Rechercher un billet :'; +$GLOBALS['__l10n']['Search'] = 'Rechercher'; +$GLOBALS['__l10n']['cancel'] = 'Annuler'; +$GLOBALS['__l10n']['This entry does not exist.'] = 'Ce billet n\'existe pas.'; +$GLOBALS['__l10n']['Edit entry'] = 'Modifier le billet'; +$GLOBALS['__l10n']['next entry'] = 'billet suivant'; +$GLOBALS['__l10n']['previous entry'] = 'billet précédent'; +$GLOBALS['__l10n']['Entry has been successfully updated.'] = 'Billet mis à jour avec succès.'; +$GLOBALS['__l10n']['Entry has been successfully created.'] = 'Billet créé avec succès.'; +$GLOBALS['__l10n']['File has been successfully attached.'] = 'Fichier attaché avec succès.'; +$GLOBALS['__l10n']['Attachment has been successfully removed.'] = 'Pièce jointe retirée avec succès.'; +$GLOBALS['__l10n']['Comment has been successfully created.'] = 'Commentaire créé avec succès.'; +$GLOBALS['__l10n']['Don\'t forget to validate your XHTML conversion by saving your post.'] = 'Enregistrez votre billet pour valider la transformation en XHTML.'; +$GLOBALS['__l10n']['Go to this entry on the site'] = 'Voir ce billet sur le site'; +$GLOBALS['__l10n']['new window'] = 'nouvelle fenêtre'; +$GLOBALS['__l10n']['Excerpt:'] = 'Extrait :'; +$GLOBALS['__l10n']['Notes:'] = 'Notes :'; +$GLOBALS['__l10n']['Preview'] = 'Prévisualiser'; +$GLOBALS['__l10n']['Entry status:'] = 'État du billet :'; +$GLOBALS['__l10n']['Published on:'] = 'Publié le :'; +$GLOBALS['__l10n']['Text formating:'] = 'Format du texte :'; +$GLOBALS['__l10n']['Convert to XHTML'] = 'Convertir en XHTML'; +$GLOBALS['__l10n']['Selected entry'] = 'Billet sélectionné'; +$GLOBALS['__l10n']['Entry lang:'] = 'Langue du billet :'; +$GLOBALS['__l10n']['Entry password:'] = 'Mot de passe du billet :'; +$GLOBALS['__l10n']['Basename:'] = 'URL spécifique :'; +$GLOBALS['__l10n']['Warning: If you set the URL manually, it may conflict with another entry.'] = 'Attention : si vous indiquez l\'URL manuellement, celle-ci peut entrer en conflit avec un autre billet.'; +$GLOBALS['__l10n']['Ping blogs'] = 'Faire des rétroliens'; +$GLOBALS['__l10n']['Trackbacks'] = 'Rétroliens'; +$GLOBALS['__l10n']['No trackback'] = 'Aucun rétrolien'; +$GLOBALS['__l10n']['Add a comment'] = 'Ajouter un commentaire'; +$GLOBALS['__l10n']['Name:'] = 'Nom :'; +$GLOBALS['__l10n']['IP address'] = 'Adresse IP'; +$GLOBALS['__l10n']['published'] = 'publié'; +$GLOBALS['__l10n']['unpublished'] = 'non publié'; +$GLOBALS['__l10n']['pending'] = 'en attente'; +$GLOBALS['__l10n']['junk'] = 'indésirable'; +$GLOBALS['__l10n']['select this comment'] = 'Sélectionner ce commentaire'; +$GLOBALS['__l10n']['select this trackback'] = 'Sélectionner ce rétrolien'; +$GLOBALS['__l10n']['Edit this comment'] = 'Modifier ce commentaire'; +$GLOBALS['__l10n']['This attachment does not exist'] = 'Cette pièce jointe n\'existe pas'; +$GLOBALS['__l10n']['Remove attachment'] = 'Supprimer la pièce jointe'; +$GLOBALS['__l10n']['Attachment'] = 'Pièce jointe'; +$GLOBALS['__l10n']['Are you sure you want to remove this attachment?'] = 'Êtes-vous certain de vouloir supprimer cette pièce jointe ?'; +$GLOBALS['__l10n']['selected'] = 'sélectionné'; +$GLOBALS['__l10n']['not selected'] = 'non sélectionné'; +$GLOBALS['__l10n']['Category'] = 'Catégorie'; +$GLOBALS['__l10n']['Selected'] = 'Sélectionné'; +$GLOBALS['__l10n']['Publish'] = 'Publier'; +$GLOBALS['__l10n']['Unpublish'] = 'Mettre hors ligne'; +$GLOBALS['__l10n']['Schedule'] = 'Programmer'; +$GLOBALS['__l10n']['Mark as pending'] = 'Mettre en attente'; +$GLOBALS['__l10n']['Mark'] = 'Marquer'; +$GLOBALS['__l10n']['Mark as selected'] = 'Sélectionner'; +$GLOBALS['__l10n']['Mark as unselected'] = 'Désélectionner'; +$GLOBALS['__l10n']['Change'] = 'Changer'; +$GLOBALS['__l10n']['Change category'] = 'Changer la catégorie'; +$GLOBALS['__l10n']['Change author'] = 'Changer l\'auteur'; +$GLOBALS['__l10n']['Selected:'] = 'Sélectionné :'; +$GLOBALS['__l10n']['Month:'] = 'Mois :'; +$GLOBALS['__l10n']['Lang:'] = 'Langue :'; +$GLOBALS['__l10n']['Selected entries action:'] = 'Action sur les billets sélectionnés :'; +$GLOBALS['__l10n']['This user does not exist'] = 'Cet utilisateur n\'existe pas'; +$GLOBALS['__l10n']['Change category for entries'] = 'Changer de catégorie pour les billets'; +$GLOBALS['__l10n']['Change author for entries'] = 'Changer l\'auteur des billets'; +$GLOBALS['__l10n']['Author ID:'] = 'Identifiant de l\'utilisateur :'; +$GLOBALS['__l10n']['Default'] = 'Défaut'; +$GLOBALS['__l10n']['If you want to change your email or password you must provide your current password.'] = 'Si vous voulez changer votre adresse email ou votre mot de passe, vous devez indiquer votre mot de passe actuel.'; +$GLOBALS['__l10n']['No favorite selected'] = 'Aucun favori sélectionné'; +$GLOBALS['__l10n']['Personal information has been successfully updated.'] = 'Informations personnelles mises à jour avec succès.'; +$GLOBALS['__l10n']['Personal options has been successfully updated.'] = 'Vos options personnelles ont été enregistrées avec succès.'; +$GLOBALS['__l10n']['Favorites have been successfully added.'] = 'Les favoris ont été ajoutés avec succès.'; +$GLOBALS['__l10n']['Favorites have been successfully updated.'] = 'Les favoris ont été mis à jour avec succès.'; +$GLOBALS['__l10n']['Favorites have been successfully removed.'] = 'Les favoris ont été retirés avec succès.'; +$GLOBALS['__l10n']['Default favorites have been successfully updated.'] = 'Les favoris par défaut ont été enregistrés avec succès.'; +$GLOBALS['__l10n']['My profile'] = 'Mon profil'; +$GLOBALS['__l10n']['Display name:'] = 'Pseudonyme :'; +$GLOBALS['__l10n']['User language:'] = 'Langue de l\'utilisateur :'; +$GLOBALS['__l10n']['User timezone:'] = 'Fuseau horaire de l\'utilisateur :'; +$GLOBALS['__l10n']['If you have changed this user email or password you must provide your current password to save these modifications.'] = 'Si vous voulez changer votre adresse email ou votre mot de passe, vous devez indiquer votre mot de passe.'; +$GLOBALS['__l10n']['My options'] = 'Mes options'; +$GLOBALS['__l10n']['Preferred format:'] = 'Format d\'édition préféré :'; +$GLOBALS['__l10n']['Default entry status:'] = 'État des billets par défaut :'; +$GLOBALS['__l10n']['Entry edit field height:'] = 'Taille de la zone d\'édition :'; +$GLOBALS['__l10n']['Enable WYSIWYG mode'] = 'Activer l\'éditeur visuel'; +$GLOBALS['__l10n']['Activate enhanced uploader in media manager'] = 'Activer l\'interface avancée du gestionnaire de médias'; +$GLOBALS['__l10n']['Hide My favorites menu'] = 'Cacher le menu Mes Favoris'; +$GLOBALS['__l10n']['Iconset:'] = 'Jeu d\'icônes :'; +$GLOBALS['__l10n']['Do not use standard favicon'] = 'Ne pas utiliser le favicon standard'; +$GLOBALS['__l10n']['This will be applied for all users'] = 'Ce choix sera actif pour tous les utilisateurs'; +$GLOBALS['__l10n']['Accessibility options'] = 'Options d\'accessibilité'; +$GLOBALS['__l10n']['Disable javascript powered drag and drop for ordering items'] = 'Désactiver le drag and drop javascript pour ordonnancer les éléments'; +$GLOBALS['__l10n']['Numeric fields will allow to type the elements\' ordering number.'] = 'Des champs numériques permettront d\'indiquer la position des éléments.'; +$GLOBALS['__l10n']['Dashboard modules'] = 'Modules du tableau de bord'; +$GLOBALS['__l10n']['Display documentation links'] = 'Afficher les liens de documentation'; +$GLOBALS['__l10n']['Display Dotclear news'] = 'Afficher les nouvelles de Dotclear'; +$GLOBALS['__l10n']['Display quick entry form'] = 'Afficher le formulaire de billet rapide'; +$GLOBALS['__l10n']['My favorites'] = 'Mes favoris'; +$GLOBALS['__l10n']['position of %s'] = 'position de %s'; +$GLOBALS['__l10n']['Save order'] = 'Enregistrer l\'ordre'; +$GLOBALS['__l10n']['Delete selected favorites'] = 'Retirer les favoris sélectionnés'; +$GLOBALS['__l10n']['Are you sure you want to remove selected favorites?'] = 'Êtes-vous sûr de vouloir retirer les favoris sélectionnés ?'; +$GLOBALS['__l10n']['If you are a super administrator, you may define this set of favorites to be used by default on all blogs of this installation:'] = 'Si vous êtes super administrateur, vous pouvez définir ce jeu de favoris comme l\'ensemble par défaut pour tous les blogs de l\'installation :'; +$GLOBALS['__l10n']['Define as default favorites'] = 'Définir comme favoris par défaut'; +$GLOBALS['__l10n']['Currently no personal favorites.'] = 'La liste de vos favoris est vide pour le moment.'; +$GLOBALS['__l10n']['Default favorites'] = 'Favoris par défaut'; +$GLOBALS['__l10n']['Those favorites are displayed when My Favorites list is empty.'] = 'Favoris affichés quand la liste Mes Favoris est vide.'; +$GLOBALS['__l10n']['Available favorites'] = 'Favoris disponibles'; +$GLOBALS['__l10n']['Add to my favorites'] = 'Ajouter à mes favoris'; +$GLOBALS['__l10n']['Search options'] = 'Options de recherche'; +$GLOBALS['__l10n']['Query:'] = 'Requête :'; +$GLOBALS['__l10n']['Search entries'] = 'Rechercher des billets'; +$GLOBALS['__l10n']['Search comments'] = 'Rechercher des commentaires'; +$GLOBALS['__l10n']['schedule'] = 'programmer'; +$GLOBALS['__l10n']['change category'] = 'changer la catégorie'; +$GLOBALS['__l10n']['change author'] = 'changer l\'auteur'; +$GLOBALS['__l10n']['%d entries found'] = '%d billets trouvés'; +$GLOBALS['__l10n']['%d entry found'] = '%d billet trouvé'; +$GLOBALS['__l10n']['%d comment found'] = '%d commentaire trouvé'; +$GLOBALS['__l10n']['%d comments found'] = '%d commentaires trouvés'; +$GLOBALS['__l10n']['This entry does not exist or is not published'] = 'Ce billet n\'existe pas ou n\'est pas publié'; +$GLOBALS['__l10n']['All pings sent.'] = 'Tous les rétroliens ont été envoyés.'; +$GLOBALS['__l10n']['Back to "%s"'] = 'Retour à "%s"'; +$GLOBALS['__l10n']['Auto discover ping URLs'] = 'Découverte automatique des URL à rétrolier'; +$GLOBALS['__l10n']['URLs to ping:'] = 'URLs à rétrolier :'; +$GLOBALS['__l10n']['Send excerpt:'] = 'Envoyer l\'extrait :'; +$GLOBALS['__l10n']['Previously sent pings'] = 'Rétroliens déjà envoyés'; +$GLOBALS['__l10n']['Dotclear update'] = 'Mise à jour de Dotclear'; +$GLOBALS['__l10n']['Unable to delete file %s'] = 'Impossible de supprimer le fichier %s'; +$GLOBALS['__l10n']['Downloaded Dotclear archive seems to be corrupted. Try download it again.'] = 'L\'archive téléchargée de Dotclear semble être corrompue. Essayer de la télécharger à nouveau.'; +$GLOBALS['__l10n']['The following files of your Dotclear installation have been modified so we won\'t try to update your installation. Please try to update manually.'] = 'Comme les fichiers suivants de votre installation de Dotclear ont été modifiés, votre installation ne peut être mise à jour. Merci de mettre à jour manuellement.'; +$GLOBALS['__l10n']['The following files of your Dotclear installation are not readable. Please fix this or try to make a backup file named %s manually.'] = 'Les fichiers suivants de votre installation de Dotclear ne peuvent pas être lus. Veuillez corriger ceci ou créer un fichier de backup nommé %s manuellement.'; +$GLOBALS['__l10n']['The following files of your Dotclear installation cannot be written. Please fix this or try to update manually.'] = 'Les fichiers suivants de votre installation de Dotclear ne peuvent pas être écrits. Veuillez corriger ceci ou mettre à jour manuellement.'; +$GLOBALS['__l10n']['No newer Dotclear version available.'] = 'Aucune nouvelle version de Dotclear n\'est disponible.'; +$GLOBALS['__l10n']['Dotclear %s is available.'] = 'Dotclear %s est disponible.'; +$GLOBALS['__l10n']['To upgrade your Dotclear installation simply click on the following button. A backup file of your current installation will be created in your root directory.'] = 'Pour mettre à jour votre installation de Dotclear, cliquez sur le bouton suivant. Un fichier de sauvegarde de votre installation actuelle sera créé dans votre répertoire principal.'; +$GLOBALS['__l10n']['Update Dotclear'] = 'Mettre à jour Dotclear'; +$GLOBALS['__l10n']['Update backup files'] = 'Sauvegardes des mises à jour'; +$GLOBALS['__l10n']['The following files are backups of previously updates. You can revert your previous installation or delete theses files.'] = 'Les fichiers suivants sont des sauvegardes de mises à jour précédentes. Vous pouvez rétablir votre installation précédente ou supprimer ces fichiers.'; +$GLOBALS['__l10n']['Please note that reverting your Dotclear version may have some unwanted side-effects. Consider reverting only if you experience strong issues with this new version.'] = 'Merci de noter que rétablir votre version de Dotclear peut avoir des effets non désirés. N\'envisagez ceci que si vous rencontrez d\'importantes difficultés avec cette nouvelle version.'; +$GLOBALS['__l10n']['You should not revert to version prior to last one (%s).'] = 'Vous ne devez pas rétablir une version précédant la dernière (%s).'; +$GLOBALS['__l10n']['Delete selected file'] = 'Supprimer le fichier sélectionné'; +$GLOBALS['__l10n']['Revert to selected file'] = 'Rétablir le fichier sélectionné'; +$GLOBALS['__l10n']['Congratulations, you\'re one click away from the end of the update.'] = 'Félicitations, vous êtes à un clic de la fin de la mise à jour.'; +$GLOBALS['__l10n']['Finish the update.'] = 'Finir la mise à jour.'; +$GLOBALS['__l10n']['new user'] = 'nouvel utilisateur'; +$GLOBALS['__l10n']['User "%s" already exists.'] = 'L\'utilisateur "%s" existe déjà.'; +$GLOBALS['__l10n']['User has been successfully updated.'] = 'Utilisateur mis à jour avec succès.'; +$GLOBALS['__l10n']['User has been successfully created.'] = 'Utilisateur créé avec succès.'; +$GLOBALS['__l10n']['Warning:'] = 'Attention :'; +$GLOBALS['__l10n']['If you change your username, you will have to log in again.'] = 'Si vous changez votre login, vous devrez vous identifier à nouveau.'; +$GLOBALS['__l10n']['Mandatory for password recovering procedure.'] = 'Obligatoire pour la procédure de récupération de mot de passe.'; +$GLOBALS['__l10n']['Password change required to connect'] = 'Changement de mot de passe requis pour la connexion'; +$GLOBALS['__l10n']['Save and create another'] = 'Enregistrer et créer un nouveau'; +$GLOBALS['__l10n']['No permissions.'] = 'Aucune permission.'; +$GLOBALS['__l10n']['Add new permissions'] = 'Ajouter de nouvelles permissions'; +$GLOBALS['__l10n']['Username'] = 'Identifiant'; +$GLOBALS['__l10n']['Last Name'] = 'Nom'; +$GLOBALS['__l10n']['First Name'] = 'Prénom'; +$GLOBALS['__l10n']['Display name'] = 'Pseudonyme'; +$GLOBALS['__l10n']['Number of entries'] = 'Nombre de billets'; +$GLOBALS['__l10n']['users'] = 'utilisateurs'; +$GLOBALS['__l10n']['User has been successfully removed.'] = 'Utilisateur supprimé avec succès.'; +$GLOBALS['__l10n']['Create a new user'] = 'Créer un nouvel utilisateur'; +$GLOBALS['__l10n']['Users per page'] = 'Utilisateurs par page'; +$GLOBALS['__l10n']['Selected users action:'] = 'Action sur les utilisateurs sélectionnés :'; +$GLOBALS['__l10n']['Blog:'] = 'Blog :'; +$GLOBALS['__l10n']['Change blog'] = 'Changer de blog'; +$GLOBALS['__l10n']['Blogs:'] = 'Blogs :'; +$GLOBALS['__l10n']['Go to the content'] = 'Aller au contenu'; +$GLOBALS['__l10n']['Go to the menu'] = 'Aller au menu'; +$GLOBALS['__l10n']['Go to site'] = 'Aller sur le site'; +$GLOBALS['__l10n']['My dashboard'] = 'Mon tableau de bord'; +$GLOBALS['__l10n']['Logout %s'] = 'Déconnecter %s'; +$GLOBALS['__l10n']['Safe mode'] = 'Mode de secours'; +$GLOBALS['__l10n']['You are in safe mode. All plugins have been temporarily disabled. Remind to log out then log in again normally to get back all functionalities'] = 'Vous êtes en mode de secours. Tous les plugins ont été temporairement désactivés. N\'oubliez-pas de vous déconnecter puis de vous reconnecter normalement pour retrouver toutes les fonctionnalités'; +$GLOBALS['__l10n']['Thank you for using %s.'] = 'Merci d\'utiliser %s.'; +$GLOBALS['__l10n']['Help'] = 'Aide'; +$GLOBALS['__l10n']['uncover'] = 'dévoiler'; +$GLOBALS['__l10n']['hide'] = 'cacher'; +$GLOBALS['__l10n']['help'] = 'aide'; +$GLOBALS['__l10n']['no selection'] = 'aucune sélection'; +$GLOBALS['__l10n']['select all'] = 'tout sélectionner'; +$GLOBALS['__l10n']['invert selection'] = 'inverser la sélection'; +$GLOBALS['__l10n']['view entry'] = 'voir le billet'; +$GLOBALS['__l10n']['Are you sure you want to delete selected entries (%s)?'] = 'Êtes-vous certain de vouloir supprimer les billets sélectionnés (%s) ?'; +$GLOBALS['__l10n']['Are you sure you want to delete this entry?'] = 'Êtes-vous certain de vouloir supprimer ce billet ?'; +$GLOBALS['__l10n']['Are you sure you want to delete selected comments (%s)?'] = 'Êtes-vous certain de vouloir supprimer les commentaires sélectionnés (%s) ?'; +$GLOBALS['__l10n']['Are you sure you want to delete this comment?'] = 'Êtes-vous certain de vouloir supprimer ce commentaire ?'; +$GLOBALS['__l10n']['Users with posts cannot be deleted.'] = 'Les utilisateurs ayant écrit des billets ne peuvent être effacées.'; +$GLOBALS['__l10n']['Are you sure you want to delete selected users (%s)?'] = 'Êtes-vous certain de vouloir supprimer les utilisateurs sélectionnés (%s) ?'; +$GLOBALS['__l10n']['Are you sure you want to delete category "%s"?'] = 'Êtes-vous certain de vouloir supprimer la catégorie "%s" ?'; +$GLOBALS['__l10n']['Are you sure you want to reorder all categories?'] = 'Êtes-vous certain de vouloir réinitialiser l\'ordre des catégories ?'; +$GLOBALS['__l10n']['Are you sure you want to remove media "%s"?'] = 'Êtes-vous certain de vouloir supprimer le média "%s" ?'; +$GLOBALS['__l10n']['Are you sure you want to extract archive in current directory?'] = 'Êtes-vous certain de vouloir extraire l\'archive dans le répertoire actuel ?'; +$GLOBALS['__l10n']['Are you sure you want to remove attachment "%s"?'] = 'Êtes-vous certain de vouloir supprimer la pièce jointe "%s" ?'; +$GLOBALS['__l10n']['Are you sure you want to delete "%s" language?'] = 'Êtes-vous certain de vouloir supprimer la langue "%s" ?'; +$GLOBALS['__l10n']['Are you sure you want to delete "%s" plugin?'] = 'Êtes-vous certain de vouloir supprimer l\'extension "%s" ?'; +$GLOBALS['__l10n']['Use this theme'] = 'Utiliser ce thème'; +$GLOBALS['__l10n']['Remove this theme'] = 'Supprimer ce thème'; +$GLOBALS['__l10n']['Are you sure you want to delete "%s" theme?'] = 'Êtes-vous certain de vouloir supprimer le thème "%s" ?'; +$GLOBALS['__l10n']['Zip file content'] = 'Contenu du fichier zip'; +$GLOBALS['__l10n']['XHTML markup validator'] = 'Validation XHTML'; +$GLOBALS['__l10n']['XHTML content is valid.'] = 'Le contenu XHTML est valide.'; +$GLOBALS['__l10n']['There are XHTML markup errors.'] = 'Il y a des erreurs XHTML.'; +$GLOBALS['__l10n']['You have unsaved changes. Switch post format will loose these changes. Proceed anyway?'] = 'Vous avez des modifications non sauvegardées. Changer de format vous fera perdre ces modifications. Continuer ?'; +$GLOBALS['__l10n']['Loading enhanced uploader, please wait.'] = 'Chargement de l\'interface avancée.'; +$GLOBALS['__l10n']['You have unsaved changes.'] = 'Vous n\'avez pas enregistré vos modifications.'; +$GLOBALS['__l10n']['close'] = 'fermer'; +$GLOBALS['__l10n']['now'] = 'maintenant'; +$GLOBALS['__l10n']['visual'] = 'visuel'; +$GLOBALS['__l10n']['source'] = 'source'; +$GLOBALS['__l10n']['You can use the following shortcuts to format your text.'] = 'Vous pouvez utiliser les raccourcis suivants pour formater votre texte.'; +$GLOBALS['__l10n']['-- none --'] = '-- aucun --'; +$GLOBALS['__l10n']['-- block format --'] = '-- format bloc --'; +$GLOBALS['__l10n']['Paragraph'] = 'Paragraphe'; +$GLOBALS['__l10n']['Level 1 header'] = 'Titre de niveau 1'; +$GLOBALS['__l10n']['Level 2 header'] = 'Titre de niveau 2'; +$GLOBALS['__l10n']['Level 3 header'] = 'Titre de niveau 3'; +$GLOBALS['__l10n']['Level 4 header'] = 'Titre de niveau 4'; +$GLOBALS['__l10n']['Level 5 header'] = 'Titre de niveau 5'; +$GLOBALS['__l10n']['Level 6 header'] = 'Titre de niveau 6'; +$GLOBALS['__l10n']['Strong emphasis'] = 'Forte emphase'; +$GLOBALS['__l10n']['Emphasis'] = 'Emphase'; +$GLOBALS['__l10n']['Inserted'] = 'Insertion'; +$GLOBALS['__l10n']['Deleted'] = 'Suppression'; +$GLOBALS['__l10n']['Inline quote'] = 'Citation en ligne'; +$GLOBALS['__l10n']['Code'] = 'Code'; +$GLOBALS['__l10n']['Line break'] = 'Passage à la ligne'; +$GLOBALS['__l10n']['Blockquote'] = 'Bloc de citation'; +$GLOBALS['__l10n']['Preformated text'] = 'Texte préformaté'; +$GLOBALS['__l10n']['Unordered list'] = 'Liste à puces'; +$GLOBALS['__l10n']['Ordered list'] = 'Liste numérotée'; +$GLOBALS['__l10n']['Link'] = 'Lien'; +$GLOBALS['__l10n']['URL?'] = 'URL ?'; +$GLOBALS['__l10n']['Language?'] = 'Langue ?'; +$GLOBALS['__l10n']['External image'] = 'Image externe'; +$GLOBALS['__l10n']['Media chooser'] = 'Sélecteur de média'; +$GLOBALS['__l10n']['Link to an entry'] = 'Lien vers un billet'; +$GLOBALS['__l10n']['Activate enhanced uploader'] = 'Activer l\'interface avancée'; +$GLOBALS['__l10n']['Disable enhanced uploader'] = 'Désactiver l\'interface avancée'; +$GLOBALS['__l10n']['File successfully uploaded.'] = 'Fichier envoyé avec succès.'; +$GLOBALS['__l10n']['Maximum file size allowed:'] = 'Taille maximale de fichier autorisée :'; +$GLOBALS['__l10n']['Limit exceeded.'] = 'Limite dépassée.'; +$GLOBALS['__l10n']['File size exceeds allowed limit.'] = 'La taille du fichier dépasse la limite autorisée.'; +$GLOBALS['__l10n']['Canceled.'] = 'Annulé.'; +$GLOBALS['__l10n']['HTTP Error:'] = 'Erreur HTTP :'; +$GLOBALS['__l10n']['Choose file'] = 'Choisir un fichier'; +$GLOBALS['__l10n']['Choose files'] = 'Choisir des fichiers'; +$GLOBALS['__l10n']['Clean'] = 'Nettoyer'; +$GLOBALS['__l10n']['Upload'] = 'Envoyer'; +$GLOBALS['__l10n']['No file in queue.'] = 'Aucun fichier en file d\'attente.'; +$GLOBALS['__l10n']['1 file in queue.'] = '1 fichier en attente.'; +$GLOBALS['__l10n']['%d files in queue.'] = '%d fichiers en attente.'; +$GLOBALS['__l10n']['Queue error:'] = 'Erreur de file d\'attente :'; +$GLOBALS['__l10n']['«prev.'] = '«préc.'; +$GLOBALS['__l10n']['next»'] = 'suiv.»'; +$GLOBALS['__l10n']['No entry'] = 'Pas de billet'; +$GLOBALS['__l10n']['scheduled'] = 'programmé'; +$GLOBALS['__l10n']['protected'] = 'protégé'; +$GLOBALS['__l10n']['%d attachment'] = '%d annexe'; +$GLOBALS['__l10n']['%d attachments'] = '%d annexes'; +$GLOBALS['__l10n']['Type'] = 'Type'; +$GLOBALS['__l10n']['No user'] = 'Pas d\'utilisateur'; +$GLOBALS['__l10n']['admin'] = 'Administrateur'; +$GLOBALS['__l10n']['superadmin'] = 'Super administrateur'; +$GLOBALS['__l10n']['Database error'] = 'Erreur de base de données :'; +$GLOBALS['__l10n']['There seems to be no Session table in your database. Is Dotclear completly installed?'] = 'Il semble de la table Session n\'existe pas dans votre base de données. Dotclear est-il bien installé correctement?'; +$GLOBALS['__l10n']['System'] = 'Système'; +$GLOBALS['__l10n']['Blog'] = 'Blog'; +$GLOBALS['__l10n']['Updates'] = 'Mises à jour'; +$GLOBALS['__l10n']['Languages'] = 'Langues'; +$GLOBALS['__l10n']['administrator'] = 'administrateur'; +$GLOBALS['__l10n']['manage their own entries and comments'] = 'gérer ses propres billets et commentaires'; +$GLOBALS['__l10n']['publish entries and comments'] = 'publier des billets et des commentaires'; +$GLOBALS['__l10n']['delete entries and comments'] = 'supprimer des billets et des commentaires'; +$GLOBALS['__l10n']['manage all entries and comments'] = 'gérer tous les billets et commentaires'; +$GLOBALS['__l10n']['manage categories'] = 'gérer les catégories'; +$GLOBALS['__l10n']['manage their own media items'] = 'gérer ses propres médias'; +$GLOBALS['__l10n']['manage all media items'] = 'gérer tous les médias'; +$GLOBALS['__l10n']['That user does not exist in the database.'] = 'Cet utilisateur n\'existe pas dans la base de données.'; +$GLOBALS['__l10n']['That key does not exist in the database.'] = 'Cette clé n\'existe pas dans la base de données.'; +$GLOBALS['__l10n']['You are not allowed to add categories'] = 'Vous n\'êtes pas autorisé à créer des catégories'; +$GLOBALS['__l10n']['You are not allowed to update categories'] = 'Vous n\'êtes pas autorisé à modifier des catégories'; +$GLOBALS['__l10n']['You are not allowed to delete categories'] = 'Vous n\'êtes pas autorisé à supprimer des catégories'; +$GLOBALS['__l10n']['This category is not empty.'] = 'Cette catégorie n\'est pas vide.'; +$GLOBALS['__l10n']['You are not allowed to reset categories order'] = 'Vous n\'êtes pas autorisé à modifier l\'ordre des catégories'; +$GLOBALS['__l10n']['Category URL must be unique.'] = 'L\'URL de chaque catégorie doit être unique.'; +$GLOBALS['__l10n']['You must provide a category title'] = 'Vous devez indiquer un titre de catégorie'; +$GLOBALS['__l10n']['You must provide a category URL'] = 'Vous devez indiquer une URL de catégorie'; +$GLOBALS['__l10n']['You are not allowed to create an entry'] = 'Vous n\'êtes pas autorisé à créer des billets'; +$GLOBALS['__l10n']['You are not allowed to update entries'] = 'Vous n\'êtes pas autorisé à modifier les billets'; +$GLOBALS['__l10n']['No such entry ID'] = 'Identifiant du billet inconnu'; +$GLOBALS['__l10n']['You are not allowed to edit this entry'] = 'Vous n\'êtes pas autorisé à modifier ce billet'; +$GLOBALS['__l10n']['You are not allowed to change this entry status'] = 'Vous n\'êtes pas autorisé à modifier l\'état de ce billet'; +$GLOBALS['__l10n']['You are not allowed to change this entry category'] = 'Vous n\'êtes pas autorisé à modifier la catégorie de ce billet'; +$GLOBALS['__l10n']['You are not allowed to mark this entry as selected'] = 'Vous n\'êtes pas autorisé à marquer ce billet comme sélectionné'; +$GLOBALS['__l10n']['You are not allowed to delete entries'] = 'Vous n\'êtes pas autorisé à supprimer des billets'; +$GLOBALS['__l10n']['You are not allowed to delete this entry'] = 'Vous n\'êtes pas autorisé à supprimer ce billet'; +$GLOBALS['__l10n']['No entry title'] = 'Pas de titre de billet'; +$GLOBALS['__l10n']['No entry content'] = 'Pas de contenu de billet'; +$GLOBALS['__l10n']['Empty entry URL'] = 'URL du billet vide'; +$GLOBALS['__l10n']['You are not allowed to update comments'] = 'Vous n\'êtes pas autorisé à modifier des commentaires'; +$GLOBALS['__l10n']['No such comment ID'] = 'Identifiant du commentaire inconnu'; +$GLOBALS['__l10n']['You are not allowed to update this comment'] = 'Vous n\'êtes pas autorisé à modifier ce commentaire'; +$GLOBALS['__l10n']['You are not allowed to change this comment\'s status'] = 'Vous n\'êtes pas autorisé à changer l\'état de ce commentaire'; +$GLOBALS['__l10n']['You are not allowed to delete comments'] = 'Vous n\'êtes pas autorisé à supprimer des commentaires'; +$GLOBALS['__l10n']['You are not allowed to delete this comment'] = 'Vous n\'êtes pas autorisé à supprimer ce commentaire'; +$GLOBALS['__l10n']['You must provide a comment'] = 'Vous devez indiquer un commentaire'; +$GLOBALS['__l10n']['You must provide an author name'] = 'Vous devez indiquer un nom d\'auteur'; +$GLOBALS['__l10n']['Email address is not valid.'] = 'Adresse email invalide.'; +$GLOBALS['__l10n']['online'] = 'en ligne'; +$GLOBALS['__l10n']['offline'] = 'hors ligne'; +$GLOBALS['__l10n']['removed'] = 'supprimé'; +$GLOBALS['__l10n']['You are not an administrator'] = 'Vous n\'êtes pas administrateur'; +$GLOBALS['__l10n']['Invalid user language code'] = 'Code langue de l\'utilisateur invalide'; +$GLOBALS['__l10n']['Blog ID must contain at least 2 characters using letters, numbers or symbols.'] = 'L\'identifiant du blog doit contenir au moins 2 caractères composés de lettres, chiffres ou symboles.'; +$GLOBALS['__l10n']['No blog name'] = 'Pas de nom de blog'; +$GLOBALS['__l10n']['No blog URL'] = 'Pas d\'URL de blog'; +$GLOBALS['__l10n']['No log message'] = 'Pas de message dans le journal'; +$GLOBALS['__l10n']['unknown'] = 'inconnu'; +$GLOBALS['__l10n']['No blog defined.'] = 'Aucun blog défini.'; +$GLOBALS['__l10n']['Directory %s does not exist.'] = 'Le répertoire %s n\'existe pas.'; +$GLOBALS['__l10n']['You are not a super administrator.'] = 'Vous n\'êtes pas super administrateur.'; +$GLOBALS['__l10n']['Permission denied.'] = 'Permission refusée.'; +$GLOBALS['__l10n']['You are not the file owner.'] = 'Vous n\'êtes pas le propriétaire de ce fichier.'; +$GLOBALS['__l10n']['This file is not allowed.'] = 'Ce fichier n\'est pas autorisé.'; +$GLOBALS['__l10n']['New file already exists.'] = 'Le nouveau fichier existe déjà.'; +$GLOBALS['__l10n']['File does not exist in the database.'] = 'Ce fichier n\'existe pas dans la base de données.'; +$GLOBALS['__l10n']['Extract destination directory %s already exists.'] = 'Le répertoire de destination d\'extraction %s existe déjà.'; +$GLOBALS['__l10n']['Embedded Audio Player'] = 'Fichier audio intégré'; +$GLOBALS['__l10n']['Embedded Video Player'] = 'Fichier vidéo intégré'; +$GLOBALS['__l10n']['%s: in [%s] and [%s]'] = '%s: dans [%s] et [%s]'; +$GLOBALS['__l10n']['Empty module zip file.'] = 'Fichier zip de module vide.'; +$GLOBALS['__l10n']['The zip file does not appear to be a valid Dotclear module.'] = 'Le fichier zip ne semble pas être un fichier valide de module Dotclear.'; +$GLOBALS['__l10n']['An error occurred during module deletion.'] = 'Une erreur est survenue durant la suppression du module.'; +$GLOBALS['__l10n']['Unable to upgrade "%s". (same version)'] = 'Impossible de mettre à jour "%s" (même version).'; +$GLOBALS['__l10n']['Unable to read new _define.php file'] = 'Impossible de lire le nouveau fichier _define.php.'; +$GLOBALS['__l10n']['No such module.'] = 'Module inexistant.'; +$GLOBALS['__l10n']['Cannot remove module files'] = 'Impossible de supprimer les fichiers du module'; +$GLOBALS['__l10n']['Cannot deactivate plugin.'] = 'L\'extension ne peut pas être désactivée.'; +$GLOBALS['__l10n']['Cannot activate plugin.'] = 'L\'extension ne peut pas être activée.'; +$GLOBALS['__l10n']['Invalid setting dcNamespace: %s'] = 'Espace de nommage du paramètre invalide : %s'; +$GLOBALS['__l10n']['Unable to retrieve settings:'] = 'Impossible d\'obtenir les paramètres :'; +$GLOBALS['__l10n']['%s is not a valid setting id'] = '%s n\'est pas un identifiant de paramètre valide'; +$GLOBALS['__l10n']['No namespace specified'] = 'Aucun espace de nommage spécifié'; +$GLOBALS['__l10n']['Unable to retrieve workspaces:'] = 'Impossible d\'obtenir les espaces de travail :'; +$GLOBALS['__l10n']['Unable to retrieve namespaces:'] = 'Impossible d\'obtenir les espaces de nommage :'; +$GLOBALS['__l10n']['Invalid setting namespace: %s'] = 'Espace de nommage du paramètre invalide : %s'; +$GLOBALS['__l10n']['%s has still been pinged'] = 'Un rétrolien vers %s a déjà été fait'; +$GLOBALS['__l10n']['Unable to ping URL'] = 'Impossible de réaliser le rétrolien'; +$GLOBALS['__l10n']['%s is not a ping URL'] = '%s n\'est pas une URL de rétrolien'; +$GLOBALS['__l10n']['%s, ping error:'] = '%s, erreur de rétrolien :'; +$GLOBALS['__l10n']['Digests file not found.'] = 'Fichier de contrôle introuvable.'; +$GLOBALS['__l10n']['No file to download'] = 'Aucun fichier à télécharger.'; +$GLOBALS['__l10n']['Root directory is not writable.'] = 'Le répertoire principal n\'est pas accessible en écriture.'; +$GLOBALS['__l10n']['An error occurred while downloading archive.'] = 'Une erreur est survenue lors du téléchargement de l\'archive.'; +$GLOBALS['__l10n']['Archive not found.'] = 'L\'archive n\'a pas été trouvée.'; +$GLOBALS['__l10n']['Unable to read current digests file.'] = 'Impossible de lire le fichier de contrôle actuel.'; +$GLOBALS['__l10n']['Downloaded file does not seem to be a valid archive.'] = 'Le fichier téléchargé ne semble pas être une archive valide.'; +$GLOBALS['__l10n']['Incomplete archive.'] = 'Archive incomplète.'; +$GLOBALS['__l10n']['Unable to read digests file.'] = 'Impossible de lire le fichier de contrôle.'; +$GLOBALS['__l10n']['Invalid digests file.'] = 'Fichier de contrôle invalide.'; +$GLOBALS['__l10n']['Invalid dcWorkspace: %s'] = 'Espace de travail de la préférence invalide : %s'; +$GLOBALS['__l10n']['Unable to retrieve prefs:'] = 'Impossible d\'obtenir les préférences :'; +$GLOBALS['__l10n']['%s is not a valid pref id'] = '%s n\'est pas un identifiant de préférence valide'; +$GLOBALS['__l10n']['No workspace specified'] = 'Aucun espace de travail spécifié'; +$GLOBALS['__l10n']['SQLite Database Schema cannot be upgraded.'] = 'Le schema de base de données SQLite ne peut pas être mis à jour.'; +$GLOBALS['__l10n']['Something went wrong with auto upgrade:'] = 'Une erreur est survenue durant la mise à jour automatique :'; +$GLOBALS['__l10n']['Unable to open directory.'] = 'Impossible d\'ouvrir le répertoire.'; +$GLOBALS['__l10n']['Unable to create directory.'] = 'Impossible de créer le répertoire.'; +$GLOBALS['__l10n']['File is not writable.'] = 'Le fichier n\'est pas accessible en écriture.'; +$GLOBALS['__l10n']['Unable to open file.'] = 'Impossible d\'ouvrir le fichier.'; +$GLOBALS['__l10n']['Not an uploaded file.'] = 'Pas un fichier déposé.'; +$GLOBALS['__l10n']['The uploaded file exceeds the maximum file size allowed.'] = 'Le fichier déposé est plus grand que la taille maximale autorisée.'; +$GLOBALS['__l10n']['The uploaded file was only partially uploaded.'] = 'Le fichier n\'a été chargé qu\'en partie.'; +$GLOBALS['__l10n']['No file was uploaded.'] = 'Aucun fichier chargé.'; +$GLOBALS['__l10n']['Missing a temporary folder.'] = 'Il manque un répertoire temporaire.'; +$GLOBALS['__l10n']['Failed to write file to disk.'] = 'Impossible d\'écrire le fichier.'; +$GLOBALS['__l10n']['%s is not a directory.'] = '%s n\'est pas un répertoire.'; +$GLOBALS['__l10n']['Bad range'] = 'Mauvaises limites'; +$GLOBALS['__l10n']['Invalid range'] = 'Sélection invalide'; +$GLOBALS['__l10n']['Invalid line number'] = 'Numéro de ligne invalide invalide'; +$GLOBALS['__l10n']['Chunk is out of range'] = 'L\'extrait est hors limite'; +$GLOBALS['__l10n']['Bad context'] = 'Contexte invalide'; +$GLOBALS['__l10n']['Bad context (in deletion)'] = 'Contexte invalide (lors de la suppression)'; +$GLOBALS['__l10n']['Invalid diff format'] = 'Format de fichier diff invalide.'; +$GLOBALS['__l10n']['Uploading this file is not allowed.'] = 'L\'envoi de ce fichier n\'est pas autorisé.'; +$GLOBALS['__l10n']['Destination directory is not in jail.'] = 'Le répertoire cible n\'est pas en jail.'; +$GLOBALS['__l10n']['File already exists.'] = 'Le nouveau fichier existe déjà.'; +$GLOBALS['__l10n']['Cannot write in this directory.'] = 'Impossible d\'écrire dans ce répertoire.'; +$GLOBALS['__l10n']['An error occurred while writing the file.'] = 'Une erreur est survenue pendant l\'écriture du fichier.'; +$GLOBALS['__l10n']['Source file does not exist.'] = 'Le fichier source n\'existe pas'; +$GLOBALS['__l10n']['File is not in jail.'] = 'Le fichier n\'est pas en jail.'; +$GLOBALS['__l10n']['Destination directory is not writable.'] = 'Le répertoire cible n\'est pas accessible en écriture.'; +$GLOBALS['__l10n']['Unable to rename file.'] = 'Impossible de renommer le fichier.'; +$GLOBALS['__l10n']['File cannot be removed.'] = 'Ce fichier ne peut pas être supprimé.'; +$GLOBALS['__l10n']['Directory is not in jail.'] = 'Le répertoire n\'est pas en jail.'; +$GLOBALS['__l10n']['Directory cannot be removed.'] = 'Ce répertoire ne peut pas être supprimé.'; +$GLOBALS['__l10n']['Not enough memory to open image.'] = 'Mémoire insuffisante pour ouvrir l\'image.'; +$GLOBALS['__l10n']['File %s is not compressed in the zip.'] = 'Le fichier %s n\'est pas compressé dans le zip.'; +$GLOBALS['__l10n']['Trying to unzip a folder name %s'] = 'Tentative de décompresser un répertoire %s'; +$GLOBALS['__l10n']['Unable to write destination file.'] = 'Impossible d\'écrire le fichier de destination'; +$GLOBALS['__l10n']['Unable to write in target directory, permission denied.'] = 'Impossible d\'écrire dans le répertoire cible, permission refusée.'; +$GLOBALS['__l10n']['Not enough memory to open file.'] = 'Mémoire insuffisante pour ouvrir le fichier.'; +$GLOBALS['__l10n']['File does not exist'] = 'Le fichier n\'existe pas'; +$GLOBALS['__l10n']['Cannot read file'] = 'Impossible de lire le fichier'; +$GLOBALS['__l10n']['Directory does not exist'] = 'Le répertoire n\'existe pas'; +$GLOBALS['__l10n']['Cannot read directory'] = 'Impossible de lire le répertoire'; +$GLOBALS['__l10n']['Unable to connect to database'] = 'Connexion à la base de données impossible'; +$GLOBALS['__l10n']['

        This either means that the username and password information in your config.php file is incorrect or we can\'t contact the database server at "%s". This could mean your host\'s database server is down.

        • Are you sure you have the correct username and password?
        • Are you sure that you have typed the correct hostname?
        • Are you sure that the database server is running?

        If you\'re unsure what these terms mean you should probably contact your host. If you still need help you can always visit the Dotclear Support Forums.

        '] = '

        Cela signifie soit que les informations d\'identifiant ou de mot de passe de votre fichier config.php sont incorrects, soit que nous ne pouvons pas contacter le serveur de base de données à l\'adresse "%s". Cela peut vouloir dire que le serveur en question est éteint.

        • Êtes-vous sûr que l\'identifiant et le mot de passe sont corrects ?
        • Êtes-vous sûr d\'avoir entré le bon nom de serveur ?
        • Êtes-vous sûr que le serveur fonctionne ?

        S vous n\'êtes pas sûr de la signification de ces termes, vous devriez probablement contacter votre hébergeur. Si vous avez besoin d\'une aide supplémentaire, vous pouvez vous rendre sur le forum d\'entraide Dotclear.

        '; +$GLOBALS['__l10n']['The following error was encountered while trying to read the database:'] = 'L\'erreur suivante a été rencontrée lors de la tentative d\'accès à la base de données :'; +?> \ No newline at end of file diff --git a/v2/dotclear/locales/fr/main.po b/v2/dotclear/locales/fr/main.po new file mode 100644 index 0000000..2cceae3 --- /dev/null +++ b/v2/dotclear/locales/fr/main.po @@ -0,0 +1,2896 @@ +# French translation of DotClear +# Copyright (C) 2006. +# Olivier Meunier , 2006. +msgid "" +msgstr "" +"Project-Id-Version: Dotclear 2\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-08-13 10:46+0200\n" +"PO-Revision-Date: 2011-10-13 19:26+0100\n" +"Last-Translator: xave \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: \n" +"X-Poedit-Language: French\n" + +msgid "Dotclear has been upgraded." +msgstr "Dotclear a été mis à jour." + +msgid "Password reset" +msgstr "Réinitialisation du mot de passe" + +msgid "Someone has requested to reset the password for the following site and username." +msgstr "Quelqu'un a demandé la réinitialisation du mot de passe pour le site et l'utilisateur suivants." + +msgid "Username:" +msgstr "Nom d'utilisateur :" + +msgid "To reset your password visit the following address, otherwise just ignore this email and nothing will happen." +msgstr "Pour réinitialiser votre mot de passe, rendez-vous à l'adresse suivante. Sinon ignorez simplement ce message et rien ne se passera." + +#, php-format +msgid "The e-mail was sent successfully to %s." +msgstr "Le message a été envoyé avec succès à %s." + +msgid "Your new password" +msgstr "Votre nouveau mot de passe" + +msgid "Password:" +msgstr "Mot de passe :" + +msgid "Your new password is in your mailbox." +msgstr "Votre nouveau mot de passe est dans votre boîte à lettres." + +msgid "Passwords don't match" +msgstr "Les mots de passe ne correspondent pas" + +msgid "You didn't change your password." +msgstr "Vous n'avez pas changé votre mot de passe." + +msgid "You have to change your password before you can login." +msgstr "Vous devez changer de mot de passe avant de vous connecter." + +msgid "In order to login, you have to change your password now." +msgstr "Afin de vous connecter, vous devez changer votre mot de passe." + +msgid "Safe Mode can only be used for super administrators." +msgstr "Le mode sans échec ne peut être utilisé que par un super administrateur." + +msgid "Wrong username or password" +msgstr "Nom d'utilisateur ou mot de passe incorrect" + +msgid "Back to login screen" +msgstr "Retour à l'écran de connexion" + +msgid "Request a new password" +msgstr "Demander un nouveau mot de passe" + +msgid "Email:" +msgstr "Email :" + +msgid "recover" +msgstr "récupérer" + +msgid "Change your password" +msgstr "Changer votre mot de passe" + +msgid "New password:" +msgstr "Nouveau mot de passe :" + +msgid "Confirm password:" +msgstr "Confirmez le mot de passe :" + +msgid "change" +msgstr "changer" + +msgid "Safe mode login" +msgstr "Connexion en mode sans échec" + +msgid "This mode allows you to login without activating any of your plugins. This may be useful to solve compatibility problems" +msgstr "Ce mode vous permet de vous connecter sans activer de plugins. Il peut être utile pour résoudre un problème de compatibilité" + +msgid "Disable or delete any plugin suspected to cause trouble, then log out and log back in normally." +msgstr "Désactivez ou supprimez les plugins semblant en être la cause, puis déconnectez-vous et connectez-vous à nouveau normalement." + +msgid "Remember my ID on this computer" +msgstr "Se souvenir de mon identifiant sur cet ordinateur" + +msgid "log in" +msgstr "Se connecter" + +msgid "You must accept cookies in order to use the private area." +msgstr "Vous devez accepter les cookies pour utiliser l'interface privée." + +msgid "Get back to normal authentication" +msgstr "Retour à l'écran de connexion normal" + +msgid "Connection issue?" +msgstr "Problème de connexion ?" + +msgid "I forgot my password" +msgstr "J'ai oublié mon mot de passe" + +msgid "I want to log in in safe mode" +msgstr "Me connecter en mode sans échec" + +msgid "New blog" +msgstr "Nouveau blog" + +msgid "Blogs" +msgstr "Blogs" + +msgid "Blog ID:" +msgstr "Identifiant du blog :" + +msgid "Required field" +msgstr "Champ obligatoire" + +msgid "At least 2 characters using letters, numbers or symbols." +msgstr "Au moins 2 caractères, composés de lettres non accentuées, chiffres ou symboles." + +msgid "Please note that changing your blog ID may require changes in your public index.php file." +msgstr "Veuillez noter que changer l'identifiant de votre blog peut nécessiter des modifications dans votre fichier index.php public." + +msgid "Blog name:" +msgstr "Nom du blog :" + +msgid "Blog URL:" +msgstr "URL du blog :" + +msgid "Blog description:" +msgstr "Description du blog :" + +msgid "Create" +msgstr "Créer" + +msgid "No such blog ID" +msgstr "Identifiant de blog inconnu" + +msgid "Password verification failed" +msgstr "La vérification du mot de passe a échoué" + +msgid "Delete a blog" +msgstr "Supprimer un blog" + +msgid "Warning" +msgstr "Attention" + +#, php-format +msgid "You are about to delete the blog %s. Every entry, comment and category will be deleted." +msgstr "Vous êtes sur le point de supprimer le blog %s. Tous ses billets, commentaires et catégories seront supprimés." + +msgid "Please give your password to confirm the blog deletion." +msgstr "Veuillez indiquer votre mot de passe pour confirmer la suppression du blog." + +msgid "Your password:" +msgstr "Votre mot de passe :" + +msgid "Delete this blog" +msgstr "Supprimer ce blog" + +msgid "No given blog id." +msgstr "Pas d'identifiant de blog." + +msgid "No such blog." +msgstr "Blog inexistant." + +msgid "year/month/day/title" +msgstr "année/mois/jour/titre" + +msgid "year/month/title" +msgstr "année/mois/titre" + +msgid "year/title" +msgstr "année/titre" + +msgid "title" +msgstr "titre" + +msgid "Title" +msgstr "Titre" + +msgid "Title, Date" +msgstr "Titre, date" + +msgid "Title, Country, Date" +msgstr "Titre, pays, date" + +msgid "Title, City, Country, Date" +msgstr "Titre, ville, pays, date" + +msgid "I would like search engines and archivers to index and archive my blog's content." +msgstr "Je souhaite que mon blog soit indexé et archivé par les moteurs de recherche et archiveurs." + +msgid "I would like search engines and archivers to index but not archive my blog's content." +msgstr "Je souhaite que mon blog soit indexé mais pas archivé par les moteurs de recherche et archiveurs." + +msgid "I would like to prevent search engines and archivers from indexing or archiving my blog's content." +msgstr "Je souhaite que mon blog ne soit ni indexé ni archivé par les moteurs de recherche et archiveurs." + +msgid "That blog Id is already in use." +msgstr "Cet identifiant est déjà utilisé" + +msgid "Invalid language code" +msgstr "Code langue invalide" + +msgid "Blog settings" +msgstr "Paramètres du blog" + +msgid "Warning: except for special configurations, it is generally advised to have a trailing \"/\" in your blog URL in PATH_INFO mode." +msgstr "Attention: sauf cas particulier, il est généralement conseillé de terminer l'URL de votre blog par \"/\" en mode PATH_INFO." + +msgid "Warning: except for special configurations, it is generally advised to have a trailing \"?\" in your blog URL in QUERY_STRING mode." +msgstr "Attention: sauf cas particulier, il est généralement conseillé de terminer l'URL de votre blog par \"?\" en mode QUERY_STRING." + +msgid "Blog has been successfully created." +msgstr "Blog créé avec succès." + +msgid "Blog has been successfully updated." +msgstr "Blog mis à jour avec succès." + +msgid "Parameters" +msgstr "Paramètres" + +msgid "Blog details" +msgstr "Informations du blog" + +msgid "URL scan method:" +msgstr "Méthode de lecture de l'URL :" + +msgid "Blog status:" +msgstr "État du blog :" + +msgid "Blog configuration" +msgstr "Configuration du blog" + +msgid "Blog editor name:" +msgstr "Nom de l'éditeur du blog :" + +msgid "Default language:" +msgstr "Langue par défaut :" + +msgid "Blog timezone:" +msgstr "Fuseau horaire du blog :" + +msgid "Copyright notice:" +msgstr "Note de copyright :" + +msgid "New post URL format:" +msgstr "Format d'URL des nouveaux billets :" + +msgid "Enable XML/RPC interface" +msgstr "Activer l'interface XML/RPC" + +msgid "more information" +msgstr "plus d'informations" + +msgid "Comments and trackbacks" +msgstr "Commentaires et rétroliens" + +msgid "Accept comments" +msgstr "Accepter les commentaires" + +msgid "Moderate comments" +msgstr "Modérer les commentaires" + +#, php-format +msgid "Leave comments open for %s days" +msgstr "Laisser les commentaires ouverts durant %s jours" + +msgid "Leave blank to disable this feature." +msgstr "Laissez vide pour annuler ce comportement." + +msgid "Wiki syntax for comments" +msgstr "Syntaxe wiki pour les commentaires" + +msgid "Accept trackbacks" +msgstr "Accepter les rétroliens" + +msgid "Moderate trackbacks" +msgstr "Modérer les rétroliens" + +#, php-format +msgid "Leave trackbacks open for %s days" +msgstr "Laisser les rétroliens ouverts durant %s jours" + +msgid "Add \"nofollow\" relation on comments and trackbacks links" +msgstr "Ajouter la relation \"nofollow\" aux liens des commentaires et rétroliens" + +msgid "Blog presentation" +msgstr "Présentation du blog" + +msgid "Date format:" +msgstr "Format des dates :" + +msgid "Time format:" +msgstr "Format des heures :" + +msgid "Display smilies on entries and comments" +msgstr "Afficher des émoticones dans les billets et commentaires" + +#, php-format +msgid "Display %s entries per page" +msgstr "Afficher %s billets par page" + +#, php-format +msgid "Display %s entries per feed" +msgstr "Afficher %s billets par flux de syndication" + +#, php-format +msgid "Display %s comments per feed" +msgstr "Afficher %s commentaires par flux de syndication" + +msgid "Truncate feeds" +msgstr "Tronquer les flux de syndication" + +msgid "Media and images" +msgstr "Médias et images" + +msgid "Generated image sizes (in pixels)" +msgstr "Tailles des images générées (en pixels)" + +msgid "Thumbnails:" +msgstr "Miniatures :" + +msgid "Small:" +msgstr "Petites :" + +msgid "Medium:" +msgstr "Moyennes :" + +msgid "Inserted image title" +msgstr "Titres des images insérées" + +msgid "This defines image tag title when you insert it in a post from the media manager. It is retrieved from the picture's metadata." +msgstr "Ceci définit le titre de la balise d'une image insérée depuis le gestionnaire de media. Les informations sont obtenues depuis les métadonnées de l'image." + +msgid "Search engines robots policy" +msgstr "Paramètres d'indexation par les moteurs de recherche" + +msgid "Save" +msgstr "Enregistrer" + +msgid "XML/RPC interface" +msgstr "Interface XML/RPC" + +msgid "XML/RPC interface allows you to edit your blog with an external client." +msgstr "L'interface XML/RPC vous permet de publier sur votre blog avec un client externe." + +msgid "XML/RPC interface is not active. Change settings to enable it." +msgstr "L'interface XML/RPC n'est pas active. Changez vos paramètres pour l'activer." + +msgid "XML/RPC interface is active. You should set the following parameters on your XML/RPC client:" +msgstr "L'interface XML/RPC est active. Vous êtes invités à indiquer les paramètres suivants dans votre client XML/RPC :" + +msgid "Server URL:" +msgstr "URL du serveur :" + +msgid "Blogging system:" +msgstr "Système de blog :" + +msgid "User name:" +msgstr "Nom d'utilisateur :" + +msgid "your password" +msgstr "votre mot de passe" + +msgid "Users" +msgstr "Utilisateurs" + +msgid "Users on this blog" +msgstr "Utilisateurs de ce blog" + +msgid "No users" +msgstr "Aucun utilisateur" + +msgid "Change permissions" +msgstr "Changer les permissions" + +msgid "Super administrator" +msgstr "Super administrateur" + +msgid "You can't remove default theme." +msgstr "Vous ne pouvez pas supprimer le thème par défaut." + +msgid "Theme does not exist." +msgstr "Ce thème n'existe pas." + +msgid "Unable to move uploaded file." +msgstr "Impossible de déplacer le fichier téléchargé." + +msgid "An error occurred while downloading the file." +msgstr "Une erreur est survenue lors du téléchargement du fichier." + +#, php-format +msgid "by %s" +msgstr "par %s" + +#, php-format +msgid "version %s" +msgstr "version %s" + +#, php-format +msgid "(built on \"%s\")" +msgstr "(basé sur \"%s\")" + +#, php-format +msgid "(requires \"%s\")" +msgstr "(nécessite \"%s\")" + +msgid "Stylesheet" +msgstr "Feuille de style" + +msgid "Configure theme" +msgstr "Configurer le thème" + +msgid "Blog appearance" +msgstr "Apparence du blog" + +msgid "Theme has been successfully changed." +msgstr "Thème changé avec succès." + +msgid "Theme has been successfully installed." +msgstr "Le thème a été installé avec succès." + +msgid "Theme has been successfully upgraded" +msgstr "Le thème a été mis à jour avec succès." + +msgid "Theme has been successfully deleted." +msgstr "Le thème a été supprimé avec succès." + +#, php-format +msgid "You can find additional themes for your blog on %s." +msgstr "Vous pouvez trouver de nouveaux thèmes pour votre blog sur %s." + +msgid "To install or upgrade a theme you generally just need to upload it in \"Install or upgrade a theme\" section." +msgstr "Tout ce que vous avez à faire pour installer ou mettre à jour un thème est généralement de le déposer dans la section \"Installer ou mettre à jour un thème\"." + +msgid "Themes" +msgstr "Thèmes" + +#, php-format +msgid "You are currently using \"%s\"" +msgstr "Vous utilisez actuellement \"%s\"" + +msgid "Use selected theme" +msgstr "Utiliser le thème sélectionné" + +msgid "Delete selected theme" +msgstr "Supprimer le thème sélectionné" + +msgid "Install or upgrade a theme" +msgstr "Installer ou mettre à jour un thème" + +msgid "You can install themes by uploading or downloading zip files." +msgstr "Vous pouvez installer des thèmes en déposant ou téléchargeant des fichiers zip." + +msgid "Upload a zip file" +msgstr "Déposer un fichier zip" + +msgid "Theme zip file:" +msgstr "Fichier zip du thème :" + +msgid "Upload theme" +msgstr "Déposer un thème" + +msgid "Download a zip file" +msgstr "Télécharger un fichier zip" + +msgid "Theme zip file URL:" +msgstr "URL du fichier zip du thème :" + +msgid "Download theme" +msgstr "Télécharger le thème" + +msgid "To enable this function, please give write access to your themes directory." +msgstr "Pour activer cette fonction, donnez un accès en écriture à votre répertoire de thèmes." + +msgid "Theme configuration" +msgstr "Configurer le thème" + +msgid "back" +msgstr "retour" + +msgid "Last update" +msgstr "Dernière mise à jour" + +msgid "Blog name" +msgstr "Nom du blog" + +msgid "Blog ID" +msgstr "Identifiant du blog" + +msgid "Descending" +msgstr "Décroissant" + +msgid "Ascending" +msgstr "Croissant" + +msgid "List of blogs" +msgstr "Liste des blogs" + +msgid "Blog has been successfully deleted." +msgstr "Blog supprimé avec succès." + +msgid "Create a new blog" +msgstr "Créer un nouveau blog" + +msgid "Filters" +msgstr "Filtres" + +msgid "Order by:" +msgstr "Trier par :" + +msgid "Sort:" +msgstr "Ordre :" + +msgid "Search:" +msgstr "Chercher :" + +msgid "Blogs per page" +msgstr "Blogs par page" + +msgid "Apply filters" +msgstr "Appliquer les filtres" + +msgid "No blog" +msgstr "Pas de blog" + +msgid "Page(s)" +msgstr "Page(s)" + +msgid "Entries" +msgstr "Billets" + +msgid "Status" +msgstr "État" + +#, php-format +msgid "Edit blog %s" +msgstr "Modifier le blog %s" + +msgid "edit" +msgstr "modifier" + +#, php-format +msgid "Switch to blog %s" +msgstr "Passer au blog %s" + +msgid "This category does not exist." +msgstr "Cette catégorie n'existe pas." + +msgid "Categories" +msgstr "Catégories" + +msgid "The category has been successfully created." +msgstr "Catégorie créée avec succès." + +msgid "The category has been successfully removed." +msgstr "Catégorie supprimée avec succès." + +msgid "Categories have been successfully reordered." +msgstr "Catégories réordonnées avec succès." + +msgid "The category has been successfully moved." +msgstr "Catégorie déplacée avec succès." + +msgid "No category yet." +msgstr "Pas encore de catégorie." + +msgid "Categories list" +msgstr "Liste des catégories" + +#, php-format +msgid "%d entries" +msgstr "%d billets" + +#, php-format +msgid "%d entry" +msgstr "%d billet" + +msgid "total:" +msgstr "total :" + +msgid "URL:" +msgstr "URL :" + +msgid "Add a new category" +msgstr "Créer une nouvelle catégorie" + +msgid "Title:" +msgstr "Titre :" + +msgid "Parent:" +msgstr "Parent :" + +msgid "Top level" +msgstr "Premier niveau" + +msgid "Remove a category" +msgstr "Supprimer une catégorie" + +msgid "Choose a category to remove:" +msgstr "Choisissez une catégorie à supprimer :" + +msgid "Delete" +msgstr "Supprimer" + +msgid "Reorder categories" +msgstr "Réordonner les catégories" + +msgid "This will relocate all categories on the top level" +msgstr "Ceci va déplacer toutes les catégories au premier niveau" + +msgid "Reorder" +msgstr "Réordonner" + +msgid "New category" +msgstr "Nouvelle catégorie" + +msgid "Category has been successfully updated." +msgstr "Catégorie mise à jour avec succès." + +msgid "Category information" +msgstr "Détails de la catégorie" + +msgid "Warning: If you set the URL manually, it may conflict with another category." +msgstr "Attention : si vous indiquez l'URL manuellement, celle-ci peut entrer en conflit avec une autre catégorie." + +msgid "Description:" +msgstr "Description :" + +msgid "Move this category" +msgstr "Déplacer cette catégorie" + +msgid "Category parent" +msgstr "Catégorie parente" + +msgid "Category sibling" +msgstr "Catégorie voisine" + +msgid "Move current category" +msgstr "Déplacer la catégorie" + +msgid "after" +msgstr "après" + +msgid "before" +msgstr "avant" + +msgid "position: " +msgstr "position : " + +msgid "Entry does not exist." +msgstr "Ce billet n'existe pas." + +msgid "No comment" +msgstr "Aucun commentaire" + +msgid "You can't edit this comment." +msgstr "Vous ne pouvez pas modifier ce commentaire." + +msgid "Edit comment" +msgstr "Modifier le commentaire" + +msgid "Comment has been successfully updated." +msgstr "Commentaire mis à jour avec succès." + +#, php-format +msgid "Your comment on my blog %s" +msgstr "Votre commentaire sur mon blog %s" + +#, php-format +msgid "" +"Hi!\n" +"\n" +"You wrote a comment on:\n" +"%s\n" +"\n" +"\n" +msgstr "" +"Bonjour,\n" +"\n" +"Vous avez déposé un commentaire sur \n" +"%s\n" +"\n" +"\n" + +msgid "Send an e-mail" +msgstr "Envoyer un email" + +msgid "IP address:" +msgstr "Adresse IP :" + +msgid "Date:" +msgstr "Date :" + +msgid "Author:" +msgstr "Auteur :" + +msgid "Web site:" +msgstr "Site web :" + +msgid "Status:" +msgstr "État :" + +msgid "Comment:" +msgstr "Commentaire :" + +msgid "comment" +msgstr "commentaire" + +msgid "trackback" +msgstr "rétrolien" + +msgid "Date" +msgstr "Date" + +msgid "Entry title" +msgstr "Titre du billet" + +msgid "Author" +msgstr "Auteur" + +msgid "publish" +msgstr "publier" + +msgid "unpublish" +msgstr "hors ligne" + +msgid "mark as pending" +msgstr "en attente" + +msgid "mark as junk" +msgstr "indésirable" + +msgid "Type:" +msgstr "Type :" + +msgid "Comments per page" +msgstr "Commentaires par page" + +msgid "Comment author:" +msgstr "Auteur du commentaire :" + +msgid "You have one spam comments." +msgstr "Vous avez un commentaire indésirable." + +msgid "Show it." +msgstr "L'afficher" + +#, php-format +msgid "You have %s spam comments." +msgstr "Vous avez %s commentaires indésirables." + +msgid "Show them." +msgstr "Les afficher." + +msgid "Selected comments action:" +msgstr "Action sur les commentaires sélectionnés :" + +msgid "action: " +msgstr "action : " + +msgid "ok" +msgstr "ok" + +msgid "Comments" +msgstr "Commentaires" + +#, php-format +msgid "%d comment" +msgstr "%d commentaire" + +#, php-format +msgid "%d comments" +msgstr "%d commentaires" + +msgid "New entry" +msgstr "Nouveau billet" + +msgid "My preferences" +msgstr "Mes préférences" + +msgid "Documentation and support" +msgstr "Documentation et support" + +msgid "Latest news" +msgstr "Actualités" + +msgid "Dashboard" +msgstr "Tableau de bord" + +msgid "Make this blog my default blog" +msgstr "Définir comme blog par défaut" + +msgid "This blog is offline" +msgstr "Ce blog est hors ligne" + +msgid "This blog is removed" +msgstr "Ce blog est supprimé" + +msgid "is not defined, you should edit your configuration file." +msgstr "n'est pas défini, vous devriez corriger votre fichier de configuration." + +msgid "Following plugins have been installed:" +msgstr "Les extensions suivantes ont été installées :" + +msgid "Following plugins have not been installed:" +msgstr "Les extensions suivantes n'ont pas été installées :" + +#, php-format +msgid "Dotclear %s is available!" +msgstr "Dotclear %s est disponible !" + +msgid "Upgrade now" +msgstr "Mettre à jour maintenant" + +msgid "Remind me later" +msgstr "Me le rappeler plus tard" + +msgid "information about this version" +msgstr "Information à propos de cette version" + +msgid "Some plugins are installed twice:" +msgstr "Ces extensions sont installées en double :" + +msgid "Quick entry" +msgstr "Billet rapide" + +msgid "Content:" +msgstr "Contenu :" + +msgid "Category:" +msgstr "Catégorie :" + +msgid "Save and publish" +msgstr "Enregister et publier" + +#, php-format +msgid "PHP version is %s (5.0 or earlier needed)." +msgstr "La version de PHP est %s (5.0 ou plus récent nécessaire.)" + +msgid "Multibyte string module (mbstring) is not available." +msgstr "Le support des chaînes multi-octets (mbstring) n'est pas disponible." + +msgid "Iconv module is not available." +msgstr "Le module iconv n'est pas disponible." + +msgid "Output control functions are not available." +msgstr "Les fonctions de bufferisation de sortie ne sont pas disponibles." + +msgid "SimpleXML module is not available." +msgstr "Le module SimpleXML n'est pas disponible." + +msgid "DOM XML module is not available." +msgstr "Le module DOM XML n'est pas disponible." + +msgid "PCRE engine does not support UTF-8 strings." +msgstr "Le moteur d'expressions rationnelles PCRE ne gère pas les chaînes UTF-8." + +msgid "SPL module is not available." +msgstr "Le module SPL n'est pas disponible." + +#, php-format +msgid "MySQL version is %s (4.1 or earlier needed)." +msgstr "La version de MySQL est %s (4.1 ou plus récent nécessaire)." + +msgid "MySQL InnoDB engine is not available." +msgstr "Le gestionnaire de stockage InnoDB de MySQL n'est pas disponible." + +#, php-format +msgid "PostgreSQL version is %s (8.0 or earlier needed)." +msgstr "La version de PostgreSQL est %s (8.0 ou plus récent nécessaire)." + +msgid "Please set a master key (DC_MASTER_KEY) in configuration file." +msgstr "Veuillez indiquer une clé de référence (DC_MASTER_KEY) dans le fichier de configuration." + +msgid "Dotclear is already installed." +msgstr "Dotclear est déjà installé." + +msgid "Dotclear cannot be installed." +msgstr "Dotclear ne peut pas être installé." + +msgid "No user ID given" +msgstr "Aucun identifiant utilisateur spécifié" + +msgid "User ID must contain at least 2 characters using letters, numbers or symbols." +msgstr "L'identifiant utilisateur doit contenir au moins 2 caractères composés de lettres, chiffres ou symboles." + +msgid "Invalid email address" +msgstr "Adresse email incorrecte" + +msgid "No password given" +msgstr "Aucun mot de passe spécifié" + +msgid "Password must contain at least 6 characters." +msgstr "Le mot de passe doit contenir au moins 6 caractères." + +msgid "My first blog" +msgstr "Mon premier blog" + +msgid "%A, %B %e %Y" +msgstr "%A %e %B %Y" + +msgid "Welcome to Dotclear!" +msgstr "Bienvenue sur Dotclear !" + +msgid "This is your first entry. When you're ready to blog, log in to edit or delete it." +msgstr "Ceci est votre premier billet. Quand vous serez prêt à bloguer, connectez-vous pour le modifier ou le supprimer." + +msgid "Dotclear Team" +msgstr "L'équipe Dotclear" + +msgid "" +"

        This is a comment.

        \n" +"

        To delete it, log in and view your blog's comments. Then you might remove or edit it.

        " +msgstr "

        Ceci est un commentaire

        Pour le supprimer, connectez-vous et affichez les commentaires de votre blog. Vous pourrez alors le supprimer ou le modifier.

        " + +msgid "Dotclear Install" +msgstr "Installation de Dotclear" + +msgid "show" +msgstr "voir" + +msgid "Dotclear installation" +msgstr "Installation de Dotclear" + +#, php-format +msgid "Cache directory %s is not writable." +msgstr "Le répertoire de cache %s n'est pas accessible en écriture." + +msgid "Errors:" +msgstr "Erreurs :" + +msgid "Configuration file has been successfully created." +msgstr "Le fichier de configuration a été créé avec succès." + +msgid "User information" +msgstr "Informations utilisateur" + +msgid "Please provide the following information needed to create the first user." +msgstr "Merci de fournir les informations suivantes pour créer le premier utilisateur." + +msgid "First Name:" +msgstr "Prénom :" + +msgid "Last Name:" +msgstr "Nom :" + +msgid "Username and password" +msgstr "Identifiant et mot de passe" + +msgid "All done!" +msgstr "Terminé !" + +msgid "Dotclear has been successfully installed. Here is some useful information you should keep." +msgstr "Dotclear a été installé avec succès. Conservez les informations suivantes précieusement." + +msgid "Your account" +msgstr "Votre compte" + +msgid "Your blog" +msgstr "Votre blog" + +msgid "Blog address:" +msgstr "Adresse du blog :" + +msgid "Administration interface:" +msgstr "Interface d'administration :" + +msgid "Manage your blog now" +msgstr "Gérez votre blog" + +msgid "Installation can not be completed" +msgstr "L'installation ne peut pas être menée à bien" + +msgid "For the said reasons, Dotclear can not be installed. Please refer to the documentation to learn how to correct the problem." +msgstr "Pour les raisons ci-dessus, Dotclear ne peut pas être installé. Référez-vous à la documentation pour savoir comment corriger le problème." + +#, php-format +msgid "File %s does not exist." +msgstr "Le fichier %s n'existe pas." + +#, php-format +msgid "Cannot write %s file." +msgstr "Impossible d'écrire le fichier %s." + +msgid "Dotclear installation wizard" +msgstr "Assistant d'installation de Dotclear" + +msgid "Welcome" +msgstr "Bienvenue" + +msgid "To complete your Dotclear installation and start writing on your blog, we just need to know how to access your database and who you are. Just fill this two steps wizard with this information and we will be done." +msgstr "Pour achever votre installation de Dotclear, il ne manque plus que les informations concernant votre base de données, puis vos informations personnelles. Remplissez simplement les deux formulaires suivants et vous pourrez commencer à utiliser votre blog." + +msgid "Attention:" +msgstr "Attention :" + +msgid "this wizard may not function on every host. If it does not work for you, please refer to the documentation to learn how to create the config.php file manually." +msgstr "cet assistant peut ne pas fonctionner chez tous les hébergeurs. Si vous rencontrez un problème, vous trouverez comment créer le fichier de configuration dans la documentation." + +msgid "System information" +msgstr "Informations système" + +msgid "Please provide the following information needed to create your configuration file." +msgstr "Merci de fournir les informations suivantes :" + +msgid "Database type:" +msgstr "Type de base de données :" + +msgid "Database Host Name:" +msgstr "Nom d'hôte de la base de données :" + +msgid "Database Name:" +msgstr "Nom de la base de données :" + +msgid "Database User Name:" +msgstr "Nom d'utilisateur de la base de données :" + +msgid "Database Password:" +msgstr "Mot de passe de la base de données :" + +msgid "Database Tables Prefix:" +msgstr "Préfixe des tables de la base de données :" + +msgid "Continue" +msgstr "Continuer" + +msgid "No such installed language" +msgstr "Cette langue n'est pas installée" + +msgid "You can't remove English language." +msgstr "Vous ne pouvez pas supprimer la langue anglaise." + +msgid "Permissions to delete language denied." +msgstr "Permission de supprimer la langue refusée." + +msgid "Invalid language file URL." +msgstr "URL de fichier de langue invalide." + +msgid "Languages management" +msgstr "Gestion des langues" + +msgid "Language has been successfully deleted." +msgstr "La langue a été supprimée avec succès." + +msgid "Language has been successfully installed." +msgstr "La langue a été installée avec succès." + +msgid "Language has been successfully upgraded" +msgstr "La langue a été mise à jour avec succès." + +msgid "Here you can install, upgrade or remove languages for your Dotclear installation." +msgstr "Sur cette page, vous pouvez installer, mettre à jour ou supprimer des langues de votre installation de Dotclear." + +#, php-format +msgid "You can change your user language in your preferences or change your blog's main language in your blog settings." +msgstr "Vous pouvez changer votre langue d'utilisateur dans vos préférences ou changer la langue principale de votre blog dans vos paramètres de blog." + +msgid "Installed languages" +msgstr "Langues installées" + +msgid "No additional language is installed." +msgstr "Aucune langue supplémentaire n'est installée." + +msgid "Language" +msgstr "Langue" + +msgid "Action" +msgstr "Action" + +msgid "Install or upgrade languages" +msgstr "Installer ou mettre à jour une langue" + +#, php-format +msgid "You can install or remove a language by adding or removing the relevant directory in your %s folder." +msgstr "Vous pouvez installer ou supprimer une langue en ajoutant ou supprimant le répertoire correspondant dans votre répertoire %s." + +msgid "Available languages" +msgstr "Langues disponibles" + +#, php-format +msgid "You can download and install a additional language directly from Dotclear.net. Proposed languages are based on your version: %s." +msgstr "Vous pouvez télécharger et installer une langue supplémentaire directement depuis Dotclear.net. Les langues proposées sont basées sur votre version : %s." + +msgid "Language:" +msgstr "Langue :" + +msgid "Install language" +msgstr "Installer la langue" + +msgid "You can install languages by uploading zip files." +msgstr "Vous pouvez installer des langues en déposant des fichiers zip." + +msgid "Language zip file:" +msgstr "Fichier zip de la langue :" + +msgid "Upload language" +msgstr "Déposer la langue" + +msgid "Invalid language zip file." +msgstr "Fichier zip de langue invalide." + +msgid "The zip file does not appear to be a valid Dotclear language pack." +msgstr "Le fichier zip ne semble pas être un fichier valide de langue Dotclear." + +msgid "An error occurred during language upgrade." +msgstr "Une erreur est survenue durant la mise à jour de la langue." + +msgid "Error:" +msgstr "Erreur :" + +msgid "By names, in ascending order" +msgstr "Par noms, croissants" + +msgid "By names, in descending order" +msgstr "Par noms, décroissants" + +msgid "By dates, in ascending order" +msgstr "Par dates, croissantes" + +msgid "By dates, in descending order" +msgstr "Par dates, décroissantes" + +msgid "Media manager" +msgstr "Gestionnaire de médias" + +msgid "confirm removal" +msgstr "Confirmer la suppression" + +#, php-format +msgid "Are you sure you want to remove %s?" +msgstr "Êtes-vous certain de vouloir supprimer %s ?" + +msgid "Cancel" +msgstr "Annuler" + +msgid "Yes" +msgstr "oui" + +msgid "Directory has been successfully created." +msgstr "Répertoire créé avec succès." + +msgid "Files have been successfully uploaded." +msgstr "Fichier chargé avec succès." + +msgid "File has been successfully removed." +msgstr "Fichier supprimé avec succès." + +msgid "Directory has been successfully removed." +msgstr "Répertoire supprimé avec succès." + +msgid "Directory has been successfully rebuilt." +msgstr "Répertoire reconstruit avec succès." + +msgid "Zip file has been successfully extracted." +msgstr "Le fichier zip a été extrait avec succès." + +#, php-format +msgid "Choose a file to attach to entry %s by clicking on %s." +msgstr "Choisissez un fichier à attacher au billet %s en cliquant sur %s." + +msgid "Attach this file to entry" +msgstr "Attacher ce fichier au billet" + +#, php-format +msgid "Choose a file to insert into entry by clicking on %s." +msgstr "Choisissez un fichier à insérer dans le billet en cliquant sur %s." + +msgid "No file." +msgstr "Aucun fichier." + +msgid "Sort files:" +msgstr "Trier les fichiers :" + +msgid "Sort" +msgstr "Trier" + +msgid "Add files" +msgstr "Ajouter des fichiers" + +msgid "Please take care to publish media that you own and that are not protected by copyright." +msgstr "Veuillez prendre garde à ne publier que des médias que vous possédez ou qui ne sont pas protégés contre la copie." + +msgid "Choose a file:" +msgstr "Choisissez un fichier :" + +#, php-format +msgid "Maximum size %s" +msgstr "Taille maximale %s" + +msgid "Private" +msgstr "Privé" + +msgid "To send several files at the same time, you can activate the enhanced uploader in" +msgstr "Pour envoyer plusieurs fichiers à la fois, vous pouvez activer l'interface avancée dans" + +msgid "Send" +msgstr "Envoyer" + +msgid "New directory" +msgstr "Nouveau répertoire" + +msgid "Directory Name:" +msgstr "Nom du répertoire :" + +msgid "Download this directory as a zip file" +msgstr "Télécharger ce répertoire dans un fichier zip" + +msgid "open" +msgstr "ouvrir" + +msgid "Insert this file into entry" +msgstr "Insérer ce fichier dans le billet" + +msgid "delete" +msgstr "supprimer" + +msgid "Not a valid file" +msgstr "Fichier invalide" + +msgid "File has been successfully updated." +msgstr "Fichier mis à jour avec succès." + +msgid "Thumbnails have been successfully updated." +msgstr "Les miniatures ont été mises à jour avec succès." + +msgid "Insert media item" +msgstr "Insérer un média" + +msgid "Image size:" +msgstr "Taille de l'image :" + +msgid "original" +msgstr "originale" + +msgid "Image alignment" +msgstr "Alignement de l'image" + +msgid "None" +msgstr "Aucun" + +msgid "Left" +msgstr "Gauche" + +msgid "Right" +msgstr "Droite" + +msgid "Center" +msgstr "Centre" + +msgid "Image insertion" +msgstr "Insertion de l'image" + +msgid "As a single image" +msgstr "En tant qu'image uniquement" + +msgid "As a link to original image" +msgstr "En tant que lien vers l'image originale" + +msgid "MP3 disposition" +msgstr "Disposition du MP3" + +msgid "Please note that you cannot insert mp3 files with visual editor." +msgstr "Merci de noter que vous ne pouvez pas insérer de fichier mp3 avec l'éditeur visuel." + +msgid "Please note that you cannot insert video files with visual editor." +msgstr "Merci de noter que vous ne pouvez pas insérer de fichier vidéo avec l'éditeur visuel." + +msgid "Video size" +msgstr "Taille de la vidéo" + +msgid "Width:" +msgstr "Largeur :" + +msgid "Height:" +msgstr "Hauteur :" + +msgid "Video disposition" +msgstr "Disposition de la vidéo" + +msgid "Media item will be inserted as a link." +msgstr "Le média sera inséré en tant que lien." + +msgid "Insert" +msgstr "Insérer" + +msgid "Media details" +msgstr "Détails du média" + +msgid "Available sizes:" +msgstr "Tailles disponibles :" + +msgid "File owner:" +msgstr "Propriétaire du fichier :" + +msgid "File type:" +msgstr "Type de fichier :" + +msgid "File size:" +msgstr "Taille du fichier :" + +msgid "File URL:" +msgstr "URL du fichier :" + +msgid "Show entries containing this media" +msgstr "Afficher les billets contenant ce média" + +msgid "Entries containing this media" +msgstr "Billets contenant ce média" + +msgid "No entry seems contain this media." +msgstr "Aucun billet ne semble contenir ce média." + +msgid "Image details" +msgstr "Détails de l'image" + +msgid "No detail" +msgstr "Aucun détail" + +msgid "Update thumbnails" +msgstr "Mettre à jour les miniatures" + +msgid "This will create or update thumbnails for this image." +msgstr "Ceci va créer ou mettre à jour les miniatures pour cette image." + +msgid "Extract in a new directory" +msgstr "Extraire dans un nouveau répertoire" + +msgid "Extract in current directory" +msgstr "Extraire dans le répertoire actuel" + +msgid "Extract archive" +msgstr "Extraire l'archive" + +msgid "This will extract archive in a new directory that should not exist yet." +msgstr "Ceci va extraire l'archive dans un nouveau répertoire qui ne doit pas encore exister." + +msgid "This will extract archive in current directory and will overwrite existing files or directory." +msgstr "Ceci va extraire l'archive dans le répertoire actuel et va écraser les fichiers ou répertoires existants." + +msgid "Extract mode:" +msgstr "Mode d'extraction :" + +msgid "Extract" +msgstr "Extrait" + +msgid "Change media properties" +msgstr "Changer les propriétés du média" + +msgid "File name:" +msgstr "Nom du fichier :" + +msgid "File title:" +msgstr "Titre du fichier :" + +msgid "File date:" +msgstr "Date du fichier :" + +msgid "New directory:" +msgstr "Nouveau répertoire :" + +msgid "Change file" +msgstr "Changer le fichier" + +msgid "No blog or user given." +msgstr "Vous n'avez pas indiqué de blog ou d'utilisateur" + +msgid "permissions" +msgstr "permissions" + +msgid "Permissions" +msgstr "Permissions" + +msgid "The permissions have been successfully updated." +msgstr "Permissions mises à jour avec succès." + +#, php-format +msgid "You are about to change permissions on the following blogs for users %s." +msgstr "Vous allez changer les permissions des utilisateurs %s pour ces blogs." + +msgid "Validate permissions" +msgstr "Valider les permissions" + +msgid "choose a blog" +msgstr "choisissez un blog" + +msgid "Choose a blog" +msgstr "Choisissez un blog" + +msgid "Entries per page" +msgstr "Billets par page" + +#, php-format +msgid "Choose one or more blogs to which you want to give permissions to users %s." +msgstr "Choisissez un ou plusieurs blogs pour lesquels les utilisateurs suivants auront des permissions : %s." + +msgid "Set permissions" +msgstr "définir les permissions" + +msgid "select" +msgstr "sélectionner" + +msgid "No content found on this plugin." +msgstr "Aucun contenu pour cette extension." + +msgid "Plugin not found" +msgstr "Extension introuvable" + +msgid "The plugin you reached does not exist or does not have an admin page." +msgstr "L'extension que vous essayez d'atteindre n'existe pas ou n'a pas de page d'administration." + +msgid "No such plugin." +msgstr "Extension inexistante." + +msgid "You don't have permissions to delete this plugin." +msgstr "Vous n'avez pas les permissions pour effacer cette extension" + +msgid "You don't have permissions to deactivate this plugin." +msgstr "Vous n'avez pas les permissions pour désactiver cette extension." + +msgid "Plugins management" +msgstr "Gestion des extensions" + +msgid "Plugin has been successfully deleted." +msgstr "L'extension a été supprimée avec succès." + +msgid "Plugin has been successfully installed." +msgstr "L'extension a été installée avec succès." + +msgid "Plugin has been successfully upgraded" +msgstr "L'extension a été mise à jour avec succès." + +msgid "Plugins add new functionalities to Dotclear. Here you can activate or deactivate installed plugins." +msgstr "Les extensions ajoutent de nouvelles fonctionnalités à Dotclear. Ici, vous pouvez activer ou désactiver les extensions installées." + +#, php-format +msgid "You can find additional plugins for your blog on %s." +msgstr "Vous pouvez trouver de nouvelles extensions pour votre blog sur %s." + +msgid "To install or upgrade a plugin you generally just need to upload it in \"Install or upgrade a plugin\" section." +msgstr "Tout ce que vous avez à faire pour installer ou mettre à jour une extension est généralement de la déposer dans la section \"Installer ou mettre à jour une extension\"." + +msgid "To install or upgrade a plugin you just need to extract it in your plugins directory." +msgstr "Tout ce que vous avez à faire pour installer une extension est de l'extraire dans votre répertoire d'extensions." + +msgid "Plugins" +msgstr "Extensions" + +msgid "Activated plugins" +msgstr "Extensions activées" + +msgid "Plugin" +msgstr "Extension" + +msgid "Version" +msgstr "Version" + +msgid "Details" +msgstr "Détails" + +msgid "Deactivate" +msgstr "Désactiver" + +msgid "Deactivated plugins" +msgstr "Extensions désactivées" + +msgid "Activate" +msgstr "Activer" + +msgid "Install or upgrade a plugin" +msgstr "Installer ou mettre à jour une extension" + +msgid "You can install plugins by uploading or downloading zip files." +msgstr "Vous pouvez installer des extensions en déposant ou téléchargeant des fichiers zip." + +msgid "Plugin zip file:" +msgstr "Fichier zip de l'extension :" + +msgid "Upload plugin" +msgstr "Déposer l'extension" + +msgid "Plugin zip file URL:" +msgstr "URL du fichier zip de l'extension :" + +msgid "Download plugin" +msgstr "Télécharger l'extension" + +msgid "To enable this function, please give write access to your plugins directory." +msgstr "Pour activer cette fonction, donnez un accès en écriture à votre répertoire d'extensions." + +msgid "Add a link" +msgstr "Ajouter un lien" + +msgid "Available" +msgstr "Disponible" + +msgid "Most used" +msgstr "Plus utilisées" + +msgid "Link URL:" +msgstr "URL du lien :" + +msgid "Link title:" +msgstr "Titre du lien :" + +msgid "Link language:" +msgstr "Langue du lien :" + +msgid "Add a link to an entry" +msgstr "Ajouter un lien vers un billet" + +msgid "Search entry:" +msgstr "Rechercher un billet :" + +msgid "Search" +msgstr "Rechercher" + +msgid "cancel" +msgstr "Annuler" + +msgid "This entry does not exist." +msgstr "Ce billet n'existe pas." + +msgid "Edit entry" +msgstr "Modifier le billet" + +msgid "next entry" +msgstr "billet suivant" + +msgid "previous entry" +msgstr "billet précédent" + +msgid "Entry has been successfully updated." +msgstr "Billet mis à jour avec succès." + +msgid "Entry has been successfully created." +msgstr "Billet créé avec succès." + +msgid "File has been successfully attached." +msgstr "Fichier attaché avec succès." + +msgid "Attachment has been successfully removed." +msgstr "Pièce jointe retirée avec succès." + +msgid "Comment has been successfully created." +msgstr "Commentaire créé avec succès." + +msgid "Don't forget to validate your XHTML conversion by saving your post." +msgstr "Enregistrez votre billet pour valider la transformation en XHTML." + +msgid "Go to this entry on the site" +msgstr "Voir ce billet sur le site" + +msgid "new window" +msgstr "nouvelle fenêtre" + +msgid "Excerpt:" +msgstr "Extrait :" + +msgid "Notes:" +msgstr "Notes :" + +msgid "Preview" +msgstr "Prévisualiser" + +msgid "Entry status:" +msgstr "État du billet :" + +msgid "Published on:" +msgstr "Publié le :" + +msgid "Text formating:" +msgstr "Format du texte :" + +msgid "Convert to XHTML" +msgstr "Convertir en XHTML" + +msgid "Selected entry" +msgstr "Billet sélectionné" + +msgid "Entry lang:" +msgstr "Langue du billet :" + +msgid "Entry password:" +msgstr "Mot de passe du billet :" + +msgid "Basename:" +msgstr "URL spécifique :" + +msgid "Warning: If you set the URL manually, it may conflict with another entry." +msgstr "Attention : si vous indiquez l'URL manuellement, celle-ci peut entrer en conflit avec un autre billet." + +msgid "Ping blogs" +msgstr "Faire des rétroliens" + +msgid "Trackbacks" +msgstr "Rétroliens" + +msgid "No trackback" +msgstr "Aucun rétrolien" + +msgid "Add a comment" +msgstr "Ajouter un commentaire" + +msgid "Name:" +msgstr "Nom :" + +msgid "IP address" +msgstr "Adresse IP" + +msgid "published" +msgstr "publié" + +msgid "unpublished" +msgstr "non publié" + +msgid "pending" +msgstr "en attente" + +msgid "junk" +msgstr "indésirable" + +msgid "select this comment" +msgstr "Sélectionner ce commentaire" + +msgid "select this trackback" +msgstr "Sélectionner ce rétrolien" + +msgid "Edit this comment" +msgstr "Modifier ce commentaire" + +msgid "This attachment does not exist" +msgstr "Cette pièce jointe n'existe pas" + +msgid "Remove attachment" +msgstr "Supprimer la pièce jointe" + +msgid "Attachment" +msgstr "Pièce jointe" + +msgid "Are you sure you want to remove this attachment?" +msgstr "Êtes-vous certain de vouloir supprimer cette pièce jointe ?" + +msgid "selected" +msgstr "sélectionné" + +msgid "not selected" +msgstr "non sélectionné" + +msgid "Category" +msgstr "Catégorie" + +msgid "Selected" +msgstr "Sélectionné" + +msgid "Publish" +msgstr "Publier" + +msgid "Unpublish" +msgstr "Mettre hors ligne" + +msgid "Schedule" +msgstr "Programmer" + +msgid "Mark as pending" +msgstr "Mettre en attente" + +msgid "Mark" +msgstr "Marquer" + +msgid "Mark as selected" +msgstr "Sélectionner" + +msgid "Mark as unselected" +msgstr "Désélectionner" + +msgid "Change" +msgstr "Changer" + +msgid "Change category" +msgstr "Changer la catégorie" + +msgid "Change author" +msgstr "Changer l'auteur" + +msgid "Selected:" +msgstr "Sélectionné :" + +msgid "Month:" +msgstr "Mois :" + +msgid "Lang:" +msgstr "Langue :" + +msgid "Selected entries action:" +msgstr "Action sur les billets sélectionnés :" + +msgid "This user does not exist" +msgstr "Cet utilisateur n'existe pas" + +msgid "Change category for entries" +msgstr "Changer de catégorie pour les billets" + +msgid "Change author for entries" +msgstr "Changer l'auteur des billets" + +msgid "Author ID:" +msgstr "Identifiant de l'utilisateur :" + +msgid "Default" +msgstr "Défaut" + +msgid "If you want to change your email or password you must provide your current password." +msgstr "Si vous voulez changer votre adresse email ou votre mot de passe, vous devez indiquer votre mot de passe actuel." + +msgid "No favorite selected" +msgstr "Aucun favori sélectionné" + +msgid "Personal information has been successfully updated." +msgstr "Informations personnelles mises à jour avec succès." + +msgid "Personal options has been successfully updated." +msgstr "Vos options personnelles ont été enregistrées avec succès." + +msgid "Favorites have been successfully added." +msgstr "Les favoris ont été ajoutés avec succès." + +msgid "Favorites have been successfully updated." +msgstr "Les favoris ont été mis à jour avec succès." + +msgid "Favorites have been successfully removed." +msgstr "Les favoris ont été retirés avec succès." + +msgid "Default favorites have been successfully updated." +msgstr "Les favoris par défaut ont été enregistrés avec succès." + +msgid "My profile" +msgstr "Mon profil" + +msgid "Display name:" +msgstr "Pseudonyme :" + +msgid "User language:" +msgstr "Langue de l'utilisateur :" + +msgid "User timezone:" +msgstr "Fuseau horaire de l'utilisateur :" + +msgid "If you have changed this user email or password you must provide your current password to save these modifications." +msgstr "Si vous voulez changer votre adresse email ou votre mot de passe, vous devez indiquer votre mot de passe." + +msgid "My options" +msgstr "Mes options" + +msgid "Preferred format:" +msgstr "Format d'édition préféré :" + +msgid "Default entry status:" +msgstr "État des billets par défaut :" + +msgid "Entry edit field height:" +msgstr "Taille de la zone d'édition :" + +msgid "Enable WYSIWYG mode" +msgstr "Activer l'éditeur visuel" + +msgid "Activate enhanced uploader in media manager" +msgstr "Activer l'interface avancée du gestionnaire de médias" + +msgid "Hide My favorites menu" +msgstr "Cacher le menu Mes Favoris" + +msgid "Iconset:" +msgstr "Jeu d'icônes :" + +msgid "Do not use standard favicon" +msgstr "Ne pas utiliser le favicon standard" + +msgid "This will be applied for all users" +msgstr "Ce choix sera actif pour tous les utilisateurs" + +msgid "Accessibility options" +msgstr "Options d'accessibilité" + +msgid "Disable javascript powered drag and drop for ordering items" +msgstr "Désactiver le drag and drop javascript pour ordonnancer les éléments" + +msgid "Numeric fields will allow to type the elements' ordering number." +msgstr "Des champs numériques permettront d'indiquer la position des éléments." + +msgid "Dashboard modules" +msgstr "Modules du tableau de bord" + +msgid "Display documentation links" +msgstr "Afficher les liens de documentation" + +msgid "Display Dotclear news" +msgstr "Afficher les nouvelles de Dotclear" + +msgid "Display quick entry form" +msgstr "Afficher le formulaire de billet rapide" + +msgid "My favorites" +msgstr "Mes favoris" + +#, php-format +msgid "position of %s" +msgstr "position de %s" + +msgid "Save order" +msgstr "Enregistrer l'ordre" + +msgid "Delete selected favorites" +msgstr "Retirer les favoris sélectionnés" + +msgid "Are you sure you want to remove selected favorites?" +msgstr "Êtes-vous sûr de vouloir retirer les favoris sélectionnés ?" + +msgid "If you are a super administrator, you may define this set of favorites to be used by default on all blogs of this installation:" +msgstr "Si vous êtes super administrateur, vous pouvez définir ce jeu de favoris comme l'ensemble par défaut pour tous les blogs de l'installation :" + +msgid "Define as default favorites" +msgstr "Définir comme favoris par défaut" + +msgid "Currently no personal favorites." +msgstr "La liste de vos favoris est vide pour le moment." + +msgid "Default favorites" +msgstr "Favoris par défaut" + +msgid "Those favorites are displayed when My Favorites list is empty." +msgstr "Favoris affichés quand la liste Mes Favoris est vide." + +msgid "Available favorites" +msgstr "Favoris disponibles" + +msgid "Add to my favorites" +msgstr "Ajouter à mes favoris" + +msgid "Search options" +msgstr "Options de recherche" + +msgid "Query:" +msgstr "Requête :" + +msgid "Search entries" +msgstr "Rechercher des billets" + +msgid "Search comments" +msgstr "Rechercher des commentaires" + +msgid "schedule" +msgstr "programmer" + +msgid "change category" +msgstr "changer la catégorie" + +msgid "change author" +msgstr "changer l'auteur" + +#, php-format +msgid "%d entries found" +msgstr "%d billets trouvés" + +#, php-format +msgid "%d entry found" +msgstr "%d billet trouvé" + +#, php-format +msgid "%d comment found" +msgstr "%d commentaire trouvé" + +#, php-format +msgid "%d comments found" +msgstr "%d commentaires trouvés" + +msgid "This entry does not exist or is not published" +msgstr "Ce billet n'existe pas ou n'est pas publié" + +msgid "All pings sent." +msgstr "Tous les rétroliens ont été envoyés." + +#, php-format +msgid "Back to \"%s\"" +msgstr "Retour à \"%s\"" + +msgid "Auto discover ping URLs" +msgstr "Découverte automatique des URL à rétrolier" + +msgid "URLs to ping:" +msgstr "URLs à rétrolier :" + +msgid "Send excerpt:" +msgstr "Envoyer l'extrait :" + +msgid "Previously sent pings" +msgstr "Rétroliens déjà envoyés" + +msgid "Dotclear update" +msgstr "Mise à jour de Dotclear" + +#, php-format +msgid "Unable to delete file %s" +msgstr "Impossible de supprimer le fichier %s" + +#, php-format +msgid "Downloaded Dotclear archive seems to be corrupted. Try download it again." +msgstr "L'archive téléchargée de Dotclear semble être corrompue. Essayer de la télécharger à nouveau." + +msgid "The following files of your Dotclear installation have been modified so we won't try to update your installation. Please try to update manually." +msgstr "Comme les fichiers suivants de votre installation de Dotclear ont été modifiés, votre installation ne peut être mise à jour. Merci de mettre à jour manuellement." + +#, php-format +msgid "The following files of your Dotclear installation are not readable. Please fix this or try to make a backup file named %s manually." +msgstr "Les fichiers suivants de votre installation de Dotclear ne peuvent pas être lus. Veuillez corriger ceci ou créer un fichier de backup nommé %s manuellement." + +msgid "The following files of your Dotclear installation cannot be written. Please fix this or try to update manually." +msgstr "Les fichiers suivants de votre installation de Dotclear ne peuvent pas être écrits. Veuillez corriger ceci ou mettre à jour manuellement." + +msgid "No newer Dotclear version available." +msgstr "Aucune nouvelle version de Dotclear n'est disponible." + +#, php-format +msgid "Dotclear %s is available." +msgstr "Dotclear %s est disponible." + +msgid "To upgrade your Dotclear installation simply click on the following button. A backup file of your current installation will be created in your root directory." +msgstr "Pour mettre à jour votre installation de Dotclear, cliquez sur le bouton suivant. Un fichier de sauvegarde de votre installation actuelle sera créé dans votre répertoire principal." + +msgid "Update Dotclear" +msgstr "Mettre à jour Dotclear" + +msgid "Update backup files" +msgstr "Sauvegardes des mises à jour" + +msgid "The following files are backups of previously updates. You can revert your previous installation or delete theses files." +msgstr "Les fichiers suivants sont des sauvegardes de mises à jour précédentes. Vous pouvez rétablir votre installation précédente ou supprimer ces fichiers." + +msgid "Please note that reverting your Dotclear version may have some unwanted side-effects. Consider reverting only if you experience strong issues with this new version." +msgstr "Merci de noter que rétablir votre version de Dotclear peut avoir des effets non désirés. N'envisagez ceci que si vous rencontrez d'importantes difficultés avec cette nouvelle version." + +#, php-format +msgid "You should not revert to version prior to last one (%s)." +msgstr "Vous ne devez pas rétablir une version précédant la dernière (%s)." + +msgid "Delete selected file" +msgstr "Supprimer le fichier sélectionné" + +msgid "Revert to selected file" +msgstr "Rétablir le fichier sélectionné" + +msgid "Congratulations, you're one click away from the end of the update." +msgstr "Félicitations, vous êtes à un clic de la fin de la mise à jour." + +msgid "Finish the update." +msgstr "Finir la mise à jour." + +msgid "new user" +msgstr "nouvel utilisateur" + +#, php-format +msgid "User \"%s\" already exists." +msgstr "L'utilisateur \"%s\" existe déjà." + +msgid "User has been successfully updated." +msgstr "Utilisateur mis à jour avec succès." + +msgid "User has been successfully created." +msgstr "Utilisateur créé avec succès." + +msgid "Warning:" +msgstr "Attention :" + +msgid "If you change your username, you will have to log in again." +msgstr "Si vous changez votre login, vous devrez vous identifier à nouveau." + +msgid "Mandatory for password recovering procedure." +msgstr "Obligatoire pour la procédure de récupération de mot de passe." + +msgid "Password change required to connect" +msgstr "Changement de mot de passe requis pour la connexion" + +msgid "Save and create another" +msgstr "Enregistrer et créer un nouveau" + +msgid "No permissions." +msgstr "Aucune permission." + +msgid "Add new permissions" +msgstr "Ajouter de nouvelles permissions" + +msgid "Username" +msgstr "Identifiant" + +msgid "Last Name" +msgstr "Nom" + +msgid "First Name" +msgstr "Prénom" + +msgid "Display name" +msgstr "Pseudonyme" + +msgid "Number of entries" +msgstr "Nombre de billets" + +msgid "users" +msgstr "utilisateurs" + +msgid "User has been successfully removed." +msgstr "Utilisateur supprimé avec succès." + +msgid "Create a new user" +msgstr "Créer un nouvel utilisateur" + +msgid "Users per page" +msgstr "Utilisateurs par page" + +msgid "Selected users action:" +msgstr "Action sur les utilisateurs sélectionnés :" + +msgid "Blog:" +msgstr "Blog :" + +msgid "Change blog" +msgstr "Changer de blog" + +msgid "Blogs:" +msgstr "Blogs :" + +msgid "Go to the content" +msgstr "Aller au contenu" + +msgid "Go to the menu" +msgstr "Aller au menu" + +msgid "Go to site" +msgstr "Aller sur le site" + +msgid "My dashboard" +msgstr "Mon tableau de bord" + +#, php-format +msgid "Logout %s" +msgstr "Déconnecter %s" + +msgid "Safe mode" +msgstr "Mode de secours" + +msgid "You are in safe mode. All plugins have been temporarily disabled. Remind to log out then log in again normally to get back all functionalities" +msgstr "Vous êtes en mode de secours. Tous les plugins ont été temporairement désactivés. N'oubliez-pas de vous déconnecter puis de vous reconnecter normalement pour retrouver toutes les fonctionnalités" + +#, php-format +msgid "Thank you for using %s." +msgstr "Merci d'utiliser %s." + +msgid "Help" +msgstr "Aide" + +msgid "uncover" +msgstr "dévoiler" + +msgid "hide" +msgstr "cacher" + +msgid "help" +msgstr "aide" + +msgid "no selection" +msgstr "aucune sélection" + +msgid "select all" +msgstr "tout sélectionner" + +msgid "invert selection" +msgstr "inverser la sélection" + +msgid "view entry" +msgstr "voir le billet" + +#, php-format +msgid "Are you sure you want to delete selected entries (%s)?" +msgstr "Êtes-vous certain de vouloir supprimer les billets sélectionnés (%s) ?" + +msgid "Are you sure you want to delete this entry?" +msgstr "Êtes-vous certain de vouloir supprimer ce billet ?" + +#, php-format +msgid "Are you sure you want to delete selected comments (%s)?" +msgstr "Êtes-vous certain de vouloir supprimer les commentaires sélectionnés (%s) ?" + +msgid "Are you sure you want to delete this comment?" +msgstr "Êtes-vous certain de vouloir supprimer ce commentaire ?" + +msgid "Users with posts cannot be deleted." +msgstr "Les utilisateurs ayant écrit des billets ne peuvent être effacées." + +#, php-format +msgid "Are you sure you want to delete selected users (%s)?" +msgstr "Êtes-vous certain de vouloir supprimer les utilisateurs sélectionnés (%s) ?" + +#, php-format +msgid "Are you sure you want to delete category \"%s\"?" +msgstr "Êtes-vous certain de vouloir supprimer la catégorie \"%s\" ?" + +msgid "Are you sure you want to reorder all categories?" +msgstr "Êtes-vous certain de vouloir réinitialiser l'ordre des catégories ?" + +#, php-format +msgid "Are you sure you want to remove media \"%s\"?" +msgstr "Êtes-vous certain de vouloir supprimer le média \"%s\" ?" + +msgid "Are you sure you want to extract archive in current directory?" +msgstr "Êtes-vous certain de vouloir extraire l'archive dans le répertoire actuel ?" + +#, php-format +msgid "Are you sure you want to remove attachment \"%s\"?" +msgstr "Êtes-vous certain de vouloir supprimer la pièce jointe \"%s\" ?" + +#, php-format +msgid "Are you sure you want to delete \"%s\" language?" +msgstr "Êtes-vous certain de vouloir supprimer la langue \"%s\" ?" + +#, php-format +msgid "Are you sure you want to delete \"%s\" plugin?" +msgstr "Êtes-vous certain de vouloir supprimer l'extension \"%s\" ?" + +msgid "Use this theme" +msgstr "Utiliser ce thème" + +msgid "Remove this theme" +msgstr "Supprimer ce thème" + +#, php-format +msgid "Are you sure you want to delete \"%s\" theme?" +msgstr "Êtes-vous certain de vouloir supprimer le thème \"%s\" ?" + +msgid "Zip file content" +msgstr "Contenu du fichier zip" + +msgid "XHTML markup validator" +msgstr "Validation XHTML" + +msgid "XHTML content is valid." +msgstr "Le contenu XHTML est valide." + +msgid "There are XHTML markup errors." +msgstr "Il y a des erreurs XHTML." + +msgid "You have unsaved changes. Switch post format will loose these changes. Proceed anyway?" +msgstr "Vous avez des modifications non sauvegardées. Changer de format vous fera perdre ces modifications. Continuer ?" + +msgid "Loading enhanced uploader, please wait." +msgstr "Chargement de l'interface avancée." + +msgid "You have unsaved changes." +msgstr "Vous n'avez pas enregistré vos modifications." + +msgid "close" +msgstr "fermer" + +msgid "now" +msgstr "maintenant" + +msgid "visual" +msgstr "visuel" + +msgid "source" +msgstr "source" + +msgid "You can use the following shortcuts to format your text." +msgstr "Vous pouvez utiliser les raccourcis suivants pour formater votre texte." + +msgid "-- none --" +msgstr "-- aucun --" + +msgid "-- block format --" +msgstr "-- format bloc --" + +msgid "Paragraph" +msgstr "Paragraphe" + +msgid "Level 1 header" +msgstr "Titre de niveau 1" + +msgid "Level 2 header" +msgstr "Titre de niveau 2" + +msgid "Level 3 header" +msgstr "Titre de niveau 3" + +msgid "Level 4 header" +msgstr "Titre de niveau 4" + +msgid "Level 5 header" +msgstr "Titre de niveau 5" + +msgid "Level 6 header" +msgstr "Titre de niveau 6" + +msgid "Strong emphasis" +msgstr "Forte emphase" + +msgid "Emphasis" +msgstr "Emphase" + +msgid "Inserted" +msgstr "Insertion" + +msgid "Deleted" +msgstr "Suppression" + +msgid "Inline quote" +msgstr "Citation en ligne" + +msgid "Code" +msgstr "Code" + +msgid "Line break" +msgstr "Passage à la ligne" + +msgid "Blockquote" +msgstr "Bloc de citation" + +msgid "Preformated text" +msgstr "Texte préformaté" + +msgid "Unordered list" +msgstr "Liste à puces" + +msgid "Ordered list" +msgstr "Liste numérotée" + +msgid "Link" +msgstr "Lien" + +msgid "URL?" +msgstr "URL ?" + +msgid "Language?" +msgstr "Langue ?" + +msgid "External image" +msgstr "Image externe" + +msgid "Media chooser" +msgstr "Sélecteur de média" + +msgid "Link to an entry" +msgstr "Lien vers un billet" + +msgid "Activate enhanced uploader" +msgstr "Activer l'interface avancée" + +msgid "Disable enhanced uploader" +msgstr "Désactiver l'interface avancée" + +msgid "File successfully uploaded." +msgstr "Fichier envoyé avec succès." + +msgid "Maximum file size allowed:" +msgstr "Taille maximale de fichier autorisée :" + +msgid "Limit exceeded." +msgstr "Limite dépassée." + +msgid "File size exceeds allowed limit." +msgstr "La taille du fichier dépasse la limite autorisée." + +msgid "Canceled." +msgstr "Annulé." + +msgid "HTTP Error:" +msgstr "Erreur HTTP :" + +msgid "Choose file" +msgstr "Choisir un fichier" + +msgid "Choose files" +msgstr "Choisir des fichiers" + +msgid "Clean" +msgstr "Nettoyer" + +msgid "Upload" +msgstr "Envoyer" + +msgid "No file in queue." +msgstr "Aucun fichier en file d'attente." + +msgid "1 file in queue." +msgstr "1 fichier en attente." + +#, php-format +msgid "%d files in queue." +msgstr "%d fichiers en attente." + +msgid "Queue error:" +msgstr "Erreur de file d'attente :" + +msgid "«prev." +msgstr "«préc." + +msgid "next»" +msgstr "suiv.»" + +msgid "No entry" +msgstr "Pas de billet" + +msgid "scheduled" +msgstr "programmé" + +msgid "protected" +msgstr "protégé" + +#, php-format +msgid "%d attachment" +msgstr "%d annexe" + +#, php-format +msgid "%d attachments" +msgstr "%d annexes" + +msgid "Type" +msgstr "Type" + +msgid "No user" +msgstr "Pas d'utilisateur" + +msgid "admin" +msgstr "Administrateur" + +msgid "superadmin" +msgstr "Super administrateur" + +msgid "Database error" +msgstr "Erreur de base de données :" + +msgid "There seems to be no Session table in your database. Is Dotclear completly installed?" +msgstr "Il semble de la table Session n'existe pas dans votre base de données. Dotclear est-il bien installé correctement?" + +msgid "System" +msgstr "Système" + +msgid "Blog" +msgstr "Blog" + +msgid "Updates" +msgstr "Mises à jour" + +msgid "Languages" +msgstr "Langues" + +msgid "administrator" +msgstr "administrateur" + +msgid "manage their own entries and comments" +msgstr "gérer ses propres billets et commentaires" + +msgid "publish entries and comments" +msgstr "publier des billets et des commentaires" + +msgid "delete entries and comments" +msgstr "supprimer des billets et des commentaires" + +msgid "manage all entries and comments" +msgstr "gérer tous les billets et commentaires" + +msgid "manage categories" +msgstr "gérer les catégories" + +msgid "manage their own media items" +msgstr "gérer ses propres médias" + +msgid "manage all media items" +msgstr "gérer tous les médias" + +msgid "That user does not exist in the database." +msgstr "Cet utilisateur n'existe pas dans la base de données." + +msgid "That key does not exist in the database." +msgstr "Cette clé n'existe pas dans la base de données." + +msgid "You are not allowed to add categories" +msgstr "Vous n'êtes pas autorisé à créer des catégories" + +msgid "You are not allowed to update categories" +msgstr "Vous n'êtes pas autorisé à modifier des catégories" + +msgid "You are not allowed to delete categories" +msgstr "Vous n'êtes pas autorisé à supprimer des catégories" + +msgid "This category is not empty." +msgstr "Cette catégorie n'est pas vide." + +msgid "You are not allowed to reset categories order" +msgstr "Vous n'êtes pas autorisé à modifier l'ordre des catégories" + +msgid "Category URL must be unique." +msgstr "L'URL de chaque catégorie doit être unique." + +msgid "You must provide a category title" +msgstr "Vous devez indiquer un titre de catégorie" + +msgid "You must provide a category URL" +msgstr "Vous devez indiquer une URL de catégorie" + +msgid "You are not allowed to create an entry" +msgstr "Vous n'êtes pas autorisé à créer des billets" + +msgid "You are not allowed to update entries" +msgstr "Vous n'êtes pas autorisé à modifier les billets" + +msgid "No such entry ID" +msgstr "Identifiant du billet inconnu" + +msgid "You are not allowed to edit this entry" +msgstr "Vous n'êtes pas autorisé à modifier ce billet" + +msgid "You are not allowed to change this entry status" +msgstr "Vous n'êtes pas autorisé à modifier l'état de ce billet" + +msgid "You are not allowed to change this entry category" +msgstr "Vous n'êtes pas autorisé à modifier la catégorie de ce billet" + +msgid "You are not allowed to mark this entry as selected" +msgstr "Vous n'êtes pas autorisé à marquer ce billet comme sélectionné" + +msgid "You are not allowed to delete entries" +msgstr "Vous n'êtes pas autorisé à supprimer des billets" + +msgid "You are not allowed to delete this entry" +msgstr "Vous n'êtes pas autorisé à supprimer ce billet" + +msgid "No entry title" +msgstr "Pas de titre de billet" + +msgid "No entry content" +msgstr "Pas de contenu de billet" + +msgid "Empty entry URL" +msgstr "URL du billet vide" + +msgid "You are not allowed to update comments" +msgstr "Vous n'êtes pas autorisé à modifier des commentaires" + +msgid "No such comment ID" +msgstr "Identifiant du commentaire inconnu" + +msgid "You are not allowed to update this comment" +msgstr "Vous n'êtes pas autorisé à modifier ce commentaire" + +msgid "You are not allowed to change this comment's status" +msgstr "Vous n'êtes pas autorisé à changer l'état de ce commentaire" + +msgid "You are not allowed to delete comments" +msgstr "Vous n'êtes pas autorisé à supprimer des commentaires" + +msgid "You are not allowed to delete this comment" +msgstr "Vous n'êtes pas autorisé à supprimer ce commentaire" + +msgid "You must provide a comment" +msgstr "Vous devez indiquer un commentaire" + +msgid "You must provide an author name" +msgstr "Vous devez indiquer un nom d'auteur" + +msgid "Email address is not valid." +msgstr "Adresse email invalide." + +msgid "online" +msgstr "en ligne" + +msgid "offline" +msgstr "hors ligne" + +msgid "removed" +msgstr "supprimé" + +msgid "You are not an administrator" +msgstr "Vous n'êtes pas administrateur" + +msgid "Invalid user language code" +msgstr "Code langue de l'utilisateur invalide" + +msgid "Blog ID must contain at least 2 characters using letters, numbers or symbols." +msgstr "L'identifiant du blog doit contenir au moins 2 caractères composés de lettres, chiffres ou symboles." + +msgid "No blog name" +msgstr "Pas de nom de blog" + +msgid "No blog URL" +msgstr "Pas d'URL de blog" + +msgid "No log message" +msgstr "Pas de message dans le journal" + +msgid "unknown" +msgstr "inconnu" + +msgid "No blog defined." +msgstr "Aucun blog défini." + +#, php-format +msgid "Directory %s does not exist." +msgstr "Le répertoire %s n'existe pas." + +msgid "You are not a super administrator." +msgstr "Vous n'êtes pas super administrateur." + +msgid "Permission denied." +msgstr "Permission refusée." + +msgid "You are not the file owner." +msgstr "Vous n'êtes pas le propriétaire de ce fichier." + +msgid "This file is not allowed." +msgstr "Ce fichier n'est pas autorisé." + +msgid "New file already exists." +msgstr "Le nouveau fichier existe déjà." + +msgid "File does not exist in the database." +msgstr "Ce fichier n'existe pas dans la base de données." + +#, php-format +msgid "Extract destination directory %s already exists." +msgstr "Le répertoire de destination d'extraction %s existe déjà." + +msgid "Embedded Audio Player" +msgstr "Fichier audio intégré" + +msgid "Embedded Video Player" +msgstr "Fichier vidéo intégré" + +#, php-format +msgid "%s: in [%s] and [%s]" +msgstr "%s: dans [%s] et [%s]" + +msgid "Empty module zip file." +msgstr "Fichier zip de module vide." + +msgid "The zip file does not appear to be a valid Dotclear module." +msgstr "Le fichier zip ne semble pas être un fichier valide de module Dotclear." + +msgid "An error occurred during module deletion." +msgstr "Une erreur est survenue durant la suppression du module." + +#, php-format +msgid "Unable to upgrade \"%s\". (same version)" +msgstr "Impossible de mettre à jour \"%s\" (même version)." + +msgid "Unable to read new _define.php file" +msgstr "Impossible de lire le nouveau fichier _define.php." + +msgid "No such module." +msgstr "Module inexistant." + +msgid "Cannot remove module files" +msgstr "Impossible de supprimer les fichiers du module" + +msgid "Cannot deactivate plugin." +msgstr "L'extension ne peut pas être désactivée." + +msgid "Cannot activate plugin." +msgstr "L'extension ne peut pas être activée." + +#, php-format +msgid "Invalid setting dcNamespace: %s" +msgstr "Espace de nommage du paramètre invalide : %s" + +msgid "Unable to retrieve settings:" +msgstr "Impossible d'obtenir les paramètres :" + +#, php-format +msgid "%s is not a valid setting id" +msgstr "%s n'est pas un identifiant de paramètre valide" + +msgid "No namespace specified" +msgstr "Aucun espace de nommage spécifié" + +msgid "Unable to retrieve workspaces:" +msgstr "Impossible d'obtenir les espaces de travail :" + +msgid "Unable to retrieve namespaces:" +msgstr "Impossible d'obtenir les espaces de nommage :" + +#, php-format +msgid "Invalid setting namespace: %s" +msgstr "Espace de nommage du paramètre invalide : %s" + +#, php-format +msgid "%s has still been pinged" +msgstr "Un rétrolien vers %s a déjà été fait" + +msgid "Unable to ping URL" +msgstr "Impossible de réaliser le rétrolien" + +#, php-format +msgid "%s is not a ping URL" +msgstr "%s n'est pas une URL de rétrolien" + +#, php-format +msgid "%s, ping error:" +msgstr "%s, erreur de rétrolien :" + +msgid "Digests file not found." +msgstr "Fichier de contrôle introuvable." + +msgid "No file to download" +msgstr "Aucun fichier à télécharger." + +msgid "Root directory is not writable." +msgstr "Le répertoire principal n'est pas accessible en écriture." + +msgid "An error occurred while downloading archive." +msgstr "Une erreur est survenue lors du téléchargement de l'archive." + +msgid "Archive not found." +msgstr "L'archive n'a pas été trouvée." + +msgid "Unable to read current digests file." +msgstr "Impossible de lire le fichier de contrôle actuel." + +msgid "Downloaded file does not seem to be a valid archive." +msgstr "Le fichier téléchargé ne semble pas être une archive valide." + +msgid "Incomplete archive." +msgstr "Archive incomplète." + +msgid "Unable to read digests file." +msgstr "Impossible de lire le fichier de contrôle." + +msgid "Invalid digests file." +msgstr "Fichier de contrôle invalide." + +#, php-format +msgid "Invalid dcWorkspace: %s" +msgstr "Espace de travail de la préférence invalide : %s" + +msgid "Unable to retrieve prefs:" +msgstr "Impossible d'obtenir les préférences :" + +#, php-format +msgid "%s is not a valid pref id" +msgstr "%s n'est pas un identifiant de préférence valide" + +msgid "No workspace specified" +msgstr "Aucun espace de travail spécifié" + +msgid "SQLite Database Schema cannot be upgraded." +msgstr "Le schema de base de données SQLite ne peut pas être mis à jour." + +msgid "Something went wrong with auto upgrade:" +msgstr "Une erreur est survenue durant la mise à jour automatique :" + +msgid "Unable to open directory." +msgstr "Impossible d'ouvrir le répertoire." + +msgid "Unable to create directory." +msgstr "Impossible de créer le répertoire." + +msgid "File is not writable." +msgstr "Le fichier n'est pas accessible en écriture." + +msgid "Unable to open file." +msgstr "Impossible d'ouvrir le fichier." + +# pas compris +msgid "Not an uploaded file." +msgstr "Pas un fichier déposé." + +msgid "The uploaded file exceeds the maximum file size allowed." +msgstr "Le fichier déposé est plus grand que la taille maximale autorisée." + +msgid "The uploaded file was only partially uploaded." +msgstr "Le fichier n'a été chargé qu'en partie." + +msgid "No file was uploaded." +msgstr "Aucun fichier chargé." + +msgid "Missing a temporary folder." +msgstr "Il manque un répertoire temporaire." + +msgid "Failed to write file to disk." +msgstr "Impossible d'écrire le fichier." + +#, php-format +msgid "%s is not a directory." +msgstr "%s n'est pas un répertoire." + +msgid "Bad range" +msgstr "Mauvaises limites" + +msgid "Invalid range" +msgstr "Sélection invalide" + +msgid "Invalid line number" +msgstr "Numéro de ligne invalide invalide" + +msgid "Chunk is out of range" +msgstr "L'extrait est hors limite" + +msgid "Bad context" +msgstr "Contexte invalide" + +msgid "Bad context (in deletion)" +msgstr "Contexte invalide (lors de la suppression)" + +msgid "Invalid diff format" +msgstr "Format de fichier diff invalide." + +msgid "Uploading this file is not allowed." +msgstr "L'envoi de ce fichier n'est pas autorisé." + +# "en jail" ? c'est du geek ? +msgid "Destination directory is not in jail." +msgstr "Le répertoire cible n'est pas en jail." + +msgid "File already exists." +msgstr "Le nouveau fichier existe déjà." + +msgid "Cannot write in this directory." +msgstr "Impossible d'écrire dans ce répertoire." + +msgid "An error occurred while writing the file." +msgstr "Une erreur est survenue pendant l'écriture du fichier." + +msgid "Source file does not exist." +msgstr "Le fichier source n'existe pas" + +# geek ? +msgid "File is not in jail." +msgstr "Le fichier n'est pas en jail." + +msgid "Destination directory is not writable." +msgstr "Le répertoire cible n'est pas accessible en écriture." + +msgid "Unable to rename file." +msgstr "Impossible de renommer le fichier." + +msgid "File cannot be removed." +msgstr "Ce fichier ne peut pas être supprimé." + +# décidément ! mais que veut dire "jail" ? +msgid "Directory is not in jail." +msgstr "Le répertoire n'est pas en jail." + +msgid "Directory cannot be removed." +msgstr "Ce répertoire ne peut pas être supprimé." + +msgid "Not enough memory to open image." +msgstr "Mémoire insuffisante pour ouvrir l'image." + +#, php-format +msgid "File %s is not compressed in the zip." +msgstr "Le fichier %s n'est pas compressé dans le zip." + +#, php-format +msgid "Trying to unzip a folder name %s" +msgstr "Tentative de décompresser un répertoire %s" + +msgid "Unable to write destination file." +msgstr "Impossible d'écrire le fichier de destination" + +msgid "Unable to write in target directory, permission denied." +msgstr "Impossible d'écrire dans le répertoire cible, permission refusée." + +msgid "Not enough memory to open file." +msgstr "Mémoire insuffisante pour ouvrir le fichier." + +msgid "File does not exist" +msgstr "Le fichier n'existe pas" + +msgid "Cannot read file" +msgstr "Impossible de lire le fichier" + +msgid "Directory does not exist" +msgstr "Le répertoire n'existe pas" + +msgid "Cannot read directory" +msgstr "Impossible de lire le répertoire" + +msgid "Unable to connect to database" +msgstr "Connexion à la base de données impossible" + +#, php-format +msgid "

        This either means that the username and password information in your config.php file is incorrect or we can't contact the database server at \"%s\". This could mean your host's database server is down.

        • Are you sure you have the correct username and password?
        • Are you sure that you have typed the correct hostname?
        • Are you sure that the database server is running?

        If you're unsure what these terms mean you should probably contact your host. If you still need help you can always visit the Dotclear Support Forums.

        " +msgstr "

        Cela signifie soit que les informations d'identifiant ou de mot de passe de votre fichier config.php sont incorrects, soit que nous ne pouvons pas contacter le serveur de base de données à l'adresse \"%s\". Cela peut vouloir dire que le serveur en question est éteint.

        • Êtes-vous sûr que l'identifiant et le mot de passe sont corrects ?
        • Êtes-vous sûr d'avoir entré le bon nom de serveur ?
        • Êtes-vous sûr que le serveur fonctionne ?

        S vous n'êtes pas sûr de la signification de ces termes, vous devriez probablement contacter votre hébergeur. Si vous avez besoin d'une aide supplémentaire, vous pouvez vous rendre sur le forum d'entraide Dotclear.

        " + +msgid "The following error was encountered while trying to read the database:" +msgstr "L'erreur suivante a été rencontrée lors de la tentative d'accès à la base de données :" + +#~ msgid "medium" +#~ msgstr "moyenne" + +#~ msgid "small" +#~ msgstr "petite" + +#~ msgid "thumbnail" +#~ msgstr "miniature" + +#~ msgid "square" +#~ msgstr "carrée" + +#~ msgid "Blog themes" +#~ msgstr "Thèmes du blog" + +#~ msgid "Pages" +#~ msgstr "Pages" + +#~ msgid "Blogroll" +#~ msgstr "Liens / Blogroll" + +#~ msgid "update thumbnails" +#~ msgstr "mettre à jour les miniatures" + +#~ msgid "insert" +#~ msgstr "insérer" + +#~ msgid "View entry" +#~ msgstr "Voir le billet" + +#~ msgid "Go to this page on the site" +#~ msgstr "Voir cette page sur le site" + +#~ msgid "Attachments" +#~ msgstr "Pièces jointes" + +#~ msgid "remove" +#~ msgstr "supprimer" + +#~ msgid "Remove" +#~ msgstr "Supprimer" + +#~ msgid "No attachment." +#~ msgstr "Aucune pièce jointe" + +#~ msgid "Add files to this entry" +#~ msgstr "Ajouter un fichier au billet" + +#~ msgid "User:" +#~ msgstr "Utilisateur :" + +#~ msgid "Logout" +#~ msgstr "Déconnexion" + +#~ msgid "login" +#~ msgstr "login" + +#~ msgid "filter" +#~ msgstr "filtre" + +#~ msgid "User preferences" +#~ msgstr "Préférences utilisateur" + +#~ msgid "Documentation" +#~ msgstr "Documentation" + +#~ msgid "View site" +#~ msgstr "Voir le site" + +#~ msgid "The file %s already exists. If you need to reset any of the configuration items in this file, please delete it first or you may continue to install." +#~ msgstr "Le fichier %s existe déjà. Pour réinitialiser votre configuration, supprimez d'abord ce fichier ou bien continuez l'installation." + +#~ msgid "Login:" +#~ msgstr "Login :" + +#~ msgid "Login and password" +#~ msgstr "Identifiant et mot de passe" + +#~ msgid "User ID" +#~ msgstr "Identifiant utilisateur" + +#~ msgid "Name" +#~ msgstr "Nom" + +#~ msgid "Add this page to my favorites" +#~ msgstr "Ajouter cette page à mes favoris" + +#~ msgid "Modify numbers in fields to change favorites order." +#~ msgstr "Modifiez les nombres dans les champs pour changer l'ordre des favoris." diff --git a/v2/dotclear/locales/fr/plugins.lang.php b/v2/dotclear/locales/fr/plugins.lang.php new file mode 100644 index 0000000..526dd3e --- /dev/null +++ b/v2/dotclear/locales/fr/plugins.lang.php @@ -0,0 +1,530 @@ +DC1 redirect plugin and activate it in your blog configuration.'] = 'Veuillez noter que Dotclear 2 a un nouveau format d\'URL. Vous pouvez éviter les liens morts en installant le plugin DC1 redirect et en l\'activant dans la configuration de votre blog.'; +$GLOBALS['__l10n']['next step'] = 'étape suivante'; +$GLOBALS['__l10n']['Dotclear tables not found'] = 'Tables Dotclear non trouvées'; +$GLOBALS['__l10n']['Feed import'] = 'Importer depuis un flux'; +$GLOBALS['__l10n']['Imports a feed as new entries.'] = 'Importe un flux comme nouveaux billets.'; +$GLOBALS['__l10n']['Cannot retrieve feed URL.'] = 'Impossible d\'atteindre l\'URL du fil.'; +$GLOBALS['__l10n']['No items in feed.'] = 'Aucun élément dans le feed.'; +$GLOBALS['__l10n']['Content successfully imported.'] = 'Contenu importé avec succès.'; +$GLOBALS['__l10n']['This will import a feed (RSS or Atom) a as new content in the current blog: %s.'] = 'Ceci va importer un fil (RSS ou Atom) comme un nouveau contenu dans le blog en cours : %s.'; +$GLOBALS['__l10n']['Feed URL:'] = 'URL du fil'; +$GLOBALS['__l10n']['Flat file import'] = 'Importer depuis un fichier texte'; +$GLOBALS['__l10n']['Imports a blog or a full Dotclear installation from flat file.'] = 'Importe un blog ou toutes les données depuis un fichier texte.'; +$GLOBALS['__l10n']['Single blog successfully imported.'] = 'Blog importé avec succès.'; +$GLOBALS['__l10n']['Are you sure you want to import a full backup file?'] = 'Êtes-vous certain de vouloir charger un fichier de sauvegarde complet ?'; +$GLOBALS['__l10n']['This will import a single blog backup as new content in the current blog: %s.'] = 'Ceci va charger une sauvegarde de blog comme un nouveau contenu dans le blog en cours : %s.'; +$GLOBALS['__l10n']['Upload a backup file'] = 'Charger un fichier de sauvegarde'; +$GLOBALS['__l10n']['or pick up a local file in your public directory'] = 'ou choisissez un fichier local dans votre répertoire public'; +$GLOBALS['__l10n']['This will reset all the content of your database, except users.'] = 'Ceci va remettre à zéro tout le contenu, sauf les utilisateurs.'; +$GLOBALS['__l10n']['Another file with same name exists.'] = 'Il existe déjà un fichier portant ce nom.'; +$GLOBALS['__l10n']['Failed to extract backup file.'] = 'Erreur à l\'extraction du fichier de sauvegarde.'; +$GLOBALS['__l10n']['No backup in compressed file.'] = 'Pas de sauvegarde dans le fichier compressé.'; +$GLOBALS['__l10n']['WordPress import'] = 'Importer depuis WordPress'; +$GLOBALS['__l10n']['Import a WordPress installation into your current blog.'] = 'Importe un blog WordPress dans votre blog en cours.'; +$GLOBALS['__l10n']['This will import your WordPress content as new content in the current blog: %s.'] = 'Ceci va importer votre blog WordPress comme un nouveau contenu dans le blog en cours : %s.'; +$GLOBALS['__l10n']['We first need some information about your old WordPress installation.'] = 'Nous avons d\'abord besoin de renseignements à propos de votre ancienne installation WordPress.'; +$GLOBALS['__l10n']['WordPress and Dotclear\'s handling of categories are quite different. You can assign several categories to a single post in WordPress. In the Dotclear world, we see it more like "One category, several tags." Therefore Dotclear can only import one category per post and will chose the lowest numbered one. If you want to keep a trace of every category, you can import them as tags, with an optional prefix.'] = 'WordPress et Dotclear gèrent les catégories différemment. Dans WordPress, un article peut être classé dans plusieurs catégories, alors que dans Dotclear, on voit ça plutôt comme "Une catégorie, plusieurs mots-clefs." Dotclear ne peut donc importer qu\'une seule catégorie par article et choisira dans ce cas la première créée. Si vous désirez garder une trace de chaque catégorie, vous pouvez les importer en tant que mots-clefs, avec un préfixe optionnel.'; +$GLOBALS['__l10n']['On the other hand, in WordPress, a post can not be uncategorized, and a default installation has a first category labelised "Uncategorized". If you did not change that category, you can just ignore it while importing your blog, as Dotclear allows you to actually keep your posts uncategorized.'] = 'Par contre, il est impossible dans WordPress de ne pas assigner une catégorie à un article, c\'est pourquoi lors de l\'installation est créée une première catégorie appelée "Non classée". Si vous n\'avez pas modifié cette catégorie, l\'importation peut simplement l\'ignorer. En effet, Dotclear vous permet d\'avoir des articles sans catégorie.'; +$GLOBALS['__l10n']['Ignore the first category:'] = 'Ignorer la première catégorie :'; +$GLOBALS['__l10n']['Import lowest numbered category on posts:'] = 'Importer la catégorie la plus ancienne sur les articles :'; +$GLOBALS['__l10n']['Import all categories as tags:'] = 'Importer les catégories comme des mots-clés :'; +$GLOBALS['__l10n']['Prefix such tags with:'] = 'Préfixer ces mots-clés avec :'; +$GLOBALS['__l10n']['Content filters'] = 'Filtres de contenu'; +$GLOBALS['__l10n']['You may want to process your post and/or comment content with the following filters.'] = 'Vous pouvez utiliser les filtres suivants sur vos articles et/ou commentaires.'; +$GLOBALS['__l10n']['Post content formatter:'] = 'Formatage des articles :'; +$GLOBALS['__l10n']['Comment content formatter:'] = 'Formatage des commentaires :'; +$GLOBALS['__l10n']['WordPress tables not found'] = 'Tables WordPress non trouvées'; +$GLOBALS['__l10n']['No file to read.'] = 'Aucun fichier lisible.'; +$GLOBALS['__l10n']['File is not a DotClear backup.'] = 'Le fichier n\'est pas une sauvegarde DotClear.'; +$GLOBALS['__l10n']['File is not a single blog export.'] = 'Le fichier n\'est pas un fichier d\'export simple.'; +$GLOBALS['__l10n']['File is not a full export.'] = 'Le fichier n\'est pas un fichier d\'export complet.'; +$GLOBALS['__l10n']['ID of "%3$s" does not match on record "%1$s" at line %2$s of backup file.'] = 'L\'ID de "%3$s" ne correspond pas sur l\'enregistrement "%1$s", ligne %2$s du fichier de sauvegarde.'; +$GLOBALS['__l10n']['Please wait...'] = 'Veuillez patienter...'; +$GLOBALS['__l10n']['Maintenance'] = 'Maintenance'; +$GLOBALS['__l10n']['Optimization successful.'] = 'Optimisation réalisée avec succès.'; +$GLOBALS['__l10n']['Comments and trackback counted.'] = 'Commentaires et rétroliens comptés.'; +$GLOBALS['__l10n']['Templates cache directory emptied.'] = 'Répertoire du cache des templates vidé.'; +$GLOBALS['__l10n']['Logs deleted.'] = 'Journaux effacés.'; +$GLOBALS['__l10n']['Indexing entry %d to %d.'] = 'Index des billets %d à %d'; +$GLOBALS['__l10n']['next'] = 'suivant'; +$GLOBALS['__l10n']['Entries index done.'] = 'Index des billets complet.'; +$GLOBALS['__l10n']['Back'] = 'Retour'; +$GLOBALS['__l10n']['Indexing comment %d to %d.'] = 'Index des commentaires %d à %d'; +$GLOBALS['__l10n']['Comments index done.'] = 'Index des commentaires complet.'; +$GLOBALS['__l10n']['Optimize database room'] = 'Optimiser l\'espace de la base de données'; +$GLOBALS['__l10n']['Vacuum tables'] = 'Nettoyer les tables'; +$GLOBALS['__l10n']['Counters'] = 'Compteurs'; +$GLOBALS['__l10n']['Reset comments and ping counters'] = 'Réinitialiser les compteurs des commentaires et rétroliens'; +$GLOBALS['__l10n']['Search engine index'] = 'Index du moteur de recherche'; +$GLOBALS['__l10n']['This may take a very long time'] = 'Ceci peut prendre beaucoup de temps'; +$GLOBALS['__l10n']['Index all posts'] = 'Indexer tous les billets'; +$GLOBALS['__l10n']['Index all comments'] = 'Indexer tous les commentaires'; +$GLOBALS['__l10n']['Vacuum logs'] = 'Vider les journaux'; +$GLOBALS['__l10n']['Delete all logs'] = 'Supprimer tous les journaux'; +$GLOBALS['__l10n']['Empty templates cache directory'] = 'Vider le répertoire du cache des templates'; +$GLOBALS['__l10n']['Empty directory'] = 'Vider le répertoire'; +$GLOBALS['__l10n']['Pages'] = 'Pages'; +$GLOBALS['__l10n']['%d page'] = '%d page'; +$GLOBALS['__l10n']['%d pages'] = '%d pages'; +$GLOBALS['__l10n']['manage pages'] = 'gérer les pages'; +$GLOBALS['__l10n']['Published on'] = 'Publié le'; +$GLOBALS['__l10n']['This page\'s comments feed'] = 'Fil des commentaires de cette page'; +$GLOBALS['__l10n']['You must provide a valid email address.'] = 'Vous devez indiquer une adresse email valide.'; +$GLOBALS['__l10n']['Page title'] = 'Titre de la page'; +$GLOBALS['__l10n']['Page position'] = 'Position de la page'; +$GLOBALS['__l10n']['Publication date'] = 'Date de publication'; +$GLOBALS['__l10n']['No page'] = 'Aucune page'; +$GLOBALS['__l10n']['select this page'] = 'sélectionner cette page'; +$GLOBALS['__l10n']['Are you sure you want to delete selected pages?'] = 'Êtes-vous certain de vouloir supprimer les pages sélectionnées ?'; +$GLOBALS['__l10n']['New page'] = 'Nouvelle page'; +$GLOBALS['__l10n']['Selected pages action:'] = 'Action sur les pages sélectionnées :'; +$GLOBALS['__l10n']['This page does not exist.'] = 'Cette page n\'existe pas.'; +$GLOBALS['__l10n']['Edit page'] = 'Modifier la page'; +$GLOBALS['__l10n']['next page'] = 'page suivante'; +$GLOBALS['__l10n']['previous page'] = 'page précédente'; +$GLOBALS['__l10n']['Are you sure you want to delete this page?'] = 'Êtes-vous certain de vouloir supprimer cette page ?'; +$GLOBALS['__l10n']['Page has been successfully updated.'] = 'La page a été mise à jour avec succès.'; +$GLOBALS['__l10n']['Page has been successfully created.'] = 'La page a été créée avec succès.'; +$GLOBALS['__l10n']['Go to this page on the site'] = 'Aller sur cette page'; +$GLOBALS['__l10n']['Page status:'] = 'État de la page :'; +$GLOBALS['__l10n']['Page position:'] = 'Position de la page :'; +$GLOBALS['__l10n']['Page lang:'] = 'Langue de la page :'; +$GLOBALS['__l10n']['Page password:'] = 'Mot de passe de la page :'; +$GLOBALS['__l10n']['Warning: If you set the URL manually, it may conflict with another page.'] = 'Attention : si vous indiquez l\'URL manuellement, celle-ci peut entrer en conflit avec une autre page.'; +$GLOBALS['__l10n']['Add files to this page'] = 'Ajouter un fichier à la page'; +$GLOBALS['__l10n']['Pings'] = 'Pings'; +$GLOBALS['__l10n']['Pings configuration'] = 'Configuration des pings'; +$GLOBALS['__l10n']['Settings have been successfully updated.'] = 'Paramètres enregistrés avec succès.'; +$GLOBALS['__l10n']['Activate pings extension'] = 'Activer le module de ping'; +$GLOBALS['__l10n']['Service name:'] = 'Nom du service :'; +$GLOBALS['__l10n']['Service URI:'] = 'URI du service :'; +$GLOBALS['__l10n']['error'] = 'erreur'; +$GLOBALS['__l10n']['Test ping services'] = 'Tester les services de ping'; +$GLOBALS['__l10n']['Check all'] = 'Tout cocher.'; +$GLOBALS['__l10n']['Pings:'] = 'Pings :'; +$GLOBALS['__l10n']['Simple menu'] = 'Menu simple'; +$GLOBALS['__l10n']['Menu'] = 'Menu'; +$GLOBALS['__l10n']['All months'] = 'Tous les mois'; +$GLOBALS['__l10n']['All tags'] = 'Tous les mots-clés'; +$GLOBALS['__l10n']['Home'] = 'Accueil'; +$GLOBALS['__l10n']['Archive'] = 'Archive'; +$GLOBALS['__l10n']['Page'] = 'Page'; +$GLOBALS['__l10n']['Tags'] = 'Mots-clés'; +$GLOBALS['__l10n']['User defined'] = 'Saisie libre'; +$GLOBALS['__l10n']['Label'] = 'Libellé'; +$GLOBALS['__l10n']['Recent posts'] = 'Billets récents'; +$GLOBALS['__l10n']['Switch to %s language'] = 'Basculer vers le %s'; +$GLOBALS['__l10n']['Recent Posts from this category'] = 'Billets récents de cette catégorie'; +$GLOBALS['__l10n']['Archives'] = 'Archives'; +$GLOBALS['__l10n']['Posts from %s'] = 'Billets de %s'; +$GLOBALS['__l10n']['Recent posts for %s tag'] = 'Billets récent pour le mot-clé %s'; +$GLOBALS['__l10n']['Label and URL of menu item are mandatory.'] = 'Les libellés et URL sont obligatoires.'; +$GLOBALS['__l10n']['No menu items selected.'] = 'Aucun item de menu sélectionné.'; +$GLOBALS['__l10n']['Label is mandatory.'] = 'Le libellé est obligatoire.'; +$GLOBALS['__l10n']['URL is mandatory.'] = 'l’URL est obligatoire.'; +$GLOBALS['__l10n']['Menu item has been successfully added.'] = 'L\'item de menu a été ajouté avec succès.'; +$GLOBALS['__l10n']['Menu items have been successfully removed.'] = 'Le ou les items de menu ont été supprimés avec succès.'; +$GLOBALS['__l10n']['Menu items have been successfully updated.'] = 'Le ou les items de menu ont été mis à jour avec succès.'; +$GLOBALS['__l10n']['Add item'] = 'Ajouter un item de menu'; +$GLOBALS['__l10n']['Select type'] = 'Sélection du type'; +$GLOBALS['__l10n']['Type of item menu:'] = 'Type d\'item de menu :'; +$GLOBALS['__l10n']['Continue...'] = 'Continuer…'; +$GLOBALS['__l10n']['Select language:'] = 'Sélectionnez la langue :'; +$GLOBALS['__l10n']['Select category:'] = 'Sélectionnez la catégorie :'; +$GLOBALS['__l10n']['Select month (if necessary):'] = 'Sélectionnez le mois (si nécessaire) :'; +$GLOBALS['__l10n']['Select page:'] = 'Sélectionnez la page :'; +$GLOBALS['__l10n']['Select tag (if necessary):'] = 'Sélectionnez le mot clé (si nécessaire) :'; +$GLOBALS['__l10n']['Label of item menu:'] = 'Libellé de l\'item de menu :'; +$GLOBALS['__l10n']['Description of item menu:'] = 'Description de l\'item de menu :'; +$GLOBALS['__l10n']['URL of item menu:'] = 'URL de l\'item de menu :'; +$GLOBALS['__l10n']['Add this item'] = 'Ajouter cet item'; +$GLOBALS['__l10n']['Add an item'] = 'Ajouter un item de menu'; +$GLOBALS['__l10n']['Menu items list'] = 'Liste des items de menu'; +$GLOBALS['__l10n']['Update menu'] = 'Mettre à jour le menu'; +$GLOBALS['__l10n']['Delete selected menu items'] = 'Supprimer les items de menu sélectionnés'; +$GLOBALS['__l10n']['Are you sure you want to remove selected menu items?'] = 'Êtes-vous sûr de vouloir supprimer les items de menu sélectionnés ?'; +$GLOBALS['__l10n']['Currently no menu items'] = 'Aucun item de menu pour l\'instant'; +$GLOBALS['__l10n']['Tags:'] = 'Mots-clés :'; +$GLOBALS['__l10n']['Are you sure you want to remove this %s?'] = 'Êtes vous certain de vouloir supprimer ce %s ?'; +$GLOBALS['__l10n']['Add a %s to this entry'] = 'Ajouter un %s à ce billet'; +$GLOBALS['__l10n']['Choose from list'] = 'Choisir depuis la liste'; +$GLOBALS['__l10n']['all'] = 'tous'; +$GLOBALS['__l10n']['Tag'] = 'Mot-clé'; +$GLOBALS['__l10n']['used in %e - frequency %p%'] = 'utilisé dans %e - fréquence %p%'; +$GLOBALS['__l10n']['entry'] = 'billet'; +$GLOBALS['__l10n']['entries'] = 'billets'; +$GLOBALS['__l10n']['Enter tags separated by coma'] = 'Entrer les mots-clés séparés par une virgule'; +$GLOBALS['__l10n']['Add tags'] = 'Ajouter des mots-clés'; +$GLOBALS['__l10n']['Remove tags'] = 'Supprimer des mots-clés'; +$GLOBALS['__l10n']['Add tags to entries'] = 'Ajouter des mots-clés aux billets'; +$GLOBALS['__l10n']['Tags to add:'] = 'Mots-clés à ajouter :'; +$GLOBALS['__l10n']['Remove selected tags from entries'] = 'Supprimer les mots-clés sélectionnés des billets'; +$GLOBALS['__l10n']['No tags for selected entries'] = 'Aucun mot-clé pour les billets sélectionnés'; +$GLOBALS['__l10n']['Following tags have been found in selected entries:'] = 'Les mots-clés suivants ont été trouvés dans les billets sélectionnés :'; +$GLOBALS['__l10n']['short'] = 'court'; +$GLOBALS['__l10n']['extended'] = 'étendu'; +$GLOBALS['__l10n']['Tags list format:'] = 'Format de la liste des mots-clés :'; +$GLOBALS['__l10n']['This tag\'s comments Atom feed'] = 'Fil Atom des commentaires de ce mot-clé'; +$GLOBALS['__l10n']['This tag\'s entries Atom feed'] = 'Fil Atom des billets de ce mot-clé'; +$GLOBALS['__l10n']['Limit (empty means no limit):'] = 'Limite (laisser vide pour aucune limite)'; +$GLOBALS['__l10n']['Entries count'] = 'Nombre de billets'; +$GLOBALS['__l10n']['Tag name'] = 'Nom du mot-clé'; +$GLOBALS['__l10n']['Link to all tags:'] = 'Lien vers tous les mots-clés :'; +$GLOBALS['__l10n']['Edit tag'] = 'Modifier le mot-clé'; +$GLOBALS['__l10n']['Tag has been successfully renamed'] = 'Mot-clé renommé avec succès'; +$GLOBALS['__l10n']['Back to tags list'] = 'Retour à la liste des mots-clés'; +$GLOBALS['__l10n']['Actions for this tag'] = 'Actions pour ce mot-clé'; +$GLOBALS['__l10n']['Edit tag name:'] = 'Renommer ce mot-clé :'; +$GLOBALS['__l10n']['Rename'] = 'Renommer'; +$GLOBALS['__l10n']['Delete this tag:'] = 'Supprimer ce mot-clé :'; +$GLOBALS['__l10n']['List of entries with this tag'] = 'Liste des billets avec ce mot-clé'; +$GLOBALS['__l10n']['Tag has been successfully removed'] = 'Mot-clé supprimé avec succès'; +$GLOBALS['__l10n']['No tags on this blog.'] = 'Aucun mot-clé sur ce blog'; +$GLOBALS['__l10n']['Theme Editor'] = 'Éditeur de thème'; +$GLOBALS['__l10n']['No file'] = 'Aucun fichier'; +$GLOBALS['__l10n']['File does not exist.'] = 'Le fichier n\'existe pas.'; +$GLOBALS['__l10n']['File %s is not readable'] = 'Le fichier %s n\'est pas lisible'; +$GLOBALS['__l10n']['Unable to write file %s. Please check your theme files and folders permissions.'] = 'Impossible d\'écrire le fichier %s. Veuillez vérifier les permissions des fichiers et répertoires de votre thème.'; +$GLOBALS['__l10n']['Saving document...'] = 'Sauvegarde du document...'; +$GLOBALS['__l10n']['Document saved'] = 'Document sauvegardé'; +$GLOBALS['__l10n']['An error occurred:'] = 'Une erreur s\'est produite :'; +$GLOBALS['__l10n']['Your current theme on this blog is "%s".'] = 'Le thème utilisé actuellement sur votre blog est "%s".'; +$GLOBALS['__l10n']['You can\'t edit default theme.'] = 'Vous ne pouvez pas modifier le thème par défaut.'; +$GLOBALS['__l10n']['Please select a file to edit.'] = 'Veuillez sélectionner un fichier à modifier.'; +$GLOBALS['__l10n']['File editor'] = 'Éditeur de fichier'; +$GLOBALS['__l10n']['Editing file %s'] = 'Modification du fichier %s'; +$GLOBALS['__l10n']['This file is not writable. Please check your theme files permissions.'] = 'Ce fichier ne peut pas être modifié. Veuillez vérifier les permissions des fichiers de votre thème.'; +$GLOBALS['__l10n']['Templates files'] = 'Fichiers template'; +$GLOBALS['__l10n']['CSS files'] = 'Fichiers CSS'; +$GLOBALS['__l10n']['JavaScript files'] = 'Fichiers JavaScript'; +$GLOBALS['__l10n']['Preferences successfully updated'] = 'Préférences mises à jour avec succès'; +$GLOBALS['__l10n']['Preferences definition successfully updated'] = 'Définition des préférences mise à jour avec succès'; +$GLOBALS['__l10n']['user preferences'] = 'préférences utilisateur'; +$GLOBALS['__l10n']['global preferences'] = 'préférences globales'; +$GLOBALS['__l10n']['Presentation widgets'] = 'Widgets de présentation'; +$GLOBALS['__l10n']['Search engine'] = 'Moteur de recherche'; +$GLOBALS['__l10n']['Navigation links'] = 'Liens de navigation'; +$GLOBALS['__l10n']['Selected entries'] = 'Billets sélectionnés'; +$GLOBALS['__l10n']['Best of me'] = 'À retenir'; +$GLOBALS['__l10n']['Blog languages'] = 'Langues du blog'; +$GLOBALS['__l10n']['With entries counts'] = 'Afficher le nombre de billets'; +$GLOBALS['__l10n']['Subscribe links'] = 'Liens d\'abonnement'; +$GLOBALS['__l10n']['Subscribe'] = 'S\'abonner'; +$GLOBALS['__l10n']['Feeds type:'] = 'Types de fil :'; +$GLOBALS['__l10n']['Feed reader'] = 'Lecteur de fils de nouvelles'; +$GLOBALS['__l10n']['Somewhere else'] = 'Ailleurs'; +$GLOBALS['__l10n']['Entries limit:'] = 'Nombre de billets maximum :'; +$GLOBALS['__l10n']['Text'] = 'Texte'; +$GLOBALS['__l10n']['Text:'] = 'Texte :'; +$GLOBALS['__l10n']['Last entries'] = 'Derniers billets'; +$GLOBALS['__l10n']['Uncategorized'] = 'Non catégorisé'; +$GLOBALS['__l10n']['Tag:'] = 'Mot-clé :'; +$GLOBALS['__l10n']['Last comments'] = 'Derniers commentaires'; +$GLOBALS['__l10n']['Comments limit:'] = 'Nombre de commentaires maximum :'; +$GLOBALS['__l10n']['This blog\'s entries %s feed'] = 'Fil %s des billets de ce blog'; +$GLOBALS['__l10n']['This blog\'s comments %s feed'] = 'Fil %s des commentaires de ce blog'; +$GLOBALS['__l10n']['Entries feed'] = 'Fil des billets'; +$GLOBALS['__l10n']['Comments feed'] = 'Fil des commentaires'; +$GLOBALS['__l10n']['navigation'] = 'navigation'; +$GLOBALS['__l10n']['extra'] = 'extra'; +$GLOBALS['__l10n']['custom'] = 'supplémentaire'; +$GLOBALS['__l10n']['Widgets'] = 'Widgets'; +$GLOBALS['__l10n']['Are you sure you want to reset sidebars?'] = 'Êtes-vous certain de vouloir réinitialiser les bandeaux ?'; +$GLOBALS['__l10n']['Available widgets'] = 'Widgets disponibles'; +$GLOBALS['__l10n']['Append to:'] = 'Ajouter à :'; +$GLOBALS['__l10n']['Add widgets to sidebars'] = 'Ajouter les widgets aux bandeaux'; +$GLOBALS['__l10n']['Navigation sidebar'] = 'Bandeau de navigation'; +$GLOBALS['__l10n']['Extra sidebar'] = 'Bandeau d\'extra'; +$GLOBALS['__l10n']['Custom sidebar'] = 'Bandeau supplémentaire'; +$GLOBALS['__l10n']['Update sidebars'] = 'Mettre à jour les bandeaux'; +$GLOBALS['__l10n']['Reset sidebars'] = 'Réinitialiser les bandeaux'; +$GLOBALS['__l10n']['Use of widgets'] = 'Utilisation des widgets'; +$GLOBALS['__l10n']['Widgets may be used to add various blocks of content to be displayed on your public pages. To add a widget, drag it from the Available widgets list on the left to one of the sidebars on the right of this page. You can order your widgets in a sidebar by dragging them up or down. You must update sidebars to apply your changes.'] = 'Les widgets sont utilisés pour ajouter des blocs de contenus divers dans vos pages publiques. Pour ajouter un widget, faites-le glisser depuis la liste des Widgets disponibles à gauche jusqu\'à l\'un des bandeaux sur la droite de la page. Vous pouvez ré-ordonner vos widgets dans un bandeau en le faisant glisser vers le haut ou vers le bas. Vous devez mettre à jour les bandeaux pour enregistrer vos modifications.'; +$GLOBALS['__l10n']['Once included in a sidebar, widgets have configuration options that you can reach by clicking on the + sign next to their name.'] = 'Une fois inclus dans un bandeau, les widgets ont généralement des options que vous pouvez configurer. Cliquez sur le signe + à côté de leur nom pour y accéder.'; +$GLOBALS['__l10n']['Reset sidebars to get back to default widgets installation.'] = 'Réinitialisez les bandeaux pour retrouver les widgets par défaut de votre installation.'; +$GLOBALS['__l10n']['Widget templates tags'] = 'Marqueurs de template des widgets'; +$GLOBALS['__l10n']['If you are allowed to edit your theme templates, you can directly add widgets as templates tags, with their own configuration.'] = 'Si vous avez le droit de modifier les templates de votre thème, vous pouvez directement ajouter des widgets à l\'aide de marqueurs de template, avec leur propre configuration.'; +$GLOBALS['__l10n']['To add a widget in your template, you need to write code like this:'] = 'Pour ajouter un widget dans votre template, vous devez écrire un code comme ceci :'; +$GLOBALS['__l10n']['Widget ID'] = 'Identifiant du widget'; +$GLOBALS['__l10n']['Setting name'] = 'Nom du paramètre'; +$GLOBALS['__l10n']['Setting value'] = 'Valeur du paramètre'; +$GLOBALS['__l10n']['Here are the following available widgets for your blog:'] = 'Voici les widgets disponibles pour votre blog :'; +$GLOBALS['__l10n']['Widget ID:'] = 'Identifiant du widget :'; +$GLOBALS['__l10n']['No setting for this widget'] = 'Aucun paramètre pour ce widget'; +$GLOBALS['__l10n']['Setting name:'] = 'Nom du paramètre :'; +$GLOBALS['__l10n']['No widget.'] = 'Aucun widget.'; +$GLOBALS['__l10n']['order'] = 'ordre'; +$GLOBALS['__l10n']['Remove widget'] = 'Supprimer le widget'; +?> \ No newline at end of file diff --git a/v2/dotclear/locales/fr/plugins.po b/v2/dotclear/locales/fr/plugins.po new file mode 100644 index 0000000..586b32e --- /dev/null +++ b/v2/dotclear/locales/fr/plugins.po @@ -0,0 +1,1769 @@ +# French translation of DotClear +# Copyright (C) 2006. +# Olivier Meunier , 2006. +msgid "" +msgstr "" +"Project-Id-Version: Dotclear 2\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-08-13 10:46+0200\n" +"PO-Revision-Date: \n" +"Last-Translator: xave \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: fr\n" + +msgid "no" +msgstr "non" + +msgid "yes" +msgstr "oui" + +msgid "Configuration successfully updated" +msgstr "Configuration mise à jour avec succès" + +msgid "Settings definition successfully updated" +msgstr "Définition des paramètres mise à jour avec succès" + +msgid "blog settings" +msgstr "paramètres du blog" + +msgid "Value" +msgstr "Valeur" + +msgid "Description" +msgstr "Description" + +msgid "Goto:" +msgstr "Aller à :" + +msgid "Ok" +msgstr "Valider" + +msgid "global settings" +msgstr "paramètres globaux" + +msgid "Akismet spam filter" +msgstr "Filtre de spam Akismet" + +#, php-format +msgid "Filtered by %s." +msgstr "Filtré par %s" + +msgid "Akismet API key:" +msgstr "Clé de l'interface Akismet :" + +msgid "API key verified" +msgstr "Clé vérifiée" + +msgid "API key not verified" +msgstr "Clé non vérifiée" + +msgid "Get your own API key" +msgstr "Obtenez votre clé Akismet" + +msgid "Antispam" +msgstr "Antispam" + +msgid "Delete junk comments older than" +msgstr "Supprimer les commentaires indésirables après" + +msgid "days" +msgstr "jours" + +msgid "IP Blacklist / Whitelist Filter" +msgstr "Liste noire / Liste blanche IP" + +#, php-format +msgid "Filtered by %1$s with rule %2$s." +msgstr "Filtré par %1$s avec la règle %2$s." + +msgid "IP address has been successfully added." +msgstr "L'adresse IP a été ajoutée avec succès." + +msgid "IP addresses have been successfully removed." +msgstr "L'adresse IP a été supprimée avec succès." + +msgid "Blacklist" +msgstr "Liste noire" + +msgid "Whitelist" +msgstr "Liste blanche" + +msgid "Add an IP address: " +msgstr "Ajouter une adresse IP" + +msgid "Global IP" +msgstr "IP globale" + +msgid "Add" +msgstr "Ajouter" + +msgid "No IP address in list." +msgstr "Aucune adresse IP dans la liste." + +msgid "IP list" +msgstr "Liste d'IP" + +msgid "Checks sender IP address against DNSBL servers" +msgstr "Vérifie l'adresse IP de l'auteur sur des serveurs DNSBL" + +#, php-format +msgid "Filtered by %1$s with server %2$s." +msgstr "Filtré par %1$s avec le serveur %2$s." + +msgid "IP Lookup servers" +msgstr "Serveurs de résolution d'IP" + +msgid "Add here a coma separated list of servers." +msgstr "Ajoutez ici une liste de serveurs, séparés par des virgules." + +msgid "Checks links in comments against surbl.org" +msgstr "Vérifie les liens dans les commentaires sur surbl.org" + +msgid "Words Blacklist" +msgstr "Liste de termes interdits" + +#, php-format +msgid "Filtered by %1$s with word %2$s." +msgstr "Filtré par %1$s avec le terme %2$s." + +msgid "Words have been successfully added." +msgstr "Les mots ont été ajouté avec succès." + +msgid "Word has been successfully added." +msgstr "Le mot a été ajouté avec succès." + +msgid "Words have been successfully removed." +msgstr "Les mots ont été supprimés avec succès." + +msgid "Add a word " +msgstr "Ajouter un mot" + +msgid "Global word" +msgstr "Mot global" + +msgid "No word in list." +msgstr "Aucun mot dans la liste." + +msgid "List of bad words" +msgstr "Liste de mots interdits" + +msgid "Delete selected words" +msgstr "Supprimer les mots sélectionnés" + +msgid "Create default wordlist" +msgstr "Créer une liste par défaut" + +msgid "This word exists" +msgstr "Ce mot existe" + +msgid "No description" +msgstr "Aucune description" + +#, php-format +msgid "Filtered by %1$s (%2$s)" +msgstr "Filtré par %1$s (%2$s)" + +msgid "Unknown filter." +msgstr "Filtre inconnu" + +msgid "This comment is a spam:" +msgstr "Ce commentaire est un indésirable :" + +#, php-format +msgid "(including %d spam comment)" +msgstr "(dont %d commentaire indésirable)" + +#, php-format +msgid "(including %d spam comments)" +msgstr "(dont %d commentaires indésirables)" + +msgid "Spam moderation" +msgstr "Modération des indésirables" + +msgid "Spam" +msgstr "Spam" + +msgid "Ham" +msgstr "Non spam" + +msgid "Filter does not exist." +msgstr "Le filtre n'existe pas." + +msgid "Filter has no user interface." +msgstr "Le filtre n'a pas d'interface utilisateur." + +#, php-format +msgid "%s configuration" +msgstr "%s configuration" + +msgid "Information" +msgstr "Informations" + +msgid "Spam comments have been successfully deleted." +msgstr "Les commentaires indésirables ont été supprimés avec succès." + +msgid "Junk comments:" +msgstr "Commentaires indésirables :" + +msgid "Published comments:" +msgstr "Commentaires publiés :" + +msgid "Delete all spams" +msgstr "Supprimer tous les indésirables" + +#, php-format +msgid "All spam comments older than %s day(s) will be automatically deleted." +msgstr "" +"Tous les indésirables de plus de %s jour(s) seront automatiquement supprimés." + +msgid "You can modify this duration in " +msgstr "Vous pouvez modifier cet intervalle dans" + +msgid "Blog preferences" +msgstr "Préférences du blog" + +msgid "Filters configuration has been successfully saved." +msgstr "La configuration des filtres a été enregistrée avec succès." + +msgid "Available spam filters" +msgstr "Filtres disponibles" + +msgid "Order" +msgstr "Ordre" + +msgid "Active" +msgstr "Actif" + +msgid "Auto Del." +msgstr "Suppr. Auto" + +msgid "Filter name" +msgstr "Nom du filtre" + +msgid "Filter configuration" +msgstr "Configuration du filtre" + +msgid "position" +msgstr "position" + +msgid "Syndication" +msgstr "Syndication" + +msgid "Junk comments RSS feed" +msgstr "Fil RSS des commentaires indésirables" + +msgid "Published comments RSS feed" +msgstr "Fil RSS des commentaires publiés" + +msgid "Attachments" +msgstr "Fichiers attachés" + +msgid "remove" +msgstr "supprimer" + +msgid "No attachment." +msgstr "Pas de fichier attaché" + +msgid "Add files to this entry" +msgstr "Ajouter des fichiers à la page" + +msgid "Blogroll" +msgstr "Liens / Blogroll" + +msgid "manage blogroll" +msgstr "gérer la liste de liens" + +msgid "Links" +msgstr "Liens" + +msgid "All categories" +msgstr "Toutes les catégories" + +msgid "Home page only" +msgstr "Page d'accueil uniquement" + +msgid "You must provide a link title" +msgstr "Vous devez indiquer un titre de lien" + +msgid "You must provide a link URL" +msgstr "Vous devez indiquer une URL" + +msgid "You need to provide a XBEL or OPML file." +msgstr "Vous devez fournir un fichier XBEL ou OPML." + +msgid "File is not in XML format." +msgstr "Le fichier n'est pas au format XML." + +msgid "No such link or title" +msgstr "Lien ou catégorie inexistant" + +msgid "Return to blogroll" +msgstr "Retour à la liste des liens" + +msgid "Category has been successfully updated" +msgstr "Catégorie mise à jour avec succès" + +msgid "Edit category" +msgstr "Modifier une catégorie" + +msgid "Link has been successfully updated" +msgstr "Lien mis à jour avec succès" + +msgid "Edit link" +msgstr "Modifier le lien" + +msgid "XFN" +msgstr "XFN" + +msgid "_xfn_Me" +msgstr "Moi" + +msgid "_xfn_Another link for myself" +msgstr "Autre lien m'appartenant" + +msgid "_xfn_Friendship" +msgstr "Amitié" + +msgid "_xfn_Contact" +msgstr "Contact" + +msgid "_xfn_Acquaintance" +msgstr "Connaissance" + +msgid "_xfn_Friend" +msgstr "Ami(e)" + +msgid "_xfn_Physical" +msgstr "Physique" + +msgid "_xfn_Met" +msgstr "Rencontré(e)" + +msgid "_xfn_Professional" +msgstr "Professionnel" + +msgid "_xfn_Co-worker" +msgstr "Camarade de travail" + +msgid "_xfn_Colleague" +msgstr "Collègue" + +msgid "_xfn_Geographical" +msgstr "Géographique" + +msgid "_xfn_Co-resident" +msgstr "Colocataire" + +msgid "_xfn_Neighbor" +msgstr "Voisin(e)" + +msgid "_xfn_Family" +msgstr "Famille" + +msgid "_xfn_Child" +msgstr "Enfant" + +msgid "_xfn_Parent" +msgstr "Parent" + +msgid "_xfn_Sibling" +msgstr "Frère/Soeur" + +msgid "_xfn_Spouse" +msgstr "Époux/Épouse" + +msgid "_xfn_Kin" +msgstr "Famille" + +msgid "_xfn_Romantic" +msgstr "Romantique" + +msgid "_xfn_Muse" +msgstr "Muse" + +msgid "_xfn_Crush" +msgstr "Bluette" + +msgid "_xfn_Date" +msgstr "Petit(e) ami(e)" + +msgid "_xfn_Sweetheart" +msgstr "Ami(e)" + +msgid "Nothing to import" +msgstr "Rien à importer" + +msgid "Import operation cancelled." +msgstr "Importation annulée." + +msgid "Items order has been successfully updated" +msgstr "L'ordre des éléments a été mis à jour avec succès" + +msgid "Items have been successfully removed." +msgstr "Éléments supprimés avec succès." + +msgid "Link has been successfully created." +msgstr "Lien créé avec succès." + +msgid "category has been successfully created." +msgstr "Catégorie mise à jour avec succès." + +msgid "links have been successfully imported." +msgstr "Liens importés avec succès." + +msgid "URL" +msgstr "URL" + +msgid "Lang" +msgstr "Langue" + +msgid "select this link" +msgstr "sélectionner ce lien" + +msgid "Delete selected links" +msgstr "Supprimer les liens sélectionnés" + +msgid "Are you sure you want to delete selected links?" +msgstr "Êtes-vous certain de vouloir supprimer les liens sélectionnés ?" + +msgid "The link list is empty." +msgstr "La liste des liens est vide." + +msgid "Add a new link" +msgstr "Ajouter un nouveau lien" + +msgid "Add a category" +msgstr "Ajouter une catégorie" + +msgid "Import links" +msgstr "Importer des liens" + +msgid "OPML or XBEL File:" +msgstr "Fichier OPML ou XBEL :" + +msgid "Import" +msgstr "Importer" + +msgid "Light linear gradient" +msgstr "Dégradé linéaire clair" + +msgid "Medium linear gradient" +msgstr "Dégradé linéaire moyen" + +msgid "Dark linear gradient" +msgstr "Dégradé linéaire foncé" + +msgid "Solid color" +msgstr "Couleur unie" + +msgid "Custom..." +msgstr "Personnalisé..." + +msgid "Blowup configuration" +msgstr "Configuration Blowup" + +msgid "Predefined styles" +msgstr "Styles prédéfinis" + +msgid "Apply code" +msgstr "Appliquer le code" + +msgid "Choose a predefined style" +msgstr "Sélectionnez un style prédéfini" + +msgid "" +"For the following reasons, images cannot be created. You won't be able to " +"change some background properties." +msgstr "" +"Pour les raisons qui suivent, les images ne pouvant être créées, vous ne " +"pourrez pas changer certaines propriétés." + +msgid "Theme configuration has been successfully updated." +msgstr "La configuration du thème a été mise à jour avec succès." + +msgid "General" +msgstr "Général" + +msgid "Background color:" +msgstr "Couleur de fond :" + +msgid "Background color fill:" +msgstr "Remplissage de la couleur de fond :" + +msgid "Main text font:" +msgstr "Police du texte principal :" + +msgid "Main text font size:" +msgstr "Taille du texte principal :" + +msgid "Main text color:" +msgstr "Couleur du texte principal :" + +msgid "Text line height:" +msgstr "Hauteur des lignes :" + +msgid "Links color:" +msgstr "Couleur des liens :" + +msgid "Visited links color:" +msgstr "Couleurs des liens visités :" + +msgid "Focus links color:" +msgstr "Couleur des liens survolés :" + +msgid "Page top" +msgstr "Haut de page" + +msgid "Prelude color:" +msgstr "Couleur du prélude :" + +msgid "Hide main title" +msgstr "Cacher le titre principal" + +msgid "Main title font:" +msgstr "Police du titre principal :" + +msgid "Main title font size:" +msgstr "Taille du titre principal :" + +msgid "Main title color:" +msgstr "Couleur du titre principal :" + +msgid "Main title alignment:" +msgstr "Alignement du titre principal :" + +msgid "center" +msgstr "centre" + +msgid "left" +msgstr "gauche" + +msgid "right" +msgstr "droite" + +msgid "Main title position (x:y)" +msgstr "Position du titre principal (x:y)" + +msgid "Top image" +msgstr "Image d'en-tête" + +msgid "Choose \"Custom...\" to upload your own image." +msgstr "Choisissez \"Personnalisé...\" pour déposer votre propre image." + +msgid "Add your image:" +msgstr "Ajouter votre image :" + +#, php-format +msgid "JPEG or PNG file, 800 pixels wide, maximum size %s" +msgstr "Fichier JPEG ou PNG, 800 pixels de large et de taille maximale %s" + +msgid "Sidebar" +msgstr "Bandeau" + +msgid "Sidebar position:" +msgstr "Position du bandeau" + +msgid "Sidebar text font:" +msgstr "Police du texte du bandeau :" + +msgid "Sidebar text font size:" +msgstr "Taille du texte du bandeau :" + +msgid "Sidebar text color:" +msgstr "Couleur du texte du bandeau :" + +msgid "Sidebar titles font:" +msgstr "Police des titres du bandeau :" + +msgid "Sidebar titles font size:" +msgstr "Taille des titres du bandeau :" + +msgid "Sidebar titles color:" +msgstr "Couleur des titres du bandeau :" + +msgid "Sidebar 2nd level titles font:" +msgstr "Police des titres de niveau 2 du bandeau :" + +msgid "Sidebar 2nd level titles font size:" +msgstr "Taille des titres de niveau 2 du bandeau :" + +msgid "Sidebar 2nd level titles color:" +msgstr "Couleur des titres de niveau 2 du bandeau :" + +msgid "Sidebar lines color:" +msgstr "Couleur des lignes du bandeau :" + +msgid "Sidebar links color:" +msgstr "Couleur des liens du bandeau :" + +msgid "Sidebar visited links color:" +msgstr "Couleurs des liens vistés du bandeau :" + +msgid "Sidebar focus links color:" +msgstr "Couleurs des liens survolés du bandeau :" + +msgid "Date title font:" +msgstr "Police des titres de dates :" + +msgid "Date title font size:" +msgstr "Taille des titres de dates :" + +msgid "Date title color:" +msgstr "Couleur des titres de date :" + +msgid "Entry title font:" +msgstr "Police des titres de billet :" + +msgid "Entry title font size:" +msgstr "Taille des titres des billets :" + +msgid "Entry title color:" +msgstr "Couleur des titres des billets :" + +msgid "Comment background color:" +msgstr "Couleur du fond des commentaires :" + +msgid "Comment text color:" +msgstr "Couleur du texte des commentaires :" + +msgid "My comment background color:" +msgstr "Couleur du fond de mes commentaires :" + +msgid "My comment text color:" +msgstr "Couleur du texte de mes commentaires :" + +msgid "Footer" +msgstr "Pied de page" + +msgid "Footer font:" +msgstr "Police du pied de page :" + +msgid "Footer font size:" +msgstr "Taille du texte du pied de page :" + +msgid "Footer color:" +msgstr "Couleur du texte du pied de page :" + +msgid "Footer links color:" +msgstr "Couleur des liens du pied de page :" + +msgid "Footer background color:" +msgstr "Couleur de fond du pied de page :" + +msgid "Additional CSS" +msgstr "Style additionnel" + +msgid "Configuration import / export" +msgstr "Import / export de configuration" + +msgid "" +"You can share your configuration using the following code. To apply a " +"configuration, paste the code, click on \"Apply code\" and save." +msgstr "" +"Vous pouvez partager votre configuration en utilisant le code suivant. Pour " +"appliquer une configuration, copiez le code, cliquez sur \"Appliquer le code" +"\" et enregistrez." + +msgid "Copy this code:" +msgstr "Copier ce code :" + +msgid "default" +msgstr "par défaut" + +msgid "" +"At least one of the following functions is not available: " +"imagecreatetruecolor, imagepng & imagecreatefrompng." +msgstr "" +"L'une de ces fonctions au moins est indisponible : imagecreatetruecolor, " +"imagepng & imagecreatefrompng." + +msgid "The 'public' directory does not exist." +msgstr "Le répertoire 'public' n'existe pas." + +#, php-format +msgid "The '%s' directory cannot be modified." +msgstr "Le répertoire '%s' ne peut pas être modifié." + +msgid "Unable to create images." +msgstr "Impossible de créer les images." + +msgid "Invalid file type." +msgstr "Type de fichier non valide." + +msgid "Uploaded image is not 800 pixels wide." +msgstr "L'image fournie de fait pas 800 pixels de large." + +msgid "Unable to open image." +msgstr "Impossible d'ouvrir l'image." + +msgid "Checks trackback source for a link to the post" +msgstr "Vérifie si la source du rétrolien possède un lien vers le billet" + +msgid "Import/Export" +msgstr "Import/Export" + +msgid "Flat file export" +msgstr "Exporter un fichier texte" + +msgid "Exports a blog or a full Dotclear installation to flat file." +msgstr "" +"Exporte un blog ou toutes les données de Dotclear dans un fichier texte." + +msgid "Export file not found." +msgstr "Fichier d'export non trouvé." + +msgid "Failed to compress export file." +msgstr "Erreur à la compression du fichier d'exportation" + +msgid "Single blog" +msgstr "Un seul blog" + +#, php-format +msgid "This will create an export of your current blog: %s" +msgstr "Ceci va exporter le contenu du blog en cours : %s." + +msgid "Compress file" +msgstr "Compresser le fichier" + +msgid "You may also want to download your media directory as a zip file" +msgstr "" +"Vous pouvez également télécharger votre répertoire de médias au format zip." + +msgid "Export" +msgstr "Exporter" + +msgid "Multiple blogs" +msgstr "Plusieurs blogs" + +msgid "This will create an export of all the content of your database." +msgstr "L'intégralité de votre base de données sera exportée." + +msgid "Congratulation!" +msgstr "Félicitations !" + +msgid "Your blog has been successfully imported. Welcome on Dotclear 2!" +msgstr "Votre blog a été importé avec succès. Bienvenue sur Dotclear 2 !" + +msgid "Why don't you blog this now?" +msgstr "Pourquoi ne pas le bloguer maintenant ?" + +msgid "or" +msgstr "ou" + +msgid "visit your dashboard" +msgstr "vous rendre sur votre tableau de bord" + +msgid "Dotclear 1.2 import" +msgstr "Importer depuis Dotclear 1.2" + +msgid "Import a Dotclear 1.2 installation into your current blog." +msgstr "Importe un blog Dotclear 1.2 dans votre blog en cours." + +#, php-format +msgid "" +"This will import your Dotclear 1.2 content as new content in the current " +"blog: %s." +msgstr "" +"Ceci va importer votre blog Dotclear 1.2 comme un nouveau contenu dans le " +"blog en cours : %s." + +msgid "" +"Please note that this process will empty your categories, blogroll, entries " +"and comments on the current blog." +msgstr "" +"Veuillez noter que cette opération va vider vos catégories, liens, billets " +"et commentaires sur le blog en cours." + +msgid "Depending on the size of your blog, it could take a few minutes." +msgstr "Selon la taille de votre blog, ceci peut prendre quelques minutes." + +msgid "General information" +msgstr "Informations générales" + +msgid "Import my blog now" +msgstr "Importer mon blog" + +msgid "" +"We first need some information about your old Dotclear 1.2 installation." +msgstr "" +"Nous avons d'abord besoin de renseignements à propos de votre ancienne " +"installation Dotclear 1.2." + +msgid "Entries import options" +msgstr "Options d'importation des billets" + +msgid "Number of entries to import at once:" +msgstr "Nombre de billets à importer à chaque étape :" + +msgid "Importing users" +msgstr "Importe les utilisateurs" + +msgid "Importing categories" +msgstr "Importe les catégories" + +msgid "Importing blogroll" +msgstr "Importe les liens" + +#, php-format +msgid "Importing entries from %d to %d / %d" +msgstr "Importation des billets %d à %d sur %d" + +msgid "Please read carefully" +msgstr "Merci de lire attentivement" + +msgid "" +"Every newly imported user has received a random password and will need to " +"ask for a new one by following the \"I forgot my password\" link on the " +"login page (Their registered email address has to be valid.)" +msgstr "" +"Chaque utilisateur nouvellement importé a reçu un mot de passe aléatoire et " +"devra en demander un nouveau en suivant le lien \"J'ai oublié mon mot de " +"passe\" sur la page de connexion à l'interface d'aministration." + +#, php-format +msgid "" +"Please note that Dotclear 2 has a new URL layout. You can avoid broken links " +"by installing DC1 redirect plugin and activate it in your " +"blog configuration." +msgstr "" +"Veuillez noter que Dotclear 2 a un nouveau format d'URL. Vous pouvez éviter " +"les liens morts en installant le plugin DC1 redirect et " +"en l'activant dans la configuration de votre blog." + +msgid "next step" +msgstr "étape suivante" + +msgid "Dotclear tables not found" +msgstr "Tables Dotclear non trouvées" + +msgid "Feed import" +msgstr "Importer depuis un flux" + +msgid "Imports a feed as new entries." +msgstr "Importe un flux comme nouveaux billets." + +msgid "Cannot retrieve feed URL." +msgstr "Impossible d'atteindre l'URL du fil." + +msgid "No items in feed." +msgstr "Aucun élément dans le feed." + +msgid "Content successfully imported." +msgstr "Contenu importé avec succès." + +#, php-format +msgid "" +"This will import a feed (RSS or Atom) a as new content in the current blog: " +"%s." +msgstr "" +"Ceci va importer un fil (RSS ou Atom) comme un nouveau contenu dans le blog " +"en cours : %s." + +msgid "Feed URL:" +msgstr "URL du fil" + +msgid "Flat file import" +msgstr "Importer depuis un fichier texte" + +msgid "Imports a blog or a full Dotclear installation from flat file." +msgstr "Importe un blog ou toutes les données depuis un fichier texte." + +msgid "Single blog successfully imported." +msgstr "Blog importé avec succès." + +msgid "Are you sure you want to import a full backup file?" +msgstr "" +"Êtes-vous certain de vouloir charger un fichier de sauvegarde complet ?" + +#, php-format +msgid "" +"This will import a single blog backup as new content in the current blog: %s." +msgstr "" +"Ceci va charger une sauvegarde de blog comme un nouveau contenu dans le blog " +"en cours : %s." + +msgid "Upload a backup file" +msgstr "Charger un fichier de sauvegarde" + +msgid "or pick up a local file in your public directory" +msgstr "ou choisissez un fichier local dans votre répertoire public" + +msgid "This will reset all the content of your database, except users." +msgstr "Ceci va remettre à zéro tout le contenu, sauf les utilisateurs." + +msgid "Another file with same name exists." +msgstr "Il existe déjà un fichier portant ce nom." + +msgid "Failed to extract backup file." +msgstr "Erreur à l'extraction du fichier de sauvegarde." + +msgid "No backup in compressed file." +msgstr "Pas de sauvegarde dans le fichier compressé." + +msgid "WordPress import" +msgstr "Importer depuis WordPress" + +msgid "Import a WordPress installation into your current blog." +msgstr "Importe un blog WordPress dans votre blog en cours." + +#, php-format +msgid "" +"This will import your WordPress content as new content in the current blog: " +"%s." +msgstr "" +"Ceci va importer votre blog WordPress comme un nouveau contenu dans le blog " +"en cours : %s." + +msgid "We first need some information about your old WordPress installation." +msgstr "" +"Nous avons d'abord besoin de renseignements à propos de votre ancienne " +"installation WordPress." + +msgid "" +"WordPress and Dotclear's handling of categories are quite different. You can " +"assign several categories to a single post in WordPress. In the Dotclear " +"world, we see it more like \"One category, several tags.\" Therefore " +"Dotclear can only import one category per post and will chose the lowest " +"numbered one. If you want to keep a trace of every category, you can import " +"them as tags, with an optional prefix." +msgstr "" +"WordPress et Dotclear gèrent les catégories différemment. Dans WordPress, un " +"article peut être classé dans plusieurs catégories, alors que dans Dotclear, " +"on voit ça plutôt comme \"Une catégorie, plusieurs mots-clefs.\" Dotclear ne " +"peut donc importer qu'une seule catégorie par article et choisira dans ce " +"cas la première créée. Si vous désirez garder une trace de chaque catégorie, " +"vous pouvez les importer en tant que mots-clefs, avec un préfixe optionnel." + +msgid "" +"On the other hand, in WordPress, a post can not be uncategorized, and a " +"default installation has a first category labelised \"Uncategorized\". If you did not change that category, you can just ignore it while " +"importing your blog, as Dotclear allows you to actually keep your posts " +"uncategorized." +msgstr "" +"Par contre, il est impossible dans WordPress de ne pas assigner une " +"catégorie à un article, c'est pourquoi lors de l'installation est créée une " +"première catégorie appelée \"Non classée\". Si vous n'avez pas " +"modifié cette catégorie, l'importation peut simplement l'ignorer. En effet, " +"Dotclear vous permet d'avoir des articles sans catégorie." + +msgid "Ignore the first category:" +msgstr "Ignorer la première catégorie :" + +msgid "Import lowest numbered category on posts:" +msgstr "Importer la catégorie la plus ancienne sur les articles :" + +msgid "Import all categories as tags:" +msgstr "Importer les catégories comme des mots-clés :" + +msgid "Prefix such tags with:" +msgstr "Préfixer ces mots-clés avec :" + +msgid "Content filters" +msgstr "Filtres de contenu" + +msgid "" +"You may want to process your post and/or comment content with the following " +"filters." +msgstr "" +"Vous pouvez utiliser les filtres suivants sur vos articles et/ou " +"commentaires." + +msgid "Post content formatter:" +msgstr "Formatage des articles :" + +msgid "Comment content formatter:" +msgstr "Formatage des commentaires :" + +msgid "WordPress tables not found" +msgstr "Tables WordPress non trouvées" + +msgid "No file to read." +msgstr "Aucun fichier lisible." + +msgid "File is not a DotClear backup." +msgstr "Le fichier n'est pas une sauvegarde DotClear." + +msgid "File is not a single blog export." +msgstr "Le fichier n'est pas un fichier d'export simple." + +msgid "File is not a full export." +msgstr "Le fichier n'est pas un fichier d'export complet." + +#, php-format +msgid "" +"ID of \"%3$s\" does not match on record \"%1$s\" at line %2$s of backup file." +msgstr "" +"L'ID de \"%3$s\" ne correspond pas sur l'enregistrement \"%1$s\", ligne %2$s " +"du fichier de sauvegarde." + +msgid "Please wait..." +msgstr "Veuillez patienter..." + +# French translation of DotClea" +msgid "Maintenance" +msgstr "Maintenance" + +msgid "Optimization successful." +msgstr "Optimisation réalisée avec succès." + +msgid "Comments and trackback counted." +msgstr "Commentaires et rétroliens comptés." + +msgid "Templates cache directory emptied." +msgstr "Répertoire du cache des templates vidé." + +msgid "Logs deleted." +msgstr "Journaux effacés." + +#, php-format +msgid "Indexing entry %d to %d." +msgstr "Index des billets %d à %d" + +msgid "next" +msgstr "suivant" + +msgid "Entries index done." +msgstr "Index des billets complet." + +msgid "Back" +msgstr "Retour" + +#, php-format +msgid "Indexing comment %d to %d." +msgstr "Index des commentaires %d à %d" + +msgid "Comments index done." +msgstr "Index des commentaires complet." + +msgid "Optimize database room" +msgstr "Optimiser l'espace de la base de données" + +msgid "Vacuum tables" +msgstr "Nettoyer les tables" + +msgid "Counters" +msgstr "Compteurs" + +msgid "Reset comments and ping counters" +msgstr "Réinitialiser les compteurs des commentaires et rétroliens" + +msgid "Search engine index" +msgstr "Index du moteur de recherche" + +msgid "This may take a very long time" +msgstr "Ceci peut prendre beaucoup de temps" + +msgid "Index all posts" +msgstr "Indexer tous les billets" + +msgid "Index all comments" +msgstr "Indexer tous les commentaires" + +msgid "Vacuum logs" +msgstr "Vider les journaux" + +msgid "Delete all logs" +msgstr "Supprimer tous les journaux" + +msgid "Empty templates cache directory" +msgstr "Vider le répertoire du cache des templates" + +msgid "Empty directory" +msgstr "Vider le répertoire" + +msgid "Pages" +msgstr "Pages" + +#, php-format +msgid "%d page" +msgstr "%d page" + +#, php-format +msgid "%d pages" +msgstr "%d pages" + +msgid "manage pages" +msgstr "gérer les pages" + +msgid "Published on" +msgstr "Publié le" + +msgid "This page's comments feed" +msgstr "Fil des commentaires de cette page" + +msgid "You must provide a valid email address." +msgstr "Vous devez indiquer une adresse email valide." + +msgid "Page title" +msgstr "Titre de la page" + +msgid "Page position" +msgstr "Position de la page" + +msgid "Publication date" +msgstr "Date de publication" + +msgid "No page" +msgstr "Aucune page" + +msgid "select this page" +msgstr "sélectionner cette page" + +msgid "Are you sure you want to delete selected pages?" +msgstr "Êtes-vous certain de vouloir supprimer les pages sélectionnées ?" + +msgid "New page" +msgstr "Nouvelle page" + +msgid "Selected pages action:" +msgstr "Action sur les pages sélectionnées :" + +msgid "This page does not exist." +msgstr "Cette page n'existe pas." + +msgid "Edit page" +msgstr "Modifier la page" + +msgid "next page" +msgstr "page suivante" + +msgid "previous page" +msgstr "page précédente" + +msgid "Are you sure you want to delete this page?" +msgstr "Êtes-vous certain de vouloir supprimer cette page ?" + +msgid "Page has been successfully updated." +msgstr "La page a été mise à jour avec succès." + +msgid "Page has been successfully created." +msgstr "La page a été créée avec succès." + +msgid "Go to this page on the site" +msgstr "Aller sur cette page" + +msgid "Page status:" +msgstr "État de la page :" + +msgid "Page position:" +msgstr "Position de la page :" + +msgid "Page lang:" +msgstr "Langue de la page :" + +msgid "Page password:" +msgstr "Mot de passe de la page :" + +msgid "" +"Warning: If you set the URL manually, it may conflict with another page." +msgstr "" +"Attention : si vous indiquez l'URL manuellement, celle-ci peut entrer en " +"conflit avec une autre page." + +msgid "Add files to this page" +msgstr "Ajouter un fichier à la page" + +msgid "Pings" +msgstr "Pings" + +msgid "Pings configuration" +msgstr "Configuration des pings" + +msgid "Settings have been successfully updated." +msgstr "Paramètres enregistrés avec succès." + +msgid "Activate pings extension" +msgstr "Activer le module de ping" + +msgid "Service name:" +msgstr "Nom du service :" + +msgid "Service URI:" +msgstr "URI du service :" + +msgid "error" +msgstr "erreur" + +msgid "Test ping services" +msgstr "Tester les services de ping" + +msgid "Check all" +msgstr "Tout cocher." + +msgid "Pings:" +msgstr "Pings :" + +msgid "Simple menu" +msgstr "Menu simple" + +msgid "Menu" +msgstr "Menu" + +msgid "All months" +msgstr "Tous les mois" + +msgid "All tags" +msgstr "Tous les mots-clés" + +msgid "Home" +msgstr "Accueil" + +msgid "Archive" +msgstr "Archive" + +msgid "Page" +msgstr "Page" + +msgid "Tags" +msgstr "Mots-clés" + +msgid "User defined" +msgstr "Saisie libre" + +msgid "Label" +msgstr "Libellé" + +msgid "Recent posts" +msgstr "Billets récents" + +#, php-format +msgid "Switch to %s language" +msgstr "Basculer vers le %s" + +msgid "Recent Posts from this category" +msgstr "Billets récents de cette catégorie" + +msgid "Archives" +msgstr "Archives" + +#, php-format +msgid "Posts from %s" +msgstr "Billets de %s" + +#, php-format +msgid "Recent posts for %s tag" +msgstr "Billets récent pour le mot-clé %s" + +msgid "Label and URL of menu item are mandatory." +msgstr "Les libellés et URL sont obligatoires." + +msgid "No menu items selected." +msgstr "Aucun item de menu sélectionné." + +msgid "Label is mandatory." +msgstr "Le libellé est obligatoire." + +msgid "URL is mandatory." +msgstr "l’URL est obligatoire." + +msgid "Menu item has been successfully added." +msgstr "L'item de menu a été ajouté avec succès." + +msgid "Menu items have been successfully removed." +msgstr "Le ou les items de menu ont été supprimés avec succès." + +msgid "Menu items have been successfully updated." +msgstr "Le ou les items de menu ont été mis à jour avec succès." + +msgid "Add item" +msgstr "Ajouter un item de menu" + +msgid "Select type" +msgstr "Sélection du type" + +msgid "Type of item menu:" +msgstr "Type d'item de menu :" + +msgid "Continue..." +msgstr "Continuer…" + +msgid "Select language:" +msgstr "Sélectionnez la langue :" + +msgid "Select category:" +msgstr "Sélectionnez la catégorie :" + +msgid "Select month (if necessary):" +msgstr "Sélectionnez le mois (si nécessaire) :" + +msgid "Select page:" +msgstr "Sélectionnez la page :" + +msgid "Select tag (if necessary):" +msgstr "Sélectionnez le mot clé (si nécessaire) :" + +msgid "Label of item menu:" +msgstr "Libellé de l'item de menu :" + +msgid "Description of item menu:" +msgstr "Description de l'item de menu :" + +msgid "URL of item menu:" +msgstr "URL de l'item de menu :" + +msgid "Add this item" +msgstr "Ajouter cet item" + +msgid "Add an item" +msgstr "Ajouter un item de menu" + +msgid "Menu items list" +msgstr "Liste des items de menu" + +msgid "Update menu" +msgstr "Mettre à jour le menu" + +msgid "Delete selected menu items" +msgstr "Supprimer les items de menu sélectionnés" + +msgid "Are you sure you want to remove selected menu items?" +msgstr "Êtes-vous sûr de vouloir supprimer les items de menu sélectionnés ?" + +msgid "Currently no menu items" +msgstr "Aucun item de menu pour l'instant" + +msgid "Tags:" +msgstr "Mots-clés :" + +#, php-format +msgid "Are you sure you want to remove this %s?" +msgstr "Êtes vous certain de vouloir supprimer ce %s ?" + +#, php-format +msgid "Add a %s to this entry" +msgstr "Ajouter un %s à ce billet" + +msgid "Choose from list" +msgstr "Choisir depuis la liste" + +msgid "all" +msgstr "tous" + +msgid "Tag" +msgstr "Mot-clé" + +msgid "used in %e - frequency %p%" +msgstr "utilisé dans %e - fréquence %p%" + +msgid "entry" +msgstr "billet" + +msgid "entries" +msgstr "billets" + +msgid "Enter tags separated by coma" +msgstr "Entrer les mots-clés séparés par une virgule" + +msgid "Add tags" +msgstr "Ajouter des mots-clés" + +msgid "Remove tags" +msgstr "Supprimer des mots-clés" + +msgid "Add tags to entries" +msgstr "Ajouter des mots-clés aux billets" + +msgid "Tags to add:" +msgstr "Mots-clés à ajouter :" + +msgid "Remove selected tags from entries" +msgstr "Supprimer les mots-clés sélectionnés des billets" + +msgid "No tags for selected entries" +msgstr "Aucun mot-clé pour les billets sélectionnés" + +msgid "Following tags have been found in selected entries:" +msgstr "Les mots-clés suivants ont été trouvés dans les billets sélectionnés :" + +msgid "short" +msgstr "court" + +msgid "extended" +msgstr "étendu" + +msgid "Tags list format:" +msgstr "Format de la liste des mots-clés :" + +msgid "This tag's comments Atom feed" +msgstr "Fil Atom des commentaires de ce mot-clé" + +msgid "This tag's entries Atom feed" +msgstr "Fil Atom des billets de ce mot-clé" + +msgid "Limit (empty means no limit):" +msgstr "Limite (laisser vide pour aucune limite)" + +msgid "Entries count" +msgstr "Nombre de billets" + +msgid "Tag name" +msgstr "Nom du mot-clé" + +msgid "Link to all tags:" +msgstr "Lien vers tous les mots-clés :" + +msgid "Edit tag" +msgstr "Modifier le mot-clé" + +msgid "Tag has been successfully renamed" +msgstr "Mot-clé renommé avec succès" + +msgid "Back to tags list" +msgstr "Retour à la liste des mots-clés" + +msgid "Actions for this tag" +msgstr "Actions pour ce mot-clé" + +msgid "Edit tag name:" +msgstr "Renommer ce mot-clé :" + +msgid "Rename" +msgstr "Renommer" + +msgid "Delete this tag:" +msgstr "Supprimer ce mot-clé :" + +msgid "List of entries with this tag" +msgstr "Liste des billets avec ce mot-clé" + +msgid "Tag has been successfully removed" +msgstr "Mot-clé supprimé avec succès" + +msgid "No tags on this blog." +msgstr "Aucun mot-clé sur ce blog" + +msgid "Theme Editor" +msgstr "Éditeur de thème" + +msgid "No file" +msgstr "Aucun fichier" + +msgid "File does not exist." +msgstr "Le fichier n'existe pas." + +#, php-format +msgid "File %s is not readable" +msgstr "Le fichier %s n'est pas lisible" + +#, php-format +msgid "" +"Unable to write file %s. Please check your theme files and folders " +"permissions." +msgstr "" +"Impossible d'écrire le fichier %s. Veuillez vérifier les permissions des " +"fichiers et répertoires de votre thème." + +msgid "Saving document..." +msgstr "Sauvegarde du document..." + +msgid "Document saved" +msgstr "Document sauvegardé" + +msgid "An error occurred:" +msgstr "Une erreur s'est produite :" + +#, php-format +msgid "Your current theme on this blog is \"%s\"." +msgstr "Le thème utilisé actuellement sur votre blog est \"%s\"." + +msgid "You can't edit default theme." +msgstr "Vous ne pouvez pas modifier le thème par défaut." + +msgid "Please select a file to edit." +msgstr "Veuillez sélectionner un fichier à modifier." + +msgid "File editor" +msgstr "Éditeur de fichier" + +#, php-format +msgid "Editing file %s" +msgstr "Modification du fichier %s" + +msgid "This file is not writable. Please check your theme files permissions." +msgstr "" +"Ce fichier ne peut pas être modifié. Veuillez vérifier les permissions des " +"fichiers de votre thème." + +msgid "Templates files" +msgstr "Fichiers template" + +msgid "CSS files" +msgstr "Fichiers CSS" + +msgid "JavaScript files" +msgstr "Fichiers JavaScript" + +msgid "Preferences successfully updated" +msgstr "Préférences mises à jour avec succès" + +msgid "Preferences definition successfully updated" +msgstr "Définition des préférences mise à jour avec succès" + +msgid "user preferences" +msgstr "préférences utilisateur" + +msgid "global preferences" +msgstr "préférences globales" + +msgid "Presentation widgets" +msgstr "Widgets de présentation" + +msgid "Search engine" +msgstr "Moteur de recherche" + +msgid "Navigation links" +msgstr "Liens de navigation" + +msgid "Selected entries" +msgstr "Billets sélectionnés" + +msgid "Best of me" +msgstr "À retenir" + +msgid "Blog languages" +msgstr "Langues du blog" + +msgid "With entries counts" +msgstr "Afficher le nombre de billets" + +msgid "Subscribe links" +msgstr "Liens d'abonnement" + +msgid "Subscribe" +msgstr "S'abonner" + +msgid "Feeds type:" +msgstr "Types de fil :" + +msgid "Feed reader" +msgstr "Lecteur de fils de nouvelles" + +msgid "Somewhere else" +msgstr "Ailleurs" + +msgid "Entries limit:" +msgstr "Nombre de billets maximum :" + +msgid "Text" +msgstr "Texte" + +msgid "Text:" +msgstr "Texte :" + +msgid "Last entries" +msgstr "Derniers billets" + +msgid "Uncategorized" +msgstr "Non catégorisé" + +msgid "Tag:" +msgstr "Mot-clé :" + +msgid "Last comments" +msgstr "Derniers commentaires" + +msgid "Comments limit:" +msgstr "Nombre de commentaires maximum :" + +#, php-format +msgid "This blog's entries %s feed" +msgstr "Fil %s des billets de ce blog" + +#, php-format +msgid "This blog's comments %s feed" +msgstr "Fil %s des commentaires de ce blog" + +msgid "Entries feed" +msgstr "Fil des billets" + +msgid "Comments feed" +msgstr "Fil des commentaires" + +msgid "navigation" +msgstr "navigation" + +msgid "extra" +msgstr "extra" + +msgid "custom" +msgstr "supplémentaire" + +msgid "Widgets" +msgstr "Widgets" + +msgid "Are you sure you want to reset sidebars?" +msgstr "Êtes-vous certain de vouloir réinitialiser les bandeaux ?" + +msgid "Available widgets" +msgstr "Widgets disponibles" + +msgid "Append to:" +msgstr "Ajouter à :" + +msgid "Add widgets to sidebars" +msgstr "Ajouter les widgets aux bandeaux" + +msgid "Navigation sidebar" +msgstr "Bandeau de navigation" + +msgid "Extra sidebar" +msgstr "Bandeau d'extra" + +msgid "Custom sidebar" +msgstr "Bandeau supplémentaire" + +msgid "Update sidebars" +msgstr "Mettre à jour les bandeaux" + +msgid "Reset sidebars" +msgstr "Réinitialiser les bandeaux" + +msgid "Use of widgets" +msgstr "Utilisation des widgets" + +msgid "" +"Widgets may be used to add various blocks of content to be displayed on your " +"public pages. To add a widget, drag it from the Available widgets list on " +"the left to one of the sidebars on the right of this page. You can order " +"your widgets in a sidebar by dragging them up or down. You must update " +"sidebars to apply your changes." +msgstr "" +"Les widgets sont utilisés pour ajouter des blocs de contenus divers dans vos " +"pages publiques. Pour ajouter un widget, faites-le glisser depuis la liste " +"des Widgets disponibles à gauche jusqu'à l'un des bandeaux sur la droite de " +"la page. Vous pouvez ré-ordonner vos widgets dans un bandeau en le faisant " +"glisser vers le haut ou vers le bas. Vous devez mettre à jour les bandeaux " +"pour enregistrer vos modifications." + +msgid "" +"Once included in a sidebar, widgets have configuration options that you can " +"reach by clicking on the + sign next to their name." +msgstr "" +"Une fois inclus dans un bandeau, les widgets ont généralement des options " +"que vous pouvez configurer. Cliquez sur le signe + à côté de leur nom pour y " +"accéder." + +msgid "Reset sidebars to get back to default widgets installation." +msgstr "" +"Réinitialisez les bandeaux pour retrouver les widgets par défaut de votre " +"installation." + +msgid "Widget templates tags" +msgstr "Marqueurs de template des widgets" + +msgid "" +"If you are allowed to edit your theme templates, you can directly add " +"widgets as templates tags, with their own configuration." +msgstr "" +"Si vous avez le droit de modifier les templates de votre thème, vous pouvez " +"directement ajouter des widgets à l'aide de marqueurs de template, avec leur " +"propre configuration." + +msgid "To add a widget in your template, you need to write code like this:" +msgstr "" +"Pour ajouter un widget dans votre template, vous devez écrire un code comme " +"ceci :" + +msgid "Widget ID" +msgstr "Identifiant du widget" + +msgid "Setting name" +msgstr "Nom du paramètre" + +msgid "Setting value" +msgstr "Valeur du paramètre" + +msgid "Here are the following available widgets for your blog:" +msgstr "Voici les widgets disponibles pour votre blog :" + +msgid "Widget ID:" +msgstr "Identifiant du widget :" + +msgid "No setting for this widget" +msgstr "Aucun paramètre pour ce widget" + +msgid "Setting name:" +msgstr "Nom du paramètre :" + +msgid "No widget." +msgstr "Aucun widget." + +msgid "order" +msgstr "ordre" + +msgid "Remove widget" +msgstr "Supprimer le widget" + +#~ msgid "Export a blog" +#~ msgstr "Exporter un blog" + +#~ msgid "Export all content" +#~ msgstr "Exporter tout le contenu" + +#~ msgid "Import from a feed" +#~ msgstr "Importer depuis un fil de nouvelles" + +#~ msgid "Import a full backup file" +#~ msgstr "Import d'un fichier de sauvegarde complet" + +#~ msgid "The backup file does not appear to be well formed." +#~ msgstr "Le fichier de sauvegarde ne semble pas être correctement formaté" + +#~ msgid "List" +#~ msgstr "Liste" + +#~ msgid "Return to filters" +#~ msgstr "Retour aux filtres" + +#~ msgid "import" +#~ msgstr "importer" + +#~ msgid "Preview" +#~ msgstr "Prévisualiser" + +#~ msgid "Send" +#~ msgstr "Envoyer" + +#~ msgid "View page" +#~ msgstr "Voir la page" + +#~ msgid "Preview page" +#~ msgstr "Prévisualiser la page" + +#~ msgid "Save order" +#~ msgstr "Enregistrer l'ordre" + +#~ msgid "External media" +#~ msgstr "Média externe" + +#~ msgid "External media selector" +#~ msgstr "Sélecteur de médias externes" + +#~ msgid "Supported media services" +#~ msgstr "Services de média supportés" + +#~ msgid "" +#~ "Please enter the URL of the page containing the video you want to include " +#~ "in your post." +#~ msgstr "" +#~ "Entrez l'URL de la page contenant la video que vous voulez intégrer à " +#~ "votre billet." + +#~ msgid "Page URL:" +#~ msgstr "URL de la page :" + +#~ msgid "Media alignment" +#~ msgstr "Alignement du média" + +#~ msgid "Media title" +#~ msgstr "Titre du média" + +#~ msgid "Unsupported service" +#~ msgstr "Service non pris en charge" + +#~ msgid "Invalid page URL" +#~ msgstr "URL de la page non valide" diff --git a/v2/dotclear/locales/fr/public.lang.php b/v2/dotclear/locales/fr/public.lang.php new file mode 100644 index 0000000..fac7047 --- /dev/null +++ b/v2/dotclear/locales/fr/public.lang.php @@ -0,0 +1,94 @@ +%1$s returned no result.'] = 'Votre recherche de %1$s n\'a donné aucun résultat.'; +$GLOBALS['__l10n']['Your search for %1$s returned %2$s result.'] = 'Votre recherche de %1$s a donné %2$s résultat.'; +$GLOBALS['__l10n']['Your search for %1$s returned %2$s results.'] = 'Votre recherche de %1$s a donné %2$s résultats.'; +$GLOBALS['__l10n']['Home'] = 'Accueil'; +$GLOBALS['__l10n']['All keywords'] = 'Tous les mots clés'; +$GLOBALS['__l10n']['Best of me'] = 'À retenir'; +$GLOBALS['__l10n']['Languages'] = 'Langues'; +$GLOBALS['__l10n']['Categories'] = 'Catégories'; +$GLOBALS['__l10n']['Subcategories'] = 'Sous-catégories'; +$GLOBALS['__l10n']['Archives'] = 'Archives'; +$GLOBALS['__l10n']['Links'] = 'Liens'; +$GLOBALS['__l10n']['Subscribe'] = 'S\'abonner'; +$GLOBALS['__l10n']['Entries feed'] = 'Fil des billets'; +$GLOBALS['__l10n']['Comments feed'] = 'Fil des commentaires'; +$GLOBALS['__l10n']['This blog\'s comments Atom feed'] = 'Fil Atom des commentaires de ce blog'; +$GLOBALS['__l10n']['This category\'s entries Atom feed'] = 'Fil Atom des billets de cette catégorie'; +$GLOBALS['__l10n']['This category\'s comments Atom feed'] = 'Fil Atom des commentaires de cette catégorie'; +$GLOBALS['__l10n']['This post\'s comments feed'] = 'Fil des commentaires de ce billet'; +$GLOBALS['__l10n']['This post\'s comments Atom feed'] = 'Fil Atom des commentaires de ce billet'; +$GLOBALS['__l10n']['Attachments'] = 'Annexes'; +$GLOBALS['__l10n']['Permalink'] = 'Lien permanent'; +$GLOBALS['__l10n']['Comments'] = 'Commentaires'; +$GLOBALS['__l10n']['Your comment'] = 'Votre commentaire'; +$GLOBALS['__l10n']['Your comment has been published.'] = 'Votre commentaire a été publié.'; +$GLOBALS['__l10n']['Your comment has been submitted and will be reviewed for publication.'] = 'Votre commentaire a été enregistré et sera publié après validation.'; +$GLOBALS['__l10n']['Add a comment'] = 'Ajouter un commentaire'; +$GLOBALS['__l10n']['Name or nickname'] = 'Nom ou pseudo'; +$GLOBALS['__l10n']['Email address'] = 'Adresse email'; +$GLOBALS['__l10n']['Website'] = 'Site web'; +$GLOBALS['__l10n']['optional'] = 'facultatif'; +$GLOBALS['__l10n']['Comment'] = 'Commentaire'; +$GLOBALS['__l10n']['Comments can be formatted using a simple wiki syntax.'] = 'Les commentaires peuvent être formatés en utilisant une syntaxe wiki simplifiée.'; +$GLOBALS['__l10n']['HTML code is displayed as text and web addresses are automatically converted.'] = 'Le code HTML est affiché comme du texte et les adresses web sont automatiquement transformées.'; +$GLOBALS['__l10n']['Remember me on this blog'] = 'Se souvenir de moi sur ce blog'; +$GLOBALS['__l10n']['preview'] = 'prévisualiser'; +$GLOBALS['__l10n']['send'] = 'envoyer'; +$GLOBALS['__l10n']['They posted on the same topic'] = 'La discussion continue ailleurs'; +$GLOBALS['__l10n']['Trackback URL'] = 'URL de rétrolien'; +$GLOBALS['__l10n']['You must provide an author name'] = 'Vous devez indiquer un nom'; +$GLOBALS['__l10n']['You must provide a comment'] = 'Vous devez écrire un commentaire'; +$GLOBALS['__l10n']['Email address is not valid'] = 'Adresse email incorrecte'; +$GLOBALS['__l10n']['Document not found'] = 'Document non trouvé'; +$GLOBALS['__l10n']['The document you are looking for does not exist.'] = 'Le document que vous cherchez n\'existe pas.'; +$GLOBALS['__l10n']['Powered by %s'] = 'Propulsé par %s'; +$GLOBALS['__l10n']['Subscribe to'] = 'S\'abonner à'; +$GLOBALS['__l10n']['What is an RSS feed?'] = 'Qu\'est ce qu\'un fil RSS ?'; +$GLOBALS['__l10n']['RSS feed is a free blog summary. It provides content (either posts or comments) or summaries of content, together with links to the full versions, and other metadata. The last published items may then be read by your favorite RSS aggregator.'] = 'Un fil RSS recueille les informations de mise à jour d\'un site. Il fournit le contenu des billets ou des commentaires ou un extrait de ceux-ci, ainsi qu\'un lien vers les versions complètes et quelques autres informations. Ce fil a pour vocation d\'être lu par un agrégateur RSS.'; +$GLOBALS['__l10n']['Simply copy the following URL into your aggregator:'] = 'Copier simplement l\'adresse suivante dans votre agrégateur :'; +$GLOBALS['__l10n']['Password needed'] = 'Mot de passe nécessaire'; +$GLOBALS['__l10n']['You must give a password to access this area.'] = 'Vous devez indiquer un mot de passe pour accéder à cette partie.'; +$GLOBALS['__l10n']['Password:'] = 'Mot de passe :'; +$GLOBALS['__l10n']['You must provide a valid email address.'] = 'Vous devez indiquer une adresse e-mail valide.'; +$GLOBALS['__l10n']['Read'] = 'Lire'; +?> \ No newline at end of file diff --git a/v2/dotclear/locales/fr/public.po b/v2/dotclear/locales/fr/public.po new file mode 100644 index 0000000..ce50b8e --- /dev/null +++ b/v2/dotclear/locales/fr/public.po @@ -0,0 +1,241 @@ +# French translation of DotClear +# Copyright (C) 2006. +# Olivier Meunier , 2006. +msgid "" +msgstr "" +"Project-Id-Version: Dotclear 2\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2008-10-13 05:22+0200\n" +"PO-Revision-Date: 2011-01-15 22:47+0100\n" +"Last-Translator: xave \n" +"Language-Team: \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: French\n" + +msgid "To content" +msgstr "Aller au contenu" + +msgid "To menu" +msgstr "Aller au menu" + +msgid "To search" +msgstr "Aller à la recherche" + +msgid "By" +msgstr "Par" + +msgid "by" +msgstr "par" + +msgid "on" +msgstr "le" + +msgid "On" +msgstr "Le" + +msgid "Continue reading" +msgstr "Lire la suite" + +msgid "no comment" +msgstr "aucun commentaire" + +msgid "one comment" +msgstr "un commentaire" + +msgid "%d comments" +msgstr "%d commentaires" + +msgid "no trackback" +msgstr "aucun rétrolien" + +msgid "one trackback" +msgstr "un rétrolien" + +msgid "%d trackbacks" +msgstr "%d rétroliens" + +msgid "no attachment" +msgstr "aucune annexe" + +msgid "one attachment" +msgstr "une annexe" + +msgid "%d attachments" +msgstr "%d annexes" + +msgid "previous entries" +msgstr "billets précédents" + +msgid "page" +msgstr "page" + +msgid "of" +msgstr "de" + +msgid "next entries" +msgstr "billets suivants" + +msgid "Search" +msgstr "Recherche" + +msgid "Your search for %1$s returned no result." +msgstr "Votre recherche de %1$s n'a donné aucun résultat." + +msgid "Your search for %1$s returned %2$s result." +msgstr "Votre recherche de %1$s a donné %2$s résultat." + +msgid "Your search for %1$s returned %2$s results." +msgstr "Votre recherche de %1$s a donné %2$s résultats." + +msgid "Home" +msgstr "Accueil" + +msgid "All keywords" +msgstr "Tous les mots clés" + +msgid "Best of me" +msgstr "À retenir" + +msgid "Languages" +msgstr "Langues" + +msgid "Categories" +msgstr "Catégories" + +msgid "Subcategories" +msgstr "Sous-catégories" + +msgid "Archives" +msgstr "Archives" + +msgid "Links" +msgstr "Liens" + +msgid "Subscribe" +msgstr "S'abonner" + +msgid "Entries feed" +msgstr "Fil des billets" + +msgid "Comments feed" +msgstr "Fil des commentaires" + +msgid "This blog's comments Atom feed" +msgstr "Fil Atom des commentaires de ce blog" + +msgid "This category's entries Atom feed" +msgstr "Fil Atom des billets de cette catégorie" + +msgid "This category's comments Atom feed" +msgstr "Fil Atom des commentaires de cette catégorie" + +msgid "This post's comments feed" +msgstr "Fil des commentaires de ce billet" + +msgid "This post's comments Atom feed" +msgstr "Fil Atom des commentaires de ce billet" + +msgid "Attachments" +msgstr "Annexes" + +msgid "Permalink" +msgstr "Lien permanent" + +msgid "Comments" +msgstr "Commentaires" + +msgid "Your comment" +msgstr "Votre commentaire" + +msgid "Your comment has been published." +msgstr "Votre commentaire a été publié." + +msgid "Your comment has been submitted and will be reviewed for publication." +msgstr "Votre commentaire a été enregistré et sera publié après validation." + +msgid "Add a comment" +msgstr "Ajouter un commentaire" + +msgid "Name or nickname" +msgstr "Nom ou pseudo" + +msgid "Email address" +msgstr "Adresse email" + +msgid "Website" +msgstr "Site web" + +msgid "optional" +msgstr "facultatif" + +msgid "Comment" +msgstr "Commentaire" + +msgid "Comments can be formatted using a simple wiki syntax." +msgstr "Les commentaires peuvent être formatés en utilisant une syntaxe wiki simplifiée." + +msgid "HTML code is displayed as text and web addresses are automatically converted." +msgstr "Le code HTML est affiché comme du texte et les adresses web sont automatiquement transformées." + +msgid "Remember me on this blog" +msgstr "Se souvenir de moi sur ce blog" + +msgid "preview" +msgstr "prévisualiser" + +msgid "send" +msgstr "envoyer" + +msgid "They posted on the same topic" +msgstr "La discussion continue ailleurs" + +msgid "Trackback URL" +msgstr "URL de rétrolien" + +msgid "You must provide an author name" +msgstr "Vous devez indiquer un nom" + +msgid "You must provide a comment" +msgstr "Vous devez écrire un commentaire" + +msgid "Email address is not valid" +msgstr "Adresse email incorrecte" + +msgid "Document not found" +msgstr "Document non trouvé" + +msgid "The document you are looking for does not exist." +msgstr "Le document que vous cherchez n'existe pas." + +msgid "Powered by %s" +msgstr "Propulsé par %s" + +msgid "Subscribe to" +msgstr "S'abonner à" + +msgid "What is an RSS feed?" +msgstr "Qu'est ce qu'un fil RSS ?" + +msgid "RSS feed is a free blog summary. It provides content (either posts or comments) or summaries of content, together with links to the full versions, and other metadata. The last published items may then be read by your favorite RSS aggregator." +msgstr "Un fil RSS recueille les informations de mise à jour d'un site. Il fournit le contenu des billets ou des commentaires ou un extrait de ceux-ci, ainsi qu'un lien vers les versions complètes et quelques autres informations. Ce fil a pour vocation d'être lu par un agrégateur RSS." + +msgid "Simply copy the following URL into your aggregator:" +msgstr "Copier simplement l'adresse suivante dans votre agrégateur :" + +msgid "Password needed" +msgstr "Mot de passe nécessaire" + +msgid "You must give a password to access this area." +msgstr "Vous devez indiquer un mot de passe pour accéder à cette partie." + +msgid "Password:" +msgstr "Mot de passe :" + +msgid "You must provide a valid email address." +msgstr "Vous devez indiquer une adresse e-mail valide." + +msgid "Read" +msgstr "Lire" diff --git a/v2/dotclear/locales/fr/resources.php b/v2/dotclear/locales/fr/resources.php new file mode 100644 index 0000000..d0e57b7 --- /dev/null +++ b/v2/dotclear/locales/fr/resources.php @@ -0,0 +1,23 @@ + 'http://doc.dotclear.net/2.0', + 'Présentation de Dotclear 2' => 'http://doc.dotclear.net/2.0/overview/tour', + "Manuel de l'utilisateur" => 'http://doc.dotclear.net/2.0/usage', + "Guide d'installation et d'administration" => 'http://doc.dotclear.net/2.0/admin', + "Forum de support de Dotclear 2" => 'http://forum.dotclear.net/' +); +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/.htaccess b/v2/dotclear/plugins/.htaccess new file mode 100644 index 0000000..14249c5 --- /dev/null +++ b/v2/dotclear/plugins/.htaccess @@ -0,0 +1 @@ +Deny from all \ No newline at end of file diff --git a/v2/dotclear/plugins/aboutConfig/_admin.php b/v2/dotclear/plugins/aboutConfig/_admin.php new file mode 100644 index 0000000..7a161a0 --- /dev/null +++ b/v2/dotclear/plugins/aboutConfig/_admin.php @@ -0,0 +1,17 @@ +addItem('about:config','plugin.php?p=aboutConfig','index.php?pf=aboutConfig/icon.png', + preg_match('/plugin.php\?p=aboutConfig(&.*)?$/',$_SERVER['REQUEST_URI']), + $core->auth->isSuperAdmin()); +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/aboutConfig/_define.php b/v2/dotclear/plugins/aboutConfig/_define.php new file mode 100644 index 0000000..271c26e --- /dev/null +++ b/v2/dotclear/plugins/aboutConfig/_define.php @@ -0,0 +1,20 @@ +registerModule( + /* Name */ "about:config", + /* Description*/ "Manage every blog configuration directive", + /* Author */ "Olivier Meunier", + /* Version */ '0.4' +); +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/aboutConfig/icon-big.png b/v2/dotclear/plugins/aboutConfig/icon-big.png new file mode 100644 index 0000000000000000000000000000000000000000..f5e9c5d80fe3a12b5b91330bdc9056f093f5acfe GIT binary patch literal 9886 zcmV;PCSlo$P)KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z000}wNkl3~KTyG5gE>=J(_=_4Q>hTQ{bcmVcx zvsGfKt$K1doaI^_I346?`4}WduLtllN&F`S@ZKW{=N!+&p{muY%|{WEFiCjtNt1-h zIREQPOUt%huj2rm8830Hg~ihK=2p!nZ&O~gOko)Q4mX{SoH-iJeVePS(#ys|5I)}L z4&bcaw&L@HhkjpIPq9vGYYg5ClAYbm0ra|Ej*d?(O%q1NjQs1HQ8D9iW4(nW0w@Qt z7eMRs;(U5=dp9UoRvH0BKL7v#|Nn%LJrBV^9LAr2iwR*su!)3|RMgv+$VQZhPMBsWZ ze9y&df7CZu7t?M7yJGD(l64r}q{Lx4k1QErX0Bn$Al~!g(AR-6fRPRih6_{ZfT5Ja z8vp?R|AdmgN+V$yg`aQs!$dQwf*EJkF)0F)#w`K?8-HLI1PiO+CFo69cn?;)djqy& zkw#Q3goRiL+C?RfZZ;N4z~r0!%xjSt#VtH=;4Kb^^B&HpJ$wfJdIUj$@81)Nj&oZs zOCpgtHpWb~TCI7{^RksnB!IO~migJ!cyr_(_vT@G#@rC6!TssALKg#wr91x{klPBiJhO#z@*tMU8SPtjj= zuOId`Ku=lx`L;B8Ck#1UTV$hn4#1eD?)JauQzHXC+)+FpXKQ;)rrfW&z?gj5itJry za|HbmC!(qMLMCk6lnOt_tN&{JXE1~s@*`wO0D2<4kX9})QAS}Hf6n*K#YR6Ju|}D| zOG=}7=|bV4LSm4%k;0&Gp+<`~LAG!c1YNLbX@5gdU=}T!f*M^!x^bgsL6pVV=*)a` z(eb;S^Ihh&7{^)ECOoSH2VS1%J-_#P_sxNTeV)DGF-;Q=hXb5*q|+%>SJz-=d6|1k zOXutB>$^9iQB>E|prDv@jTR?n%5O+yZ zR~1l3F&hpKWipu}$}`i`9%V;S3(|Yf_7T%GP=BNe&%dqfx@DILyPzE|FGu|SYY>5u zk+HG7f^+@-n!_m)P1isfMJyJ(kO?`60Ww?VlkFL=F}PVUbFAC@p$mn%!`G*Pmb=Mp4w;Dfe5v2cwJ6B>}iAL$97yNiZ^x~Z?ZeX z!H(n9=F~$!X`~&^&di(lz4@NzvFpL(hJ+^^th!@aR>hB0RR!m~M3v+C?ky}VF@9cs(N@0&hcC{dQ@gC_3zvq zbi+WnqoW1@t49kL!n>Zyq)pSzuC1jna?bZGYp0?uYs0FUV_C&ReIf~o)s>-Q(dy;E z$7VMBP3N&=ukW*3`LCJ*(=gt80$9myLn1GjO|%R+ES(!nVhV^CFV8ip8Ac&qQ(cZd`2JHsq>GSg>s{NkYV{VJ@=)cZ0h!rnwjf z{Kgxto`$c_1pT!DVmEJsh;ZY^^*ncYO<^VqpibNv)BqLO0}LHBqNjYjeLl`EK> z7`Ff@rR!v)JskdSb!Fu>Cd>Hcg;6kPui`eJ4))`8s~^ei7M2P{e0XaCE+Pm1b0#?1cO0vA;3A`zA!&O!#M{b1hLM}O^niLZfPk|FE?nK zHX8^8wn>t7ZfR+0!lP(Tyt~^EAz&C~Y~I|x?2$$fw4`K`r+2px4S`acPbLzzQ2@y2 zaydc>80UaTuMET3DufV~$_h_(T_+a~g-|Y+VOQ<{4g-yctjM@={W?0ky7C0D7!7J>iYiu z{OgR-FIG(Ro>4AS&RAC+6YFANVPOG`v96h0x6-z4Ly{zDng+|VnmP(0P_0%$DFq<} zexDDjhw#R#gQjUPEek>jgd^cfUvFPf2!Z~Af!0$H3WWfWrBbN`RZ+nihv6Dcs?Rh{ z#A2~$W3ku^@pv3Yr2@uSXEKraNB~=9vf|W6?Lb}kv*-g4V0G$mnu4}K0Fg+T?cB9< z&~+U!Mw^;p7#JTPmo!a#fpZS#xtC(0R+VsF*#~%IK!#@$)ig*Qw@AAazU-zJmE9}xroe_%xgYL*;1o)fFdhkLLhtdDlk6_$O;_S!RY8$ z$?(WOf+QA(P1*lw}zbfJM_rzUttO z2n1w;?tq3l(_V%W69OSs!9;JI?C*-U#(-bbpa+9^?bTPal)4?Oad7p@m7|o>H++8o z6YnUIpX95~@((B%_}RW8^oDDK>hy(AQDG{CXvWkhnY_HeE6Q4W;PRzQpp^DaO-`m( z=j`SB7l7_~9Pe}wQwOAJ0F(>t?~3BbySL+$)Es`3T3TK)Ydcy1<0AaZp-0LsJEgvT>^+eC7xEq5P4^6!V$Y^puK8Q02!Eu# z>A6K2e!6c*W!)(F#qr~C90!sl!RPZ$_Vn~%&+a`iO|vO1DWlkW=QFsH3=S-}fVwgs zH=u(xJmUa*Lv7P4Hi!a+5HJ8?U58~^c<=r9VOiGRsmb&ItYbpg_1ly&)v>HCpY9%o zp|50DhjV=J?b=?=yL0z&>f#k-wHhcZl;OaM&Fi8{2*Et+%dnN_7U9&!2eCG0Fx}sEeBikKRtJfdPrp zHK0`VApCzi`S9DPPhMWFj9VF?0q6n{_NvyZ2h_Sjbr(rJJw3sr$Bv$~ENlAI?@vFs zsUsE~{K1dDr#`rMlo9wf+nUS1`PwTt-aPZR_bm&+5`Y|S_~~i`6i=FKo-|iINiMIJ z<^YH%#fi6e3Q-#&^=40y8upkc%^gpgTN`;`T@}6R{GSf7>WtN8`u`hw{%`iJEJm`b z41ed`t*W}V?yBmgnznmpdYKuK(Q!tG1|)&dOpN+qh#Cb)3==gNeN>Fm7f4i$K9C>; zVn{S9fdL6S$`}z8ohV4p%Fx}zOz%r=x0bt{bABJHs=Iorrbi%}NWb*0o4cIzo%1i> z|NZyBK7jvwcK$v9|4ZeOjl`omS@1j$LI?zdL2P6;M1*WM3st2_%RJ8t1eU8E%Q4%w zyXNQT?{FOFAOIE&249HAV&9F&;}_Nt6xf9VO64+y@53+*P)+Hmi|uPkO`XJA4dT>t zrM#gi@wNc`M-HW`o~0QOVH$snbLKF{;JPj{OG_Xk5YfS0Hv5d`{ zfC1NaxBH$4)W~4H60hkRlF8I{jIpDrnMyvNgT^@mfgrll=?zWfT`~a%UDqIdfoMFA z?(S}An)dhc@$v7xH8JrMjjvu=x8lI5RJH-wR=vANpyC0 z{$P85|4|_XW@lzlDwTlR4tdW^fH4Nn7?Vm4Dk(b@(V0R%KbOs95C{ao7&}EE2qoTA zuPvoSu%+en?94Rs`8<4IK;v46l=4!>_yXtrL`|J}XC_doR94lj&%W`--I+}08@i^! z^?hiZ!?Y}b$On-omEyK-H|^PAjiym2h=c}9Z=2O zND;!3@Nc$n-~NTQbBo2}TL<9y=xF1Bw$0AY9(P?Q#2U(vsFfk=P7+PGAi?wedau}0 zFc^F#7z&LB1A*z9D$(J(?xm$tX;=u6(sdoCWi~gLP2NjN!L%&5r>AGXrfH*%^BdZ^ zbL#*If29Ie19eq4x?Bqp{1n- z;aUyAE*9Z94nm<2D&;av%Sz<3*}JBurfxA!b6vz}Y92zsFwNZl{rhiBwYR?@*OceY zwMFc=ivo6`fMU^xt{Z3xhmpxFLD!A==~Jg(w)2JE^-|sX^{#e>_4M{WGCVx|*-R!w z=O!lLc^;zCC`zRgTEgK50BlrBWweAsD3yu`hC)arlF)P=6B85nkB^PrYMRY=gi;Ej zaLf4M(9jh`G@nQ$kj-QurGym-EGKUr9UT|%1c?ae&!5N4%rv^w-DquVZFL+cDwF`< zAd@B#lqBrv@BdzRclVu>7cPK^kVqsjzpzkGhE_7hP#C-=hEynsoa+ISP$3|rbC{%% z?jJnd5(>R?e01~yR%gDo|8+o=BDk*Gs&U>am733FGMJj2M0i3(cdJ4{Z8tD5FwPK- z#*SUKXU}INk;plv6jG_w)&Y3z$dOQ`QhD7M{*EojSE{zx>=+ohJ)KVfaFq=bfoU2# z)7@2@CW5aNW=jryQgDR2=4`HbkHNLwCf87r0*)^rNTJqUx(p%%pfQe+t|Mew5CAeu z3lL)`z;jE0W~@XI!W?640Dyh-p+j3Yfqnb-mB+@%o;`K))NNM4T26x4+n5X2I9$g~ zm#X5`@_EBB(7Sy{b@vc~0Wdhne8s)>#FBk~B48owdT^u!M}wS4)o>_?U@(TxPyn{; zV$v=m8VW&`%TOR#x{1!cS7XWZ;GB9D*4!i& zjWcgto5?KoCX&hU;^N|$i*|8C2S`NFbscSqguQRyzP-9(yh(Ml35LLeq2-KC5k(&# zpZ=4tOf9^$CiFO2Q+=Pf=X&lL52*pb2{K1aM zfq)g5skbdA!!26}ppeg_QmLR&$YXqb9J;O}kxara6fiS0``fws+0Shh4v7fCKmdtE za^~^_2d+*glVb~WbI41DKq3jI6a*pmyYcB`I^zQij?;AF^|QWIXbYJ5(#~FV1gpF8 z_h-iN==c;;$<#UrM?^>k0uZFmezLD~KL_#zU@#uJI49VsEE5r4f9+p8PMtpavxWKj zPjQWJY6^yKA{vWfXlUr3-oCzXo*NsJsx=9gXveGbOZT2Dl)vgJ1z9tPbupb3+AIr~ zC88LNhY>eTlzbn5J~xRMXO_^`+6tyr(~6|V7%a~5foSl)y~)w4;9suu28*RjW(~lj|gEy zhs6ksu8&XmrSX~V-77NETa&os@1tnz=mIqbfnaeB0G&5D-%UX2?yL4}-3d-jPcH)? zgh(tcF7B)yubCuO!*VnGbt;&vlrcLq-Klf_BWj8MXklOvd~SekQq(BbI^9b`fYvKZSUf|dD`kJ0hU{WEEJFr$DygsNt>?->6QRK(X*1l*_8@@eR={a z97n-*H@#mFp(_+P+Zzd%grbWBpx)9@Z-?NV+dVx!hr{8P!=+*ok!Z9=ZVaT;-J_{w z>hw!5zclI#KeSoipi6=7sW&kR=pPtFG#Z7J5=zSWbI(2d ze7RH#>H7LdDk-5qHuvo9DS0 z+PUk+SSC>n81UZKtj^m$uu7uPKa3$9z*Pc@74TtdUJ%jjA zYZRO@xWdQD#Vno}yMUwfS-`Yb=~k{(h+1am&dVmwrvZ@9B)7r)3D!kVU^%w#gR-+SME&)UUeeS9=Ba{ZyJhKC=l7g%-SW4`?o zoY}Pxo?$|l>oYb5f{@kj6P>dS$0is@N3tz5_~!9j|M9>*kNxGZe}Uuqt8#>m=K6L3 zXf=hhE|b<(%DP`2wkT8G9U;`+k_UVY&V6s~=0oD*l zS;OzmCe5(^t1h+$nYmF`rZwkj&H4JVYWS_zT%)k&Ytr}C;rGSS)qnpU01LQXT8UJA Q2LJ#707*qoM6N<$f;BkRnE(I) literal 0 HcmV?d00001 diff --git a/v2/dotclear/plugins/aboutConfig/icon.png b/v2/dotclear/plugins/aboutConfig/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..adbbf0f3058c0349a65ad7a777bb8241310b0023 GIT binary patch literal 1679 zcmbVNYfuwc6b>MWpnwRsY(tVg2FwqdT*E&%O72-+9k& z(j_dM;uYe>;c%vC79o0e^>e0(P!ecocHC1uP~7 zH$|)kwWJC+TNdR}cw$~c5|(GhWF~Ih0wC5QX9;XLV+0(wEITcCD7YiMa#nU8^SQu? z3S(7pN1ZZgb%2VXa6rrhqcBhc0uqP^2}M$=bUq*eA&?IW_>dq9lFEewIS2w{50|w@ znKI;h1Rb-*?i5@z!;o@5KQ}j*mn-BER3;yi$z)Crfgp<2h@#in8KWc0PR|)v5XMrZBc18FR+LZ0_D{$f?MBBVR&U*rFJ-5CY4#;dVxYD7fqm&tx&l5itxy zGE@*PRf1{|VnrbW!y>g%jH0MWpd9CT9abb(OHmmjQHoFj1gSw-s#3wQ079gYNFoy; z<5-QIW{h?WAGd2^?T%r^Z^X(~6mDb)Dv2Pn#ydb~CK!S?6C|KY6ay(1yNSr9oy8fA z6~QS>4sJpz!Ul|FS8jQYbzyWgEL9?i8dZv%QNt1hg4M8C0D>w=Dr2J_#hU(4#`vr= zd}nLC(kkOeZ2vjMmyOSEUXBiKXXk}t2P1whSjOSFp3@+3lB2USQA_wQ4N$nbxnFLn z^sCuFcl(3~d!|60*G0M;+LhVH_kvQYt4{S@Y+l`urd-_nw|AFlHZNpG2_(^BskUXE zPd6MrAqI6}XIfn@Z+RH5!P2G8b;I^siaTBOAjToBR_ij@k6f|#S@(CVnrGe2p4jZ0 zs*dj%27ASG!hCK99X4p+syOh|suzLlBt^Q%SJSSqEO>voxcB;H&X<{4o?`z~GkaTl zDVa$Syrr~sxBg&@S(Kia7gD@yvtQjED7PGbd)I}Y&kA^Vf0_R$>gf7FR=TMR1Y z-79$K|De8VY@89+T3`%nnnwl=3+t;Nwfp1Ij+n#0%~+S-b0U12TV%4gPkluH<2*Qj zxB?+~KmFaq{VASIlszdtqzpij;y2>F`kl!Y!|f+*qAZ zu@KgiZ3o()McuyL73f7i?@z6|7wM&*RQm|;^W^k@NYm3gvbG<)_c#xkSl}BoH>|CC zef3(?{eqn7JKv>JTkzU;ce5y@vST1;&ygd($#sF!^RYiC2KN+;Pb59@thrk6Xly9H zawh+HQrmP8ex-m9N?cf-|;!fm$hYjZt({ReN0E*V}N^Hwi?@O+^UzOU3fW=TuJ zuYIn5XyZ+Hxb1wFV5ZBp&*`*yp>+rgPZ>O$f4p{s6^=>%y{zVL(qgospOH`YElbOh zpcO@zx`%Xe_dS9exzDR6^_3^oHb9|6-*n{f{tIzw!@fn6JMKLE5!!nCMt@O+#$Yhi z>_@p%gC=_fc)7PxiQo6XGxgr^Gbk>uOn(qboqZuRG&CqAL&fKs(fV5aP zP5)RqdxEPA*okecI@#2;r2-L!?7M+AEQzq}G_Q^hYh4hLx_Ej?{Xe0xKUBm;Ks_<7 n-9wS(A8iGSjvB5!Ny&HN4D8VRFarbYoxcc;Isy4wnYR94&(d^R literal 0 HcmV?d00001 diff --git a/v2/dotclear/plugins/aboutConfig/index.php b/v2/dotclear/plugins/aboutConfig/index.php new file mode 100644 index 0000000..dda5716 --- /dev/null +++ b/v2/dotclear/plugins/aboutConfig/index.php @@ -0,0 +1,240 @@ + $s) + { + $core->blog->settings->addNamespace($ns); + + foreach ($s as $k => $v) { + $core->blog->settings->$ns->put($k,$v); + } + + $core->blog->triggerBlog(); + } + + http::redirect($p_url.'&upd=1'); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} + +# Global settings update +if (!empty($_POST['gs']) && is_array($_POST['gs'])) +{ + try + { + foreach ($_POST['gs'] as $ns => $s) + { + $core->blog->settings->addNamespace($ns); + + foreach ($s as $k => $v) { + $core->blog->settings->$ns->put($k,$v,null,null,true,true); + } + + $core->blog->triggerBlog(); + } + + http::redirect($p_url.'&upd=1&part=global'); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} + +$part = !empty($_GET['part']) && $_GET['part'] == 'global' ? 'global' : 'local'; + +function settingLine($id,$s,$ns,$field_name,$strong_label) +{ + if ($s['type'] == 'boolean') { + $field = form::combo(array($field_name.'['.$ns.']['.$id.']',$field_name.'_'.$id), + array(__('yes') => 1, __('no') => 0),$s['value']); + } else { + $field = form::field(array($field_name.'['.$ns.']['.$id.']',$field_name.'_'.$id),40,null, + html::escapeHTML($s['value'])); + } + + $slabel = $strong_label ? '%s' : '%s'; + + return + ''. + ''. + ''.$field.''. + ''.$s['type'].''. + ''.html::escapeHTML($s['label']).''. + ''; +} +?> + + + about:config + + + + + + +'.__('Configuration successfully updated').'

        '; +} + +if (!empty($_GET['upda'])) { + echo '

        '.__('Settings definition successfully updated').'

        '; +} +?> +

        blog->name); ?> › about:config

        + +
        + +%s'. +''. +''."\n". +' Setting ID'."\n". +' '.__('Value').''."\n". +' '.__('Type').''."\n". +' '.__('Description').''."\n". +''."\n". +''."\n". +''; +$table_footer = ''; + +$settings = array(); +foreach ($core->blog->settings->dumpNamespaces() as $ns => $namespace) { + foreach ($namespace->dumpSettings() as $k => $v) { + $settings[$ns][$k] = $v; + } +} +ksort($settings); +if (count($settings) > 0) { + $ns_combo = array(); + foreach ($settings as $ns => $s) { + $ns_combo[$ns] = '#l_'.$ns; + } + echo + '
        '. + '

        '. + ' '.form::combo('ls_nav',$ns_combo). + ' '. + ''. + $core->formNonce().'

        '; +} +?> + +
        + + $s) +{ + ksort($s); + echo sprintf($table_header,'l_'.$ns,$ns); + foreach ($s as $k => $v) + { + echo settingLine($k,$v,$ns,'s',!$v['global']); + } + echo $table_footer; +} +?> + +

        + +formNonce(); ?>

        +
        +
        + +
        + +blog->settings->dumpNamespaces() as $ns => $namespace) { + foreach ($namespace->dumpGlobalSettings() as $k => $v) { + $settings[$ns][$k] = $v; + } +} + +ksort($settings); + +if (count($settings) > 0) { + $ns_combo = array(); + foreach ($settings as $ns => $s) { + $ns_combo[$ns] = '#g_'.$ns; + } + echo + '
        '. + '

        '. + ' '.form::combo('gs_nav',$ns_combo). + ' '. + ''. + $core->formNonce().'

        '; +} +?> + +
        + + $s) +{ + ksort($s); + echo sprintf($table_header,'g_'.$ns,$ns); + foreach ($s as $k => $v) + { + echo settingLine($k,$v,$ns,'gs',false); + } + echo $table_footer; +} +?> + +

        + +formNonce(); ?>

        +
        +
        + + + \ No newline at end of file diff --git a/v2/dotclear/plugins/akismet/_define.php b/v2/dotclear/plugins/akismet/_define.php new file mode 100644 index 0000000..599cf82 --- /dev/null +++ b/v2/dotclear/plugins/akismet/_define.php @@ -0,0 +1,24 @@ +registerModule( + /* Name */ "Akismet", + /* Description*/ "Akismet interface for Dotclear", + /* Author */ "Olivier Meunier", + /* Version */ '1.1', + array( + 'permissions' => 'usage,contentadmin', + 'priority' => 200 + ) +); +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/akismet/_prepend.php b/v2/dotclear/plugins/akismet/_prepend.php new file mode 100644 index 0000000..c65fb2d --- /dev/null +++ b/v2/dotclear/plugins/akismet/_prepend.php @@ -0,0 +1,17 @@ +spamfilters[] = 'dcFilterAkismet'; +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/akismet/class.dc.filter.akismet.php b/v2/dotclear/plugins/akismet/class.dc.filter.akismet.php new file mode 100644 index 0000000..44530a4 --- /dev/null +++ b/v2/dotclear/plugins/akismet/class.dc.filter.akismet.php @@ -0,0 +1,260 @@ +auth->isSuperAdmin()) { + $this->has_gui = false; + } + } + + protected function setInfo() + { + $this->description = __('Akismet spam filter'); + } + + public function getStatusMessage($status,$comment_id) + { + return sprintf(__('Filtered by %s.'),$this->guiLink()); + } + + private function akInit() + { + $blog =& $this->core->blog; + + if (!$blog->settings->akismet->ak_key) { + return false; + } + + return new akismet($blog->url,$blog->settings->akismet->ak_key); + } + + public function isSpam($type,$author,$email,$site,$ip,$content,$post_id,&$status) + { + if (($ak = $this->akInit()) === false) { + return; + } + + $blog =& $this->core->blog; + + try + { + if ($ak->verify()) + { + $post = $blog->getPosts(array('post_id' => $post_id)); + + $c = $ak->comment_check( + $post->getURL(), + $type, + $author, + $email, + $site, + $content + ); + + if ($c) { + $status = 'Filtered by Akismet'; + return true; + } + } + } catch (Exception $e) {} # If http or akismet is dead, we don't need to know it + } + + public function trainFilter($status,$filter,$type,$author,$email,$site,$ip,$content,$rs) + { + # We handle only false positive from akismet + if ($status == 'spam' && $filter != 'dcFilterAkismet') + { + return; + } + + $f = $status == 'spam' ? 'submit_spam' : 'submit_ham'; + + if (($ak = $this->akInit()) === false) { + return; + } + + try + { + if ($ak->verify()) { + $ak->{$f}($rs->getPostURL(),$type,$author,$email,$site,$content); + } + } catch (Exception $e) {} # If http or akismet is dead, we don't need to know it + } + + public function gui($url) + { + $blog =& $this->core->blog; + + $ak_key = $blog->settings->akismet->ak_key; + $ak_verified = null; + + if (isset($_POST['ak_key'])) + { + try + { + $ak_key = $_POST['ak_key']; + + $blog->settings->addNamespace('akismet'); + $blog->settings->akismet->put('ak_key',$ak_key,'string'); + + http::redirect($url.'&up=1'); + } + catch (Exception $e) + { + $this->core->error->add($e->getMessage()); + } + } + + if ($blog->settings->akismet->ak_key) + { + try { + $ak = new akismet($blog->url,$blog->settings->akismet->ak_key); + $ak_verified = $ak->verify(); + } catch (Exception $e) { + $this->core->error->add($e->getMessage()); + } + } + + $res = + '
        '. + '

        '; + + if ($ak_verified !== null) { + if ($ak_verified) { + $res .= ' '.__('API key verified'); + } else { + $res .= ' '.__('API key not verified'); + } + } + + $res .= '

        '; + + $res .= + '

        '.__('Get your own API key').'

        '. + '

        '. + $this->core->formNonce().'

        '. + '
        '; + + return $res; + } +} + +class akismet extends netHttp +{ + protected $base_host = 'rest.akismet.com'; + protected $ak_host = ''; + protected $ak_version = '1.1'; + protected $ak_path = '/%s/%s'; + + protected $ak_key = null; + protected $blog_url; + + protected $timeout = 3; + + public function __construct($blog_url,$api_key) + { + $this->blog_url = $blog_url; + $this->ak_key = $api_key; + + $this->ak_path = sprintf($this->ak_path,$this->ak_version,'%s'); + $this->ak_host = $this->ak_key.'.'.$this->base_host; + + parent::__construct($this->ak_host,80); + } + + public function verify() + { + $this->host = $this->base_host; + $path = sprintf($this->ak_path,'verify-key'); + + $data = array( + 'key' => $this->ak_key, + 'blog' => $this->blog_url + ); + + if ($this->post($path,$data,'UTF-8')) + { + return $this->getContent() == 'valid'; + } + + return false; + } + + public function comment_check($permalink,$type,$author,$email,$url,$content) + { + $info_ignore = array('HTTP_COOKIE'); + $info = array(); + + foreach ($_SERVER as $k => $v) { + if (strpos($k,'HTTP_') === 0 && !in_array($k,$info_ignore)) { + $info[$k] = $v; + } + } + + return $this->callFunc('comment-check',$permalink,$type,$author,$email,$url,$content,$info); + } + + public function submit_spam($permalink,$type,$author,$email,$url,$content) + { + $this->callFunc('submit-spam',$permalink,$type,$author,$email,$url,$content); + return true; + } + + public function submit_ham($permalink,$type,$author,$email,$url,$content) + { + $this->callFunc('submit-ham',$permalink,$type,$author,$email,$url,$content); + return true; + } + + protected function callFunc($function,$permalink,$type,$author,$email,$url,$content,$info=array()) + { + $ua = isset($info['HTTP_USER_AGENT']) ? $info['HTTP_USER_AGENT'] : ''; + $referer = isset($info['HTTP_REFERER']) ? $info['HTTP_REFERER'] : ''; + + # Prepare comment data + $data = array( + 'blog' => $this->blog_url, + 'user_ip' => http::realIP(), + 'user_agent' => $ua, + 'referrer' => $referer, + 'permalink' => $permalink, + 'comment_type' => $type, + 'comment_author' => $author, + 'comment_author_email' => $email, + 'comment_author_url' => $url, + 'comment_content' => $content + ); + + $data = array_merge($data,$info); + + $this->host = $this->ak_host; + $path = sprintf($this->ak_path,$function); + + if (!$this->post($path,$data,'UTF-8')) { + throw new Exception('HTTP error: '.$this->getError()); + } + + return $this->getContent() == 'true'; + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/antispam/_admin.php b/v2/dotclear/plugins/antispam/_admin.php new file mode 100644 index 0000000..838301d --- /dev/null +++ b/v2/dotclear/plugins/antispam/_admin.php @@ -0,0 +1,73 @@ +addItem(__('Antispam'),'plugin.php?p=antispam','index.php?pf=antispam/icon.png', + preg_match('/plugin.php\?p=antispam(&.*)?$/',$_SERVER['REQUEST_URI']), + $core->auth->check('admin',$core->blog->id)); + +$core->addBehavior('coreAfterCommentUpdate',array('dcAntispam','trainFilters')); +$core->addBehavior('adminAfterCommentDesc',array('dcAntispam','statusMessage')); +$core->addBehavior('adminDashboardIcons',array('dcAntispam','dashboardIcon')); + +$core->addBehavior('adminDashboardFavs','antispamDashboardFavs'); +$core->addBehavior('adminDashboardFavsIcon','antispamDashboardFavsIcon'); + +function antispamDashboardFavs($core,$favs) +{ + $favs['antispam'] = new ArrayObject(array('antispam','Antispam','plugin.php?p=antispam', + 'index.php?pf=antispam/icon.png','index.php?pf=antispam/icon-big.png', + 'admin',null,null)); +} + +function antispamDashboardFavsIcon($core,$name,$icon) +{ + // Check if it is comments favs + if ($name == 'comments') { + // Hack comments title if there is at least one spam + $str = dcAntispam::dashboardIconTitle($core); + if ($str != '') { + $icon[0] .= $str; + } + } +} + +if (!DC_ANTISPAM_CONF_SUPER || $core->auth->isSuperAdmin()) { + $core->addBehavior('adminBlogPreferencesForm',array('antispamBehaviors','adminBlogPreferencesForm')); + $core->addBehavior('adminBeforeBlogSettingsUpdate',array('antispamBehaviors','adminBeforeBlogSettingsUpdate')); +} + +class antispamBehaviors +{ + public static function adminBlogPreferencesForm($core,$settings) + { + $ttl = $settings->antispam->antispam_moderation_ttl; + echo + '
        Antispam'. + '

        '. + '
        '; + } + + public static function adminBeforeBlogSettingsUpdate($settings) + { + $settings->addNamespace('antispam'); + $settings->antispam->put('antispam_moderation_ttl',(integer)$_POST['antispam_moderation_ttl']); + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/antispam/_define.php b/v2/dotclear/plugins/antispam/_define.php new file mode 100644 index 0000000..554194a --- /dev/null +++ b/v2/dotclear/plugins/antispam/_define.php @@ -0,0 +1,24 @@ +registerModule( + /* Name */ "Antispam", + /* Description*/ "Generic antispam plugin for Dotclear", + /* Author */ "Alain Vagner", + /* Version */ '1.3.1', + array( + 'permissions' => 'usage,contentadmin', + 'priority' => 10 + ) +); +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/antispam/_install.php b/v2/dotclear/plugins/antispam/_install.php new file mode 100644 index 0000000..ca13f6b --- /dev/null +++ b/v2/dotclear/plugins/antispam/_install.php @@ -0,0 +1,56 @@ +plugins->moduleInfo('antispam','version'); +if (version_compare($core->getVersion('antispam'),$version,'>=')) { + return; +} + +/* Database schema +-------------------------------------------------------- */ +$s = new dbStruct($core->con,$core->prefix); + +$s->spamrule + ->rule_id ('bigint', 0, false) + ->blog_id ('varchar', 32, true) + ->rule_type ('varchar', 16, false, "'word'") + ->rule_content ('varchar', 128, false) + + ->primary('pk_spamrule','rule_id') + ; + +$s->spamrule->index('idx_spamrule_blog_id','btree','blog_id'); +$s->spamrule->reference('fk_spamrule_blog','blog_id','blog','blog_id','cascade','cascade'); + +if ($s->driver() == 'pgsql') { + $s->spamrule->index('idx_spamrule_blog_id_null','btree','(blog_id IS NULL)'); +} + +# Schema installation +$si = new dbStruct($core->con,$core->prefix); +$changes = $si->synchronize($s); + +# Creating default wordslist +if ($core->getVersion('antispam') === null) { + $_o = new dcFilterWords($core); + $_o->defaultWordsList(); + unset($_o); +} + +$settings = new dcSettings($core,null); +$settings->addNamespace('antispam'); +$settings->antispam->put('antispam_moderation_ttl',0,'integer','Antispam Moderation TTL (days)',false); + +$core->setVersion('antispam',$version); +return true; +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/antispam/_prepend.php b/v2/dotclear/plugins/antispam/_prepend.php new file mode 100644 index 0000000..1dba929 --- /dev/null +++ b/v2/dotclear/plugins/antispam/_prepend.php @@ -0,0 +1,30 @@ +spamfilters = array('dcFilterIP','dcFilterWords','dcFilterIpLookup','dcFilterLinksLookup'); + +$core->url->register('spamfeed','spamfeed','^spamfeed/(.+)$',array('dcAntispamURL','spamFeed')); +$core->url->register('hamfeed','hamfeed','^hamfeed/(.+)$',array('dcAntispamURL','hamFeed')); +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/antispam/_public.php b/v2/dotclear/plugins/antispam/_public.php new file mode 100644 index 0000000..c3c3d97 --- /dev/null +++ b/v2/dotclear/plugins/antispam/_public.php @@ -0,0 +1,17 @@ +addBehavior('publicBeforeCommentCreate',array('dcAntispam','isSpam')); +$core->addBehavior('publicBeforeTrackbackCreate',array('dcAntispam','isSpam')); +$core->addBehavior('publicBeforeDocument',array('dcAntispam','purgeOldSpam')); +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/antispam/antispam.js b/v2/dotclear/plugins/antispam/antispam.js new file mode 100644 index 0000000..8f243e9 --- /dev/null +++ b/v2/dotclear/plugins/antispam/antispam.js @@ -0,0 +1,3 @@ + +var dragsort=ToolMan.dragsort();$(function(){$("#filters-list").each(function(){dragsort.makeTableSortable(this,dotclear.sortable.setHandle,dotclear.sortable.saveOrder);});});dotclear.sortable={setHandle:function(item){var handle=$(item).find('td.handle').get(0);while(handle.firstChild){handle.removeChild(handle.firstChild);} +item.toolManDragGroup.setHandle(handle);$(handle).addClass('handler');},saveOrder:function(item){var group=item.toolManDragGroup;var order=$('#filters_order').get(0);group.register('dragend',function(){order.value='';items=item.parentNode.getElementsByTagName('tr');for(var i=0;i{dK;=FInHLH~Yy`f+UH-R#Ee1*%X0sR+(bD=AMbN@eg(OfJgLO-;#6RB+2IN-fVX$}U#$ zjo3X=O9iMl-_yl0ghN*K%tgKy0}hwKF0Z9q=dP7R7<-R53@b1ojd%BVXn{$lNC=ChHjIezxBZ)FW<@0E}|`sxY81i7u7 tIM>Dr9hR8+?B2cqCzV<&|Gt(!%&$Fzt=)8b_H>}t44$rjF6*2UngITyu7v;q literal 0 HcmV?d00001 diff --git a/v2/dotclear/plugins/antispam/filters/class.dc.filter.ip.php b/v2/dotclear/plugins/antispam/filters/class.dc.filter.ip.php new file mode 100644 index 0000000..d3869e0 --- /dev/null +++ b/v2/dotclear/plugins/antispam/filters/class.dc.filter.ip.php @@ -0,0 +1,312 @@ +con =& $core->con; + $this->table = $core->prefix.'spamrule'; + } + + protected function setInfo() + { + $this->description = __('IP Blacklist / Whitelist Filter'); + } + + public function getStatusMessage($status,$comment_id) + { + return sprintf(__('Filtered by %1$s with rule %2$s.'),$this->guiLink(),$status); + } + + public function isSpam($type,$author,$email,$site,$ip,$content,$post_id,&$status) + { + if (!$ip) { + return; + } + + # White list check + if ($this->checkIP($ip,'white') !== false) { + return false; + } + + # Black list check + if (($s = $this->checkIP($ip,'black')) !== false) { + $status = $s; + return true; + } + } + + public function gui($url) + { + global $default_tab; + $core =& $this->core; + + # Set current type and tab + $ip_type = 'black'; + if (!empty($_REQUEST['ip_type']) && $_REQUEST['ip_type'] == 'white') { + $ip_type = 'white'; + } + $default_tab = 'tab_'.$ip_type; + + # Add IP to list + if (!empty($_POST['addip'])) + { + try + { + $global = !empty($_POST['globalip']) && $core->auth->isSuperAdmin(); + + $this->addIP($ip_type,$_POST['addip'],$global); + http::redirect($url.'&added=1&ip_type='.$ip_type); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } + } + + # Remove IP from list + if (!empty($_POST['delip']) && is_array($_POST['delip'])) + { + try { + $this->removeRule($_POST['delip']); + http::redirect($url.'&removed=1&ip_type='.$ip_type); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } + } + + /* DISPLAY + ---------------------------------------------- */ + $res = ''; + + if (!empty($_GET['added'])) { + $res .= '

        '.__('IP address has been successfully added.').'

        '; + } + if (!empty($_GET['removed'])) { + $res .= '

        '.__('IP addresses have been successfully removed.').'

        '; + } + + $res .= + $this->displayForms($url,'black',__('Blacklist')). + $this->displayForms($url,'white',__('Whitelist')); + + return $res; + } + + private function displayForms($url,$type,$title) + { + $core =& $this->core; + + $res = + '
        '. + + '
        '. + form::hidden(array('ip_type'),$type). + ''; + if ($core->auth->isSuperAdmin()) { + $res .= ' '; + } + + $res .= + $core->formNonce(). + '

        '. + '

        '. + '
        '; + + $rs = $this->getRules($type); + + if ($rs->isEmpty()) + { + $res .= '

        '.__('No IP address in list.').'

        '; + } + else + { + $res .= + '
        '. + '

        ' . __('IP list') . '

        '. + '
        '; + + while ($rs->fetch()) + { + $bits = explode(':',$rs->rule_content); + $pattern = $bits[0]; + $ip = $bits[1]; + $bitmask = $bits[2]; + + $disabled_ip = false; + $p_style = $this->style_p; + if (!$rs->blog_id) { + $disabled_ip = !$core->auth->isSuperAdmin(); + $p_style .= $this->style_global; + } + + $res .= + '

        '; + } + $res .= + '
        '. + '

        '. + $core->formNonce(). + form::hidden(array('ip_type'),$type). + '

        '. + '
        '; + } + + $res .= '
        '; + + return $res; + } + + private function ipmask($pattern,&$ip,&$mask) + { + $bits = explode('/',$pattern); + + # Set IP + $bits[0] .= str_repeat(".0", 3 - substr_count($bits[0], ".")); + $ip = ip2long($bits[0]); + + if (!$ip || $ip == -1) { + throw new Exception('Invalid IP address'); + } + + # Set mask + if (!isset($bits[1])) { + $mask = -1; + } elseif (strpos($bits[1],'.')) { + $mask = ip2long($bits[1]); + if (!$mask) { + $mask = -1; + } + } else { + $mask = ~((1 << (32 - $bits[1])) - 1); + } + } + + private function addIP($type,$pattern,$global) + { + $this->ipmask($pattern,$ip,$mask); + $pattern = long2ip($ip).($mask != -1 ? '/'.long2ip($mask) : ''); + $content = $pattern.':'.$ip.':'.$mask; + + $old = $this->getRuleCIDR($type,$global,$ip,$mask); + $cur = $this->con->openCursor($this->table); + + if ($old->isEmpty()) + { + $id = $this->con->select('SELECT MAX(rule_id) FROM '.$this->table)->f(0) + 1; + + $cur->rule_id = $id; + $cur->rule_type = (string) $type; + $cur->rule_content = (string) $content; + + if ($global && $this->core->auth->isSuperAdmin()) { + $cur->blog_id = null; + } else { + $cur->blog_id = $this->core->blog->id; + } + + $cur->insert(); + } + else + { + $cur->rule_type = (string) $type; + $cur->rule_content = (string) $content; + $cur->update('WHERE rule_id = '.(integer) $old->rule_id); + } + } + + private function getRules($type='all') + { + $strReq = + 'SELECT rule_id, rule_type, blog_id, rule_content '. + 'FROM '.$this->table.' '. + "WHERE rule_type = '".$this->con->escape($type)."' ". + "AND (blog_id = '".$this->core->blog->id."' OR blog_id IS NULL) ". + 'ORDER BY blog_id ASC, rule_content ASC '; + + return $this->con->select($strReq); + } + + private function getRuleCIDR($type,$global,$ip,$mask) + { + $strReq = + 'SELECT * FROM '.$this->table.' '. + "WHERE rule_type = '".$this->con->escape($type)."' ". + "AND rule_content LIKE '%:".(integer) $ip.":".(integer) $mask."' ". + 'AND blog_id '.($global ? 'IS NULL ' : "= '".$this->core->blog->id."' "); + + return $this->con->select($strReq); + } + + private function checkIP($cip,$type) + { + $core =& $this->core; + + $strReq = + 'SELECT DISTINCT(rule_content) '. + 'FROM '.$this->table.' '. + "WHERE rule_type = '".$this->con->escape($type)."' ". + "AND (blog_id = '".$this->core->blog->id."' OR blog_id IS NULL) ". + 'ORDER BY rule_content ASC '; + + $rs = $this->con->select($strReq); + while ($rs->fetch()) + { + list($pattern,$ip,$mask) = explode(':',$rs->rule_content); + if ((ip2long($cip) & (integer) $mask) == ((integer) $ip & (integer) $mask)) { + return $pattern; + } + } + return false; + } + + private function removeRule($ids) + { + $strReq = 'DELETE FROM '.$this->table.' '; + + if (is_array($ids)) { + foreach ($ids as $i => $v) { + $ids[$i] = (integer) $v; + } + $strReq .= 'WHERE rule_id IN ('.implode(',',$ids).') '; + } else { + $ids = (integer) $ids; + $strReq .= 'WHERE rule_id = '.$ids.' '; + } + + if (!$this->core->auth->isSuperAdmin()) { + $strReq .= "AND blog_id = '".$this->core->blog->id."' "; + } + + $this->con->execute($strReq); + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/antispam/filters/class.dc.filter.iplookup.php b/v2/dotclear/plugins/antispam/filters/class.dc.filter.iplookup.php new file mode 100644 index 0000000..540ae7b --- /dev/null +++ b/v2/dotclear/plugins/antispam/filters/class.dc.filter.iplookup.php @@ -0,0 +1,121 @@ +auth->isSuperAdmin()) { + $this->has_gui = false; + } + } + + protected function setInfo() + { + $this->description = __('Checks sender IP address against DNSBL servers'); + } + + public function getStatusMessage($status,$comment_id) + { + return sprintf(__('Filtered by %1$s with server %2$s.'),$this->guiLink(),$status); + } + + public function isSpam($type,$author,$email,$site,$ip,$content,$post_id,&$status) + { + if (!$ip || long2ip(ip2long($ip)) != $ip) { + return; + } + + $match = array(); + + $bls = $this->getServers(); + $bls = preg_split('/\s*,\s*/',$bls); + + foreach ($bls as $bl) + { + if ($this->dnsblLookup($ip,$bl)) { + $match[] = $bl; + } + } + + if (!empty($match)) { + $status = substr(implode(', ',$match),0,128); + return true; + } + } + + public function gui($url) + { + $bls = $this->getServers(); + + if (isset($_POST['bls'])) + { + try { + $this->core->blog->settings->addNamespace('antispam'); + $this->core->blog->settings->antispam->put('antispam_dnsbls',$_POST['bls'],'string','Antispam DNSBL servers',true,false); + http::redirect($url.'&upd=1'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } + } + + /* DISPLAY + ---------------------------------------------- */ + $res = ''; + + $res .= + '
        '. + '
        ' . __('IP Lookup servers') . ''. + '

        '. + '

        '. + $this->core->formNonce().'

        '. + '
        '. + '
        '; + + return $res; + } + + private function getServers() + { + $bls = $this->core->blog->settings->antispam->antispam_dnsbls; + if ($bls === null) { + $this->core->blog->settings->addNamespace('antispam'); + $this->core->blog->settings->antispam->put('antispam_dnsbls',$this->default_bls,'string','Antispam DNSBL servers',true,false); + return $this->default_bls; + } + + return $bls; + } + + private function dnsblLookup($ip,$bl) + { + $revIp = implode('.',array_reverse(explode('.',$ip))); + + $host = $revIp.'.'.$bl.'.'; + if (gethostbyname($host) != $host) { + return true; + } + + return false; + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/antispam/filters/class.dc.filter.linkslookup.php b/v2/dotclear/plugins/antispam/filters/class.dc.filter.linkslookup.php new file mode 100644 index 0000000..7bd87a0 --- /dev/null +++ b/v2/dotclear/plugins/antispam/filters/class.dc.filter.linkslookup.php @@ -0,0 +1,74 @@ +description = __('Checks links in comments against surbl.org'); + } + + public function getStatusMessage($status,$comment_id) + { + return sprintf(__('Filtered by %1$s with server %2$s.'),$this->guiLink(),$status); + } + + public function isSpam($type,$author,$email,$site,$ip,$content,$post_id,&$status) + { + if (!$ip || long2ip(ip2long($ip)) != $ip) { + return; + } + + $urls = $this->getLinks($content); + array_unshift($urls,$site); + + foreach ($urls as $u) + { + $b = parse_url($u); + if (!isset($b['host']) || !$b['host']) { + continue; + } + + $domain = preg_replace('/^(.*\.)([^.]+\.[^.]+)$/','$2',$b['host']); + $host = $domain.'.'.$this->server; + + if (gethostbyname($host) != $host) { + $status = substr($domain,0,128); + return true; + } + } + } + + private function getLinks($text) + { + $res = array(); + + # href attribute on "a" tags + if (preg_match_all('/]+)>/ms', $text, $match, PREG_SET_ORDER)) + { + for ($i = 0; $i \ No newline at end of file diff --git a/v2/dotclear/plugins/antispam/filters/class.dc.filter.words.php b/v2/dotclear/plugins/antispam/filters/class.dc.filter.words.php new file mode 100644 index 0000000..5444bce --- /dev/null +++ b/v2/dotclear/plugins/antispam/filters/class.dc.filter.words.php @@ -0,0 +1,356 @@ +con =& $core->con; + $this->table = $core->prefix.'spamrule'; + } + + protected function setInfo() + { + $this->description = __('Words Blacklist'); + } + + public function getStatusMessage($status,$comment_id) + { + return sprintf(__('Filtered by %1$s with word %2$s.'),$this->guiLink(),''.$status.''); + } + + public function isSpam($type,$author,$email,$site,$ip,$content,$post_id,&$status) + { + $str = $author.' '.$email.' '.$site.' '.$content; + + $rs = $this->getRules(); + + while ($rs->fetch()) + { + $word = $rs->rule_content; + + if (substr($word,0,1) == '/' && substr($word,-1,1) == '/') { + $reg = substr(substr($word,1),0,-1); + } else { + $reg = preg_quote($word, '/'); + $reg = '(^|\s+|>|<)'.$reg.'(>|<|\s+|\.|$)'; + } + + if (preg_match('/'.$reg.'/msiu',$str)) { + $status = $word; + return true; + } + } + } + + public function gui($url) + { + $core =& $this->core; + + # Create list + if (!empty($_POST['createlist'])) + { + try { + $this->defaultWordsList(); + http::redirect($url.'&list=1'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } + } + + # Adding a word + if (!empty($_POST['swa'])) + { + $globalsw = !empty($_POST['globalsw']) && $core->auth->isSuperAdmin(); + + try { + $this->addRule($_POST['swa'],$globalsw); + http::redirect($url.'&added=1'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } + } + + # Removing spamwords + if (!empty($_POST['swd']) && is_array($_POST['swd'])) + { + try { + $this->removeRule($_POST['swd']); + http::redirect($url.'&removed=1'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } + } + + /* DISPLAY + ---------------------------------------------- */ + $res = ''; + + if (!empty($_GET['list'])) { + $res .= '

        '.__('Words have been successfully added.').'

        '; + } + if (!empty($_GET['added'])) { + $res .= '

        '.__('Word has been successfully added.').'

        '; + } + if (!empty($_GET['removed'])) { + $res .= '

        '.__('Words have been successfully removed.').'

        '; + } + + $res .= + '
        '. + '

        '; + + if ($core->auth->isSuperAdmin()) { + $res .= ' '; + } + + $res .= + $core->formNonce(). + '

        '. + '

        '. + '
        '; + + $rs = $this->getRules(); + if ($rs->isEmpty()) + { + $res .= '

        '.__('No word in list.').'

        '; + } + else + { + $res .= + '
        '. + '

        ' . __('List of bad words') . '

        '. + '
        '; + + while ($rs->fetch()) + { + $disabled_word = false; + $p_style = $this->style_p; + if (!$rs->blog_id) { + $disabled_word = !$core->auth->isSuperAdmin(); + $p_style .= $this->style_global; + } + + $res .= + '

        '; + } + + $res .= + '
        '. + '

        '.form::hidden(array('spamwords'),1). + $core->formNonce(). + '

        '. + '
        '; + } + + if ($core->auth->isSuperAdmin()) + { + $res .= + '
        '. + '

        '. + form::hidden(array('spamwords'),1). + form::hidden(array('createlist'),1). + $core->formNonce().'

        '. + '
        '; + } + + return $res; + } + + private function getRules() + { + $strReq = 'SELECT rule_id, blog_id, rule_content '. + 'FROM '.$this->table.' '. + "WHERE rule_type = 'word' ". + "AND ( blog_id = '".$this->con->escape($this->core->blog->id)."' ". + "OR blog_id IS NULL ) ". + 'ORDER BY blog_id ASC, rule_content ASC '; + + return $this->con->select($strReq); + } + + private function addRule($content,$general=false) + { + $strReq = 'SELECT rule_id FROM '.$this->table.' '. + "WHERE rule_type = 'word' ". + "AND rule_content = '".$this->con->escape($content)."' "; + $rs = $this->con->select($strReq); + + if (!$rs->isEmpty()) { + throw new Exception(__('This word exists')); + } + + $rs = $this->con->select('SELECT MAX(rule_id) FROM '.$this->table); + $id = (integer) $rs->f(0) + 1; + + $cur = $this->con->openCursor($this->table); + $cur->rule_id = $id; + $cur->rule_type = 'word'; + $cur->rule_content = (string) $content; + + if ($general && $this->core->auth->isSuperAdmin()) { + $cur->blog_id = null; + } else { + $cur->blog_id = $this->core->blog->id; + } + + $cur->insert(); + } + + private function removeRule($ids) + { + $strReq = 'DELETE FROM '.$this->table.' '; + + if (is_array($ids)) { + foreach ($ids as &$v) { + $v = (integer) $v; + } + $strReq .= 'WHERE rule_id IN ('.implode(',',$ids).') '; + } else { + $ids = (integer) $ids; + $strReq .= 'WHERE rule_id = '.$ids.' '; + } + + if (!$this->core->auth->isSuperAdmin()) { + $strReq .= "AND blog_id = '".$this->con->escape($this->core->blog->id)."' "; + } + + $this->con->execute($strReq); + } + + public function defaultWordsList() + { + $words = array( + '/-credit(\s+|$)/', + '/-digest(\s+|$)/', + '/-loan(\s+|$)/', + '/-online(\s+|$)/', + '4u', + 'adipex', + 'advicer', + 'ambien', + 'baccarat', + 'baccarrat', + 'blackjack', + 'bllogspot', + 'bolobomb', + 'booker', + 'byob', + 'car-rental-e-site', + 'car-rentals-e-site', + 'carisoprodol', + 'cash', + 'casino', + 'casinos', + 'chatroom', + 'cialis', + 'craps', + 'credit-card', + 'credit-report-4u', + 'cwas', + 'cyclen', + 'cyclobenzaprine', + 'dating-e-site', + 'day-trading', + 'debt', + 'digest-', + 'discount', + 'discreetordering', + 'duty-free', + 'dutyfree', + 'estate', + 'favourits', + 'fioricet', + 'flowers-leading-site', + 'freenet', + 'freenet-shopping', + 'gambling', + 'gamias', + 'health-insurancedeals-4u', + 'holdem', + 'holdempoker', + 'holdemsoftware', + 'holdemtexasturbowilson', + 'hotel-dealse-site', + 'hotele-site', + 'hotelse-site', + 'incest', + 'insurance-quotesdeals-4u', + 'insurancedeals-4u', + 'jrcreations', + 'levitra', + 'macinstruct', + 'mortgage', + 'online-gambling', + 'onlinegambling-4u', + 'ottawavalleyag', + 'ownsthis', + 'palm-texas-holdem-game', + 'paxil', + 'pharmacy', + 'phentermine', + 'pills', + 'poker', + 'poker-chip', + 'poze', + 'prescription', + 'rarehomes', + 'refund', + 'rental-car-e-site', + 'roulette', + 'shemale', + 'slot', + 'slot-machine', + 'soma', + 'taboo', + 'tamiflu', + 'texas-holdem', + 'thorcarlson', + 'top-e-site', + 'top-site', + 'tramadol', + 'trim-spa', + 'ultram', + 'v1h', + 'vacuum', + 'valeofglamorganconservatives', + 'viagra', + 'vicodin', + 'vioxx', + 'xanax', + 'zolus' + ); + + foreach ($words as $w) { + try { + $this->addRule($w,true); + } catch (Exception $e) {} + } + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/antispam/icon-big.png b/v2/dotclear/plugins/antispam/icon-big.png new file mode 100644 index 0000000000000000000000000000000000000000..5a9f0f4676b09093da744b024428042d699499e1 GIT binary patch literal 5758 zcmbVQXH*m2x(-chq(~Df5fD%zq(KNBLLx|!4pJnP01*f!p%*~~3!w-~RX|ik5s=)`L%j#mT#XdDQ} z=45kS9eI0qH?Zv=8?c|7$Eh~}ps3>KVQcS#Cxh(pP6VQo@LE-!Fo@uwBy1+53(@sJ zRPyAdyH(5DWr^NJC)KP?!`HDG!IqLm;5P z58+cbF9%0?Lk;ZTT&F7~VP`VgLta|i*Vh;93kSPO^~ zkM_dblHI+G-Q8XPQGmX)JK3G&?Ct?V8_9so2t)^WU(%oE{3}-tycfX-?|}7kcLV)Z zU3tQPV3$LqVJIjDBYVpKCu{YIB9+hh2L{ZDR5)%2+M#EM-u z5XIb%BFOo$iF)Kw@q<*4sTOgdkG32=En%6!FpyfT#D(^j2u?XwJ;S^+LH+G-0aVnY znZoEeyv1t?gW1@on{qWK-ctL&YjXo~M#B5knfRs(%VF=jH zs-c`L{s>+cNwxl4HcO@6+@nj#^6`)a?Hd zj(REzY(Q{Qv1Yz`mjSyfQ6g48nxVp`9k@`1n=7RQbvqjEtW1d??v!4F(NsI!r+2?z zS0*yX8^mZGW=}hR;J4v{ppIYncK+;ABKg7;dg!!d@R}n98WE<%=ah(WvZwFSp8lwQ zxtS^ZX>T{1PTwa5VXa?TEb*5{_z-v}r)xv`xt%-}dpuaG6k^UuoT*}5Nl8v&Mad-v zWI!R!{DTgJ40HEe#x9a;Lw9nqj1vn}J=B^TW8KVF@7Gu^ck!vC@O@bQ$(|F8QD;V( zb>&+{G+UX*70Rtb$)=-n3u;38WtJ-qMA3Hr(lTGk&Dd2B23^(zHbC)8lK8_pNKZ(P)Y+q^eniGSiGpo5B{(_50KN1%V} z(Q%ZY=R-E9XOO82&dkwSTQo|s!prM>&%MYJ!JEsl;$E$t>vF!Wb=&@ccU1Zp2RER5 zo+_!;pUAoFwS9-F@!_-Z7px!dtLK07e@UDA(<+x?sxNGh|7cC}BK;<+7)S-_&|rw1 z4D1Lhn|}bW0O*=CHf&b!EFOxvw)LkevFV5blT@f688VOr_((gniOX2-F`Z$!?CrN6 z<^aiSa)`;;!Df>sN9wzn#W1$o=uK+UOAfsf5K@DM(Bd(Ka`DZ?@Fwm>qBy|t?kZ4w7V7k%>Q9Qo|Z=L&Cs z^Gt-Bhrf^MzTUkG;fpUqvqQr^OWv9tvH&E#!Sq}QR46y~FQ=i5IDZhpnXH9bSy{UJ zG;J6$BVQcDY;|RTYIM4veo04m?-G!nhmL^&LGi<$i^i{uQ?N8uMc>Gow%ixr@(1mYII?q}W4AsnB+ zYHvYD5*3>(0-X3BlOiBvk)#=)hA1&rSC5g}3LqsdvLjvc_qUK}<2D;J6waH$CP?t9pQ z%!&cQ&&ituTU;xQ(T|V0d9s7IgL&8`i9uMf{(QW8cGhNp+(fw2$H#OVaS{zWykXnzPemm{uw)9N2xwMXd4;A(rEc_)|`uUpK z%bw{_YLgcI0>QHp_1Ra0U>)*ZkBp%G#yhUT+%|PvqNcMhFk1XPcov5NSo?JFJb;fkFT6o6$ z`b(8ID*CfncR6Kn2$(UMj3$mM1=TKHMO^lQ7?cy<;BQ3aHF^ zcP%W+pWz$Rg(q7%vZ+zq#OSA0yjQN|n$?6_XZVto^oM5r-15GwdglXMku_sqCRa|vQibMwWEW}UeM&&t;D|Kmea&HB8 z9?3CV8HuH*0>IE!_?SzXLdrcj5Qu1%_O)J8-Qdc?+fYDsdgsL+nN#N|| zYcc$>?k9@|oK{st>G-KK<9e7Uo`E%7)AN)2iP4WjeuvN=e~?j{Nje! zT({S`^zgB2*~7-`UzodXnlc{_zI2Z(wv>9>E=3R3k39-019I@;;u0v~PUrA*Ad3%&r<{45aiS?=f_bcdI!?(+1Y(;YOR(wLh z-1R(c6AuWp3rHsOPPYj$2?Mh{<42H{xORcqw z<-QFIF@|n0No+~5h-FZgQgij5(Zo9TD<=XuVrNlqo@xa(uZ>D_+jQhhLvodZ@T%j5 zyNFjv#)hbayM!11b$-|9Np5LRJ3iRNP(&t?RNX!~R8*3tGK_?@v9s)o%L2JSRokL$ zwOxF^-`+*U-yX#3%4V2|=0#dw;Fvs0PIk1Sn@-A_uVCrfERfaHt~&cI&puF!=|w## zmRKegHE&pAp_8&uioVZURH3Bam;F5@A&di&RT{N2!+TCmp};4=O#xE=E|15ivQlm> zu`TKx?a7Yz3MZiT)3!{csFfXZNPXtvu%4td6*U9f-B$Zl+UcSSrf(nU6LZyaEUFnY z>*r2Pc|S~4Ji6F$>S=2M_(GnbJDQ~7qOPq9TFm52n!>4td8Vs#TD)Ah5W_}Bc9veF;`0|E zq+K|pc(`07d39>=ENe%1u9_LoWsHGJtb=QDU`~jDhL0~p@xaur;h$Y03s|-rzjdX` z*y}2~--K&KP<$1v1rk+$n;(Wc=!e}X8(L4(Jj~=IX3S5;?KCP&ebp2pcq2Z$r}B#) ztXZA8(QlPEVSf5$tPiBbHOdN?+i7Ps^2-Q!)l<52Ae})e8#v+6mKF@YHi}m-D={&l z0fz=ZKY1bgs#Yd=R}e3F*`3$nEC4;BUsC+_S@yQfSR!rIYwy*u+4Wu<8mr?J)pC^c zk}3DA9K=i5*9)_S)ohh>SBHCvk9QaYkwf)g3X8cDTEzSF@=UU7QhVR#+t?)LxTFie z;;&kFR(n#_A_=ZP(w$lrCE+RxD|wEmsP`^ip=DSe_EiVeIh3~i2HZ0+8zM@!znlX? zn2@192lt>l=K>OFJKh6LrXudjI3H*)X2Gs?x)!|ouwc>C% zweA(L5s2JXG#c4t^?D+dSk%rC`81vJ*-qgd+04IR=uU4>;?1-fdi6`^({bO?CeW7Uv^ zQs=?%zC08(kUi>GB2?Q4hNs^--bZfSz4LvB-gBj~gzJ8D7Vyrx8ONZ|v%-RBQ?x!* zbnL2Z2I%m)aJ8%&S;D1)0r|3dcHVZyU84xRO=@AmhSyC=8F1efXz;Zz*fN{k#aLjLa+6ej8lSV6Ej;yA$4~i2Sy|$B+UA{Jiw)4S0{?{ zeh7W4w`(StdX6b{aWX^BU(ZoK_XM^sxMF7bGEK22sqWzN`~zv5;WT)GL79`G%U{)xSBAL()~v)@0Ss*7?UI5S_KT6{N1ORL2+v-f+qZThf|ZtbS$%C7Ng!&>*dw54md zwyaNTLRHd24i?ix>%|5AXP;bW(9W$LFRB(hNy)=+U*!uDX-sLzY05;QhJ8lU42ghGyc$&>!N0!CMC1 zD=WvxR;Kc)Ud|gvi->@MPK!5Fd-@&mDk#hC{UoaXspR8QHYTBf^=$s?wbvTmzXvO+ z%NA>QCj&K(lao(hEBq9$(=D6pqXOt;AR^?_?V%5ls>*5CH0(om#%p#`>$`W|4YV>UC4n!kg8u1X`NmOM=hOd1Z$8-8h-sg={liUJ*nE9Embzq1)0e z22-dO?UN3>73!wXZriY}*!a&qE85KT&!f&}oVkWOa(cij#7+I$H}ZB7^ZmYP9}q>x z|L|Vg^2qK-n41owgn}iB_XhuJ7k|8kJ6hPx@^++pemuRnNZ%ME(-I|eob>Zr@x#Hv zL6O!Np+u2u(Z+cjC}yZcEV$!=P{_mny#ox-)Sa}bqO|#g7DP?{@jwo|Pi6D-ymI8l zgf|cSYJ94K9c^u=yABQxY;e!zPX%Wqpx~p!3oY+o&b@mb2SYp5c}!Cq9Gf`=5j+=l z>%LQLzZlnvCrv?%07Oh|!dsfdDgjQUyN|*I^04W+fmM0$8$It^P|`gzs~~~|31}f4 z@=W;bUcb{joL;?`{g0Id(!IvJgU6iL{cvfb zq)pVmVxV~574L5QO%xb_WtunSPP@4k*AKk`#(Fx BdQt!Y literal 0 HcmV?d00001 diff --git a/v2/dotclear/plugins/antispam/icon.png b/v2/dotclear/plugins/antispam/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..bf069ccf5cdca9a566b7659d2982382835c465bc GIT binary patch literal 1734 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+m{T%CB1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+* zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxKsVXI%s|1+P|wiV z#N6CmN5ROz&_Lh7NZ-&%*U;R`*vQJjKmiJrfVLH-q*(>IxIyg#@@$ndN=gc>^!3Zj z%k|2Q_413-^$jg8EkR}&8R-I5=oVMzl_XZ^<`pZ$OmImpPA){ffi_eM3D1{oGuTzrd=COM+4n&cLd=IHa;5RX-@T zIKQ+g85kdF$}r8qu)}W=NFmTQR{lkqz(`5Vami0E%}vcK@pQ3O0?O#6WTsfTSUNfy zTDloom^&G`8W;kZ#x9PICa%V&Zfx;JP@U)zv)QP(42V?rROX^?=? zOwTte+m_2!uX}zd-Mi<-a>=>Ivp(BB-))r4)7RgB-}ljzT;|QXOKUtmw>rO`cI_A2 z0f+Z9BCnYyziHxrce^RxY<91GUteFH=oj&eO25p`e-2-MS@V#Ai-_)qE@6vM?)bWI zd|Fq36-+JGF_tb2JZN(1gZjhyDz&-H876mZIGlbo_Mc2?`dQ;QK{RSzgL<6X`m1dz zdI5z8vtrL&607_5()45t>hT|Ry z<@4O3OiO}(-un7k!C`CI;dk%!&i!FHYt>#*e&CLr&b`Ky&q^$sd~Ui0Go5&(;%PAV zY=Ck@?(H3OVw4Icd}{m*vo>@!oO^B%q%*2?*Fs$U3Xh=S24bP zCFydsadWBkitqYf4skCo&b{7V@%|g%0pSA+L;WW7s=v7Vcb-?)g}bi;lEhz>?*8$i zId{+3wE7UHEn(^hrzFZ1TTIF2^G*CB@RG-ToArgTxwlSE_${S>sr-1hqgUysYf-aB zr2alJx{|50`of`RzjcW_*e~8YzBYROfkGLb>E0Fd+RJwHUM~$^dUdkUffQYgD+tJ}~8u+aNbLe(k&eMTZKfmI*7GetSR6w`EtblGTx$H*elQi8=8#KI`glscd}z`@XJNx4h2jS==Azu>9vTV3_0F VP>>nC;5Mjc@pScbS?83{1OQFcoOS>J literal 0 HcmV?d00001 diff --git a/v2/dotclear/plugins/antispam/inc/class.dc.spamfilter.php b/v2/dotclear/plugins/antispam/inc/class.dc.spamfilter.php new file mode 100644 index 0000000..59f0fe2 --- /dev/null +++ b/v2/dotclear/plugins/antispam/inc/class.dc.spamfilter.php @@ -0,0 +1,161 @@ +dcCore Dotclear core object + */ + public function __construct($core) + { + $this->core =& $core; + $this->setInfo(); + + if (!$this->name) { + $this->name = get_class($this); + } + + $this->gui_url = 'plugin.php?p=antispam&f='.get_class($this); + } + + /** + This method is called by the constructor and allows you to change some + object properties without overloading object constructor. + */ + protected function setInfo() + { + $this->description = __('No description'); + } + + /** + This method should return if a comment is a spam or not. If it returns true + or false, execution of next filters will be stoped. If should return nothing + to let next filters apply. + + Your filter should also fill $status variable with its own information if + comment is a spam. + + @param type string Comment type (comment or trackback) + @param author string Comment author + @param email string Comment author email + @param site string Comment author website + @param ip string Comment author IP address + @param content string Comment content + @param post_id integer Comment post_id + @param[out] status integer Comment status + @return boolean + */ + public function isSpam($type,$author,$email,$site,$ip,$content,$post_id,&$status) + { + } + + /** + This method is called when a non-spam (ham) comment becomes spam or when a + spam becomes a ham. + + @param type string Comment type (comment or trackback) + @param filter string Filter name + @param author string Comment author + @param email string Comment author email + @param site string Comment author website + @param ip string Comment author IP address + @param content string Comment content + @param post_url string Post URL + @param rs record Comment record + @return boolean + */ + public function trainFilter($status,$filter,$type,$author,$email,$site,$ip,$content,$rs) + { + } + + /** + This method returns filter status message. You can overload this method to + return a custom message. Message is shown in comment details and in + comments list. + + @param status string Filter status. + @param comment_id record Comment record + @return string + */ + public function getStatusMessage($status,$comment_id) + { + return sprintf(__('Filtered by %1$s (%2$s)'),$this->guiLink(),$status); + } + + /** + This method is called when you enter filter configuration. Your class should + have $has_gui property set to "true" to enable GUI. + + In this method you should put everything related to filter configuration. + $url variable is the URL of GUI unescaped. + + @param url string GUI URL. + */ + public function gui($url) + { + } + + public function hasGUI() + { + if (!$this->core->auth->check('admin',$this->core->blog->id)) { + return false; + } + + if (!$this->has_gui) { + return false; + } + + return true; + } + + public function guiURL() + { + if (!$this->hasGui()) { + return false; + } + + return $this->gui_url; + } + + /** + Returns a link to filter GUI if exists or only filter name if has_gui + property is false. + + @return string + */ + public function guiLink() + { + if (($url = $this->guiURL()) !== false) { + $url = html::escapeHTML($url); + $link = '
        %1$s'; + } else { + $link = '%1$s'; + } + + return sprintf($link,$this->name,$url); + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/antispam/inc/class.dc.spamfilters.php b/v2/dotclear/plugins/antispam/inc/class.dc.spamfilters.php new file mode 100644 index 0000000..2983aaa --- /dev/null +++ b/v2/dotclear/plugins/antispam/inc/class.dc.spamfilters.php @@ -0,0 +1,164 @@ +core =& $core; + } + + public function init($filters) + { + foreach ($filters as $f) + { + if (!class_exists($f)) { + continue; + } + + $r = new ReflectionClass($f); + $p = $r->getParentClass(); + + if (!$p || $p->name != 'dcSpamFilter') { + continue; + } + + $this->filters[$f] = new $f($this->core); + } + + $this->setFilterOpts(); + if (!empty($this->filters_opt)) { + uasort($this->filters,array($this,'orderCallBack')); + } + } + + public function getFilters() + { + return $this->filters; + } + + public function isSpam($cur) + { + foreach ($this->filters as $fid => $f) + { + if (!$f->active) { + continue; + } + + $type = $cur->comment_trackback ? 'trackback' : 'comment'; + $author = $cur->comment_author; + $email = $cur->comment_email; + $site = $cur->comment_site; + $ip = $cur->comment_ip; + $content = $cur->comment_content; + $post_id = $cur->post_id; + + $is_spam = $f->isSpam($type,$author,$email,$site,$ip,$content,$post_id,$status); + + if ($is_spam === true) { + if ($f->auto_delete) { + $cur->clean(); + } else { + $cur->comment_status = -2; + $cur->comment_spam_status = $status; + $cur->comment_spam_filter = $fid; + } + return true; + } elseif ($is_spam === false) { + return false; + } + } + + return false; + } + + public function trainFilters($rs,$status,$filter_name) + { + foreach ($this->filters as $fid => $f) + { + if (!$f->active) { + continue; + } + + $type = $rs->comment_trackback ? 'trackback' : 'comment'; + $author = $rs->comment_author; + $email = $rs->comment_email; + $site = $rs->comment_site; + $ip = $rs->comment_ip; + $content = $rs->comment_content; + + $f->trainFilter($status,$filter_name,$type,$author,$email,$site,$ip,$content,$rs); + } + } + + public function statusMessage($rs,$filter_name) + { + $f = isset($this->filters[$filter_name]) ? $this->filters[$filter_name] : null; + + if ($f === null) + { + return __('Unknown filter.'); + } + else + { + $status = $rs->exists('comment_spam_status') ? $rs->comment_spam_status : null; + + return $f->getStatusMessage($status,$rs->comment_id); + } + } + + public function saveFilterOpts($opts,$global=false) + { + $this->core->blog->settings->addNamespace('antispam'); + if ($global) { + $this->core->blog->settings->antispam->drop('antispam_filters'); + } + $this->core->blog->settings->antispam->put('antispam_filters',serialize($opts),'string','Antispam Filters',true,$global); + } + + private function setFilterOpts() + { + if ($this->core->blog->settings->antispam->antispam_filters !== null) { + $this->filters_opt = @unserialize($this->core->blog->settings->antispam->antispam_filters); + } + + # Create default options if needed + if (!is_array($this->filters_opt)) { + $this->saveFilterOpts(array(),true); + $this->filters_opt = array(); + } + + foreach ($this->filters_opt as $k => $o) + { + if (isset($this->filters[$k]) && is_array($o)) { + $this->filters[$k]->active = isset($o[0])?$o[0]:false; + $this->filters[$k]->order = isset($o[1])?$o[1]:0; + $this->filters[$k]->auto_delete = isset($o[2])?$o[2]:false; + } + } + } + + private function orderCallBack($a,$b) + { + if ($a->order == $b->order) { + return 0; + } + + return $a->order > $b->order ? 1 : -1; + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/antispam/inc/lib.dc.antispam.php b/v2/dotclear/plugins/antispam/inc/lib.dc.antispam.php new file mode 100644 index 0000000..fe788a1 --- /dev/null +++ b/v2/dotclear/plugins/antispam/inc/lib.dc.antispam.php @@ -0,0 +1,211 @@ +spamfilters)) { + return; + } + + self::$filters = new dcSpamFilters($core); + self::$filters->init($core->spamfilters); + } + + public static function isSpam($cur) + { + self::initFilters(); + self::$filters->isSpam($cur); + } + + public static function trainFilters($blog,$cur,$rs) + { + $status = null; + # From ham to spam + if ($rs->comment_status != -2 && $cur->comment_status == -2) { + $status = 'spam'; + } + + # From spam to ham + if ($rs->comment_status == -2 && $cur->comment_status == 1) { + $status = 'ham'; + } + + # the status of this comment has changed + if ($status) + { + $filter_name = $rs->exists('comment_spam_filter') ? $rs->comment_spam_filter : null; + + self::initFilters(); + self::$filters->trainFilters($rs,$status,$filter_name); + } + } + + public static function statusMessage($rs) + { + if ($rs->exists('comment_status') && $rs->comment_status == -2) + { + $filter_name = $rs->exists('comment_spam_filter') ? $rs->comment_spam_filter : null; + + self::initFilters(); + + return + '

        '.__('This comment is a spam:').' '. + self::$filters->statusMessage($rs,$filter_name).'

        '; + } + } + + public static function dashboardIcon($core, $icons) + { + if (($count = self::countSpam($core)) > 0) { + $str = ($count > 1) ? __('(including %d spam comments)') : __('(including %d spam comment)'); + $icons['comments'][0] .= '
        '.sprintf($str,$count).''; + } + } + + public static function dashboardIconTitle($core) + { + if (($count = self::countSpam($core)) > 0) { + $str = ($count > 1) ? __('(including %d spam comments)') : __('(including %d spam comment)'); + return '
        '.sprintf($str,$count).''; + } else { + return ''; + } + } + + public static function countSpam($core) + { + return $core->blog->getComments(array('comment_status'=>-2),true)->f(0); + } + + public static function countPublishedComments($core) + { + return $core->blog->getComments(array('comment_status'=>1),true)->f(0); + } + + public static function delAllSpam($core, $beforeDate = null) + { + $strReq = + 'SELECT comment_id '. + 'FROM '.$core->prefix.'comment C '. + 'JOIN '.$core->prefix.'post P ON P.post_id = C.post_id '. + "WHERE blog_id = '".$core->con->escape($core->blog->id)."' ". + 'AND comment_status = -2 '; + if ($beforeDate) { + $strReq .= 'AND comment_dt < \''.$beforeDate.'\' '; + } + + $rs = $core->con->select($strReq); + $r = array(); + while ($rs->fetch()) { + $r[] = (integer) $rs->comment_id; + } + + if (empty($r)) { + return; + } + + $strReq = + 'DELETE FROM '.$core->prefix.'comment '. + 'WHERE comment_id '.$core->con->in($r).' '; + + $core->con->execute($strReq); + } + + public static function getUserCode($core) + { + $code = + pack('a32',$core->auth->userID()). + pack('H*',crypt::hmac(DC_MASTER_KEY,$core->auth->getInfo('user_pwd'))); + return bin2hex($code); + } + + public static function checkUserCode($core,$code) + { + $code = pack('H*',$code); + + $user_id = trim(@pack('a32',substr($code,0,32))); + $pwd = @unpack('H40hex',substr($code,32,40)); + + if ($user_id === false || $pwd === false) { + return false; + } + + $pwd = $pwd['hex']; + + $strReq = 'SELECT user_id, user_pwd '. + 'FROM '.$core->prefix.'user '. + "WHERE user_id = '".$core->con->escape($user_id)."' "; + + $rs = $core->con->select($strReq); + + if ($rs->isEmpty()) { + return false; + } + + if (crypt::hmac(DC_MASTER_KEY,$rs->user_pwd) != $pwd) { + return false; + } + + $permissions = $core->getBlogPermissions($core->blog->id); + + if ( empty($permissions[$rs->user_id]) ) { + return false; + } + + return $rs->user_id; + } + + public static function purgeOldSpam($core) + { + $defaultDateLastPurge = time(); + $defaultModerationTTL = '7'; + $init = false; + + // settings + $core->blog->settings->addNamespace('antispam'); + + $dateLastPurge = $core->blog->settings->antispam->antispam_date_last_purge; + if ($dateLastPurge === null) { + $init = true; + $core->blog->settings->antispam->put('antispam_date_last_purge',$defaultDateLastPurge,'integer','Antispam Date Last Purge (unix timestamp)',true,false); + $dateLastPurge = $defaultDateLastPurge; + } + $moderationTTL = $core->blog->settings->antispam->antispam_moderation_ttl; + if ($moderationTTL === null) { + $core->blog->settings->antispam->put('antispam_moderation_ttl',$defaultModerationTTL,'integer','Antispam Moderation TTL (days)',true,false); + $moderationTTL = $defaultModerationTTL; + } + + if ($moderationTTL < 0) { + // disabled + return; + } + + // we call the purge every day + if ((time()-$dateLastPurge) > (86400)) { + // update dateLastPurge + if (!$init) { + $core->blog->settings->antispam->put('antispam_date_last_purge',time(),null,null,true,false); + } + $date = date('Y-m-d H:i:s', time() - $moderationTTL*86400); + dcAntispam::delAllSpam($core, $date); + } + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/antispam/inc/lib.dc.antispam.url.php b/v2/dotclear/plugins/antispam/inc/lib.dc.antispam.url.php new file mode 100644 index 0000000..4161fb2 --- /dev/null +++ b/v2/dotclear/plugins/antispam/inc/lib.dc.antispam.url.php @@ -0,0 +1,99 @@ +auth->checkUser($user_id,null,null); + + header('Content-Type: application/xml; charset=UTF-8'); + + $title = $core->blog->name.' - '.__('Spam moderation'). ' - '; + $params = array(); + $end_url = ''; + if ($type == 'spam') { + $title .= __('Spam'); + $params['comment_status'] = -2; + $end_url = '?status=-2'; + } else { + $title .= __('Ham'); + $params['sql'] = ' AND comment_status IN (1,-1) '; + } + + echo + ''."\n". + ''."\n". + ''."\n". + ''.html::escapeHTML($title).''."\n". + ''.(DC_ADMIN_URL ? DC_ADMIN_URL.'comments.php'.$end_url : 'about:blank').''."\n". + ''."\n"; + + $rs = $core->blog->getComments($params); + $maxitems = 20; + $nbitems = 0; + + while ($rs->fetch() && ($nbitems < $maxitems)) + { + $nbitems++; + $uri = DC_ADMIN_URL ? DC_ADMIN_URL.'comment.php?id='.$rs->comment_id : 'about:blank'; + $author = $rs->comment_author; + $title = $rs->post_title.' - '.$author; + if ($type == 'spam') { + $title .= '('.$rs->comment_spam_filter.')'; + } + $id = $rs->getFeedID(); + + $content = '

        IP: '.$rs->comment_ip; + + if (trim($rs->comment_site)) { + $content .= '
        URL:
        '.$rs->comment_site.''; + } + $content .= "


        \n"; + $content .= $rs->comment_content; + + echo + ''."\n". + ' '.html::escapeHTML($title).''."\n". + ' '.$uri.''."\n". + ' '.$id.''."\n". + ' '.$rs->getRFC822Date().''."\n". + ' '.html::escapeHTML($author).''."\n". + ' '.html::escapeHTML($content).''."\n". + ''; + } + + echo "\n"; + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/antispam/index.php b/v2/dotclear/plugins/antispam/index.php new file mode 100644 index 0000000..a13eb1b --- /dev/null +++ b/v2/dotclear/plugins/antispam/index.php @@ -0,0 +1,233 @@ +getFilters(); + +$page_name = __('Antispam'); +$filter_gui = false; +$default_tab = null; + +try +{ + # Show filter configuration GUI + if (!empty($_GET['f'])) + { + if (!isset($filters[$_GET['f']])) { + throw new Exception(__('Filter does not exist.')); + } + + if (!$filters[$_GET['f']]->hasGUI()) { + throw new Exception(__('Filter has no user interface.')); + } + + $filter = $filters[$_GET['f']]; + $filter_gui = $filter->gui($filter->guiURL()); + } + + # Remove all spam + if (!empty($_POST['delete_all'])) + { + $ts = dt::str('%Y-%m-%d %H:%M:%S',$_POST['ts'],$core->blog->settings->system->blog_timezone); + + dcAntispam::delAllSpam($core,$ts); + http::redirect($p_url.'&del=1'); + } + + # Update filters + if (isset($_POST['filters_upd'])) + { + $filters_opt = array(); + $i = 0; + foreach ($filters as $fid => $f) { + $filters_opt[$fid] = array(false,$i); + $i++; + } + + # Enable active filters + if (isset($_POST['filters_active']) && is_array($_POST['filters_active'])) { + foreach ($_POST['filters_active'] as $v) { + $filters_opt[$v][0] = true; + } + } + + # Order filters + if (!empty($_POST['f_order']) && empty($_POST['filters_order'])) + { + $order = $_POST['f_order']; + asort($order); + $order = array_keys($order); + } + elseif (!empty($_POST['filters_order'])) + { + $order = explode(',',trim($_POST['filters_order'],',')); + } + + if (isset($order)) { + foreach ($order as $i => $f) { + $filters_opt[$f][1] = $i; + } + } + + # Set auto delete flag + if (isset($_POST['filters_auto_del']) && is_array($_POST['filters_auto_del'])) { + foreach ($_POST['filters_auto_del'] as $v) { + $filters_opt[$v][2] = true; + } + } + + dcAntispam::$filters->saveFilterOpts($filters_opt); + http::redirect($p_url.'&upd=1'); + } +} +catch (Exception $e) +{ + $core->error->add($e->getMessage()); +} +?> + + + <?php echo $page_name; ?> + + + + +'.html::escapeHTML($core->blog->name).' › '.$page_name.''. + ' › '.sprintf(__('%s configuration'),$filter->name).''; + + echo $filter_gui; +} +else +{ + echo '

        '.html::escapeHTML($core->blog->name).' › '.$page_name.'

        '; + + # Information + $spam_count = dcAntispam::countSpam($core); + $published_count = dcAntispam::countPublishedComments($core); + $moderationTTL = $core->blog->settings->antispam->antispam_moderation_ttl; + + echo + '
        '. + '

        '.__('Information').'

        '; + + if (!empty($_GET['del'])) { + echo '

        '.__('Spam comments have been successfully deleted.').'

        '; + } + + echo + ''; + + if ($spam_count > 0) + { + echo + '

        '.$core->formNonce(). + form::hidden('ts',time()). + '

        '; + } + if ($moderationTTL != null && $moderationTTL >=0) { + echo '

        '.sprintf(__('All spam comments older than %s day(s) will be automatically deleted.'), $moderationTTL).' '. + __('You can modify this duration in '). + ' '.__('Blog preferences').'

        '; + } + echo '
        '; + + + # Filters + echo + '
        '; + + if (!empty($_GET['upd'])) { + echo '

        '.__('Filters configuration has been successfully saved.').'

        '; + } + + echo + ''. + ''. + ''. + ''. + ''. + ''. + ''. + ''. + ''. + ''; + + $i = 0; + foreach ($filters as $fid => $f) + { + $gui_link = ' '; + if ($f->hasGUI()) { + $gui_link = + ''. + ''.__('Filter configuration').''; + } + + echo + ''. + ''. + ''. + ''. + ''. + ''. + ''. + ''; + $i++; + } + echo + '
        '.__('Available spam filters').'
        '.__('Order').''.__('Active').''.__('Auto Del.').''.__('Filter name').''.__('Description').'
        '.form::field(array('f_order['.$fid.']'),2,5,(string) $i, '', '', false, 'title="'.__('position').'"').''.form::checkbox(array('filters_active[]'),$fid,$f->active, '', '', false, 'title="'.__('Active').'"').''.form::checkbox(array('filters_auto_del[]'),$fid,$f->auto_delete, '', '', false, 'title="'.__('Auto Del.').'"').''.$f->name.''.$f->description.''.$gui_link.'
        '. + '

        '.form::hidden('filters_order',''). + $core->formNonce(). + '

        '. + '
        '; + + + # Syndication + if (DC_ADMIN_URL) + { + $ham_feed = $core->blog->url.$core->url->getURLFor( + 'hamfeed', + $code = dcAntispam::getUserCode($core) + ); + $spam_feed = $core->blog->url.$core->url->getURLFor( + 'spamfeed', + $code = dcAntispam::getUserCode($core) + ); + + echo + '

        '.__('Syndication').'

        '. + ''; + } +} +?> + + + \ No newline at end of file diff --git a/v2/dotclear/plugins/antispam/style.css b/v2/dotclear/plugins/antispam/style.css new file mode 100644 index 0000000..c93cf1a --- /dev/null +++ b/v2/dotclear/plugins/antispam/style.css @@ -0,0 +1,23 @@ +ul.spaminfo { + display: block; + list-style: none; + margin: 1em 0; + padding: 0; +} +ul.spaminfo li { + margin: 0.5em 0; + padding-left: 16px; + /*background: url(index.php?pf=antispam/feed.png) no-repeat center left;*/ + background-color: transparent; + background-position: center left; + background-repeat: no-repeat; +} +ul.spaminfo .spamcount { + background-image: url(images/junk.png); +} +ul.spaminfo .hamcount { + background-image: url(images/check-on.png); +} +ul.spaminfo .feed { + background-image: url(index.php?pf=antispam/feed.png); +} \ No newline at end of file diff --git a/v2/dotclear/plugins/attachments/_admin.php b/v2/dotclear/plugins/attachments/_admin.php new file mode 100644 index 0000000..70ca40f --- /dev/null +++ b/v2/dotclear/plugins/attachments/_admin.php @@ -0,0 +1,75 @@ +addBehavior ('adminPostFormSidebar',array('attachmentAdmin','adminPostFormSidebar')); +$core->addBehavior ('adminPostAfterForm',array('attachmentAdmin','adminPostAfterForm')); + +class attachmentAdmin +{ + public static function adminPostFormSidebar($post) + { + if ($post !== null) + { + $core =& $GLOBALS['core']; + $post_media = $core->media->getPostMedia($post->post_id); + echo + '

        '.__('Attachments').'

        '; + foreach ($post_media as $f) + { + $ftitle = $f->media_title; + if (strlen($ftitle) > 18) { + $ftitle = substr($ftitle,0,16).'...'; + } + echo + '
        '. + ''. + ''. + ''. + '
        '; + } + unset($f); + + if (empty($post_media)) { + echo '

        '.__('No attachment.').'

        '; + } else { + } + echo '

        '.__('Add files to this entry').'

        '; + } + } + + public static function adminPostAfterForm($post) { + if ($post !== null) + { + $core =& $GLOBALS['core']; + echo + '
        '. + '
        '.form::hidden(array('post_id'),$post->post_id). + form::hidden(array('media_id'),''). + form::hidden(array('remove'),1). + $core->formNonce().'
        '; + } + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/attachments/_define.php b/v2/dotclear/plugins/attachments/_define.php new file mode 100644 index 0000000..99b4d2f --- /dev/null +++ b/v2/dotclear/plugins/attachments/_define.php @@ -0,0 +1,24 @@ +registerModule( + /* Name */ "attachments", + /* Description*/ "Manage post attachments", + /* Author */ "Dotclear Team", + /* Version */ '1.0', + array( + 'permissions' => 'usage,contentadmin,pages', + 'priority' => 999 + ) +); +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/attachments/_public.php b/v2/dotclear/plugins/attachments/_public.php new file mode 100644 index 0000000..b08c450 --- /dev/null +++ b/v2/dotclear/plugins/attachments/_public.php @@ -0,0 +1,248 @@ +tpl->addBlock('Attachments',array('attachmentTpl','Attachments')); +$core->tpl->addBlock('AttachmentsHeader',array('attachmentTpl','AttachmentsHeader')); +$core->tpl->addBlock('AttachmentsFooter',array('attachmentTpl','AttachmentsFooter')); +$core->tpl->addValue('AttachmentMimeType',array('attachmentTpl','AttachmentMimeType')); +$core->tpl->addValue('AttachmentType',array('attachmentTpl','AttachmentType')); +$core->tpl->addValue('AttachmentFileName',array('attachmentTpl','AttachmentFileName')); +$core->tpl->addValue('AttachmentSize',array('attachmentTpl','AttachmentSize')); +$core->tpl->addValue('AttachmentTitle',array('attachmentTpl','AttachmentTitle')); +$core->tpl->addValue('AttachmentThumbnailURL',array('attachmentTpl','AttachmentThumbnailURL')); +$core->tpl->addValue('AttachmentURL',array('attachmentTpl','AttachmentURL')); +$core->tpl->addValue('MediaURL',array('attachmentTpl','MediaURL')); +$core->tpl->addBlock('AttachmentIf',array('attachmentTpl','AttachmentIf')); + +$core->tpl->addValue('EntryAttachmentCount',array('attachmentTpl','EntryAttachmentCount')); + +$core->addBehavior('tplIfConditions',array('attachmentBehavior','tplIfConditions')); + +class attachmentTpl { + + /*dtd + + */ + public static function Attachments($attr,$content) + { + $res = + "posts !== null && $core->media) {'."\n". + '$_ctx->attachments = new ArrayObject($core->media->getPostMedia($_ctx->posts->post_id));'."\n". + "?>\n". + + 'attachments as $attach_i => $attach_f) : '. + '$GLOBALS[\'attach_i\'] = $attach_i; $GLOBALS[\'attach_f\'] = $attach_f;'. + '$_ctx->file_url = $attach_f->file_url; ?>'. + $content. + 'attachments = null; unset($attach_i,$attach_f,$_ctx->file_url); ?>'. + + "\n"; + + return $res; + } + + /*dtd + + */ + public static function AttachmentsHeader($attr,$content) + { + return + "". + $content. + ""; + } + + /*dtd + + */ + public static function AttachmentsFooter($attr,$content) + { + return + "attachments)) : ?>". + $content. + ""; + } + + /*dtd + + + */ + public static function AttachmentIf($attr,$content) + { + $if = array(); + + $operator = isset($attr['operator']) ? $this->getOperator($attr['operator']) : '&&'; + + if (isset($attr['is_image'])) { + $sign = (boolean) $attr['is_image'] ? '' : '!'; + $if[] = $sign.'$attach_f->media_image'; + } + + if (isset($attr['has_thumb'])) { + $sign = (boolean) $attr['has_thumb'] ? '' : '!'; + $if[] = $sign.'isset($attach_f->media_thumb[\'sq\'])'; + } + + if (isset($attr['is_mp3'])) { + $sign = (boolean) $attr['is_mp3'] ? '==' : '!='; + $if[] = '$attach_f->type '.$sign.' "audio/mpeg3"'; + } + + if (isset($attr['is_flv'])) { + $sign = (boolean) $attr['is_flv'] ? '' : '!'; + $if[] = $sign. + '($attach_f->type == "video/x-flv" || '. + '$attach_f->type == "video/mp4" || '. + '$attach_f->type == "video/x-m4v")'; + } + + if (count($if) != 0) { + return ''.$content.''; + } else { + return $content; + } + } + + /*dtd + + */ + public static function AttachmentMimeType($attr) + { + $f = $GLOBALS['core']->tpl->getFilters($attr); + return 'type').'; ?>'; + } + + /*dtd + + */ + public static function AttachmentType($attr) + { + $f = $GLOBALS['core']->tpl->getFilters($attr); + return 'media_type').'; ?>'; + } + + /*dtd + + */ + public static function AttachmentFileName($attr) + { + $f = $GLOBALS['core']->tpl->getFilters($attr); + return 'basename').'; ?>'; + } + + /*dtd + + + */ + public static function AttachmentSize($attr) + { + $f = $GLOBALS['core']->tpl->getFilters($attr); + if (!empty($attr['full'])) { + return 'size').'; ?>'; + } + return 'size)').'; ?>'; + } + + /*dtd + + */ + public static function AttachmentTitle($attr) + { + $f = $GLOBALS['core']->tpl->getFilters($attr); + return 'media_title').'; ?>'; + } + + /*dtd + + */ + public static function AttachmentThumbnailURL($attr) + { + $f = $GLOBALS['core']->tpl->getFilters($attr); + return + 'media_thumb[\'sq\'])) {'. + 'echo '.sprintf($f,'$attach_f->media_thumb[\'sq\']').';'. + '}'. + '?>'; + } + + /*dtd + + */ + public static function AttachmentURL($attr) + { + $f = $GLOBALS['core']->tpl->getFilters($attr); + return 'file_url').'; ?>'; + } + + public static function MediaURL($attr) + { + $f = $GLOBALS['core']->tpl->getFilters($attr); + return 'file_url').'; ?>'; + } + + /*dtd + + + */ + public static function EntryAttachmentCount($attr) + { + $none = 'no attachment'; + $one = 'one attachment'; + $more = '%d attachments'; + + if (isset($attr['none'])) { + $none = addslashes($attr['none']); + } + if (isset($attr['one'])) { + $one = addslashes($attr['one']); + } + if (isset($attr['more'])) { + $more = addslashes($attr['more']); + } + + return + "posts->countMedia() == 0) {\n". + " printf(__('".$none."'),(integer) \$_ctx->posts->countMedia());\n". + "} elseif (\$_ctx->posts->countMedia() == 1) {\n". + " printf(__('".$one."'),(integer) \$_ctx->posts->countMedia());\n". + "} else {\n". + " printf(__('".$more."'),(integer) \$_ctx->posts->countMedia());\n". + "} ?>"; + } +} + +class attachmentBehavior +{ + public static function tplIfConditions($tag,$attr,$content,$if) + { + if ($tag == "EntryIf" && isset($attr['has_attachment'])) { + $sign = (boolean) $attr['has_attachment'] ? '' : '!'; + $if[] = $sign.'$_ctx->posts->countMedia()'; + } + } +} +?> diff --git a/v2/dotclear/plugins/blogroll/_admin.php b/v2/dotclear/plugins/blogroll/_admin.php new file mode 100644 index 0000000..cc14260 --- /dev/null +++ b/v2/dotclear/plugins/blogroll/_admin.php @@ -0,0 +1,34 @@ +addBehavior('adminDashboardIcons','blogroll_dashboard'); +$core->addBehavior('adminDashboardFavs','blogroll_dashboard_favs'); +function blogroll_dashboard($core,$icons) +{ + $icons['blogroll'] = new ArrayObject(array(__('Blogroll'),'plugin.php?p=blogroll','index.php?pf=blogroll/icon.png')); +} +function blogroll_dashboard_favs($core,$favs) +{ + $favs['blogroll'] = new ArrayObject(array('blogroll','Blogroll','plugin.php?p=blogroll', + 'index.php?pf=blogroll/icon-small.png','index.php?pf=blogroll/icon.png', + 'usage,contentadmin',null,null)); +} + +$_menu['Plugins']->addItem(__('Blogroll'),'plugin.php?p=blogroll','index.php?pf=blogroll/icon-small.png', + preg_match('/plugin.php\?p=blogroll(&.*)?$/',$_SERVER['REQUEST_URI']), + $core->auth->check('usage,contentadmin',$core->blog->id)); + +$core->auth->setPermissionType('blogroll',__('manage blogroll')); + +require dirname(__FILE__).'/_widgets.php'; +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/blogroll/_define.php b/v2/dotclear/plugins/blogroll/_define.php new file mode 100644 index 0000000..f0f6b22 --- /dev/null +++ b/v2/dotclear/plugins/blogroll/_define.php @@ -0,0 +1,23 @@ +registerModule( + /* Name */ "Blogroll", + /* Description*/ "Manage your blogroll", + /* Author */ "Olivier Meunier", + /* Version */ '1.2', + array( + 'permissions' => 'blogroll' + ) +); +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/blogroll/_install.php b/v2/dotclear/plugins/blogroll/_install.php new file mode 100644 index 0000000..b5857b1 --- /dev/null +++ b/v2/dotclear/plugins/blogroll/_install.php @@ -0,0 +1,46 @@ +plugins->moduleInfo('blogroll','version'); + +if (version_compare($core->getVersion('blogroll'),$version,'>=')) { + return; +} + +/* Database schema +-------------------------------------------------------- */ +$s = new dbStruct($core->con,$core->prefix); + +$s->link + ->link_id ('bigint', 0, false) + ->blog_id ('varchar', 32, false) + ->link_href ('varchar', 255, false) + ->link_title ('varchar', 255, false) + ->link_desc ('varchar', 255, true) + ->link_lang ('varchar', 5, true) + ->link_xfn ('varchar', 255, true) + ->link_position ('integer', 0, false, 0) + + ->primary('pk_link','link_id') + ; + +$s->link->index('idx_link_blog_id','btree','blog_id'); +$s->link->reference('fk_link_blog','blog_id','blog','blog_id','cascade','cascade'); + +# Schema installation +$si = new dbStruct($core->con,$core->prefix); +$changes = $si->synchronize($s); + +$core->setVersion('blogroll',$version); +return true; +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/blogroll/_prepend.php b/v2/dotclear/plugins/blogroll/_prepend.php new file mode 100644 index 0000000..d39e7bd --- /dev/null +++ b/v2/dotclear/plugins/blogroll/_prepend.php @@ -0,0 +1,15 @@ + \ No newline at end of file diff --git a/v2/dotclear/plugins/blogroll/_public.php b/v2/dotclear/plugins/blogroll/_public.php new file mode 100644 index 0000000..7f24029 --- /dev/null +++ b/v2/dotclear/plugins/blogroll/_public.php @@ -0,0 +1,233 @@ +tpl->addValue('Blogroll',array('tplBlogroll','blogroll')); +$core->tpl->addValue('BlogrollXbelLink',array('tplBlogroll','blogrollXbelLink')); + +$core->url->register('xbel','xbel','^xbel(?:/?)$',array('urlBlogroll','xbel')); + +class tplBlogroll +{ + public static function blogroll($attr) + { + $category='

        %s

        '; + $block='
          %s
        '; + $item='%1$s'; + + if (isset($attr['category'])) { + $category = addslashes($attr['category']); + } + + if (isset($attr['block'])) { + $block = addslashes($attr['block']); + } + + if (isset($attr['item'])) { + $item = addslashes($attr['item']); + } + + $only_cat = 'null'; + if (!empty($attr['only_category'])) { + $only_cat = "'".addslashes($attr['only_category'])."'"; + } + + return + ''; + } + + public static function blogrollXbelLink($attr) + { + $f = $GLOBALS['core']->tpl->getFilters($attr); + return 'blog->url.$core->url->getURLFor("xbel")').'; ?>'; + } + + public static function getList($cat_title='

        %s

        ',$block='
          %s
        ',$item='
      • %s
      • ',$category=null) + { + $blogroll = new dcBlogroll($GLOBALS['core']->blog); + + try { + $links = $blogroll->getLinks(); + } catch (Exception $e) { + return false; + } + + $res = ''; + + $hierarchy = $blogroll->getLinksHierarchy($links); + + if ($category) { + if (!isset($hierarchy[$category])) { + return ''; + } + $hierarchy = array($hierarchy[$category]); + } + + foreach ($hierarchy as $k => $v) + { + if ($k != '') { + $res .= sprintf($cat_title,html::escapeHTML($k))."\n"; + } + + $res .= self::getLinksList($v,$block,$item); + } + + return $res; + } + + private static function getLinksList($links,$block='
          %s
        ',$item='%1$s') + { + $list = ''; + + # Find current link item if any + $current = -1; + $current_size = 0; + $self_uri = http::getSelfURI(); + + foreach ($links as $k => $v) + { + if (!preg_match('$^([a-z][a-z0-9.+-]+://)$',$v['link_href'])) { + $url = http::concatURL($self_uri,$v['link_href']); + if (strlen($url) > $current_size && preg_match('/^'.preg_quote($url,'/').'/',$self_uri)) { + $current = $k; + $current_size = strlen($url); + } + } + } + + foreach ($links as $k => $v) + { + $title = $v['link_title']; + $href = $v['link_href']; + $desc = $v['link_desc']; + $lang = $v['link_lang']; + $xfn = $v['link_xfn']; + + $link = + ''. + html::escapeHTML($title). + ''; + + $current_class = $current == $k ? ' class="active"' : ''; + + $list .= sprintf($item,$link,$current_class)."\n"; + } + + return sprintf($block,$list)."\n"; + } + + # Widget function + public static function linksWidget($w) + { + global $core; + + if ($w->homeonly && $core->url->type != 'default') { + return; + } + + $links = self::getList('

        %s

        ','
          %s
        ','%1$s',$w->category); + + if (empty($links)) { + return; + } + + return + ''; + } +} + +class urlBlogroll extends dcUrlHandlers +{ + public static function xbel($args) + { + $blogroll = new dcBlogroll($GLOBALS['core']->blog); + + try { + $links = $blogroll->getLinks(); + } catch (Exception $e) { + self::p404(); + return; + } + + if ($args) { + self::p404(); + return; + } + + http::cache($GLOBALS['mod_files'],$GLOBALS['mod_ts']); + + header('Content-Type: text/xml; charset=UTF-8'); + + echo + ''."\n". + ''."\n". + ''."\n". + ''.html::escapeHTML($GLOBALS['core']->blog->name)." blogroll\n"; + + $i = 1; + foreach ($blogroll->getLinksHierarchy($links) as $cat_title => $links) + { + if ($cat_title != '') { + echo + ''."\n". + "".html::escapeHTML($cat_title)."\n"; + } + + foreach ($links as $k => $v) + { + $lang = $v['link_lang'] ? ' xml:lang="'.$v['link_lang'].'"' : ''; + + echo + ''."\n". + ''.html::escapeHTML($v['link_title'])."\n"; + + if ($v['link_desc']) { + echo ''.html::escapeHTML($v['link_desc'])."\n"; + } + + if ($v['link_xfn']) { + echo + "\n". + ''.$v['link_xfn']."\n". + "\n"; + } + + echo + "\n"; + } + + if ($cat_title != '') { + echo "\n"; + } + + $i++; + } + + echo + ''; + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/blogroll/_widgets.php b/v2/dotclear/plugins/blogroll/_widgets.php new file mode 100644 index 0000000..b0f54ed --- /dev/null +++ b/v2/dotclear/plugins/blogroll/_widgets.php @@ -0,0 +1,44 @@ +addBehavior('initWidgets',array('blogrollWidgets','initWidgets')); +$core->addBehavior('initDefaultWidgets',array('blogrollWidgets','initDefaultWidgets')); + +class blogrollWidgets +{ + public static function initWidgets($w) + { + $w->create('links',__('Blogroll'),array('tplBlogroll','linksWidget')); + $w->links->setting('title',__('Title:'),__('Links')); + + $br = new dcBlogroll($GLOBALS['core']->blog); + $h = $br->getLinksHierarchy($br->getLinks()); + $h = array_keys($h); + $categories = array(__('All categories') => ''); + foreach ($h as $v) { + if ($v) { + $categories[$v] = $v; + } + } + unset($br,$h); + $w->links->setting('category',__('Category'),'','combo',$categories); + + $w->links->setting('homeonly',__('Home page only'),1,'check'); + } + + public static function initDefaultWidgets($w,$d) + { + $d['extra']->append($w->links); + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/blogroll/class.dc.blogroll.php b/v2/dotclear/plugins/blogroll/class.dc.blogroll.php new file mode 100644 index 0000000..da0b8e0 --- /dev/null +++ b/v2/dotclear/plugins/blogroll/class.dc.blogroll.php @@ -0,0 +1,198 @@ +blog =& $blog; + $this->con =& $blog->con; + $this->table = $this->blog->prefix.'link'; + } + + public function getLinks($params=array()) + { + $strReq = 'SELECT link_id, link_title, link_desc, link_href, '. + 'link_lang, link_xfn, link_position '. + 'FROM '.$this->table.' '. + "WHERE blog_id = '".$this->con->escape($this->blog->id)."' "; + + if (isset($params['link_id'])) { + $strReq .= 'AND link_id = '.(integer) $params['link_id'].' '; + } + + $strReq .= 'ORDER BY link_position '; + + $rs = $this->con->select($strReq); + $rs = $rs->toStatic(); + + $this->setLinksData($rs); + + return $rs; + } + + public function getLink($id) + { + $params['link_id'] = $id; + + $rs = $this->getLinks($params); + + return $rs; + } + + public function addLink($title,$href,$desc='',$lang='', $xfn='') + { + $cur = $this->con->openCursor($this->table); + + $cur->blog_id = (string) $this->blog->id; + $cur->link_title = (string) $title; + $cur->link_href = (string) $href; + $cur->link_desc = (string) $desc; + $cur->link_lang = (string) $lang; + $cur->link_xfn = (string) $xfn; + + if ($cur->link_title == '') { + throw new Exception(__('You must provide a link title')); + } + + if ($cur->link_href == '') { + throw new Exception(__('You must provide a link URL')); + } + + $strReq = 'SELECT MAX(link_id) FROM '.$this->table; + $rs = $this->con->select($strReq); + $cur->link_id = (integer) $rs->f(0) + 1; + + $cur->insert(); + $this->blog->triggerBlog(); + } + + public function updateLink($id,$title,$href,$desc='',$lang='', $xfn='') + { + $cur = $this->con->openCursor($this->table); + + $cur->link_title = (string) $title; + $cur->link_href = (string) $href; + $cur->link_desc = (string) $desc; + $cur->link_lang = (string) $lang; + $cur->link_xfn = (string) $xfn; + + if ($cur->link_title == '') { + throw new Exception(__('You must provide a link title')); + } + + if ($cur->link_href == '') { + throw new Exception(__('You must provide a link URL')); + } + + $cur->update('WHERE link_id = '.(integer) $id. + " AND blog_id = '".$this->con->escape($this->blog->id)."'"); + $this->blog->triggerBlog(); + } + + public function updateCategory($id,$desc) + { + $cur = $this->con->openCursor($this->table); + + $cur->link_desc = (string) $desc; + + if ($cur->link_desc == '') { + throw new Exception(__('You must provide a category title')); + } + + $cur->update('WHERE link_id = '.(integer) $id. + " AND blog_id = '".$this->con->escape($this->blog->id)."'"); + $this->blog->triggerBlog(); + } + + public function addCategory($title) + { + $cur = $this->con->openCursor($this->table); + + $cur->blog_id = (string) $this->blog->id; + $cur->link_desc = (string) $title; + $cur->link_href = ''; + $cur->link_title = ''; + + if ($cur->link_desc == '') { + throw new Exception(__('You must provide a category title')); + } + + $strReq = 'SELECT MAX(link_id) FROM '.$this->table; + $rs = $this->con->select($strReq); + $cur->link_id = (integer) $rs->f(0) + 1; + + $cur->insert(); + $this->blog->triggerBlog(); + + return $cur->link_id; + } + + public function delItem($id) + { + $id = (integer) $id; + + $strReq = 'DELETE FROM '.$this->table.' '. + "WHERE blog_id = '".$this->con->escape($this->blog->id)."' ". + 'AND link_id = '.$id.' '; + + $this->con->execute($strReq); + $this->blog->triggerBlog(); + } + + public function updateOrder($id,$position) + { + $cur = $this->con->openCursor($this->table); + $cur->link_position = (integer) $position; + + $cur->update('WHERE link_id = '.(integer) $id. + " AND blog_id = '".$this->con->escape($this->blog->id)."'"); + $this->blog->triggerBlog(); + } + + + private function setLinksData($rs) + { + $cat_title = null; + while ($rs->fetch()) { + $rs->set('is_cat',!$rs->link_title && !$rs->link_href); + + if ($rs->is_cat) { + $cat_title = $rs->link_desc; + $rs->set('cat_title',null); + } else { + $rs->set('cat_title',$cat_title); + } + } + $rs->moveStart(); + } + + public function getLinksHierarchy($rs) + { + $res = array(); + + foreach ($rs->rows() as $k => $v) + { + if (!$v['is_cat']) { + $res[$v['cat_title']][] = $v; + } + } + + return $res; + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/blogroll/class.dc.importblogroll.php b/v2/dotclear/plugins/blogroll/class.dc.importblogroll.php new file mode 100644 index 0000000..a7317e3 --- /dev/null +++ b/v2/dotclear/plugins/blogroll/class.dc.importblogroll.php @@ -0,0 +1,101 @@ +_parseXBEL($data); + } + elseif (preg_match('!_parseOPML($data); + } + else { + throw new Exception(__('You need to provide a XBEL or OPML file.')); + } + } + + + protected function _parseOPML($data) + { + $xml = @simplexml_load_string($data); + if (!$xml) throw new Exception(__('File is not in XML format.')); + + $outlines = $xml->xpath("//outline"); + + $this->entries = array(); + foreach ($outlines as $outline) { + if (isset($outline['htmlUrl'])) { + $link = $outline['htmlUrl']; + } + elseif (isset($outline['url'])) { + $link = $outline['url']; + } + else continue; + $entry = new StdClass(); + $entry->link = $link; + $entry->title = (!empty($outline['title']))?$outline['title']:''; + if (empty($entry->title)) { + $entry->title = (!empty($outline['text']))?$outline['text']:$entry->link; + } + $entry->desc = (!empty($outline['description']))?$outline['description']:''; + $this->entries[] = $entry; + } + } + + protected function _parseXBEL($data) + { + $xml = @simplexml_load_string($data); + if (!$xml) throw new Exception(__('File is not in XML format.')); + + $outlines = $xml->xpath("//bookmark"); + + $this->entries = array(); + foreach ($outlines as $outline) { + if (!isset($outline['href'])) continue; + $entry = new StdClass(); + $entry->link = $outline['href']; + $entry->title = (!empty($outline->title))?$outline->title:''; + if (empty($entry->title)) { + $entry->title = $entry->link; + } + $entry->desc = (!empty($outline->desc))?$outline->desc:''; + $this->entries[] = $entry; + } + } + + + public function getAll() + { + if (!$this->entries) return null; + return $this->entries; + } + +} + +class dcImportBlogroll { + + public static function loadFile($file) + { + if (file_exists($file) && is_readable($file)) { + $importer = new linksImporter(); + $importer->parse(file_get_contents($file)); + return $importer->getAll(); + } + return false; + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/blogroll/edit.php b/v2/dotclear/plugins/blogroll/edit.php new file mode 100644 index 0000000..6a6aa39 --- /dev/null +++ b/v2/dotclear/plugins/blogroll/edit.php @@ -0,0 +1,241 @@ +getLink($id); +} catch (Exception $e) { + $core->error->add($e->getMessage()); +} + +if (!$core->error->flag() && $rs->isEmpty()) { + $core->error->add(__('No such link or title')); +} else { + $link_title = $rs->link_title; + $link_href = $rs->link_href; + $link_desc = $rs->link_desc; + $link_lang = $rs->link_lang; + $link_xfn = $rs->link_xfn; +} + +# Update a link +if (isset($rs) && !$rs->is_cat && !empty($_POST['edit_link'])) +{ + $link_title = $_POST['link_title']; + $link_href = $_POST['link_href']; + $link_desc = $_POST['link_desc']; + $link_lang = $_POST['link_lang']; + + $link_xfn = ''; + + if (!empty($_POST['identity'])) + { + $link_xfn .= $_POST['identity']; + } + else + { + if(!empty($_POST['friendship'])) { + $link_xfn .= ' '.$_POST['friendship']; + } + if(!empty($_POST['physical'])) { + $link_xfn .= ' met'; + } + if(!empty($_POST['professional'])) { + $link_xfn .= ' '.implode(' ',$_POST['professional']); + } + if(!empty($_POST['geographical'])) { + $link_xfn .= ' '.$_POST['geographical']; + } + if(!empty($_POST['family'])) { + $link_xfn .= ' '.$_POST['family']; + } + if(!empty($_POST['romantic'])) { + $link_xfn .= ' '.implode(' ',$_POST['romantic']); + } + } + + try { + $blogroll->updateLink($id,$link_title,$link_href,$link_desc,$link_lang,trim($link_xfn)); + http::redirect($p_url.'&edit=1&id='.$id.'&upd=1'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} + + +# Update a category +if (isset($rs) && $rs->is_cat && !empty($_POST['edit_cat'])) +{ + $link_desc = $_POST['link_desc']; + + try { + $blogroll->updateCategory($id,$link_desc); + http::redirect($p_url.'&edit=1&id='.$id.'&upd=1'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} + +?> + + + Blogroll + + + +'.__('Return to blogroll').'

        '; ?> + +is_cat) +{ + if (!empty($_GET['upd'])) { + echo '

        '.__('Category has been successfully updated').'

        '; + } + + echo + '
        '. + '
        '.__('Edit category').''. + + '

        '. + + form::hidden('edit',1). + form::hidden('id',$id). + $core->formNonce(). + '

        '. + '
        '. + '
        '; +} +if (isset($rs) && !$rs->is_cat) +{ + if (!empty($_GET['upd'])) { + echo '

        '.__('Link has been successfully updated').'

        '; + } + + echo + '
        '. + '
        '.__('Edit link').''. + + '

        '. + + '

        '. + + '

        '. + + '

        '. + + '

        '.form::hidden('p','blogroll'). + form::hidden('edit',1). + form::hidden('id',$id). + $core->formNonce(). + '

        '. + '
        '. + + + # XFN nightmare + '
        '.__('XFN').''. + ''. + + ''. + ''. + ''. + ''. + + ''. + ''. + ''. + ''. + + ''. + ''. + ''. + ''. + + ''. + ''. + ''. + ''. + + ''. + ''. + ''. + ''. + + ''. + ''. + ''. + ''. + + ''. + ''. + ''. + ''. + '
        '.__('_xfn_Me').'

        '.'

        '.__('_xfn_Friendship').'

        '. + ' '. + ' '. + ' '. + ''. + '

        '.__('_xfn_Physical').'

        '. + ''. + '

        '.__('_xfn_Professional').'

        '. + ' '. + ''. + '

        '.__('_xfn_Geographical').'

        '. + ' '. + ' '. + ''. + '

        '.__('_xfn_Family').'

        '. + ' '. + ' '. + ' '. + ' '. + ' '. + ''. + '

        '.__('_xfn_Romantic').'

        '. + ' '. + ' '. + ' '. + ' '. + '

        '. + + '
        '. + + '
        '; +} +?> + + \ No newline at end of file diff --git a/v2/dotclear/plugins/blogroll/icon-small.png b/v2/dotclear/plugins/blogroll/icon-small.png new file mode 100644 index 0000000000000000000000000000000000000000..935a9e475e46ec75a961f69ec4ae9754b353e517 GIT binary patch literal 1810 zcmbVNc~BE~6b^?p$e>&b=rFEPJP?vBA?7dwVw%-ut~bn;jhJ zZ##RzY#a_}D_X}7!A3jNi?_nQi-tbRu)!4-NKrAe6V=PKFpdKukuV@q$rNx1EQ8`> z@4_q`&H_?Oq^LAtBU6s3h%%E6(V)^`XdI5^YtYE#(J%@`!V0CDO&F+cAOK2;P1s5e zAO~o8aFlXgf)*Ah1WM!y(Q*bv@LdbA3`~qb1*0;+po&rJm|fr3nc5Osv*@N)(ndl0l{+fkZM%r831eWvxR);D6ls zqP0#EuYpM+unvjS%CY;{xnu^6P*R;{-$ z3D{)sKpHLy!Vexa7~QC>Aq&GRNA9rg;__6FG|9%zf-=j_s}Gf7v`e&$C#$pdk4KVi zdBJu9H)WY?Geh6P9*sy>c%E2w|BkpkKEuJEy=>fRx5~e}7GB=<X#3;evut9#?sLSMH)Bu4Ao}6 z{Or?W|1kGE?rT;wqj`mI{K7H~RTbl{4T&YXq#=*YcegpXzRu;vKji6K1_pYJ_ZZdv z^oO|zbQPOpcd4Dnmzd*^&_h!Hn8+$?Hq4#XURN`6VMWfo1E}$LlBLHiNMO8}5$n@& z>v{IFwrwtsh4^$yx}PPv_y)Yzg>pS)P`=$4y>^=WA)kU5mYNST7$Km9Q?92&SVa!HIYjdQ-EIHKcRNc+ooQ?ut z>$7IARV0oB4griZ#$1m-#YeL;?5qOkzq$F)EsWmH-Qvb0wm0n(7=N-pKEOT3mh|r* zn`~9y5>tO((DW?FBWM4I{$qZg5y-6aHmfqb9S6gf9-h+`4!L}v*tzXW-pVNPOODK8 zBy}V-=|yI*tFU#e;!y7JpySD^%qM$%hE;`+>urzID__~Kt2|UBc+)gV2+F_V>|Xig z?W(TV$Te24MNqfYeghH#nQf+Aup4f&=F1P+xpf;GLVJfjJ-^*O&niWp;W+WyRuSK4 zk#j#~fpwMaba?$@rywH1MPy(hc~yBQBARjwqFDG-=freR^HEX7%kX!@hr6FjQ+Cal zHq^gpt8VQsI5G8?5(xtN7r8sq{|0Z*!R7z} literal 0 HcmV?d00001 diff --git a/v2/dotclear/plugins/blogroll/icon.png b/v2/dotclear/plugins/blogroll/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..bc426a44f2d7803a8c60e60d0239ecf3f4db7ebe GIT binary patch literal 7485 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 + +if (!empty($_REQUEST['edit']) && !empty($_REQUEST['id'])) { + include dirname(__FILE__).'/edit.php'; + return; +} + +$default_tab = ''; +$link_title = $link_href = $link_desc = $link_lang = ''; +$cat_title = ''; + +# Import links +if (!empty($_POST['import_links']) && !empty($_FILES['links_file'])) +{ + $default_tab = 'import-links'; + + try + { + files::uploadStatus($_FILES['links_file']); + $ifile = DC_TPL_CACHE.'/'.md5(uniqid()); + if (!move_uploaded_file($_FILES['links_file']['tmp_name'],$ifile)) { + throw new Exception(__('Unable to move uploaded file.')); + } + + require_once dirname(__FILE__).'/class.dc.importblogroll.php'; + try { + $imported = dcImportBlogroll::loadFile($ifile); + @unlink($ifile); + } catch (Exception $e) { + @unlink($ifile); + throw $e; + } + + + if (empty($imported)) { + unset($imported); + throw new Exception(__('Nothing to import')); + } + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} + +if (!empty($_POST['import_links_do'])) { + foreach ($_POST['entries'] as $idx) { + $link_title = $_POST['title'][$idx]; + $link_href = $_POST['url'][$idx]; + $link_desc = $_POST['desc'][$idx]; + try { + $blogroll->addLink($link_title,$link_href,$link_desc,''); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + $default_tab = 'import-links'; + } + } + http::redirect($p_url.'&importlinks=1'); +} + +if (!empty($_POST['cancel_import'])) { + $core->error->add(__('Import operation cancelled.')); + $default_tab = 'import-links'; +} + +# Add link +if (!empty($_POST['add_link'])) +{ + $link_title = $_POST['link_title']; + $link_href = $_POST['link_href']; + $link_desc = $_POST['link_desc']; + $link_lang = $_POST['link_lang']; + + try { + $blogroll->addLink($link_title,$link_href,$link_desc,$link_lang); + http::redirect($p_url.'&addlink=1'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + $default_tab = 'add-link'; + } +} + +# Add category +if (!empty($_POST['add_cat'])) +{ + $cat_title = $_POST['cat_title']; + + try { + $blogroll->addCategory($cat_title); + http::redirect($p_url.'&addcat=1'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + $default_tab = 'add-cat'; + } +} + +# Delete link +if (!empty($_POST['removeaction']) && !empty($_POST['remove'])) { + foreach ($_POST['remove'] as $k => $v) + { + try { + $blogroll->delItem($v); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + break; + } + } + + if (!$core->error->flag()) { + http::redirect($p_url.'&removed=1'); + } +} + +# Order links +$order = array(); +if (empty($_POST['links_order']) && !empty($_POST['order'])) { + $order = $_POST['order']; + asort($order); + $order = array_keys($order); +} elseif (!empty($_POST['links_order'])) { + $order = explode(',',$_POST['links_order']); +} + +if (!empty($_POST['saveorder']) && !empty($order)) +{ + foreach ($order as $pos => $l) { + $pos = ((integer) $pos)+1; + + try { + $blogroll->updateOrder($l,$pos); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } + } + + if (!$core->error->flag()) { + http::redirect($p_url.'&neworder=1'); + } +} + + +# Get links +try { + $rs = $blogroll->getLinks(); +} catch (Exception $e) { + $core->error->add($e->getMessage()); +} + +?> + + + <?php echo __('Blogroll'); ?> + + + auth->user_prefs->addWorkspace('accessibility'); + $user_dm_nodragdrop = $core->auth->user_prefs->accessibility->nodragdrop; + ?> + + + + + + + +

        blog->name); ?> ›

        + +'.__('Items order has been successfully updated').'

        '; +} + +if (!empty($_GET['removed'])) { + echo '

        '.__('Items have been successfully removed.').'

        '; +} + +if (!empty($_GET['addlink'])) { + echo '

        '.__('Link has been successfully created.').'

        '; +} + +if (!empty($_GET['addcat'])) { + echo '

        '.__('category has been successfully created.').'

        '; +} + +if (!empty($_GET['importlinks'])) { + echo '

        '.__('links have been successfully imported.').'

        '; +} +?> + +
        + +
        + +'. +''. +'
        '; + +echo +'
        '. +'
        '. +'
        '.__('Add a new category').''. +'

        '. +form::hidden(array('p'),'blogroll'). +$core->formNonce(). +'

        '. +'
        '. +'
        '. +'
        '; + +echo +''; + +dcPage::helpBlock('blogroll'); +?> + + + \ No newline at end of file diff --git a/v2/dotclear/plugins/blogroll/locales/en/help/blogroll.html b/v2/dotclear/plugins/blogroll/locales/en/help/blogroll.html new file mode 100644 index 0000000..b1eeb8f --- /dev/null +++ b/v2/dotclear/plugins/blogroll/locales/en/help/blogroll.html @@ -0,0 +1,41 @@ + + + Blogroll + + + + +

        Blogroll

        +

        Blogroll allows you to display on your blog a list of links to other blogs or websites that +you wish to suggest to your visitors.

        +
        +
        Links
        +
        Here are displayed your links and categories. Categories are displayed in bold characters. + You can reorder this list by dragging its items upwards or downwards. Once done, clic on "save order". + The order chosen here will be applied to links displayed on the blog with the Blogroll widget. + Clic on a link or category to edit it.
        + +
        Delete selected links
        +
        Allows you to delete links or categories by checking the boxes next to each of them.
        + +
        Add a new link
        +
        +
          +
        • Title : Type here the anchor text. For example "Jules and Julie". This field is mandatory.
        • +
        • URL : Type here the link's destination. It must begin with http://. This field is mandatory.
        • +
        • Description : Type here a short description for the link (will be displayed in a tooltip). For example "Jules and Julie world trip".
        • +
        • Language : Type here a two characters code for the destination language (for example en for english).
        • +
        +
        + + +
        Add a category
        +
        Links categories allow you to classify links diplayed by the Blogroll widget. They are displayed in bold characters. + Type here the category's name.
        + +
        Import links
        +
        This option allows you to import links from an OPML or XBEL file.
        + +
        + + \ No newline at end of file diff --git a/v2/dotclear/plugins/blogroll/locales/en/resources.php b/v2/dotclear/plugins/blogroll/locales/en/resources.php new file mode 100644 index 0000000..f690ced --- /dev/null +++ b/v2/dotclear/plugins/blogroll/locales/en/resources.php @@ -0,0 +1,18 @@ + \ No newline at end of file diff --git a/v2/dotclear/plugins/blogroll/locales/fr/help/blogroll.html b/v2/dotclear/plugins/blogroll/locales/fr/help/blogroll.html new file mode 100644 index 0000000..0d48812 --- /dev/null +++ b/v2/dotclear/plugins/blogroll/locales/fr/help/blogroll.html @@ -0,0 +1,38 @@ + + + Liens + + + + +

        Liens

        +

        La gestion des liens vous permet d'afficher sur votre blog un "blogroll" ou liste de liens vers d'autres blogs ou sites que vous souhaitez porter à l'attention de vos visiteurs.

        +
        +
        Liens
        +
        Sur cet onglet s'affichent les liens que vous avez ajoutés, ainsi que les catégories de lien que vous avez créées. Les catégories apparaissent en gras. Vous pouvez réordonner votre liste en cliquant sur les flèches bleues à gauche et en faisant glisser le lien vers le haut ou vers le bas afin de le placer à l'endroit désiré. Une fois vos liens ordonnés, cliquez sur "enregistrer l'ordre" afin d'appliquer les changements. L'ordre que vous choisissez sur cet écran sera l'ordre dans lequel s'afficheront les liens sur vos bandeaux de navigation par le biais du widget 'liens'.
        +Cliquer sur un lien vous mènera à sa fenêtre d'édition
        + +
        Supprimer les liens sélectionnés
        +
        Vous permet de supprimer les liens que vous avez sélectionnés au moyen de la case à cocher à gauche de chaque lien.
        + +
        Ajouter un lien
        +
        +
          +
        • Titre : Entrez ici le texte que vous voulez afficher sur votre blog. Par exemple "Jules et Julie". Ce champ est obligatoire.
        • +
        • URL : Saisissez ici l'adresse du lien. L'url doit commencer avec http://. Ce champ est obligatoire.
        • +
        • Description : Saisissez ici une courte description du lien (permet l'affichage d'info-bulles par survol de la souris). Par exemple "Le blog du voyage de Jules et Julie à travers le monde".
        • +
        • Langue : Saisissez ici le code à deux lettres de la langue du lien (par exemple fr pour le français).
        • +
        +
        + + +
        Ajouter une catégorie
        +
        Il s'agit là de catégories de liens, qui vous permettent d'agencer l'affichage de vos liens par le biais du widget "Liens". + Les catégories s'affichent en gras dans la liste.Saisissez le titre de la catégorie. Par exemple "Blogs des copains"
        + +
        Importer des liens
        +
        Permet d'importer des liens à partir d'un fichier externe au format OPML (format des listes de flux RSS) ou XBEL (format de partage de marque-pages ou favoris).
        + +
        + + \ No newline at end of file diff --git a/v2/dotclear/plugins/blogroll/locales/fr/resources.php b/v2/dotclear/plugins/blogroll/locales/fr/resources.php new file mode 100644 index 0000000..f690ced --- /dev/null +++ b/v2/dotclear/plugins/blogroll/locales/fr/resources.php @@ -0,0 +1,18 @@ + \ No newline at end of file diff --git a/v2/dotclear/plugins/blowupConfig/_admin.php b/v2/dotclear/plugins/blowupConfig/_admin.php new file mode 100644 index 0000000..193844a --- /dev/null +++ b/v2/dotclear/plugins/blowupConfig/_admin.php @@ -0,0 +1,26 @@ +addBehavior('adminCurrentThemeDetails','blowup_config_details'); + +if (!isset($__resources['help']['blowupConfig'])) { + $__resources['help']['blowupConfig'] = dirname(__FILE__).'/help.html'; +} + +function blowup_config_details($core,$id) +{ + if ($id == 'default' && $core->auth->check('admin',$core->blog->id)) { + return '

        '.__('Theme configuration').'

        '; + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/blowupConfig/_define.php b/v2/dotclear/plugins/blowupConfig/_define.php new file mode 100644 index 0000000..4cb2b9c --- /dev/null +++ b/v2/dotclear/plugins/blowupConfig/_define.php @@ -0,0 +1,23 @@ +registerModule( + /* Name */ "Blowup Config", + /* Description*/ "Configure your Blowup Theme", + /* Author */ "Olivier Meunier", + /* Version */ '1.1', + array( + 'permissions' => 'admin' + ) +); +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/blowupConfig/_install.php b/v2/dotclear/plugins/blowupConfig/_install.php new file mode 100644 index 0000000..9fb9499 --- /dev/null +++ b/v2/dotclear/plugins/blowupConfig/_install.php @@ -0,0 +1,25 @@ +plugins->moduleInfo('blowupConfig','version'); +if (version_compare($core->getVersion('blowupConfig'),$version,'>=')) { + return; +} + +$settings = new dcSettings($core,null); +$settings->addNamespace('themes'); +$settings->themes->put('blowup_style','','string','Blow Up custom style',false); + +$core->setVersion('blowupConfig',$version); +return true; +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/blowupConfig/_public.php b/v2/dotclear/plugins/blowupConfig/_public.php new file mode 100644 index 0000000..ad7967a --- /dev/null +++ b/v2/dotclear/plugins/blowupConfig/_public.php @@ -0,0 +1,196 @@ +blog->settings->system->theme != 'default') { + return; +} + +require dirname(__FILE__).'/lib/class.blowup.config.php'; +$core->addBehavior('publicHeadContent',array('tplBlowupTheme','publicHeadContent')); + +class tplBlowUpTheme +{ + public static function publicHeadContent($core) + { + echo '\n"; + } + + public static function blowUpStyleHelper() + { + $s = $GLOBALS['core']->blog->settings->themes->blowup_style; + + if ($s === null) { + return; + } + + $s = @unserialize($s); + if (!is_array($s)) { + return; + } + + $css = array(); + + /* Sidebar position + ---------------------------------------------- */ + if ($s['sidebar_position'] == 'left') { + $css['#wrapper']['background-position'] = '-300px 0'; + $css['#main']['float'] = 'right'; + $css['#sidebar']['float'] = 'left'; + } + + /* Properties + ---------------------------------------------- */ + self::prop($css,'body','background-color',$s['body_bg_c']); + + self::prop($css,'body','color',$s['body_txt_c']); + self::prop($css,'.post-tags li a:link, .post-tags li a:visited, .post-info-co a:link, .post-info-co a:visited','color',$s['body_txt_c']); + self::prop($css,'#page','font-size',$s['body_txt_s']); + self::prop($css,'body','font-family',blowupConfig::fontDef($s['body_txt_f'])); + + self::prop($css,'.post-content, .post-excerpt, #comments dd, #pings dd, dd.comment-preview','line-height',$s['body_line_height']); + + if (!$s['blog_title_hide']) + { + self::prop($css,'#top h1 a','color',$s['blog_title_c']); + self::prop($css,'#top h1','font-size',$s['blog_title_s']); + self::prop($css,'#top h1','font-family',blowupConfig::fontDef($s['blog_title_f'])); + + if ($s['blog_title_a'] == 'right' || $s['blog_title_a'] == 'left') { + $css['#top h1'][$s['blog_title_a']] = '0px'; + $css['#top h1']['width'] = 'auto'; + } + + if ($s['blog_title_p']) + { + $_p = explode(':',$s['blog_title_p']); + $css['#top h1']['top'] = $_p[1].'px'; + if ($s['blog_title_a'] != 'center') { + $_a = $s['blog_title_a'] == 'right' ? 'right' : 'left'; + $css['#top h1'][$_a] = $_p[0].'px'; + } + } + } + else + { + self::prop($css,'#top h1 span','text-indent','-5000px'); + self::prop($css,'#top h1','top','0px'); + $css['#top h1 a'] = array( + 'display' => 'block', + 'height' => $s['top_height'] ? ($s['top_height']-10).'px' : '120px', + 'width' => '800px' + ); + } + self::prop($css,'#top','height',$s['top_height']); + + self::prop($css,'.day-date','color',$s['date_title_c']); + self::prop($css,'.day-date','font-family',blowupConfig::fontDef($s['date_title_f'])); + self::prop($css,'.day-date','font-size',$s['date_title_s']); + + self::prop($css,'a','color',$s['body_link_c']); + self::prop($css,'a:visited','color',$s['body_link_v_c']); + self::prop($css,'a:hover, a:focus, a:active','color',$s['body_link_f_c']); + + self::prop($css,'#comment-form input, #comment-form textarea','color',$s['body_link_c']); + self::prop($css,'#comment-form input.preview','color',$s['body_link_c']); + self::prop($css,'#comment-form input.preview:hover','background',$s['body_link_f_c']); + self::prop($css,'#comment-form input.preview:hover','border-color',$s['body_link_f_c']); + self::prop($css,'#comment-form input.submit','color',$s['body_link_c']); + self::prop($css,'#comment-form input.submit:hover','background',$s['body_link_f_c']); + self::prop($css,'#comment-form input.submit:hover','border-color',$s['body_link_f_c']); + + self::prop($css,'#sidebar','font-family',blowupConfig::fontDef($s['sidebar_text_f'])); + self::prop($css,'#sidebar','font-size',$s['sidebar_text_s']); + self::prop($css,'#sidebar','color',$s['sidebar_text_c']); + + self::prop($css,'#sidebar h2','font-family',blowupConfig::fontDef($s['sidebar_title_f'])); + self::prop($css,'#sidebar h2','font-size',$s['sidebar_title_s']); + self::prop($css,'#sidebar h2','color',$s['sidebar_title_c']); + + self::prop($css,'#sidebar h3','font-family',blowupConfig::fontDef($s['sidebar_title2_f'])); + self::prop($css,'#sidebar h3','font-size',$s['sidebar_title2_s']); + self::prop($css,'#sidebar h3','color',$s['sidebar_title2_c']); + + self::prop($css,'#sidebar ul','border-top-color',$s['sidebar_line_c']); + self::prop($css,'#sidebar li','border-bottom-color',$s['sidebar_line_c']); + self::prop($css,'#topnav ul','border-bottom-color',$s['sidebar_line_c']); + + self::prop($css,'#sidebar li a','color',$s['sidebar_link_c']); + self::prop($css,'#sidebar li a:visited','color',$s['sidebar_link_v_c']); + self::prop($css,'#sidebar li a:hover, #sidebar li a:focus, #sidebar li a:active','color',$s['sidebar_link_f_c']); + self::prop($css,'#search input','color',$s['sidebar_link_c']); + self::prop($css,'#search .submit','color',$s['sidebar_link_c']); + self::prop($css,'#search .submit:hover','background',$s['sidebar_link_f_c']); + self::prop($css,'#search .submit:hover','border-color',$s['sidebar_link_f_c']); + + self::prop($css,'.post-title','color',$s['post_title_c']); + self::prop($css,'.post-title a, .post-title a:visited','color',$s['post_title_c']); + self::prop($css,'.post-title','font-family',blowupConfig::fontDef($s['post_title_f'])); + self::prop($css,'.post-title','font-size',$s['post_title_s']); + + self::prop($css,'#comments dd','background-color',$s['post_comment_bg_c']); + self::prop($css,'#comments dd','color',$s['post_comment_c']); + self::prop($css,'#comments dd.me','background-color',$s['post_commentmy_bg_c']); + self::prop($css,'#comments dd.me','color',$s['post_commentmy_c']); + + self::prop($css,'#prelude, #prelude a','color',$s['prelude_c']); + + self::prop($css,'#footer p','background-color',$s['footer_bg_c']); + self::prop($css,'#footer p','color',$s['footer_c']); + self::prop($css,'#footer p','font-size',$s['footer_s']); + self::prop($css,'#footer p','font-family',blowupConfig::fontDef($s['footer_f'])); + self::prop($css,'#footer p a','color',$s['footer_l_c']); + + /* Images + ------------------------------------------------------ */ + self::backgroundImg($css,'body',$s['body_bg_c'],'body-bg.png'); + self::backgroundImg($css,'body',$s['body_bg_g'] != 'light','body-bg.png'); + self::backgroundImg($css,'body',$s['prelude_c'],'body-bg.png'); + self::backgroundImg($css,'#top',$s['body_bg_c'],'page-t.png'); + self::backgroundImg($css,'#top',$s['body_bg_g'] != 'light','page-t.png'); + self::backgroundImg($css,'#top',$s['uploaded'] || $s['top_image'],'page-t.png'); + self::backgroundImg($css,'#footer',$s['body_bg_c'],'page-b.png'); + self::backgroundImg($css,'#comments dt',$s['post_comment_bg_c'],'comment-t.png'); + self::backgroundImg($css,'#comments dd',$s['post_comment_bg_c'],'comment-b.png'); + self::backgroundImg($css,'#comments dt.me',$s['post_commentmy_bg_c'],'commentmy-t.png'); + self::backgroundImg($css,'#comments dd.me',$s['post_commentmy_bg_c'],'commentmy-b.png'); + + $res = ''; + foreach ($css as $selector => $values) { + $res .= $selector." {\n"; + foreach ($values as $k => $v) { + $res .= $k.':'.$v.";\n"; + } + $res .= "}\n"; + } + + $res .= $s['extra_css']; + + return $res; + } + + protected static function prop(&$css,$selector,$prop,$value) + { + if ($value) { + $css[$selector][$prop] = $value; + } + } + + protected static function backgroundImg(&$css,$selector,$value,$image) + { + $file = blowupConfig::imagesPath().'/'.$image; + if ($value && file_exists($file)){ + $css[$selector]['background-image'] = 'url('.blowupConfig::imagesURL().'/'.$image.')'; + } + } +} +?> diff --git a/v2/dotclear/plugins/blowupConfig/alpha-img/comment-b.png b/v2/dotclear/plugins/blowupConfig/alpha-img/comment-b.png new file mode 100644 index 0000000000000000000000000000000000000000..b1d37c6decab7eed6f600371942c8fb8e0088cfb GIT binary patch literal 1328 zcmcIkO=uHA7~N{EHCn_XA|f)Zd+^ZB>~7MgSvIL{(w|5ZN)s@8a6U+G~M)PpUZY46^rg_vxSVJ}xg92)%P)J*srYTtRER6sz$S62XX0MZG*vEIj)6#AH&6*f+bk)t9sFl~jjHLjpw|+% z?&VJDtyUh$rtSNI$Tvg}GRfBX;92_nD5sLcxtSxI8y)G+;nSDbA>y7rSPl1PKFgQ5 z`^;Tt?aRwMTxy%| qQ*MQpUa!xhbe;R<=3l*-z4@bS(|P=joH&%HX_?e$Ci#5i#_c~8c3(LF literal 0 HcmV?d00001 diff --git a/v2/dotclear/plugins/blowupConfig/alpha-img/comment-t.png b/v2/dotclear/plugins/blowupConfig/alpha-img/comment-t.png new file mode 100644 index 0000000000000000000000000000000000000000..b320da374aaa3d423feab93f4c1b137606e3b95a GIT binary patch literal 1549 zcmeAS@N?(olHy`uVBq!ia0y~yVEh7POLDLQ$>Y^`l7JLTv6E*A2N2Y7q;vrJoCO|{ z#S9GGLLkg|>2BR0prA~NYeY$Kep*R+Vo@rCV@iHfs)Ac)QEGX9QFgI{bFlG@Yi`Uy zbz&fO&PAz-C7Jno3L%-fsSF0D`UXb&1{N>OJL-V834&Ba`1)8S=jZArf(+8D$Sq*7 zv9BmdOwLX%QAkQn&&;z`QczG(QpilPRSGxtHSjHPPR+>ls47YguJQ{>uF6ifOi{A8 zg`H`7rFPApOIO3YI*GFLD%FaQ!pR)&UFCWb)AfPs=77m&6oN=dT{ za&d#&3FO%-Wt5Z@Sn2DRmzV368|&p4rRy77T3Uj9Ze*kjRH0j3nOBlnp_^B%3^4>| zj!SBBa#3ahIJ`jSCMM;Vme?vOfh>XpsOJ(3;1=Z-Ljw;OjQSOc1^R}12KsQ5ff{Xq zf>z*|$S(@X&(E>L5@|LdohXVBwj%VWx+IpQ+5yAELf61Z*T6Ky(A)}$Oe~|2^g|S( zY4^=f$xN$6*KTBJWn^MyUb)jCk(It(eyqz{=dq!{4;mK6qS>Hy|0Uo9slVX@j=IP(p;(Qk2%|a@>+OKN;!V4G~&7WLj|Cy z^z`lLxF4v1SzFI>Ka2z#XRen%SNu?~if2;HvCDgyWK=zc9>1MiI3v7aF;HyJUjNTt zK;u1owtqEQ&(RGO`g2{9f5%ZH&q+@nZFnHYZ}EHjM}O^Uo|9Cw_xKVF#ttuHS4bo4<_D$uph5)M`t%mPYATJZKwR`E3BJ`U7%`@6X1$F;AXu5Nz@ QERq>KUHx3vIVCg!0MY@?hX4Qo literal 0 HcmV?d00001 diff --git a/v2/dotclear/plugins/blowupConfig/alpha-img/gradient-d.png b/v2/dotclear/plugins/blowupConfig/alpha-img/gradient-d.png new file mode 100644 index 0000000000000000000000000000000000000000..74bf9cfbd6ccab96707908bb980714fb9389325d GIT binary patch literal 1432 zcmcIkO-vI(6ke5RsbC@p62-%0jq#xE{M`rLoaV z?e3Fqf*{&s!_jd(v$(%;9meC@+FgXF7IPq$bYZ*gl5D(h)rW7G1aY*(=?BW+XST4j z6AezFhyev8Ybr>}3MA-mie@RgcOziWV8kg0ki{>)mlWu18=-9xfU% zQ5;Q*#jF^V$iA?fw>V5zAQFJ3L^J~eznAfd zw9gOxJzh4z1_M3kK|(-aL{I@604z=8f#n#6^E0@ZijiSAo_Rw`apTdUT28zRkr{+^ zj-vAUyf^RjYDSu3g2AAp5X*Wn!ebUxBv>BRJY5a49VZG+(UA3uu1;KGN}EO@l5`T) zt#&v;uP0K?ns``7$`W*n@zPX1GA8oa$yIJlGm@H?3;*Lvc!#+I)X3W4!>E8@80*pN zp;-^zon!(WZvNoSCVmyPiyqe`IaSy}XM9P<&-ntl)#y#28l9&cA)17#sP3F;mmlmQ zm?YNq(x;7Ff;p%_6`5EwW~XM7$fYzx5l~oGgfygdHO*5E=YQ*~R*jzpewI}I zU2d0Nzsh}CG<4sW@YSIEndC=e#E(Cb&#`EK()#vm{dMai-PW>5@wa}THJ+Cjmdf&M z*ywX*g+py<8ZrGXoHP+UJt6w%(T?d=(ajv+T{RHkTzQxBQ NVuPd6R|As|{sQz3b~^w7 literal 0 HcmV?d00001 diff --git a/v2/dotclear/plugins/blowupConfig/alpha-img/gradient-l.png b/v2/dotclear/plugins/blowupConfig/alpha-img/gradient-l.png new file mode 100644 index 0000000000000000000000000000000000000000..c39567946ea756bcc4a7760c21489c6d251bb4be GIT binary patch literal 1443 zcmcIkOK1~O6dkpeHnj^~h!l~>v`druWZE=Cl75n=Nj0T3BgTT@bmk?QCiCgcluScy ztE+V3Mrx}IcY@eLLDapAf*`sn8iHUqx^ScJ{2}O@B+aLYy6NT3`&`bs_r7xMdJjf5uAN~7;_TPvE2#U&FhEyi$^YeTlsCKk}SU5i{YFs$Q*{T<6uI5B1Kb|&C zjU|X&F6YX*U8 zz01AQYppzxO-}Hr%bOdY(%M#9AN(&{3_4nB_MVC46A#vAUPgMjb59!i3jyoV=Gu)?A(XA5?ag-l zYe)O*N$1LoQeo!Wa+7^qICU!$*$(&6Lifhe!?x|T-n=s!EKU*P=c~-UjUSi0h8nXB Z;%9b+*;k?Ot4rvnSaf7Ov^9L?`fu~~fRg|K literal 0 HcmV?d00001 diff --git a/v2/dotclear/plugins/blowupConfig/alpha-img/gradient-m.png b/v2/dotclear/plugins/blowupConfig/alpha-img/gradient-m.png new file mode 100644 index 0000000000000000000000000000000000000000..b25c6bafd5a507ba4fa37b744097067b493d8d81 GIT binary patch literal 1446 zcmcIkOHUI~6dogDEolsx5MMDjW8%to9vvv1wB^yE4`LB$4amYc%-oi-org2Gb|3^3 zU5E=Y#tjQ&+?%i`a}ojvsHr#b=!t0I*Dpl zJ)CIN5@}XdJS-z+iw4E`XsQ+&6GPa^mv2lrGrC@g{NYMM4)YMGp0&=0f{0)Q>(S+< zSufp@VFEmETyVUBUjZGVr*v7#P935%{tUzM{s3-OdIP9R4^fT~4Z@UFcg}Rg5B?#T zEYjh_X6mQ?Ls z9+Y0Y%41p7bw8Hym7vF&=Yq7dw73-*zO{1Y*+ucdJCi`G_%WjKS zQG|Mx`l4XZO|_niAbRLg4?TG3K@>gJB9sbVdvG>MleQE+b=aN9&-Z=*Ki>@VXfWO1 z;yL310JJ0r5<>tqK{9u{kC5I~m|Y~pVWTIRb(416El!hlvo>(m0N~gu=XZVnHnl~9 zXU*ObGo$8Bi`Oye7S&M<`y?G(s$Mi;JmY`9+Sf#IryX2e$Gj=23d~9}26Pb7ETY@j zL(@|v+ers8lDfhPs_f$(A)hU4Akt}Tyimj@9K{7miBb?k3QA&>$^}z&N{iz$X<$;v znaOlkm@Eomk?M?jA~r|JGB$Z=%O%C&>?l>yyv!?*4MCQsNyl;w!vz>pOr=pV4;dr6nCFHPeYKoq6{W^Z zQ{xb_EX!y4eX3qSOgJ2NcFwY1g76v>ipkqv#kf!v+15#5L(nCy;+Lb#kE-Kll%kwO z^;X*)uhkPNM$J58BeHo7F+LjAl?gFIf?VY!R6VPzrPw})7IB!nK#i;oK2Go^juAiF zy)^5kgIOlTkuMOwwu4^mizjuAVIskrX!X-^#f$1qW- z`=yQRrOL600>ULMW5qOxXUuNTM1jkzy3Cs~N#+X}X-Xl28o__oSFM^{3vw+{{a$XD zUO&nMnKXPq5c#U;K_+?p>g^nPKCEP-J8Qc(mY3xRgD1L{H`bqZ&Cm2)oat&tpUw}p zJ}rIJW?#&&5a>%Qy>t|S-|z2~y#U<%DgRmE4gp}VFn7ztH(UUG-7K$eJ#c``%FwZf379IFJNFnNOWOiV+57EBu&~1!PL|Fems5Od+)w`zNgityW{Dr zX#l`@dA_s^Knn78dL+fiE&T2~pHlHm*&ZDo{jz`W8{eL*F50sP2M2q5d%MLggImVJ z`PCSJ^B2W8^6BftUjUrFz-Cw2N@dY>sIOp`t`jBkLtsrMA$D4X!FAH~g1iJFl%VJ4 zrTY^VwGtM|hBv(tNfe zw_z@q=K3-DE-!5`7McikIvu5xQE1denqe47)se2t93jWs0mF$L#5a0Q4*ir!>_lG3 zJQ_gZ7q8PzmX{ovBI(=}T)Ol^{j z+NU1@_30K8LL3pMtGYPT3H$#9bDe=+;bzqCUW@A>(k4C$Sj;ukj%(&RW`jmPW(Cj3 zO@hLpX`!LD9^IX%rFcRoJ;&0mab;&G_a2J7I6 zfWK7itIu=d1-dM7-QpI%jqUjaWK^W)cz>~9dCd`5%B5-h=5uH5&6%~gPpQ_ literal 0 HcmV?d00001 diff --git a/v2/dotclear/plugins/blowupConfig/alpha-img/page-t/animals.png b/v2/dotclear/plugins/blowupConfig/alpha-img/page-t/animals.png new file mode 100644 index 0000000000000000000000000000000000000000..4db1e880b28da32d9aa1204aaaa1973245713897 GIT binary patch literal 28044 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 X)1FU#uRCTg8bDoHN2yZLI`sbl`^Pc) literal 0 HcmV?d00001 diff --git a/v2/dotclear/plugins/blowupConfig/alpha-img/page-t/blank.png b/v2/dotclear/plugins/blowupConfig/alpha-img/page-t/blank.png new file mode 100644 index 0000000000000000000000000000000000000000..18ae6e8e9783b2ba9f724dce0cbe89b9df220e16 GIT binary patch literal 1892 zcmcIkOK1~87@j_mSgBYkiVtvDPol{_k~Ynn#A?&@K~riIwALQF-JP~;lHFx@HEF3* ztAh0+h@c>%;#Ix$;z7k;dh?*5hho8#52_#tMZtsrY|?F4ieB1*o&DyY|NH0r|9MRJ zbhp*k?5;rw)poQedJ(F^fTw($pnuWzXdC>htz#V-AG8Udauvp#jrLO(LR+@euj0+Z zh2LP@Yq$2piNzS>#1sKjGs|Gd#m>fQtK#+{Oe zg)kO44mv^Pc`?L;7^gAu8u&*|WmxP@B+F~UD8`K1wjr`?p->1Ef&tweVfjcT!g2yD z2!8PJTVt9n75$pEzZ7ISPJ&pnsT#JbYnaBBhV-*`jA7_PZYw7z8SX-wRW2Tsku6FF z%Lh2tjSR#n7{wNoNVaZfbUhbeV@slx>2X?Fb%jq7l1<`Jk0w7S`1xRlZxFeV$Z`Fv z_$8;m=qX)MhsRdYLw+Gd=|P}}%k))FWqOpQg;-S>r|LAPzwG}jm?FFNGR~SgXIm7R zB{`BOnr%VNcyG-VSsd2Qyky7Kyfi{sLmP>*E5?87E2)NK0mqVc&*idocPlpptkiu& z!k2<>*07dmV|Rnd1Dn_p`NA&GoIX z4@__WTz~jMedqnli*r||ld0+xpKg9X7ycELpB;bo_VIirLO&OlMyJOn(y6y+f(U&; z*@pAit}i4JdUr#P5Y*xY6`=I^_jasbleg zbz{z_Kpm~!i6_Sfr~Ux1 CnuJLJ literal 0 HcmV?d00001 diff --git a/v2/dotclear/plugins/blowupConfig/alpha-img/page-t/butterflies.png b/v2/dotclear/plugins/blowupConfig/alpha-img/page-t/butterflies.png new file mode 100644 index 0000000000000000000000000000000000000000..2a790c5df64dba45018fd7327cee1a0550ce60a9 GIT binary patch literal 6350 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 literal 0 HcmV?d00001 diff --git a/v2/dotclear/plugins/blowupConfig/alpha-img/page-t/default.png b/v2/dotclear/plugins/blowupConfig/alpha-img/page-t/default.png new file mode 100644 index 0000000000000000000000000000000000000000..1ea06207790cb086cab882a4f2e3ddc166f83f30 GIT binary patch literal 1926 zcmc&#S!feM7@oFKW2In46g-Emf}qJBiH%v3*dzAPrb-iN?UUQxNnD#f+})bAs1)^~ zeGwn5R7CJq6c3^(h(`qxL42rKP&^QQQUrYyRB&dKZo3*3gyIjG{pZ{7zrGnZqq{m= zYpPdN0|08;+u~gSR6*@P9FONrYUGsto|rf?5QWQ3pQ&8 zf+yxe(+S1}_}XvV4%m&Dci8s_`>oNNK(+-cqWG zcTsAuW$8Rk=W;oJF5uUU49$kaVWJSn`7pz04yu-r_o-%GG0AkEI5I^;)@@x$UZGDL zu%Z-23OQC9PSBk~s#y{b%Sh)1oo4+E?PSJ*5e)M7iD^bk)3UKLM-m~CF49cZnRpZz zEEL0fZ1FLij}4^Q%{&w28K!que3A4^ctVrp^q@ODm|{abLo$@YXOT+b5t;}wOBh>q zGSe?O{EJ|c=;);n7+L#RB#}m0q#)HYv1Y7WGfCvrnxP0*Ojd*pqIESBp=ZE9_E+p0 zUkiLKY3E)}x9%L}oH#SO&q?}X(zz^>oI1V%fXa#Xcw;L6;?v8kHTN5q&YRfyX#LIP z)6pIK7oNPb&eI0rz2)ZyCxf30V^7vR!yldTiCVl?R07~7pR(VahGC47S8k`$Q$k$M zVu;BEaXG`FqKLR1&q!T4wiEAWlZ-av@s@L71I|TWxg9c&jkuihlRC4zCv|3bO=@#~ zoAlp$AO3$jw3bzETF2qLH7B|+OnvBDecHA|ci+8U^6~4nediB^0>lbyvzJfhzU&{U zv$x;gUfNkp#U2yO_8xoxe9R6zd+W!Sqo&O$6mA^fXD+b)Ggp-N-M7-j>N5}Zsv>xO Z<;TdIb>ALv_|Fr7_HCWoN@pF literal 0 HcmV?d00001 diff --git a/v2/dotclear/plugins/blowupConfig/alpha-img/page-t/flamingo.png b/v2/dotclear/plugins/blowupConfig/alpha-img/page-t/flamingo.png new file mode 100644 index 0000000000000000000000000000000000000000..71388ee1432c56077f346b458a39df1e3851e966 GIT binary patch literal 12864 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 EUod-0?f?J) literal 0 HcmV?d00001 diff --git a/v2/dotclear/plugins/blowupConfig/alpha-img/page-t/flourish-1.png b/v2/dotclear/plugins/blowupConfig/alpha-img/page-t/flourish-1.png new file mode 100644 index 0000000000000000000000000000000000000000..48c01e3b2aa2fe8944b2263e2a346e4612b2de73 GIT binary patch literal 5045 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 EA5xVMK>z>% literal 0 HcmV?d00001 diff --git a/v2/dotclear/plugins/blowupConfig/alpha-img/page-t/flourish-2.png b/v2/dotclear/plugins/blowupConfig/alpha-img/page-t/flourish-2.png new file mode 100644 index 0000000000000000000000000000000000000000..2707e5a21c7c00130b3ba6285426c925bfaac252 GIT binary patch literal 12838 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 PallZ|RJRoA8u5Ps3?YkO literal 0 HcmV?d00001 diff --git a/v2/dotclear/plugins/blowupConfig/alpha-img/page-t/image-mask.png b/v2/dotclear/plugins/blowupConfig/alpha-img/page-t/image-mask.png new file mode 100644 index 0000000000000000000000000000000000000000..998613bcd9d98b2c37c322a7d7601df34b395eef GIT binary patch literal 1982 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 `#t2{BJ;Q@DS<3y;mE2X~ zqx2oO^L_xp>wo`qo&n@HE-QcxYt5ER9kgM|xGJ#WdeA|>E9p4z1!8~>ee7{vnN=5>QWHsTu4-krxamsuvQ_ct zj*xNwpwSIBoW2je1y{b2>sxEw{oDWkqDb5WKbr3Ouhdwu?3Ld6~%(beO?)#?Of6+ms?GOsU5hTdf z1`u`LChc*uS$;hxd|-Wq6pZg5B{)t@p{;K4q5d0iYXJL(Zvc7ezkTb<4T3OfhbMSp z$4C#Nao44VwQ`sHu<%*7c}BC02myFiF;;Zv{O*i%F4@i7Mvz}VDE z))q51f=%1R?yi8*2q4_U!4X1&N5T852IXHO4pgXE;bC5^eL; zX85RmZpi)60m$3GocITzZsmi! zyxT*}1*UwNh{`3FDPIV*5K>yq3{}RcKK#oI6X%t!%AipN4^xf@3=3D&f;NQW@9NEP zoe72jjQ|@#f&>7mekTl{6J@xpUXyk4v^6n zGy-e{2@(Lr1R!PLpjwd-n-?S&gq!1RecYK!%&MKrErmU7@BvMUbW`$q@y~a>dq94z zAArbE@hYrP;Z|JQConXa*ndNGRN|@EIh6oJ`nr~30K^I*4vhwzMu4rHZh0Z%TC$@{ zj)xDpXft1QnO6d61PKyk2msN|&o%(jC8&=C;l@~CcP5cY*47fz_E_o&AF#~p@BCTM z0CM-&-Z<9>b;xxYRK-t!G0&*T6i zS}d*dl1$4N6LbPtT)K1Oa2kEzspU2MqkiX!CB|Ag07w-=bimAwKZXFYiKeZ?}2XsdFoPoK(0y%)a6-LLljkjvSkmPA+MXREa?t2H}b$!RRD}2 zL4sVBHJVy@v%56xWrw-i7kmJ~gFp9d0Fa=J2h}!6crkpA;$HjG<#_~rP8xmyiy%RQ z1OVv{A% z210BgLJsq=3wYS}bD7^Cdk2vJI(R_354HdfK`yg4e)UyJIrtn903t|`AVGpO1BerZ z5Vcxg7D?pX3@Hup(Fh>_Kmd>+&LYAD@LppI8Pv-lL4pJc667N2AiA(Ba@x-hB5lCK z2Yd_yAUA#`07y{gg9HiScsV2hW{@C3f?TGxtSf}*U<5tEqbqy_0103aBuJ2e8bN{t z2@>Rz0Eh`f+JZ>iwZauXT-TeOf53AY-Wz{ActFDHAHedxETOb=kRU;V1PL-6fV72> zrti4r=Y8P=0Cod_1UX+Y3t$jnB1n)RL4pJc;tN8W_G?tlI)FzT_y_3D-W_X2~Zy-NRS{wf>;6Mmji$V2@)ho z1z1BJtsp^y1PK!4@&L%+2mlf!$W;*;tocEL1PKx(ND$9*@DDxf7eF=xfCLE=BuJ1T kL4pJc62u4~Zhb)h|CFu^@vH#ft^fc407*qoM6N<$g7D#;*8l(j literal 0 HcmV?d00001 diff --git a/v2/dotclear/plugins/blowupConfig/alpha-img/page-t/light-trails-3.png b/v2/dotclear/plugins/blowupConfig/alpha-img/page-t/light-trails-3.png new file mode 100644 index 0000000000000000000000000000000000000000..d1dacc23c59c622c9854094e56facd0a78bce4ff GIT binary patch literal 38308 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

        UVQ$3oVlO**JLXmyfJTxbYS0 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 Ue@Im32f)wv%sHzn3$OV90ps@!^8f$< literal 0 HcmV?d00001 diff --git a/v2/dotclear/plugins/blowupConfig/alpha-img/page-t/light-trails-4.png b/v2/dotclear/plugins/blowupConfig/alpha-img/page-t/light-trails-4.png new file mode 100644 index 0000000000000000000000000000000000000000..901b6e736949c701c6f7875392918de9ca33f339 GIT binary patch literal 32171 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

        ^_vOrcjvKKoBXHFAtkXs3L*w}ej@ovTfb_w# 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 UrOm%c|FCjO6QKhygWU=HFT|>S6aWAK literal 0 HcmV?d00001 diff --git a/v2/dotclear/plugins/blowupConfig/alpha-img/page-t/typo.png b/v2/dotclear/plugins/blowupConfig/alpha-img/page-t/typo.png new file mode 100644 index 0000000000000000000000000000000000000000..ef7689d1032fe5123e26c8eca5be51f3562e91e9 GIT binary patch literal 15365 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 ');$(styles_combo).append('');$(styles_combo).attr('title',dotclear.msg.predefined_style_title);for(var style in dotclear.blowup_styles){styles_option=document.createElement('option');styles_option.value=dotclear.blowup_styles[style];$(styles_option).append(style);$(styles_combo).append(styles_option);} +$('#theme_config').prepend(styles_combo);$(styles_combo).wrap('

        ').before(''+dotclear.msg.predefined_styles+'').wrap('

        ');$(styles_combo).change(function(){if(this.value=='none'){$(this.form).find('input[type=text]').val('').css({backgroundColor:'#FFF',color:'#000'});$(this.form).find('select').not($(this)).val('');$('#top_image').val('default');}else{applyBlowupValues(this.value);}});var e=$('#bu_export ~ fieldset:first');e.toggle();var img=document.createElement('img');img.src=dotclear.img_plus_src;img.alt=dotclear.img_plus_alt;img.className='expand';$(img).css('cursor','pointer');$(document.createTextNode(' ')).prependTo('#bu_export');$(img).prependTo('#bu_export');$(img).click(function(){if(e.css('display')=='none'){this.src=dotclear.img_minus_src;this.alt=dotclear.img_minus_alt;}else{this.src=dotclear.img_plus_src;this.alt=dotclear.img_plus_alt;} +e.toggle();});var a=document.createElement('a');a.href='#';$(a).text(dotclear.msg.apply_code);e.append(a);$(a).click(function(){var code=e.find('#export_code');if(code.size()==0){return false;} +applyBlowupValues(code.val());return false;});function toggleDisable(e){if(e.attr('disabled')){e.removeAttr('disabled');}else{e.attr('disabled','disabled');}} +function applyBlowupValues(code){code=code.replace("\n","");var re=/(^| )([a-zA-Z0-9_]+):"(.*?)"(;|$)/g;var s=code.match(re);if(typeof(s)=='object'&&s.length>0){var member,target,value,t_e;var reg=new RegExp('^(.+):"(.*)"(;?)\s*$');for(var i=0;i0.5?'#000':'#fff'});}} +function getColorLum(color) +{var rgb=[parseInt('0x'+color.substring(1,3))/255,parseInt('0x'+color.substring(3,5))/255,parseInt('0x'+color.substring(5,7))/255];return(Math.min(rgb[0],Math.min(rgb[1],rgb[2]))+Math.max(rgb[0],Math.max(rgb[1],rgb[2])))/2;}});dotclear.blowup_styles={'Spring Time':'body_bg_c:"#E0E0E0"; body_bg_g:"light"; body_txt_f:"ss1"; body_txt_s:"1.2em"; body_txt_c:"#6B6B6B"; body_line_height:"1.4em"; top_image:"light-trails-1"; blog_title_hide:"0"; blog_title_f:""; blog_title_s:"3.5em"; blog_title_c:"#9AC528"; blog_title_a:"center"; blog_title_p:""; body_link_c:"#279AC4"; body_link_f_c:"#6D8824"; body_link_v_c:"#279AC4"; sidebar_position:""; sidebar_text_f:""; sidebar_text_s:""; sidebar_text_c:"#6B6B6B"; sidebar_title_f:""; sidebar_title_s:""; sidebar_title_c:"#8FB22F"; sidebar_title2_f:""; sidebar_title2_s:""; sidebar_title2_c:"#279AC4"; sidebar_line_c:"#FFD02C"; sidebar_link_c:"#6B6B6B"; sidebar_link_f_c:"#9AC528"; sidebar_link_v_c:"#6B6B6B"; date_title_f:""; date_title_s:"1em"; date_title_c:"#279AC4"; post_title_f:""; post_title_s:"1.7em"; post_title_c:"#9AC528"; post_comment_bg_c:"#FFFAD1"; post_comment_c:"#6B6B6B"; post_commentmy_bg_c:"#F5F9D9"; post_commentmy_c:"#6B6B6B"; prelude_c:"#EDEDED"; footer_f:""; footer_s:"1.2em"; footer_c:"#9AC528"; footer_l_c:"#6D8824"; footer_bg_c:"#E0E0E0"','Forest':'body_bg_c:"#80661A"; body_bg_g:"light"; body_txt_f:""; body_txt_s:""; body_txt_c:"#0A0A00"; body_line_height:"1.4em"; top_image:"default"; blog_title_hide:"0"; blog_title_f:"s3"; blog_title_s:"4em"; blog_title_c:"#D9D9BF"; blog_title_a:""; blog_title_p:""; body_link_c:"#666600"; body_link_f_c:"#CC9933"; body_link_v_c:"#8D8D40"; sidebar_position:""; sidebar_text_f:""; sidebar_text_s:""; sidebar_text_c:"#0A0A00"; sidebar_title_f:"s2"; sidebar_title_s:"1.6em"; sidebar_title_c:"#4D4D00"; sidebar_title2_f:"s2"; sidebar_title2_s:""; sidebar_title2_c:"#575700"; sidebar_line_c:"#D9D9BF"; sidebar_link_c:"#40330D"; sidebar_link_f_c:"#666600"; sidebar_link_v_c:"#40330D"; date_title_f:""; date_title_s:""; date_title_c:"#B3B380"; post_title_f:"s2"; post_title_s:"2em"; post_title_c:"#4D4D00"; post_comment_bg_c:"#F0F0E6"; post_comment_c:"#0A0A00"; prelude_c:"#140F05"; footer_f:""; footer_s:""; footer_c:"#FFFFFF"; footer_l_c:"#D9AD2B"; footer_bg_c:"#33260D"','Flamingo':'body_bg_c:"#CC9999"; body_bg_g:"light"; body_txt_f:"ss3"; body_txt_s:"1.2em"; body_txt_c:"#1A1A00"; body_line_height:"1.5em"; top_image:"flamingo"; blog_title_hide:"0"; blog_title_f:"ss1"; blog_title_s:"3.5em"; blog_title_c:"#FFFFFF"; blog_title_a:""; blog_title_p:""; body_link_c:"#AD8282"; body_link_f_c:"#8282D9"; body_link_v_c:"#997373"; sidebar_position:""; sidebar_text_f:""; sidebar_text_s:""; sidebar_text_c:""; sidebar_title_f:"ss4"; sidebar_title_s:"1.4em"; sidebar_title_c:"#8282D9"; sidebar_title2_f:"ss3"; sidebar_title2_s:"1.2em"; sidebar_title2_c:"#AD8282"; sidebar_line_c:"#CDCDFF"; sidebar_link_c:"#262640"; sidebar_link_f_c:"#AD8282"; sidebar_link_v_c:"#262640"; date_title_f:"ss4"; date_title_s:""; date_title_c:"#D9B3B3"; post_title_f:"ss4"; post_title_s:"1.8em"; post_title_c:"#8282D9"; post_comment_bg_c:"#F2E5E5"; post_comment_c:""; prelude_c:"#140F0F"; footer_f:""; footer_s:""; footer_c:"#FFFFFF"; footer_l_c:""; footer_bg_c:"#140F0F"','Iceberg':'body_bg_c:"#5280A3"; body_bg_g:"dark"; body_txt_f:"ss3"; body_txt_s:"1.1em"; body_txt_c:"#757575"; body_line_height:"1.5em"; top_image:"default"; blog_title_hide:"0"; blog_title_f:"s2"; blog_title_s:"3em"; blog_title_c:"#FFFFFF"; blog_title_a:""; blog_title_p:""; body_link_c:"#BDB000"; body_link_f_c:"#F3E66D"; body_link_v_c:"#BDB000"; sidebar_position:"left"; sidebar_text_f:""; sidebar_text_s:""; sidebar_text_c:""; sidebar_title_f:"ss3"; sidebar_title_s:"1.4em"; sidebar_title_c:"#689B9C"; sidebar_title2_f:"ss3"; sidebar_title2_s:"1.2em"; sidebar_title2_c:"#737300"; sidebar_line_c:"#E6E6CD"; sidebar_link_c:"#66664D"; sidebar_link_f_c:"#5280A3"; sidebar_link_v_c:"#66664D"; date_title_f:""; date_title_s:""; date_title_c:"#000000"; post_title_f:"s2"; post_title_s:"1.8em"; post_title_c:"#6F6800"; post_comment_bg_c:"#E4E4E2"; post_comment_c:""; prelude_c:"#0E2734"; footer_f:""; footer_s:""; footer_c:"#FFFFFF"; footer_l_c:""; footer_bg_c:"#0E2734"','Night':'body_bg_c:"#0D1A26"; body_bg_g:"dark"; body_txt_f:"ss3"; body_txt_s:"1.1em"; body_txt_c:"#050A0F"; body_line_height:"1.5em"; top_image:"default"; blog_title_hide:"0"; blog_title_f:"s2"; blog_title_s:"3.5em"; blog_title_c:"#F2F2E5"; blog_title_a:""; body_link_c:"#336699"; body_link_f_c:"#66664D"; body_link_v_c:"#2B5782"; sidebar_position:""; sidebar_text_f:""; sidebar_text_s:""; sidebar_text_c:""; sidebar_title_f:"ss3"; sidebar_title_s:"1.4em"; sidebar_title_c:"#336699"; sidebar_title2_f:"ss3"; sidebar_title2_s:"1.2em"; sidebar_title2_c:"#737300"; sidebar_line_c:"#E6E6CD"; sidebar_link_c:"#66664D"; sidebar_link_f_c:"#336699"; sidebar_link_v_c:"#66664D"; date_title_f:""; date_title_s:""; date_title_c:"#ADAD82"; post_title_f:"s2"; post_title_s:"1.8em"; post_title_c:"#737300"; post_comment_bg_c:"#E6E6CD"; post_comment_c:""; prelude_c:"#070E14"; footer_f:""; footer_s:""; footer_c:"#FFFFFF"; footer_l_c:""; footer_bg_c:"#14140F"; blog_title_p:""','Peas & Carrots':'body_bg_c:"#9DCA25"; body_bg_g:"light"; body_txt_f:"ss1"; body_txt_s:"1.2em"; body_txt_c:"#383839"; body_line_height:"1.5em"; top_image:"butterflies"; blog_title_hide:"0"; blog_title_f:"ss4"; blog_title_s:"3em"; blog_title_c:"#DBDB9D"; blog_title_a:"left"; blog_title_p:""; body_link_c:"#646B10"; body_link_f_c:"#DF6C01"; body_link_v_c:"#919924"; sidebar_position:"left"; sidebar_text_f:""; sidebar_text_s:""; sidebar_text_c:""; sidebar_title_f:"ss4"; sidebar_title_s:""; sidebar_title_c:"#FE9017"; sidebar_title2_f:"s2"; sidebar_title2_s:"1.2em"; sidebar_title2_c:"#826228"; sidebar_line_c:"#D3EB8B"; sidebar_link_c:"#858547"; sidebar_link_f_c:"#FE9017"; sidebar_link_v_c:"#8F9645"; date_title_f:""; date_title_s:""; date_title_c:"#826228"; post_title_f:"ss4"; post_title_s:"1.8em"; post_title_c:"#806432"; post_comment_bg_c:"#EFFDCC"; post_comment_c:"#826228"; prelude_c:"#C8E186"; footer_f:""; footer_s:"1em"; footer_c:"#FFFFFF"; footer_l_c:"#FFFFFF"; footer_bg_c:"#484432"','Rabbit':'body_bg_c:"#8F9645"; body_bg_g:"solid"; body_txt_f:"ss1"; body_txt_s:"1.2em"; body_txt_c:"#625D47"; body_line_height:"1.4em"; top_image:"rabbit"; blog_title_hide:"0"; blog_title_f:"ss1"; blog_title_s:"3.5em"; blog_title_c:"#DBDB9D"; blog_title_a:""; blog_title_p:"130:70"; body_link_c:"#646B10"; body_link_f_c:"#484C12"; body_link_v_c:"#919924"; sidebar_position:""; sidebar_text_f:""; sidebar_text_s:""; sidebar_text_c:"#858547"; sidebar_title_f:""; sidebar_title_s:""; sidebar_title_c:"#8F9645"; sidebar_title2_f:"s2"; sidebar_title2_s:""; sidebar_title2_c:"#826228"; sidebar_line_c:"#95956B"; sidebar_link_c:"#858547"; sidebar_link_f_c:"#826228"; sidebar_link_v_c:"#8F9645"; date_title_f:"s2"; date_title_s:"1em"; date_title_c:"#826228"; post_title_f:"s2"; post_title_s:"1.6em"; post_title_c:"#806432"; post_comment_bg_c:"#D6DE91"; post_comment_c:"#826228"; prelude_c:"#484432"; footer_f:""; footer_s:"1em"; footer_c:"#A6AF50"; footer_l_c:"#DBDB9D"; footer_bg_c:"#484432"','Rec Room':'body_bg_c:"#9B5E1C"; body_bg_g:"dark"; body_txt_f:"ss3"; body_txt_s:"1.1em"; body_txt_c:"#757575"; body_line_height:"1.5em"; top_image:"default"; blog_title_hide:"0"; blog_title_f:"s2"; blog_title_s:"3em"; blog_title_c:"#F9FAD6"; blog_title_a:""; blog_title_p:""; body_link_c:"#D1BF1D"; body_link_f_c:"#EEE168"; body_link_v_c:"#D1BF1D"; sidebar_position:"left"; sidebar_text_f:""; sidebar_text_s:""; sidebar_text_c:""; sidebar_title_f:"ss3"; sidebar_title_s:"1.2em"; sidebar_title_c:"#689B9C"; sidebar_title2_f:"ss3"; sidebar_title2_s:"1.2em"; sidebar_title2_c:"#737300"; sidebar_line_c:"#E6E6CD"; sidebar_link_c:"#66664D"; sidebar_link_f_c:"#689B9C"; sidebar_link_v_c:"#66664D"; date_title_f:""; date_title_s:""; date_title_c:"#000000"; post_title_f:"s2"; post_title_s:"1.8em"; post_title_c:"#689B9C"; post_comment_bg_c:"#E4E4E2"; post_comment_c:""; prelude_c:"#3B2C16"; footer_f:""; footer_s:""; footer_c:"#FFFFFF"; footer_l_c:""; footer_bg_c:"#3B2C16"','Seville':'body_bg_c:"#B51A0D"; body_bg_g:"dark"; body_txt_f:"ss3"; body_txt_s:"1.1em"; body_txt_c:"#383839"; body_line_height:"1.5em"; top_image:"default"; blog_title_hide:"0"; blog_title_f:"s2"; blog_title_s:"3em"; blog_title_c:"#FFFFFF"; blog_title_a:""; blog_title_p:""; body_link_c:"#F18A32"; body_link_f_c:"#F1B232"; body_link_v_c:"#F18A32"; sidebar_position:"left"; sidebar_text_f:""; sidebar_text_s:""; sidebar_text_c:""; sidebar_title_f:"ss3"; sidebar_title_s:"1.4em"; sidebar_title_c:"#97471C"; sidebar_title2_f:"ss3"; sidebar_title2_s:"1.2em"; sidebar_title2_c:"#737300"; sidebar_line_c:"#E6E6CD"; sidebar_link_c:"#6E6E72"; sidebar_link_f_c:"#F18A32"; sidebar_link_v_c:"#6E6E72"; date_title_f:""; date_title_s:""; date_title_c:"#97471C"; post_title_f:"s2"; post_title_s:"1.8em"; post_title_c:"#F18A32"; post_comment_bg_c:"#E4E4E2"; post_comment_c:""; prelude_c:"#381A1A"; footer_f:""; footer_s:""; footer_c:"#FFFFFF"; footer_l_c:""; footer_bg_c:"#381A1A"','Typo':'body_bg_c:"#FFFFFF"; body_bg_g:"solid"; body_txt_f:"ss1"; body_txt_s:"1.2em"; body_txt_c:"#000000"; body_line_height:"1.4em"; top_image:"typo"; blog_title_hide:"0"; blog_title_f:"s2"; blog_title_s:"3.5em"; blog_title_c:"#B11508"; blog_title_a:"left"; blog_title_p:"140:50"; body_link_c:"#B11508"; body_link_f_c:"#000000"; body_link_v_c:"#4D4D4D"; sidebar_position:""; sidebar_text_f:""; sidebar_text_s:""; sidebar_text_c:"#000000"; sidebar_title_f:"s2"; sidebar_title_s:""; sidebar_title_c:"#B11508"; sidebar_title2_f:"s2"; sidebar_title2_s:""; sidebar_title2_c:"#000000"; sidebar_line_c:"#000000"; sidebar_link_c:"#000000"; sidebar_link_f_c:"#B11508"; sidebar_link_v_c:"#000000"; date_title_f:"s2"; date_title_s:"1em"; date_title_c:"#000000"; post_title_f:"s2"; post_title_s:"1.6em"; post_title_c:"#B11508"; post_comment_bg_c:"#FFFFFF"; post_comment_c:"#000000"; prelude_c:"#FFFFFF"; footer_f:""; footer_s:"1em"; footer_c:"#000000"; footer_l_c:"#B11508"; footer_bg_c:"#FFFFFF"'}; \ No newline at end of file diff --git a/v2/dotclear/plugins/blowupConfig/help.html b/v2/dotclear/plugins/blowupConfig/help.html new file mode 100644 index 0000000..8442326 --- /dev/null +++ b/v2/dotclear/plugins/blowupConfig/help.html @@ -0,0 +1,55 @@ + + + + Blowup theme configuration + + + +

        Modifying Blowup theme configuration allows you to customize your theme very easily. To do so, simply fill in the configuration fields or choose a predefined style.

        + +

        Colors

        + +

        When you have to enter a color value, you should use the hexadecimal format. For example: "#FF0000" will give you red. You may also use the color picker located next to every color field.

        +

        If you lack inspiration, try and visit the following pages:

        +
        + +

        Measurement units

        + +

        When you have to indicate a size, it must be followed by a measurement unit. For example: "1em". If you do not include the unit, pixels will be used as default measurement unit.

        +

        The following measurement units are available:

        +
          +
        • px
        • +
        • em
        • +
        • ex
        • +
        • pt
        • +
        • %
        • +
        + +

        Header images

        + +

        You can choose a header image among the list to use in place of the default one.

        + +

        When you choose "Custom..." in the image list, you will be able to upload your own image. The image file must be in JPG or PNG format and must be precisely 800px wide. + +

        If you upload a JPG image, a border will be added to the image, which is not the case with PNG images (the transparency of which will also be kept).

        + +

        Predefined styles

        + +

        You can choose a predefined style in the "Predefinite styles" drop-down list. +Once you have chosen the style, you have to submit the form to apply the modifications.

        + +

        You may then modify the predefined style according to your taste and needs.

        + +

        Configuration import / export

        + +

        At the end of Blowup options, you can display an area names "Configuration import/export". This text area contains the configuration you are currently using. You can copy it to share it with others.

        + +

        To apply (import) a configuration, you simply need to replace the content of the text area with the configuration you want to use. Don't forget to click on "apply code".

        + + + diff --git a/v2/dotclear/plugins/blowupConfig/index.php b/v2/dotclear/plugins/blowupConfig/index.php new file mode 100644 index 0000000..34e7248 --- /dev/null +++ b/v2/dotclear/plugins/blowupConfig/index.php @@ -0,0 +1,464 @@ +error->flag()) { + $notices = $core->error->toHTML(); + $core->error->reset(); +} + +$blowup_base = array( + 'body_bg_c' => null, + 'body_bg_g' => 'light', + + 'body_txt_f' => null, + 'body_txt_s' => null, + 'body_txt_c' => null, + 'body_line_height' => null, + + 'top_image' => 'default', + 'top_height' => null, + 'uploaded' => null, + + 'blog_title_hide' => null, + 'blog_title_f' => null, + 'blog_title_s' => null, + 'blog_title_c' => null, + 'blog_title_a' => null, + 'blog_title_p' => null, + + 'body_link_c' => null, + 'body_link_f_c' => null, + 'body_link_v_c' => null, + + 'sidebar_position' => null, + 'sidebar_text_f' => null, + 'sidebar_text_s' => null, + 'sidebar_text_c' => null, + 'sidebar_title_f' => null, + 'sidebar_title_s' => null, + 'sidebar_title_c' => null, + 'sidebar_title2_f' => null, + 'sidebar_title2_s' => null, + 'sidebar_title2_c' => null, + 'sidebar_line_c' => null, + 'sidebar_link_c' => null, + 'sidebar_link_f_c' => null, + 'sidebar_link_v_c' => null, + + 'date_title_f' => null, + 'date_title_s' => null, + 'date_title_c' => null, + + 'post_title_f' => null, + 'post_title_s' => null, + 'post_title_c' => null, + 'post_comment_bg_c' => null, + 'post_comment_c' => null, + 'post_commentmy_bg_c' => null, + 'post_commentmy_c' => null, + + 'prelude_c' => null, + 'footer_f' => null, + 'footer_s' => null, + 'footer_c' => null, + 'footer_l_c' => null, + 'footer_bg_c' => null, + + 'extra_css' => null +); + +$blowup_user = $core->blog->settings->themes->blowup_style; + +$blowup_user = @unserialize($blowup_user); +if (!is_array($blowup_user)) { + $blowup_user = array(); +} + +$blowup_user = array_merge($blowup_base,$blowup_user); + +$gradient_types = array( + __('Light linear gradient') => 'light', + __('Medium linear gradient') => 'medium', + __('Dark linear gradient') => 'dark', + __('Solid color') => 'solid' +); + +$top_images = array(__('Custom...') => 'custom'); +$top_images = array_merge($top_images,array_flip(blowupConfig::$top_images)); + + +if (!empty($_POST)) +{ + try + { + $blowup_user['body_txt_f'] = $_POST['body_txt_f']; + $blowup_user['body_txt_s'] = blowupConfig::adjustFontSize($_POST['body_txt_s']); + $blowup_user['body_txt_c'] = blowupConfig::adjustColor($_POST['body_txt_c']); + $blowup_user['body_line_height'] = blowupConfig::adjustFontSize($_POST['body_line_height']); + + $blowup_user['blog_title_hide'] = (integer) !empty($_POST['blog_title_hide']); + $update_blog_title = !$blowup_user['blog_title_hide'] && ( + !empty($_POST['blog_title_f']) || !empty($_POST['blog_title_s']) || + !empty($_POST['blog_title_c']) || !empty($_POST['blog_title_a']) || + !empty($_POST['blog_title_p']) + ); + + if ($update_blog_title) + { + $blowup_user['blog_title_f'] = $_POST['blog_title_f']; + $blowup_user['blog_title_s'] = blowupConfig::adjustFontSize($_POST['blog_title_s']); + $blowup_user['blog_title_c'] = blowupConfig::adjustColor($_POST['blog_title_c']); + $blowup_user['blog_title_a'] = preg_match('/^(left|center|right)$/',$_POST['blog_title_a']) ? $_POST['blog_title_a'] : null; + $blowup_user['blog_title_p'] = blowupConfig::adjustPosition($_POST['blog_title_p']); + } + + $blowup_user['body_link_c'] = blowupConfig::adjustColor($_POST['body_link_c']); + $blowup_user['body_link_f_c'] = blowupConfig::adjustColor($_POST['body_link_f_c']); + $blowup_user['body_link_v_c'] = blowupConfig::adjustColor($_POST['body_link_v_c']); + + $blowup_user['sidebar_text_f'] = $_POST['sidebar_text_f']; + $blowup_user['sidebar_text_s'] = blowupConfig::adjustFontSize($_POST['sidebar_text_s']); + $blowup_user['sidebar_text_c'] = blowupConfig::adjustColor($_POST['sidebar_text_c']); + $blowup_user['sidebar_title_f'] = $_POST['sidebar_title_f']; + $blowup_user['sidebar_title_s'] = blowupConfig::adjustFontSize($_POST['sidebar_title_s']); + $blowup_user['sidebar_title_c'] = blowupConfig::adjustColor($_POST['sidebar_title_c']); + $blowup_user['sidebar_title2_f'] = $_POST['sidebar_title2_f']; + $blowup_user['sidebar_title2_s'] = blowupConfig::adjustFontSize($_POST['sidebar_title2_s']); + $blowup_user['sidebar_title2_c'] = blowupConfig::adjustColor($_POST['sidebar_title2_c']); + $blowup_user['sidebar_line_c'] = blowupConfig::adjustColor($_POST['sidebar_line_c']); + $blowup_user['sidebar_link_c'] = blowupConfig::adjustColor($_POST['sidebar_link_c']); + $blowup_user['sidebar_link_f_c'] = blowupConfig::adjustColor($_POST['sidebar_link_f_c']); + $blowup_user['sidebar_link_v_c'] = blowupConfig::adjustColor($_POST['sidebar_link_v_c']); + + $blowup_user['sidebar_position'] = ($_POST['sidebar_position'] == 'left') ? 'left' : null; + + $blowup_user['date_title_f'] = $_POST['date_title_f']; + $blowup_user['date_title_s'] = blowupConfig::adjustFontSize($_POST['date_title_s']); + $blowup_user['date_title_c'] = blowupConfig::adjustColor($_POST['date_title_c']); + + $blowup_user['post_title_f'] = $_POST['post_title_f']; + $blowup_user['post_title_s'] = blowupConfig::adjustFontSize($_POST['post_title_s']); + $blowup_user['post_title_c'] = blowupConfig::adjustColor($_POST['post_title_c']); + $blowup_user['post_comment_c'] = blowupConfig::adjustColor($_POST['post_comment_c']); + $blowup_user['post_commentmy_c'] = blowupConfig::adjustColor($_POST['post_commentmy_c']); + + + $blowup_user['footer_f'] = $_POST['footer_f']; + $blowup_user['footer_s'] = blowupConfig::adjustFontSize($_POST['footer_s']); + $blowup_user['footer_c'] = blowupConfig::adjustColor($_POST['footer_c']); + $blowup_user['footer_l_c'] = blowupConfig::adjustColor($_POST['footer_l_c']); + $blowup_user['footer_bg_c'] = blowupConfig::adjustColor($_POST['footer_bg_c']); + + + $blowup_user['extra_css'] = blowupConfig::cleanCSS($_POST['extra_css']); + + if ($can_write_images) + { + $uploaded = null; + if ($blowup_user['uploaded'] && is_file(blowupConfig::imagesPath().'/'.$blowup_user['uploaded'])) { + $uploaded = blowupConfig::imagesPath().'/'.$blowup_user['uploaded']; + } + + if (!empty($_FILES['upfile']) && !empty($_FILES['upfile']['name'])) { + files::uploadStatus($_FILES['upfile']); + $uploaded = blowupConfig::uploadImage($_FILES['upfile']); + $blowup_user['uploaded'] = basename($uploaded); + } + + $blowup_user['top_image'] = in_array($_POST['top_image'],$top_images) ? $_POST['top_image'] : 'default'; + + $blowup_user['body_bg_c'] = blowupConfig::adjustColor($_POST['body_bg_c']); + $blowup_user['body_bg_g'] = in_array($_POST['body_bg_g'],$gradient_types) ? $_POST['body_bg_g'] : ''; + $blowup_user['post_comment_bg_c'] = blowupConfig::adjustColor($_POST['post_comment_bg_c']); + $blowup_user['post_commentmy_bg_c'] = blowupConfig::adjustColor($_POST['post_commentmy_bg_c']); + $blowup_user['prelude_c'] = blowupConfig::adjustColor($_POST['prelude_c']); + blowupConfig::createImages($blowup_user,$uploaded); + } + + $core->blog->settings->addNamespace('themes'); + $core->blog->settings->themes->put('blowup_style',serialize($blowup_user)); + $core->blog->triggerBlog(); + + http::redirect($p_url.'&upd=1'); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} +?> + + + <?php echo __('Blowup configuration'); ?> + + + + + + +'.html::escapeHTML($core->blog->name). +' › '.__('Blog appearance').''.__('Blowup configuration').''. +'

        '.__('back').'

        '; + + +if (!$can_write_images) { + echo '
        '. + __('For the following reasons, images cannot be created. You won\'t be able to change some background properties.'). + $notices.'
        '; +} + +if (!empty($_GET['upd'])) { + echo '

        '.__('Theme configuration has been successfully updated.').'

        '; +} + +echo '
        '; + +echo '
        '.__('General').''; + +if ($can_write_images) { + echo + '

        '. + + '

        '; +} + +echo +'

        '. + +'

        '. + +'

        '. + +'

        '. +'
        '. + +'
        '.__('Links').''. +'

        '. + +'

        '. + +'

        '. +'
        '. + +'
        '.__('Page top').''; + +if ($can_write_images) { + echo + '

        '; +} + +echo +'

        '. + +'

        '. + +'

        '. + +'

        '. + +'

        '. + +'

        '. +'
        '; + +if ($can_write_images) { + if ($blowup_user['top_image'] == 'custom' && $blowup_user['uploaded']) { + $preview_image = http::concatURL($core->blog->url,blowupConfig::imagesURL().'/page-t.png'); + } else { + $preview_image = 'index.php?pf=blowupConfig/alpha-img/page-t/'.$blowup_user['top_image'].'.png'; + } + + echo + '
        '.__('Top image').''. + '

        '. + '

        '.__('Choose "Custom..." to upload your own image.').'

        '. + + '

        '. + + '

        '.__('Preview').'

        '. + '
        '. + ''. + '
        '. + '
        '; +} + +echo +'
        '.__('Sidebar').''. +'

        '. + +'

        '. + +'

        '. + +'

        '. + +'

        '. + +'

        '. + +'

        '. + +'

        '. + +'

        '. + +'

        '. + +'

        '. + +'

        '. + +'

        '. + +'

        '. +'
        '. + +'
        '.__('Entries').''. +'

        '. + +'

        '. + +'

        '. + +'

        '. + +'

        '. + +'

        '; + +if ($can_write_images) { + echo + '

        '; +} + +echo +'

        '; + +if ($can_write_images) { + echo + '

        '; +} + +echo +'

        '. +'
        '. + +'
        '.__('Footer').''. +'

        '. + +'

        '. + +'

        '. + +'

        '. + +'

        '. +'
        '; + +echo +'
        '.__('Additional CSS').''. +'

        '.form::textarea('extra_css',72,5,html::escapeHTML($blowup_user['extra_css']),'maximal','',false,'title="'.__('Additional CSS').'"').'

        '. +'
        '; + + + +// Import / Export configuration +$tmp_array = array(); +$tmp_exclude = array('uploaded','top_height'); +if ($blowup_user['top_image'] == 'custom') { + $tmp_exclude[] = 'top_image'; +} +foreach ($blowup_user as $k => $v) { + if (!in_array($k,$tmp_exclude)) { + $tmp_array[] = $k.':'.'"'.$v.'"'; + } +} +echo +'

        '.__('Configuration import / export').'

        '. +'

        '.__('You can share your configuration using the following code. To apply a configuration, paste the code, click on "Apply code" and save.').'

        '. +'

        '.form::textarea('export_code',72,5,implode('; ',$tmp_array),'maximal','',false,'title="'.__('Copy this code:').'"').'

        '. +'
        '; + +echo +'

        '. +$core->formNonce().'

        '. +'
        '; + +dcPage::helpBlock('blowupConfig'); +?> + + diff --git a/v2/dotclear/plugins/blowupConfig/lib/class.blowup.config.php b/v2/dotclear/plugins/blowupConfig/lib/class.blowup.config.php new file mode 100644 index 0000000..a7fe577 --- /dev/null +++ b/v2/dotclear/plugins/blowupConfig/lib/class.blowup.config.php @@ -0,0 +1,429 @@ + array( + 'ss1' => 'Arial, Helvetica, sans-serif', + 'ss2' => 'Verdana,Geneva, Arial, Helvetica, sans-serif', + 'ss3' => '"Lucida Grande", "Lucida Sans Unicode", sans-serif', + 'ss4' => '"Trebuchet MS", Helvetica, sans-serif', + 'ss5' => 'Impact, Charcoal, sans-serif' + ), + + 'serif' => array( + 's1' => 'Times, "Times New Roman", serif', + 's2' => 'Georgia, serif', + 's3' => 'Baskerville, "Palatino Linotype", serif' + ), + + 'monospace' => array( + 'm1' => '"Andale Mono", "Courier New", monospace', + 'm2' => '"Courier New", Courier, mono, monospace' + ) + ); + + protected static $fonts_combo = array(); + protected static $fonts_list = array(); + + public static $top_images = array( + 'default' => 'Default', + 'blank' => 'Blank', + 'light-trails-1' => 'Light Trails 1', + 'light-trails-2' => 'Light Trails 2', + 'light-trails-3' => 'Light Trails 3', + 'light-trails-4' => 'Light Trails 4', + 'butterflies' => 'Butterflies', + 'flourish-1' => 'Flourished 1', + 'flourish-2' => 'Flourished 2', + 'animals' => 'Animals', + 'flamingo' => 'Flamingo', + 'rabbit' => 'Rabbit', + 'roadrunner-1' => 'Road Runner 1', + 'roadrunner-2' => 'Road Runner 2', + 'typo' => 'Typo' + ); + + public static function fontsList() + { + if (empty(self::$fonts_combo)) + { + self::$fonts_combo[__('default')] = ''; + foreach (self::$fonts as $family => $g) + { + $fonts = array(); + foreach ($g as $code => $font) { + $fonts[str_replace('"','',$font)] = $code; + } + self::$fonts_combo[$family] = $fonts; + } + } + + return self::$fonts_combo; + } + + public static function fontDef($c) + { + if (empty(self::$fonts_list)) + { + foreach (self::$fonts as $family => $g) + { + foreach ($g as $code => $font) { + self::$fonts_list[$code] = $font; + } + } + } + + return isset(self::$fonts_list[$c]) ? self::$fonts_list[$c] : null; + } + + public static function adjustFontSize($s) + { + if (preg_match('/^([0-9.]+)\s*(%|pt|px|em|ex)?$/',$s,$m)) { + if (empty($m[2])) { + $m[2] = 'px'; + } + return $m[1].$m[2]; + } + + return null; + } + + public static function adjustPosition($p) + { + if (!preg_match('/^[0-9]+(:[0-9]+)?$/',$p)) { + return null; + } + + $p = explode(':',$p); + + return $p[0].(count($p) == 1 ? ':0' : ':'.$p[1]); + } + + public static function adjustColor($c) + { + if ($c === '') { + return ''; + } + + $c = strtoupper($c); + + if (preg_match('/^[A-F0-9]{3,6}$/',$c)) { + $c = '#'.$c; + } + + if (preg_match('/^#[A-F0-9]{6}$/',$c)) { + return $c; + } + + if (preg_match('/^#[A-F0-9]{3,}$/',$c)) { + return '#'.substr($c,1,1).substr($c,1,1).substr($c,2,1).substr($c,2,1).substr($c,3,1).substr($c,3,1); + } + + return ''; + } + + public static function cleanCSS($css) + { + // TODO ? + return $css; + } + + public static function imagesPath() + { + global $core; + return path::real($core->blog->public_path).'/blowup-images'; + } + + public static function imagesURL() + { + global $core; + return $core->blog->settings->system->public_url.'/blowup-images'; + } + + public static function canWriteImages($create=false) + { + global $core; + + $public = path::real($core->blog->public_path); + $imgs = self::imagesPath(); + + if (!function_exists('imagecreatetruecolor') || !function_exists('imagepng') || !function_exists('imagecreatefrompng')) { + $core->error->add(__('At least one of the following functions is not available: '. + 'imagecreatetruecolor, imagepng & imagecreatefrompng.')); + return false; + } + + if (!is_dir($public)) { + $core->error->add(__('The \'public\' directory does not exist.')); + return false; + } + + if (!is_dir($imgs)) { + if (!is_writable($public)) { + $core->error->add(sprintf(__('The \'%s\' directory cannot be modified.'),'public')); + return false; + } + if ($create) { + files::makeDir($imgs); + } + return true; + } + + if (!is_writable($imgs)) { + $core->error->add(sprintf(__('The \'%s\' directory cannot be modified.'),'public/blowup-images')); + return false; + } + + return true; + } + + public static function uploadImage($f) + { + if (!self::canWriteImages(true)) { + throw new Exception(__('Unable to create images.')); + } + + $name = $f['name']; + $type = files::getMimeType($name); + + if ($type != 'image/jpeg' && $type != 'image/png') { + throw new Exception(__('Invalid file type.')); + } + + $dest = self::imagesPath().'/uploaded'.($type == 'image/png' ? '.png' : '.jpg'); + + if (@move_uploaded_file($f['tmp_name'],$dest) === false) { + throw new Exception(__('An error occurred while writing the file.')); + } + + $s = getimagesize($dest); + if ($s[0] != 800) { + throw new Exception(__('Uploaded image is not 800 pixels wide.')); + } + + return $dest; + } + + public static function createImages(&$config,$uploaded) + { + $body_color = $config['body_bg_c']; + $prelude_color = $config['prelude_c']; + $gradient = $config['body_bg_g']; + $comment_color = $config['post_comment_bg_c']; + $comment_color_my = $config['post_commentmy_bg_c']; + $top_image = $config['top_image']; + + $config['top_height'] = null; + + if ($top_image != 'custom' && !isset(self::$top_images[$top_image])) { + $top_image = 'default'; + } + if ($uploaded && !is_file($uploaded)) { + $uploaded = null; + } + + if (!self::canWriteImages(true)) { + throw new Exception(__('Unable to create images.')); + } + + $body_fill = array( + 'light' => dirname(__FILE__).'/../alpha-img/gradient-l.png', + 'medium' => dirname(__FILE__).'/../alpha-img/gradient-m.png', + 'dark' => dirname(__FILE__).'/../alpha-img/gradient-d.png' + ); + + $body_g = isset($body_fill[$gradient]) ? $body_fill[$gradient] : false; + + if ($top_image == 'custom' && $uploaded) { + $page_t = $uploaded; + } else { + $page_t = dirname(__FILE__).'/../alpha-img/page-t/'.$top_image.'.png'; + } + + $body_bg = dirname(__FILE__).'/../alpha-img/body-bg.png'; + $page_t_mask = dirname(__FILE__).'/../alpha-img/page-t/image-mask.png'; + $page_b = dirname(__FILE__).'/../alpha-img/page-b.png'; + $comment_t = dirname(__FILE__).'/../alpha-img/comment-t.png'; + $comment_b = dirname(__FILE__).'/../alpha-img/comment-b.png'; + $default_bg = '#e0e0e0'; + $default_prelude = '#ededed'; + + self::dropImage(basename($body_bg)); + self::dropImage('page-t.png'); + self::dropImage(basename($page_b)); + self::dropImage(basename($comment_t)); + self::dropImage(basename($comment_b)); + + $body_color = self::adjustColor($body_color); + $prelude_color = self::adjustColor($prelude_color); + $comment_color = self::adjustColor($comment_color); + + if ($top_image || $body_color || $gradient != 'light' || $prelude_color || $uploaded) + { + if (!$body_color) { + $body_color = $default_bg; + } + $body_color = sscanf($body_color,'#%2X%2X%2X'); + + # Create body gradient with color + $d_body_bg = imagecreatetruecolor(50,180); + $fill = imagecolorallocate($d_body_bg,$body_color[0],$body_color[1],$body_color[2]); + imagefill($d_body_bg,0,0,$fill); + + # User choosed a gradient + if ($body_g) { + $s_body_bg = imagecreatefrompng($body_g); + imagealphablending($s_body_bg,true); + imagecopy($d_body_bg,$s_body_bg,0,0,0,0,50,180); + imagedestroy($s_body_bg); + } + + if (!$prelude_color) { + $prelude_color = $default_prelude; + } + $prelude_color = sscanf($prelude_color,'#%2X%2X%2X'); + + $s_prelude = imagecreatetruecolor(50,30); + $fill = imagecolorallocate($s_prelude,$prelude_color[0],$prelude_color[1],$prelude_color[2]); + imagefill($s_prelude,0,0,$fill); + imagecopy($d_body_bg,$s_prelude,0,0,0,0,50,30); + + imagepng($d_body_bg,self::imagesPath().'/'.basename($body_bg)); + } + + if ($top_image || $body_color || $gradient != 'light') + { + # Create top image from uploaded image + $size = getimagesize($page_t); + $size = $size[1]; + $type = files::getMimeType($page_t); + + $d_page_t = imagecreatetruecolor(800,$size); + + if ($type == 'image/png') { + $s_page_t = @imagecreatefrompng($page_t); + } else { + $s_page_t = @imagecreatefromjpeg($page_t); + } + + if (!$s_page_t) { + throw new exception(__('Unable to open image.')); + } + + $fill = imagecolorallocate($d_page_t,$body_color[0],$body_color[1],$body_color[2]); + imagefill($d_page_t,0,0,$fill); + + if ($type == 'image/png') + { + # PNG, we only add body gradient and image + imagealphablending($s_page_t,true); + imagecopyresized($d_page_t,$d_body_bg,0,0,0,50,800,130,50,130); + imagecopy($d_page_t,$s_page_t,0,0,0,0,800,$size); + } + else + { + # JPEG, we add image and a frame with rounded corners + imagecopy($d_page_t,$s_page_t,0,0,0,0,800,$size); + + imagecopy($d_page_t,$d_body_bg,0,0,0,50,8,4); + imagecopy($d_page_t,$d_body_bg,0,4,0,54,4,4); + imagecopy($d_page_t,$d_body_bg,792,0,0,50,8,4); + imagecopy($d_page_t,$d_body_bg,796,4,0,54,4,4); + + $mask = imagecreatefrompng($page_t_mask); + imagealphablending($mask,true); + imagecopy($d_page_t,$mask,0,0,0,0,800,11); + imagedestroy($mask); + + $fill = imagecolorallocate($d_page_t,255,255,255); + imagefilledrectangle($d_page_t,0,11,3,$size-1,$fill); + imagefilledrectangle($d_page_t,796,11,799,$size-1,$fill); + imagefilledrectangle($d_page_t,0,$size-9,799,$size-1,$fill); + } + + $config['top_height'] = ($size).'px'; + + imagepng($d_page_t,self::imagesPath().'/page-t.png'); + + imagedestroy($d_body_bg); + imagedestroy($d_page_t); + imagedestroy($s_page_t); + + # Create bottom image with color + $d_page_b = imagecreatetruecolor(800,8); + $fill = imagecolorallocate($d_page_b,$body_color[0],$body_color[1],$body_color[2]); + imagefill($d_page_b,0,0,$fill); + + $s_page_b = imagecreatefrompng($page_b); + imagealphablending($s_page_b,true); + imagecopy($d_page_b,$s_page_b,0,0,0,0,800,160); + + imagepng($d_page_b,self::imagesPath().'/'.basename($page_b)); + + imagedestroy($d_page_b); + imagedestroy($s_page_b); + } + + if ($comment_color) { + self::commentImages($comment_color,$comment_t,$comment_b,basename($comment_t),basename($comment_b)); + } + if ($comment_color_my) { + self::commentImages($comment_color_my,$comment_t,$comment_b,'commentmy-t.png','commentmy-b.png'); + } + } + + protected static function commentImages($comment_color,$comment_t,$comment_b,$dest_t,$dest_b) + { + $comment_color = sscanf($comment_color,'#%2X%2X%2X'); + + $d_comment_t = imagecreatetruecolor(500,25); + $fill = imagecolorallocate($d_comment_t,$comment_color[0],$comment_color[1],$comment_color[2]); + imagefill($d_comment_t,0,0,$fill); + + $s_comment_t = imagecreatefrompng($comment_t); + imagealphablending($s_comment_t,true); + imagecopy($d_comment_t,$s_comment_t,0,0,0,0,500,25); + + imagepng($d_comment_t,self::imagesPath().'/'.$dest_t); + imagedestroy($d_comment_t); + imagedestroy($s_comment_t); + + $d_comment_b = imagecreatetruecolor(500,7); + $fill = imagecolorallocate($d_comment_b,$comment_color[0],$comment_color[1],$comment_color[2]); + imagefill($d_comment_b,0,0,$fill); + + $s_comment_b = imagecreatefrompng($comment_b); + imagealphablending($s_comment_b,true); + imagecopy($d_comment_b,$s_comment_b,0,0,0,0,500,7); + + imagepng($d_comment_b,self::imagesPath().'/'.$dest_b); + imagedestroy($d_comment_b); + imagedestroy($s_comment_b); + } + + public static function dropImage($img) + { + $img = path::real(self::imagesPath().'/'.$img); + if (is_writable(dirname($img))) { + @unlink($img); + @unlink(dirname($img).'/.'.basename($img,'.png').'_sq.jpg'); + @unlink(dirname($img).'/.'.basename($img,'.png').'_m.jpg'); + @unlink(dirname($img).'/.'.basename($img,'.png').'_s.jpg'); + @unlink(dirname($img).'/.'.basename($img,'.png').'_sq.jpg'); + @unlink(dirname($img).'/.'.basename($img,'.png').'_t.jpg'); + } + } +} +?> diff --git a/v2/dotclear/plugins/fairTrackbacks/_define.php b/v2/dotclear/plugins/fairTrackbacks/_define.php new file mode 100644 index 0000000..6b4197d --- /dev/null +++ b/v2/dotclear/plugins/fairTrackbacks/_define.php @@ -0,0 +1,24 @@ +registerModule( + /* Name */ "Fair Trackbacks", + /* Description*/ "Trackback validity check", + /* Author */ "Olivier Meunier", + /* Version */ '1.1', + array( + 'permissions' => 'usage,contentadmin', + 'priority' => 200 + ) +); +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/fairTrackbacks/_prepend.php b/v2/dotclear/plugins/fairTrackbacks/_prepend.php new file mode 100644 index 0000000..9b6f2fd --- /dev/null +++ b/v2/dotclear/plugins/fairTrackbacks/_prepend.php @@ -0,0 +1,22 @@ +spamfilters[] = 'dcFilterFairTrackbacks'; +} +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/fairTrackbacks/_public.php b/v2/dotclear/plugins/fairTrackbacks/_public.php new file mode 100644 index 0000000..4fd2644 --- /dev/null +++ b/v2/dotclear/plugins/fairTrackbacks/_public.php @@ -0,0 +1,18 @@ +spamfilters[] = 'dcFilterFairTrackbacks'; +} +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/fairTrackbacks/class.dc.filter.fairtrackbacks.php b/v2/dotclear/plugins/fairTrackbacks/class.dc.filter.fairtrackbacks.php new file mode 100644 index 0000000..1248ea1 --- /dev/null +++ b/v2/dotclear/plugins/fairTrackbacks/class.dc.filter.fairtrackbacks.php @@ -0,0 +1,85 @@ +description = __('Checks trackback source for a link to the post'); + } + + + public function isSpam($type,$author,$email,$site,$ip,$content,$post_id,&$status) + { + if ($type != 'trackback') { + return; + } + + try + { + $default_parse = array('scheme'=>'','host'=>'','path'=>'','query'=>''); + $S = array_merge($default_parse,parse_url($site)); + + if ($S['scheme'] != 'http' || !$S['host'] || !$S['path']) { + throw new Exception('Invalid URL'); + } + + # Check incomink link page + $post = $this->core->blog->getPosts(array('post_id' => $post_id)); + $post_url = $post->getURL(); + $P = array_merge($default_parse,parse_url($post_url)); + + if ($post_url == $site) { + throw new Exception('Same source and destination'); + } + + $o = netHttp::initClient($site,$path); + $o->setTimeout(3); + $o->get($path); + + # Trackback source does not return 200 status code + if ($o->getStatus() != 200) { + throw new Exception('Invalid Status Code'); + } + + $tb_page = $o->getContent(); + + # Do we find a link to post in trackback source? + if ($S['host'] == $P['host']) { + $pattern = $P['path'].($P['query'] ? '?'.$P['query'] : ''); + } else { + $pattern = $post_url; + } + $pattern = preg_quote($pattern,'/'); + + if (!preg_match('/'.$pattern.'/',$tb_page)) { + throw new Exception('Unfair'); + } + } + catch (Exception $e) + { + throw new Exception('Trackback not allowed for this URL.'); + } + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/importExport/_admin.php b/v2/dotclear/plugins/importExport/_admin.php new file mode 100644 index 0000000..ec5dbae --- /dev/null +++ b/v2/dotclear/plugins/importExport/_admin.php @@ -0,0 +1,35 @@ +addItem( + __('Import/Export'), + 'plugin.php?p=importExport', + 'index.php?pf=importExport/icon.png', + preg_match('/plugin.php\?p=importExport(&.*)?$/',$_SERVER['REQUEST_URI']), + $core->auth->check('admin',$core->blog->id) +); + +$core->addBehavior('adminDashboardFavs','importExportDashboardFavs'); + +function importExportDashboardFavs($core,$favs) +{ + $favs['importExport'] = new ArrayObject(array( + 'importExport', + __('Import/Export'), + 'plugin.php?p=importExport', + 'index.php?pf=importExport/icon.png', + 'index.php?pf=importExport/icon-big.png', + 'admin',null,null + )); +} +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/importExport/_define.php b/v2/dotclear/plugins/importExport/_define.php new file mode 100644 index 0000000..0a45722 --- /dev/null +++ b/v2/dotclear/plugins/importExport/_define.php @@ -0,0 +1,21 @@ +registerModule( + /* Name */ "Import / Export", + /* Description*/ "Import and Export your blog", + /* Author */ "Olivier Meunier & Contributors", + /* Version */ '3.1', + /* Perm */ 'admin' +); +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/importExport/_prepend.php b/v2/dotclear/plugins/importExport/_prepend.php new file mode 100644 index 0000000..34c66df --- /dev/null +++ b/v2/dotclear/plugins/importExport/_prepend.php @@ -0,0 +1,42 @@ +addBehavior('importExportModules','registerIeModules'); + +function registerIeModules($modules) +{ + $modules['import'][] = 'dcImportFlat'; + $modules['import'][] = 'dcImportFeed'; + + $modules['export'][] = 'dcExportFlat'; + + if ($GLOBALS['core']->auth->isSuperAdmin()) { + $modules['import'][] = 'dcImportDC1'; + $modules['import'][] = 'dcImportWP'; + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/importExport/icon-big.png b/v2/dotclear/plugins/importExport/icon-big.png new file mode 100644 index 0000000000000000000000000000000000000000..e4a6303cf2264790c8bd751406dbf90f52a14380 GIT binary patch literal 6024 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%0D%d|{ zdIHWu+@d`_sC&&n*?Rx%{&vtDb$n!$Cw*HF$kRLmzfeVHl^_vJvYWAE&Ik-mFp6kGsLa^Fn{v#Q-c|Hch<&2-AO HT*Ceb3w6Gp literal 0 HcmV?d00001 diff --git a/v2/dotclear/plugins/importExport/icon.png b/v2/dotclear/plugins/importExport/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..274b67c427db8b8be8988c5c4e92ed1d64f1ee6c GIT binary patch literal 1666 zcmbVNeM}Q)7_X>&35F?ZL_W^e7&2*lcNF>o71~}8TPdrhj-q2y+Cw^MuU@aT1wV1P z5dz3$C^BPW1eFC7!Qux3y3Hai#js-HoNnmQxfvs(+i=>sD^RyTh=1&oyZ3qD_xb&v z?_8BKDy8f~uLpw^HYMW#T98(CVP4$E#dQ)n73HO+3;>WVQED8RNFOhWpT?mjwT z&7X%?{AHk*xQOJw21RyM@v^L-pJ%%n7!7Ke${+LPTjEd2E71D z5{V!_3iG&PPzpknn23l(9BE<_ilQ7??B|#bi^7ORBH{7H5RVT*Qcw(wKq(5tAP<2> z5(xEUWhM)$HR&+FT?1uz2FrUZRv;lTEr}Cq953;AfU*cDaZ3?y1|-=@K#swr$88p0 zai(KMFv3uZ=}`hV0#n%)7-qAM^7s-+!sUv@l;5*OJ&o1>pNz37XV|{h_)n|&kEs6h ziEkR8+PoPZ%tXx#K@A4on;S!;1)P;3BDMV%N9A6>Vnf8P?p$YXK}U1AVq`TU3#P|@ zQ@6go#UQJstCXVSam$2D%i|}5B9HfX**nziK&C39ZHZ_VM}4VzEZ=+5rPm$4Uh^{f zW$A&e%#^US2R%oQ{MpETq4 z%DY>02dt{b*Vo3Ji^2jISABfCcz>ouc1kn3qb#Z#p(zroLlz1{4(3*lzq|Cz7gt(x zDxEiOG#si}7RF#Ozys?zf58#KCR1p|sI1JpbJxA<_&dyp4d{2urqS|=;S;*rUw+-b zHm(YN;Oehm<*uo@T5!hYLJxXgkYvMaAfLh7Y)(|7n{T zm&yk3KjVPCKa&fe|L!*8j9N*>?o!+E-MfP$k(ZhxrHz>ILpJUV7?8JoHMzZ489(nF z+8DEW)25?`(pk%H-8^}!pm23mO;p&vi;d|~Jv}|ntD+T=(kAzVuCA_^3l>~^j6Suy zu?wwp#e>{HVLCiFo4D{n`iLIB^7l`Bha%^@hmJKL_IkZ}d3n)F>E(kdX=x|Yf4pnv zHM=X~SIOijJeA@(zd>Q1+qX;3{h)0K4-X&Td*h>+=;&8#F4N?D>RydkKa2DI6=c#Z Jtype = 'export'; + $this->name = __('Flat file export'); + $this->description = __('Exports a blog or a full Dotclear installation to flat file.'); + } + + public function process($do) + { + # Export a blog + if ($do == 'export_blog' && $this->core->auth->check('admin',$this->core->blog->id)) + { + $fullname = $this->core->blog->public_path.'/.backup_'.sha1(uniqid()); + $blog_id = $this->core->con->escape($this->core->blog->id); + + try + { + $exp = new flatExport($this->core->con,$fullname,$this->core->prefix); + fwrite($exp->fp,'///DOTCLEAR|'.DC_VERSION."|single\n"); + + $exp->export('category', + 'SELECT * FROM '.$this->core->prefix.'category '. + "WHERE blog_id = '".$blog_id."'" + ); + $exp->export('link', + 'SELECT * FROM '.$this->core->prefix.'link '. + "WHERE blog_id = '".$blog_id."'" + ); + $exp->export('setting', + 'SELECT * FROM '.$this->core->prefix.'setting '. + "WHERE blog_id = '".$blog_id."'" + ); + $exp->export('post', + 'SELECT * FROM '.$this->core->prefix.'post '. + "WHERE blog_id = '".$blog_id."'" + ); + $exp->export('meta', + 'SELECT meta_id, meta_type, M.post_id '. + 'FROM '.$this->core->prefix.'meta M, '.$this->core->prefix.'post P '. + 'WHERE P.post_id = M.post_id '. + "AND P.blog_id = '".$blog_id."'" + ); + $exp->export('media', + 'SELECT * FROM '.$this->core->prefix."media WHERE media_path = '". + $this->core->con->escape($this->core->blog->settings->system->public_path)."'" + ); + $exp->export('post_media', + 'SELECT media_id, M.post_id '. + 'FROM '.$this->core->prefix.'post_media M, '.$this->core->prefix.'post P '. + 'WHERE P.post_id = M.post_id '. + "AND P.blog_id = '".$blog_id."'" + ); + $exp->export('ping', + 'SELECT ping.post_id, ping_url, ping_dt '. + 'FROM '.$this->core->prefix.'ping ping, '.$this->core->prefix.'post P '. + 'WHERE P.post_id = ping.post_id '. + "AND P.blog_id = '".$blog_id."'" + ); + $exp->export('comment', + 'SELECT C.* '. + 'FROM '.$this->core->prefix.'comment C, '.$this->core->prefix.'post P '. + 'WHERE P.post_id = C.post_id '. + "AND P.blog_id = '".$blog_id."'" + ); + + # --BEHAVIOR-- exportSingle + $this->core->callBehavior('exportSingle',$this->core,$exp,$blog_id); + + $_SESSION['export_file'] = $fullname; + $_SESSION['export_filename'] = $_POST['file_name']; + $_SESSION['export_filezip'] = !empty($_POST['file_zip']); + http::redirect($this->getURL().'&do=ok'); + } + catch (Exception $e) + { + @unlink($fullname); + throw $e; + } + } + + # Export all content + if ($do == 'export_all' && $this->core->auth->isSuperAdmin()) + { + $fullname = $this->core->blog->public_path.'/.backup_'.sha1(uniqid()); + try + { + $exp = new flatExport($this->core->con,$fullname,$this->core->prefix); + fwrite($exp->fp,'///DOTCLEAR|'.DC_VERSION."|full\n"); + $exp->exportTable('blog'); + $exp->exportTable('category'); + $exp->exportTable('link'); + $exp->exportTable('setting'); + $exp->exportTable('user'); + $exp->exportTable('pref'); + $exp->exportTable('permissions'); + $exp->exportTable('post'); + $exp->exportTable('meta'); + $exp->exportTable('media'); + $exp->exportTable('post_media'); + $exp->exportTable('log'); + $exp->exportTable('ping'); + $exp->exportTable('comment'); + $exp->exportTable('spamrule'); + $exp->exportTable('version'); + + # --BEHAVIOR-- exportFull + $this->core->callBehavior('exportFull',$this->core,$exp); + + $_SESSION['export_file'] = $fullname; + $_SESSION['export_filename'] = $_POST['file_name']; + $_SESSION['export_filezip'] = !empty($_POST['file_zip']); + http::redirect($this->getURL().'&do=ok'); + } + catch (Exception $e) + { + @unlink($fullname); + throw $e; + } + } + + # Send file content + if ($do == 'ok') + { + if (!file_exists($_SESSION['export_file'])) { + throw new Exception(__('Export file not found.')); + } + + ob_end_clean(); + + if (substr($_SESSION['export_filename'],-4) == '.zip') { + $_SESSION['export_filename'] = substr($_SESSION['export_filename'],0,-4);//.'.txt'; + } + + # Flat export + if (empty($_SESSION['export_filezip'])) { + + header('Content-Disposition: attachment;filename='.$_SESSION['export_filename']); + header('Content-Type: text/plain; charset=UTF-8'); + readfile($_SESSION['export_file']); + + unlink($_SESSION['export_file']); + unset($_SESSION['export_file'],$_SESSION['export_filename'],$_SESSION['export_filezip']); + exit; + } + # Zip export + else { + try + { + $file_zipname = $_SESSION['export_filename'].'.zip'; + + $fp = fopen('php://output','wb'); + $zip = new fileZip($fp); + $zip->addFile($_SESSION['export_file'],$_SESSION['export_filename']); + + header('Content-Disposition: attachment;filename='.$file_zipname); + header('Content-Type: application/x-zip'); + + $zip->write(); + + unlink($_SESSION['export_file']); + unset($zip,$_SESSION['export_file'],$_SESSION['export_filename'],$file_zipname); + exit; + } + catch (Exception $e) + { + unset($zip,$_SESSION['export_file'],$_SESSION['export_filename'],$file_zipname); + @unlink($_SESSION['export_file']); + + throw new Exception(__('Failed to compress export file.')); + } + } + } + } + + public function gui() + { + echo + '
        '. + '
        '.__('Single blog').''. + '

        '.sprintf(__('This will create an export of your current blog: %s'),html::escapeHTML($this->core->blog->name)).'

        '. + + '

        '. + form::field(array('file_name','file_name'),50,255,date('Y-m-d-').html::escapeHTML($this->core->blog->id.'-backup.txt')). + '

        '. + + '

        '. + '

        '. + + '

        '. + __('You may also want to download your media directory as a zip file').'

        '. + + '

        '. + form::hidden(array('do'),'export_blog'). + $this->core->formNonce().'

        '. + + '
        '. + '
        '; + + if ($this->core->auth->isSuperAdmin()) + { + echo + '
        '. + '
        '.__('Multiple blogs').''. + '

        '.__('This will create an export of all the content of your database.').'

        '. + + '

        '. + form::field(array('file_name','file_name2'),50,255,date('Y-m-d-').'dotclear-backup.txt'). + '

        '. + + '

        '. + '

        '. + + '

        '. + form::hidden(array('do'),'export_all'). + $this->core->formNonce().'

        '. + + '
        '. + '
        '; + } + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/importExport/inc/class.dc.ieModule.php b/v2/dotclear/plugins/importExport/inc/class.dc.ieModule.php new file mode 100644 index 0000000..bfd9f2a --- /dev/null +++ b/v2/dotclear/plugins/importExport/inc/class.dc.ieModule.php @@ -0,0 +1,80 @@ +core =& $core; + $this->setInfo(); + + if (!in_array($this->type,array('import','export'))) { + throw new Exception(sprintf('Unknow type for module %s',get_class($this))); + } + + if (!$this->name) { + $this->name = get_class($this); + } + + $this->id = get_class($this); + $this->url = sprintf('plugin.php?p=importExport&type=%s&module=%s',$this->type,$this->id); + } + + public function init() + { + } + + abstract protected function setInfo(); + + final public function getURL($escape=false) + { + return $escape ? html::escapeHTML($this->url) : $this->url; + } + + abstract public function process($do); + + abstract public function gui(); + + protected function progressBar($percent) + { + $percent = ceil($percent); + if ($percent > 100) { + $percent = 100; + } + return '
        '.$percent.' %
        '; + } + + protected function autoSubmit() + { + return form::hidden(array('autosubmit'),1); + } + + protected function congratMessage() + { + return + '

        '.__('Congratulation!').'

        '. + '

        '.__('Your blog has been successfully imported. Welcome on Dotclear 2!').'

        '. + ''; + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/importExport/inc/class.dc.import.dc1.php b/v2/dotclear/plugins/importExport/inc/class.dc.import.dc1.php new file mode 100644 index 0000000..7ddb23e --- /dev/null +++ b/v2/dotclear/plugins/importExport/inc/class.dc.import.dc1.php @@ -0,0 +1,625 @@ + '', + 'db_name' => '', + 'db_user' => '', + 'db_pwd' => '', + 'db_prefix' => 'dc_', + 'post_limit' => 20, + 'cat_ids' => array() + ); + + protected function setInfo() + { + $this->type = 'import'; + $this->name = __('Dotclear 1.2 import'); + $this->description = __('Import a Dotclear 1.2 installation into your current blog.'); + } + + public function init() + { + $this->con =& $this->core->con; + $this->prefix = $this->core->prefix; + $this->blog_id = $this->core->blog->id; + + if (!isset($_SESSION['dc1_import_vars'])) { + $_SESSION['dc1_import_vars'] = $this->base_vars; + } + $this->vars =& $_SESSION['dc1_import_vars']; + + if ($this->vars['post_limit'] > 0) { + $this->post_limit = $this->vars['post_limit']; + } + } + + public function resetVars() + { + $this->vars = $this->base_vars;; + unset($_SESSION['dc1_import_vars']); + } + + public function process($do) + { + $this->action = $do; + } + + # We handle process in another way to always display something to + # user + protected function guiprocess($do) + { + switch ($do) + { + case 'step1': + $this->vars['db_host'] = $_POST['db_host']; + $this->vars['db_name'] = $_POST['db_name']; + $this->vars['db_user'] = $_POST['db_user']; + $this->vars['db_pwd'] = $_POST['db_pwd']; + $this->vars['post_limit'] = abs((integer) $_POST['post_limit']) > 0 ? $_POST['post_limit'] : 0; + $this->vars['db_prefix'] = $_POST['db_prefix']; + $db = $this->db(); + $db->close(); + $this->step = 2; + echo $this->progressBar(1); + break; + case 'step2': + $this->step = 2; + $this->importUsers(); + $this->step = 3; + echo $this->progressBar(3); + break; + case 'step3': + $this->step = 3; + $this->importCategories(); + if ($this->core->plugins->moduleExists('blogroll')) { + $this->step = 4; + echo $this->progressBar(5); + } else { + $this->step = 5; + echo $this->progressBar(7); + } + break; + case 'step4': + $this->step = 4; + $this->importLinks(); + $this->step = 5; + echo $this->progressBar(7); + break; + case 'step5': + $this->step = 5; + $this->post_offset = !empty($_REQUEST['offset']) ? abs((integer) $_REQUEST['offset']) : 0; + if ($this->importPosts($percent) === -1) { + http::redirect($this->getURL().'&do=ok'); + } else { + echo $this->progressBar(ceil($percent*0.93)+7); + } + break; + case 'ok': + $this->resetVars(); + $this->core->blog->triggerBlog(); + $this->step = 6; + echo $this->progressBar(100); + break; + } + } + + public function gui() + { + try { + $this->guiprocess($this->action); + } catch (Exception $e) { + $this->error($e); + } + + switch ($this->step) + { + case 1: + echo + '

        '.sprintf(__('This will import your Dotclear 1.2 content as new content in the current blog: %s.'), + ''.html::escapeHTML($this->core->blog->name).'').'

        '. + '

        '.__('Please note that this process '. + 'will empty your categories, blogroll, entries and comments on the current blog.').'

        '. + '

        '.__('Depending on the size of your blog, it could take a few minutes.').'

        '; + + printf($this->imForm(1,__('General information'),__('Import my blog now')), + '

        '.__('We first need some information about your old Dotclear 1.2 installation.').'

        '. + '

        '. + '

        '. + '

        '. + '

        '. + '

        '. + '

        '.__('Entries import options').'

        '. + '

        ' + ); + break; + case 2: + printf($this->imForm(2,__('Importing users')), + $this->autoSubmit() + ); + break; + case 3: + printf($this->imForm(3,__('Importing categories')), + $this->autoSubmit() + ); + break; + case 4: + printf($this->imForm(4,__('Importing blogroll')), + $this->autoSubmit() + ); + break; + case 5: + $t = sprintf(__('Importing entries from %d to %d / %d'),$this->post_offset, + min(array($this->post_offset+$this->post_limit,$this->post_count)),$this->post_count); + printf($this->imForm(5,$t), + form::hidden(array('offset'),$this->post_offset). + $this->autoSubmit() + ); + break; + case 6: + echo + '

        '.__('Please read carefully').'

        '. + '
          '. + '
        • '.__('Every newly imported user has received a random password '. + 'and will need to ask for a new one by following the "I forgot my password" link on the login page '. + '(Their registered email address has to be valid.)').'
        • '. + + '
        • '.sprintf(__('Please note that Dotclear 2 has a new URL layout. You can avoid broken '. + 'links by installing DC1 redirect plugin and activate it in your blog configuration.'), + 'http://plugins.dotaddict.org/dc2/details/dc1redirect').'
        • '. + '
        '. + + $this->congratMessage(); + + break; + } + } + + # Simple form for step by step process + protected function imForm($step,$legend,$submit_value=null) + { + if (!$submit_value) { + $submit_value = __('next step').' >'; + } + + return + '
        '. + '
        '.$legend.''. + $this->core->formNonce(). + form::hidden(array('do'),'step'.$step). + '%s'. + '

        '. + '
        '. + '
        '; + } + + # Error display + protected function error($e) + { + echo '
        '.__('Errors:').''. + '

        '.$e->getMessage().'

        '; + } + + # Database init + protected function db() + { + $db = dbLayer::init('mysql',$this->vars['db_host'],$this->vars['db_name'],$this->vars['db_user'],$this->vars['db_pwd']); + + $rs = $db->select("SHOW TABLES LIKE '".$this->vars['db_prefix']."%'"); + if ($rs->isEmpty()) { + throw new Exception(__('Dotclear tables not found')); + } + + while ($rs->fetch()) { + $this->has_table[$rs->f(0)] = true; + } + + # Set this to read data as they were written in Dotclear 1 + try { + $db->execute('SET NAMES DEFAULT'); + } catch (Exception $e) {} + + $db->execute('SET CHARACTER SET DEFAULT'); + $db->execute("SET COLLATION_CONNECTION = DEFAULT"); + $db->execute("SET COLLATION_SERVER = DEFAULT"); + $db->execute("SET CHARACTER_SET_SERVER = DEFAULT"); + $db->execute("SET CHARACTER_SET_DATABASE = DEFAULT"); + + $this->post_count = $db->select( + 'SELECT COUNT(post_id) FROM '.$this->vars['db_prefix'].'post ' + )->f(0); + + return $db; + } + + protected function cleanStr($str) + { + return text::cleanUTF8(@text::toUTF8($str)); + } + + # Users import + protected function importUsers() + { + $db = $this->db(); + $prefix = $this->vars['db_prefix']; + $rs = $db->select('SELECT * FROM '.$prefix.'user'); + + try + { + $this->con->begin(); + + while ($rs->fetch()) + { + if (!$this->core->userExists($rs->user_id)) + { + $cur = $this->con->openCursor($this->prefix.'user'); + $cur->user_id = $rs->user_id; + $cur->user_name = $rs->user_nom; + $cur->user_firstname = $rs->user_prenom; + $cur->user_displayname = $rs->user_pseudo; + $cur->user_pwd = crypt::createPassword(); + $cur->user_email = $rs->user_email; + $cur->user_lang = $rs->user_lang; + $cur->user_tz = $this->core->blog->settings->system->blog_timezone; + $cur->user_post_status = $rs->user_post_pub ? 1 : -2; + $cur->user_options = new ArrayObject(array( + 'edit_size' => (integer) $rs->user_edit_size, + 'post_format' => $rs->user_post_format + )); + + $permissions = array(); + switch ($rs->user_level) + { + case '0': + $cur->user_status = 0; + break; + case '1': # editor + $permissions['usage'] = true; + break; + case '5': # advanced editor + $permissions['contentadmin'] = true; + $permissions['categories'] = true; + $permissions['media_admin'] = true; + break; + case '9': # admin + $permissions['admin'] = true; + break; + } + + $this->core->addUser($cur); + $this->core->setUserBlogPermissions( + $rs->user_id, + $this->blog_id, + $permissions + ); + } + } + + $this->con->commit(); + $db->close(); + } + catch (Exception $e) + { + $this->con->rollback(); + $db->close(); + throw $e; + } + } + + # Categories import + protected function importCategories() + { + $db = $this->db(); + $prefix = $this->vars['db_prefix']; + $rs = $db->select('SELECT * FROM '.$prefix.'categorie ORDER BY cat_ord ASC'); + + try + { + $this->con->execute( + 'DELETE FROM '.$this->prefix.'category '. + "WHERE blog_id = '".$this->con->escape($this->blog_id)."' " + ); + + $ord = 2; + while ($rs->fetch()) + { + $cur = $this->con->openCursor($this->prefix.'category'); + $cur->blog_id = $this->blog_id; + $cur->cat_title = $this->cleanStr(htmlspecialchars_decode($rs->cat_libelle)); + $cur->cat_desc = $this->cleanStr($rs->cat_desc); + $cur->cat_url = $this->cleanStr($rs->cat_libelle_url); + $cur->cat_lft = $ord++; + $cur->cat_rgt = $ord++; + + $cur->cat_id = $this->con->select( + 'SELECT MAX(cat_id) FROM '.$this->prefix.'category' + )->f(0) + 1; + $this->vars['cat_ids'][$rs->cat_id] = $cur->cat_id; + $cur->insert(); + } + + $db->close(); + } + catch (Exception $e) + { + $db->close(); + throw $e; + } + } + + # Blogroll import + protected function importLinks() + { + $db = $this->db(); + $prefix = $this->vars['db_prefix']; + $rs = $db->select('SELECT * FROM '.$prefix.'link ORDER BY link_id ASC'); + + try + { + $this->con->execute( + 'DELETE FROM '.$this->prefix.'link '. + "WHERE blog_id = '".$this->con->escape($this->blog_id)."' " + ); + + while ($rs->fetch()) + { + $cur = $this->con->openCursor($this->prefix.'link'); + $cur->blog_id = $this->blog_id; + $cur->link_href = $this->cleanStr($rs->href); + $cur->link_title = $this->cleanStr($rs->label); + $cur->link_desc = $this->cleanStr($rs->title); + $cur->link_lang = $this->cleanStr($rs->lang); + $cur->link_xfn = $this->cleanStr($rs->rel); + $cur->link_position = (integer) $rs->position; + + $cur->link_id = $this->con->select( + 'SELECT MAX(link_id) FROM '.$this->prefix.'link' + )->f(0) + 1; + $cur->insert(); + } + + $db->close(); + } + catch (Exception $e) + { + $db->close(); + throw $e; + } + } + + # Entries import + protected function importPosts(&$percent) + { + $db = $this->db(); + $prefix = $this->vars['db_prefix']; + + $count = $db->select('SELECT COUNT(post_id) FROM '.$prefix.'post')->f(0); + + $rs = $db->select( + 'SELECT * FROM '.$prefix.'post ORDER BY post_id ASC '. + $db->limit($this->post_offset,$this->post_limit) + ); + + try + { + if ($this->post_offset == 0) + { + $this->con->execute( + 'DELETE FROM '.$this->prefix.'post '. + "WHERE blog_id = '".$this->con->escape($this->blog_id)."' " + ); + } + + while ($rs->fetch()) { + $this->importPost($rs,$db); + } + + $db->close(); + } + catch (Exception $e) + { + $db->close(); + throw $e; + } + + if ($rs->count() < $this->post_limit) { + return -1; + } else { + $this->post_offset += $this->post_limit; + } + + if ($this->post_offset > $this->post_count) { + $percent = 100; + } else { + $percent = $this->post_offset * 100 / $this->post_count; + } + } + + protected function importPost($rs,$db) + { + $cur = $this->con->openCursor($this->prefix.'post'); + $cur->blog_id = $this->blog_id; + $cur->user_id = $rs->user_id; + $cur->cat_id = (integer) $this->vars['cat_ids'][$rs->cat_id]; + $cur->post_dt = $rs->post_dt; + $cur->post_creadt = $rs->post_creadt; + $cur->post_upddt = $rs->post_upddt; + $cur->post_title = html::decodeEntities($this->cleanStr($rs->post_titre)); + + $cur->post_url = date('Y/m/d/',strtotime($cur->post_dt)).$rs->post_id.'-'.$rs->post_titre_url; + $cur->post_url = substr($cur->post_url,0,255); + + $cur->post_format = $rs->post_content_wiki == '' ? 'xhtml' : 'wiki'; + $cur->post_content_xhtml = $this->cleanStr($rs->post_content); + $cur->post_excerpt_xhtml = $this->cleanStr($rs->post_chapo); + + if ($cur->post_format == 'wiki') { + $cur->post_content = $this->cleanStr($rs->post_content_wiki); + $cur->post_excerpt = $this->cleanStr($rs->post_chapo_wiki); + } else { + $cur->post_content = $this->cleanStr($rs->post_content); + $cur->post_excerpt = $this->cleanStr($rs->post_chapo); + } + + $cur->post_notes = $this->cleanStr($rs->post_notes); + $cur->post_status = (integer) $rs->post_pub; + $cur->post_selected = (integer) $rs->post_selected; + $cur->post_open_comment = (integer) $rs->post_open_comment; + $cur->post_open_tb = (integer) $rs->post_open_tb; + $cur->post_lang = $rs->post_lang; + + $cur->post_words = implode(' ',text::splitWords( + $cur->post_title.' '. + $cur->post_excerpt_xhtml.' '. + $cur->post_content_xhtml + )); + + $cur->post_id = $this->con->select( + 'SELECT MAX(post_id) FROM '.$this->prefix.'post' + )->f(0) + 1; + + $cur->insert(); + $this->importComments($rs->post_id,$cur->post_id,$db); + $this->importPings($rs->post_id,$cur->post_id,$db); + + # Load meta if we have some in DC1 + if (isset($this->has_table[$this->vars['db_prefix'].'post_meta'])) { + $this->importMeta($rs->post_id,$cur->post_id,$db); + } + } + + # Comments import + protected function importComments($post_id,$new_post_id,$db) + { + $count_c = $count_t = 0; + + $rs = $db->select( + 'SELECT * FROM '.$this->vars['db_prefix'].'comment '. + 'WHERE post_id = '.(integer) $post_id.' ' + ); + + while ($rs->fetch()) + { + $cur = $this->con->openCursor($this->prefix.'comment'); + $cur->post_id = (integer) $new_post_id; + $cur->comment_author = $this->cleanStr($rs->comment_auteur); + $cur->comment_status = (integer) $rs->comment_pub; + $cur->comment_dt = $rs->comment_dt; + $cur->comment_upddt = $rs->comment_upddt; + $cur->comment_email = $this->cleanStr($rs->comment_email); + $cur->comment_content = $this->cleanStr($rs->comment_content); + $cur->comment_ip = $rs->comment_ip; + $cur->comment_trackback = (integer) $rs->comment_trackback; + + $cur->comment_site = $this->cleanStr($rs->comment_site); + if ($cur->comment_site != '' && !preg_match('!^http://.*$!',$cur->comment_site)) { + $cur->comment_site = substr('http://'.$cur->comment_site,0,255); + } + + if ($rs->exists('spam') && $rs->spam && $rs->comment_status = 0) { + $cur->comment_status = -2; + } + + $cur->comment_words = implode(' ',text::splitWords($cur->comment_content)); + + $cur->comment_id = $this->con->select( + 'SELECT MAX(comment_id) FROM '.$this->prefix.'comment' + )->f(0) + 1; + + $cur->insert(); + + if ($cur->comment_trackback && $cur->comment_status == 1) { + $count_t++; + } elseif ($cur->comment_status == 1) { + $count_c++; + } + } + + if ($count_t > 0 || $count_c > 0) + { + $this->con->execute( + 'UPDATE '.$this->prefix.'post SET '. + 'nb_comment = '.$count_c.', '. + 'nb_trackback = '.$count_t.' '. + 'WHERE post_id = '.(integer) $new_post_id.' ' + ); + } + } + + # Pings import + protected function importPings($post_id,$new_post_id,$db) + { + $urls = array(); + + $rs = $db->select( + 'SELECT * FROM '.$this->vars['db_prefix'].'ping '. + 'WHERE post_id = '.(integer) $post_id + ); + + while ($rs->fetch()) + { + $url = $this->cleanStr($rs->ping_url); + if (isset($urls[$url])) { + continue; + } + + $cur = $this->con->openCursor($this->prefix.'ping'); + $cur->post_id = (integer) $new_post_id; + $cur->ping_url = $url; + $cur->ping_dt = $rs->ping_dt; + $cur->insert(); + + $urls[$url] = true; + } + } + + # Meta import + protected function importMeta($post_id,$new_post_id,$db) + { + $rs = $db->select( + 'SELECT * FROM '.$this->vars['db_prefix'].'post_meta '. + 'WHERE post_id = '.(integer) $post_id.' ' + ); + + if ($rs->isEmpty()) { + return; + } + + while ($rs->fetch()) { + $this->core->meta->setPostMeta($new_post_id,$this->cleanStr($rs->meta_key),$this->cleanStr($rs->meta_value)); + } + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/importExport/inc/class.dc.import.feed.php b/v2/dotclear/plugins/importExport/inc/class.dc.import.feed.php new file mode 100644 index 0000000..cca76c1 --- /dev/null +++ b/v2/dotclear/plugins/importExport/inc/class.dc.import.feed.php @@ -0,0 +1,99 @@ +type = 'import'; + $this->name = __('Feed import'); + $this->description = __('Imports a feed as new entries.'); + } + + public function process($do) + { + if ($do == 'ok') { + $this->status = true; + return; + } + + if (empty($_POST['feed_url'])) { + return; + } + + $this->feed_url = $_POST['feed_url']; + + $feed = feedReader::quickParse($this->feed_url); + if ($feed === false) { + throw new Exception(__('Cannot retrieve feed URL.')); + } + if (count($feed->items) == 0) { + throw new Exception(__('No items in feed.')); + } + + $cur = $this->core->con->openCursor($this->core->prefix.'post'); + $this->core->con->begin(); + foreach ($feed->items as $item) + { + $cur->clean(); + $cur->user_id = $this->core->auth->userID(); + $cur->post_content = $item->content ? $item->content : $item->description; + $cur->post_title = $item->title ? $item->title : text::cutString(html::clean($cur->post_content),60); + $cur->post_format = 'xhtml'; + $cur->post_status = -2; + $cur->post_dt = strftime('%Y-%m-%d %H:%M:%S',$item->TS); + + try { + $post_id = $this->core->blog->addPost($cur); + } catch (Exception $e) { + $this->core->con->rollback(); + throw $e; + } + + foreach ($item->subject as $subject) { + $this->core->meta->setPostMeta($post_id,'tag',dcMeta::sanitizeMetaID($subject)); + } + } + + $this->core->con->commit(); + http::redirect($this->getURL().'&do=ok'); + + } + + public function gui() + { + if ($this->status) { + echo '

        '.__('Content successfully imported.').'

        '; + } + + echo + '
        '. + '
        '.__('Single blog').''. + '

        '.sprintf(__('This will import a feed (RSS or Atom) a as new content in the current blog: %s.'),html::escapeHTML($this->core->blog->name)).'

        '. + + '

        '. + form::field('feed_url',50,300,html::escapeHTML($this->feed_url)).'

        '. + + '

        '. + $this->core->formNonce(). + form::hidden(array('do'),1). + '

        '. + + '
        '. + '
        '; + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/importExport/inc/class.dc.import.flat.php b/v2/dotclear/plugins/importExport/inc/class.dc.import.flat.php new file mode 100644 index 0000000..96f2c6c --- /dev/null +++ b/v2/dotclear/plugins/importExport/inc/class.dc.import.flat.php @@ -0,0 +1,325 @@ +type = 'import'; + $this->name = __('Flat file import'); + $this->description = __('Imports a blog or a full Dotclear installation from flat file.'); + } + + public function process($do) + { + if ($do == 'single' || $do == 'full') { + $this->status = $do; + return; + } + + $to_unlink = false; + + # Single blog import + $files = $this->getPublicFiles(); + $single_upl = null; + if (!empty($_POST['public_single_file']) && in_array($_POST['public_single_file'],$files)) { + $single_upl = false; + } elseif (!empty($_FILES['up_single_file'])) { + $single_upl = true; + } + + if ($single_upl !== null) + { + if ($single_upl) { + files::uploadStatus($_FILES['up_single_file']); + $file = DC_TPL_CACHE.'/'.md5(uniqid()); + if (!move_uploaded_file($_FILES['up_single_file']['tmp_name'],$file)) { + throw new Exception(__('Unable to move uploaded file.')); + } + $to_unlink = true; + } else { + $file = $_POST['public_single_file']; + } + + try { + # Try to unzip file + $unzip_file = $this->unzip($file); + if (false !== $unzip_file) { + $bk = new flatImport($this->core,$unzip_file); + } + # Else this is a normal file + else { + $bk = new flatImport($this->core,$file); + } + + $bk->importSingle(); + } catch (Exception $e) { + @unlink($unzip_file); + if ($to_unlink) { + @unlink($file); + } + throw $e; + } + @unlink($unzip_file); + if ($to_unlink) { + @unlink($file); + } + http::redirect($this->getURL().'&do=single'); + } + + # Full import + $full_upl = null; + if (!empty($_POST['public_full_file']) && in_array($_POST['public_full_file'],$files)) { + $full_upl = false; + } elseif (!empty($_FILES['up_full_file'])) { + $full_upl = true; + } + + if ($full_upl !== null && $this->core->auth->isSuperAdmin()) + { + if (empty($_POST['your_pwd']) || !$this->core->auth->checkPassword(crypt::hmac(DC_MASTER_KEY,$_POST['your_pwd']))) { + throw new Exception(__('Password verification failed')); + } + + if ($full_upl) { + files::uploadStatus($_FILES['up_full_file']); + $file = DC_TPL_CACHE.'/'.md5(uniqid()); + if (!move_uploaded_file($_FILES['up_full_file']['tmp_name'],$file)) { + throw new Exception(__('Unable to move uploaded file.')); + } + $to_unlink = true; + } else { + $file = $_POST['public_full_file']; + } + + try { + # Try to unzip file + $unzip_file = $this->unzip($file); + if (false !== $unzip_file) { + $bk = new flatImport($this->core,$unzip_file); + } + # Else this is a normal file + else { + $bk = new flatImport($this->core,$file); + } + + $bk->importFull(); + } catch (Exception $e) { + @unlink($unzip_file); + if ($to_unlink) { + @unlink($file); + } + throw $e; + } + @unlink($unzip_file); + if ($to_unlink) { + @unlink($file); + } + http::redirect($this->getURL().'&do=full'); + } + + header('content-type:text/plain'); + var_dump($_POST); + exit; + + $this->status = true; + } + + public function gui() + { + if ($this->status == 'single') + { + echo '

        '.__('Single blog successfully imported.').'

        '; + return; + } + if ($this->status == 'full') + { + echo '

        '.__('Content successfully imported.').'

        '; + return; + } + + $public_files = array_merge(array('-' => ''),$this->getPublicFiles()); + $has_files = (boolean) (count($public_files) - 1); + + echo + '\n"; + + echo + '
        '. + '
        '.__('Single blog').''. + '

        '.sprintf(__('This will import a single blog backup as new content in the current blog: %s.'),html::escapeHTML($this->core->blog->name)).'

        '. + + '

        '. + ''. + '

        '; + + if ($has_files) { + echo + '

        '; + } + + echo + '

        '. + $this->core->formNonce(). + form::hidden(array('do'),1). + form::hidden(array('MAX_FILE_SIZE'),DC_MAX_UPLOAD_SIZE). + '

        '. + + '
        '. + '
        '; + + if ($this->core->auth->isSuperAdmin()) + { + echo + '
        '. + '
        '.__('Multiple blogs').''. + '

        '.__('This will reset all the content of your database, except users.').'

        '. + + '

        '. + ''. + '

        '; + + if ($has_files) { + echo + '

        '. + form::combo('public_full_file',$public_files). + '

        '; + } + + echo + '

        '. + form::password('your_pwd',20,255).'

        '. + + '

        '. + $this->core->formNonce(). + form::hidden(array('do'),1). + form::hidden(array('MAX_FILE_SIZE'),DC_MAX_UPLOAD_SIZE). + '

        '. + + '
        '. + '
        '; + } + } + + protected function getPublicFiles() + { + $public_files = array(); + $dir = @dir($this->core->blog->public_path); + if ($dir) + { + while (($entry = $dir->read()) !== false) { + $entry_path = $dir->path.'/'.$entry; + + if (is_file($entry_path) && is_readable($entry_path)) + { + # Do not test each zip file content here, its too long + if (substr($entry_path,-4) == '.zip') { + $public_files[$entry] = $entry_path; + } + elseif (self::checkFileContent($entry_path)) { + $public_files[$entry] = $entry_path; + } + } + } + } + return $public_files; + } + + protected static function checkFileContent($entry_path) + { + $ret = false; + + $fp = fopen($entry_path,'rb'); + $ret = strpos(fgets($fp),'///DOTCLEAR|') === 0; + fclose($fp); + + return $ret; + } + + private function unzip($file) + { + $zip = new fileUnzip($file); + + if ($zip->isEmpty()) { + $zip->close(); + return false;//throw new Exception(__('File is empty or not a compressed file.')); + } + + foreach($zip->getFilesList() as $zip_file) + { + # Check zipped file name + if (substr($zip_file,-4) != '.txt') { + continue; + } + + # Check zipped file contents + $content = $zip->unzip($zip_file); + if (strpos($content,'///DOTCLEAR|') !== 0) { + unset($content); + continue; + } + + $target = path::fullFromRoot($zip_file,dirname($file)); + + # Check existing files with same name + if (file_exists($target)) { + $zip->close(); + unset($content); + throw new Exception(__('Another file with same name exists.')); + } + + # Extract backup content + if (file_put_contents($target,$content) === false) { + $zip->close(); + unset($content); + throw new Exception(__('Failed to extract backup file.')); + } + + $zip->close(); + unset($content); + + # Return extracted file name + return $target; + } + + $zip->close(); + throw new Exception(__('No backup in compressed file.')); + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/importExport/inc/class.dc.import.wp.php b/v2/dotclear/plugins/importExport/inc/class.dc.import.wp.php new file mode 100644 index 0000000..3336f11 --- /dev/null +++ b/v2/dotclear/plugins/importExport/inc/class.dc.import.wp.php @@ -0,0 +1,788 @@ + '', + 'db_name' => '', + 'db_user' => '', + 'db_pwd' => '', + 'db_prefix' => 'wp_', + 'ignore_first_cat' => 1, + 'cat_import' => 1, + 'cat_as_tags' => '', + 'cat_tags_prefix' => 'cat: ', + 'post_limit' => 20, + 'post_formater' => 'xhtml', + 'comment_formater' => 'xhtml', + 'user_ids' => array(), + 'cat_ids' => array(), + 'permalink_template' => 'p=%post_id%', + 'permalink_tags' => array( + '%year%', + '%monthnum%', + '%day%', + '%hour%', + '%minute%', + '%second%', + '%postname%', + '%post_id%', + '%category%', + '%author%' + ) + ); + protected $formaters; + + protected function setInfo() + { + $this->type = 'import'; + $this->name = __('WordPress import'); + $this->description = __('Import a WordPress installation into your current blog.'); + } + + public function init() + { + $this->con =& $this->core->con; + $this->prefix = $this->core->prefix; + $this->blog_id = $this->core->blog->id; + + if (!isset($_SESSION['wp_import_vars'])) { + $_SESSION['wp_import_vars'] = $this->base_vars; + } + $this->vars =& $_SESSION['wp_import_vars']; + + if ($this->vars['post_limit'] > 0) { + $this->post_limit = $this->vars['post_limit']; + } + + foreach ($this->core->getFormaters() as $v) { + $this->formaters[$v] = $v; + } + } + + public function resetVars() + { + $this->vars = $this->base_vars;; + unset($_SESSION['wp_import_vars']); + } + + public function process($do) + { + $this->action = $do; + } + + # We handle process in another way to always display something to + # user + protected function guiprocess($do) + { + switch ($do) + { + case 'step1': + $this->vars['db_host'] = $_POST['db_host']; + $this->vars['db_name'] = $_POST['db_name']; + $this->vars['db_user'] = $_POST['db_user']; + $this->vars['db_pwd'] = $_POST['db_pwd']; + $this->vars['db_prefix'] = $_POST['db_prefix']; + $this->vars['ignore_first_cat'] = isset($_POST['ignore_first_cat']); + $this->vars['cat_import'] = isset($_POST['cat_import']); + $this->vars['cat_as_tags'] = isset($_POST['cat_as_tags']); + $this->vars['cat_tags_prefix'] = $_POST['cat_tags_prefix']; + $this->vars['post_limit'] = abs((integer) $_POST['post_limit']) > 0 ? $_POST['post_limit'] : 0; + $this->vars['post_formater'] = isset($this->formaters[$_POST['post_formater']]) ? $_POST['post_formater'] : 'xhtml'; + $this->vars['comment_formater'] = isset($this->formaters[$_POST['comment_formater']]) ? $_POST['comment_formater'] : 'xhtml'; + $db = $this->db(); + $db->close(); + $this->step = 2; + echo $this->progressBar(1); + break; + case 'step2': + $this->step = 2; + $this->importUsers(); + $this->step = 3; + echo $this->progressBar(3); + break; + case 'step3': + $this->step = 3; + $this->importCategories(); + if ($this->core->plugins->moduleExists('blogroll')) { + $this->step = 4; + echo $this->progressBar(5); + } else { + $this->step = 5; + echo $this->progressBar(7); + } + break; + case 'step4': + $this->step = 4; + $this->importLinks(); + $this->step = 5; + echo $this->progressBar(7); + break; + case 'step5': + $this->step = 5; + $this->post_offset = !empty($_REQUEST['offset']) ? abs((integer) $_REQUEST['offset']) : 0; + if ($this->importPosts($percent) === -1) { + http::redirect($this->getURL().'&do=ok'); + } else { + echo $this->progressBar(ceil($percent*0.93)+7); + } + break; + case 'ok': + $this->resetVars(); + $this->core->blog->triggerBlog(); + $this->step = 6; + echo $this->progressBar(100); + break; + } + } + + public function gui() + { + try { + $this->guiprocess($this->action); + } catch (Exception $e) { + $this->error($e); + } + + switch ($this->step) + { + case 1: + echo + '

        '.sprintf(__('This will import your WordPress content as new content in the current blog: %s.'), + ''.html::escapeHTML($this->core->blog->name).'').'

        '. + '

        '.__('Please note that this process '. + 'will empty your categories, blogroll, entries and comments on the current blog.').'

        '. + '

        '.__('Depending on the size of your blog, it could take a few minutes.').'

        '; + + printf($this->imForm(1,__('General information'),__('Import my blog now')), + '

        '.__('We first need some information about your old WordPress installation.').'

        '. + '

        '. + '

        '. + '

        '. + '

        '. + '

        '. + '

        '.__('Entries import options').'

        '. + '

        '.__('WordPress and Dotclear\'s handling of categories are quite different. '. + 'You can assign several categories to a single post in WordPress. In the Dotclear world, '. + 'we see it more like "One category, several tags." Therefore Dotclear can only import one '. + 'category per post and will chose the lowest numbered one. If you want to keep a trace of '. + 'every category, you can import them as tags, with an optional prefix.').'

        '. + '

        '.__('On the other hand, in WordPress, a post can not be uncategorized, and a default '. + 'installation has a first category labelised "Uncategorized". If you did not change that '. + 'category, you can just ignore it while importing your blog, as Dotclear allows you to '. + 'actually keep your posts uncategorized.').'

        '. + '

        '. + '

        '. + '

        '. + '

        '. + '

        '. + + '

        '.__('Content filters').'

        '. + '

        '.__('You may want to process your post and/or comment content with the following filters.').'

        '. + '

        '. + '

        ' + ); + break; + case 2: + printf($this->imForm(2,__('Importing users')), + $this->autoSubmit() + ); + break; + case 3: + printf($this->imForm(3,__('Importing categories')), + $this->autoSubmit() + ); + break; + case 4: + printf($this->imForm(4,__('Importing blogroll')), + $this->autoSubmit() + ); + break; + case 5: + $t = sprintf(__('Importing entries from %d to %d / %d'),$this->post_offset, + min(array($this->post_offset+$this->post_limit,$this->post_count)),$this->post_count); + printf($this->imForm(5,$t), + form::hidden(array('offset'),$this->post_offset). + $this->autoSubmit() + ); + break; + case 6: + echo + '

        '.__('Every newly imported user has received a random password '. + 'and will need to ask for a new one by following the "I forgot my password" link on the login page '. + '(Their registered email address has to be valid.)').'

        '. + $this->congratMessage(); + break; + } + } + + # Simple form for step by step process + protected function imForm($step,$legend,$submit_value=null) + { + if (!$submit_value) { + $submit_value = __('next step').' >'; + } + + return + '
        '. + '
        '.$legend.''. + $this->core->formNonce(). + form::hidden(array('do'),'step'.$step). + '%s'. + '

        '. + '
        '. + '
        '; + } + + # Error display + protected function error($e) + { + echo '
        '.__('Errors:').''. + '

        '.$e->getMessage().'

        '; + } + + # Database init + protected function db() + { + $db = dbLayer::init('mysql',$this->vars['db_host'],$this->vars['db_name'],$this->vars['db_user'],$this->vars['db_pwd']); + + $rs = $db->select("SHOW TABLES LIKE '".$this->vars['db_prefix']."%'"); + if ($rs->isEmpty()) { + throw new Exception(__('WordPress tables not found')); + } + + while ($rs->fetch()) { + $this->has_table[$rs->f(0)] = true; + } + + # Set this to read data as they were written + try { + $db->execute('SET NAMES DEFAULT'); + } catch (Exception $e) {} + + $db->execute('SET CHARACTER SET DEFAULT'); + $db->execute("SET COLLATION_CONNECTION = DEFAULT"); + $db->execute("SET COLLATION_SERVER = DEFAULT"); + $db->execute("SET CHARACTER_SET_SERVER = DEFAULT"); + $db->execute("SET CHARACTER_SET_DATABASE = DEFAULT"); + + $this->post_count = $db->select( + 'SELECT COUNT(ID) FROM '.$this->vars['db_prefix'].'posts '. + 'WHERE post_type = \'post\' OR post_type = \'page\'' + )->f(0); + + return $db; + } + + protected function cleanStr($str) + { + return text::cleanUTF8(@text::toUTF8($str)); + } + + # Users import + protected function importUsers() + { + $db = $this->db(); + $prefix = $this->vars['db_prefix']; + $rs = $db->select('SELECT * FROM '.$prefix.'users'); + + try + { + $this->con->begin(); + + while ($rs->fetch()) + { + $user_login = preg_replace('/[^A-Za-z0-9@._-]/','-',$rs->user_login); + $this->vars['user_ids'][$rs->ID] = $user_login; + if (!$this->core->userExists($user_login)) + { + $cur = $this->con->openCursor($this->prefix.'user'); + $cur->user_id = $user_login; + $cur->user_pwd = crypt::createPassword(); + $cur->user_displayname = $rs->user_nicename; + $cur->user_email = $rs->user_email; + $cur->user_url = $rs->user_url; + $cur->user_creadt = $rs->user_registered; + $cur->user_lang = $this->core->blog->settings->system->lang; + $cur->user_tz = $this->core->blog->settings->system->blog_timezone; + $permissions = array(); + + $rs_meta = $db->select('SELECT * FROM '.$prefix.'usermeta WHERE user_id = '.$rs->ID); + while ($rs_meta->fetch()) + { + switch ($rs_meta->meta_key) + { + case 'first_name': + $cur->user_firstname = $this->cleanStr($rs_meta->meta_value); + break; + case 'last_name': + $cur->user_name = $this->cleanStr($rs_meta->meta_value); + break; + case 'description': + $cur->user_desc = $this->cleanStr($rs_meta->meta_value); + break; + case 'rich_editing': + $cur->user_options = new ArrayObject(array( + 'enable_wysiwyg' => $rs_meta->meta_value == 'true' ? true : false + )); + break; + case 'wp_user_level': + switch ($rs_meta->meta_value) + { + case '0': # Subscriber + $cur->user_status = 0; + break; + case '1': # Contributor + $permissions['usage'] = true; + $permissions['publish'] = true; + $permissions['delete'] = true; + break; + case '2': # Author + case '3': + case '4': + $permissions['contentadmin'] = true; + $permissions['media'] = true; + break; + case '5': # Editor + case '6': + case '7': + $permissions['contentadmin'] = true; + $permissions['categories'] = true; + $permissions['media_admin'] = true; + $permissions['pages'] = true; + $permissions['blogroll'] = true; + break; + case '8': # Administrator + case '9': + case '10': + $permissions['admin'] = true; + break; + } + break; + } + } + $this->core->addUser($cur); + $this->core->setUserBlogPermissions( + $cur->user_id, + $this->blog_id, + $permissions + ); + } + } + $this->con->commit(); + $db->close(); + } + catch (Exception $e) + { + $this->con->rollback(); + $db->close(); + throw $e; + } + } + + # Categories import + protected function importCategories() + { + $db = $this->db(); + $prefix = $this->vars['db_prefix']; + $rs = $db->select( + 'SELECT * FROM '.$prefix.'terms AS t, '.$prefix.'term_taxonomy AS x '. + 'WHERE x.taxonomy = \'category\' '. + 'AND t.term_id = x.term_id '. + ($this->vars['ignore_first_cat'] ? 'AND t.term_id <> 1 ' : ''). + 'ORDER BY t.term_id ASC' + ); + + try + { + $this->con->execute( + 'DELETE FROM '.$this->prefix.'category '. + "WHERE blog_id = '".$this->con->escape($this->blog_id)."' " + ); + + $ord = 2; + while ($rs->fetch()) + { + $cur = $this->con->openCursor($this->prefix.'category'); + $cur->blog_id = $this->blog_id; + $cur->cat_title = $this->cleanStr($rs->name); + $cur->cat_desc = $this->cleanStr($rs->description); + $cur->cat_url = $this->cleanStr($rs->slug); + $cur->cat_lft = $ord++; + $cur->cat_rgt = $ord++; + + $cur->cat_id = $this->con->select( + 'SELECT MAX(cat_id) FROM '.$this->prefix.'category' + )->f(0) + 1; + $this->vars['cat_ids'][$rs->term_id] = $cur->cat_id; + $cur->insert(); + } + + $db->close(); + } + catch (Exception $e) + { + $db->close(); + throw $e; + } + } + + # Blogroll import + protected function importLinks() + { + $db = $this->db(); + $prefix = $this->vars['db_prefix']; + $rs = $db->select('SELECT * FROM '.$prefix.'links ORDER BY link_id ASC'); + + try + { + $this->con->execute( + 'DELETE FROM '.$this->prefix.'link '. + "WHERE blog_id = '".$this->con->escape($this->blog_id)."' " + ); + + while ($rs->fetch()) + { + $cur = $this->con->openCursor($this->prefix.'link'); + $cur->blog_id = $this->blog_id; + $cur->link_href = $this->cleanStr($rs->link_url); + $cur->link_title = $this->cleanStr($rs->link_name); + $cur->link_desc = $this->cleanStr($rs->link_description); + $cur->link_xfn = $this->cleanStr($rs->link_rel); + + $cur->link_id = $this->con->select( + 'SELECT MAX(link_id) FROM '.$this->prefix.'link' + )->f(0) + 1; + $cur->insert(); + } + + $db->close(); + } + catch (Exception $e) + { + $db->close(); + throw $e; + } + } + + # Entries import + protected function importPosts(&$percent) + { + $db = $this->db(); + $prefix = $this->vars['db_prefix']; + + $plink = $db->select( + 'SELECT option_value FROM '.$prefix.'options '. + "WHERE option_name = 'permalink_structure'" + )->option_value; + if ($plink) { + $this->vars['permalink_template'] = substr($plink,1); + } + + $rs = $db->select( + 'SELECT * FROM '.$prefix.'posts '. + 'WHERE post_type = \'post\' OR post_type = \'page\' '. + 'ORDER BY ID ASC '. + $db->limit($this->post_offset,$this->post_limit) + ); + + try + { + if ($this->post_offset == 0) + { + $this->con->execute( + 'DELETE FROM '.$this->prefix.'post '. + "WHERE blog_id = '".$this->con->escape($this->blog_id)."' " + ); + } + + while ($rs->fetch()) { + $this->importPost($rs,$db); + } + + $db->close(); + } + catch (Exception $e) + { + $db->close(); + throw $e; + } + + if ($rs->count() < $this->post_limit) { + return -1; + } else { + $this->post_offset += $this->post_limit; + } + + if ($this->post_offset > $this->post_count) { + $percent = 100; + } else { + $percent = $this->post_offset * 100 / $this->post_count; + } + } + + protected function importPost($rs,$db) + { + $post_date = !@strtotime($rs->post_date) ? '1970-01-01 00:00' : $rs->post_date; + if (!isset($this->vars['user_ids'][$rs->post_author])) { + $user_id = $this->core->auth->userID(); + } else { + $user_id = $this->vars['user_ids'][$rs->post_author]; + } + + $cur = $this->con->openCursor($this->prefix.'post'); + $cur->blog_id = $this->blog_id; + $cur->user_id = $user_id; + $cur->post_dt = $post_date; + $cur->post_creadt = $post_date; + $cur->post_upddt = $rs->post_modified; + $cur->post_title = $this->cleanStr($rs->post_title); + + if (!$cur->post_title) { + $cur->post_title = 'No title'; + } + + if ($this->vars['cat_import'] || $this->vars['cat_as_tags']) + { + $old_cat_ids = $db->select( + 'SELECT * FROM '.$this->vars['db_prefix'].'terms AS t, '. + $this->vars['db_prefix'].'term_taxonomy AS x, '. + $this->vars['db_prefix'].'term_relationships AS r '. + 'WHERE t.term_id = x.term_id '. + ($this->vars['ignore_first_cat'] ? 'AND t.term_id <> 1 ' : ''). + 'AND x.taxonomy = \'category\' '. + 'AND t.term_id = r.term_taxonomy_id '. + 'AND r.object_id ='.$rs->ID. + ' ORDER BY t.term_id ASC ' + ); + if (!$old_cat_ids->isEmpty() && $this->vars['cat_import']) + { + $cur->cat_id = $this->vars['cat_ids'][(integer) $old_cat_ids->term_id]; + } + } + + $permalink_infos = array( + date('Y',strtotime($cur->post_dt)), + date('m',strtotime($cur->post_dt)), + date('d',strtotime($cur->post_dt)), + date('H',strtotime($cur->post_dt)), + date('i',strtotime($cur->post_dt)), + date('s',strtotime($cur->post_dt)), + $rs->post_name, + $rs->ID, + $cur->cat_id, + $cur->user_id + ); + $cur->post_url = str_replace( + $this->vars['permalink_tags'], + $permalink_infos, + $rs->post_type== 'post' ? $this->vars['permalink_template'] : '%postname%' + ); + $cur->post_url = substr($cur->post_url,0,255); + + if (!$cur->post_url) { + $cur->post_url = $rs->ID; + } + + $cur->post_format = $this->vars['post_formater']; + $_post_content = explode('',$rs->post_content,2); + if (count($_post_content) == 1) { + $cur->post_excerpt = NULL; + $cur->post_content = $this->cleanStr(array_shift($_post_content)); + } else { + $cur->post_excerpt = $this->cleanStr(array_shift($_post_content)); + $cur->post_content = $this->cleanStr(array_shift($_post_content)); + } + + $cur->post_content_xhtml = $this->core->callFormater($this->vars['post_formater'],$cur->post_content); + $cur->post_excerpt_xhtml = $this->core->callFormater($this->vars['post_formater'],$cur->post_excerpt); + + switch ($rs->post_status) + { + case 'publish': + $cur->post_status = 1; + break; + case 'draft': + $cur->post_status = 0; + break; + case 'pending': + $cur->post_status = -2; + break; + default: + $cur->post_status = -2; + } + $cur->post_type = $rs->post_type; + $cur->post_password = $rs->post_password ? $rs->post_password : NULL; + $cur->post_open_comment = $rs->comment_status == 'open' ? 1 : 0; + $cur->post_open_tb = $rs->ping_status == 'open' ? 1 : 0; + + $cur->post_words = implode(' ',text::splitWords( + $cur->post_title.' '. + $cur->post_excerpt_xhtml.' '. + $cur->post_content_xhtml + )); + + $cur->post_id = $this->con->select( + 'SELECT MAX(post_id) FROM '.$this->prefix.'post' + )->f(0) + 1; + + $cur->post_url = $this->core->blog->getPostURL($cur->post_url,$cur->post_dt,$cur->post_title,$cur->post_id); + + $cur->insert(); + $this->importComments($rs->ID,$cur->post_id,$db); + $this->importPings($rs->ID,$cur->post_id,$db); + + # Create tags + $this->importTags($rs->ID,$cur->post_id,$db); + + if (!$old_cat_ids->isEmpty() && $this->vars['cat_as_tags']) + { + $old_cat_ids->moveStart(); + while ($old_cat_ids->fetch()) { + $this->core->meta->setPostMeta($cur->post_id,'tag',$this->cleanStr($this->vars['cat_tags_prefix'].$old_cat_ids->name)); + } + } + } + + # Comments import + protected function importComments($post_id,$new_post_id,$db) + { + $count_c = $count_t = 0; + + $rs = $db->select( + 'SELECT * FROM '.$this->vars['db_prefix'].'comments '. + 'WHERE comment_post_ID = '.(integer) $post_id.' ' + ); + + while ($rs->fetch()) + { + $cur = $this->con->openCursor($this->prefix.'comment'); + $cur->post_id = (integer) $new_post_id; + $cur->comment_author = $this->cleanStr($rs->comment_author); + $cur->comment_status = (integer) $rs->comment_approved ; + $cur->comment_dt = $rs->comment_date; + $cur->comment_email = $this->cleanStr($rs->comment_author_email); + $cur->comment_content = $this->core->callFormater($this->vars['comment_formater'],$this->cleanStr($rs->comment_content)); + $cur->comment_ip = $rs->comment_author_IP; + $cur->comment_trackback = $rs->comment_type == 'trackback' ? 1 : 0; + $cur->comment_site = substr($this->cleanStr($rs->comment_author_url),0,255); + if ($cur->comment_site == '') $cur->comment_site = NULL; + + if ($rs->comment_approved == 'spam') { + $cur->comment_status = -2; + } + + $cur->comment_words = implode(' ',text::splitWords($cur->comment_content)); + + $cur->comment_id = $this->con->select( + 'SELECT MAX(comment_id) FROM '.$this->prefix.'comment' + )->f(0) + 1; + + $cur->insert(); + + if ($cur->comment_trackback && $cur->comment_status == 1) { + $count_t++; + } elseif ($cur->comment_status == 1) { + $count_c++; + } + } + + if ($count_t > 0 || $count_c > 0) + { + $this->con->execute( + 'UPDATE '.$this->prefix.'post SET '. + 'nb_comment = '.$count_c.', '. + 'nb_trackback = '.$count_t.' '. + 'WHERE post_id = '.(integer) $new_post_id.' ' + ); + } + } + + # Pings import + protected function importPings($post_id,$new_post_id,$db) + { + $urls = array(); + $pings = array(); + + $rs = $db->select( + 'SELECT pinged FROM '.$this->vars['db_prefix'].'posts '. + 'WHERE ID = '.(integer) $post_id + ); + $pings = explode ("\n",$rs->pinged); + unset ($pings[0]); + + foreach($pings as $ping_url) + { + $url = $this->cleanStr($ping_url); + if (isset($urls[$url])) { + continue; + } + + $cur = $this->con->openCursor($this->prefix.'ping'); + $cur->post_id = (integer) $new_post_id; + $cur->ping_url = $url; + $cur->insert(); + + $urls[$url] = true; + } + } + + # Meta import + protected function importTags($post_id,$new_post_id,$db) + { + $rs = $db->select( + 'SELECT * FROM '.$this->vars['db_prefix'].'terms AS t, '. + $this->vars['db_prefix'].'term_taxonomy AS x, '. + $this->vars['db_prefix'].'term_relationships AS r '. + 'WHERE t.term_id = x.term_id '. + 'AND x.taxonomy = \'post_tag\' '. + 'AND t.term_id = r.term_taxonomy_id '. + 'AND r.object_id ='.$post_id. + ' ORDER BY t.term_id ASC' + ); + + if ($rs->isEmpty()) { + return; + } + + while ($rs->fetch()) { + $this->core->meta->setPostMeta($new_post_id,'tag',$this->cleanStr($rs->name)); + } + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/importExport/inc/flat/class.flat.backup.php b/v2/dotclear/plugins/importExport/inc/flat/class.flat.backup.php new file mode 100644 index 0000000..7e61cad --- /dev/null +++ b/v2/dotclear/plugins/importExport/inc/flat/class.flat.backup.php @@ -0,0 +1,148 @@ +(\\\\\\\\)*+)(\\\\n)/u' => "\$1\n", + '/(?(\\\\\\\\)*+)(\\\\r)/u' => "\$1\r", + '/(?(\\\\\\\\)*+)(\\\\")/u' => '$1"', + '/(\\\\\\\\)/' => '\\' + ); + + public function __construct($file) + { + if (file_exists($file) && is_readable($file)) { + $this->fp = fopen($file,'rb'); + $this->line_num = 1; + } else { + throw new Exception(__('No file to read.')); + } + } + + public function __destruct() + { + if ($this->fp) { + fclose($this->fp); + } + } + + public function getLine() + { + if (($line = $this->nextLine()) === false) { + return false; + } + + if (substr($line,0,1) == '[') + { + $this->line_name = substr($line,1,strpos($line,' ')-1); + + $line = substr($line,strpos($line,' ')+1,-1); + $this->line_cols = explode(',',$line); + + return $this->getLine(); + } + elseif (substr($line,0,1) == '"') + { + $line = preg_replace('/^"|"$/','',$line); + $line = preg_split('/(^"|","|"$)/m',$line); + + if (count($this->line_cols) != count($line)) { + throw new Exception(sprintf('Invalid row count at line %s',$this->line_num)); + } + + $res = array(); + + for ($i=0; $iline_cols[$i]] = + preg_replace(array_keys($this->replacement),array_values($this->replacement),$line[$i]); + } + + return new flatBackupItem($this->line_name,$res,$this->line_num); + } + else + { + return $this->getLine(); + } + } + + private function nextLine() + { + if (feof($this->fp)) { + return false; + } + $this->line_num++; + + $line = fgets($this->fp); + $line = trim($line); + + return empty($line) ? $this->nextLine() : $line; + } +} + +class flatBackupItem +{ + public $__name; + public $__line; + private $__data = array(); + + public function __construct($name,$data,$line) + { + $this->__name = $name; + $this->__data = $data; + $this->__line = $line; + } + + public function f($name) + { + return iconv('UTF-8','UTF-8//IGNORE',$this->__data[$name]); + } + + public function __get($name) + { + return $this->f($name); + } + + public function __set($n,$v) + { + $this->__data[$n] = $v; + } + + public function exists($n) + { + return isset($this->__data[$n]); + } + + public function drop() + { + foreach (func_get_args() as $n) { + if (isset($this->__data[$n])) { + unset($this->__data[$n]); + } + } + } + + public function substitute($old,$new) + { + if (isset($this->__data[$old])) { + $this->__data[$new] = $this->__data[$old]; + unset($this->__data[$old]); + } + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/importExport/inc/flat/class.flat.export.php b/v2/dotclear/plugins/importExport/inc/flat/class.flat.export.php new file mode 100644 index 0000000..eec2b75 --- /dev/null +++ b/v2/dotclear/plugins/importExport/inc/flat/class.flat.export.php @@ -0,0 +1,106 @@ +con =& $con; + $this->prefix = $prefix; + + if (($this->fp = fopen($out,'w')) === false) { + return false; + } + @set_time_limit(300); + } + + function __destruct() + { + if (is_resource($this->fp)) { + fclose($this->fp); + } + } + + function export($name,$sql) + { + $rs = $this->con->select($sql); + + if (!$rs->isEmpty()) + { + fwrite($this->fp,"\n[".$name.' '.implode(',',$rs->columns())."]\n"); + while ($rs->fetch()) { + fwrite($this->fp,$this->getLine($rs)); + } + fflush($this->fp); + } + } + + function exportAll() + { + $tables = $this->getTables(); + + foreach ($tables as $table) + { + $this->exportTable($table); + } + } + + function exportTable($table) + { + $req = 'SELECT * FROM '.$this->con->escapeSystem($this->prefix.$table); + + $this->export($table,$req); + } + + function getTables() + { + $schema = dbSchema::init($this->con); + $db_tables = $schema->getTables(); + + $tables = array(); + foreach ($db_tables as $t) + { + if ($this->prefix) { + if (strpos($t,$this->prefix) === 0) { + $tables[] = $t; + } + } else { + $tables[] = $t; + } + } + + return $tables; + } + + function getLine($rs) + { + $l = array(); + $cols = $rs->columns(); + foreach ($cols as $i => &$c) { + $s = $rs->f($c); + $s = preg_replace($this->line_reg,$this->line_rep,$s); + $s = '"'.$s.'"'; + $l[$i] = $s; + } + return implode(',',$l)."\n"; + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/importExport/inc/flat/class.flat.import.php b/v2/dotclear/plugins/importExport/inc/flat/class.flat.import.php new file mode 100644 index 0000000..bdbd55b --- /dev/null +++ b/v2/dotclear/plugins/importExport/inc/flat/class.flat.import.php @@ -0,0 +1,869 @@ + array(), + 'post' => array(), + 'media' => array() + ); + + public $stack = array( + 'categories'=>null, + 'cat_id'=>1, + 'cat_lft'=>array(), + 'post_id'=>1, + 'media_id'=>1, + 'comment_id'=>1, + 'link_id'=>1 + ); + + public $has_categories = false; + + public function __construct($core,$file) + { + parent::__construct($file); + + $first_line = fgets($this->fp); + if (strpos($first_line,'///DOTCLEAR|') !== 0) { + throw new Exception(__('File is not a DotClear backup.')); + } + + @set_time_limit(300); + + $l = explode('|',$first_line); + + if (isset($l[1])) { + $this->dc_version = $l[1]; + } + + $this->mode = isset($l[2]) ? strtolower(trim($l[2])) : 'single'; + if ($this->mode != 'full' && $this->mode != 'single') { + $this->mode = 'single'; + } + + if (version_compare('1.2',$this->dc_version,'<=') && + version_compare('1.3',$this->dc_version,'>')) { + $this->dc_major_version = '1.2'; + } else { + $this->dc_major_version = '2.0'; + } + + $this->core =& $core; + $this->con =& $core->con; + $this->prefix = $core->prefix; + + $this->cur_blog = $this->con->openCursor($this->prefix.'blog'); + $this->cur_category = $this->con->openCursor($this->prefix.'category'); + $this->cur_link = $this->con->openCursor($this->prefix.'link'); + $this->cur_setting = $this->con->openCursor($this->prefix.'setting'); + $this->cur_user = $this->con->openCursor($this->prefix.'user'); + $this->cur_pref = $this->con->openCursor($this->prefix.'pref'); + $this->cur_permissions = $this->con->openCursor($this->prefix.'permissions'); + $this->cur_post = $this->con->openCursor($this->prefix.'post'); + $this->cur_meta = $this->con->openCursor($this->prefix.'meta'); + $this->cur_media = $this->con->openCursor($this->prefix.'media'); + $this->cur_post_media = $this->con->openCursor($this->prefix.'post_media'); + $this->cur_log = $this->con->openCursor($this->prefix.'log'); + $this->cur_ping = $this->con->openCursor($this->prefix.'ping'); + $this->cur_comment = $this->con->openCursor($this->prefix.'comment'); + $this->cur_spamrule = $this->con->openCursor($this->prefix.'spamrule'); + $this->cur_version = $this->con->openCursor($this->prefix.'version'); + + # --BEHAVIOR-- importInit + $this->core->callBehavior('importInit',$this,$this->core); + } + + public function importSingle() + { + if ($this->mode != 'single') { + throw new Exception(__('File is not a single blog export.')); + } + + if (!$this->core->auth->check('admin',$this->core->blog->id)) { + throw new Exception(__('Permission denied.')); + } + + $this->blog_id = $this->core->blog->id; + + $this->stack['categories'] = $this->con->select( + 'SELECT cat_id, cat_title, cat_url '. + 'FROM '.$this->prefix.'category '. + "WHERE blog_id = '".$this->con->escape($this->blog_id)."' " + ); + + $rs = $this->con->select('SELECT MAX(cat_id) FROM '.$this->prefix.'category'); + $this->stack['cat_id'] = ((integer) $rs->f(0))+1; + + $rs = $this->con->select('SELECT MAX(link_id) FROM '.$this->prefix.'link'); + $this->stack['link_id'] = ((integer) $rs->f(0))+1; + + $rs = $this->con->select('SELECT MAX(post_id) FROM '.$this->prefix.'post'); + $this->stack['post_id'] = ((integer) $rs->f(0))+1; + + $rs = $this->con->select('SELECT MAX(media_id) FROM '.$this->prefix.'media'); + $this->stack['media_id'] = ((integer) $rs->f(0))+1; + + $rs = $this->con->select('SELECT MAX(comment_id) FROM '.$this->prefix.'comment'); + $this->stack['comment_id'] = ((integer) $rs->f(0))+1; + + $rs = $this->con->select( + 'SELECT MAX(cat_rgt) AS cat_rgt FROM '.$this->prefix.'category '. + "WHERE blog_id = '".$this->con->escape($this->core->blog->id)."'" + ); + + if ((integer) $rs->cat_rgt > 0) { + $this->has_categories = true; + $this->stack['cat_lft'][$this->core->blog->id] = (integer) $rs->cat_rgt + 1; + } + + $this->con->begin(); + + try + { + $last_line_name = ''; + $constrained = array('post', 'meta', 'post_media', 'ping', 'comment'); + + while (($line = $this->getLine()) !== false) + { + # import DC 1.2.x, we fix lines before insert + if ($this->dc_major_version == '1.2') { + $this->prepareDC12line($line); + } + + if ($last_line_name != $line->__name) { + if (in_array($last_line_name,$constrained)) { + # UNDEFER + if ($this->con->driver() == 'mysql') $this->con->execute('SET foreign_key_checks = 1'); + if ($this->con->driver() == 'pgsql') $this->con->execute('SET CONSTRAINTS ALL DEFERRED'); + } + + if (in_array($line->__name,$constrained)) { + # DEFER + if ($this->con->driver() == 'mysql') $this->con->execute('SET foreign_key_checks = 0'); + if ($this->con->driver() == 'pgsql') $this->con->execute('SET CONSTRAINTS ALL IMMEDIATE'); + } + + $last_line_name = $line->__name; + } + + switch ($line->__name) + { + case 'category': + $this->insertCategorySingle($line); + break; + case 'link': + $this->insertLinkSingle($line); + break; + case 'post': + $this->insertPostSingle($line); + break; + case 'meta': + $this->insertMetaSingle($line); + break; + case 'media': + $this->insertMediaSingle($line); + break; + case 'post_media': + $this->insertPostMediaSingle($line); + break; + case 'ping': + $this->insertPingSingle($line); + break; + case 'comment': + $this->insertCommentSingle($line); + break; + } + + # --BEHAVIOR-- importSingle + $this->core->callBehavior('importSingle',$line,$this,$this->core); + } + + if ($this->con->driver() == 'mysql') $this->con->execute('SET foreign_key_checks = 1'); + if ($this->con->driver() == 'pgsql') $this->con->execute('SET CONSTRAINTS ALL DEFERRED'); + } + catch (Exception $e) + { + $this->con->rollback(); + throw $e; + } + + $this->con->commit(); + } + + public function importFull() + { + if ($this->mode != 'full') { + throw new Exception(__('File is not a full export.')); + } + + if (!$this->core->auth->isSuperAdmin()) { + throw new Exception(__('Permission denied.')); + } + + $this->con->begin(); + $this->con->execute('DELETE FROM '.$this->prefix.'blog'); + $this->con->execute('DELETE FROM '.$this->prefix.'media'); + $this->con->execute('DELETE FROM '.$this->prefix.'spamrule'); + $this->con->execute('DELETE FROM '.$this->prefix.'setting'); + + try + { + while (($line = $this->getLine()) !== false) + { + switch ($line->__name) + { + case 'blog': + $this->insertBlog($line); + break; + case 'category': + $this->insertCategory($line); + break; + case 'link': + $this->insertLink($line); + break; + case 'setting': + $this->insertSetting($line); + break; + case 'user': + $this->insertUser($line); + break; + case 'pref': + $this->insertPref($line); + break; + case 'permissions': + $this->insertPermissions($line); + break; + case 'post': + $this->insertPost($line); + break; + case 'meta': + $this->insertMeta($line); + break; + case 'media': + $this->insertMedia($line); + break; + case 'post_media': + $this->insertPostMedia($line); + break; + case 'log'; + $this->insertLog($line); + break; + case 'ping': + $this->insertPing($line); + break; + case 'comment': + $this->insertComment($line); + break; + case 'spamrule': + $this->insertSpamRule($line); + break; + } + # --BEHAVIOR-- importFull + $this->core->callBehavior('importFull',$line,$this,$this->core); + } + } + catch (Exception $e) + { + $this->con->rollback(); + throw $e; + } + + $this->con->commit(); + } + + private function insertBlog($blog) + { + $this->cur_blog->clean(); + + $this->cur_blog->blog_id = (string) $blog->blog_id; + $this->cur_blog->blog_uid = (string) $blog->blog_uid; + $this->cur_blog->blog_creadt = (string) $blog->blog_creadt; + $this->cur_blog->blog_upddt = (string) $blog->blog_upddt; + $this->cur_blog->blog_url = (string) $blog->blog_url; + $this->cur_blog->blog_name = (string) $blog->blog_name; + $this->cur_blog->blog_desc = (string) $blog->blog_desc; + + $this->cur_blog->blog_status = $blog->exists('blog_status') ? (integer) $blog->blog_status : 1; + + $this->cur_blog->insert(); + } + + private function insertCategory($category) + { + $this->cur_category->clean(); + + $this->cur_category->cat_id = (string) $category->cat_id; + $this->cur_category->blog_id = (string) $category->blog_id; + $this->cur_category->cat_title = (string) $category->cat_title; + $this->cur_category->cat_url = (string) $category->cat_url; + $this->cur_category->cat_desc = (string) $category->cat_desc; + + if (!$this->has_categories && $category->exists('cat_lft') && $category->exists('cat_rgt')) { + $this->cur_category->cat_lft = (integer) $category->cat_lft; + $this->cur_category->cat_rgt = (integer) $category->cat_rgt; + } else { + if (!isset($this->stack['cat_lft'][$category->blog_id])) { + $this->stack['cat_lft'][$category->blog_id] = 2; + } + $this->cur_category->cat_lft = $this->stack['cat_lft'][$category->blog_id]++; + $this->cur_category->cat_rgt = $this->stack['cat_lft'][$category->blog_id]++; + } + + $this->cur_category->insert(); + } + + private function insertLink($link) + { + $this->cur_link->clean(); + + $this->cur_link->link_id = (integer) $link->link_id; + $this->cur_link->blog_id = (string) $link->blog_id; + $this->cur_link->link_href = (string) $link->link_href; + $this->cur_link->link_title = (string) $link->link_title; + $this->cur_link->link_desc = (string) $link->link_desc; + $this->cur_link->link_lang = (string) $link->link_lang; + $this->cur_link->link_xfn = (string) $link->link_xfn; + $this->cur_link->link_position = (integer) $link->link_position; + + $this->cur_link->insert(); + } + + private function insertSetting($setting) + { + $this->cur_setting->clean(); + + $this->cur_setting->setting_id = (string) $setting->setting_id; + $this->cur_setting->blog_id = !$setting->blog_id ? null : (string) $setting->blog_id; + $this->cur_setting->setting_ns = (string) $setting->setting_ns; + $this->cur_setting->setting_value = (string) $setting->setting_value; + $this->cur_setting->setting_type = (string) $setting->setting_type; + $this->cur_setting->setting_label = (string) $setting->setting_label; + + $this->cur_setting->insert(); + } + + private function insertPref($pref) + { + if ($this->prefExists($pref->pref_ws,$pref->pref_id,$pref->user_id)) { + return; + } + + $this->cur_pref->clean(); + + $this->cur_pref->pref_id = (string) $pref->pref_id; + $this->cur_pref->user_id = !$pref->user_id ? null : (string) $pref->user_id; + $this->cur_pref->pref_ws = (string) $pref->pref_ws; + $this->cur_pref->pref_value = (string) $pref->pref_value; + $this->cur_pref->pref_type = (string) $pref->pref_type; + $this->cur_pref->pref_label = (string) $pref->pref_label; + + $this->cur_pref->insert(); + } + + private function insertUser($user) + { + if ($this->userExists($user->user_id)) { + return; + } + + $this->cur_user->clean(); + + $this->cur_user->user_id = (string) $user->user_id; + $this->cur_user->user_super = (integer) $user->user_super; + $this->cur_user->user_pwd = (string) $user->user_pwd; + $this->cur_user->user_recover_key = (string) $user->user_recover_key; + $this->cur_user->user_name = (string) $user->user_name; + $this->cur_user->user_firstname = (string) $user->user_firstname; + $this->cur_user->user_displayname = (string) $user->user_displayname; + $this->cur_user->user_email = (string) $user->user_email; + $this->cur_user->user_url = (string) $user->user_url; + $this->cur_user->user_default_blog = !$user->user_default_blog ? null : (string) $user->user_default_blog; + $this->cur_user->user_lang = (string) $user->user_lang; + $this->cur_user->user_tz = (string) $user->user_tz; + $this->cur_user->user_post_status = (integer) $user->user_post_status; + $this->cur_user->user_creadt = (string) $user->user_creadt; + $this->cur_user->user_upddt = (string) $user->user_upddt; + + $this->cur_user->user_desc = $user->exists('user_desc') ? (string) $user->user_desc : null; + $this->cur_user->user_options = $user->exists('user_options') ? (string) $user->user_options : null; + $this->cur_user->user_status = $user->exists('user_status') ? (integer) $user->user_status : 1; + + $this->cur_user->insert(); + + $this->stack['users'][$user->user_id] = true; + } + + private function insertPermissions($permissions) + { + $this->cur_permissions->clean(); + + $this->cur_permissions->user_id = (string) $permissions->user_id; + $this->cur_permissions->blog_id = (string) $permissions->blog_id; + $this->cur_permissions->permissions = (string) $permissions->permissions; + + $this->cur_permissions->insert(); + } + + private function insertPost($post) + { + $this->cur_post->clean(); + + $cat_id = (integer) $post->cat_id; + if (!$cat_id) { + $cat_id = null; + } + + $post_password = $post->post_password ? (string) $post->post_password : null; + + $this->cur_post->post_id = (integer) $post->post_id; + $this->cur_post->blog_id = (string) $post->blog_id; + $this->cur_post->user_id = (string) $this->getUserId($post->user_id); + $this->cur_post->cat_id = $cat_id; + $this->cur_post->post_dt = (string) $post->post_dt; + $this->cur_post->post_creadt = (string) $post->post_creadt; + $this->cur_post->post_upddt = (string) $post->post_upddt; + $this->cur_post->post_password = $post_password; + $this->cur_post->post_type = (string) $post->post_type; + $this->cur_post->post_format = (string) $post->post_format; + $this->cur_post->post_url = (string) $post->post_url; + $this->cur_post->post_lang = (string) $post->post_lang; + $this->cur_post->post_title = (string) $post->post_title; + $this->cur_post->post_excerpt = (string) $post->post_excerpt; + $this->cur_post->post_excerpt_xhtml = (string) $post->post_excerpt_xhtml; + $this->cur_post->post_content = (string) $post->post_content; + $this->cur_post->post_content_xhtml = (string) $post->post_content_xhtml; + $this->cur_post->post_notes = (string) $post->post_notes; + $this->cur_post->post_words = (string) $post->post_words; + $this->cur_post->post_meta = (string) $post->post_meta; + $this->cur_post->post_status = (integer) $post->post_status; + $this->cur_post->post_selected = (integer) $post->post_selected; + $this->cur_post->post_open_comment = (integer) $post->post_open_comment; + $this->cur_post->post_open_tb = (integer) $post->post_open_tb; + $this->cur_post->nb_comment = (integer) $post->nb_comment; + $this->cur_post->nb_trackback = (integer) $post->nb_trackback; + + $this->cur_post->post_tz = $post->exists('post_tz') ? (string) $post->post_tz : 'UTC'; + + $this->cur_post->insert(); + } + + private function insertMeta($meta) + { + $this->cur_meta->clean(); + + $this->cur_meta->meta_id = (string) $meta->meta_id; + $this->cur_meta->meta_type = (string) $meta->meta_type; + $this->cur_meta->post_id = (integer) $meta->post_id; + + $this->cur_meta->insert(); + } + + private function insertMedia($media) + { + $this->cur_media->clean(); + + $this->cur_media->media_id = (integer) $media->media_id; + $this->cur_media->user_id = (string) $media->user_id; + $this->cur_media->media_path = (string) $media->media_path; + $this->cur_media->media_title = (string) $media->media_title; + $this->cur_media->media_file = (string) $media->media_file; + $this->cur_media->media_meta = (string) $media->media_meta; + $this->cur_media->media_dt = (string) $media->media_dt; + $this->cur_media->media_creadt = (string) $media->media_creadt; + $this->cur_media->media_upddt = (string) $media->media_upddt; + $this->cur_media->media_private = (integer) $media->media_private; + + $this->cur_media->media_dir = $media->exists('media_dir') ? (string) $media->media_dir : dirname($media->media_file); + + if (!$this->mediaExists()) { + $this->cur_media->insert(); + } + } + + private function insertPostMedia($post_media) + { + $this->cur_post_media->clean(); + + $this->cur_post_media->media_id = (integer) $post_media->media_id; + $this->cur_post_media->post_id = (integer) $post_media->post_id; + + $this->cur_post_media->insert(); + } + + private function insertLog($log) + { + $this->cur_log->clean(); + + $this->cur_log->log_id = (integer) $log->log_id; + $this->cur_log->user_id = (string) $log->user_id; + $this->cur_log->log_table = (string) $log->log_table; + $this->cur_log->log_dt = (string) $log->log_dt; + $this->cur_log->log_ip = (string) $log->log_ip; + $this->cur_log->log_msg = (string) $log->log_msg; + + $this->cur_log->insert(); + } + + private function insertPing($ping) + { + $this->cur_ping->clean(); + + $this->cur_ping->post_id = (integer) $ping->post_id; + $this->cur_ping->ping_url = (string) $ping->ping_url; + $this->cur_ping->ping_dt = (string) $ping->ping_dt; + + $this->cur_ping->insert(); + } + + private function insertComment($comment) + { + $this->cur_comment->clean(); + + $this->cur_comment->comment_id = (integer) $comment->comment_id; + $this->cur_comment->post_id = (integer) $comment->post_id; + $this->cur_comment->comment_dt = (string) $comment->comment_dt; + $this->cur_comment->comment_upddt = (string) $comment->comment_upddt; + $this->cur_comment->comment_author = (string) $comment->comment_author; + $this->cur_comment->comment_email = (string) $comment->comment_email; + $this->cur_comment->comment_site = (string) $comment->comment_site; + $this->cur_comment->comment_content = (string) $comment->comment_content; + $this->cur_comment->comment_words = (string) $comment->comment_words; + $this->cur_comment->comment_ip = (string) $comment->comment_ip; + $this->cur_comment->comment_status = (integer) $comment->comment_status; + $this->cur_comment->comment_spam_status = (integer) $comment->comment_spam_status; + $this->cur_comment->comment_trackback = (integer) $comment->comment_trackback; + + $this->cur_comment->comment_tz = $comment->exists('comment_tz') ? (string) $comment->comment_tz : 'UTC'; + $this->cur_comment->comment_spam_filter = $comment->exists('comment_spam_filter') ? (integer) $comment->comment_spam_filter : null; + + $this->cur_comment->insert(); + } + + private function insertSpamRule($spamrule) + { + $this->cur_spamrule->clean(); + + $this->cur_spamrule->rule_id = (integer) $spamrule->rule_id; + $this->cur_spamrule->blog_id = !$spamrule->blog_id ? null : (string) $spamrule->blog_id; + $this->cur_spamrule->rule_type = (string) $spamrule->rule_type; + $this->cur_spamrule->rule_content = (string) $spamrule->rule_content; + + $this->cur_spamrule->insert(); + } + + private function insertCategorySingle($category) + { + $this->cur_category->clean(); + + $m = $this->searchCategory($this->stack['categories'],$category->cat_url); + + $old_id = $category->cat_id; + if ($m !== false) + { + $cat_id = $m; + } + else + { + $cat_id = $this->stack['cat_id']; + $category->cat_id = $cat_id; + $category->blog_id = $this->blog_id; + + $this->insertCategory($category); + $this->stack['cat_id']++; + } + + $this->old_ids['category'][(integer) $old_id] = $cat_id; + } + + private function insertLinkSingle($link) + { + $link->blog_id = $this->blog_id; + $link->link_id = $this->stack['link_id']; + + $this->insertLink($link); + $this->stack['link_id']++; + } + + private function insertPostSingle($post) + { + if (!$post->cat_id || isset($this->old_ids['category'][(integer) $post->cat_id])) { + $post_id = $this->stack['post_id']; + $this->old_ids['post'][(integer) $post->post_id] = $post_id; + + $cat_id = $post->cat_id ? $this->old_ids['category'][(integer) $post->cat_id] : null; + + $post->post_id = $post_id; + $post->cat_id = $cat_id; + $post->blog_id = $this->blog_id; + + $post->post_url = $this->core->blog->getPostURL( + $post->post_url,$post->post_dt,$post->post_title,$post->post_id + ); + + $this->insertPost($post); + $this->stack['post_id']++; + } else { + self::throwIdError($post->__name,$post->__line,'category'); + } + } + + private function insertMetaSingle($meta) + { + if (isset($this->old_ids['post'][(integer) $meta->post_id])) { + $meta->post_id = $this->old_ids['post'][(integer) $meta->post_id]; + $this->insertMeta($meta); + } else { + self::throwIdError($meta->__name,$meta->__line,'post'); + } + } + + private function insertMediaSingle($media) + { + $media_id = $this->stack['media_id']; + $old_id = $media->media_id; + + $media->media_id = $media_id; + $media->media_path = $this->core->blog->settings->system->public_path; + $media->user_id = $this->getUserId($media->user_id); + + $this->insertMedia($media); + $this->stack['media_id']++; + $this->old_ids['media'][(integer) $old_id] = $media_id; + } + + private function insertPostMediaSingle($post_media) + { + if (isset($this->old_ids['media'][(integer) $post_media->media_id]) && + isset($this->old_ids['post'][(integer) $post_media->post_id])) { + $post_media->media_id = $this->old_ids['media'][(integer) $post_media->media_id]; + $post_media->post_id = $this->old_ids['post'][(integer) $post_media->post_id]; + + $this->insertPostMedia($post_media); + } elseif (!isset($this->old_ids['media'][(integer) $post_media->media_id])) { + self::throwIdError($post_media->__name,$post_media->__line,'media'); + }else { + self::throwIdError($post_media->__name,$post_media->__line,'post'); + } + } + + private function insertPingSingle($ping) + { + if (isset($this->old_ids['post'][(integer) $ping->post_id])) { + $ping->post_id = $this->old_ids['post'][(integer) $ping->post_id]; + + $this->insertPing($ping); + } else { + self::throwIdError($ping->__name,$ping->__line,'post'); + } + } + + private function insertCommentSingle($comment) + { + if (isset($this->old_ids['post'][(integer) $comment->post_id])) { + $comment_id = $this->stack['comment_id']; + + $comment->comment_id = $comment_id; + $comment->post_id = $this->old_ids['post'][(integer) $comment->post_id]; + + $this->insertComment($comment); + $this->stack['comment_id']++; + } else { + self::throwIdError($comment->__name,$comment->__line,'post'); + } + } + + private static function throwIdError($name,$line,$related) + { + throw new Exception(sprintf( + __('ID of "%3$s" does not match on record "%1$s" at line %2$s of backup file.'), + html::escapeHTML($name), + html::escapeHTML($line), + html::escapeHTML($related) + )); + } + + public function searchCategory($rs,$url) + { + while ($rs->fetch()) + { + if ($rs->cat_url == $url) { + return $rs->cat_id; + } + } + + return false; + } + + public function getUserId($user_id) + { + if (!$this->userExists($user_id)) + { + if ($this->core->auth->isSuperAdmin()) + { + # Sanitizes user_id and create a lambda user + $user_id = preg_replace('/[^A-Za-z0-9]$/','',$user_id); + $user_id .= strlen($user_id) < 2 ? '-a' : ''; + + # We change user_id, we need to check again + if (!$this->userExists($user_id)) + { + $this->cur_user->clean(); + $this->cur_user->user_id = (string) $user_id; + $this->cur_user->user_pwd = md5(uniqid()); + + $this->core->addUser($this->cur_user); + + $this->stack['users'][$user_id] = true; + } + } + else + { + # Returns current user id + $user_id = $this->core->auth->userID(); + } + } + + return $user_id; + } + + private function userExists($user_id) + { + if (isset($this->stack['users'][$user_id])) { + return $this->stack['users'][$user_id]; + } + + $strReq = 'SELECT user_id '. + 'FROM '.$this->prefix.'user '. + "WHERE user_id = '".$this->con->escape($user_id)."' "; + + $rs = $this->con->select($strReq); + + $this->stack['users'][$user_id] = !$rs->isEmpty(); + return $this->stack['users'][$user_id]; + } + + private function prefExists($pref_ws,$pref_id,$user_id) + { + $strReq = 'SELECT pref_id,pref_ws,user_id '. + 'FROM '.$this->prefix.'pref '. + "WHERE pref_id = '".$this->con->escape($pref_id)."' ". + "AND pref_ws = '".$this->con->escape($pref_ws)."' "; + if (!$user_id) { + $strReq .= "AND user_id IS NULL "; + } else { + $strReq .= "AND user_id = '".$this->con->escape($user_id)."' "; + } + + $rs = $this->con->select($strReq); + + return !$rs->isEmpty(); + } + + private function mediaExists() + { + $strReq = 'SELECT media_id '. + 'FROM '.$this->prefix.'media '. + "WHERE media_path = '".$this->cur_media->media_path."' ". + "AND media_file = '".$this->cur_media->media_file."' "; + + $rs = $this->con->select($strReq); + + return !$rs->isEmpty(); + } + + private function prepareDC12line(&$line) + { + $settings = array('dc_theme','dc_nb_post_per_page','dc_allow_comments', + 'dc_allow_trackbacks','dc_comment_pub','dc_comments_ttl', + 'dc_wiki_comments','dc_use_smilies','dc_date_format','dc_time_format', + 'dc_url_scan'); + + switch ($line->__name) + { + case 'categorie': + $line->substitute('cat_libelle','cat_title'); + $line->substitute('cat_libelle_url','cat_url'); + $line->__name = 'category'; + $line->blog_id = 'default'; + break; + case 'link': + $line->substitute('href','link_href'); + $line->substitute('label','link_title'); + $line->substitute('title','link_desc'); + $line->substitute('lang','link_lang'); + $line->substitute('rel','link_xfn'); + $line->substitute('position','link_position'); + $line->blog_id = 'default'; + break; + case 'post': + $line->substitute('post_titre','post_title'); + $line->post_title = html::decodeEntities($line->post_title); + $line->post_url = date('Y/m/d/',strtotime($line->post_dt)).$line->post_id.'-'.$line->post_titre_url; + $line->post_url = substr($line->post_url,0,255); + $line->post_format = $line->post_content_wiki == '' ? 'xhtml' : 'wiki'; + $line->post_content_xhtml = $line->post_content; + $line->post_excerpt_xhtml = $line->post_chapo; + + if ($line->post_format == 'wiki') { + $line->post_content = $line->post_content_wiki; + $line->post_excerpt = $line->post_chapo_wiki; + } else { + $line->post_content = $line->post_content; + $line->post_excerpt = $line->post_chapo; + } + + $line->post_status = (integer) $line->post_pub; + $line->post_type = 'post'; + $line->blog_id = 'default'; + + $line->drop('post_titre_url','post_content_wiki','post_chapo','post_chapo_wiki','post_pub'); + + break; + case 'post_meta': + $line->drop('meta_id'); + $line->substitute('meta_key','meta_type'); + $line->substitute('meta_value','meta_id'); + $line->__name = 'meta'; + $line->blog_id = 'default'; + break; + case 'comment': + $line->substitute('comment_auteur','comment_author'); + if ($line->comment_site != '' && !preg_match('!^http://.*$!', $line->comment_site,$m)) { + $line->comment_site = 'http://'.$line->comment_site; + } + $line->comment_status = (integer) $line->comment_pub; + $line->drop('comment_pub'); + break; + } + + # --BEHAVIOR-- importPrepareDC12 + $this->core->callBehavior('importPrepareDC12',$line,$this,$this->core); + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/importExport/inc/img/progress.png b/v2/dotclear/plugins/importExport/inc/img/progress.png new file mode 100644 index 0000000000000000000000000000000000000000..267f54111eae4c93e3629b643bb5a61609e2769c GIT binary patch literal 858 zcmV-g1Eu_lP)RGReGUQd7@Bypi^|BM|q!9a-l6z7Pj;M8 zbDc_Yo<($OmUh?a+pkTnMiS$N^6@taF|GMmPl!uH*S?kZ|hkTqqGJ7$bPWsE*!jXGVBDq@Q|UXCtYk11Y@Fj|c#Uy3wgi8@(}CRmFl zU57MQi6d5sB~^$bRE8o|h9y&mAXJ4URD&f^gdS6YB~*bZQh_2?fGksgCr^SLPJbLt zfErAH8B2W`N_`hidLT=C8%TQMgsr<02XvbSad^jWnpw_ zZ*Cw|X>DZyGC40WH7_tY@MYc30003kNklUHWeNNLtF5Z;u+0Us$1 zKHu0jRryJ6@K@~7Vm4_S^0yA9ow6KB*D!TPJ$a;SxS-uas?#-GQbRHA>l&`5'.html::escapeHTML($o->name).''. + '
        '.html::escapeHTML($o->description).'
        '; + + unset($o); + } + return '
        '.$res.'
        '; +} + +$modules = new ArrayObject(array('import' => array(),'export' => array())); + +# --BEHAVIOR-- importExportModules +$core->callBehavior('importExportModules',$modules); + +$type = null; +if (!empty($_REQUEST['type']) && in_array($_REQUEST['type'],array('export','import'))) { + $type = $_REQUEST['type']; +} + +$module = null; +if ($type && !empty($_REQUEST['module'])) { + + if (isset($modules[$type]) && in_array($_REQUEST['module'],$modules[$type])) { + + $module = new $_REQUEST['module']($core); + $module->init(); + } +} + +if ($type && $module !== null && !empty($_REQUEST['do'])) +{ + try { + $module->process($_REQUEST['do']); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} + +$title = __('Import/Export'); + +echo ' + + + '.$title.' + + '.dcPage::jsLoad('index.php?pf=importExport/js/script.js').' + + +'; + +if ($type && $module !== null) { + echo + '

        '.$title.''. + ' › '.html::escapeHTML($module->name).'

        '. + '
        '; + + $module->gui(); + + echo '
        '; +} +else { + echo + '

        '.$title.'

        '. + '

        '.__('Import').'

        '.listImportExportModules($core,$modules['import']). + '

        '.__('Export').'

        '.listImportExportModules($core,$modules['export']); +} + +echo ' + +'; +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/importExport/js/script.js b/v2/dotclear/plugins/importExport/js/script.js new file mode 100644 index 0000000..82892fd --- /dev/null +++ b/v2/dotclear/plugins/importExport/js/script.js @@ -0,0 +1,3 @@ + +$(function(){if($('*.error').length>0){return;} +$('#ie-gui form[method=post]:has(input[type=hidden][name=autosubmit])').each(function(){$('input[type=submit]',this).remove();$(this).after('

        '+dotclear.msg.please_wait+'

        ');$(this).submit();});}); \ No newline at end of file diff --git a/v2/dotclear/plugins/importExport/locales/fr/main.lang.php b/v2/dotclear/plugins/importExport/locales/fr/main.lang.php new file mode 100644 index 0000000..7d8c291 --- /dev/null +++ b/v2/dotclear/plugins/importExport/locales/fr/main.lang.php @@ -0,0 +1,92 @@ + \ No newline at end of file diff --git a/v2/dotclear/plugins/importExport/locales/fr/main.po b/v2/dotclear/plugins/importExport/locales/fr/main.po new file mode 100644 index 0000000..d0049f1 --- /dev/null +++ b/v2/dotclear/plugins/importExport/locales/fr/main.po @@ -0,0 +1,333 @@ +# Language: Français +# Module: importExport - 3.1 +# Date: 2012-07-09 14:37:32 +# Translated with translater 1.5 + +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" +"Project-Id-Version: importExport 3.1\n" +"POT-Creation-Date: \n" +"PO-Revision-Date: 2012-07-09T14:37:32+00:00\n" +"Last-Translator: Jean-Christian Denis\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Transfer-Encoding: 8bit\n" + +#: _admin.php:15 +#: _admin.php:28 +#: index.php:59 +msgid "Import/Export" +msgstr "Import/Export" + +#: inc/class.dc.export.flat.php:19 +msgid "Flat file export" +msgstr "Exporter un fichier texte" + +#: inc/class.dc.export.flat.php:20 +msgid "Exports a blog or a full Dotclear installation to flat file." +msgstr "Exporte un blog ou toutes les données de Dotclear dans un fichier texte." + +#: inc/class.dc.export.flat.php:140 +msgid "Export file not found." +msgstr "Fichier d'export non trouvé." + +#: inc/class.dc.export.flat.php:184 +msgid "Failed to compress export file." +msgstr "Impossible de compresser le fichier d'export." + +#: inc/class.dc.export.flat.php:194 +#: inc/class.dc.import.feed.php:84 +#: inc/class.dc.import.flat.php:183 +msgid "Single blog" +msgstr "Un seul blog" + +#: inc/class.dc.export.flat.php:195 +msgid "This will create an export of your current blog: %s" +msgstr "Ceci va exporter le contenu du blog en cours : %s." + +#: inc/class.dc.export.flat.php:197 +#: inc/class.dc.export.flat.php:223 +msgid "File name:" +msgstr "Nom du fichier :" + +#: inc/class.dc.export.flat.php:203 +#: inc/class.dc.export.flat.php:229 +msgid "Compress file" +msgstr "Compresser le fichier" + +#: inc/class.dc.export.flat.php:207 +msgid "You may also want to download your media directory as a zip file" +msgstr "Vous pouvez également télécharger votre répertoire de médias au format zip." + +#: inc/class.dc.export.flat.php:209 +#: inc/class.dc.export.flat.php:232 +#: index.php:89 +msgid "Export" +msgstr "Exporter" + +#: inc/class.dc.export.flat.php:220 +#: inc/class.dc.import.flat.php:211 +msgid "Multiple blogs" +msgstr "Tous les blogs" + +#: inc/class.dc.export.flat.php:221 +msgid "This will create an export of all the content of your database." +msgstr "Ceci va exporter le contenu complet de votre base de données." + +#: inc/class.dc.ieModule.php:74 +msgid "Congratulation!" +msgstr "Félicitations !" + +#: inc/class.dc.ieModule.php:75 +msgid "Your blog has been successfully imported. Welcome on Dotclear 2!" +msgstr "Votre blog a été importé avec succès. Bienvenue sur Dotclear 2 !" + +#: inc/class.dc.ieModule.php:76 +msgid "Why don't you blog this now?" +msgstr "Pourquoi ne pas le bloguer maintenant ?" + +#: inc/class.dc.ieModule.php:77 +msgid "or" +msgstr "ou" + +#: inc/class.dc.ieModule.php:77 +msgid "visit your dashboard" +msgstr "vous rendre sur votre tableau de bord" + +#: inc/class.dc.import.dc1.php:43 +msgid "Dotclear 1.2 import" +msgstr "Importer depuis Dotclear 1.2" + +#: inc/class.dc.import.dc1.php:44 +msgid "Import a Dotclear 1.2 installation into your current blog." +msgstr "Importe un blog Dotclear 1.2 dans votre blog en cours." + +#: inc/class.dc.import.dc1.php:145 +msgid "This will import your Dotclear 1.2 content as new content in the current blog: %s." +msgstr "Ceci va importer votre blog Dotclear 1.2 comme un nouveau contenu dans le blog en cours : %s." + +#: inc/class.dc.import.dc1.php:149 +#: inc/class.dc.import.wp.php:180 +msgid "Depending on the size of your blog, it could take a few minutes." +msgstr "Selon la taille de votre blog, ceci peut prendre quelques minutes." + +#: inc/class.dc.import.dc1.php:151 +#: inc/class.dc.import.wp.php:182 +msgid "General information" +msgstr "Informations générales" + +#: inc/class.dc.import.dc1.php:151 +#: inc/class.dc.import.wp.php:182 +msgid "Import my blog now" +msgstr "Importer mon blog" + +#: inc/class.dc.import.dc1.php:152 +msgid "We first need some information about your old Dotclear 1.2 installation." +msgstr "Nous avons d'abord besoin de renseignements à propos de votre ancienne installation Dotclear 1.2." + +#: inc/class.dc.import.dc1.php:163 +#: inc/class.dc.import.wp.php:194 +msgid "Entries import options" +msgstr "Options d'importation des billets" + +#: inc/class.dc.import.dc1.php:164 +#: inc/class.dc.import.wp.php:212 +msgid "Number of entries to import at once:" +msgstr "Nombre de billets à importer à chaque étape :" + +#: inc/class.dc.import.dc1.php:169 +#: inc/class.dc.import.wp.php:222 +msgid "Importing users" +msgstr "Importe les utilisateurs" + +#: inc/class.dc.import.dc1.php:174 +#: inc/class.dc.import.wp.php:227 +msgid "Importing categories" +msgstr "Importe les catégories" + +#: inc/class.dc.import.dc1.php:179 +#: inc/class.dc.import.wp.php:232 +msgid "Importing blogroll" +msgstr "Importe les liens" + +#: inc/class.dc.import.dc1.php:184 +#: inc/class.dc.import.wp.php:237 +msgid "Importing entries from %d to %d / %d" +msgstr "Importation des billets %d à %d" + +#: inc/class.dc.import.dc1.php:193 +msgid "Please read carefully" +msgstr "Merci de lire attentivement" + +#: inc/class.dc.import.dc1.php:214 +#: inc/class.dc.import.wp.php:258 +msgid "next step" +msgstr "étape suivante" + +#: inc/class.dc.import.dc1.php:242 +msgid "Dotclear tables not found" +msgstr "Tables Dotclear non trouvées" + +#: inc/class.dc.import.feed.php:22 +msgid "Feed import" +msgstr "Importer depuis un flux" + +#: inc/class.dc.import.feed.php:23 +msgid "Imports a feed as new entries." +msgstr "Importe un flux comme nouveaux billets." + +#: inc/class.dc.import.feed.php:41 +msgid "Cannot retrieve feed URL." +msgstr "Impossible d'atteindre l'URL du fil." + +#: inc/class.dc.import.feed.php:44 +msgid "No items in feed." +msgstr "Aucun élément dans le fil." + +#: inc/class.dc.import.feed.php:79 +#: inc/class.dc.import.flat.php:149 +msgid "Content successfully imported." +msgstr "Contenu importé avec succès." + +#: inc/class.dc.import.feed.php:85 +msgid "This will import a feed (RSS or Atom) a as new content in the current blog: %s." +msgstr "Ceci va importer un fil (RSS ou Atom) comme un nouveau contenu dans le blog en cours : %s." + +#: inc/class.dc.import.feed.php:87 +msgid "Feed URL:" +msgstr "URL du fil :" + +#: inc/class.dc.import.feed.php:93 +#: inc/class.dc.import.flat.php:202 +#: inc/class.dc.import.flat.php:233 +#: index.php:88 +msgid "Import" +msgstr "Importer" + +#: inc/class.dc.import.flat.php:21 +msgid "Flat file import" +msgstr "Importer depuis un fichier texte" + +#: inc/class.dc.import.flat.php:22 +msgid "Imports a blog or a full Dotclear installation from flat file." +msgstr "Importe un blog ou toutes les données depuis un fichier texte." + +#: inc/class.dc.import.flat.php:144 +msgid "Single blog successfully imported." +msgstr "Blog importé avec succès." + +#: inc/class.dc.import.flat.php:160 +msgid "Are you sure you want to import a full backup file?" +msgstr "Êtes-vous certain de vouloir charger un fichier de sauvegarde complet ?" + +#: inc/class.dc.import.flat.php:184 +msgid "This will import a single blog backup as new content in the current blog: %s." +msgstr "Ceci va charger une sauvegarde de blog comme un nouveau contenu dans le blog en cours : %s." + +#: inc/class.dc.import.flat.php:186 +#: inc/class.dc.import.flat.php:214 +msgid "Upload a backup file" +msgstr "Charger un fichier de sauvegarde" + +#: inc/class.dc.import.flat.php:192 +#: inc/class.dc.import.flat.php:220 +msgid "or pick up a local file in your public directory" +msgstr "ou choisissez un fichier local dans votre répertoire public" + +#: inc/class.dc.import.flat.php:212 +msgid "This will reset all the content of your database, except users." +msgstr "Ceci va remettre à zéro tout le contenu, sauf les utilisateurs." + +#: inc/class.dc.import.flat.php:281 +msgid "File is empty or not a compressed file." +msgstr "Le Fichier est vide ou n'est pas un fichier compressé." + +#: inc/class.dc.import.flat.php:304 +msgid "Another file with same name exists." +msgstr "Un autre fichier du même nom existe déjà." + +#: inc/class.dc.import.flat.php:311 +msgid "Failed to extract backup file." +msgstr "Impossible d'extraire le fichier de sauvegarde." + +#: inc/class.dc.import.flat.php:322 +msgid "No backup in compressed file." +msgstr "Pas de sauvegarde dans le fichier compressé." + +#: inc/class.dc.import.wp.php:64 +msgid "WordPress import" +msgstr "Importer depuis WordPress" + +#: inc/class.dc.import.wp.php:65 +msgid "Import a WordPress installation into your current blog." +msgstr "Importe un blog WordPress dans votre blog en cours." + +#: inc/class.dc.import.wp.php:176 +msgid "This will import your WordPress content as new content in the current blog: %s." +msgstr "Ceci va importer votre blog WordPress comme un nouveau contenu dans le blog en cours : %s." + +#: inc/class.dc.import.wp.php:183 +msgid "We first need some information about your old WordPress installation." +msgstr "Nous avons d'abord besoin de renseignements à propos de votre ancienne installation WordPress." + +#: inc/class.dc.import.wp.php:205 +msgid "Ignore the first category:" +msgstr "Ignorer la première catégorie :" + +#: inc/class.dc.import.wp.php:207 +msgid "Import lowest numbered category on posts:" +msgstr "Importer la catégorie la plus ancienne sur les articles :" + +#: inc/class.dc.import.wp.php:209 +msgid "Import all categories as tags:" +msgstr "Importer les catégories comme des mots-clés :" + +#: inc/class.dc.import.wp.php:210 +msgid "Prefix such tags with:" +msgstr "Préfixer ces mots-clés avec :" + +#: inc/class.dc.import.wp.php:215 +msgid "Content filters" +msgstr "Filtres de contenu" + +#: inc/class.dc.import.wp.php:216 +msgid "You may want to process your post and/or comment content with the following filters." +msgstr "Vous pouvez utiliser les filtres suivants sur vos articles et/ou commentaires." + +#: inc/class.dc.import.wp.php:217 +msgid "Post content formatter:" +msgstr "Formatage des articles :" + +#: inc/class.dc.import.wp.php:218 +msgid "Comment content formatter:" +msgstr "Formatage des commentaires :" + +#: inc/class.dc.import.wp.php:286 +msgid "WordPress tables not found" +msgstr "Tables WordPress non trouvées" + +#: inc/flat/class.flat.backup.php:34 +msgid "No file to read." +msgstr "Aucun fichier lisible." + +#: inc/flat/class.flat.import.php:54 +msgid "File is not a DotClear backup." +msgstr "Le fichier n'est pas une sauvegarde DotClear." + +#: inc/flat/class.flat.import.php:105 +msgid "File is not a single blog export." +msgstr "Le fichier n'est pas un fichier d'export simple." + +#: inc/flat/class.flat.import.php:222 +msgid "File is not a full export." +msgstr "Le fichier n'est pas un fichier d'export complet." + +#: inc/flat/class.flat.import.php:704 +msgid "ID of \"%3$s\" does not match on record \"%1$s\" at line %2$s of backup file." +msgstr "L'ID de \"%3$s\" ne correspond pas dans l'enregistrement de \"%1$s\" à la ligne %2$s du fichier de sauvegarde." + +#: index.php:69 +msgid "Please wait..." +msgstr "Veuillez patienter..." + diff --git a/v2/dotclear/plugins/importExport/style.css b/v2/dotclear/plugins/importExport/style.css new file mode 100644 index 0000000..7aeb3c4 --- /dev/null +++ b/v2/dotclear/plugins/importExport/style.css @@ -0,0 +1,25 @@ +dl.modules dt { + font-weight: bold; + font-size: 1.1em; + margin: 1em 0 0 0; +} +dl.modules dd { + margin: 0 0 1.5em 0; +} +div.ie-progress { + background: #eee; + margin: 1em 0; +} +div.ie-progress div { + height: 10px; + width: 0; + font-size: 0.8em; + line-height: 1em; + height: 1em; + padding: 2px 0; + text-align: right; + background: green url(index.php?pf=importExport/progress.png) repeat-x top left; + color: white; + font-weight: bold; + -moz-border-radius: 2px; +} \ No newline at end of file diff --git a/v2/dotclear/plugins/maintenance/_admin.php b/v2/dotclear/plugins/maintenance/_admin.php new file mode 100644 index 0000000..c74b5c5 --- /dev/null +++ b/v2/dotclear/plugins/maintenance/_admin.php @@ -0,0 +1,26 @@ +addItem(__('Maintenance'),'plugin.php?p=maintenance','index.php?pf=maintenance/icon.png', + preg_match('/plugin.php\?p=maintenance(&.*)?$/',$_SERVER['REQUEST_URI']), + $core->auth->isSuperAdmin()); + +$core->addBehavior('adminDashboardFavs','maintenanceDashboardFavs'); + +function maintenanceDashboardFavs($core,$favs) +{ + $favs['maintenance'] = new ArrayObject(array('maintenance','Maintenance','plugin.php?p=maintenance', + 'index.php?pf=maintenance/icon.png','index.php?pf=maintenance/icon-big.png', + null,null,null)); +} +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/maintenance/_define.php b/v2/dotclear/plugins/maintenance/_define.php new file mode 100644 index 0000000..3dab8db --- /dev/null +++ b/v2/dotclear/plugins/maintenance/_define.php @@ -0,0 +1,20 @@ +registerModule( + /* Name */ "Maintenance", + /* Description*/ "Maintain your database", + /* Author */ "Olivier Meunier", + /* Version */ '1.1' +); +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/maintenance/icon-big.png b/v2/dotclear/plugins/maintenance/icon-big.png new file mode 100644 index 0000000000000000000000000000000000000000..eeb8306d426abf9a95bb1c2d6153bc5e1dfd936f GIT binary patch literal 6729 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 + $db_tables = $schema->getTables(); + + foreach ($db_tables as $t) { + if (strpos($t,$core->prefix) === 0) { + $core->con->vacuum($t); + } + } + http::redirect($p_url.'&vacuum=1'); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} +elseif ($action == 'commentscount') +{ + try { + $core->countAllComments(); + http::redirect($p_url.'&commentscount=1'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} +elseif ($action == 'empty_cache') +{ + try { + $core->emptyTemplatesCache(); + http::redirect($p_url.'&empty_cache=1'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} +elseif ($action == 'log') +{ + try { + $core->log->delLogs(null,true); + http::redirect($p_url.'&delete_logs=1'); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} + +?> + + + <?php echo __('Maintenance'); ?> + + + +

        + +'.__('Optimization successful.').'

        '; +} +if (!empty($_GET['commentscount'])) { + echo '

        '.__('Comments and trackback counted.').'

        '; +} +if (!empty($_GET['empty_cache'])) { + echo '

        '.__('Templates cache directory emptied.').'

        '; +} +if (!empty($_GET['delete_logs'])) { + echo '

        '.__('Logs deleted.').'

        '; +} + +if ($action == 'index' && !empty($_GET['indexposts'])) +{ + $limit = 1000; + echo '

        '.sprintf(__('Indexing entry %d to %d.'),$start,$start+$limit).'

        '; + + $new_start = $core->indexAllPosts($start,$limit); + + if ($new_start) + { + $new_url = $p_url.'&action=index&indexposts=1&start='.$new_start; + echo + ''. + ''; + } + else + { + echo '

        '.__('Entries index done.').'

        '; + echo '

        '.__('Back').'

        '; + } +} +elseif ($action == 'index' && !empty($_GET['indexcomments'])) +{ + $limit = 1000; + echo '

        '.sprintf(__('Indexing comment %d to %d.'),$start,$start+$limit).'

        '; + + $new_start = $core->indexAllComments($start,$limit); + + if ($new_start) + { + $new_url = $p_url.'&action=index&indexcomments=1&start='.$new_start; + echo + ''. + ''; + } + else + { + echo '

        '.__('Comments index done.').'

        '; + echo '

        '.__('Back').'

        '; + } +} +else +{ + echo + '

        '.__('Optimize database room').'

        '. + '
        '. + '

        '. + $core->formNonce(). + form::hidden(array('action'),'vacuum'). + form::hidden(array('p'),'maintenance').'

        '. + '
        '; + + echo + '

        '.__('Counters').'

        '. + '
        '. + '

        '. + $core->formNonce(). + form::hidden(array('action'),'commentscount'). + form::hidden(array('p'),'maintenance').'

        '. + '
        '; + + echo + '

        '.__('Search engine index').' ('.__('This may take a very long time').')

        '. + '
        '. + '

        '. + ' '. + form::hidden(array('action'),'index'). + form::hidden(array('p'),'maintenance').'

        '. + '
        '; + + echo + '

        '.__('Vacuum logs').'

        '. + '
        '. + '

        '. + $core->formNonce(). + form::hidden(array('action'),'log'). + form::hidden(array('p'),'maintenance').'

        '. + '
        '; + + echo + '

        '.__('Empty templates cache directory').'

        '. + '
        '. + '

        '. + $core->formNonce(). + form::hidden(array('action'),'empty_cache'). + form::hidden(array('p'),'maintenance').'

        '. + '
        '; +} +dcPage::helpBlock('maintenance'); +?> + + + \ No newline at end of file diff --git a/v2/dotclear/plugins/maintenance/locales/en/help/maintenance.html b/v2/dotclear/plugins/maintenance/locales/en/help/maintenance.html new file mode 100644 index 0000000..98e69c6 --- /dev/null +++ b/v2/dotclear/plugins/maintenance/locales/en/help/maintenance.html @@ -0,0 +1,41 @@ + + + Maintenance + + + + +

        Maintenance

        + +
        +
        Optimize database room
        +
        After numerous delete or update operations on Dotclear's database, it gets fragmented. + Optimizing will allow to defragment it.
        + It has no incidence on your data's integrity.
        + It is recommended to optimize before any blog export.
        + +
        Counters
        +
        Initializing comments and trackbacks counters allows to check their exact numbers. + This operation can be useful when importing from another blog platform + (or when migrating from dotclear 1 to dotclear 2).
        + +
        Search engine index
        +
        These operations are necessary, after importing content in your blog, to use internal search engine, on public and private pages. +
          +
        • Index all posts: allows to index all posts
        • +
        • Index all comments: allows to index all comments and trackbacks
        • +
        +
        + +
        Vacuum logs
        +
        Logs record all activity and connection to your blog history. Unless you need to keep this history, + consider deleting these logs from time to time.
        + +
        Empty templates cache directory
        +
        It may be useful to empty this cache when modifying a theme's .html or .css files (or when updating + a theme or plugin).
        + Notice : with some hosters, the templates cache cannot be emptied with this extension. + You may then have to delete the directory /cbtpl/ directly on the server with your FTP software.
        +
        + + \ No newline at end of file diff --git a/v2/dotclear/plugins/maintenance/locales/en/resources.php b/v2/dotclear/plugins/maintenance/locales/en/resources.php new file mode 100644 index 0000000..4c0cad4 --- /dev/null +++ b/v2/dotclear/plugins/maintenance/locales/en/resources.php @@ -0,0 +1,18 @@ + \ No newline at end of file diff --git a/v2/dotclear/plugins/maintenance/locales/fr/help/maintenance.html b/v2/dotclear/plugins/maintenance/locales/fr/help/maintenance.html new file mode 100644 index 0000000..5fa0864 --- /dev/null +++ b/v2/dotclear/plugins/maintenance/locales/fr/help/maintenance.html @@ -0,0 +1,39 @@ + + + Maintenance + + + + +

        Maintenance

        + +
        +
        Optimiser l'espace de la base de données
        +
        Au fur at à mesure des suppressions ou modifications dans vos billets, les tables de la + base de données se fragmentent. L'opération d'optimisation permet de compacter celles-ci.
        + Cette opération n'a aucun impact sur l'intégrité de vos données.
        + Il est fortement conseillé d'optimiser la base de données avant tout export de blog
        + +
        Compteurs
        +
        Réinitialiser les compteurs des commentaires et des rétroliens a pour effet + de donner le nombre exact de ceux-ci pour chaque billet. Cette opération peut se + révéler utile lors de l'import d'un blog d'une autre plateforme (ou d'une migration + de dotclear 1 vers dotclear 2).
        + +
        Index du moteur de recherche
        +
        Ces opérations s'effectuent généralement suite à un import afin d'obtenir des résultats lors des recherches, aussi bien depuis l'administration du blog qu'en partie publique. +
          +
        • Indexer tous les billets : permet d'indexer les billets
        • +
        • Indexer tous les commentaires : permet d'indexer les commentaires
        • +
        +
        + +
        Vider les journaux
        +
        Sauf si vous avez un besoin précis de conservation des activités de connexion sur votre blog, pensez à vider régulièrement la table des journaux : elle contient l'enregistrement de chaque connexion à l'administration et des opérations qui s'y sont déroulées.
        + +
        Vider le répertoire du cache des templates
        +
        La suppression du répertoire du cache des templates peut se révéler nécessaire lors de modifications dans les fichiers .html ou .css d'un thème (voire lors d'un changement de thème ou de mise à jour de plugin).
        + Attention : chez certains hébergeurs (Free par exemple), le cache du répertoire des templates ne peut pas être vidé grâce à l'extension Maintenance, il faut supprimer le répertoire cbtpl situé dans le répertoire cache (dotclear/cache par défaut) avec un logiciel FTP.
        +
        + + \ No newline at end of file diff --git a/v2/dotclear/plugins/maintenance/locales/fr/resources.php b/v2/dotclear/plugins/maintenance/locales/fr/resources.php new file mode 100644 index 0000000..4c0cad4 --- /dev/null +++ b/v2/dotclear/plugins/maintenance/locales/fr/resources.php @@ -0,0 +1,18 @@ + \ No newline at end of file diff --git a/v2/dotclear/plugins/pages/_admin.php b/v2/dotclear/plugins/pages/_admin.php new file mode 100644 index 0000000..0183cfc --- /dev/null +++ b/v2/dotclear/plugins/pages/_admin.php @@ -0,0 +1,51 @@ +addBehavior('adminDashboardIcons','pages_dashboard'); +$core->addBehavior('adminDashboardFavs','pages_dashboard_favs'); +$core->addBehavior('adminDashboardFavsIcon','pages_dashboard_favs_icon'); +function pages_dashboard($core,$icons) +{ + $icons['pages'] = new ArrayObject(array(__('Pages'),'plugin.php?p=pages','index.php?pf=pages/icon-big.png')); +} +function pages_dashboard_favs($core,$favs) +{ + $favs['pages'] = new ArrayObject(array('pages','Pages','plugin.php?p=pages', + 'index.php?pf=pages/icon.png','index.php?pf=pages/icon-big.png', + 'contentadmin,pages',null,null)); + $favs['newpage'] = new ArrayObject(array('newpage','New page','plugin.php?p=pages&act=page', + 'index.php?pf=pages/icon-np.png','index.php?pf=pages/icon-np-big.png', + 'contentadmin,pages',null,null)); +} +function pages_dashboard_favs_icon($core,$name,$icon) +{ + // Check if it is one of my own favs + if ($name == 'pages') { + $params = new ArrayObject(); + $params['post_type'] = 'page'; + $page_count = $core->blog->getPosts($params,true)->f(0); + if ($page_count > 0) { + $str_pages = ($page_count > 1) ? __('%d pages') : __('%d page'); + $icon[0] = sprintf($str_pages,$page_count); + } + } +} + +$_menu['Blog']->addItem(__('Pages'),'plugin.php?p=pages','index.php?pf=pages/icon.png', + preg_match('/plugin.php\?p=pages(&.*)?$/',$_SERVER['REQUEST_URI']), + $core->auth->check('contentadmin,pages',$core->blog->id)); + +$core->auth->setPermissionType('pages',__('manage pages')); + +require dirname(__FILE__).'/_widgets.php'; +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/pages/_define.php b/v2/dotclear/plugins/pages/_define.php new file mode 100644 index 0000000..421fe2a --- /dev/null +++ b/v2/dotclear/plugins/pages/_define.php @@ -0,0 +1,24 @@ +registerModule( + /* Name */ "Pages", + /* Description*/ "Serve entries as simple web pages", + /* Author */ "Olivier Meunier", + /* Version */ '1.1.1', + array( + 'permissions' => 'contentadmin,pages', + 'priority' => 999 + ) +); +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/pages/_prepend.php b/v2/dotclear/plugins/pages/_prepend.php new file mode 100644 index 0000000..72bba20 --- /dev/null +++ b/v2/dotclear/plugins/pages/_prepend.php @@ -0,0 +1,21 @@ +url->register('pages','pages','^pages/(.+)$',array('urlPages','pages')); +$core->url->register('pagespreview','pagespreview','^pagespreview/(.+)$',array('urlPages','pagespreview')); + +$core->setPostType('page','plugin.php?p=pages&act=page&id=%d',$core->url->getURLFor('pages','%s')); + +# We should put this as settings later +$GLOBALS['page_url_format'] = '{t}'; +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/pages/_public.php b/v2/dotclear/plugins/pages/_public.php new file mode 100644 index 0000000..0d59325 --- /dev/null +++ b/v2/dotclear/plugins/pages/_public.php @@ -0,0 +1,267 @@ +blog->withoutPassword(false); + + $params = new ArrayObject(array( + 'post_type' => 'page', + 'post_url' => $args)); + + $core->callBehavior('publicPagesBeforeGetPosts',$params,$args); + + $_ctx->posts = $core->blog->getPosts($params); + + $_ctx->comment_preview = new ArrayObject(); + $_ctx->comment_preview['content'] = ''; + $_ctx->comment_preview['rawcontent'] = ''; + $_ctx->comment_preview['name'] = ''; + $_ctx->comment_preview['mail'] = ''; + $_ctx->comment_preview['site'] = ''; + $_ctx->comment_preview['preview'] = false; + $_ctx->comment_preview['remember'] = false; + + $core->blog->withoutPassword(true); + + + if ($_ctx->posts->isEmpty()) + { + # The specified page does not exist. + self::p404(); + } + else + { + $post_id = $_ctx->posts->post_id; + $post_password = $_ctx->posts->post_password; + + # Password protected entry + if ($post_password != '' && !$_ctx->preview) + { + # Get passwords cookie + if (isset($_COOKIE['dc_passwd'])) { + $pwd_cookie = unserialize($_COOKIE['dc_passwd']); + } else { + $pwd_cookie = array(); + } + + # Check for match + if ((!empty($_POST['password']) && $_POST['password'] == $post_password) + || (isset($pwd_cookie[$post_id]) && $pwd_cookie[$post_id] == $post_password)) + { + $pwd_cookie[$post_id] = $post_password; + setcookie('dc_passwd',serialize($pwd_cookie),0,'/'); + } + else + { + self::serveDocument('password-form.html','text/html',false); + return; + } + } + + $post_comment = + isset($_POST['c_name']) && isset($_POST['c_mail']) && + isset($_POST['c_site']) && isset($_POST['c_content']) && + $_ctx->posts->commentsActive(); + + # Posting a comment + if ($post_comment) + { + # Spam trap + if (!empty($_POST['f_mail'])) { + http::head(412,'Precondition Failed'); + header('Content-Type: text/plain'); + echo "So Long, and Thanks For All the Fish"; + # Exits immediately the application to preserve the server. + exit; + } + + $name = $_POST['c_name']; + $mail = $_POST['c_mail']; + $site = $_POST['c_site']; + $content = $_POST['c_content']; + $preview = !empty($_POST['preview']); + + if ($content != '') + { + if ($core->blog->settings->system->wiki_comments) { + $core->initWikiComment(); + } else { + $core->initWikiSimpleComment(); + } + $content = $core->wikiTransform($content); + $content = $core->HTMLfilter($content); + } + + $_ctx->comment_preview['content'] = $content; + $_ctx->comment_preview['rawcontent'] = $_POST['c_content']; + $_ctx->comment_preview['name'] = $name; + $_ctx->comment_preview['mail'] = $mail; + $_ctx->comment_preview['site'] = $site; + + if ($preview) + { + # --BEHAVIOR-- publicBeforeCommentPreview + $core->callBehavior('publicBeforeCommentPreview',$_ctx->comment_preview); + + $_ctx->comment_preview['preview'] = true; + } + else + { + # Post the comment + $cur = $core->con->openCursor($core->prefix.'comment'); + $cur->comment_author = $name; + $cur->comment_site = html::clean($site); + $cur->comment_email = html::clean($mail); + $cur->comment_content = $content; + $cur->post_id = $_ctx->posts->post_id; + $cur->comment_status = $core->blog->settings->system->comments_pub ? 1 : -1; + $cur->comment_ip = http::realIP(); + + $redir = $_ctx->posts->getURL(); + $redir .= $core->blog->settings->system->url_scan == 'query_string' ? '&' : '?'; + + try + { + if (!text::isEmail($cur->comment_email)) { + throw new Exception(__('You must provide a valid email address.')); + } + + # --BEHAVIOR-- publicBeforeCommentCreate + $core->callBehavior('publicBeforeCommentCreate',$cur); + if ($cur->post_id) { + $comment_id = $core->blog->addComment($cur); + + # --BEHAVIOR-- publicAfterCommentCreate + $core->callBehavior('publicAfterCommentCreate',$cur,$comment_id); + } + + if ($cur->comment_status == 1) { + $redir_arg = 'pub=1'; + } else { + $redir_arg = 'pub=0'; + } + + header('Location: '.$redir.$redir_arg); + } + catch (Exception $e) + { + $_ctx->form_error = $e->getMessage(); + $_ctx->form_error; + } + } + } + + # The entry + $core->tpl->setPath($core->tpl->getPath(), dirname(__FILE__).'/default-templates'); + self::serveDocument('page.html'); + } + } + } + + public static function pagespreview($args) + { + $core = $GLOBALS['core']; + $_ctx = $GLOBALS['_ctx']; + + if (!preg_match('#^(.+?)/([0-9a-z]{40})/(.+?)$#',$args,$m)) { + # The specified Preview URL is malformed. + self::p404(); + } + else + { + $user_id = $m[1]; + $user_key = $m[2]; + $post_url = $m[3]; + if (!$core->auth->checkUser($user_id,null,$user_key)) { + # The user has no access to the entry. + self::p404(); + } + else + { + $_ctx->preview = true; + self::pages($post_url); + } + } + } +} + +class tplPages +{ + # Widget function + public static function pagesWidget($w) + { + global $core, $_ctx; + + if ($w->homeonly && $core->url->type != 'default') { + return; + } + + $params['post_type'] = 'page'; + $params['limit'] = abs((integer) $w->limit); + $params['no_content'] = true; + + $sort = $w->sortby; + if (!in_array($sort,array('post_title','post_position','post_dt'))) { + $sort = 'post_title'; + } + + $order = $w->orderby; + if ($order != 'asc') { + $order = 'desc'; + } + $params['order'] = $sort.' '.$order; + + $rs = $core->blog->getPosts($params); + + if ($rs->isEmpty()) { + return; + } + + $res = + '
        '. + ($w->title ? '

        '.html::escapeHTML($w->title).'

        ' : ''). + '
          '; + + while ($rs->fetch()) { + $class = ''; + if (($core->url->type == 'pages' && $_ctx->posts instanceof record && $_ctx->posts->post_id == $rs->post_id)) { + $class = ' class="page-current"'; + } + $res .= ''. + html::escapeHTML($rs->post_title).''; + } + + $res .= '
        '; + + return $res; + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/pages/_widgets.php b/v2/dotclear/plugins/pages/_widgets.php new file mode 100644 index 0000000..a6ba820 --- /dev/null +++ b/v2/dotclear/plugins/pages/_widgets.php @@ -0,0 +1,41 @@ +addBehavior('initWidgets',array('pagesWidgets','initWidgets')); +$core->addBehavior('initDefaultWidgets',array('pagesWidgets','initDefaultWidgets')); + +class pagesWidgets +{ + public static function initWidgets($w) + { + $w->create('pages',__('Pages'),array('tplPages','pagesWidget')); + $w->pages->setting('title',__('Title:'),__('Pages')); + $w->pages->setting('homeonly',__('Home page only'),1,'check'); + $w->pages->setting('sortby',__('Order by:'),'post_title','combo', + array( + __('Page title') => 'post_title', + __('Page position') => 'post_position', + __('Publication date') => 'post_dt' + ) + ); + $w->pages->setting('orderby',__('Sort:'),'asc','combo', + array(__('Ascending') => 'asc', __('Descending') => 'desc') + ); + } + + public static function initDefaultWidgets($w,$d) + { + $d['extra']->append($w->pages); + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/pages/default-templates/page.html b/v2/dotclear/plugins/pages/default-templates/page.html new file mode 100644 index 0000000..1a79823 --- /dev/null +++ b/v2/dotclear/plugins/pages/default-templates/page.html @@ -0,0 +1,247 @@ + + + + + + + {{tpl:EntryTitle encode_html="1"}} - {{tpl:BlogName encode_html="1"}} + + + + + + + + + + + + + + + + + + + + + + {{tpl:include src="_head.html"}} + + + + + + +
        +{{tpl:EntryPingData}} + +{{tpl:include src="_top.html"}} + +
        + +
        +
        + +
        +

        {{tpl:EntryTitle encode_html="1"}}

        + + + {{tpl:SysBehavior behavior="publicEntryBeforeContent"}} + + +
        {{tpl:EntryExcerpt}}
        +
        +
        {{tpl:EntryContent}}
        + +

        {{tpl:lang Published on}} {{tpl:EntryDate}} + {{tpl:lang by}} {{tpl:EntryAuthorLink}}

        + + + {{tpl:SysBehavior behavior="publicEntryAfterContent"}} +
        + + + + +
        +

        {{tpl:lang Attachments}}

        +
          + +
        • + + {{tpl:include src="_mp3_player.html"/}} - + + + {{tpl:include src="_flv_player.html"/}} + + + {{tpl:AttachmentTitle}} + +
        • + +
        +
        + +
        + + + + + +
        +

        {{tpl:lang Comments}}

        +
        + +
        {{tpl:CommentOrderNumber}}. + {{tpl:lang On}} {{tpl:CommentDate}}, {{tpl:CommentTime}} + {{tpl:lang by}} {{tpl:CommentAuthorLink}}
        + +
        + + {{tpl:SysBehavior behavior="publicCommentBeforeContent"}} + + {{tpl:CommentContent}} + + + {{tpl:SysBehavior behavior="publicCommentAfterContent"}} +
        + +
        +
        + +
        +
        + + + +

        {{tpl:SysFormError}}

        +
        + + +

        {{tpl:lang Your comment has been published.}}

        +
        + + +

        {{tpl:lang Your comment has been submitted and + will be reviewed for publication.}}

        +
        + + +
        + +
        +

        {{tpl:lang Your comment}}

        +
        +
        {{tpl:CommentPreviewContent}}
        +
        +

        +
        +
        + +

        {{tpl:lang Add a comment}}

        +
        + + {{tpl:SysBehavior behavior="publicCommentFormBeforeContent"}} + +

        + +

        + +

        + +

        + +

        + +

        + +

        + +

        + +

        + +

        {{tpl:CommentHelp}}

        + + + {{tpl:SysBehavior behavior="publicCommentFormAfterContent"}} +
        + +
        +

        +

        +
        +
        +
        + + + +
        +

        {{tpl:lang They posted on the same topic}}

        + + +
        + +
        {{tpl:PingOrderNumber}}. + {{tpl:lang On}} {{tpl:PingDate}}, {{tpl:PingTime}} + {{tpl:lang by}} {{tpl:PingBlogName encode_html="1"}}
        + +
        + + {{tpl:SysBehavior behavior="publicPingBeforeContent"}} + +

        {{tpl:PingTitle encode_html="1"}}

        + {{tpl:PingContent}} + + + {{tpl:SysBehavior behavior="publicPingAfterContent"}} +
        + +
        + +
        +
        +
        + + +

        {{tpl:lang Trackback URL}} : {{tpl:EntryPingLink}}

        +
        + + +

        {{tpl:lang This page's comments feed}}

        +
        +
        +
        + + + +
        + +{{tpl:include src="_footer.html"}} +
        + + \ No newline at end of file diff --git a/v2/dotclear/plugins/pages/icon-big.png b/v2/dotclear/plugins/pages/icon-big.png new file mode 100644 index 0000000000000000000000000000000000000000..b11cfb55b83e0b525af53ad1a20be8ec46065d65 GIT binary patch literal 2736 zcmbVOcT`hnAHGSDJp#&b!8Je&B4hvwL`D`tP!JQuRM8TW3#5=i5(H8|Oe0%FR8TBf zmMohgaTJlN)Cwr5pdg^Z1}pu(KYIGdch9-^UC;CU=6lXf3-I^W(_W@lXZ8Qq}1d&F% zqyBP=^OUY#Bxc2 z21z(#o=D0Q3cy80cBn8$>W)%*`d0{ik)Pk+!UDu~)AJLM)coBqVKoVh$n4_vknB@{#mAij8ve_f#y@c#sV+`9FFb`z#^SJ8 zFAN2bp{YdZDm5&XOd~9DeFPFITfl*q?DAB0KXb|d$|X|85L+q~2MUEzOC1mpA(RRw z5ke72Wjcd9cml34R9Y~tp|$p{WdWMqjy``X533L=~=h?w%UaCFVg$eKqUZA-jyse4pU*8zKjt@Vv;)M%g!OgO15kBufQ{w}5#uYboz$tCV zEn6S!mTfHkPB)dxxv>s`$K&4yJ9L+qm)|VBYi-G>yrW@hX<5=2!iBd@>>yF<*UV?0(3u-Mf_wWBuj(sWJLbt$UJz zlB&1n&4|a#;DkUk9vVjerDO_ep})o7|BDXa6ZWLv#AF9d+UjC(pWG5F>L`fCr3?XMK4$;nCE1|kuy z)rO;QHof27W3m;_KX55et=$KRGF9Vn3-0M? zX6T~eG04J;=ieiWe$*L<+^i5ENDZPV?IWk;$Wi!=xi<-to2uz%z!TFzKx=+$h#|@K6hV+{(;M80?bIIE19E&)8;$mw3On zxbfhCJih(Z#@J_JVPPJM%?z*>P;Uqrq;%5X<_!pwZ14@hU8i;qwm90KRZ2?!CLR|S zFy(*rXh%o(>E+pLQkmz`^t2)-?z-)*)_d2ujFy-e_hLnP>x_Ygo%6*tp}>cRE+5nn zpx4<=K|%NP$DEem4!y45JYd_U+hukORzpLP8Fa>u505N>SAkX5{aX!@8@#Nj?HThf z;e{`1Whb`~`z7`xHrASJ%p9{*oqH1|6G|={3kbkoP9nMTfL%n>m18CsYtlE-MN3$ z!b-XE`{nh6tRd#b)odahwY^=9 zUp{RnsV!eO=ii!he5iQs-IYZS7bE;ron|l3M`mh$?3VZRYF!|oK4Kv3h^RSK;2n#( z6Bf4xm8%)U{l#VkhMz2HNiporNTVYk-r6;eEt}JyE}0FbJ!gKq@L_H$jhfO$h@$Hr z8}yk>O42&o_mFV@Ij+tI+nNS(IGh&pq-nG#D!sb8+G1{`^TLeS(sb9ZYh9jmar4<} z2hW_@-s=?U=BxW!U7BJHv=%VE`@fXPPOkdtv`K%(+I}-wZA_L;X*^SNnciM@RrwfW z>&s21?+w2jpH*;H=lo{M9KX1VG$HFO4@oR*SoY=ab9Wvj^%@0vS7x0`IzF=>t_%E> Wdd+`L`WwvRKctVBKkXbPMDZsKe__7> literal 0 HcmV?d00001 diff --git a/v2/dotclear/plugins/pages/icon-np-big.png b/v2/dotclear/plugins/pages/icon-np-big.png new file mode 100644 index 0000000000000000000000000000000000000000..d4ffd60f9053f2b29c67cf575b2f1e327f953a9a GIT binary patch literal 2635 zcmbVOX;f2Z8jc|-1fd}XDrn&n<5CRS2nmSR__F}aYGY$QP<%aDRCb*q4A z#pRd|(K1v~TcL;uh={m>sGve6RI!kX3jzXFhq+kk%#WV_nD3l>zvVv9^Df`}o^!WF zM+Vy?-H~9Ri){&MH&#slBhO;K&V2L4)Q^f zWJ~51&>se~lE?&!y2OZZhFGP*i{>zRy+RGKVKD!7dbLQL0qTHFV7g4n#5_OOi~(d4 zCMLl*f*7F=0;RH$91R$o6DbhqWQge!%(?);U(bL96rfH7=oNCMmZ4{2-sv)+_1rN5 z1H6OiGMJb@oJx#{27*)?5b(tly~RW-5ulRrBp(WmM#BMQB8f;Kk_jZTH;KmZAv1_X z;Qhcr)-;kd2A{)wZwuNnF;bmQ%^(o6v$OHpK6sTToj{_~>2n%nvNweA)^1ViM0#(f zcKN&l2h@r+GPO>oQUY^|qD`tS9TNk2`bP)~bwtFU!b@V{>SC0Z-kq6P_kP^-$)h@tyPTRu;Qa`*R!=75klj3|u^x)hO|qY`H+K&38} z!^A*e@DiDXL8kL4G!C0h<@oWqL=wr*&zH*cAya8|GL1)M`_60p6_-b2@q9QGKNgDw z4K9&QVYB_XTso0XByqW9;ygE0snv;;VsPHB46^&4OZ!_cBS-^^bSjNNrIOEAK(th) zQ)#6tH4qf*3na*t5>>W#?sEQ!l>=&In?VUrqf!9xvdfVDg>@Q*NcE!!LG{97%|*@T z5PgGKJ~S$o=EI|~{V?yjlK&@T1jre}TxtAIsmvci^*6Wtv+$wKpREHbp?=XojbSmV znqjbo`Jo(^K;Ji%5|)AEI@MHLD#F9l@)QUU;9=y=FN_acn^Ev2$#Tg@FA7rI_CAr9 z;oh#mARl&Sq3f$`k)CILZg0pse&Ao5JDERKH&ma?DcfOR{A@ye%bZ}|a>t@{fQ`;J zIyG6P5;n)~U)Oy=HSNCFH}HvR1*L;~vDPZLv!li?jAOP7HXNNt zz}??;TF5KuUwiJ7#bWs>H#c|V5SGPRX!_Z%Eu^=^_~^pRp|glOp9+`s^z4%*>vmqN1qD9#!AWwNsxwvUwHa zib_2tBBdU0MRd}6v_6sDwzUxhOt6}*}G z=-`dC<9EQ*o~;gUgZn+V#$T7VQPlfKpA8OtA?^P_PlR8eeb{dOW#w$|+O>NtRuXL0 zyYeE~F;1tL?me%UuIa?AK*)*qu)D&ARFum_(FPZ*%%q$YVaO8a!b^2sXs4TNtOvIR zMejcT!KsW~DdyMl^KH)%t7mtO?=)7z%9_Pf*_f7)-Pwn{g4&xsVbsv-(+IV7Xr=wf z!Hu#4oGWhQVwr#hG#pXxE$T$=m&WX_R|7mO(F9L zT)tRpRlma|#ty9i-GT%j4_k#X5COSvTN`}uR+0NLn_<4D0y!YeqlW{|h+fSGst2X}As4ZXZj760k+Hvsfn3?vko9NAFj7N*ljLM?# zFM+vRzUw%fu_Nx=?y0ktS6Q$ok*)G0>C*Z>L;Gi?9m8V{%|KQBVx9H%Wx`FY+v4dd zgyn(cq?PIAqSZ&%6&LRR47RH)(=jIL=Hy723BHd^_$tmoc`(vabQ_e4>{wE8;fF`YMcw|k>s@;BrJ6c%Y{3Vg(F$F1wD1@eQBmz(8Y zZFhT52lh=ab6$Vgwn~tC-xc|(mu4u_bUAACDYvvL2Q|}b5I3G`{K5O%V>UGyfe~)J zk#iwlbu5PMiZs|2|9sGm`tb(gq&gggpMYOpT>tF@ccYYm8nG@7SZVmq)S3uiZ!iry z+x6D&b8yuTbvc(cW4(SE5k&}MvB%Ja?SUUE5X)7{{jI|zK@03)-;Ih3-5$_@ z0I!bncr?7C67agRWxL?>qGd_2;0Nd>l$osSV>u?fVAH+@J@sk3>d_OERzB^psaAS?Umuxj41E@WUN7j$#7u5C(Gt2A&^URASC)Q{YLyeB zJ+aIA$syKd9nQNY7R%@@<8Qh6E3qD>zK%d>n*u((Hr_nF%$hxVax%E|Xyu-^#PM$` z2LbkDe#^s`FJBIy4A4(ic61*LII-;Qn?l5zZ8jwmN}TYsQQQ}kZ?E1HEXhfzSMu&0 z>2#=g{e4VFqj%DH%0{mjO9`ftIO4dg+bg^0%LyZ1jEFRc4*)oOmmI4f*0k fX2itvf3InQ^>m0wC6138=YH=(xsjY2wy^L&yzxQT literal 0 HcmV?d00001 diff --git a/v2/dotclear/plugins/pages/icon-np.png b/v2/dotclear/plugins/pages/icon-np.png new file mode 100644 index 0000000000000000000000000000000000000000..6f7f7de66a13d314e17bdd57761543cffaba1d45 GIT binary patch literal 1369 zcmbVMZA{!`951jrB$B=80z)UYGiErsw)bi)2lTF2Ipx^xI5IRWtXz9{9rT5^a0e!O zA&VKJjuH3n=KD)bgbX872_py!+m|hb!9>TLV{VIK%fi%{#o$xm&<|uEe3JHg{!jnE z-~YX>{<3E?GjcK@2+H)9&;hWoF`o4Mz&m$#js@EW-BYQT%V9mnsysw-at#lAMK;0* zc$RCbKg}0FP#Px$EA>iWDH)PQ6Km+0;-Ui35L8eUSJ+T3ufsKbM39`wt=@hF7C0xe z-R8r5ikpuLCCw^d-dq+8HP?m+4k;>x3*sao5P6-2<6@npk#Q$7&r5={ag8GIyoz4y zL>8Q?^!Z`8tn#qUgyn}YI|kcv6K=6O9FC`8GlpX*W=3&yKJFkbW)j2T#f1QCDik5gYu~^I$vzTNxg5m^07#wDEKG4Y5nk1c#=S$kABm>QBAyrUxL6%^H zk*$#%bSDBlT?j!`e7+@ONn1=5NEsSu6%;pNs3;n7&1-9VfdAKxWwo_nlft6`UXvTt z5U59ZQxXhvcW*<6BJhUXstTYeY#l9!8bn^wy|fbnUre09k+g%tF`FGDa2MvmaGYQ) zG(}lG78}DbRtVLx7c9+}W?SjO~G0iB>Laa2e3XMF+sImypXO|R~ zvrgIRr#(2vm|a#QY9Qj2hq9S5%#Aw;;Q0cU`#%{&fitMl8vkjPYI{Kd-U;4XcV=kzyW3CfpY6^%J$%)7`7-xPWMk`|)R7~* zW?J_@clG_UK;-c2lkIDWy?jcjY9PD!?`?VG#gAp@hGUMv9ZOfN@Yl0l@`K%3cjpq+ z0HIa1k7ZAn?d|DcEM2zhEO$bwr&}%@_K%Lfcy8CjO8dnh-#l7Pypa2wojjF(;#kT0 z8+y(IeVH5g9U3aG_~c+S)DxXHB|NDIu7!6LeR$|`%HJ7$qc9O1_@Vmc6|>&=-o5*K z8aBfw;L^G1OVELKi8y{`u;taMw1j_W#{C~arNhr0D_l9o4xE7#nSGCrY!Qj$E!&_w zCsTLhU+iug-vdo-Nk2OB$hoOYiOISPpZ@^`vnEnjCN?yDHudSm_|Lf~zUlVwyK)jr XgQW1;s;R~ZX8i2Do-(@AwX@|PuuJH; literal 0 HcmV?d00001 diff --git a/v2/dotclear/plugins/pages/icon.png b/v2/dotclear/plugins/pages/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..26f64b8cc6da5288231e547451dafae0417dd7c7 GIT binary patch literal 1509 zcmbVMdr%a09N!EX155@hDJs_!)QY>^z2i7`=_8$Qz}gBe;Y zTdvMTGu;MI#H5w+z*?4NbCeZ3a9XxxF`VorBmox?DcI{OVFkjgm5u8X(mb$@$l!5^ zSge&zIF*x`4I4Nfz-k35cc6(VoQNqfRf0yNiHDUah9amE!IW}LL#UJlio%nROtQw) zPQpT(CT&S8t*l5C-2{SoJRXHdrQrBN1jBJWprKUCC4^ikWkt#>XNCDe1ri7jo^gu| z$HD~xT;pg#w19uzm=Z16O5Fgl z0D)W0JEVFz=LgAB?jCI@0F=BTUgH_5C{zi_Iaa#>E1F5IOgd4}3{8+49fqnCQ5@5w zMij$vlZw>o5{xRf$z)1U>Vq0nagC(XfMbS4J(h%Hm=V>fj2gX0m1IyU)#?N_8RVK- zL8Mp*2-;;NyOUh?Be{fu2b9S1HjXO^c0hI!Cvrj&=Y|bdHN2c*Y0e`AiZc-_33z4= zpiMmIg2%HiX6SmzjEe;)KkLV8am_`0k61AD{Ltw2 zU+!Ly7(C6lwRQKK4ToX5J++b;9FpJnjy7Ex$cz2LRPy)v9XJdt)c%Ku>Y6Hr09?bygzNBhPzt%^Mtz}wecr&41&A|rPkSkT`c`-hY9 z_uRbqz5mkY3Qcu%Ztp_=#Mwi(4}1$MziB<5A9J(vuXEAxJKxSQ`b8h_TNr(7ItTWNYfQ3xD~z9)c?+L3M<+b}t5cowU_+hJ-q3SH$QYwr z1_nUCbzXU>J)Shouy!8WVyI{x-2tKot7dJV)yNXz< z1>56L_T8Gz?)6O}-Q{cFb39cv0P8Oq>uURUtvWQQND-P2s+l=IElr8Po9i3XR*}E@N*w;( \ No newline at end of file diff --git a/v2/dotclear/plugins/pages/list.php b/v2/dotclear/plugins/pages/list.php new file mode 100644 index 0000000..695f548 --- /dev/null +++ b/v2/dotclear/plugins/pages/list.php @@ -0,0 +1,205 @@ +rs->isEmpty()) + { + echo '

        '.__('No page').'

        '; + } + else + { + $pager = new pager($page,$this->rs_count,$nb_per_page,10); + $pager->html_prev = $this->html_prev; + $pager->html_next = $this->html_next; + $pager->var_page = 'page'; + + $html_block = + ''. + ''. + ''. + ''. + ''. + ''. + ''. + '%s
        '.__('Title').''.__('Date').''.__('Author').''.__('Comments').''.__('Trackbacks').''.__('Status').'
        '; + + if ($enclose_block) { + $html_block = sprintf($enclose_block,$html_block); + } + + echo '

        '.__('Page(s)').' : '.$pager->getLinks().'

        '; + + $blocks = explode('%s',$html_block); + + echo $blocks[0]; + + while ($this->rs->fetch()) + { + echo $this->postLine(); + } + + echo $blocks[1]; + + echo '

        '.__('Page(s)').' : '.$pager->getLinks().'

        '; + } + } + + private function postLine() + { + $img = '%1$s'; + switch ($this->rs->post_status) { + case 1: + $img_status = sprintf($img,__('published'),'check-on.png'); + break; + case 0: + $img_status = sprintf($img,__('unpublished'),'check-off.png'); + break; + case -1: + $img_status = sprintf($img,__('scheduled'),'scheduled.png'); + break; + case -2: + $img_status = sprintf($img,__('pending'),'check-wrn.png'); + break; + } + + $protected = ''; + if ($this->rs->post_password) { + $protected = sprintf($img,__('protected'),'locker.png'); + } + + $selected = ''; + if ($this->rs->post_selected) { + $selected = sprintf($img,__('selected'),'selected.png'); + } + + $attach = ''; + $nb_media = $this->rs->countMedia(); + if ($nb_media > 0) { + $attach_str = $nb_media == 1 ? __('%d attachment') : __('%d attachments'); + $attach = sprintf($img,sprintf($attach_str,$nb_media),'attach.png'); + } + + $res = ''; + + $res .= + ''. + form::checkbox(array('entries[]'),$this->rs->post_id,'','','',!$this->rs->isEditable(),'title="'.__('select this page').'"').''. + ''. + html::escapeHTML($this->rs->post_title).''. + ''.dt::dt2str(__('%Y-%m-%d %H:%M'),$this->rs->post_dt).''. + + ''.$this->rs->user_id.''. + ''.$this->rs->nb_comment.''. + ''.$this->rs->nb_trackback.''. + ''.$img_status.' '.$selected.' '.$protected.' '.$attach.''. + ''; + + return $res; + } +} + +/* Getting pages +-------------------------------------------------------- */ +$params = array( + 'post_type' => 'page' +); + +$page = !empty($_GET['page']) ? (integer) $_GET['page'] : 1; +$nb_per_page = 30; + +if (!empty($_GET['nb']) && (integer) $_GET['nb'] > 0) { + $nb_per_page = (integer) $_GET['nb']; +} + +$params['limit'] = array((($page-1)*$nb_per_page),$nb_per_page); +$params['no_content'] = true; +$params['order'] = 'post_position ASC, post_title ASC'; + +try { + $pages = $core->blog->getPosts($params); + $counter = $core->blog->getPosts($params,true); + $post_list = new adminPageList($core,$pages,$counter->f(0)); +} catch (Exception $e) { + $core->error->add($e->getMessage()); +} + +# Actions combo box +$combo_action = array(); +if ($core->auth->check('publish,contentadmin',$core->blog->id)) +{ + $combo_action[__('publish')] = 'publish'; + $combo_action[__('unpublish')] = 'unpublish'; + $combo_action[__('schedule')] = 'schedule'; + $combo_action[__('mark as pending')] = 'pending'; +} +if ($core->auth->check('admin',$core->blog->id)) { + $combo_action[__('change author')] = 'author'; +} +if ($core->auth->check('delete,contentadmin',$core->blog->id)) +{ + $combo_action[__('delete')] = 'delete'; +} + +# --BEHAVIOR-- adminPagesActionsCombo +$core->callBehavior('adminPagesActionsCombo',array(&$combo_action)); + +/* Display +-------------------------------------------------------- */ +?> + + + <?php echo __('Pages'); ?> + + + + + +'.html::escapeHTML($core->blog->name).' › '.__('Pages').''. +'

        '.__('New page').'

        '; + +if (!$core->error->flag()) +{ + # Show pages + $post_list->display($page,$nb_per_page, + '
        '. + + '%s'. + + '
        '. + '

        '. + + '

        '. + form::combo('action',$combo_action). + '

        '. + form::hidden(array('post_type'),'page'). + form::hidden(array('redir'),html::escapeHTML($_SERVER['REQUEST_URI'])). + $core->formNonce(). + '
        '. + '
        '); +} +dcPage::helpBlock('pages'); +?> + + \ No newline at end of file diff --git a/v2/dotclear/plugins/pages/locales/en/help/page.html b/v2/dotclear/plugins/pages/locales/en/help/page.html new file mode 100644 index 0000000..b91793f --- /dev/null +++ b/v2/dotclear/plugins/pages/locales/en/help/page.html @@ -0,0 +1,165 @@ + + + Editing a page + + + + +

        Editing a page

        + +
        +
        Page title
        +
        Type in the page title. This field is mandatory.
        + +
        Excerpt
        +
        This field is optional.
        + +
        Content
        +
        The content of your page. This field is mandatory.
        + +
        Notes
        +
        This text area is for personal use, for notes or memos. What you enter here + will never be displayed on the blog..
        + +
        Page status
        +
        Allows you to choose your page's status: +
          +
        • pending: the publication status has not yet been decided.
        • +
        • scheduled: the page will be set online at the time and date + set in the Published on field.
        • +
        • unpublished: the page is offline.
        • +
        • published: the page is online.
        • +
        +
        + +
        Published on
        +
        Here you can change the page's publication date and time. If the page's + status is scheduled, it will come online at the said date and time.
        + +
        Text formating
        +
        To choose the page syntax. Wiki is a simplified syntax + and will be converted to valid xhtml ; Unless you have a perfect + understanding of xhtml, we advise you to choose the wiki syntax. + See the Wiki syntax reference for more information.
        + +
        Accept comments
        +
        Select this box to allow your visitors to comment the page. The corresponding + global setting is to be found in the blog settings.
        + +
        Accept trackbacks
        +
        A trackback is a way to let a portion of your page as a comment on + another blog. Select this box to allow others to trackback your page. The + corresponding global setting is to be found in the blog settings.
        + +
        Page position
        +
        Allows to order pages according to this number. + This field is used by Pages widget (Order by page position).
        + +
        Page language
        +
        The two character language code of your page. It defaults to your (as a + user) language but you can change it to whatever language code you want, ie. + "en" or "fr-qc". This code is used for the page's display, no check is made + on it.
        + +
        Page password
        +
        You can enter a password for your page. A password protected page will + not be displayed on your blog, it will only be reachable to those you will + give the page url (see the view page link) and password.
        + +
        Basename
        +
        By clicking on its lock, you can unprotect this field and and choose another + URL for your page. If the URL you're trying to use is already used by another + page, a number will be added to it.
        +
        + +

        Comments

        +
        +
        Comment list
        +
        On the Comments tab, you can read and change the status of + your page's comments. If you're allowed to by the blog administrator, + you will be able to set your comments online or offline, to delete them or + to mark them as junk.
        + +
        Add a comment
        +
        On the Add a comment tab, you can reply to one of your page's + comments without leaving your blog's backend. The syntax to be used here is + plain, unlimited, xhtml. Use the fields as if you were modifying a comment.
        +
        + +

        Wiki syntax reference

        + +

        The wiki syntax is a way to enhance your text with a minimal set +of tags, studied to cover the basic needs (titles, paragraphs, quotes, +lists...)

        + +
        +
        Block elements
        +
        +
          +
        • Leave an empty line between two similar blocks.
        • +
        • Paragraph: free text, ended by an empty line if + another paragraph is to follow.
        • +
        • Title: !!! title, !! title + or ! title, allowing you to use three different levels of + heading.
        • +
        • Horizontal line: ----
        • +
        • Lists: Start each line with + * or # for unnumbered or numbered lists respectively. + List imbrication is done by mixing list markers this way: +
          +* item 1
          +** item 1.1
          +* item 2
          +*# item 2.1
          +...
          +
          +
        • +
        • Preformatted text: each line must start with a space.
        • +
        • Block quote: each line must start with a semicolon (>).
        • +
        +
        + +
        Formatting tags
        +
        +
          +
        • Emphasis: two quotes ''text''
        • +
        • Strong emphasis: two underscore __text__
        • +
        • New line: %%%
        • +
        • Insertion: two plusses ++text++
        • +
        • Deletion: two minuses --text--
        • +
        • Link: [url], [name|url], + [name|url|language] or [name|url|languagee|title]
        • +
        • Image: + ((url|alternative text)), + ((url|alternative text|position)) or + ((url|alternative text|position|long description)). +
          The position can be either L or G (left), R or D (right) or C (centered).
        • +
        • Anchor: ~anchor~
        • +
        • Acronym: ??acronym|title??
        • +
        • Inline HTML: two backquotes ``html code``
        • +
        • Inline quote: {{quote}}, + {{quote|language}} or {{quote|language|url}}
        • +
        • Code: @@code@@
        • +
        • Footnotes: $$footnote$$
        • +
        +
        + +
        Unformatted text
        +
        If you don't want one formatting character to be interpreted as such, add a +\ just before it. This way: +\[text in brackets without being a link\] +
        + +
        HTML Code
        +
        Even if you chose the wiki syntax, you may sometimes need a more +powerful formatting, i.e. HTML syntax. Do it the following way: +
        +///html
        +<p style="color:red">my text in red</p>
        +///
        +
        +
        +
        + + + \ No newline at end of file diff --git a/v2/dotclear/plugins/pages/locales/en/help/pages.html b/v2/dotclear/plugins/pages/locales/en/help/pages.html new file mode 100644 index 0000000..1afd515 --- /dev/null +++ b/v2/dotclear/plugins/pages/locales/en/help/pages.html @@ -0,0 +1,22 @@ + + + Managing pages + + + + +

        Selected pages actions

        +

        If your user permission level allows it, you can perform batch operations on the +pages you select in the list.

        + +
          +
        • Publish : set pages online,
        • +
        • Unpublish : set pages offline,
        • +
        • Mark as pending : erase other publication status,
        • +
        • Change author : allows you to change the pages' author by + entering the new author's ID,
        • +
        • Delete : suppress the pages (this operation cannot be undone).
        • +
        + + + \ No newline at end of file diff --git a/v2/dotclear/plugins/pages/locales/en/resources.php b/v2/dotclear/plugins/pages/locales/en/resources.php new file mode 100644 index 0000000..1df1128 --- /dev/null +++ b/v2/dotclear/plugins/pages/locales/en/resources.php @@ -0,0 +1,21 @@ + \ No newline at end of file diff --git a/v2/dotclear/plugins/pages/locales/fr/help/page.html b/v2/dotclear/plugins/pages/locales/fr/help/page.html new file mode 100644 index 0000000..1b17b7d --- /dev/null +++ b/v2/dotclear/plugins/pages/locales/fr/help/page.html @@ -0,0 +1,172 @@ + + + Rédaction d'une page + + + + +

        Rédaction de la page

        + +
        +
        Titre de la page
        +
        Inscrivez le titre de la page. Ce champ est obligatoire.
        + +
        Extrait
        +
        Ce champ est optionnel.
        + +
        Contenu
        +
        Le contenu de la page. Ce champ est obligatoire.
        + +
        Notes
        +
        Cette zone de texte sert à la prise de notes ou pense-bête divers. Elle ne + sera jamais affichée sur le blog.
        + +
        Etat de la page
        +
        Permet de choisir l'état de la page après enregistrement : +
          +
        • en attente : en attente de publication.
        • +
        • programmée : la page sera mise en ligne à la date et à l'heure + indiquées dans le champ Publiée le.
        • +
        • non publiée : page hors ligne.
        • +
        • publiée : page en ligne.
        • +
        +
        + +
        Publiée le
        +
        Permet de modifier la date et l'heure de publication de la page. Si vous avez + choisi le statut programmée elle sera mise en ligne aux date et heure + définis dans ce champ.
        + +
        Format du texte
        +
        Permet de choisir la syntaxe de saisie de la page. Le wiki est une syntaxe + simplifiée et sera converti en xhtml valide ; à moins que vous maîtrisiez + parfaitement le xhtml nous vous conseillons de la choisir de préférence. + Consultez la référence de la syntaxe Wiki pour plus + d'informations.
        + +
        Accepter les commentaires
        +
        Cochez ou décochez la case selon que vous souhaitez permettre ou interdire + les commentaires sur la page en particulier. L'option pour permettre ou + autoriser de façon générale les commentaires se situe dans le menu Préférences + du blog.
        + +
        Accepter les rétroliens
        +
        Un rétrolien permet de signaler une page dans les commentaires d'un autre + blog. Cochez ou décochez la case selon que vous souhaitez permettre ou interdire + les rétroliens sur la page. L'option pour permettre ou autoriser de façon + générale les rétroliens se situe dans le menu Préférences du blog.
        + +
        Position de la page
        +
        Permet de classer les différentes pages en fonction de leur numéro d'ordre. + Ce champ est utilisé par le widget Pages (Trier par position de la page).
        + +
        Langue de la page
        +
        Code langue de votre page. Par défaut, il s'agit du code de votre + langue. Vous pouvez le changer, par le code d'une autre langue, par + exemple "en", "fr-qc". Ce code est libre, il sera utilisé lors de l'affichage + des pages.
        + +
        Mot de passe de la page
        +
        Permet de déterminer un mot de passe d'accès à une page dans le blog. Une + page protégée par mot de passe ne sera visible nulle part sur votre blog, vous + pourrez en donner l'adresse à vos lecteurs en vous rendant sur le lien + Voir la page.
        + +
        URL spécifique
        +
        Ce champ permet de choisir une URL pour une page autre que celle par défaut + après avoir cliqué sur le petit verrou placé à sa droite. Si vous essayez + d'utiliser une URL déjà existante, celle-ci se verra incrémentée d'un chiffre.
        +
        + +

        Commentaires

        +
        +
        Liste les commentaires
        +
        Depuis l'onglets Commentaires vous pouvez lire et changer l'état + des commentaires de votre page. Suivant vos permissions, vous pouvez modifier, + mettre en ligne ou hors ligne, supprimer ou classer comme commentaire + indésirable.
        + +
        Ajouter un commentaire
        +
        Depuis l'onglet Ajouter un commentaire vous pouvez répondre + directement à un commentaire sans passer par votre blog. Cette interface vous + permet également de saisir votre commentaire en XHTML, sans limitation. Vous + devrez remplir les champs de la même manière qu'en modifiant un commentaire.
        +
        + +

        Référence de la syntaxe Wiki

        + +

        La syntaxe Wiki est une manière d'écrire du texte avec un jeu de balises +réduit au minimum, permettant de couvrir les besoins les plus courants +(titres, paragraphes, citations, listes...).

        + +
        +
        Éléments de bloc
        +
        +
          +
        • Laissez une ligne vide entre chaque bloc de même nature.
        • +
        • Paragraphe : texte libre, terminé par une ligne + vide si suivi d'un second paragraphe.
        • +
        • Titre : !!! titre, !! titre + ou ! titre pour des titres plus ou moins importants.
        • +
        • Trait horizontal : ----
        • +
        • Listes : lignes débutant par * pour des + listes à puce ou # pour des listes numérotées. Vous pouvez faire + des listes imbriquées en mélangeant les codes de liste. Par exemple : +
          +* item 1
          +** item 1.1
          +* item 2
          +*# item 2.1
          +...
          +
          +
        • +
        • Texte préformaté : espace avant chaque ligne de texte.
        • +
        • Bloc de citation : > devant chaque + ligne de texte.
        • +
        +
        + +
        Éléments de formatage
        +
        +
          +
        • Emphase : deux apostrophes ''texte''
        • +
        • Forte emphase : deux soulignés __texte__
        • +
        • Retour forcé à la ligne : %%%
        • +
        • Insertion : deux plus ++texte++
        • +
        • Suppression : deux moins --texte--
        • +
        • Lien : [url], [nom|url], + [nom|url|langue] ou [nom|url|langue|titre]
        • +
        • Image : + ((url|texte alternatif)), + ((url|texte alternatif|position)) ou + ((url|texte alternatif|position|description longue)). +
          La position peut prendre les valeurs L ou G (gauche), R ou D (droite) ou C (centré).
        • +
        • Ancre : ~ancre~
        • +
        • Acronyme : ??acronyme|titre??
        • +
        • Code HTML en ligne: deux apostrophes inversées ``code html``
        • +
        • Citation en ligne : {{citation}}, + {{citation|langue}} ou {{citation|langue|url}}
        • +
        • Code : @@code ici@@
        • +
        • Note de bas de page : $$Corps de la note$$
        • +
        +
        + +
        Empêcher le formatage du texte
        +
        Pour insérer un caractère sans que celui-ci soit reconnu comme un caractère +de formatage, ajoutez le caractère \ avant celui-ci. Par exemple : +\[texte entre crochet qui n'est pas un lien\] +
        + +
        Insérer du code HTML
        +
        Vous pouvez ponctuellement avoir besoin d'insérer du code HTML dans votre +texte au format Wiki. Pour cela, utilisez le code suivant : +
        +///html
        +<p style="color:red">mon texte en rouge</p>
        +///
        +
        +
        +
        + + + \ No newline at end of file diff --git a/v2/dotclear/plugins/pages/locales/fr/help/pages.html b/v2/dotclear/plugins/pages/locales/fr/help/pages.html new file mode 100644 index 0000000..1036b19 --- /dev/null +++ b/v2/dotclear/plugins/pages/locales/fr/help/pages.html @@ -0,0 +1,22 @@ + + + Gestion des pages + + + + +

        Actions par lot sur les pages

        +

        Il est possible d'effectuer un ensemble d'actions sur plusieurs pages, d'un +seul coup. Les actions possibles dépendent des permissions de l'utilisateur.

        + +
          +
        • Publier : mettre la page en ligne,
        • +
        • Hors ligne : mettre la page hors ligne,
        • +
        • En attente : en attente de publication,
        • +
        • Changer l'auteur : permet de changer l'auteur de la page en indiquant + l'identifiant de l'utilisateur qui deviendra le nouvel auteur,
        • +
        • Supprimer : supprime la page (cette opération est irréversible).
        • +
        + + + \ No newline at end of file diff --git a/v2/dotclear/plugins/pages/locales/fr/resources.php b/v2/dotclear/plugins/pages/locales/fr/resources.php new file mode 100644 index 0000000..1df1128 --- /dev/null +++ b/v2/dotclear/plugins/pages/locales/fr/resources.php @@ -0,0 +1,21 @@ + \ No newline at end of file diff --git a/v2/dotclear/plugins/pages/page.php b/v2/dotclear/plugins/pages/page.php new file mode 100644 index 0000000..a123b8c --- /dev/null +++ b/v2/dotclear/plugins/pages/page.php @@ -0,0 +1,659 @@ +auth->getOption('post_format'); +$post_password = ''; +$post_url = ''; +$post_lang = $core->auth->getInfo('user_lang'); +$post_title = ''; +$post_excerpt = ''; +$post_excerpt_xhtml = ''; +$post_content = ''; +$post_content_xhtml = ''; +$post_notes = ''; +$post_status = $core->auth->getInfo('user_post_status'); +$post_position = 0; +$post_open_comment = false; +$post_open_tb = false; + +$post_media = array(); + +$page_title = __('New page'); + +$can_view_page = true; +$can_edit_page = $core->auth->check('pages,usage',$core->blog->id); +$can_publish = $core->auth->check('pages,publish,contentadmin',$core->blog->id); +$can_delete = false; + +$post_headlink = ''; +$post_link = '%s'; + +$next_link = $prev_link = $next_headlink = $prev_headlink = null; + +# If user can't publish +if (!$can_publish) { + $post_status = -2; +} + +# Status combo +foreach ($core->blog->getAllPostStatus() as $k => $v) { + $status_combo[$v] = (string) $k; +} + +# Formaters combo +foreach ($core->getFormaters() as $v) { + $formaters_combo[$v] = $v; +} + +# Languages combo +$rs = $core->blog->getLangs(array('order'=>'asc')); +$all_langs = l10n::getISOcodes(0,1); +$lang_combo = array('' => '', __('Most used') => array(), __('Available') => l10n::getISOcodes(1,1)); +while ($rs->fetch()) { + if (isset($all_langs[$rs->post_lang])) { + $lang_combo[__('Most used')][$all_langs[$rs->post_lang]] = $rs->post_lang; + unset($lang_combo[__('Available')][$all_langs[$rs->post_lang]]); + } else { + $lang_combo[__('Most used')][$rs->post_lang] = $rs->post_lang; + } +} +unset($all_langs); +unset($rs); + + +# Get page informations +if (!empty($_REQUEST['id'])) +{ + $params['post_type'] = 'page'; + $params['post_id'] = $_REQUEST['id']; + + $post = $core->blog->getPosts($params); + + if ($post->isEmpty()) + { + $core->error->add(__('This page does not exist.')); + $can_view_page = false; + } + else + { + $post_id = $post->post_id; + $post_dt = date('Y-m-d H:i',strtotime($post->post_dt)); + $post_format = $post->post_format; + $post_password = $post->post_password; + $post_url = $post->post_url; + $post_lang = $post->post_lang; + $post_title = $post->post_title; + $post_excerpt = $post->post_excerpt; + $post_excerpt_xhtml = $post->post_excerpt_xhtml; + $post_content = $post->post_content; + $post_content_xhtml = $post->post_content_xhtml; + $post_notes = $post->post_notes; + $post_status = $post->post_status; + $post_position = (integer) $post->post_position; + $post_open_comment = (boolean) $post->post_open_comment; + $post_open_tb = (boolean) $post->post_open_tb; + + $page_title = __('Edit page'); + + $can_edit_page = $post->isEditable(); + $can_delete= $post->isDeletable(); + + $next_rs = $core->blog->getNextPost($post,1); + $prev_rs = $core->blog->getNextPost($post,-1); + + if ($next_rs !== null) { + $next_link = sprintf($post_link,$next_rs->post_id, + html::escapeHTML($next_rs->post_title),__('next page').' »'); + $next_headlink = sprintf($post_headlink,'next', + html::escapeHTML($next_rs->post_title),$next_rs->post_id); + } + + if ($prev_rs !== null) { + $prev_link = sprintf($post_link,$prev_rs->post_id, + html::escapeHTML($prev_rs->post_title),'« '.__('previous page')); + $prev_headlink = sprintf($post_headlink,'previous', + html::escapeHTML($prev_rs->post_title),$prev_rs->post_id); + } + + try { + $core->media = new dcMedia($core); + $post_media = $core->media->getPostMedia($post_id); + } catch (Exception $e) {} + } +} + +# Format content +if (!empty($_POST) && $can_edit_page) +{ + $post_format = $_POST['post_format']; + $post_excerpt = $_POST['post_excerpt']; + $post_content = $_POST['post_content']; + + $post_title = $_POST['post_title']; + + if (isset($_POST['post_status'])) { + $post_status = (integer) $_POST['post_status']; + } + + if (empty($_POST['post_dt'])) { + $post_dt = ''; + } else { + $post_dt = strtotime($_POST['post_dt']); + $post_dt = date('Y-m-d H:i',$post_dt); + } + + $post_open_comment = !empty($_POST['post_open_comment']); + $post_open_tb = !empty($_POST['post_open_tb']); + $post_lang = $_POST['post_lang']; + $post_password = !empty($_POST['post_password']) ? $_POST['post_password'] : null; + $post_position = (integer) $_POST['post_position']; + + $post_notes = $_POST['post_notes']; + + if (isset($_POST['post_url'])) { + $post_url = $_POST['post_url']; + } + + $core->blog->setPostContent( + $post_id,$post_format,$post_lang, + $post_excerpt,$post_excerpt_xhtml,$post_content,$post_content_xhtml + ); +} + +# Create or update post +if (!empty($_POST) && !empty($_POST['save']) && $can_edit_page) +{ + $cur = $core->con->openCursor($core->prefix.'post'); + + # Magic tweak :) + $core->blog->settings->system->post_url_format = $page_url_format; + + $cur->post_type = 'page'; + $cur->post_title = $post_title; + $cur->post_dt = $post_dt ? date('Y-m-d H:i:00',strtotime($post_dt)) : ''; + $cur->post_format = $post_format; + $cur->post_password = $post_password; + $cur->post_lang = $post_lang; + $cur->post_title = $post_title; + $cur->post_excerpt = $post_excerpt; + $cur->post_excerpt_xhtml = $post_excerpt_xhtml; + $cur->post_content = $post_content; + $cur->post_content_xhtml = $post_content_xhtml; + $cur->post_notes = $post_notes; + $cur->post_status = $post_status; + $cur->post_position = $post_position; + $cur->post_open_comment = (integer) $post_open_comment; + $cur->post_open_tb = (integer) $post_open_tb; + + if (isset($_POST['post_url'])) { + $cur->post_url = $post_url; + } + + # Update post + if ($post_id) + { + try + { + # --BEHAVIOR-- adminBeforePageUpdate + $core->callBehavior('adminBeforePageUpdate',$cur,$post_id); + + $core->blog->updPost($post_id,$cur); + + # --BEHAVIOR-- adminAfterPageUpdate + $core->callBehavior('adminAfterPageUpdate',$cur,$post_id); + + http::redirect($redir_url.'&id='.$post_id.'&upd=1'); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } + } + else + { + $cur->user_id = $core->auth->userID(); + + try + { + # --BEHAVIOR-- adminBeforePageCreate + $core->callBehavior('adminBeforePageCreate',$cur); + + $return_id = $core->blog->addPost($cur); + + # --BEHAVIOR-- adminAfterPageCreate + $core->callBehavior('adminAfterPageCreate',$cur,$return_id); + + http::redirect($redir_url.'&id='.$return_id.'&crea=1'); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } + } +} + +if (!empty($_POST['delete']) && $can_delete) +{ + try { + # --BEHAVIOR-- adminBeforePageDelete + $core->callBehavior('adminBeforePageDelete',$post_id); + $core->blog->delPost($post_id); + http::redirect($p_url); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} + +/* DISPLAY +-------------------------------------------------------- */ +$default_tab = 'edit-entry'; +if (!$can_edit_page) { + $default_tab = ''; +} +if (!empty($_GET['co'])) { + $default_tab = 'comments'; +} + +?> + + + <?php echo $page_title.' - '.__('Pages'); ?> + + callBehavior('adminPageHeaders'). + dcPage::jsPageTabs($default_tab). + $next_headlink."\n".$prev_headlink; + ?> + + + + +'.__('Page has been successfully updated.').'

        '; +} +elseif (!empty($_GET['crea'])) { + echo '

        '.__('Page has been successfully created.').'

        '; +} +elseif (!empty($_GET['attached'])) { + echo '

        '.__('File has been successfully attached.').'

        '; +} +elseif (!empty($_GET['rmattach'])) { + echo '

        '.__('Attachment has been successfully removed.').'

        '; +} + +# XHTML conversion +if (!empty($_GET['xconv'])) +{ + $post_excerpt = $post_excerpt_xhtml; + $post_content = $post_content_xhtml; + $post_format = 'xhtml'; + + echo '

        '.__('Don\'t forget to validate your XHTML conversion by saving your post.').'

        '; +} + +echo '

        '.html::escapeHTML($core->blog->name). +' › '.__('Pages').''.$page_title; + if ($post_id) { + echo ' “'.$post_title.'”'; + } +echo '

        '; + +if ($post_id && $post->post_status == 1) { + echo '

        '.__('Go to this page on the site').'

        '; +} + +echo ''; + +if ($post_id) +{ + echo '

        '; + if ($prev_link) { echo $prev_link; } + if ($next_link && $prev_link) { echo ' - '; } + if ($next_link) { echo $next_link; } + + # --BEHAVIOR-- adminPageNavLinks + $core->callBehavior('adminPageNavLinks',isset($post) ? $post : null); + + echo '

        '; +} + +# Exit if we cannot view page +if (!$can_view_page) { + echo ''; + return; +} + + +/* Post form if we can edit post +-------------------------------------------------------- */ +if ($can_edit_page) +{ + echo '
        '; + echo '
        '; + + echo '
        '; + echo '
        '; + + echo + '

        '. + + '

        '. + form::textarea('post_excerpt',50,5,html::escapeHTML($post_excerpt)). + '

        '. + + '

        '. + form::textarea('post_content',50,$core->auth->getOption('edit_size'),html::escapeHTML($post_content)). + '

        '; + + echo + '

        '. + form::textarea('post_notes',50,5,html::escapeHTML($post_notes)). + '

        '; + + # --BEHAVIOR-- adminPageForm + $core->callBehavior('adminPageForm',isset($post) ? $post : null); + + echo + '

        '. + ($post_id ? form::hidden('id',$post_id) : ''). + ' '; + + if ($post_id) { + $preview_url = $core->blog->url. + $core->url->getURLFor('pagespreview', + $core->auth->userID().'/'. + http::browserUID(DC_MASTER_KEY.$core->auth->userID().$core->auth->getInfo('user_pwd')). + '/'.$post->post_url); + echo ''.__('Preview').''; + } + + echo + ($can_delete ? '' : ''). + $core->formNonce(). + '

        '; + + echo '
        '; // End #entry-content + echo '
        '; // End #entry-wrapper + + echo '
        '; + + echo + '

        '. + + '

        '. + + '

        '. + + '

        '. + '

        '. + + '

        '. + + '

        '. + + '

        '. + + '
        '. + '

        '. + '

        '. + __('Warning: If you set the URL manually, it may conflict with another page.'). + '

        '. + '
        '; + + if ($post_id) + { + echo + '

        '.__('Attachments').'

        '; + foreach ($post_media as $f) + { + $ftitle = $f->media_title; + if (strlen($ftitle) > 18) { + $ftitle = substr($ftitle,0,16).'...'; + } + echo + '
        '. + ''. + ''. + ''. + '
        '; + } + unset($f); + + if (empty($post_media)) { + echo '

        '.__('No attachment.').'

        '; + } + echo '

        '.__('Add files to this page').'

        '; + } + + # --BEHAVIOR-- adminPageFormSidebar + $core->callBehavior('adminPageFormSidebar',isset($post) ? $post : null); + + echo '
        '; // End #entry-sidebar + + echo '
        '; + echo '
        '; + + if ($post_id && !empty($post_media)) + { + echo + '
        '. + '
        '.form::hidden(array('post_id'),$post_id). + form::hidden(array('media_id'),''). + form::hidden(array('remove'),1). + $core->formNonce().'
        '; + } +} + + +/* Comments and trackbacks +-------------------------------------------------------- */ +if ($post_id) +{ + $params = array('post_id' => $post_id, 'order' => 'comment_dt ASC'); + + $comments = $core->blog->getComments(array_merge($params,array('comment_trackback'=>0))); + $trackbacks = $core->blog->getComments(array_merge($params,array('comment_trackback'=>1))); + + # Actions combo box + $combo_action = array(); + if ($can_edit_page && $core->auth->check('publish,contentadmin',$core->blog->id)) + { + $combo_action[__('publish')] = 'publish'; + $combo_action[__('unpublish')] = 'unpublish'; + $combo_action[__('mark as pending')] = 'pending'; + $combo_action[__('mark as junk')] = 'junk'; + } + + if ($can_edit_page && $core->auth->check('delete,contentadmin',$core->blog->id)) + { + $combo_action[__('delete')] = 'delete'; + } + + $has_action = !empty($combo_action) && (!$trackbacks->isEmpty() || !$comments->isEmpty()); + + echo + '
        '; + + if ($has_action) { + echo '
        '; + } + + echo '

        '.__('Trackbacks').'

        '; + + if (!$trackbacks->isEmpty()) { + showComments($trackbacks,$has_action); + } else { + echo '

        '.__('No trackback').'

        '; + } + + echo '

        '.__('Comments').'

        '; + if (!$comments->isEmpty()) { + showComments($comments,$has_action); + } else { + echo '

        '.__('No comment').'

        '; + } + + if ($has_action) { + echo + '
        '. + '

        '. + + '

        '. + form::combo('action',$combo_action). + form::hidden('redir',html::escapeURL($redir_url).'&id='.$post_id.'&co=1'). + $core->formNonce(). + '

        '. + '
        '. + '
        '; + } + + echo '
        '; +} + +/* Add a comment +-------------------------------------------------------- */ +if ($post_id) +{ + echo + '
        '. + '

        '.__('Add a comment').'

        '. + + '
        '. + '
        '. + '

        '. + + '

        '. + + '

        '. + + '

        '. + form::textarea('comment_content',50,8,html::escapeHTML('')). + '

        '. + + '

        '.form::hidden('post_id',$post_id). + $core->formNonce(). + '

        '. + '
        '. + '
        '. + '
        '; +} + + +# Show comments or trackbacks +function showComments($rs,$has_action) +{ + echo + ''. + ''. + ''. + ''. + ''. + ''. + ''; + + while($rs->fetch()) + { + $comment_url = 'comment.php?id='.$rs->comment_id; + + $img = '%1$s'; + switch ($rs->comment_status) { + case 1: + $img_status = sprintf($img,__('published'),'check-on.png'); + break; + case 0: + $img_status = sprintf($img,__('unpublished'),'check-off.png'); + break; + case -1: + $img_status = sprintf($img,__('pending'),'check-wrn.png'); + break; + case -2: + $img_status = sprintf($img,__('junk'),'junk.png'); + break; + } + + echo + ''. + + ''. + ''. + ''. + ''. + ''. + ''. + + ''; + } + + echo '
        '.__('Author').''.__('Date').''.__('IP address').''.__('Status').' 
        '. + ($has_action ? form::checkbox(array('comments[]'),$rs->comment_id,'','','',0,'title="'.__('select this comment').'"') : '').''.$rs->comment_author.''.dt::dt2str(__('%Y-%m-%d %H:%M'),$rs->comment_dt).''.$rs->comment_ip.''.$img_status.''. + '
        '; +} +dcPage::helpBlock('page'); +?> + + \ No newline at end of file diff --git a/v2/dotclear/plugins/pings/_admin.php b/v2/dotclear/plugins/pings/_admin.php new file mode 100644 index 0000000..86ea58c --- /dev/null +++ b/v2/dotclear/plugins/pings/_admin.php @@ -0,0 +1,47 @@ +addItem(__('Pings'),'plugin.php?p=pings','index.php?pf=pings/icon.png', + preg_match('/plugin.php\?p=pings/',$_SERVER['REQUEST_URI']), + $core->auth->isSuperAdmin()); + +$__autoload['pingsAPI'] = dirname(__FILE__).'/lib.pings.php'; +$__autoload['pingsBehaviors'] = dirname(__FILE__).'/lib.pings.php'; + +# Create settings if they don't exist +if (!array_key_exists('pings',$core->blog->settings->dumpNamespaces())) +{ + $default_pings_uris = array( + 'Ping-o-Matic!' => 'http://rpc.pingomatic.com/', + 'Google Blog Search' => 'http://blogsearch.google.com/ping/RPC2' + ); + + $core->blog->settings->addNamespace('pings'); + $core->blog->settings->pings->put('pings_active',1,'boolean','Activate pings plugin',true,true); + $core->blog->settings->pings->put('pings_uris',serialize($default_pings_uris),'string','Pings services URIs',true,true); +} + +$core->addBehavior('adminPostHeaders',array('pingsBehaviors','pingJS')); +$core->addBehavior('adminPostFormSidebar',array('pingsBehaviors','pingsForm')); +$core->addBehavior('adminAfterPostCreate',array('pingsBehaviors','doPings')); +$core->addBehavior('adminAfterPostUpdate',array('pingsBehaviors','doPings')); + +$core->addBehavior('adminDashboardFavs','pingDashboardFavs'); + +function pingDashboardFavs($core,$favs) +{ + $favs['pings'] = new ArrayObject(array('pings','Pings','plugin.php?p=pings', + 'index.php?pf=pings/icon.png','index.php?pf=pings/icon-big.png', + null,null,null)); +} +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/pings/_define.php b/v2/dotclear/plugins/pings/_define.php new file mode 100644 index 0000000..8e7a8a9 --- /dev/null +++ b/v2/dotclear/plugins/pings/_define.php @@ -0,0 +1,23 @@ +registerModule( + /* Name */ "Pings", + /* Description*/ "Ping services", + /* Author */ "Olivier Meunier", + /* Version */ '1.1', + array( + 'permissions' => 'usage,contentadmin' + ) +); +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/pings/icon-big.png b/v2/dotclear/plugins/pings/icon-big.png new file mode 100644 index 0000000000000000000000000000000000000000..19dd23f9684d4910a558c6df23f568c4b4559b0a GIT binary patch literal 5223 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 literal 0 HcmV?d00001 diff --git a/v2/dotclear/plugins/pings/icon.png b/v2/dotclear/plugins/pings/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..4324dd541cf77d3ceb252bec51f9e34b208a4030 GIT binary patch literal 1370 zcmbVMZA{#B9PWV(g5nS+3W3mckr~5X-?%%jazK0S!J)_C?${7FLb(>M9Cz*7vO6Ho zNgPVh7<36jf^XT}hhxFzdg_M zd;PbkstJRthVhD=B2nM5=5w#LHMj!~d{y>^FnQJ0E zv~%5-wz5M3Rh0-Bjzl7+2yPPPW*D{EY`O-988w7aX%DMx)EHK_#}sH@@ymjw3St=4 z71>6yO|?Usr)wdEB)5A*IIOHEN=q3WWhEFjA#f<9$F+)9R1g2J8=ImPU%SM^9$pdK zWWQFArtLAZmb-f!(t(;c#7Y#83aXb zPMjvm0tPoboz4P`ifL@hwK%LeZF5k#g+w)WAy!B-3}r*jq=lg!c#P``D=HiI^D(=E zZg-7K-IGf=WS&(;*(Zvvu@0yTh^nXrLb}??*t%m@>@QRBjebFBdzka@Ayfk&9`Rjux{wA2=hMVcp>5=)V-l~t= zQxcwCGITMIC);nQe$qSI#TFlrVpB=d(QVQ< z`-6|=1*S#=JK4~ZxZK%yr`K|O@b?}ljp!emXr3MT;6mNjW21&s^E1Ic`*N<%9{5zc2(=TSx6>pqd03W{GUVkICye7?t zi8*6e^Gc6;ey%&QD_wavE&o9J>4rzUy+4}551no4tIhcQwFP5B0dR4cm8{^E4Bx;+ z=`~O0%V}{_(yNcW!)6=q@9eu#8karsLSg>Nvt{E&)pmolw|_@!#d{aV&)qEj>Zx0$ z09TXTGxz<0ys627L*FRq?blog->settings->pings->pings_uris); + if (!$pings_uris) { + $pings_uris = array(); + } + + if (isset($_POST['pings_srv_name'])) + { + $pings_srv_name = is_array($_POST['pings_srv_name']) ? $_POST['pings_srv_name'] : array(); + $pings_srv_uri = is_array($_POST['pings_srv_uri']) ? $_POST['pings_srv_uri'] : array(); + $pings_uris = array(); + + foreach ($pings_srv_name as $k => $v) { + if (trim($v) && trim($pings_srv_uri[$k])) { + $pings_uris[trim($v)] = trim($pings_srv_uri[$k]); + } + } + + $core->blog->settings->addNamespace('pings'); + $core->blog->settings->pings->put('pings_active',!empty($_POST['pings_active']),null,null,true,true); + $core->blog->settings->pings->put('pings_uris',serialize($pings_uris),null,null,true,true); + http::redirect($p_url.'&up=1'); + } +} +catch (Exception $e) +{ + $core->error->add($e->getMessage()); +} +?> + + + <?php echo __('Pings'); ?> + + + +'.__('Pings configuration').''; + +if (!empty($_GET['up'])) { + echo '

        '.__('Settings have been successfully updated.').'

        '; +} + +echo +'
        '. +'

        '; + +$i = 0; +foreach ($pings_uris as $n => $u) +{ + echo + '

        '. + ''; + + if (!empty($_GET['test'])) + { + try { + pingsAPI::doPings($u,'Example site','http://example.com'); + echo ' ok'; + } catch (Exception $e) { + echo ' '.__('error').' '.$e->getMessage(); + } + } + + echo '

        '; + $i++; +} + +echo +'

        '. +''. +'

        '. + +'

        '. +$core->formNonce().'

        '. +'
        '; + +echo '

        '.__('Test ping services').'

        '; +?> + + \ No newline at end of file diff --git a/v2/dotclear/plugins/pings/lib.pings.php b/v2/dotclear/plugins/pings/lib.pings.php new file mode 100644 index 0000000..7b3cbdb --- /dev/null +++ b/v2/dotclear/plugins/pings/lib.pings.php @@ -0,0 +1,99 @@ +timeout = 3; + + $rsp = $o->query('weblogUpdates.ping',$site_name,$site_url); + + if (isset($rsp['flerror']) && $rsp['flerror']) { + throw new Exception($rsp['message']); + } + + return true; + } +} + +class pingsBehaviors +{ + public static function pingJS() + { + $res = + "\n".dcPage::jsLoad('index.php?pf=pings/post.js'); + + return $res; + } + + public static function pingsForm($post) + { + $core =& $GLOBALS['core']; + if (!$core->blog->settings->pings->pings_active) { + return; + } + + $pings_uris = @unserialize($core->blog->settings->pings->pings_uris); + if (empty($pings_uris) || !is_array($pings_uris)) { + return; + } + + if (!empty($_POST['pings_do']) && is_array($_POST['pings_do'])) { + $pings_do = $_POST['pings_do']; + } else { + $pings_do = array(); + } + + echo '

        '.__('Pings:').'

        '; + $i = 0; + foreach ($pings_uris as $k => $v) + { + echo + '

        '; + $i++; + } + } + + public static function doPings($cur,$post_id) + { + if (empty($_POST['pings_do']) || !is_array($_POST['pings_do'])) { + return; + } + + $core =& $GLOBALS['core']; + if (!$core->blog->settings->pings->pings_active) { + return; + } + + $pings_uris = @unserialize($core->blog->settings->pings->pings_uris); + if (empty($pings_uris) || !is_array($pings_uris)) { + return; + } + + foreach ($_POST['pings_do'] as $uri) + { + if (in_array($uri,$pings_uris)) { + try { + pingsAPI::doPings($uri,$core->blog->name,$core->blog->url); + } catch (Exception $e) {} + } + } + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/pings/post.js b/v2/dotclear/plugins/pings/post.js new file mode 100644 index 0000000..8be054a --- /dev/null +++ b/v2/dotclear/plugins/pings/post.js @@ -0,0 +1,3 @@ + +$(function(){$('#edit-entry').onetabload(function(){if($('p.ping-services').length>0){p=$('

        ');p.addClass('ping-services');a=$('');a.text(dotclear.msg.check_all);a.click(function(){$('p.ping-services input[type="checkbox"]').attr('checked','checked');return false;});$('p.ping-services:last').after(p.append(a));} +$('h3.ping-services').toggleWithLegend($('p.ping-services'),{cookie:'dcx_ping_services'});});}); \ No newline at end of file diff --git a/v2/dotclear/plugins/simpleMenu/_admin.php b/v2/dotclear/plugins/simpleMenu/_admin.php new file mode 100644 index 0000000..f838125 --- /dev/null +++ b/v2/dotclear/plugins/simpleMenu/_admin.php @@ -0,0 +1,32 @@ +addBehavior('adminDashboardIcons','simpleMenu_dashboard'); +$core->addBehavior('adminDashboardFavs','simpleMenu_dashboard_favs'); +function simpleMenu_dashboard($core,$icons) +{ + $icons['simpleMenu'] = new ArrayObject(array(__('Simple menu'),'plugin.php?p=simpleMenu','index.php?pf=simpleMenu/icon.png')); +} +function simpleMenu_dashboard_favs($core,$favs) +{ + $favs['simpleMenu'] = new ArrayObject(array('simpleMenu','Simple menu','plugin.php?p=simpleMenu', + 'index.php?pf=simpleMenu/icon-small.png','index.php?pf=simpleMenu/icon.png', + 'usage,contentadmin',null,null)); +} + +$_menu['Plugins']->addItem(__('Simple menu'),'plugin.php?p=simpleMenu','index.php?pf=simpleMenu/icon-small.png', + preg_match('/plugin.php\?p=simpleMenu(&.*)?$/',$_SERVER['REQUEST_URI']), + $core->auth->check('usage,contentadmin',$core->blog->id)); + +require dirname(__FILE__).'/_widgets.php'; +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/simpleMenu/_define.php b/v2/dotclear/plugins/simpleMenu/_define.php new file mode 100644 index 0000000..c76d76d --- /dev/null +++ b/v2/dotclear/plugins/simpleMenu/_define.php @@ -0,0 +1,23 @@ +registerModule( + /* Name */ "simpleMenu", + /* Description*/ "Simple menu for Dotclear", + /* Author */ "Franck Paul", + /* Version */ '1.0', + array( + 'permissions' => 'admin' + ) +); +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/simpleMenu/_install.php b/v2/dotclear/plugins/simpleMenu/_install.php new file mode 100644 index 0000000..f6722e7 --- /dev/null +++ b/v2/dotclear/plugins/simpleMenu/_install.php @@ -0,0 +1,29 @@ +plugins->moduleInfo('simpleMenu','version'); +if (version_compare($core->getVersion('simpleMenu'),$version,'>=')) { + return; +} + +# Menu par défaut +$blog_url = html::stripHostURL($core->blog->url); +$menu_default = array( + array('label' => 'Home', 'descr' => 'Recent posts', 'url' => $blog_url), + array('label' => 'Archives', 'descr' => '', 'url' => $blog_url.$core->url->getURLFor('archive')) +); +$core->blog->settings->system->put('simpleMenu',serialize($menu_default),'string','simpleMenu default menu',false,true); + +$core->setVersion('simpleMenu',$version); +return true; +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/simpleMenu/_public.php b/v2/dotclear/plugins/simpleMenu/_public.php new file mode 100644 index 0000000..5737447 --- /dev/null +++ b/v2/dotclear/plugins/simpleMenu/_public.php @@ -0,0 +1,116 @@ +tpl->addValue('SimpleMenu',array('tplSimpleMenu','simpleMenu')); + +class tplSimpleMenu +{ + # Template function + public static function simpleMenu($attr) + { + $class = isset($attr['class']) ? trim($attr['class']) : ''; + $id = isset($attr['id']) ? trim($attr['id']) : ''; + $description = isset($attr['description']) ? trim($attr['description']) : ''; + + if (!preg_match('#^(title|span)$#',$description)) { + $description = ''; + } + + return ''; + } + + # Widget function + public static function simpleMenuWidget($w) + { + global $core, $_ctx; + + if ($w->homeonly && $core->url->type != 'default') { + return; + } + + $menu = tplSimpleMenu::displayMenu('','','title'); + if ($menu == '') { + return; + } + + return '
        '.($w->title ? '

        '.html::escapeHTML($w->title).'

        ' : '').$menu.'
        '; + } + + public static function displayMenu($class='',$id='',$description='') + { + $ret = ''; + + $menu = $GLOBALS['core']->blog->settings->system->get('simpleMenu'); + $menu = @unserialize($menu); + + if (is_array($menu)) + { + // Current relative URL + $url = $_SERVER['REQUEST_URI']; + $abs_url = http::getHost().$url; + + // Home recognition var + $home_url = html::stripHostURL($GLOBALS['core']->blog->url); + $home_directory = dirname($home_url); + if ($home_directory != '/') + $home_directory = $home_directory.'/'; + + // Menu items loop + foreach ($menu as $i => $m) { + # $href = lien de l'item de menu + $href = $m['url']; + $href = html::escapeHTML($href); + + # Active item test + $active = false; + if (($url == $href) || + ($abs_url == $href) || + ($_SERVER['URL_REQUEST_PART'] == $href) || + (($_SERVER['URL_REQUEST_PART'] == '') && (($href == $home_url) || ($href == $home_directory)))) { + $active = true; + } + $title = $span = ''; + if ($m['descr']) { + if ($description == 'title') { + $title = ' title="'.__($m['descr']).'"'; + } else { + $span = ' '.__($m['descr']).''; + } + } + $ret .= '
      • '. + ''.__($m['label']).$span.''. + '
      • '; + } + + // Final rendering + if ($ret) { + $ret = '
          '."\n".$ret."\n".'
        '; + } + } + + return $ret; + } +} + +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/simpleMenu/_widgets.php b/v2/dotclear/plugins/simpleMenu/_widgets.php new file mode 100644 index 0000000..72f9507 --- /dev/null +++ b/v2/dotclear/plugins/simpleMenu/_widgets.php @@ -0,0 +1,25 @@ +addBehavior('initWidgets',array('simpleMenuWidgets','initWidgets')); + +class simpleMenuWidgets +{ + public static function initWidgets($w) + { + $w->create('simplemenu',__('Simple menu'),array('tplSimpleMenu','simpleMenuWidget')); + $w->simplemenu->setting('title',__('Title:'),__('Menu')); + $w->simplemenu->setting('homeonly',__('Home page only'),1,'check'); + } +} +?> \ No newline at end of file diff --git a/v2/dotclear/plugins/simpleMenu/icon-small.png b/v2/dotclear/plugins/simpleMenu/icon-small.png new file mode 100644 index 0000000000000000000000000000000000000000..aea1775ddc5fba30fb4e08ccef3681c33058e1bd GIT binary patch literal 1328 zcmbVMZA{!`9Pf<`aNz>UVm8P!O3`E(xwhAPYjZbt*Ivg>4$k8YOii}l^*LzZ+FM(^ z0})U*P=eVD%Um3Z@x!7YrfeGbVJ4CZW?AC&gD*IZF6tDgWFSOQV4P3k4*fv(!6xnV z_WS+*uTNhJ)$ccNE8B)3h&fQph2dCYyoLGjTfUGH;83djoApK|uBQYQAYM_40yK~i zT0j^GV&{?Tz>Oezq7-S?n}c;sOi5S-17k@il8}uc?wWK`h_wM7je-_Q_F%K`k7KAL zdax#YkO(GO&??n-si3i|J`(F{i_s!hvln%z87Pndx`3t=?Xt$CJ=mHq1Lwvzj-hK1 zz0HHIJJlQvp{$|;)NUcFV}yf19i)Y%Y)+^1QPfJ11Ws6S(ppVA8Oq8K1e$#?XiXL4 zOqk=dw&2Qxwd#73!SPfoWl2#MMQy=Jnx+j6tF;;;sS(GC}DXGs#WU49quqkRt6>Gko1gUWFOvZf1i4CL%e z&~BFNyf2qwRUqh!8c~$?TnB_&6$cXK0kTmC4uH!7I-X{I=zHP*5-!e)`v) zm5oD}4v3RW_YTb;eBg~6!xwfvwRi099H_X>u}_o|=7l|#r+b!OzB*WOLB)qmZm-{y z>Fr7NJz^S}R%)((zvWN!YfY*AcTn4ohLfjH=?_kep}cSAf2d-Q{frOnKfas%_{l5B zP98>k4o;n0a9@0L;pW)vC+G*4OZv&WddJY6vKQmgmai6*tK+*yFU^7H4$-4|McmHM z0@v!db2ZCRneNX&EX{YuyHoLo%*E9& z#uiP#oSGS)IXZ&vsftY$6z^W?UA+5kW_fWobNn%LAw`A?=gQ`OyjDCg~i4{Ea0!_-u4}S;UBQ-)=2;W literal 0 HcmV?d00001 diff --git a/v2/dotclear/plugins/simpleMenu/icon.png b/v2/dotclear/plugins/simpleMenu/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..07f5de7afcc97d73e3e94fb0c2e3dbca30390e49 GIT binary patch literal 2188 zcmbVOX;2es8t#A~hYXGjf~Z3qYGGE%(SZ<%#1PU!ZaL*}$r6$VT1Yx14TMWj3-Dl6 zhAEK4tth&qponHbK?D)GSHNQ(v{Zye5eH;;R^*z2?Wj2W!*Z*(tGeIs`}%#J_wMS0 z0sh-fjI4|R05I|Lgo6m_ro9dHiDwm>^pp_ma6vd8jK$)qA_W5QBv=drdPzlbNDv~D zq$PDDt^lAbK|{jva6ezR7?V;(S{clsN}FW{ z7*UE9s2oQz8K`9x#bC)ehfH|-J_M=U&+j9#O!*;EM9OF?k(>rm=`^WS8`nE+B_4$Q z?#3szl_6bDsSTx}bJ~m`{?=A-aaAHYM$^yO6i0vi{561yN_C8mWgn9yBIBcMtp45H5@E zJz6}1@9AGinwoCfzDsXDHvV{L6Mg1bQEx_*wURqiG1V{=3sxxOV~f}oW!He~Z&k!5s5@sTn8^z`%^ zC%#dIw`~zm5Mk`*ZUB=D)mhCEj?X;5Hj7MkFGj{PHNe0`;9p7(Cv=vb)wvy{=MPq_^2WCx#z}hN<^K;Qf(%(nLa&TRaF7MmN$2Qj3ihm7y z;U=%kEbSaC9V%dJvv!?!+peQubp+eQ zE!;me1#~%2H0GWf&D}h#`6py|USFyAG;KJpdZ|+Q9LpvF>jB-7llJ*GUwrd4h*a~8 z)|s`I1emWvZ#HGDbRZRw!)I&GHGY4ibbSY!*bHBZ!$l>%^e*0z#UtZCRm|eKOEeEl z(nR6gj6ywjda1oAe}Sv=YZQh7XKNRrd^`3`&z*)0v!DfuLDi1QgNJ-f>rQi5w$LI6 zlH;%I2lPlO=dYd1TT$hecy)XJk;2l(FjB=Wp?}Ajm)^y##*m?z-qv72x3q3(Fxc;M zj)ksJuw?qOZGWfd$=Aqg^J&=8{=|3CrHNd`k<4qaDm-lY>TX`)p6BgpT@pr4HScoK zqsqi3lEgDK>1JW)V8_J8@Vd|fOS|B%6B6|vZ z=e|7`$bowQUcYNF_*fJt5)NzdNw4**@!ovPMhb3eJs_Axh6Fb>k?a#MCMPHR4qyd2 zXO3K}nR(JZq<1(XpuPt?nsTC{zWS~1SLJ>9jOmu@fZCpD9qXHIQARmd)W&Yn$;+?K z@4M8qN+r~{i|ZJwoi^bF=0~j?zq5Jh^%LtX`Q2&vqOu*FmY7kuVzYwP$`MVU<_bqo zj>cwMmeYhXj@f|~r!k)iom%%-CC30-elk0%HD8A@i+NL$Ui=5c;0WO zO0?M8f4gbv$2rannzZJ(D4KA->L@TPqtxEp>OQj7T_*blog->url); + +# Liste des catégories +$categories_combo = array(); +$categories_label = array(); +try { + $rs = $core->blog->getCategories(array('post_type'=>'post')); + while ($rs->fetch()) { + $categories_combo[] = new formSelectOption( + str_repeat('  ',$rs->level-1).($rs->level-1 == 0 ? '' : '• ').html::escapeHTML($rs->cat_title), + $rs->cat_url + ); + $categories_label[$rs->cat_url] = html::escapeHTML($rs->cat_title); + } +} catch (Exception $e) { } + +# Liste des langues utilisées +$langs_combo = array(); +try { + $rs = $core->blog->getLangs(array('order'=>'asc')); + if ($rs->count() > 1) + { + $all_langs = l10n::getISOcodes(0,1); + while ($rs->fetch()) { + $lang_name = isset($all_langs[$rs->post_lang]) ? $all_langs[$rs->post_lang] : $rs->post_lang; + $langs_combo[$lang_name] = $rs->post_lang; + } + unset($all_langs); + } + unset($rs); +} catch (Exception $e) { } + +# Liste des mois d'archive +$months_combo = array(); +try { + $rs = $core->blog->getDates(array('type'=>'month')); + $months_combo[__('All months')] = '-'; + $first_year = $last_year = 0; + while ($rs->fetch()) { + $months_combo[dt::str('%B %Y',$rs->ts())] = $rs->year().$rs->month(); + if (($first_year == 0) || ($rs->year() < $first_year)) $first_year = $rs->year(); + if (($last_year == 0) || ($rs->year() > $last_year)) $last_year = $rs->year(); + } + unset($rs); +} catch (Exception $e) { } + +# Liste des pages -- Doit être pris en charge plus tard par le plugin ? +$pages_combo = array(); +try { + $rs = $core->blog->getPosts(array('post_type'=>'page')); + while ($rs->fetch()) { + $pages_combo[$rs->post_title] = $rs->getURL(); + } + unset($rs); +} catch (Exception $e) { } + +# Liste des tags -- Doit être pris en charge plus tard par le plugin ? +$tags_combo = array(); +try { + $rs = $core->meta->getMetadata(array('meta_type' => 'tag')); + $tags_combo[__('All tags')] = '-'; + while ($rs->fetch()) { + $tags_combo[$rs->meta_id] = $rs->meta_id; + } + unset($rs); +} catch (Exception $e) { } + +# Liste des types d'item de menu +$items = new ArrayObject(); +$items['home'] = new ArrayObject(array(__('Home'),false)); + +if (count($langs_combo) > 1) { + $items['lang'] = new ArrayObject(array(__('Language'),true)); +} +if (count($categories_combo)) { + $items['category'] = new ArrayObject(array(__('Category'),true)); +} +if (count($months_combo) > 1) { + $items['archive'] = new ArrayObject(array(__('Archive'),true)); +} +if ($core->plugins->moduleExists('pages')) { + if(count($pages_combo)) + $items['pages'] = new ArrayObject(array(__('Page'),true)); +} +if ($core->plugins->moduleExists('tags')) { + if (count($tags_combo) > 1) + $items['tags'] = new ArrayObject(array(__('Tags'),true)); +} + +# --BEHAVIOR-- adminSimpleMenuAddType +# Should add an item to $items[] as an array(