From f3c9e83b0f9223e33c36cf977cdc670c0449afb1 Mon Sep 17 00:00:00 2001 From: fwhite Date: Tue, 25 Aug 2009 12:16:42 +0000 Subject: [PATCH] initial import --- CBLA.txt | 96 + VERSION | 5 + docs/CBLA.txt | 96 + docs/CHANGELOG | 92 + docs/README | 18 + docs/README_WIN32.txt | 17 + docs/installation.html | 132 + docs/requirements.html | 38 + sql/cb_new_install.sql | 2064 ++++++++ sql/upgrade.sql.txt | 26 + upload/.htaccess | 153 + upload/ActualUpload.php | 32 + upload/LICENSE | 96 + upload/aboutus.php | 16 + upload/actions/embed_form_verifier.php | 25 + upload/actions/file_downloader.php | 77 + upload/actions/file_uploader.php | 140 + upload/actions/get_file_size.php | 11 + upload/actions/process_video.php | 28 + upload/actions/update_phrase.php | 20 + upload/actions/video_convert.php | 63 + upload/activation.php | 56 + upload/actual_upload.php | 42 + upload/add_group_videos.php | 62 + upload/admin_area/add_custom_fields.php | 30 + upload/admin_area/add_phrase.php | 30 + upload/admin_area/ads_add_placements.php | 48 + upload/admin_area/ads_manager.php | 91 + upload/admin_area/category.php | 75 + upload/admin_area/edit_announcement.php | 23 + upload/admin_area/edit_group.php | 52 + upload/admin_area/edit_member.php | 47 + upload/admin_area/edit_video.php | 52 + upload/admin_area/editor_pick.php | 52 + upload/admin_area/email_settings.php | 57 + upload/admin_area/ffmpeg_check.php | 22 + upload/admin_area/flagged_videos.php | 113 + upload/admin_area/groups_manager.php | 281 ++ upload/admin_area/index.php | 44 + upload/admin_area/language_settings.php | 75 + upload/admin_area/login.php | 43 + upload/admin_area/logo_change.php | 57 + upload/admin_area/logout.php | 4 + upload/admin_area/main.php | 138 + upload/admin_area/mass_email.php | 57 + upload/admin_area/mass_uploader.php | 136 + upload/admin_area/members.php | 304 ++ upload/admin_area/module_manager.php | 67 + upload/admin_area/phpinfo.php | 12 + upload/admin_area/plugin_manager.php | 78 + .../styles/cbadmin/images/arrow_return.png | Bin 0 -> 3712 bytes .../cbadmin/images/arrow_return_invert.png | Bin 0 -> 3746 bytes .../cbadmin/images/bgs/_notes/dwsync.xml | 11 + .../cbadmin/images/bgs/admin_menu_bg.png | Bin 0 -> 674 bytes .../styles/cbadmin/images/bgs/gr_bg.png | Bin 0 -> 324 bytes .../cbadmin/images/bgs/left_menu_foot.png | Bin 0 -> 340 bytes .../cbadmin/images/bgs/left_menu_head.png | Bin 0 -> 821 bytes .../images/bgs/left_menu_head_selected.png | Bin 0 -> 619 bytes .../styles/cbadmin/images/bgs/login.png | Bin 0 -> 515 bytes .../styles/cbadmin/images/bgs/menu_bg.png | Bin 0 -> 1551 bytes .../cbadmin/images/bgs/pagination_bg.png | Bin 0 -> 238 bytes .../styles/cbadmin/images/bgs/round_bg.png | Bin 0 -> 2261 bytes .../styles/cbadmin/images/button_bg.png | Bin 0 -> 298 bytes .../admin_area/styles/cbadmin/images/dot.gif | Bin 0 -> 43 bytes .../styles/cbadmin/images/login.png | Bin 0 -> 10366 bytes .../admin_area/styles/cbadmin/images/logo.png | Bin 0 -> 6256 bytes .../styles/cbadmin/layout/add_phrase.html | 48 + .../cbadmin/layout/blocks/comments.html | 57 + .../cbadmin/layout/blocks/edit_video.html | 190 + .../cbadmin/layout/blocks/pagination.html | 3 + .../styles/cbadmin/layout/body.html | 28 + .../styles/cbadmin/layout/category.html | 124 + .../styles/cbadmin/layout/edit_video.html | 190 + .../styles/cbadmin/layout/email_settings.html | 151 + .../styles/cbadmin/layout/global_header.html | 71 + .../styles/cbadmin/layout/header.html | 14 + .../styles/cbadmin/layout/index.html | 1 + .../cbadmin/layout/language_settings.html | 80 + .../styles/cbadmin/layout/left_menu.html | 19 + .../styles/cbadmin/layout/login.html | 32 + .../styles/cbadmin/layout/main.html | 391 ++ .../admin_area/styles/cbadmin/layout/msg.html | 32 + .../styles/cbadmin/layout/plugin_manager.html | 69 + .../styles/cbadmin/layout/video_manager.html | 163 + .../cbadmin/layout/view_conversion_log.html | 57 + .../styles/cbadmin/layout/view_video.html | 197 + .../admin_area/styles/cbadmin/theme/cbtab.css | 36 + .../styles/cbadmin/theme/pagination.css | 17 + .../styles/cbadmin/theme/slidemenu.css | 81 + .../styles/cbadmin/theme/stylesheet.css | 116 + .../images/arrow-down-title-on.jpg | Bin 0 -> 1655 bytes .../images/arrow-down-title.jpg | Bin 0 -> 1641 bytes .../images/arrow-up-title-on.jpg | Bin 0 -> 1663 bytes .../clipbucketblue/images/arrow-up-title.jpg | Bin 0 -> 1642 bytes .../styles/clipbucketblue/images/down.png | Bin 0 -> 568 bytes .../clipbucketblue/images/icons/error.png | Bin 0 -> 666 bytes .../clipbucketblue/images/icons/info.png | Bin 0 -> 778 bytes .../images/icons/progIndicator.gif | Bin 0 -> 2209 bytes .../styles/clipbucketblue/images/login.gif | Bin 0 -> 7582 bytes .../styles/clipbucketblue/images/logo.gif | Bin 0 -> 6217 bytes .../styles/clipbucketblue/images/menu_bg.png | Bin 0 -> 576 bytes .../clipbucketblue/images/navbar_bg.png | Bin 0 -> 280 bytes .../clipbucketblue/images/placements.png | Bin 0 -> 6961 bytes .../clipbucketblue/images/powered_by.png | Bin 0 -> 2972 bytes .../clipbucketblue/images/processing-big.png | Bin 0 -> 16482 bytes .../clipbucketblue/images/processing.png | Bin 0 -> 3627 bytes .../clipbucketblue/images/question_mark.png | Bin 0 -> 757 bytes .../styles/clipbucketblue/images/top_bg.jpg | Bin 0 -> 285 bytes .../clipbucketblue/images/top_body_bg.jpg | Bin 0 -> 3857 bytes .../clipbucketblue/images/top_links_bg.png | Bin 0 -> 761 bytes .../styles/clipbucketblue/images/up.png | Bin 0 -> 566 bytes .../layout/add_custom_fields.html | 75 + .../layout/ads_add_placements.html | 73 + .../clipbucketblue/layout/ads_manager.html | 178 + .../layout/blocks/comments.html | 56 + .../clipbucketblue/layout/category.html | 116 + .../layout/edit_announcemnent.html | 13 + .../clipbucketblue/layout/edit_group.html | 136 + .../clipbucketblue/layout/edit_member.html | 126 + .../clipbucketblue/layout/edit_video.html | 180 + .../clipbucketblue/layout/editor_pick.html | 27 + .../clipbucketblue/layout/email_settings.html | 151 + .../clipbucketblue/layout/flagged_videos.html | 66 + .../styles/clipbucketblue/layout/footer.html | 12 + .../clipbucketblue/layout/groups_manager.html | 219 + .../styles/clipbucketblue/layout/header.html | 35 + .../styles/clipbucketblue/layout/index.html | 91 + .../layout/language_settings.html | 23 + .../clipbucketblue/layout/leftmenu.html | 38 + .../styles/clipbucketblue/layout/login.html | 65 + .../clipbucketblue/layout/logo_change.html | 55 + .../styles/clipbucketblue/layout/main.html | 583 +++ .../clipbucketblue/layout/mass_email.html | 100 + .../clipbucketblue/layout/mass_uploader.html | 353 ++ .../styles/clipbucketblue/layout/members.html | 401 ++ .../styles/clipbucketblue/layout/message.html | 32 + .../clipbucketblue/layout/module_manager.html | 78 + .../clipbucketblue/layout/plugin_manager.html | 69 + .../clipbucketblue/layout/super_admin.html | 40 + .../clipbucketblue/layout/templates.html | 77 + .../clipbucketblue/layout/upload_thumbs.html | 30 + .../clipbucketblue/layout/user_levels.html | 104 + .../clipbucketblue/layout/video_manager.html | 229 + .../layout/view_conversion_log.html | 52 + .../clipbucketblue/layout/view_video.html | 186 + .../styles/clipbucketblue/theme/login.css | 14 + .../styles/clipbucketblue/theme/slidemenu.css | 146 + .../clipbucketblue/theme/stylesheet.css | 240 + upload/admin_area/super_admin.php | 32 + upload/admin_area/templates.php | 74 + upload/admin_area/upload_thumbs.php | 69 + upload/admin_area/user_levels.php | 75 + upload/admin_area/vid_check.php | 22 + upload/admin_area/vid_test.php | 30 + upload/admin_area/video_manager.php | 273 ++ upload/admin_area/view_conversion_log.php | 24 + upload/admin_area/view_lang_vars.php | 72 + upload/admin_area/view_video.php | 51 + upload/cUrldownload.php | 170 + upload/captcha.php | 12 + upload/channels.php | 102 + upload/compose.php | 77 + upload/contactus.php | 16 + upload/convert_process.php | 13 + upload/create_group.php | 49 + upload/delete_group.php | 42 + upload/download.php | 52 + upload/edit_group.php | 51 + upload/edit_video.php | 60 + upload/error_pages/403.php | 23 + upload/error_pages/404.php | 15 + upload/favicon.ico | Bin 0 -> 1150 bytes upload/files/.htaccess | 5 + upload/files/thumbs/processing.jpg | Bin 0 -> 4063 bytes upload/forgot.php | 42 + upload/group_check.php | 34 + upload/group_inc.php | 14 + upload/groups.php | 98 + upload/help.php | 16 + upload/images/avatars/no_avatar-small.jpg | Bin 0 -> 852 bytes upload/images/avatars/no_avatar.jpg | Bin 0 -> 2065 bytes upload/images/category_thumbs/no_thumb.jpg | Bin 0 -> 4293 bytes upload/images/groups_thumbs/no_thumb.png | Bin 0 -> 2982 bytes upload/images/icons/XPButton.png | Bin 0 -> 1855 bytes upload/images/icons/cb_powered.gif | Bin 0 -> 2359 bytes upload/images/icons/error.png | Bin 0 -> 666 bytes upload/images/icons/ico_lightsoff.gif | Bin 0 -> 1510 bytes upload/images/icons/info.png | Bin 0 -> 778 bytes upload/images/icons/progIndicator.gif | Bin 0 -> 2209 bytes upload/inactive.php | 15 + upload/inbox.php | 82 + upload/includes/.htaccess | 0 upload/includes/active.php | 73 + upload/includes/admin_config.php | 63 + upload/includes/adminfunctions.php | 14 + .../adodb/adodb-active-record.inc.php | 626 +++ upload/includes/adodb/adodb-csvlib.inc.php | 312 ++ upload/includes/adodb/adodb-datadict.inc.php | 997 ++++ upload/includes/adodb/adodb-error.inc.php | 258 + .../includes/adodb/adodb-errorhandler.inc.php | 79 + upload/includes/adodb/adodb-errorpear.inc.php | 88 + .../includes/adodb/adodb-exceptions.inc.php | 82 + upload/includes/adodb/adodb-iterator.inc.php | 85 + upload/includes/adodb/adodb-lib.inc.php | 1174 +++++ .../includes/adodb/adodb-memcache.lib.inc.php | 118 + upload/includes/adodb/adodb-pager.inc.php | 290 ++ upload/includes/adodb/adodb-pear.inc.php | 374 ++ upload/includes/adodb/adodb-perf.inc.php | 1079 +++++ upload/includes/adodb/adodb-php4.inc.php | 16 + upload/includes/adodb/adodb-time.inc.php | 1409 ++++++ upload/includes/adodb/adodb.inc.php | 4242 +++++++++++++++++ upload/includes/adodb/adodb.php | 7 + .../adodb/drivers/adodb-mysql.inc.php | 849 ++++ upload/includes/adodb/index.php | 3 + upload/includes/adodb/pivottable.inc.php | 187 + upload/includes/adodb/rsfilter.inc.php | 61 + upload/includes/adodb/server.php | 100 + upload/includes/adodb/toexport.inc.php | 133 + upload/includes/adodb/tohtml.inc.php | 195 + upload/includes/adodb/xmlschema.dtd | 39 + upload/includes/adodb/xmlschema03.dtd | 43 + upload/includes/classes/ClipBucket.class.php | 296 ++ upload/includes/classes/ads.class.php | 198 + upload/includes/classes/calcdate.class.php | 28 + .../includes/classes/captcha/class.files.php | 116 + .../classes/captcha/class.img_validator.php | 326 ++ upload/includes/classes/captcha/img.php | 12 + upload/includes/classes/captcha/img/bg1.jpg | Bin 0 -> 3801 bytes upload/includes/classes/captcha/img/bg2.jpg | Bin 0 -> 2558 bytes upload/includes/classes/captcha/img/bg3.jpg | Bin 0 -> 2348 bytes upload/includes/classes/captcha/img/bg4.jpg | Bin 0 -> 2014 bytes .../classes/captcha/img/fonts/arial.ttf | Bin 0 -> 367112 bytes .../classes/captcha/img/fonts/comicbd.ttf | Bin 0 -> 111476 bytes .../classes/captcha/img/fonts/impact.ttf | Bin 0 -> 136076 bytes .../classes/captcha/img/fonts/monofont.ttf | Bin 0 -> 41036 bytes .../classes/captcha/img/fonts/verdana.ttf | Bin 0 -> 171792 bytes upload/includes/classes/captcha/index.php | 3 + .../includes/classes/captcha_simple.img.php | 86 + .../classes/conversion/ffmpeg.class.php | 646 +++ .../classes/conversion/ffmpeg.win32.php | 663 +++ .../classes/conversion/multi.class.php | 542 +++ upload/includes/classes/curl/class.curl.php | 547 +++ .../includes/classes/errorhandler.class.php | 141 + upload/includes/classes/form.class.php | 262 + upload/includes/classes/groups.class.php | 629 +++ upload/includes/classes/image.class.php | 61 + upload/includes/classes/index.php | 3 + upload/includes/classes/lang.class.php | 191 + upload/includes/classes/log.class.php | 65 + upload/includes/classes/mass_upload.class.php | 106 + upload/includes/classes/my_queries.class.php | 1526 ++++++ upload/includes/classes/pages.class.php | 314 ++ upload/includes/classes/plugin.class.php | 307 ++ upload/includes/classes/session.class.php | 131 + upload/includes/classes/signup.class.php | 430 ++ upload/includes/classes/stats.class.php | 459 ++ upload/includes/classes/swfObj.class.php | 97 + upload/includes/classes/sysinfo.class.php | 272 ++ upload/includes/classes/template.class.php | 111 + upload/includes/classes/upload.class.php | 862 ++++ upload/includes/classes/user.class.php | 1434 ++++++ upload/includes/common.php | 407 ++ upload/includes/config.inc.php | 51 + upload/includes/configs/index.php | 3 + upload/includes/conversion.conf.php | 171 + upload/includes/dbconnect.php | 42 + upload/includes/define_php_links.php | 59 + upload/includes/defined_links.php | 117 + .../activation_request.header.php | 5 + .../activation_request.template.php | 14 + .../email_templates/email_verify.header.php | 5 + .../email_templates/email_verify.template.php | 21 + upload/includes/email_templates/index.php | 3 + .../email_templates/share_video.header.php | 5 + .../email_templates/share_video.template.php | 78 + .../email_templates/template_writer.php | 105 + .../welcome_message.header.php | 5 + .../welcome_message.template.php | 17 + .../welcome_messege.header.php | 5 + .../welcome_messege.template.php | 17 + upload/includes/flv_player.php | 59 + upload/includes/functions.php | 1910 ++++++++ upload/includes/index.php | 3 + upload/includes/languages.php | 49 + upload/includes/modules.php | 115 + upload/includes/plugins.php | 42 + upload/includes/plugins_functions.php | 77 + .../templatelib/Config_File.class.php | 389 ++ .../includes/templatelib/Template.class.php | 1944 ++++++++ .../templatelib/Template_Compiler.class.php | 2327 +++++++++ upload/includes/templatelib/debug.tpl | 157 + upload/includes/templatelib/footer.html | 11 + upload/includes/templatelib/header.html | 1 + upload/includes/templatelib/index.php | 3 + .../core.assemble_plugin_filepath.php | 67 + .../core.assign_smarty_interface.php | 43 + .../internals/core.create_dir_structure.php | 79 + .../internals/core.display_debug_console.php | 61 + .../internals/core.get_include_path.php | 44 + .../internals/core.get_microtime.php | 23 + .../internals/core.get_php_resource.php | 80 + .../templatelib/internals/core.is_secure.php | 59 + .../templatelib/internals/core.is_trusted.php | 47 + .../internals/core.load_plugins.php | 125 + .../internals/core.load_resource_plugin.php | 74 + .../internals/core.process_cached_inserts.php | 71 + .../core.process_compiled_include.php | 37 + .../internals/core.read_cache_file.php | 101 + .../templatelib/internals/core.rm_auto.php | 71 + .../templatelib/internals/core.rmdir.php | 54 + .../internals/core.run_insert_handler.php | 71 + .../internals/core.smarty_include_php.php | 50 + .../internals/core.write_cache_file.php | 96 + .../internals/core.write_compiled_include.php | 91 + .../core.write_compiled_resource.php | 35 + .../templatelib/internals/core.write_file.php | 54 + .../templatelib/plugins/block.textformat.php | 103 + .../templatelib/plugins/compiler.assign.php | 46 + .../plugins/function.assign_debug_info.php | 40 + .../plugins/function.config_load.php | 142 + .../templatelib/plugins/function.counter.php | 80 + .../templatelib/plugins/function.cycle.php | 102 + .../templatelib/plugins/function.debug.php | 35 + .../templatelib/plugins/function.eval.php | 49 + .../templatelib/plugins/function.fetch.php | 221 + .../plugins/function.html_checkboxes.php | 143 + .../plugins/function.html_image.php | 142 + .../plugins/function.html_options.php | 122 + .../plugins/function.html_radios.php | 156 + .../plugins/function.html_select_date.php | 331 ++ .../plugins/function.html_select_time.php | 194 + .../plugins/function.html_table.php | 177 + .../templatelib/plugins/function.mailto.php | 165 + .../templatelib/plugins/function.math.php | 84 + .../templatelib/plugins/function.popup.php | 119 + .../plugins/function.popup_init.php | 40 + .../plugins/modifier.capitalize.php | 43 + .../templatelib/plugins/modifier.cat.php | 33 + .../plugins/modifier.count_characters.php | 32 + .../plugins/modifier.count_paragraphs.php | 29 + .../plugins/modifier.count_sentences.php | 29 + .../plugins/modifier.count_words.php | 33 + .../plugins/modifier.date_format.php | 58 + .../plugins/modifier.debug_print_var.php | 90 + .../templatelib/plugins/modifier.default.php | 32 + .../templatelib/plugins/modifier.escape.php | 93 + .../templatelib/plugins/modifier.indent.php | 28 + .../templatelib/plugins/modifier.lower.php | 26 + .../templatelib/plugins/modifier.nl2br.php | 35 + .../plugins/modifier.regex_replace.php | 35 + .../templatelib/plugins/modifier.replace.php | 30 + .../templatelib/plugins/modifier.spacify.php | 30 + .../plugins/modifier.string_format.php | 29 + .../templatelib/plugins/modifier.strip.php | 33 + .../plugins/modifier.strip_tags.php | 32 + .../templatelib/plugins/modifier.truncate.php | 50 + .../templatelib/plugins/modifier.upper.php | 26 + .../templatelib/plugins/modifier.wordwrap.php | 29 + .../plugins/outputfilter.trimwhitespace.php | 75 + .../plugins/shared.escape_special_chars.php | 31 + .../plugins/shared.make_timestamp.php | 46 + upload/includes/upload_forms.php | 34 + upload/index.php | 67 + upload/invite_group.php | 56 + upload/join_group.php | 57 + upload/jquery.tooltip.css | 9 + upload/js/admin_functions.js | 5 + upload/js/ajax.js | 25 + upload/js/ajaxtabs.js | 134 + upload/js/bbcode_js/ed.js | 186 + upload/js/checkall.js | 130 + upload/js/dom-event.js | 142 + upload/js/dropdown.js | 85 + upload/js/dynamic_content.js | 61 + upload/js/embed_video_mod/functions.js | 28 + upload/js/flashobject.js | 141 + upload/js/fullscreen.js | 24 + upload/js/functions.js | 261 + upload/js/jquery.js | 19 + upload/js/jquery_plugs/cb.tabs.js | 31 + upload/js/jquery_plugs/chili-1.7.pack.js | 1 + .../jquery_plugs/compressed/datepicker.js.php | 901 ++++ upload/js/jquery_plugs/compressed/eye.js | 1 + .../jquery_plugs/compressed/hover_intent.js | 1 + .../js/jquery_plugs/compressed/jeditable.js | 37 + upload/js/jquery_plugs/compressed/layout.js | 1 + upload/js/jquery_plugs/compressed/utils.js | 1 + upload/js/jquery_plugs/css/bg.gif | Bin 0 -> 1175 bytes upload/js/jquery_plugs/css/image.png | Bin 0 -> 11172 bytes upload/js/jquery_plugs/css/jquery.tooltip.css | 9 + upload/js/jquery_plugs/css/karte.png | Bin 0 -> 28245 bytes upload/js/jquery_plugs/css/screen.css | 48 + upload/js/jquery_plugs/css/shadow.png | Bin 0 -> 4648 bytes .../js/jquery_plugs/css/shadow2-reverse.png | Bin 0 -> 5025 bytes upload/js/jquery_plugs/css/shadow2.png | Bin 0 -> 5351 bytes upload/js/jquery_plugs/datepicker.js | 891 ++++ upload/js/jquery_plugs/eye.js | 34 + upload/js/jquery_plugs/hover_intent.js | 9 + upload/js/jquery_plugs/jquery.bgiframe.js | 104 + upload/js/jquery_plugs/jquery.delegate.js | 56 + upload/js/jquery_plugs/jquery.dimensions.js | 504 ++ upload/js/jquery_plugs/jquery.tooltip.pack.js | 15 + upload/js/jquery_plugs/layout.js | 49 + upload/js/jquery_plugs/utils.js | 252 + upload/js/light_off/lightsoff.js | 71 + upload/js/lightsoff.js | 71 + upload/js/pagination.js | 106 + upload/js/pagination_02.js | 158 + upload/js/pngfix.js | 39 + upload/js/popup_image.js | 115 + upload/js/rating_update.js | 138 + upload/js/redir.js | 15 + upload/js/slidemenu.js | 442 ++ upload/js/swfobj.js.php | 93 + upload/js/swfupload/plugins/fileprogress.js | 203 + upload/js/swfupload/plugins/handlers.js | 179 + .../js/swfupload/plugins/swfupload.cookies.js | 53 + .../js/swfupload/plugins/swfupload.queue.js | 98 + .../js/swfupload/plugins/swfupload.speed.js | 342 ++ .../swfupload/plugins/swfupload.swfobject.js | 111 + upload/js/swfupload/swfupload.js | 980 ++++ upload/js/swfupload/swfupload.swf | Bin 0 -> 12787 bytes upload/js/swfupload/swfuploadbutton.swf | Bin 0 -> 3056 bytes upload/js/switch_content.js | 211 + upload/lang/en/admin/files.php | 47 + upload/lang/en/admin/template.php | 2 + upload/lang/en/class.php | 61 + upload/lang/en/common.php | 63 + upload/lang/en/global.php | 193 + upload/lang/en/groups/files.php | 52 + upload/lang/en/groups/template.php | 122 + upload/lang/en/lang.php | 48 + upload/lang/en/lang.xml | 6 + upload/lang/en/menu.php | 13 + upload/lang/en/rss_lang.php | 7 + upload/lang/en/sub_titles.php | 48 + upload/lang/en/titles.php | 12 + upload/lang/en/user/files.php | 107 + upload/lang/en/user/template.php | 171 + upload/lang/en/videos/files.php | 26 + upload/lang/en/videos/template.php | 82 + upload/lang_change.php | 50 + upload/leave_group.php | 47 + upload/login_success.php | 41 + upload/logout.php | 5 + upload/logout_success.php | 32 + upload/logs/logs.txt | 0 upload/logs/mylog.txt | 1 + upload/logs/thumblog.txt | 0 upload/manage_contacts.php | 71 + upload/manage_favourites.php | 59 + upload/manage_group_members.php | 121 + upload/manage_group_videos.php | 119 + upload/manage_groups.php | 104 + upload/manage_subscriptions.php | 56 + upload/manage_videos.php | 107 + upload/modules/bookmarks/blinklist.gif | Bin 0 -> 423 bytes upload/modules/bookmarks/delicious.gif | Bin 0 -> 147 bytes upload/modules/bookmarks/digg.gif | Bin 0 -> 303 bytes upload/modules/bookmarks/reddit.gif | Bin 0 -> 1120 bytes upload/modules/bookmarks/stumbleit.gif | Bin 0 -> 1157 bytes upload/modules/bookmarks/technorati.gif | Bin 0 -> 278 bytes .../editors_pick_player.instructions.php | 26 + upload/modules/editors_pick_player.php | 36 + upload/modules/editors_pick_player.swf | Bin 0 -> 29220 bytes upload/modules/encoders/README | 4 + .../flash_recent_videos.instructions.php | 26 + upload/modules/flash_recent_videos.php | 56 + upload/modules/flash_recent_videos.swf | Bin 0 -> 11419 bytes upload/modules/flash_recent_videos_black.swf | Bin 0 -> 11279 bytes upload/modules/lightoff.instructions.php | 27 + upload/modules/lightoff/lightoff.html | 13 + .../modules/recently_viewd_2.instructions.php | 26 + upload/modules/recently_viewd_2.php | 31 + upload/modules/recently_viewd_2.swf | Bin 0 -> 2113 bytes upload/myaccount.php | 35 + upload/opensearch.php | 22 + upload/php.ini | 5 + upload/player/clipbucketblue.swf | Bin 0 -> 55049 bytes upload/player/embed_player.swf | Bin 0 -> 40997 bytes upload/player/logo.png | Bin 0 -> 5904 bytes upload/player/mini_logo.png | Bin 0 -> 4054 bytes upload/player/panel.xml.php | 49 + upload/player/player.conf.php | 61 + upload/player/youtube.swf | Bin 0 -> 25426 bytes upload/player/youtube_glossy.swf | Bin 0 -> 22917 bytes upload/plugins/cb_bbcode.php | 52 + upload/plugins/cb_bbcodes/images/Thumbs.db | Bin 0 -> 14848 bytes upload/plugins/cb_bbcodes/images/bold.gif | Bin 0 -> 567 bytes upload/plugins/cb_bbcodes/images/code.gif | Bin 0 -> 552 bytes upload/plugins/cb_bbcodes/images/italic.gif | Bin 0 -> 305 bytes upload/plugins/cb_bbcodes/images/link.gif | Bin 0 -> 659 bytes upload/plugins/cb_bbcodes/images/ordered.gif | Bin 0 -> 621 bytes upload/plugins/cb_bbcodes/images/picture.gif | Bin 0 -> 700 bytes upload/plugins/cb_bbcodes/images/quote.gif | Bin 0 -> 300 bytes .../plugins/cb_bbcodes/images/underline.gif | Bin 0 -> 347 bytes upload/plugins/cb_bbcodes/images/unlink.gif | Bin 0 -> 640 bytes upload/plugins/cb_bbcodes/styles.css | 22 + upload/plugins/comment_censor.php | 44 + upload/plugins/custom_fields.php | 90 + upload/plugins/date_picker.php | 18 + upload/plugins/date_picker/css/datepicker.css | 191 + .../date_picker/css/datepicker.css.php | 202 + .../css/datepicker_compress.css.php | 10 + upload/plugins/date_picker/header.html | 5 + .../plugins/date_picker/images/custom_b.png | Bin 0 -> 179 bytes .../plugins/date_picker/images/custom_bl.png | Bin 0 -> 213 bytes .../plugins/date_picker/images/custom_br.png | Bin 0 -> 227 bytes .../plugins/date_picker/images/custom_l.png | Bin 0 -> 148 bytes .../plugins/date_picker/images/custom_r.png | Bin 0 -> 165 bytes .../plugins/date_picker/images/custom_t.png | Bin 0 -> 159 bytes .../plugins/date_picker/images/custom_tl.png | Bin 0 -> 165 bytes .../plugins/date_picker/images/custom_tr.png | Bin 0 -> 222 bytes .../date_picker/images/datepicker_b.png | Bin 0 -> 135 bytes .../date_picker/images/datepicker_bl.png | Bin 0 -> 211 bytes .../date_picker/images/datepicker_br.png | Bin 0 -> 208 bytes .../date_picker/images/datepicker_l.png | Bin 0 -> 131 bytes .../date_picker/images/datepicker_r.png | Bin 0 -> 132 bytes .../date_picker/images/datepicker_t.png | Bin 0 -> 140 bytes .../date_picker/images/datepicker_tl.png | Bin 0 -> 209 bytes .../date_picker/images/datepicker_tr.png | Bin 0 -> 240 bytes upload/plugins/date_picker/images/field.png | Bin 0 -> 767 bytes upload/plugins/embed_video_mod.php | 236 + upload/plugins/embed_video_mod/header.html | 1 + upload/plugins/global_announcement.php | 44 + upload/plugins/install_custom_fields.php | 48 + upload/plugins/install_embed_video_mod.php | 18 + .../plugins/install_global_announcement.php | 23 + upload/plugins/jw_player/expressInstall.swf | Bin 0 -> 773 bytes upload/plugins/jw_player/player.swf | Bin 0 -> 51680 bytes upload/plugins/jw_player/yt.swf | Bin 0 -> 1093 bytes upload/plugins/jwplayer.php | 37 + upload/plugins/uninstall_custom_fields.php | 15 + upload/plugins/uninstall_embed_video_mod.php | 14 + .../plugins/uninstall_global_announcement.php | 12 + upload/privacy.php | 16 + upload/rating_process.php | 43 + upload/regen_thumbs.php | 49 + upload/rss.php | 70 + upload/search_result.php | 212 + upload/sent.php | 78 + upload/signup.php | 70 + upload/signup_success.php | 19 + upload/sitemap.php | 56 + upload/style_change.php | 49 + upload/styles/.htaccess | 4 + .../images/CommentThumbDown.jpg | Bin 0 -> 421 bytes .../clipbucketblue/images/CommentThumbpup.jpg | Bin 0 -> 420 bytes .../clipbucketblue/images/account_tabs.png | Bin 0 -> 447 bytes .../images/add_contact_icon.png | Bin 0 -> 421 bytes upload/styles/clipbucketblue/images/alert.png | Bin 0 -> 1252 bytes .../clipbucketblue/images/attachment_icon.png | Bin 0 -> 519 bytes .../images/bg_gradient_f0f0f0-fffff.png | Bin 0 -> 277 bytes .../clipbucketblue/images/bl_view_channel.gif | Bin 0 -> 46 bytes .../clipbucketblue/images/body_background.png | Bin 0 -> 381 bytes .../clipbucketblue/images/br_view_channel.gif | Bin 0 -> 46 bytes .../styles/clipbucketblue/images/bullet.png | Bin 0 -> 398 bytes .../styles/clipbucketblue/images/button.png | Bin 0 -> 1113 bytes .../clipbucketblue/images/cancelbutton.gif | Bin 0 -> 1221 bytes upload/styles/clipbucketblue/images/check.png | Bin 0 -> 985 bytes .../clipbucketblue/images/comments_bg.png | Bin 0 -> 816 bytes .../clipbucketblue/images/composse_icon.png | Bin 0 -> 877 bytes .../images/composse_icon_f0f0f0bg.png | Bin 0 -> 861 bytes .../clipbucketblue/images/crystal_bg01.png | Bin 0 -> 249 bytes .../images/crystal_bg01_over.png | Bin 0 -> 231 bytes .../images/crystal_bg01_round_l.png | Bin 0 -> 340 bytes .../images/crystal_bg01_round_r.png | Bin 0 -> 340 bytes .../clipbucketblue/images/crystal_bg02.png | Bin 0 -> 305 bytes .../images/crystal_bg02_over.png | Bin 0 -> 296 bytes .../images/crystal_bg02_round_l.png | Bin 0 -> 480 bytes .../images/crystal_bg02_round_r.png | Bin 0 -> 485 bytes .../clipbucketblue/images/delete_icon.png | Bin 0 -> 852 bytes upload/styles/clipbucketblue/images/down.png | Bin 0 -> 470 bytes .../clipbucketblue/images/download_ico.png | Bin 0 -> 448 bytes .../images/en/download_button.png | Bin 0 -> 3051 bytes .../images/en/edit_video_button.png | Bin 0 -> 1392 bytes .../clipbucketblue/images/en/editors_pick.png | Bin 0 -> 2615 bytes .../clipbucketblue/images/en/fav_icon.png | Bin 0 -> 786 bytes .../clipbucketblue/images/en/featured.png | Bin 0 -> 2020 bytes .../clipbucketblue/images/en/flag_icon.png | Bin 0 -> 985 bytes .../images/en/processing-big.png | Bin 0 -> 16482 bytes .../clipbucketblue/images/en/processing.png | Bin 0 -> 3627 bytes .../images/en/remove_small_button.png | Bin 0 -> 1645 bytes .../images/en/remove_video_button.png | Bin 0 -> 1342 bytes .../images/en/search_button01.png | Bin 0 -> 688 bytes .../clipbucketblue/images/en/share_icon.png | Bin 0 -> 1045 bytes .../images/en/subscribe_button.png | Bin 0 -> 1429 bytes .../clipbucketblue/images/en/unknown.png | Bin 0 -> 6352 bytes .../images/en/unsubscribe_button.png | Bin 0 -> 1432 bytes .../images/footer_background.png | Bin 0 -> 805 bytes .../clipbucketblue/images/header_links_bg.png | Bin 0 -> 514 bytes .../clipbucketblue/images/inbox_icon.png | Bin 0 -> 907 bytes .../images/inbox_icon_f0f0f0bg.png | Bin 0 -> 885 bytes .../clipbucketblue/images/index_tab_bg.png | Bin 0 -> 1245 bytes .../clipbucketblue/images/index_tab_bg_bg.png | Bin 0 -> 216 bytes .../clipbucketblue/images/left_round.png | Bin 0 -> 210 bytes .../clipbucketblue/images/link_button.png | Bin 0 -> 2283 bytes .../styles/clipbucketblue/images/loading.gif | Bin 0 -> 1542 bytes .../clipbucketblue/images/login_button.gif | Bin 0 -> 367 bytes upload/styles/clipbucketblue/images/logo.gif | Bin 0 -> 5605 bytes .../clipbucketblue/images/logout_button.gif | Bin 0 -> 367 bytes .../clipbucketblue/images/message_b.png | Bin 0 -> 130 bytes .../clipbucketblue/images/message_bl.png | Bin 0 -> 278 bytes .../clipbucketblue/images/message_br.png | Bin 0 -> 279 bytes .../clipbucketblue/images/message_icon.png | Bin 0 -> 759 bytes .../clipbucketblue/images/message_icon_2.png | Bin 0 -> 470 bytes .../clipbucketblue/images/message_l.png | Bin 0 -> 130 bytes .../clipbucketblue/images/message_r.png | Bin 0 -> 130 bytes .../clipbucketblue/images/message_t.png | Bin 0 -> 130 bytes .../clipbucketblue/images/message_tl.png | Bin 0 -> 282 bytes .../clipbucketblue/images/message_tr.png | Bin 0 -> 280 bytes .../clipbucketblue/images/messege_b.png | Bin 0 -> 130 bytes .../clipbucketblue/images/messege_bl.png | Bin 0 -> 278 bytes .../clipbucketblue/images/messege_br.png | Bin 0 -> 279 bytes .../clipbucketblue/images/messege_icon.png | Bin 0 -> 759 bytes .../clipbucketblue/images/messege_icon_2.png | Bin 0 -> 470 bytes .../clipbucketblue/images/messege_l.png | Bin 0 -> 130 bytes .../clipbucketblue/images/messege_r.png | Bin 0 -> 130 bytes .../clipbucketblue/images/messege_t.png | Bin 0 -> 130 bytes .../clipbucketblue/images/messege_tl.png | Bin 0 -> 282 bytes .../clipbucketblue/images/messege_tr.png | Bin 0 -> 280 bytes .../clipbucketblue/images/navbar_bg.png | Bin 0 -> 280 bytes .../clipbucketblue/images/navbar_button.gif | Bin 0 -> 2425 bytes .../images/new_message_icon.png | Bin 0 -> 722 bytes .../images/new_message_icon_2.png | Bin 0 -> 648 bytes .../images/new_messege_icon.png | Bin 0 -> 722 bytes .../images/new_messege_icon_2.png | Bin 0 -> 648 bytes .../clipbucketblue/images/outbox_icon.png | Bin 0 -> 895 bytes .../images/outbox_icon_f0f0f0bg.png | Bin 0 -> 881 bytes .../clipbucketblue/images/play_icon.png | Bin 0 -> 1006 bytes .../clipbucketblue/images/play_icon01.png | Bin 0 -> 972 bytes .../images/progress/progress_bar.png | Bin 0 -> 405 bytes .../images/progress/progress_bg.png | Bin 0 -> 365 bytes .../styles/clipbucketblue/images/quote_1.gif | Bin 0 -> 184 bytes .../styles/clipbucketblue/images/quote_1.png | Bin 0 -> 468 bytes .../styles/clipbucketblue/images/quote_2.gif | Bin 0 -> 138 bytes .../styles/clipbucketblue/images/quote_2.png | Bin 0 -> 468 bytes .../clipbucketblue/images/rating_loading.gif | Bin 0 -> 847 bytes .../clipbucketblue/images/rating_star.gif | Bin 0 -> 1120 bytes .../clipbucketblue/images/rating_star_2.gif | Bin 0 -> 1112 bytes .../clipbucketblue/images/rating_tick.gif | Bin 0 -> 516 bytes .../clipbucketblue/images/right_round.png | Bin 0 -> 204 bytes .../styles/clipbucketblue/images/round01.png | Bin 0 -> 214 bytes .../styles/clipbucketblue/images/round02.png | Bin 0 -> 207 bytes .../clipbucketblue/images/search_bar_bg01.png | Bin 0 -> 664 bytes .../images/send_message_icon.png | Bin 0 -> 414 bytes .../images/send_messege_icon.png | Bin 0 -> 414 bytes .../clipbucketblue/images/seperator.jpg | Bin 0 -> 505 bytes .../clipbucketblue/images/seperator_2.png | Bin 0 -> 1326 bytes .../clipbucketblue/images/seperator_big.jpg | Bin 0 -> 776 bytes .../clipbucketblue/images/small_button.png | Bin 0 -> 719 bytes .../clipbucketblue/images/stock_mail-send.png | Bin 0 -> 895 bytes .../clipbucketblue/images/tab_selected01.png | Bin 0 -> 145 bytes .../images/tab_unselected01.png | Bin 0 -> 138 bytes .../clipbucketblue/images/tabs_bg01.png | Bin 0 -> 287 bytes .../clipbucketblue/images/tabs_bg02.png | Bin 0 -> 252 bytes .../clipbucketblue/images/thumb_bg01.png | Bin 0 -> 386 bytes .../clipbucketblue/images/tl_view_channel.gif | Bin 0 -> 46 bytes .../clipbucketblue/images/tr_view_channel.gif | Bin 0 -> 46 bytes upload/styles/clipbucketblue/images/up.png | Bin 0 -> 427 bytes .../images/upload_button_bg.png | Bin 0 -> 346 bytes .../clipbucketblue/images/uploader_bl.gif | Bin 0 -> 846 bytes .../clipbucketblue/images/uploader_br.gif | Bin 0 -> 107 bytes .../clipbucketblue/images/uploader_tl.gif | Bin 0 -> 109 bytes .../clipbucketblue/images/uploader_tr.gif | Bin 0 -> 109 bytes .../clipbucketblue/images/user_icon.png | Bin 0 -> 854 bytes .../images/video_second_column.png | Bin 0 -> 209 bytes .../clipbucketblue/images/video_title_bg.png | Bin 0 -> 733 bytes upload/styles/clipbucketblue/layout/403.html | 35 + upload/styles/clipbucketblue/layout/404.html | 36 + .../styles/clipbucketblue/layout/aboutus.html | 13 + .../clipbucketblue/layout/activation.html | 102 + .../layout/add_group_videos.html | 42 + .../layout/block/group_common_block.html | 34 + .../layout/block/pm_left_block.html | 41 + .../layout/block/users_block_common.html | 32 + .../layout/block/video_block_common.html | 26 + .../layout/block/video_block_index.html | 29 + .../clipbucketblue/layout/channels.html | 46 + .../styles/clipbucketblue/layout/compose.html | 88 + .../clipbucketblue/layout/contactus.html | 10 + .../clipbucketblue/layout/create_group.html | 117 + .../clipbucketblue/layout/delete_group.html | 24 + .../clipbucketblue/layout/edit_group.html | 133 + .../clipbucketblue/layout/edit_video.html | 114 + .../styles/clipbucketblue/layout/footer.html | 42 + .../styles/clipbucketblue/layout/forgot.html | 121 + .../clipbucketblue/layout/group_header.html | 34 + .../styles/clipbucketblue/layout/groups.html | 52 + .../styles/clipbucketblue/layout/header.html | 310 ++ upload/styles/clipbucketblue/layout/help.html | 16 + .../clipbucketblue/layout/inactive.html | 28 + .../styles/clipbucketblue/layout/inbox.html | 130 + .../styles/clipbucketblue/layout/index.html | 175 + .../clipbucketblue/layout/invite_group.html | 66 + .../clipbucketblue/layout/join_group.html | 23 + .../clipbucketblue/layout/lang_change.html | 36 + .../clipbucketblue/layout/lang_changer.html | 37 + .../clipbucketblue/layout/leave_group.html | 23 + .../clipbucketblue/layout/login_success.html | 11 + .../clipbucketblue/layout/logout_success.html | 12 + .../layout/manage_contacts.html | 56 + .../layout/manage_favourites.html | 40 + .../layout/manage_group_members.html | 78 + .../layout/manage_group_videos.html | 76 + .../clipbucketblue/layout/manage_groups.html | 79 + .../layout/manage_subscriptions.html | 41 + .../clipbucketblue/layout/manage_videos.html | 98 + .../styles/clipbucketblue/layout/message.html | 53 + .../clipbucketblue/layout/myaccount.html | 130 + .../styles/clipbucketblue/layout/privacy.html | 10 + upload/styles/clipbucketblue/layout/rss.html | 64 + .../clipbucketblue/layout/search_box.html | 14 + .../clipbucketblue/layout/search_result.html | 233 + upload/styles/clipbucketblue/layout/sent.html | 118 + .../styles/clipbucketblue/layout/signup.html | 98 + .../clipbucketblue/layout/signup_success.html | 35 + .../styles/clipbucketblue/layout/sitemap.xml | 17 + .../clipbucketblue/layout/style_change.html | 36 + .../styles/clipbucketblue/layout/tabs01.html | 19 + .../styles/clipbucketblue/layout/tabs02.html | 106 + .../styles/clipbucketblue/layout/tabs03.html | 21 + .../clipbucketblue/layout/termsofuse.html | 9 + .../styles/clipbucketblue/layout/upload.html | 181 + .../clipbucketblue/layout/user_account.html | 444 ++ .../clipbucketblue/layout/user_contacts.html | 87 + .../layout/user_fav_videos.html | 78 + .../clipbucketblue/layout/user_videos.html | 65 + .../styles/clipbucketblue/layout/videos.html | 49 + .../layout/videouploadsuccess.html | 33 + .../clipbucketblue/layout/view_channel.html | 304 ++ .../clipbucketblue/layout/view_group.html | 150 + .../layout/view_group_members.html | 75 + .../layout/view_group_videos.html | 53 + .../clipbucketblue/layout/view_topic.html | 65 + .../clipbucketblue/layout/watch_video.html | 353 ++ .../styles/clipbucketblue/theme/ajaxtabs.css | 127 + upload/styles/clipbucketblue/theme/body.css | 216 + .../styles/clipbucketblue/theme/container.css | 554 +++ .../clipbucketblue/theme/date_picker.css | 128 + .../styles/clipbucketblue/theme/drop_down.css | 42 + upload/styles/clipbucketblue/theme/links.css | 304 ++ upload/styles/clipbucketblue/theme/main.css | 18 + .../clipbucketblue/theme/pagination.css | 107 + .../clipbucketblue/theme/rating_style.css | 175 + .../styles/clipbucketblue/theme/ui.tabs.css | 114 + .../styles/clipbucketblue/theme/uploader.css | 128 + .../clipbucketblue/theme/view_channel.css | 224 + upload/tabs01.php | 49 + upload/tabs02.php | 87 + upload/tabs03.php | 76 + upload/termsofuse.php | 16 + upload/upload.php | 61 + upload/user_account.php | 58 + upload/user_contacts.php | 73 + upload/user_fav_videos.php | 76 + upload/user_videos.php | 71 + upload/videos.php | 119 + upload/videouploadsuccess.php | 38 + upload/view_channel.php | 142 + upload/view_group.php | 138 + upload/view_group_members.php | 106 + upload/view_group_videos.php | 109 + upload/view_topic.php | 77 + upload/watch_video.php | 263 + 765 files changed, 71732 insertions(+) create mode 100644 CBLA.txt create mode 100644 VERSION create mode 100644 docs/CBLA.txt create mode 100644 docs/CHANGELOG create mode 100644 docs/README create mode 100644 docs/README_WIN32.txt create mode 100644 docs/installation.html create mode 100644 docs/requirements.html create mode 100644 sql/cb_new_install.sql create mode 100644 sql/upgrade.sql.txt create mode 100644 upload/.htaccess create mode 100644 upload/ActualUpload.php create mode 100644 upload/LICENSE create mode 100644 upload/aboutus.php create mode 100644 upload/actions/embed_form_verifier.php create mode 100644 upload/actions/file_downloader.php create mode 100644 upload/actions/file_uploader.php create mode 100644 upload/actions/get_file_size.php create mode 100644 upload/actions/process_video.php create mode 100644 upload/actions/update_phrase.php create mode 100644 upload/actions/video_convert.php create mode 100644 upload/activation.php create mode 100644 upload/actual_upload.php create mode 100644 upload/add_group_videos.php create mode 100644 upload/admin_area/add_custom_fields.php create mode 100644 upload/admin_area/add_phrase.php create mode 100644 upload/admin_area/ads_add_placements.php create mode 100644 upload/admin_area/ads_manager.php create mode 100644 upload/admin_area/category.php create mode 100644 upload/admin_area/edit_announcement.php create mode 100644 upload/admin_area/edit_group.php create mode 100644 upload/admin_area/edit_member.php create mode 100644 upload/admin_area/edit_video.php create mode 100644 upload/admin_area/editor_pick.php create mode 100644 upload/admin_area/email_settings.php create mode 100644 upload/admin_area/ffmpeg_check.php create mode 100644 upload/admin_area/flagged_videos.php create mode 100644 upload/admin_area/groups_manager.php create mode 100644 upload/admin_area/index.php create mode 100644 upload/admin_area/language_settings.php create mode 100644 upload/admin_area/login.php create mode 100644 upload/admin_area/logo_change.php create mode 100644 upload/admin_area/logout.php create mode 100644 upload/admin_area/main.php create mode 100644 upload/admin_area/mass_email.php create mode 100644 upload/admin_area/mass_uploader.php create mode 100644 upload/admin_area/members.php create mode 100644 upload/admin_area/module_manager.php create mode 100644 upload/admin_area/phpinfo.php create mode 100644 upload/admin_area/plugin_manager.php create mode 100644 upload/admin_area/styles/cbadmin/images/arrow_return.png create mode 100644 upload/admin_area/styles/cbadmin/images/arrow_return_invert.png create mode 100644 upload/admin_area/styles/cbadmin/images/bgs/_notes/dwsync.xml create mode 100644 upload/admin_area/styles/cbadmin/images/bgs/admin_menu_bg.png create mode 100644 upload/admin_area/styles/cbadmin/images/bgs/gr_bg.png create mode 100644 upload/admin_area/styles/cbadmin/images/bgs/left_menu_foot.png create mode 100644 upload/admin_area/styles/cbadmin/images/bgs/left_menu_head.png create mode 100644 upload/admin_area/styles/cbadmin/images/bgs/left_menu_head_selected.png create mode 100644 upload/admin_area/styles/cbadmin/images/bgs/login.png create mode 100644 upload/admin_area/styles/cbadmin/images/bgs/menu_bg.png create mode 100644 upload/admin_area/styles/cbadmin/images/bgs/pagination_bg.png create mode 100644 upload/admin_area/styles/cbadmin/images/bgs/round_bg.png create mode 100644 upload/admin_area/styles/cbadmin/images/button_bg.png create mode 100644 upload/admin_area/styles/cbadmin/images/dot.gif create mode 100644 upload/admin_area/styles/cbadmin/images/login.png create mode 100644 upload/admin_area/styles/cbadmin/images/logo.png create mode 100644 upload/admin_area/styles/cbadmin/layout/add_phrase.html create mode 100644 upload/admin_area/styles/cbadmin/layout/blocks/comments.html create mode 100644 upload/admin_area/styles/cbadmin/layout/blocks/edit_video.html create mode 100644 upload/admin_area/styles/cbadmin/layout/blocks/pagination.html create mode 100644 upload/admin_area/styles/cbadmin/layout/body.html create mode 100644 upload/admin_area/styles/cbadmin/layout/category.html create mode 100644 upload/admin_area/styles/cbadmin/layout/edit_video.html create mode 100644 upload/admin_area/styles/cbadmin/layout/email_settings.html create mode 100644 upload/admin_area/styles/cbadmin/layout/global_header.html create mode 100644 upload/admin_area/styles/cbadmin/layout/header.html create mode 100644 upload/admin_area/styles/cbadmin/layout/index.html create mode 100644 upload/admin_area/styles/cbadmin/layout/language_settings.html create mode 100644 upload/admin_area/styles/cbadmin/layout/left_menu.html create mode 100644 upload/admin_area/styles/cbadmin/layout/login.html create mode 100644 upload/admin_area/styles/cbadmin/layout/main.html create mode 100644 upload/admin_area/styles/cbadmin/layout/msg.html create mode 100644 upload/admin_area/styles/cbadmin/layout/plugin_manager.html create mode 100644 upload/admin_area/styles/cbadmin/layout/video_manager.html create mode 100644 upload/admin_area/styles/cbadmin/layout/view_conversion_log.html create mode 100644 upload/admin_area/styles/cbadmin/layout/view_video.html create mode 100644 upload/admin_area/styles/cbadmin/theme/cbtab.css create mode 100644 upload/admin_area/styles/cbadmin/theme/pagination.css create mode 100644 upload/admin_area/styles/cbadmin/theme/slidemenu.css create mode 100644 upload/admin_area/styles/cbadmin/theme/stylesheet.css create mode 100644 upload/admin_area/styles/clipbucketblue/images/arrow-down-title-on.jpg create mode 100644 upload/admin_area/styles/clipbucketblue/images/arrow-down-title.jpg create mode 100644 upload/admin_area/styles/clipbucketblue/images/arrow-up-title-on.jpg create mode 100644 upload/admin_area/styles/clipbucketblue/images/arrow-up-title.jpg create mode 100644 upload/admin_area/styles/clipbucketblue/images/down.png create mode 100644 upload/admin_area/styles/clipbucketblue/images/icons/error.png create mode 100644 upload/admin_area/styles/clipbucketblue/images/icons/info.png create mode 100644 upload/admin_area/styles/clipbucketblue/images/icons/progIndicator.gif create mode 100644 upload/admin_area/styles/clipbucketblue/images/login.gif create mode 100644 upload/admin_area/styles/clipbucketblue/images/logo.gif create mode 100644 upload/admin_area/styles/clipbucketblue/images/menu_bg.png create mode 100644 upload/admin_area/styles/clipbucketblue/images/navbar_bg.png create mode 100644 upload/admin_area/styles/clipbucketblue/images/placements.png create mode 100644 upload/admin_area/styles/clipbucketblue/images/powered_by.png create mode 100644 upload/admin_area/styles/clipbucketblue/images/processing-big.png create mode 100644 upload/admin_area/styles/clipbucketblue/images/processing.png create mode 100644 upload/admin_area/styles/clipbucketblue/images/question_mark.png create mode 100644 upload/admin_area/styles/clipbucketblue/images/top_bg.jpg create mode 100644 upload/admin_area/styles/clipbucketblue/images/top_body_bg.jpg create mode 100644 upload/admin_area/styles/clipbucketblue/images/top_links_bg.png create mode 100644 upload/admin_area/styles/clipbucketblue/images/up.png create mode 100644 upload/admin_area/styles/clipbucketblue/layout/add_custom_fields.html create mode 100644 upload/admin_area/styles/clipbucketblue/layout/ads_add_placements.html create mode 100644 upload/admin_area/styles/clipbucketblue/layout/ads_manager.html create mode 100644 upload/admin_area/styles/clipbucketblue/layout/blocks/comments.html create mode 100644 upload/admin_area/styles/clipbucketblue/layout/category.html create mode 100644 upload/admin_area/styles/clipbucketblue/layout/edit_announcemnent.html create mode 100644 upload/admin_area/styles/clipbucketblue/layout/edit_group.html create mode 100644 upload/admin_area/styles/clipbucketblue/layout/edit_member.html create mode 100644 upload/admin_area/styles/clipbucketblue/layout/edit_video.html create mode 100644 upload/admin_area/styles/clipbucketblue/layout/editor_pick.html create mode 100644 upload/admin_area/styles/clipbucketblue/layout/email_settings.html create mode 100644 upload/admin_area/styles/clipbucketblue/layout/flagged_videos.html create mode 100644 upload/admin_area/styles/clipbucketblue/layout/footer.html create mode 100644 upload/admin_area/styles/clipbucketblue/layout/groups_manager.html create mode 100644 upload/admin_area/styles/clipbucketblue/layout/header.html create mode 100644 upload/admin_area/styles/clipbucketblue/layout/index.html create mode 100644 upload/admin_area/styles/clipbucketblue/layout/language_settings.html create mode 100644 upload/admin_area/styles/clipbucketblue/layout/leftmenu.html create mode 100644 upload/admin_area/styles/clipbucketblue/layout/login.html create mode 100644 upload/admin_area/styles/clipbucketblue/layout/logo_change.html create mode 100644 upload/admin_area/styles/clipbucketblue/layout/main.html create mode 100644 upload/admin_area/styles/clipbucketblue/layout/mass_email.html create mode 100644 upload/admin_area/styles/clipbucketblue/layout/mass_uploader.html create mode 100644 upload/admin_area/styles/clipbucketblue/layout/members.html create mode 100644 upload/admin_area/styles/clipbucketblue/layout/message.html create mode 100644 upload/admin_area/styles/clipbucketblue/layout/module_manager.html create mode 100644 upload/admin_area/styles/clipbucketblue/layout/plugin_manager.html create mode 100644 upload/admin_area/styles/clipbucketblue/layout/super_admin.html create mode 100644 upload/admin_area/styles/clipbucketblue/layout/templates.html create mode 100644 upload/admin_area/styles/clipbucketblue/layout/upload_thumbs.html create mode 100644 upload/admin_area/styles/clipbucketblue/layout/user_levels.html create mode 100644 upload/admin_area/styles/clipbucketblue/layout/video_manager.html create mode 100644 upload/admin_area/styles/clipbucketblue/layout/view_conversion_log.html create mode 100644 upload/admin_area/styles/clipbucketblue/layout/view_video.html create mode 100644 upload/admin_area/styles/clipbucketblue/theme/login.css create mode 100644 upload/admin_area/styles/clipbucketblue/theme/slidemenu.css create mode 100644 upload/admin_area/styles/clipbucketblue/theme/stylesheet.css create mode 100644 upload/admin_area/super_admin.php create mode 100644 upload/admin_area/templates.php create mode 100644 upload/admin_area/upload_thumbs.php create mode 100644 upload/admin_area/user_levels.php create mode 100644 upload/admin_area/vid_check.php create mode 100644 upload/admin_area/vid_test.php create mode 100644 upload/admin_area/video_manager.php create mode 100644 upload/admin_area/view_conversion_log.php create mode 100644 upload/admin_area/view_lang_vars.php create mode 100644 upload/admin_area/view_video.php create mode 100644 upload/cUrldownload.php create mode 100644 upload/captcha.php create mode 100644 upload/channels.php create mode 100644 upload/compose.php create mode 100644 upload/contactus.php create mode 100644 upload/convert_process.php create mode 100644 upload/create_group.php create mode 100644 upload/delete_group.php create mode 100644 upload/download.php create mode 100644 upload/edit_group.php create mode 100644 upload/edit_video.php create mode 100644 upload/error_pages/403.php create mode 100644 upload/error_pages/404.php create mode 100644 upload/favicon.ico create mode 100644 upload/files/.htaccess create mode 100644 upload/files/thumbs/processing.jpg create mode 100644 upload/forgot.php create mode 100644 upload/group_check.php create mode 100644 upload/group_inc.php create mode 100644 upload/groups.php create mode 100644 upload/help.php create mode 100644 upload/images/avatars/no_avatar-small.jpg create mode 100644 upload/images/avatars/no_avatar.jpg create mode 100644 upload/images/category_thumbs/no_thumb.jpg create mode 100644 upload/images/groups_thumbs/no_thumb.png create mode 100644 upload/images/icons/XPButton.png create mode 100644 upload/images/icons/cb_powered.gif create mode 100644 upload/images/icons/error.png create mode 100644 upload/images/icons/ico_lightsoff.gif create mode 100644 upload/images/icons/info.png create mode 100644 upload/images/icons/progIndicator.gif create mode 100644 upload/inactive.php create mode 100644 upload/inbox.php create mode 100644 upload/includes/.htaccess create mode 100644 upload/includes/active.php create mode 100644 upload/includes/admin_config.php create mode 100644 upload/includes/adminfunctions.php create mode 100644 upload/includes/adodb/adodb-active-record.inc.php create mode 100644 upload/includes/adodb/adodb-csvlib.inc.php create mode 100644 upload/includes/adodb/adodb-datadict.inc.php create mode 100644 upload/includes/adodb/adodb-error.inc.php create mode 100644 upload/includes/adodb/adodb-errorhandler.inc.php create mode 100644 upload/includes/adodb/adodb-errorpear.inc.php create mode 100644 upload/includes/adodb/adodb-exceptions.inc.php create mode 100644 upload/includes/adodb/adodb-iterator.inc.php create mode 100644 upload/includes/adodb/adodb-lib.inc.php create mode 100644 upload/includes/adodb/adodb-memcache.lib.inc.php create mode 100644 upload/includes/adodb/adodb-pager.inc.php create mode 100644 upload/includes/adodb/adodb-pear.inc.php create mode 100644 upload/includes/adodb/adodb-perf.inc.php create mode 100644 upload/includes/adodb/adodb-php4.inc.php create mode 100644 upload/includes/adodb/adodb-time.inc.php create mode 100644 upload/includes/adodb/adodb.inc.php create mode 100644 upload/includes/adodb/adodb.php create mode 100644 upload/includes/adodb/drivers/adodb-mysql.inc.php create mode 100644 upload/includes/adodb/index.php create mode 100644 upload/includes/adodb/pivottable.inc.php create mode 100644 upload/includes/adodb/rsfilter.inc.php create mode 100644 upload/includes/adodb/server.php create mode 100644 upload/includes/adodb/toexport.inc.php create mode 100644 upload/includes/adodb/tohtml.inc.php create mode 100644 upload/includes/adodb/xmlschema.dtd create mode 100644 upload/includes/adodb/xmlschema03.dtd create mode 100644 upload/includes/classes/ClipBucket.class.php create mode 100644 upload/includes/classes/ads.class.php create mode 100644 upload/includes/classes/calcdate.class.php create mode 100644 upload/includes/classes/captcha/class.files.php create mode 100644 upload/includes/classes/captcha/class.img_validator.php create mode 100644 upload/includes/classes/captcha/img.php create mode 100644 upload/includes/classes/captcha/img/bg1.jpg create mode 100644 upload/includes/classes/captcha/img/bg2.jpg create mode 100644 upload/includes/classes/captcha/img/bg3.jpg create mode 100644 upload/includes/classes/captcha/img/bg4.jpg create mode 100644 upload/includes/classes/captcha/img/fonts/arial.ttf create mode 100644 upload/includes/classes/captcha/img/fonts/comicbd.ttf create mode 100644 upload/includes/classes/captcha/img/fonts/impact.ttf create mode 100644 upload/includes/classes/captcha/img/fonts/monofont.ttf create mode 100644 upload/includes/classes/captcha/img/fonts/verdana.ttf create mode 100644 upload/includes/classes/captcha/index.php create mode 100644 upload/includes/classes/captcha_simple.img.php create mode 100644 upload/includes/classes/conversion/ffmpeg.class.php create mode 100644 upload/includes/classes/conversion/ffmpeg.win32.php create mode 100644 upload/includes/classes/conversion/multi.class.php create mode 100644 upload/includes/classes/curl/class.curl.php create mode 100644 upload/includes/classes/errorhandler.class.php create mode 100644 upload/includes/classes/form.class.php create mode 100644 upload/includes/classes/groups.class.php create mode 100644 upload/includes/classes/image.class.php create mode 100644 upload/includes/classes/index.php create mode 100644 upload/includes/classes/lang.class.php create mode 100644 upload/includes/classes/log.class.php create mode 100644 upload/includes/classes/mass_upload.class.php create mode 100644 upload/includes/classes/my_queries.class.php create mode 100644 upload/includes/classes/pages.class.php create mode 100644 upload/includes/classes/plugin.class.php create mode 100644 upload/includes/classes/session.class.php create mode 100644 upload/includes/classes/signup.class.php create mode 100644 upload/includes/classes/stats.class.php create mode 100644 upload/includes/classes/swfObj.class.php create mode 100644 upload/includes/classes/sysinfo.class.php create mode 100644 upload/includes/classes/template.class.php create mode 100644 upload/includes/classes/upload.class.php create mode 100644 upload/includes/classes/user.class.php create mode 100644 upload/includes/common.php create mode 100644 upload/includes/config.inc.php create mode 100644 upload/includes/configs/index.php create mode 100644 upload/includes/conversion.conf.php create mode 100644 upload/includes/dbconnect.php create mode 100644 upload/includes/define_php_links.php create mode 100644 upload/includes/defined_links.php create mode 100644 upload/includes/email_templates/activation_request.header.php create mode 100644 upload/includes/email_templates/activation_request.template.php create mode 100644 upload/includes/email_templates/email_verify.header.php create mode 100644 upload/includes/email_templates/email_verify.template.php create mode 100644 upload/includes/email_templates/index.php create mode 100644 upload/includes/email_templates/share_video.header.php create mode 100644 upload/includes/email_templates/share_video.template.php create mode 100644 upload/includes/email_templates/template_writer.php create mode 100644 upload/includes/email_templates/welcome_message.header.php create mode 100644 upload/includes/email_templates/welcome_message.template.php create mode 100644 upload/includes/email_templates/welcome_messege.header.php create mode 100644 upload/includes/email_templates/welcome_messege.template.php create mode 100644 upload/includes/flv_player.php create mode 100644 upload/includes/functions.php create mode 100644 upload/includes/index.php create mode 100644 upload/includes/languages.php create mode 100644 upload/includes/modules.php create mode 100644 upload/includes/plugins.php create mode 100644 upload/includes/plugins_functions.php create mode 100644 upload/includes/templatelib/Config_File.class.php create mode 100644 upload/includes/templatelib/Template.class.php create mode 100644 upload/includes/templatelib/Template_Compiler.class.php create mode 100644 upload/includes/templatelib/debug.tpl create mode 100644 upload/includes/templatelib/footer.html create mode 100644 upload/includes/templatelib/header.html create mode 100644 upload/includes/templatelib/index.php create mode 100644 upload/includes/templatelib/internals/core.assemble_plugin_filepath.php create mode 100644 upload/includes/templatelib/internals/core.assign_smarty_interface.php create mode 100644 upload/includes/templatelib/internals/core.create_dir_structure.php create mode 100644 upload/includes/templatelib/internals/core.display_debug_console.php create mode 100644 upload/includes/templatelib/internals/core.get_include_path.php create mode 100644 upload/includes/templatelib/internals/core.get_microtime.php create mode 100644 upload/includes/templatelib/internals/core.get_php_resource.php create mode 100644 upload/includes/templatelib/internals/core.is_secure.php create mode 100644 upload/includes/templatelib/internals/core.is_trusted.php create mode 100644 upload/includes/templatelib/internals/core.load_plugins.php create mode 100644 upload/includes/templatelib/internals/core.load_resource_plugin.php create mode 100644 upload/includes/templatelib/internals/core.process_cached_inserts.php create mode 100644 upload/includes/templatelib/internals/core.process_compiled_include.php create mode 100644 upload/includes/templatelib/internals/core.read_cache_file.php create mode 100644 upload/includes/templatelib/internals/core.rm_auto.php create mode 100644 upload/includes/templatelib/internals/core.rmdir.php create mode 100644 upload/includes/templatelib/internals/core.run_insert_handler.php create mode 100644 upload/includes/templatelib/internals/core.smarty_include_php.php create mode 100644 upload/includes/templatelib/internals/core.write_cache_file.php create mode 100644 upload/includes/templatelib/internals/core.write_compiled_include.php create mode 100644 upload/includes/templatelib/internals/core.write_compiled_resource.php create mode 100644 upload/includes/templatelib/internals/core.write_file.php create mode 100644 upload/includes/templatelib/plugins/block.textformat.php create mode 100644 upload/includes/templatelib/plugins/compiler.assign.php create mode 100644 upload/includes/templatelib/plugins/function.assign_debug_info.php create mode 100644 upload/includes/templatelib/plugins/function.config_load.php create mode 100644 upload/includes/templatelib/plugins/function.counter.php create mode 100644 upload/includes/templatelib/plugins/function.cycle.php create mode 100644 upload/includes/templatelib/plugins/function.debug.php create mode 100644 upload/includes/templatelib/plugins/function.eval.php create mode 100644 upload/includes/templatelib/plugins/function.fetch.php create mode 100644 upload/includes/templatelib/plugins/function.html_checkboxes.php create mode 100644 upload/includes/templatelib/plugins/function.html_image.php create mode 100644 upload/includes/templatelib/plugins/function.html_options.php create mode 100644 upload/includes/templatelib/plugins/function.html_radios.php create mode 100644 upload/includes/templatelib/plugins/function.html_select_date.php create mode 100644 upload/includes/templatelib/plugins/function.html_select_time.php create mode 100644 upload/includes/templatelib/plugins/function.html_table.php create mode 100644 upload/includes/templatelib/plugins/function.mailto.php create mode 100644 upload/includes/templatelib/plugins/function.math.php create mode 100644 upload/includes/templatelib/plugins/function.popup.php create mode 100644 upload/includes/templatelib/plugins/function.popup_init.php create mode 100644 upload/includes/templatelib/plugins/modifier.capitalize.php create mode 100644 upload/includes/templatelib/plugins/modifier.cat.php create mode 100644 upload/includes/templatelib/plugins/modifier.count_characters.php create mode 100644 upload/includes/templatelib/plugins/modifier.count_paragraphs.php create mode 100644 upload/includes/templatelib/plugins/modifier.count_sentences.php create mode 100644 upload/includes/templatelib/plugins/modifier.count_words.php create mode 100644 upload/includes/templatelib/plugins/modifier.date_format.php create mode 100644 upload/includes/templatelib/plugins/modifier.debug_print_var.php create mode 100644 upload/includes/templatelib/plugins/modifier.default.php create mode 100644 upload/includes/templatelib/plugins/modifier.escape.php create mode 100644 upload/includes/templatelib/plugins/modifier.indent.php create mode 100644 upload/includes/templatelib/plugins/modifier.lower.php create mode 100644 upload/includes/templatelib/plugins/modifier.nl2br.php create mode 100644 upload/includes/templatelib/plugins/modifier.regex_replace.php create mode 100644 upload/includes/templatelib/plugins/modifier.replace.php create mode 100644 upload/includes/templatelib/plugins/modifier.spacify.php create mode 100644 upload/includes/templatelib/plugins/modifier.string_format.php create mode 100644 upload/includes/templatelib/plugins/modifier.strip.php create mode 100644 upload/includes/templatelib/plugins/modifier.strip_tags.php create mode 100644 upload/includes/templatelib/plugins/modifier.truncate.php create mode 100644 upload/includes/templatelib/plugins/modifier.upper.php create mode 100644 upload/includes/templatelib/plugins/modifier.wordwrap.php create mode 100644 upload/includes/templatelib/plugins/outputfilter.trimwhitespace.php create mode 100644 upload/includes/templatelib/plugins/shared.escape_special_chars.php create mode 100644 upload/includes/templatelib/plugins/shared.make_timestamp.php create mode 100644 upload/includes/upload_forms.php create mode 100644 upload/index.php create mode 100644 upload/invite_group.php create mode 100644 upload/join_group.php create mode 100644 upload/jquery.tooltip.css create mode 100644 upload/js/admin_functions.js create mode 100644 upload/js/ajax.js create mode 100644 upload/js/ajaxtabs.js create mode 100644 upload/js/bbcode_js/ed.js create mode 100644 upload/js/checkall.js create mode 100644 upload/js/dom-event.js create mode 100644 upload/js/dropdown.js create mode 100644 upload/js/dynamic_content.js create mode 100644 upload/js/embed_video_mod/functions.js create mode 100644 upload/js/flashobject.js create mode 100644 upload/js/fullscreen.js create mode 100644 upload/js/functions.js create mode 100644 upload/js/jquery.js create mode 100644 upload/js/jquery_plugs/cb.tabs.js create mode 100644 upload/js/jquery_plugs/chili-1.7.pack.js create mode 100644 upload/js/jquery_plugs/compressed/datepicker.js.php create mode 100644 upload/js/jquery_plugs/compressed/eye.js create mode 100644 upload/js/jquery_plugs/compressed/hover_intent.js create mode 100644 upload/js/jquery_plugs/compressed/jeditable.js create mode 100644 upload/js/jquery_plugs/compressed/layout.js create mode 100644 upload/js/jquery_plugs/compressed/utils.js create mode 100644 upload/js/jquery_plugs/css/bg.gif create mode 100644 upload/js/jquery_plugs/css/image.png create mode 100644 upload/js/jquery_plugs/css/jquery.tooltip.css create mode 100644 upload/js/jquery_plugs/css/karte.png create mode 100644 upload/js/jquery_plugs/css/screen.css create mode 100644 upload/js/jquery_plugs/css/shadow.png create mode 100644 upload/js/jquery_plugs/css/shadow2-reverse.png create mode 100644 upload/js/jquery_plugs/css/shadow2.png create mode 100644 upload/js/jquery_plugs/datepicker.js create mode 100644 upload/js/jquery_plugs/eye.js create mode 100644 upload/js/jquery_plugs/hover_intent.js create mode 100644 upload/js/jquery_plugs/jquery.bgiframe.js create mode 100644 upload/js/jquery_plugs/jquery.delegate.js create mode 100644 upload/js/jquery_plugs/jquery.dimensions.js create mode 100644 upload/js/jquery_plugs/jquery.tooltip.pack.js create mode 100644 upload/js/jquery_plugs/layout.js create mode 100644 upload/js/jquery_plugs/utils.js create mode 100644 upload/js/light_off/lightsoff.js create mode 100644 upload/js/lightsoff.js create mode 100644 upload/js/pagination.js create mode 100644 upload/js/pagination_02.js create mode 100644 upload/js/pngfix.js create mode 100644 upload/js/popup_image.js create mode 100644 upload/js/rating_update.js create mode 100644 upload/js/redir.js create mode 100644 upload/js/slidemenu.js create mode 100644 upload/js/swfobj.js.php create mode 100644 upload/js/swfupload/plugins/fileprogress.js create mode 100644 upload/js/swfupload/plugins/handlers.js create mode 100644 upload/js/swfupload/plugins/swfupload.cookies.js create mode 100644 upload/js/swfupload/plugins/swfupload.queue.js create mode 100644 upload/js/swfupload/plugins/swfupload.speed.js create mode 100644 upload/js/swfupload/plugins/swfupload.swfobject.js create mode 100644 upload/js/swfupload/swfupload.js create mode 100644 upload/js/swfupload/swfupload.swf create mode 100644 upload/js/swfupload/swfuploadbutton.swf create mode 100644 upload/js/switch_content.js create mode 100644 upload/lang/en/admin/files.php create mode 100644 upload/lang/en/admin/template.php create mode 100644 upload/lang/en/class.php create mode 100644 upload/lang/en/common.php create mode 100644 upload/lang/en/global.php create mode 100644 upload/lang/en/groups/files.php create mode 100644 upload/lang/en/groups/template.php create mode 100644 upload/lang/en/lang.php create mode 100644 upload/lang/en/lang.xml create mode 100644 upload/lang/en/menu.php create mode 100644 upload/lang/en/rss_lang.php create mode 100644 upload/lang/en/sub_titles.php create mode 100644 upload/lang/en/titles.php create mode 100644 upload/lang/en/user/files.php create mode 100644 upload/lang/en/user/template.php create mode 100644 upload/lang/en/videos/files.php create mode 100644 upload/lang/en/videos/template.php create mode 100644 upload/lang_change.php create mode 100644 upload/leave_group.php create mode 100644 upload/login_success.php create mode 100644 upload/logout.php create mode 100644 upload/logout_success.php create mode 100644 upload/logs/logs.txt create mode 100644 upload/logs/mylog.txt create mode 100644 upload/logs/thumblog.txt create mode 100644 upload/manage_contacts.php create mode 100644 upload/manage_favourites.php create mode 100644 upload/manage_group_members.php create mode 100644 upload/manage_group_videos.php create mode 100644 upload/manage_groups.php create mode 100644 upload/manage_subscriptions.php create mode 100644 upload/manage_videos.php create mode 100644 upload/modules/bookmarks/blinklist.gif create mode 100644 upload/modules/bookmarks/delicious.gif create mode 100644 upload/modules/bookmarks/digg.gif create mode 100644 upload/modules/bookmarks/reddit.gif create mode 100644 upload/modules/bookmarks/stumbleit.gif create mode 100644 upload/modules/bookmarks/technorati.gif create mode 100644 upload/modules/editors_pick_player.instructions.php create mode 100644 upload/modules/editors_pick_player.php create mode 100644 upload/modules/editors_pick_player.swf create mode 100644 upload/modules/encoders/README create mode 100644 upload/modules/flash_recent_videos.instructions.php create mode 100644 upload/modules/flash_recent_videos.php create mode 100644 upload/modules/flash_recent_videos.swf create mode 100644 upload/modules/flash_recent_videos_black.swf create mode 100644 upload/modules/lightoff.instructions.php create mode 100644 upload/modules/lightoff/lightoff.html create mode 100644 upload/modules/recently_viewd_2.instructions.php create mode 100644 upload/modules/recently_viewd_2.php create mode 100644 upload/modules/recently_viewd_2.swf create mode 100644 upload/myaccount.php create mode 100644 upload/opensearch.php create mode 100644 upload/php.ini create mode 100644 upload/player/clipbucketblue.swf create mode 100644 upload/player/embed_player.swf create mode 100644 upload/player/logo.png create mode 100644 upload/player/mini_logo.png create mode 100644 upload/player/panel.xml.php create mode 100644 upload/player/player.conf.php create mode 100644 upload/player/youtube.swf create mode 100644 upload/player/youtube_glossy.swf create mode 100644 upload/plugins/cb_bbcode.php create mode 100644 upload/plugins/cb_bbcodes/images/Thumbs.db create mode 100644 upload/plugins/cb_bbcodes/images/bold.gif create mode 100644 upload/plugins/cb_bbcodes/images/code.gif create mode 100644 upload/plugins/cb_bbcodes/images/italic.gif create mode 100644 upload/plugins/cb_bbcodes/images/link.gif create mode 100644 upload/plugins/cb_bbcodes/images/ordered.gif create mode 100644 upload/plugins/cb_bbcodes/images/picture.gif create mode 100644 upload/plugins/cb_bbcodes/images/quote.gif create mode 100644 upload/plugins/cb_bbcodes/images/underline.gif create mode 100644 upload/plugins/cb_bbcodes/images/unlink.gif create mode 100644 upload/plugins/cb_bbcodes/styles.css create mode 100644 upload/plugins/comment_censor.php create mode 100644 upload/plugins/custom_fields.php create mode 100644 upload/plugins/date_picker.php create mode 100644 upload/plugins/date_picker/css/datepicker.css create mode 100644 upload/plugins/date_picker/css/datepicker.css.php create mode 100644 upload/plugins/date_picker/css/datepicker_compress.css.php create mode 100644 upload/plugins/date_picker/header.html create mode 100644 upload/plugins/date_picker/images/custom_b.png create mode 100644 upload/plugins/date_picker/images/custom_bl.png create mode 100644 upload/plugins/date_picker/images/custom_br.png create mode 100644 upload/plugins/date_picker/images/custom_l.png create mode 100644 upload/plugins/date_picker/images/custom_r.png create mode 100644 upload/plugins/date_picker/images/custom_t.png create mode 100644 upload/plugins/date_picker/images/custom_tl.png create mode 100644 upload/plugins/date_picker/images/custom_tr.png create mode 100644 upload/plugins/date_picker/images/datepicker_b.png create mode 100644 upload/plugins/date_picker/images/datepicker_bl.png create mode 100644 upload/plugins/date_picker/images/datepicker_br.png create mode 100644 upload/plugins/date_picker/images/datepicker_l.png create mode 100644 upload/plugins/date_picker/images/datepicker_r.png create mode 100644 upload/plugins/date_picker/images/datepicker_t.png create mode 100644 upload/plugins/date_picker/images/datepicker_tl.png create mode 100644 upload/plugins/date_picker/images/datepicker_tr.png create mode 100644 upload/plugins/date_picker/images/field.png create mode 100644 upload/plugins/embed_video_mod.php create mode 100644 upload/plugins/embed_video_mod/header.html create mode 100644 upload/plugins/global_announcement.php create mode 100644 upload/plugins/install_custom_fields.php create mode 100644 upload/plugins/install_embed_video_mod.php create mode 100644 upload/plugins/install_global_announcement.php create mode 100644 upload/plugins/jw_player/expressInstall.swf create mode 100644 upload/plugins/jw_player/player.swf create mode 100644 upload/plugins/jw_player/yt.swf create mode 100644 upload/plugins/jwplayer.php create mode 100644 upload/plugins/uninstall_custom_fields.php create mode 100644 upload/plugins/uninstall_embed_video_mod.php create mode 100644 upload/plugins/uninstall_global_announcement.php create mode 100644 upload/privacy.php create mode 100644 upload/rating_process.php create mode 100644 upload/regen_thumbs.php create mode 100644 upload/rss.php create mode 100644 upload/search_result.php create mode 100644 upload/sent.php create mode 100644 upload/signup.php create mode 100644 upload/signup_success.php create mode 100644 upload/sitemap.php create mode 100644 upload/style_change.php create mode 100644 upload/styles/.htaccess create mode 100644 upload/styles/clipbucketblue/images/CommentThumbDown.jpg create mode 100644 upload/styles/clipbucketblue/images/CommentThumbpup.jpg create mode 100644 upload/styles/clipbucketblue/images/account_tabs.png create mode 100644 upload/styles/clipbucketblue/images/add_contact_icon.png create mode 100644 upload/styles/clipbucketblue/images/alert.png create mode 100644 upload/styles/clipbucketblue/images/attachment_icon.png create mode 100644 upload/styles/clipbucketblue/images/bg_gradient_f0f0f0-fffff.png create mode 100644 upload/styles/clipbucketblue/images/bl_view_channel.gif create mode 100644 upload/styles/clipbucketblue/images/body_background.png create mode 100644 upload/styles/clipbucketblue/images/br_view_channel.gif create mode 100644 upload/styles/clipbucketblue/images/bullet.png create mode 100644 upload/styles/clipbucketblue/images/button.png create mode 100644 upload/styles/clipbucketblue/images/cancelbutton.gif create mode 100644 upload/styles/clipbucketblue/images/check.png create mode 100644 upload/styles/clipbucketblue/images/comments_bg.png create mode 100644 upload/styles/clipbucketblue/images/composse_icon.png create mode 100644 upload/styles/clipbucketblue/images/composse_icon_f0f0f0bg.png create mode 100644 upload/styles/clipbucketblue/images/crystal_bg01.png create mode 100644 upload/styles/clipbucketblue/images/crystal_bg01_over.png create mode 100644 upload/styles/clipbucketblue/images/crystal_bg01_round_l.png create mode 100644 upload/styles/clipbucketblue/images/crystal_bg01_round_r.png create mode 100644 upload/styles/clipbucketblue/images/crystal_bg02.png create mode 100644 upload/styles/clipbucketblue/images/crystal_bg02_over.png create mode 100644 upload/styles/clipbucketblue/images/crystal_bg02_round_l.png create mode 100644 upload/styles/clipbucketblue/images/crystal_bg02_round_r.png create mode 100644 upload/styles/clipbucketblue/images/delete_icon.png create mode 100644 upload/styles/clipbucketblue/images/down.png create mode 100644 upload/styles/clipbucketblue/images/download_ico.png create mode 100644 upload/styles/clipbucketblue/images/en/download_button.png create mode 100644 upload/styles/clipbucketblue/images/en/edit_video_button.png create mode 100644 upload/styles/clipbucketblue/images/en/editors_pick.png create mode 100644 upload/styles/clipbucketblue/images/en/fav_icon.png create mode 100644 upload/styles/clipbucketblue/images/en/featured.png create mode 100644 upload/styles/clipbucketblue/images/en/flag_icon.png create mode 100644 upload/styles/clipbucketblue/images/en/processing-big.png create mode 100644 upload/styles/clipbucketblue/images/en/processing.png create mode 100644 upload/styles/clipbucketblue/images/en/remove_small_button.png create mode 100644 upload/styles/clipbucketblue/images/en/remove_video_button.png create mode 100644 upload/styles/clipbucketblue/images/en/search_button01.png create mode 100644 upload/styles/clipbucketblue/images/en/share_icon.png create mode 100644 upload/styles/clipbucketblue/images/en/subscribe_button.png create mode 100644 upload/styles/clipbucketblue/images/en/unknown.png create mode 100644 upload/styles/clipbucketblue/images/en/unsubscribe_button.png create mode 100644 upload/styles/clipbucketblue/images/footer_background.png create mode 100644 upload/styles/clipbucketblue/images/header_links_bg.png create mode 100644 upload/styles/clipbucketblue/images/inbox_icon.png create mode 100644 upload/styles/clipbucketblue/images/inbox_icon_f0f0f0bg.png create mode 100644 upload/styles/clipbucketblue/images/index_tab_bg.png create mode 100644 upload/styles/clipbucketblue/images/index_tab_bg_bg.png create mode 100644 upload/styles/clipbucketblue/images/left_round.png create mode 100644 upload/styles/clipbucketblue/images/link_button.png create mode 100644 upload/styles/clipbucketblue/images/loading.gif create mode 100644 upload/styles/clipbucketblue/images/login_button.gif create mode 100644 upload/styles/clipbucketblue/images/logo.gif create mode 100644 upload/styles/clipbucketblue/images/logout_button.gif create mode 100644 upload/styles/clipbucketblue/images/message_b.png create mode 100644 upload/styles/clipbucketblue/images/message_bl.png create mode 100644 upload/styles/clipbucketblue/images/message_br.png create mode 100644 upload/styles/clipbucketblue/images/message_icon.png create mode 100644 upload/styles/clipbucketblue/images/message_icon_2.png create mode 100644 upload/styles/clipbucketblue/images/message_l.png create mode 100644 upload/styles/clipbucketblue/images/message_r.png create mode 100644 upload/styles/clipbucketblue/images/message_t.png create mode 100644 upload/styles/clipbucketblue/images/message_tl.png create mode 100644 upload/styles/clipbucketblue/images/message_tr.png create mode 100644 upload/styles/clipbucketblue/images/messege_b.png create mode 100644 upload/styles/clipbucketblue/images/messege_bl.png create mode 100644 upload/styles/clipbucketblue/images/messege_br.png create mode 100644 upload/styles/clipbucketblue/images/messege_icon.png create mode 100644 upload/styles/clipbucketblue/images/messege_icon_2.png create mode 100644 upload/styles/clipbucketblue/images/messege_l.png create mode 100644 upload/styles/clipbucketblue/images/messege_r.png create mode 100644 upload/styles/clipbucketblue/images/messege_t.png create mode 100644 upload/styles/clipbucketblue/images/messege_tl.png create mode 100644 upload/styles/clipbucketblue/images/messege_tr.png create mode 100644 upload/styles/clipbucketblue/images/navbar_bg.png create mode 100644 upload/styles/clipbucketblue/images/navbar_button.gif create mode 100644 upload/styles/clipbucketblue/images/new_message_icon.png create mode 100644 upload/styles/clipbucketblue/images/new_message_icon_2.png create mode 100644 upload/styles/clipbucketblue/images/new_messege_icon.png create mode 100644 upload/styles/clipbucketblue/images/new_messege_icon_2.png create mode 100644 upload/styles/clipbucketblue/images/outbox_icon.png create mode 100644 upload/styles/clipbucketblue/images/outbox_icon_f0f0f0bg.png create mode 100644 upload/styles/clipbucketblue/images/play_icon.png create mode 100644 upload/styles/clipbucketblue/images/play_icon01.png create mode 100644 upload/styles/clipbucketblue/images/progress/progress_bar.png create mode 100644 upload/styles/clipbucketblue/images/progress/progress_bg.png create mode 100644 upload/styles/clipbucketblue/images/quote_1.gif create mode 100644 upload/styles/clipbucketblue/images/quote_1.png create mode 100644 upload/styles/clipbucketblue/images/quote_2.gif create mode 100644 upload/styles/clipbucketblue/images/quote_2.png create mode 100644 upload/styles/clipbucketblue/images/rating_loading.gif create mode 100644 upload/styles/clipbucketblue/images/rating_star.gif create mode 100644 upload/styles/clipbucketblue/images/rating_star_2.gif create mode 100644 upload/styles/clipbucketblue/images/rating_tick.gif create mode 100644 upload/styles/clipbucketblue/images/right_round.png create mode 100644 upload/styles/clipbucketblue/images/round01.png create mode 100644 upload/styles/clipbucketblue/images/round02.png create mode 100644 upload/styles/clipbucketblue/images/search_bar_bg01.png create mode 100644 upload/styles/clipbucketblue/images/send_message_icon.png create mode 100644 upload/styles/clipbucketblue/images/send_messege_icon.png create mode 100644 upload/styles/clipbucketblue/images/seperator.jpg create mode 100644 upload/styles/clipbucketblue/images/seperator_2.png create mode 100644 upload/styles/clipbucketblue/images/seperator_big.jpg create mode 100644 upload/styles/clipbucketblue/images/small_button.png create mode 100644 upload/styles/clipbucketblue/images/stock_mail-send.png create mode 100644 upload/styles/clipbucketblue/images/tab_selected01.png create mode 100644 upload/styles/clipbucketblue/images/tab_unselected01.png create mode 100644 upload/styles/clipbucketblue/images/tabs_bg01.png create mode 100644 upload/styles/clipbucketblue/images/tabs_bg02.png create mode 100644 upload/styles/clipbucketblue/images/thumb_bg01.png create mode 100644 upload/styles/clipbucketblue/images/tl_view_channel.gif create mode 100644 upload/styles/clipbucketblue/images/tr_view_channel.gif create mode 100644 upload/styles/clipbucketblue/images/up.png create mode 100644 upload/styles/clipbucketblue/images/upload_button_bg.png create mode 100644 upload/styles/clipbucketblue/images/uploader_bl.gif create mode 100644 upload/styles/clipbucketblue/images/uploader_br.gif create mode 100644 upload/styles/clipbucketblue/images/uploader_tl.gif create mode 100644 upload/styles/clipbucketblue/images/uploader_tr.gif create mode 100644 upload/styles/clipbucketblue/images/user_icon.png create mode 100644 upload/styles/clipbucketblue/images/video_second_column.png create mode 100644 upload/styles/clipbucketblue/images/video_title_bg.png create mode 100644 upload/styles/clipbucketblue/layout/403.html create mode 100644 upload/styles/clipbucketblue/layout/404.html create mode 100644 upload/styles/clipbucketblue/layout/aboutus.html create mode 100644 upload/styles/clipbucketblue/layout/activation.html create mode 100644 upload/styles/clipbucketblue/layout/add_group_videos.html create mode 100644 upload/styles/clipbucketblue/layout/block/group_common_block.html create mode 100644 upload/styles/clipbucketblue/layout/block/pm_left_block.html create mode 100644 upload/styles/clipbucketblue/layout/block/users_block_common.html create mode 100644 upload/styles/clipbucketblue/layout/block/video_block_common.html create mode 100644 upload/styles/clipbucketblue/layout/block/video_block_index.html create mode 100644 upload/styles/clipbucketblue/layout/channels.html create mode 100644 upload/styles/clipbucketblue/layout/compose.html create mode 100644 upload/styles/clipbucketblue/layout/contactus.html create mode 100644 upload/styles/clipbucketblue/layout/create_group.html create mode 100644 upload/styles/clipbucketblue/layout/delete_group.html create mode 100644 upload/styles/clipbucketblue/layout/edit_group.html create mode 100644 upload/styles/clipbucketblue/layout/edit_video.html create mode 100644 upload/styles/clipbucketblue/layout/footer.html create mode 100644 upload/styles/clipbucketblue/layout/forgot.html create mode 100644 upload/styles/clipbucketblue/layout/group_header.html create mode 100644 upload/styles/clipbucketblue/layout/groups.html create mode 100644 upload/styles/clipbucketblue/layout/header.html create mode 100644 upload/styles/clipbucketblue/layout/help.html create mode 100644 upload/styles/clipbucketblue/layout/inactive.html create mode 100644 upload/styles/clipbucketblue/layout/inbox.html create mode 100644 upload/styles/clipbucketblue/layout/index.html create mode 100644 upload/styles/clipbucketblue/layout/invite_group.html create mode 100644 upload/styles/clipbucketblue/layout/join_group.html create mode 100644 upload/styles/clipbucketblue/layout/lang_change.html create mode 100644 upload/styles/clipbucketblue/layout/lang_changer.html create mode 100644 upload/styles/clipbucketblue/layout/leave_group.html create mode 100644 upload/styles/clipbucketblue/layout/login_success.html create mode 100644 upload/styles/clipbucketblue/layout/logout_success.html create mode 100644 upload/styles/clipbucketblue/layout/manage_contacts.html create mode 100644 upload/styles/clipbucketblue/layout/manage_favourites.html create mode 100644 upload/styles/clipbucketblue/layout/manage_group_members.html create mode 100644 upload/styles/clipbucketblue/layout/manage_group_videos.html create mode 100644 upload/styles/clipbucketblue/layout/manage_groups.html create mode 100644 upload/styles/clipbucketblue/layout/manage_subscriptions.html create mode 100644 upload/styles/clipbucketblue/layout/manage_videos.html create mode 100644 upload/styles/clipbucketblue/layout/message.html create mode 100644 upload/styles/clipbucketblue/layout/myaccount.html create mode 100644 upload/styles/clipbucketblue/layout/privacy.html create mode 100644 upload/styles/clipbucketblue/layout/rss.html create mode 100644 upload/styles/clipbucketblue/layout/search_box.html create mode 100644 upload/styles/clipbucketblue/layout/search_result.html create mode 100644 upload/styles/clipbucketblue/layout/sent.html create mode 100644 upload/styles/clipbucketblue/layout/signup.html create mode 100644 upload/styles/clipbucketblue/layout/signup_success.html create mode 100644 upload/styles/clipbucketblue/layout/sitemap.xml create mode 100644 upload/styles/clipbucketblue/layout/style_change.html create mode 100644 upload/styles/clipbucketblue/layout/tabs01.html create mode 100644 upload/styles/clipbucketblue/layout/tabs02.html create mode 100644 upload/styles/clipbucketblue/layout/tabs03.html create mode 100644 upload/styles/clipbucketblue/layout/termsofuse.html create mode 100644 upload/styles/clipbucketblue/layout/upload.html create mode 100644 upload/styles/clipbucketblue/layout/user_account.html create mode 100644 upload/styles/clipbucketblue/layout/user_contacts.html create mode 100644 upload/styles/clipbucketblue/layout/user_fav_videos.html create mode 100644 upload/styles/clipbucketblue/layout/user_videos.html create mode 100644 upload/styles/clipbucketblue/layout/videos.html create mode 100644 upload/styles/clipbucketblue/layout/videouploadsuccess.html create mode 100644 upload/styles/clipbucketblue/layout/view_channel.html create mode 100644 upload/styles/clipbucketblue/layout/view_group.html create mode 100644 upload/styles/clipbucketblue/layout/view_group_members.html create mode 100644 upload/styles/clipbucketblue/layout/view_group_videos.html create mode 100644 upload/styles/clipbucketblue/layout/view_topic.html create mode 100644 upload/styles/clipbucketblue/layout/watch_video.html create mode 100644 upload/styles/clipbucketblue/theme/ajaxtabs.css create mode 100644 upload/styles/clipbucketblue/theme/body.css create mode 100644 upload/styles/clipbucketblue/theme/container.css create mode 100644 upload/styles/clipbucketblue/theme/date_picker.css create mode 100644 upload/styles/clipbucketblue/theme/drop_down.css create mode 100644 upload/styles/clipbucketblue/theme/links.css create mode 100644 upload/styles/clipbucketblue/theme/main.css create mode 100644 upload/styles/clipbucketblue/theme/pagination.css create mode 100644 upload/styles/clipbucketblue/theme/rating_style.css create mode 100644 upload/styles/clipbucketblue/theme/ui.tabs.css create mode 100644 upload/styles/clipbucketblue/theme/uploader.css create mode 100644 upload/styles/clipbucketblue/theme/view_channel.css create mode 100644 upload/tabs01.php create mode 100644 upload/tabs02.php create mode 100644 upload/tabs03.php create mode 100644 upload/termsofuse.php create mode 100644 upload/upload.php create mode 100644 upload/user_account.php create mode 100644 upload/user_contacts.php create mode 100644 upload/user_fav_videos.php create mode 100644 upload/user_videos.php create mode 100644 upload/videos.php create mode 100644 upload/videouploadsuccess.php create mode 100644 upload/view_channel.php create mode 100644 upload/view_group.php create mode 100644 upload/view_group_members.php create mode 100644 upload/view_group_videos.php create mode 100644 upload/view_topic.php create mode 100644 upload/watch_video.php diff --git a/CBLA.txt b/CBLA.txt new file mode 100644 index 00000000..44d32e1e --- /dev/null +++ b/CBLA.txt @@ -0,0 +1,96 @@ +ClipBucket License Agreement (CBLA) +Version 1, November 13, 2008 + +Copyright © 2008 PHPBucket PVT, LTD + +Preamble + +The CBLA (ClipBucket License Agreement) is, as its name shows it, a contract between the software developer / owner (PHPBucket / ClipBucket ) and a potential user, either an Entity or a Single User, (hereinafter each licensee is addressed as "you"). By means of this contract it is established that the developer of the software is it's de facto owner, and that a copy of the respective software downloaded from a vendor (or downloaded from the Internet) only licenses it to a user, and does not transmit any intellectual rights whatsoever on the Software. + +The end user is only allowed to use it as long the terms in this license agreement are accepted. + +This ClipBucket License Agreement (CBLA) covers your use of the ClipBucket software product that accompanies this CBLA and related software components, which may include associated media, printed materials, and "online" or electronic documentation. All such software and materials are referred to herein as the "Software Product." A software license, issued to a designated user only by ClipBucket / PHPBucket or its authorized agents, is required for each user of the Software Product. If you do not agree to the terms of this CBLA, you are not authorized to install or use the associated Software Product or the Software Product License. By explicitly accepting this CBLA, or by installing, copying, downloading, accessing, or otherwise using the Software Product and/or Software Product License, you are acknowledging and agreeing to be bound by the terms listed under TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION. + + +CLIPBUCKET LICENSE AGREEMENT +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION +(subject to change without notice) + + +1. LICENSE + +(a) Software Product License. + +The Software Product License, which is issued to a designated user, enables such designated user to install and use the Software Product on a His/Her websites/domains Without paying any fee. + +You are not allowed to: + +(a.1) sell the software product +(a.2) sell derivate works based on the software product or any of it's associated components +(a.3) use any portion of the software product in other products or derivate works + +You are allowed to: + +(a.4) create modifications for the software product +(a.5) alter the software product for your own use +(a.6) sell products that integrate with or enhance the software product + + +(b) Grant of License. + +Subject to a validly issued Software Product License, ClipBucket/PHPBucket grants to you the non-exclusive, non-transferable right for you to use the Software Product on an unlimited number of websites/domains. All rights not expressly granted to you are retained by ClipBucket/ PHPBucket. + +(c) Adult Content Prohibition +You cannot use ClipBucket on any website which contain any kind of pornographic content. If you want to Use ClipBucket on such kind of websites you need to purchase the Adult Permit which is available on the official ClipBucket website for a nominal fee + +2. WARRANTY: + +ClipBucket / PHP Bucket Softwares are Provided on ”AS IS” and ” AS AVAILABLE" BASIS. ClipBucket /PHPBucket DISCLAIMS ANY IMPLIED WARRANTIES. ClipBucket/PHPBucet , ANY OF ITS EMPLOYEES, MANAGEMENT OR AFFILIATES MAY NOT BE HELD RESPONSIBLE OR THUS LIABLE FOR ANY POSSIBLE DAMAGES RESULTING IN USE OR MISUSE OF ANY INFORMATION, CONTENT OR SOFTWARE PROVIDED BY ClipBucket/PHPBucket , INCLUDING DIRECT OR INDIRECT, PUNITIVE, AND INCIDENTAL RESULTING FROM ANY FAILURE TO PROVIDE SERVICES, SUSPENSION OF SERVICES, OR TERMINATION OF SERVICES. THE SOFTWARE IS PROVIDED "AS IS" AND YOU ASSUME ALL RISK WITH ITS INSTALLATION, CONFIGURATION AND USE. THERE ARE NO WARRANTIES, CLAIMS OR REPRESENTATIONS MADE BY ClipBucket/PHPBucket, EITHER EXPRESS, IMPLIED, OR STATUTORY, WITH RESPECT TO THE SOFTWARE, INCLUDING WARRANTIES OF QUALITY, PERFORMANCE, NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE, NOR ARE THERE ANY WARRANTIES CREATED BY COURSE OF DEALING, COURSE OF PERFORMANCE, OR TRADE USAGE. FURTHER, ClipBucket / PHPBucket DOES NOT REPRESENT OR WARRANT THAT THE SOFTWARE WILL ALWAYS BE AVAILABLE, ACCESSIBLE, ACCURATE, COMPLETE, OR ERROR-FREE. THE FOREGOING EXCLUSIONS AND DISCLAIMERS ARE AN ESSENTIAL PART OF THIS AGREEMENT AND FORMED THE BASIS FOR DETERMINING THE PRICE CHARGED FOR THE SOFTWARE AND ANY ASSOCIATED SERVICES. + +3. LIMITED LIABILITY: + +YOU ASSUME ALL RISK ASSOCIATED WITH THE INSTALLATION AND USE OF THE SOFTWARE. IN NO EVENT SHALL ClipBucket/PHPBucket BE LIABLE WHETHER IN CONTRACT, WARRANTY, TORT (INCLUDING NEGLIGENCE (WHETHER ACTIVE, PASSIVE OR IMPUTED), PRODUCT LIABILITY OR STRICT LIABILITY OR OTHER THEORY), FOR COVER OR FOR ANY INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION ANY LOSS OF PROFITS OR DATA, BUSINESS INTERRUPTION, COMPUTER FAILURE OR OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OR INABILITY TO USE THE SOFTWARE OR PERFORMANCE OF ANY RELATED SERVICES, EVEN IF ClipBucket/PHPBucket HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +ClipBucket/PHPBucket’s CUMULATIVE LIABILITY TO YOU OR ANY OTHER PARTY FOR ANY LOSS OR DAMAGES RESULTING FROM ANY CLAIMS, DEMANDS, OR ACTIONS ARISING OUT OF OR RELATING TO THIS LICENSE SHALL NOT EXCEED THE AMOUNTS PAID BY YOU TO ClipBucket/PHPBucket FOR THE USE OF THE SOFTWARE. YOU HEREBY RELEASE ClipBucket/PHPBucket FROM ANY AND ALL OBLIGATIONS, LIABILITIES AND CLAIMS IN EXCESS OF THIS LIMITATION. + + +4. INTELLECTUAL PROPERTY RIGHTS RESERVED BY ClipBucket/PHPBucket: + +The Software Product is protected by U.S, CANADA, and international copyright laws and treaties, as well as other intellectual property laws and treaties. You must not remove or alter any copyright notices on any copies of the Software Product. This Software Product copy is licensed, not sold. Furthermore, this CBLA does not grant you any rights in connection with any trademarks or service marks of ClipBucket / PHPBucket . ClipBucket reserves all intellectual property rights, including copyrights, and trademark rights. + +5. NO RIGHT TO TRANSFER + +You may not rent, lease, lend, or in any way distribute or transfer any rights in this CBLA or the Software Product to third parties without ClipBucket/PHPBucket's written approval and subject to written agreement by the recipient of the terms of this CBLA. + +6. PROHIBITION ON REVERSE ENGINEERING, DECOMPILATION, AND DISASSEMBLY + +You may not reverse engineer, decompile, defeat license encryption mechanisms, or disassemble the Software Product or Software Product License except and only to the extent that such activity is expressly permitted by applicable law notwithstanding this limitation. + + +9. MISCELLANEOUS. + +We reserve the right to reference any website or company using the Software in our sales and marketing literature. + +We reserve the right to monitor compliance with this CBLA and to restrict the use of the Software for non-compliance. + +We reserve the right to include the "Flash Video Player by PHPBucket.com & Clip-bucket.com" text/link on every copy of the Flash Video Player included in the ClipBucket software. The "Flash Video Player by PHPBucket.Com" text/link can be removed by paying a small fee mentioned on the website/documentation. + + +ClipBucket / PHPBucket STRICTLY PROHIBITS SALE/RESALE OF OUR PRODUCTS. DO NOT SELL, BUT YOU CAN GIVE AWAY OR REUSE OUR PRODUCTS WITHOUT FOR FREE AND FOR NON COMMERCIAL USE, BUT IT SHOULD RETAIN ITS ORIGINAL FORM WITH OUR NAME WHILE DISTRIBUTING FREE. ClipBucket / PHPBucket will take legal action against any users that are found to be Selling Clipbucket(Lite) / ClipBucket / PHPBucket products. In addition A ClipBucket / PHPBucket will report any users found pirating other products to the products developer or care-keeper. + + +The terms set forth in this License and any related service agreements constitute the final, complete and exclusive agreement with respect to the Software and may not be contradicted, explained or supplemented by evidence of any prior agreement, any contemporaneous oral agreement or any consistent additional terms. Should any term or provision hereof be deemed invalid, void or unenforceable either in its entirety or in a particular application, the remainder of this License shall nonetheless remain in full force and effect. Any term of this License may be amended and the observance of any term may be waived only with the written consent of ClipBucket / PHPBucket . The failure of ClipBucket / PHPBucket at any time or times to require performance of any provision hereof shall in no manner affect its right at a later time to enforce the same unless the same is waived in writing. + +10. CONTACT INFORMATION + +If you have any questions about this CBLA, or if you want to contact ClipBucket / PHPBucket for any reason, please direct all correspondence to: + +http://www.clip-bucket.com +http://www.phpbucket.com + + +or email: info@phpbucket.com + + +ClipBucket Product is registered trademark of PHPBucket. + diff --git a/VERSION b/VERSION new file mode 100644 index 00000000..05e34a2c --- /dev/null +++ b/VERSION @@ -0,0 +1,5 @@ +Product: ClipBucket - http://clip-bucket.com +Version: 1.7.1 SVN - Revision 758 +Last Updated: March 26, 2009 +Copyright: ClipBucket +License: CBLA v1 \ No newline at end of file diff --git a/docs/CBLA.txt b/docs/CBLA.txt new file mode 100644 index 00000000..44d32e1e --- /dev/null +++ b/docs/CBLA.txt @@ -0,0 +1,96 @@ +ClipBucket License Agreement (CBLA) +Version 1, November 13, 2008 + +Copyright © 2008 PHPBucket PVT, LTD + +Preamble + +The CBLA (ClipBucket License Agreement) is, as its name shows it, a contract between the software developer / owner (PHPBucket / ClipBucket ) and a potential user, either an Entity or a Single User, (hereinafter each licensee is addressed as "you"). By means of this contract it is established that the developer of the software is it's de facto owner, and that a copy of the respective software downloaded from a vendor (or downloaded from the Internet) only licenses it to a user, and does not transmit any intellectual rights whatsoever on the Software. + +The end user is only allowed to use it as long the terms in this license agreement are accepted. + +This ClipBucket License Agreement (CBLA) covers your use of the ClipBucket software product that accompanies this CBLA and related software components, which may include associated media, printed materials, and "online" or electronic documentation. All such software and materials are referred to herein as the "Software Product." A software license, issued to a designated user only by ClipBucket / PHPBucket or its authorized agents, is required for each user of the Software Product. If you do not agree to the terms of this CBLA, you are not authorized to install or use the associated Software Product or the Software Product License. By explicitly accepting this CBLA, or by installing, copying, downloading, accessing, or otherwise using the Software Product and/or Software Product License, you are acknowledging and agreeing to be bound by the terms listed under TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION. + + +CLIPBUCKET LICENSE AGREEMENT +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION +(subject to change without notice) + + +1. LICENSE + +(a) Software Product License. + +The Software Product License, which is issued to a designated user, enables such designated user to install and use the Software Product on a His/Her websites/domains Without paying any fee. + +You are not allowed to: + +(a.1) sell the software product +(a.2) sell derivate works based on the software product or any of it's associated components +(a.3) use any portion of the software product in other products or derivate works + +You are allowed to: + +(a.4) create modifications for the software product +(a.5) alter the software product for your own use +(a.6) sell products that integrate with or enhance the software product + + +(b) Grant of License. + +Subject to a validly issued Software Product License, ClipBucket/PHPBucket grants to you the non-exclusive, non-transferable right for you to use the Software Product on an unlimited number of websites/domains. All rights not expressly granted to you are retained by ClipBucket/ PHPBucket. + +(c) Adult Content Prohibition +You cannot use ClipBucket on any website which contain any kind of pornographic content. If you want to Use ClipBucket on such kind of websites you need to purchase the Adult Permit which is available on the official ClipBucket website for a nominal fee + +2. WARRANTY: + +ClipBucket / PHP Bucket Softwares are Provided on ”AS IS” and ” AS AVAILABLE" BASIS. ClipBucket /PHPBucket DISCLAIMS ANY IMPLIED WARRANTIES. ClipBucket/PHPBucet , ANY OF ITS EMPLOYEES, MANAGEMENT OR AFFILIATES MAY NOT BE HELD RESPONSIBLE OR THUS LIABLE FOR ANY POSSIBLE DAMAGES RESULTING IN USE OR MISUSE OF ANY INFORMATION, CONTENT OR SOFTWARE PROVIDED BY ClipBucket/PHPBucket , INCLUDING DIRECT OR INDIRECT, PUNITIVE, AND INCIDENTAL RESULTING FROM ANY FAILURE TO PROVIDE SERVICES, SUSPENSION OF SERVICES, OR TERMINATION OF SERVICES. THE SOFTWARE IS PROVIDED "AS IS" AND YOU ASSUME ALL RISK WITH ITS INSTALLATION, CONFIGURATION AND USE. THERE ARE NO WARRANTIES, CLAIMS OR REPRESENTATIONS MADE BY ClipBucket/PHPBucket, EITHER EXPRESS, IMPLIED, OR STATUTORY, WITH RESPECT TO THE SOFTWARE, INCLUDING WARRANTIES OF QUALITY, PERFORMANCE, NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE, NOR ARE THERE ANY WARRANTIES CREATED BY COURSE OF DEALING, COURSE OF PERFORMANCE, OR TRADE USAGE. FURTHER, ClipBucket / PHPBucket DOES NOT REPRESENT OR WARRANT THAT THE SOFTWARE WILL ALWAYS BE AVAILABLE, ACCESSIBLE, ACCURATE, COMPLETE, OR ERROR-FREE. THE FOREGOING EXCLUSIONS AND DISCLAIMERS ARE AN ESSENTIAL PART OF THIS AGREEMENT AND FORMED THE BASIS FOR DETERMINING THE PRICE CHARGED FOR THE SOFTWARE AND ANY ASSOCIATED SERVICES. + +3. LIMITED LIABILITY: + +YOU ASSUME ALL RISK ASSOCIATED WITH THE INSTALLATION AND USE OF THE SOFTWARE. IN NO EVENT SHALL ClipBucket/PHPBucket BE LIABLE WHETHER IN CONTRACT, WARRANTY, TORT (INCLUDING NEGLIGENCE (WHETHER ACTIVE, PASSIVE OR IMPUTED), PRODUCT LIABILITY OR STRICT LIABILITY OR OTHER THEORY), FOR COVER OR FOR ANY INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION ANY LOSS OF PROFITS OR DATA, BUSINESS INTERRUPTION, COMPUTER FAILURE OR OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OR INABILITY TO USE THE SOFTWARE OR PERFORMANCE OF ANY RELATED SERVICES, EVEN IF ClipBucket/PHPBucket HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +ClipBucket/PHPBucket’s CUMULATIVE LIABILITY TO YOU OR ANY OTHER PARTY FOR ANY LOSS OR DAMAGES RESULTING FROM ANY CLAIMS, DEMANDS, OR ACTIONS ARISING OUT OF OR RELATING TO THIS LICENSE SHALL NOT EXCEED THE AMOUNTS PAID BY YOU TO ClipBucket/PHPBucket FOR THE USE OF THE SOFTWARE. YOU HEREBY RELEASE ClipBucket/PHPBucket FROM ANY AND ALL OBLIGATIONS, LIABILITIES AND CLAIMS IN EXCESS OF THIS LIMITATION. + + +4. INTELLECTUAL PROPERTY RIGHTS RESERVED BY ClipBucket/PHPBucket: + +The Software Product is protected by U.S, CANADA, and international copyright laws and treaties, as well as other intellectual property laws and treaties. You must not remove or alter any copyright notices on any copies of the Software Product. This Software Product copy is licensed, not sold. Furthermore, this CBLA does not grant you any rights in connection with any trademarks or service marks of ClipBucket / PHPBucket . ClipBucket reserves all intellectual property rights, including copyrights, and trademark rights. + +5. NO RIGHT TO TRANSFER + +You may not rent, lease, lend, or in any way distribute or transfer any rights in this CBLA or the Software Product to third parties without ClipBucket/PHPBucket's written approval and subject to written agreement by the recipient of the terms of this CBLA. + +6. PROHIBITION ON REVERSE ENGINEERING, DECOMPILATION, AND DISASSEMBLY + +You may not reverse engineer, decompile, defeat license encryption mechanisms, or disassemble the Software Product or Software Product License except and only to the extent that such activity is expressly permitted by applicable law notwithstanding this limitation. + + +9. MISCELLANEOUS. + +We reserve the right to reference any website or company using the Software in our sales and marketing literature. + +We reserve the right to monitor compliance with this CBLA and to restrict the use of the Software for non-compliance. + +We reserve the right to include the "Flash Video Player by PHPBucket.com & Clip-bucket.com" text/link on every copy of the Flash Video Player included in the ClipBucket software. The "Flash Video Player by PHPBucket.Com" text/link can be removed by paying a small fee mentioned on the website/documentation. + + +ClipBucket / PHPBucket STRICTLY PROHIBITS SALE/RESALE OF OUR PRODUCTS. DO NOT SELL, BUT YOU CAN GIVE AWAY OR REUSE OUR PRODUCTS WITHOUT FOR FREE AND FOR NON COMMERCIAL USE, BUT IT SHOULD RETAIN ITS ORIGINAL FORM WITH OUR NAME WHILE DISTRIBUTING FREE. ClipBucket / PHPBucket will take legal action against any users that are found to be Selling Clipbucket(Lite) / ClipBucket / PHPBucket products. In addition A ClipBucket / PHPBucket will report any users found pirating other products to the products developer or care-keeper. + + +The terms set forth in this License and any related service agreements constitute the final, complete and exclusive agreement with respect to the Software and may not be contradicted, explained or supplemented by evidence of any prior agreement, any contemporaneous oral agreement or any consistent additional terms. Should any term or provision hereof be deemed invalid, void or unenforceable either in its entirety or in a particular application, the remainder of this License shall nonetheless remain in full force and effect. Any term of this License may be amended and the observance of any term may be waived only with the written consent of ClipBucket / PHPBucket . The failure of ClipBucket / PHPBucket at any time or times to require performance of any provision hereof shall in no manner affect its right at a later time to enforce the same unless the same is waived in writing. + +10. CONTACT INFORMATION + +If you have any questions about this CBLA, or if you want to contact ClipBucket / PHPBucket for any reason, please direct all correspondence to: + +http://www.clip-bucket.com +http://www.phpbucket.com + + +or email: info@phpbucket.com + + +ClipBucket Product is registered trademark of PHPBucket. + diff --git a/docs/CHANGELOG b/docs/CHANGELOG new file mode 100644 index 00000000..e1ae5cc7 --- /dev/null +++ b/docs/CHANGELOG @@ -0,0 +1,92 @@ +March 2009 +-- added: proper comment counting (fwhite) +-- added: debug mode (fwhite) +-- added: debug mode option to admin_area (fwhite) +-- added: highest rated, most discussed filter (fwhite) +-- fixed: category filter bug (fwhite) +-- fixed: win32 conversion (limejoe) +-- fixed: "Recently Viewed..." when in subdir (thx momo) +-- fixed: admin check on IE (fw) +-- fixed: video display on manage videos - IE (fw) + + +February 2009 [fwhite] +-- added: flash_recent_videos_black.swf (momo) +-- added: FR & zh_CN lang (need images for both) +-- added: SK lang +-- changed: admin_area login page +-- fixed: template sort +-- fixed: flash_recent_videos.swf (momo) +-- fixed: bug #132 - http://bugs.cbdev.org/index.php?do=details&task_id=132&project=1 +-- fixed: destroy session on logout +-- fixed: footer - NOBR +-- fixed: unregister userid on logout +-- fixed: delete cookies on logout +-- fixed: bug# 159 - http://bugs.cbdev.org/index.php?do=details&task_id=159&project=1 +-- fixed: admin_area url in footer +-- removed: first name, last name requirement (edit_member) + + +Added Feb 11 2009 [Arslan] +-- Fixed : manage_videos.php videos order problem + +Added Feb 01 2009 [Arslan] +-- text_exec() function once added in functions.php +-- text_exec() will also check windows paths +-- footer css changed of youtube style + +January 2009 [fwhite] +-- fixed: scandir (define function !function_exists) +-- fixed: isValidEmail +-- fixed: /inactive.php redirect & inactive.html image display +-- fixed: jw_player plugin (wmode should not be opaque) + +Bug List +-- Channel Background and Avatar Change Error [Fixed] +-- Re-Login Updates Users Videos Count [Fixed] +-- Admin Panel Template Editor Fault [Fixed] +-- User Videos Pagination Error [Check livedemo .httaccess for Rewrite Rules] [Fixed] +-- FileSize() Error , [Fixed] +-- Admin Area Show 0 videos [Fixed] +-- Rating_images bug [Fixed] +-- Username Session CaSe iS sEnsiTive [Fixed] +-- DeepLinks of player do not work [Fixed] +-- Big Thumb Doesnt Not Delete [Fixed] +-- Thumb Generation Error (Overwrite Permission Problem) [Fixed] +-- Website Link in view_channel [Fixed] +-- Embed Code shows up in videuploaducess even turning of from admin panel [Fixed] +-- Advertisment Problem [Fixed] +-- YT themes Meta Descript {f} [Fixed] +-- XMLHTTPRequest Error [Fixed] {fwhite} +-- Utf-8 Fix by FrankWhite {fwhite} [Fixed] +-- Valid Emabedded Code by Murat [Fixed] {lavinya} +-- Video Flags Do Not Delete After Deleteing Video [Fixed] +-- Redirect Error on Login [Fixed] +-- Captcha Verification Problem [Fixed] +-- Warning Lists In ClipBucket [Fixed] +-- Groups Problem, Owner Autojoin etc [Fixed] +-- Manage Videos Page Problems [Fixed] +-- manage_Favoutites , Links Do not work properly [Fixed] +-- User Session Lost During Uploading [Fixed] +-- Edit Video (watch video link doesnt work) [Fixed] +-- Private Video Emailed to subscribers [Fixed] +-- Favourite Videos Do Not Remove After Deleteing Video [Fixed] +-- Registeration Closed Message [Fixed] + + + + +Updates Added +-- Tempate Editor Updated +-- Upload File Type,File Size in Admin +-- Advertismetn Section Update (Placements Added) +-- New Comments Options Added +-- New Captcha Mods Added +-- Sort Editor's Pick +-- File Types Option Added in Admin +-- Language Changer in Footer (on/off via admin panel) by Frank +-- Template Changer in Footer (on/off via admin panel) by Frank +-- Rss Feeds by Murat +-- OpenSearch By Frank +-- Videos Sitemap For Google by Murat +-- FFMPEG Conversion Class diff --git a/docs/README b/docs/README new file mode 100644 index 00000000..88e9e6db --- /dev/null +++ b/docs/README @@ -0,0 +1,18 @@ +ClipBucket is an open source video sharing script designed to build sites similar to Youtube, Metacafe, et al +ClipBucket has many features and a powerful administration panel. + +Installation Guide: +http://forums.clip-bucket.com/showthread.php?t=676 + +ClipBucket is licensed under the CBLA (ClipBucket License Agreement) +Please read the license carefully +http://cbla.cbdev.org + +Discussion & Support: +http://forums.clip-bucket.com + +Language Packs: +http://clipbucket.org/frs/?group_id=6 + +Contribute: +http://clipbucket.org \ No newline at end of file diff --git a/docs/README_WIN32.txt b/docs/README_WIN32.txt new file mode 100644 index 00000000..22ec7abd --- /dev/null +++ b/docs/README_WIN32.txt @@ -0,0 +1,17 @@ +Run ClipBucket 1.7.x on Win32 (limejoe) + +Step 1: +Download the Win32 binaries from http://clipbucket.org/scm/viewvc.php/etc/1.x/1.7/win32/?root=clipbucket + +Step 2: +Add IUSR_machine privileges to execute CLI from webserver. + +Step 3: Copy win32 php folder contents to your php installation root dir. And copy dll's from ext dir to the ext dir in your php path. + +step 4: Setup admin_area with encoding tools path. Make sure to point to .exe's. As pointing to the directory alone will nto work. eg. c:/ffmpeg/ffmpeg.exe or c:/php/php-win.exe. !important + +Step 5: Modify conversion.conf.php to user ffmpeg.win32.php isntead of ffmpeg.class.php. + +Your CB version should now work on windows! + +Have fun. diff --git a/docs/installation.html b/docs/installation.html new file mode 100644 index 00000000..ef7294b2 --- /dev/null +++ b/docs/installation.html @@ -0,0 +1,132 @@ + + + + +Installation + + + +
+

Installation

+
+
After Confirming the server is ready for ClipBucket , our next step is to Upload All Files to the Server
+

Uploading And Chmod

+
    +
  • Upload All Files From Public_html Folder to your Root dir ie( www , public_html)
  • +
  • Chmod Following to 777
  • +
      +
    • Files’ directory and all files and folders under it (Important)
    • +
    • Images’ directory and all files and folders under it (Important)
    • +
    • Styles’ directory and all files and folders under it
    • +
    • Includes/email_templates’ and files under it
    • +
    • player’ and files under it (Important)
    • +
    • Cache’ directory (Important)
    • +
    • logs’ directory and logs.txt (Important)
    • +
    +
+

Sql Dumping & Database Settings

+
    +
  • Create a database and Import the 'clipbucket_lite.sql' from Sql folder
  • +
  • Now edit values in 'config' table as +
      +
    • 'base_dir' to relative path to directory where clipbucket is installed ie /home/username/public_html (without trailing slash "/" at the end )
    • +
    • 'base_url' to direct url to website where clipbucket is installed ie http://www.clip-bucket.com (without trailing slash "/" at the end )
    • +
    +
  • +
  • Now Edit 'includes/dbconnect.php' as +
      +
    • $BDTYPE = 'mysql';
    • +
    • $DBHOST = 'localhost' ; Change the Host (Default Host is localhost so you may not need to change this)
    • +
    • $DBNAME = 'dbname'; Change this to the name of the database you created for clipbucket
    • +
    • $DBUSER = 'dbuser'; Change this to the username of the databse you assigned to the clipbucket
    • +
    • $DBPASS = 'password'; Change it to the password of the database
    • +
    +
  • +
+

now your website is almost ready to go, but you have to change some settings from the Administrator Panel

+

Settings In Admin Panel

+

First You have to access to the admin panel and by using this url http://yourwebsites.com/admin_area

+
    +
  • Enter username and password to login as Super Admin +
      +
    • username : admin
    • +
    • password : admin
    • +
    +
  • +
  • After Logging in go to Super Admin Settings +
      +
    • Change the username and pass to whatever you want, but make is so complicate so that no one able to guess it
    • +
    +
  • +
  • Now Create an Admin by clicking 'Add Member' found under User Management Menu
  • +
  • Fill The Form and Set its User Access Level to Admin and Submit it, and use this user as Admin
    + NOTE : DO NOT PERFORM ANY ACTION OTHER THAN USERMANAGMENT USING SUPERADMIN
  • +
  • Now logout and Login as Your newly created admin
  • +
+

Setting Website Configurations

+
    +
  • Website Settings + +
      +
    • Website Title "Your Website Title" ie "Best Website"
    • +
    • Website Slogan ie "We Are The Best";
    • +
    • Website Closed (If You Are Editing or Doing Maintenance) Yes/No
    • +
    • Website Closed Message is Displayed When You Have Closed Your Website
    • +
    • Set Meta Description according to your website content
    • +
    • Set Meta Keywords According to your website Content
    • +
    • Turn on/of SEO Url
    • +
    +
  • +
  • Paths + +
      +
    • FFMPEG Binary Path (Set FFMPEG path, where FFMPEG is installed)
    • +
    • FLVTool2 Path (Set Flv Tool 2 Path)
    • +
    • Mencoder Path (Set Mencoder Path)
    • +
    • Mplayer Path (Set Mplayer Path)
    • +
    • PHP Path ( Set PHP Path)
    • +
    +
  • +
  • Video, Uploading and Conversion Settings + +
      +
    • Max Upload Size (Set the Maximum Size of the File you want to be uploaded )
    • +
    • Video Comments (Turn on or off Video Comments) Yes/No
    • +
    • Video Embedding (Turn on or off Video Embedding) Yes/No
    • +
    • Video Rating (Turn on or off Video Rating) Yes/No
    • +
    • Video Comments Rating (Turn on or off Video Comments Rating ) Yes/No
    • +
    • Resize The Uploaded Video or Not +
        +
      • if yes the Set Resize Height and Resized Width
      • +
      +
    • +
    • Set Other Video Settings Accordingly
    • +
    • Keep Original File for Download (Turn on or off ) Yes/No
    • +
    • Video Activation Required (Turn on or off ) Yes/No
    • +
    +
  • +
  • Display Settings + +
      +
    • Template Name ( Select Available Template From The list)
    • +
    • Flash Player ( Select Available Flash Player From The list)
    • +
    • Video List Per Page ( Number Of Videos List Per Page )
    • +
    • Video List Per Box ( Number Of VIdeo List in a Box, Tab or other than Main or Videos Page)
    • +
    • Channel List Per Page ( Number Of Channels List Per Page)
    • +
    • Channels List Per Box ( Number OF Channels List Per Box , Tab or Other than main or Channels Page)
    • +
    • Set Number Of Search Results Display
    • +
    • Set Number of Recently Viewed Videos in a Flash Widget
    • +
    +
  • +
  • User Registration + +
      +
    • Turn On/Off User Registrations
    • +
    • Set on/Off Email Verification
    • +
    +
  • +
+

 

+

Your Basic Installation is Done and Your website is ready to Launch

+ + diff --git a/docs/requirements.html b/docs/requirements.html new file mode 100644 index 00000000..748896f5 --- /dev/null +++ b/docs/requirements.html @@ -0,0 +1,38 @@ + + + + +Requirements + + + +
+

Requirements

+
+
ClipBucket has a few requirements which must be met before you are able to install and use it. In this section, these requirements are explained.
+
    +
  • Linux Server (some old distributions are not supported)
  • +
  • Apache Web Server
  • +
  • MySQL (version 4 +)
  • +
  • PHP ( PHP 5)
  • +
  • PHP Configuration
  • +
      +
    • safe_mode = off
    • +
    • max_execution_time = 1000 (recommended to prevent timeouts during video upload/conversion)
    • +
    • session.gc_maxlifetime = 14000 (recommended to prevent session expires during video upload)
    • +
    • open_basedir = (no value)
    • +
    • output_buffering = on
    • +
    • upload_max_filesize = 100M (recommended maximum video upload size in MB)
    • +
    • post_max_size = 100M (recommended maximum video upload size in MB)
    • +
    • GD library Enabled (v2 or higher)
    • +
    +
  • Mplayer + Mencoder (http://www.mplayerhq.hu/design7/dload.html)
  • +
  • Flv2tool (http://inlet-media.de/flvtool2)
  • +
  • Libogg + Libvorbis (http://www.xiph.org/downloads)
  • +
  • LAME MP3 Encoder (http://lame.sourceforge.net)
  • +
  • Apache mod_rewrite Enabled
  • +
  • Must be able to run PHP from the command line (CLI) with exec()
  • +
  • Allowed execution of background processes with exec("binary > /dev/null &")
  • +
+ + diff --git a/sql/cb_new_install.sql b/sql/cb_new_install.sql new file mode 100644 index 00000000..d1e42c34 --- /dev/null +++ b/sql/cb_new_install.sql @@ -0,0 +1,2064 @@ +-- phpMyAdmin SQL Dump +-- version 3.1.3 +-- http://www.phpmyadmin.net +-- +-- Host: localhost +-- Generation Time: Jul 07, 2009 at 10:07 AM +-- Server version: 5.1.32 +-- PHP Version: 5.2.9-1 + +SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO"; + +-- +-- Database: `clipbucket_svn` +-- + +-- -------------------------------------------------------- + +-- +-- Table structure for table `action_log` +-- + +CREATE TABLE IF NOT EXISTS `action_log` ( + `action_id` int(255) NOT NULL AUTO_INCREMENT, + `action_type` varchar(60) CHARACTER SET latin1 NOT NULL, + `action_username` varchar(60) CHARACTER SET latin1 NOT NULL, + `action_userid` int(30) NOT NULL, + `action_useremail` varchar(200) CHARACTER SET latin1 NOT NULL, + `action_userlevel` int(11) NOT NULL, + `action_ip` varchar(15) CHARACTER SET latin1 NOT NULL, + `date_added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `action_success` enum('yes','no') CHARACTER SET latin1 NOT NULL, + `action_details` text CHARACTER SET latin1 NOT NULL, + PRIMARY KEY (`action_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ; + +-- +-- Dumping data for table `action_log` +-- + +INSERT INTO `action_log` (`action_id`, `action_type`, `action_username`, `action_userid`, `action_useremail`, `action_userlevel`, `action_ip`, `date_added`, `action_success`, `action_details`) VALUES +(1, 'login', 'admin', 1, '', 0, '127.0.0.1', '2009-07-04 13:11:25', 'yes', ''); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ads_data` +-- + +CREATE TABLE IF NOT EXISTS `ads_data` ( + `ad_id` int(50) NOT NULL AUTO_INCREMENT, + `ad_name` mediumtext NOT NULL, + `ad_code` mediumtext NOT NULL, + `ad_placement` varchar(50) NOT NULL DEFAULT '', + `ad_category` int(11) NOT NULL DEFAULT '0', + `ad_status` enum('0','1') NOT NULL DEFAULT '0', + `ad_impressions` bigint(255) NOT NULL DEFAULT '0', + `date_added` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`ad_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=8 ; + +-- +-- Dumping data for table `ads_data` +-- + +INSERT INTO `ads_data` (`ad_id`, `ad_name`, `ad_code`, `ad_placement`, `ad_category`, `ad_status`, `ad_impressions`, `date_added`) VALUES +(1, 'Ad Box of 300 x 250', '
\r\n Ad Box 11 x 11\r\n
', 'ad_300x250', 0, '1', 675, '0000-00-00 00:00:00'), +(2, 'Adbox 160x600', '
\r\n Ad Box 160 x 600\r\n
', 'ad_160x600', 0, '1', 409, '0000-00-00 00:00:00'), +(3, 'Adbox 468x60', '
\r\n Ad Box 468 x 60\r\n
', 'ad_468x60', 0, '1', 1330, '0000-00-00 00:00:00'), +(4, 'Adbox 728x90', '
\r\n Ad Box 728 x 90\r\n
', 'ad_728x90', 0, '1', 692, '0000-00-00 00:00:00'), +(5, 'Adbox 120x600', '
\r\n Ad Box 120 x 600\r\n
', 'ad_120x600', 0, '1', 681, '0000-00-00 00:00:00'), +(6, 'Test', '
\r\n Ad Box 11 x 11\r\n
', 'ad_160x600', 0, '1', 375, '0000-00-00 00:00:00'), +(7, 'Rasd', 'asd', 'ad_300x250', 0, '1', 279, '0000-00-00 00:00:00'); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ads_placements` +-- + +CREATE TABLE IF NOT EXISTS `ads_placements` ( + `placement_id` int(20) NOT NULL AUTO_INCREMENT, + `placement` varchar(26) NOT NULL, + `placement_name` varchar(50) NOT NULL, + `disable` enum('yes','no') NOT NULL DEFAULT 'no', + PRIMARY KEY (`placement_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=9 ; + +-- +-- Dumping data for table `ads_placements` +-- + +INSERT INTO `ads_placements` (`placement_id`, `placement`, `placement_name`, `disable`) VALUES +(1, 'ad_160x600', 'Wide Skyscrapper 160 x 600', 'yes'), +(2, 'ad_468x60', 'Banner 468 x 60', 'yes'), +(3, 'ad_300x250', 'Medium Rectangle 300 x 250', 'yes'), +(4, 'ad_728x90', 'Leader Board 728 x 90', 'yes'), +(7, 'ad_120x600', 'Skyscrapper 120 x 600', 'yes'); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `category` +-- + +CREATE TABLE IF NOT EXISTS `category` ( + `categoryid` int(225) NOT NULL AUTO_INCREMENT, + `category_name` varchar(30) NOT NULL DEFAULT '', + `category_description` mediumtext NOT NULL, + `date_added` mediumtext NOT NULL, + `category_thumb` mediumtext NOT NULL, + PRIMARY KEY (`categoryid`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=34 ; + +-- +-- Dumping data for table `category` +-- + +INSERT INTO `category` (`categoryid`, `category_name`, `category_description`, `date_added`, `category_thumb`) VALUES +(27, 'Trailers', 'Trailers', '2008-01-17 18:20:15', 'no_thumb.jpg'), +(26, 'Animation', 'Animation', '2008-01-17 18:20:08', 'no_thumb.jpg'), +(20, 'Funny', 'Funny', '2008-01-02 02:02:34', '986bd05c18.jpg'), +(23, 'Sports', 'Sports', '2008-01-02 02:02:28', 'no_thumb.jpg'), +(28, 'How To', 'How To', '2008-01-17 18:20:21', 'no_thumb.jpg'); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `comments` +-- + +CREATE TABLE IF NOT EXISTS `comments` ( + `comment_id` int(60) NOT NULL AUTO_INCREMENT, + `type` enum('v','c') NOT NULL, + `comment` text NOT NULL, + `userid` int(60) NOT NULL, + `parent_id` int(60) NOT NULL, + `type_id` int(225) NOT NULL, + `vote` bigint(225) NOT NULL, + `voters` text NOT NULL, + `date_added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`comment_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; + +-- +-- Dumping data for table `comments` +-- + + +-- -------------------------------------------------------- + +-- +-- Table structure for table `config` +-- + +CREATE TABLE IF NOT EXISTS `config` ( + `configid` int(20) NOT NULL AUTO_INCREMENT, + `name` varchar(100) NOT NULL DEFAULT '', + `value` mediumtext NOT NULL, + PRIMARY KEY (`configid`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=68 ; + +-- +-- Dumping data for table `config` +-- + +INSERT INTO `config` (`configid`, `name`, `value`) VALUES +(1, 'site_title', 'ClipBucket v2'), +(2, 'site_slogan', 'A way to broadcast yourself'), +(3, 'baseurl', 'http://localhost/clipbucket/2.x/upload'), +(4, 'basedir', 'F:\\wamp\\www\\clipbucket\\2.x\\upload'), +(5, 'template_dir', 'clipbucketblue'), +(6, 'player_file', 'clipbucketblue.swf'), +(7, 'closed', '0'), +(8, 'closed_msg', 'We Are Updating Our Website, Please Visit us after few hours.'), +(9, 'description', 'Clip Bucket is an ultimate Video Sharing script'), +(10, 'keywords', 'clip bucket video sharing website script'), +(11, 'ffmpegpath', 'F:/wamp/bin/ffmpeg/ffmpeg.exe'), +(12, 'flvpath', ''), +(13, 'whatis', '

ClipBucket is the home for video online:

\r\n \r\n
  • Watch millions of videos
  • Share favorites with friends and family
  • Connect with other users who share your interests
  • Upload your videos to a worldwide audience
\r\n

Sign up now to join the ClipBucket community!

'), +(14, 'vbrate', '500000'), +(15, 'srate', '22050'), +(16, 'r_height', '240'), +(17, 'r_width', '300'), +(18, 'resize', 'yes'), +(19, 'mencoderpath', ''), +(45, 'user_comment_opt1', 'yes'), +(20, 'keep_original', '1'), +(21, 'activation', '0'), +(22, 'mplayerpath', ''), +(44, 'ffmpeg_type', 'd'), +(23, 'email_verification', '1'), +(24, 'allow_registeration', '1'), +(25, 'php_path', 'F:/wamp/bin/php/php5.2.9-1/php-win.exe'), +(26, 'videos_list_per_page', '24'), +(27, 'channels_list_per_page', '25'), +(28, 'videos_list_per_tab', '12'), +(29, 'channels_list_per_tab', '12'), +(30, 'video_comments', '1'), +(31, 'video_rating', '1'), +(32, 'comment_rating', '1'), +(33, 'video_download', '0'), +(34, 'video_embed', '1'), +(35, 'groups_list_per_page', '15'), +(36, 'seo', 'no'), +(37, 'admin_pages', '20'), +(38, 'search_list_per_page', '20'), +(39, 'recently_viewed_limit', '12'), +(40, 'max_upload_size', '100'), +(41, 'sbrate', '64000'), +(42, 'thumb_width', '120'), +(43, 'thumb_height', '90'), +(46, 'user_comment_opt2', ''), +(47, 'user_comment_opt3', ''), +(48, 'user_comment_opt4', ''), +(49, 'user_rate_opt1', 'yes'), +(50, 'captcha_type', '1'), +(51, 'allow_upload', 'yes'), +(52, 'allowed_types', 'wmv avi divx 3gp mov mpeg mpg xvid flv asf rm dat mp4'), +(53, 'version', '1.7.1'), +(54, 'version_type', 'SVN'), +(55, 'allow_template_change', '1'), +(56, 'allow_language_change', '1'), +(57, 'default_site_lang', 'en'), +(58, 'video_require_login', '0'), +(59, 'audio_codec', 'None'), +(60, 'con_modules_type', '0'), +(61, 'remoteUpload', ''), +(62, 'embedUpload', 'yes'), +(63, 'player_div_id', 'videoplayer'), +(64, 'code_dev', ' (Powered by ClipBucket)'), +(65, 'sys_os', 'win'), +(66, 'debug_level', '2'), +(67, 'enable_troubleshooter', '1'); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `contacts` +-- + +CREATE TABLE IF NOT EXISTS `contacts` ( + `contactid` int(11) NOT NULL AUTO_INCREMENT, + `username` varchar(20) NOT NULL, + `friend_username` varchar(20) NOT NULL, + `type` int(20) NOT NULL DEFAULT '1', + `status` enum('1','0') NOT NULL DEFAULT '0', + `date_added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`contactid`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; + +-- +-- Dumping data for table `contacts` +-- + + +-- -------------------------------------------------------- + +-- +-- Table structure for table `conversion_queue` +-- + +CREATE TABLE IF NOT EXISTS `conversion_queue` ( + `cqueue_id` int(11) NOT NULL AUTO_INCREMENT, + `cqueue_name` varchar(32) NOT NULL, + `cqueue_ext` varchar(5) NOT NULL, + `cqueue_tmp_ext` varchar(3) NOT NULL, + `cqueue_conversion` enum('yes','no','p') NOT NULL DEFAULT 'no', + `date_added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`cqueue_id`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; + +-- +-- Dumping data for table `conversion_queue` +-- + + +-- -------------------------------------------------------- + +-- +-- Table structure for table `countries` +-- + +CREATE TABLE IF NOT EXISTS `countries` ( + `id` int(11) NOT NULL, + `iso2` char(2) CHARACTER SET latin1 DEFAULT NULL, + `iso3` char(3) CHARACTER SET latin1 DEFAULT NULL, + `name_en` varchar(64) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `countries` +-- + +INSERT INTO `countries` (`id`, `iso2`, `iso3`, `name_en`) VALUES +(1, 'AF', 'AFG', 'Afghanistan'), +(4, 'DZ', 'DZA', 'Algeria'), +(3, 'AL', 'ALB', 'Albania'), +(5, 'AS', 'ASM', 'American Samoa'), +(6, 'AD', 'AND', 'Andorra'), +(7, 'AO', 'AGO', 'Angola'), +(8, 'AI', 'AIA', 'Anguilla'), +(9, 'AQ', 'ATA', 'Antarctica'), +(10, 'AG', 'ATG', 'Antigua and Barbuda'), +(11, 'AR', 'ARG', 'Argentina'), +(12, 'AM', 'ARM', 'Armenia'), +(13, 'AW', 'ABW', 'Aruba'), +(14, 'AU', 'AUS', 'Australia'), +(15, 'AT', 'AUT', 'Austria'), +(16, 'AZ', 'AZE', 'Azerbaijan'), +(17, 'BS', 'BHS', 'Bahamas'), +(18, 'BH', 'BHR', 'Bahrain'), +(19, 'BD', 'BGD', 'Bangladesh'), +(20, 'BB', 'BRB', 'Barbados'), +(21, 'BY', 'BLR', 'Belarus'), +(22, 'BE', 'BEL', 'Belgium'), +(23, 'BZ', 'BLZ', 'Belize'), +(24, 'BJ', 'BEN', 'Benin'), +(25, 'BM', 'BMU', 'Bermuda'), +(26, 'BT', 'BTN', 'Bhutan'), +(27, 'BO', 'BOL', 'Bolivia'), +(28, 'BA', 'BIH', 'Bosnia and Herzegovina'), +(29, 'BW', 'BWA', 'Botswana'), +(30, 'BV', 'BVT', 'Bouvet Island'), +(31, 'BR', 'BRA', 'Brazil'), +(32, 'IO', 'IOT', 'British Indian Ocean Territory'), +(33, 'BN', 'BRN', 'Brunei Darussalam'), +(34, 'BG', 'BGR', 'Bulgaria'), +(35, 'BF', 'BFA', 'Burkina Faso'), +(36, 'BI', 'BDI', 'Burundi'), +(37, 'KH', 'KHM', 'Cambodia'), +(38, 'CM', 'CMR', 'Cameroon'), +(39, 'CA', 'CAN', 'Canada'), +(40, 'CV', 'CPV', 'Cape Verde'), +(41, 'KY', 'CYM', 'Cayman Islands'), +(42, 'CF', 'CAF', 'Central African Republic'), +(43, 'TD', 'TCD', 'Chad'), +(44, 'CL', 'CHL', 'Chile'), +(45, 'CN', 'CHN', 'China'), +(46, 'CX', 'CXR', 'Christmas Island'), +(47, 'CC', 'CCK', 'Cocos Islands'), +(48, 'CO', 'COL', 'Colombia'), +(49, 'KM', 'COM', 'Comoros'), +(50, 'CG', 'COG', 'Congo, Republic Of'), +(52, 'CK', 'COK', 'Cook Islands'), +(53, 'CR', 'CRI', 'Costa Rica'), +(55, 'HR', 'HRV', 'Croatia'), +(56, 'CU', 'CUB', 'Cuba'), +(57, 'CY', 'CYP', 'Cyprus'), +(58, 'CZ', 'CZE', 'Czech Republic'), +(59, 'DK', 'DNK', 'Denmark'), +(60, 'DJ', 'DJI', 'Djibouti'), +(61, 'DM', 'DMA', 'Dominica'), +(62, 'DO', 'DOM', 'Dominican Republic'), +(63, 'EC', 'ECU', 'Ecuador'), +(64, 'EG', 'EGY', 'Egypt'), +(65, 'SV', 'SLV', 'El Salvador'), +(66, 'GQ', 'GNQ', 'Equatorial Guinea'), +(67, 'ER', 'ERI', 'Eritrea'), +(68, 'EE', 'EST', 'Estonia'), +(69, 'ET', 'ETH', 'Ethiopia'), +(70, 'FO', 'FRO', 'Faeroe Islands'), +(71, 'FK', 'FLK', 'Falkland Islands'), +(72, 'FJ', 'FJI', 'Fiji'), +(73, 'FI', 'FIN', 'Finland'), +(74, 'FR', 'FRA', 'France'), +(75, 'GF', 'GUF', 'French Guiana'), +(76, 'PF', 'PYF', 'French Polynesia'), +(78, 'GA', 'GAB', 'Gabon'), +(79, 'GM', 'GMB', 'Gambia, The'), +(80, 'GE', 'GEO', 'Georgia'), +(81, 'DE', 'DEU', 'Germany'), +(82, 'GH', 'GHA', 'Ghana'), +(83, 'GI', 'GIB', 'Gibraltar'), +(84, 'GB', 'GBR', 'Great Britain'), +(85, 'GR', 'GRC', 'Greece'), +(86, 'GL', 'GRL', 'Greenland'), +(87, 'GD', 'GRD', 'Grenada'), +(88, 'GP', 'GLP', 'Guadeloupe'), +(89, 'GU', 'GUM', 'Guam'), +(90, 'GT', 'GTM', 'Guatemala'), +(91, 'GN', 'GIN', 'Guinea'), +(92, 'GW', 'GNB', 'Guinea-bissau'), +(93, 'GY', 'GUY', 'Guyana'), +(94, 'HT', 'HTI', 'Haiti'), +(95, 'HM', 'HMD', 'Heard Island'), +(96, 'HN', 'HND', 'Honduras'), +(97, 'HK', 'HKG', 'Hong Kong'), +(98, 'HU', 'HUN', 'Hungary'), +(99, 'IS', 'ISL', 'Iceland'), +(100, 'IN', 'IND', 'India'), +(101, 'ID', 'IDN', 'Indonesia'), +(102, 'IR', 'IRN', 'Iran'), +(103, 'IQ', 'IRQ', 'Iraq'), +(104, 'IE', 'IRL', 'Ireland'), +(105, 'IL', 'ISR', 'Israel'), +(106, 'IT', 'ITA', 'Italy'), +(107, 'JM', 'JAM', 'Jamaica'), +(108, 'JP', 'JPN', 'Japan'), +(109, 'JO', 'JOR', 'Jordan'), +(110, 'KZ', 'KAZ', 'Kazakhstan'), +(111, 'KE', 'KEN', 'Kenya'), +(112, 'KI', 'KIR', 'Kiribati'), +(113, 'KP', 'PRK', 'Korea'), +(114, 'KR', 'KOR', 'Korea'), +(115, 'KW', 'KWT', 'Kuwait'), +(116, 'KG', 'KGZ', 'Kyrgyzstan'), +(117, 'LA', 'LAO', 'Lao'), +(118, 'LV', 'LVA', 'Latvia'), +(119, 'LB', 'LBN', 'Lebanon'), +(120, 'LS', 'LSO', 'Lesotho'), +(121, 'LR', 'LBR', 'Liberia'), +(122, 'LY', 'LBY', 'Libya'), +(124, 'LT', 'LTU', 'Lithuania'), +(125, 'LU', 'LUX', 'Luxembourg'), +(128, 'MG', 'MDG', 'Madagascar'), +(129, 'MW', 'MWI', 'Malawi'), +(130, 'MY', 'MYS', 'Malaysia'), +(131, 'MV', 'MDV', 'Maldives'), +(132, 'ML', 'MLI', 'Mali'), +(133, 'MT', 'MLT', 'Malta'), +(134, 'MH', 'MHL', 'Marshall Islands'), +(135, 'MQ', 'MTQ', 'Martinique'), +(136, 'MR', 'MRT', 'Mauritania'), +(137, 'MU', 'MUS', 'Mauritius'), +(138, 'YT', 'MYT', 'Mayotte'), +(139, 'MX', 'MEX', 'Mexico'), +(141, 'MD', 'MDA', 'Moldova'), +(142, 'MC', 'MCO', 'Monaco'), +(143, 'MN', 'MNG', 'Mongolia'), +(144, 'MS', 'MSR', 'Montserrat'), +(145, 'MA', 'MAR', 'Morocco'), +(147, 'MM', 'MMR', 'Myanmar '), +(148, 'NA', 'NAM', 'Namibia'), +(149, 'NR', 'NRU', 'Nauru'), +(150, 'NP', 'NPL', 'Nepal'), +(151, 'NL', 'NLD', 'Netherlands'), +(152, 'AN', 'ANT', 'Netherlands Antilles'), +(153, 'NC', 'NCL', 'New Caledonia'), +(154, 'NZ', 'NZL', 'New Zealand'), +(155, 'NI', 'NIC', 'Nicaragua'), +(156, 'NE', 'NER', 'Niger'), +(157, 'NG', 'NGA', 'Nigeria'), +(158, 'NU', 'NIU', 'Niue'), +(159, 'NF', 'NFK', 'Norfolk Island'), +(160, 'MP', 'MNP', 'Northern Mariana Islands'), +(161, 'NO', 'NOR', 'Norway'), +(162, 'OM', 'OMN', 'Oman'), +(163, 'PK', 'PAK', 'Pakistan'), +(164, 'PW', 'PLW', 'Palau'), +(165, 'PS', 'PSE', 'Palestinian Territories'), +(166, 'PA', 'PAN', 'Panama'), +(167, 'PG', 'PNG', 'Papua New Guinea'), +(168, 'PY', 'PRY', 'Paraguay'), +(169, 'PE', 'PER', 'Peru'), +(170, 'PH', 'PHL', 'Philippines'), +(171, 'PN', 'PCN', 'Pitcairn'), +(172, 'PL', 'POL', 'Poland'), +(173, 'PT', 'PRT', 'Portugal'), +(174, 'PR', 'PRI', 'Puerto Rico'), +(175, 'QA', 'QAT', 'Qatar'), +(177, 'RO', 'ROU', 'Romania'), +(178, 'RU', 'RUS', 'Russian Federation'), +(179, 'RW', 'RWA', 'Rwanda'), +(180, 'SH', 'SHN', 'Saint Helena'), +(181, 'KN', 'KNA', 'Saint Kitts and Nevis'), +(182, 'LC', 'LCA', 'Saint Lucia'), +(183, 'PM', 'SPM', 'Saint Pierre and Miquelon'), +(184, 'VC', 'VCT', 'Saint Vincent '), +(185, 'WS', 'WSM', 'Samoa '), +(186, 'SM', 'SMR', 'San Marino'), +(187, 'ST', 'STP', 'Sao Tome and Principe'), +(188, 'SA', 'SAU', 'Saudi Arabia'), +(189, 'SN', 'SEN', 'Senegal'), +(190, 'CS', 'SCG', 'Serbia and Montenegro '), +(191, 'SC', 'SYC', 'Seychelles'), +(192, 'SL', 'SLE', 'Sierra Leone'), +(193, 'SG', 'SGP', 'Singapore'), +(194, 'SK', 'SVK', 'Slovakia '), +(195, 'SI', 'SVN', 'Slovenia'), +(196, 'SB', 'SLB', 'Solomon Islands'), +(197, 'SO', 'SOM', 'Somalia'), +(198, 'ZA', 'ZAF', 'South Africa'), +(199, 'GS', 'SGS', 'South Georgia'), +(200, 'ES', 'ESP', 'Spain'), +(201, 'LK', 'LKA', 'Sri Lanka'), +(202, 'SD', 'SDN', 'Sudan'), +(203, 'SR', 'SUR', 'Suriname'), +(204, 'SJ', 'SJM', 'Svalbard and Jan Mayen'), +(205, 'SZ', 'SWZ', 'Swaziland'), +(206, 'SE', 'SWE', 'Sweden'), +(207, 'CH', 'CHE', 'Switzerland'), +(208, 'SY', 'SYR', 'Syrian Arab Republic'), +(209, 'TW', 'TWN', 'Taiwan'), +(210, 'TJ', 'TJK', 'Tajikistan'), +(211, 'TZ', 'TZA', 'Tanzania'), +(212, 'TH', 'THA', 'Thailand'), +(213, 'TL', 'TLS', 'Timor-Leste'), +(214, 'TG', 'TGO', 'Togo'), +(215, 'TK', 'TKL', 'Tokelau'), +(216, 'TO', 'TON', 'Tonga'), +(217, 'TT', 'TTO', 'Trinidad and Tobago'), +(218, 'TN', 'TUN', 'Tunisia'), +(219, 'TR', 'TUR', 'Turkey'), +(220, 'TM', 'TKM', 'Turkmenistan'), +(221, 'TC', 'TCA', 'Turks and Caicos Islands'), +(222, 'TV', 'TUV', 'Tuvalu'), +(223, 'UG', 'UGA', 'Uganda'), +(224, 'UA', 'UKR', 'Ukraine'), +(225, 'AE', 'ARE', 'United Arab Emirates'), +(226, 'GB', 'GBR', 'United Kingdom'), +(227, 'US', 'USA', 'United States'), +(229, 'UY', 'URY', 'Uruguay'), +(230, 'UZ', 'UZB', 'Uzbekistan'), +(231, 'VU', 'VUT', 'Vanuatu'), +(232, 'VA', 'VAT', 'Vatican City'), +(233, 'VE', 'VEN', 'Venezuela'), +(234, 'VN', 'VNM', 'Viet Nam'), +(235, 'VG', 'VGB', 'Virgin Islands, British'), +(236, 'VI', 'VIR', 'Virgin Islands, U.S.'), +(237, 'WF', 'WLF', 'Wallis and Futuna'), +(238, 'EH', 'ESH', 'Western Sahara'), +(239, 'YE', 'YEM', 'Yemen'), +(240, 'ZM', 'ZMB', 'Zambia'), +(241, 'ZW', 'ZWE', 'Zimbabwe'); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `editors_picks` +-- + +CREATE TABLE IF NOT EXISTS `editors_picks` ( + `pick_id` int(225) NOT NULL AUTO_INCREMENT, + `videokey` mediumtext NOT NULL, + `sort` bigint(5) NOT NULL DEFAULT '1', + `date_added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `status` enum('0','1') NOT NULL DEFAULT '1', + PRIMARY KEY (`pick_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; + +-- +-- Dumping data for table `editors_picks` +-- + + +-- -------------------------------------------------------- + +-- +-- Table structure for table `email_settings` +-- + +CREATE TABLE IF NOT EXISTS `email_settings` ( + `email_settings_id` int(25) NOT NULL AUTO_INCREMENT, + `email_settings_name` varchar(60) NOT NULL, + `email_settings_value` mediumtext NOT NULL, + `email_settings_headers` mediumtext NOT NULL, + PRIMARY KEY (`email_settings_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=9 ; + +-- +-- Dumping data for table `email_settings` +-- + +INSERT INTO `email_settings` (`email_settings_id`, `email_settings_name`, `email_settings_value`, `email_settings_headers`) VALUES +(1, 'website_email', 'email@example.com', ''), +(2, 'support_email', 'support@example.com', ''), +(3, 'welcome_email', 'no-reply@example.com', ''), +(4, 'email_verification_template', 'Hello $username,\r\nThank For Joining Us, Your Account Details are\r\n\r\nUsername : $username\r\nPassword : $password\r\nEmail : $email\r\nDate Joined : $cur_date\r\n\r\nYour Account Is Inactive Please Activate it by using following link \r\n\r\nClick Here\r\n\r\n$baseurl/activation.php?username=$username&avcode=$avcode\r\n\r\n====================\r\nRegards\r\n$title', '$uname''s Account Activation'), +(5, 'welcome_message_template', 'Hello $username, Welcome to $title.\r\nYou are now our member, you can now\r\n\r\n-> Upload Videos\r\n-> Share Videos\r\n-> Make Friends and Send Messeges\r\n-> Now You Have Your Own Channel\r\n\r\nTo Access Your Account Please Click Here and login\r\n\r\nThank You For Joining Us,\r\nRegards\r\n$title Team', 'Welcome $username to $title'), +(6, 'activate_request_template', 'Hello $username,\r\n\r\nYour Activation Code is : $avcode\r\nClick Here To Goto Activation Page\r\n\r\nDirect Activation\r\n==========================================\r\nClick Here or Copy & Paste the following link in your browser\r\n$baseurl/activation.php?username=$username&avcode=$avcode\r\n', '$username''s Account Activation'), +(7, 'share_video_template', '\r\n\r\n\r\n\r\n\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
$titleshare video
$username wants to share Video With You
Video Description
\r\n $videodes
Personal Messege
\r\n $messege\r\n
\r\n
\r\nThanks,
\r\n$username
copyrights 2007 $title
\r\n\r\n', '$username Want To Share A Video With You'), +(8, 'share_picture_template', '\r\n\r\n\r\n\r\n\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
$titleshare Picture
$username wants to share Picture With You\r\n
Picture Description
\r\n $picdes
Personal Messege
\r\n $messege\r\n
\r\n
\r\nThanks,
\r\n$username
copyrights 2007 $title
\r\n\r\n', '$username Want To Share A Picture With You'); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `flagged_videos` +-- + +CREATE TABLE IF NOT EXISTS `flagged_videos` ( + `flagged_id` int(11) NOT NULL AUTO_INCREMENT, + `videoid` int(11) NOT NULL, + `username` varchar(20) NOT NULL, + `date_added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`flagged_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; + +-- +-- Dumping data for table `flagged_videos` +-- + + +-- -------------------------------------------------------- + +-- +-- Table structure for table `groups` +-- + +CREATE TABLE IF NOT EXISTS `groups` ( + `group_id` int(225) NOT NULL AUTO_INCREMENT, + `group_name` mediumtext NOT NULL, + `group_description` mediumtext NOT NULL, + `group_tags` mediumtext NOT NULL, + `group_url` mediumtext NOT NULL, + `group_category` int(20) NOT NULL, + `group_type` enum('0','1','2') NOT NULL DEFAULT '0', + `video_type` enum('0','1','2') NOT NULL DEFAULT '0', + `post_type` enum('0','1','2') NOT NULL DEFAULT '0', + `active` enum('yes','no') NOT NULL DEFAULT 'yes', + `date_added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `username` varchar(26) NOT NULL, + `userid` int(11) NOT NULL, + `featured` enum('yes','no') NOT NULL DEFAULT 'no', + `group_thumb` mediumtext NOT NULL, + `total_videos` int(225) NOT NULL, + `total_members` int(225) NOT NULL, + `total_topics` int(225) NOT NULL, + PRIMARY KEY (`group_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; + +-- +-- Dumping data for table `groups` +-- + + +-- -------------------------------------------------------- + +-- +-- Table structure for table `group_invitations` +-- + +CREATE TABLE IF NOT EXISTS `group_invitations` ( + `invitation_id` int(225) NOT NULL AUTO_INCREMENT, + `group_id` int(225) NOT NULL, + `invited_user` varchar(16) NOT NULL, + `invited_by` varchar(16) NOT NULL, + `date_added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`invitation_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; + +-- +-- Dumping data for table `group_invitations` +-- + + +-- -------------------------------------------------------- + +-- +-- Table structure for table `group_members` +-- + +CREATE TABLE IF NOT EXISTS `group_members` ( + `group_mid` int(225) NOT NULL AUTO_INCREMENT, + `group_id` int(225) NOT NULL, + `username` varchar(26) NOT NULL, + `userid` int(11) NOT NULL, + `date_added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `active` enum('yes','no') NOT NULL DEFAULT 'yes', + PRIMARY KEY (`group_mid`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; + +-- +-- Dumping data for table `group_members` +-- + + +-- -------------------------------------------------------- + +-- +-- Table structure for table `group_posts` +-- + +CREATE TABLE IF NOT EXISTS `group_posts` ( + `post_id` int(225) NOT NULL AUTO_INCREMENT, + `topic_id` int(225) NOT NULL, + `post` mediumtext NOT NULL, + `username` varchar(26) NOT NULL, + `userid` int(11) NOT NULL, + `reply_to` int(225) NOT NULL, + `date_added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`post_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; + +-- +-- Dumping data for table `group_posts` +-- + + +-- -------------------------------------------------------- + +-- +-- Table structure for table `group_topics` +-- + +CREATE TABLE IF NOT EXISTS `group_topics` ( + `topic_id` int(225) NOT NULL AUTO_INCREMENT, + `topic_title` mediumtext NOT NULL, + `group_id` int(225) NOT NULL, + `date_added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `last_reply` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + `username` varchar(26) NOT NULL, + `userid` int(11) NOT NULL, + `videokey` mediumtext NOT NULL, + `approved` enum('yes','no') NOT NULL DEFAULT 'yes', + PRIMARY KEY (`topic_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; + +-- +-- Dumping data for table `group_topics` +-- + + +-- -------------------------------------------------------- + +-- +-- Table structure for table `group_videos` +-- + +CREATE TABLE IF NOT EXISTS `group_videos` ( + `group_vid` int(225) NOT NULL AUTO_INCREMENT, + `videokey` mediumtext NOT NULL, + `group_id` int(225) NOT NULL, + `username` varchar(26) NOT NULL, + `userid` int(11) NOT NULL, + `date_added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `approved` enum('yes','no') NOT NULL, + PRIMARY KEY (`group_vid`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; + +-- +-- Dumping data for table `group_videos` +-- + + +-- -------------------------------------------------------- + +-- +-- Table structure for table `languages` +-- + +CREATE TABLE IF NOT EXISTS `languages` ( + `language_id` int(9) NOT NULL AUTO_INCREMENT, + `language_code` varchar(8) COLLATE utf8_unicode_ci NOT NULL DEFAULT '', + `language_name` varchar(20) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0', + `language_regex` varchar(64) COLLATE utf8_unicode_ci NOT NULL, + `language_default` enum('yes','no') COLLATE utf8_unicode_ci NOT NULL, + PRIMARY KEY (`language_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=3 ; + +-- +-- Dumping data for table `languages` +-- + +INSERT INTO `languages` (`language_id`, `language_code`, `language_name`, `language_regex`, `language_default`) VALUES +(2, 'en', 'English', '/^en/i', 'no'); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `messages` +-- + +CREATE TABLE IF NOT EXISTS `messages` ( + `message_id` int(225) NOT NULL AUTO_INCREMENT, + `inbox_user` varchar(20) NOT NULL, + `outbox_user` varchar(20) NOT NULL, + `message` mediumtext NOT NULL, + `type` enum('1') NOT NULL DEFAULT '1', + `attachment_type` enum('1') NOT NULL DEFAULT '1', + `attachment` mediumtext NOT NULL, + `date_added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `subject` varchar(70) NOT NULL, + `status` enum('0','1') NOT NULL DEFAULT '0', + `reply_to` int(225) NOT NULL DEFAULT '0', + `reciever` varchar(20) NOT NULL, + `sender` varchar(20) NOT NULL, + `inbox_user_id` int(11) NOT NULL, + `outbox_user_id` int(11) NOT NULL, + `sender_id` int(11) NOT NULL, + `reciever_id` int(11) NOT NULL, + PRIMARY KEY (`message_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; + +-- +-- Dumping data for table `messages` +-- + + +-- -------------------------------------------------------- + +-- +-- Table structure for table `modules` +-- + +CREATE TABLE IF NOT EXISTS `modules` ( + `module_id` int(25) NOT NULL AUTO_INCREMENT, + `module_name` varchar(25) NOT NULL, + `module_file` varchar(60) NOT NULL, + `active` varchar(5) NOT NULL, + `module_include_file` text NOT NULL, + PRIMARY KEY (`module_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=11 ; + +-- +-- Dumping data for table `modules` +-- + +INSERT INTO `modules` (`module_id`, `module_name`, `module_file`, `active`, `module_include_file`) VALUES +(7, 'flash_recent_videos', 'flash_recent_videos.instructions.php', 'yes', ''), +(8, 'editors_pick_player', 'editors_pick_player.instructions.php', 'yes', ''), +(9, 'recently_viewd_2', 'recently_viewd_2.instructions.php', 'yes', ''), +(10, 'lightoff', 'lightoff.instructions.php', 'yes', 'lightoff/lightoff.html'); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `phrases` +-- + +CREATE TABLE IF NOT EXISTS `phrases` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `lang_iso` varchar(2) CHARACTER SET utf8 NOT NULL DEFAULT 'en', + `varname` varchar(250) CHARACTER SET utf8 NOT NULL DEFAULT '', + `text` text COLLATE utf8_unicode_ci, + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=756 ; + +-- +-- Dumping data for table `phrases` +-- + +INSERT INTO `phrases` (`id`, `lang_iso`, `varname`, `text`) VALUES +(507, 'en', 'grp_add_vdo_msg', 'Add Videos To Group '), +(2, 'en', 'ad_name_error', 'Error : Please Enter Name For The Advertisment'), +(3, 'en', 'ad_code_error', 'Error : Please Enter Code For Advertisement'), +(4, 'en', 'ad_exists_error1', 'Error : Advertisment Doesn’t Exists'), +(5, 'en', 'ad_exists_error2', 'Error : Advertisement With This Name Already Exists'), +(6, 'en', 'ad_add_msg', 'Advertisment Has Been Added'), +(7, 'en', 'ad_msg', 'Ad Has Been '), +(8, 'en', 'ad_update_msg', 'Advertisment Has Been Updated'), +(9, 'en', 'ad_del_msg', 'Advertisement Has Been Deleted'), +(10, 'en', 'ad_deactive', 'Deactivated'), +(11, 'en', 'ad_active', 'Activated'), +(12, 'en', 'ad_placment_delete_msg', 'Placement Has Been Removed'), +(13, 'en', 'ad_placement_err1', 'Placement Already Exist'), +(14, 'en', 'ad_placement_err2', 'Please Enter Name For Placement'), +(15, 'en', 'ad_placement_err3', 'Please Enter Code For Placement'), +(16, 'en', 'ad_placement_msg', 'Placement Has Been Added'), +(17, 'en', 'cat_img_error', 'Please Upload JPEG, GIF or PNG image only'), +(18, 'en', 'cat_exist_error', 'Category Doesn’t Exist'), +(19, 'en', 'cat_add_msg', 'Category Has Been Added Successfully'), +(20, 'en', 'cat_update_msg', 'Category Has Been Updated'), +(21, 'en', 'grp_err', 'Group Doesn’t Exist'), +(22, 'en', 'grp_fr_msg', 'Group Has Been Set to Featured'), +(23, 'en', 'grp_fr_msg1', 'Selected Groups Have Been Removed From The Featured List'), +(24, 'en', 'grp_ac_msg', 'Selected Groups Have Been Activated'), +(25, 'en', 'grp_dac_msg', 'Selected Groups Have Been Dectivated'), +(26, 'en', 'grp_del_msg', 'Group Has Been Delete'), +(27, 'en', 'editor_pic_up', 'Video Has Been Moved Up'), +(28, 'en', 'editor_pic_down', 'Video Has Been Moved Down'), +(29, 'en', 'plugin_install_msg', 'Plugin has been installed'), +(30, 'en', 'plugin_no_file_err', 'No file was found'), +(31, 'en', 'plugin_file_detail_err', 'Unknown plugin details found'), +(32, 'en', 'plugin_installed_err', 'Plugin already installed'), +(33, 'en', 'plugin_no_install_err', 'Plugin is not installed'), +(34, 'en', 'grp_name_error', 'Please Enter Name For Group'), +(35, 'en', 'grp_name_error1', 'Group Name Already Exists'), +(36, 'en', 'grp_des_error', 'Please Enter Little Description For Group'), +(37, 'en', 'grp_tags_error', 'Please Enter Tags For Group'), +(38, 'en', 'grp_url_error', 'Please Enter URL For Group”'), +(39, 'en', 'grp_url_error1', 'Please enter Valid URL name'), +(40, 'en', 'grp_url_error2', 'Group URL Already Exists, Please Choose a Different URL'), +(41, 'en', 'grp_tpc_error', 'Please enter a topic to add'), +(42, 'en', 'grp_comment_error', 'You Must Enter A Comment'), +(43, 'en', 'grp_join_error', 'You Have Already Joined This Group'), +(44, 'en', 'grp_prvt_error', 'This Group Is Private, Please Login to View this Group'), +(45, 'en', 'grp_inact_error', 'This Group Is Inactive, Please Contact Administrator for the problem'), +(46, 'en', 'grp_join_error1', 'You Have Not Joined This Group Yet'), +(47, 'en', 'grp_exist_error', 'Sorry, Group Doesn’t Exist'), +(48, 'en', 'grp_tpc_error1', 'This Topic Is Not Approved By The Group Owner'), +(49, 'en', 'grp_cat_error', 'Please Select A Category For Your group'), +(50, 'en', 'grp_tpc_error2', 'Please enter topic to add'), +(51, 'en', 'grp_tpc_error3', 'Your Topic Requires Approval From Owner Of This Group'), +(52, 'en', 'grp_tpc_msg', 'Topic Has Been Added'), +(53, 'en', 'grp_comment_msg', 'Comment Has Been Added'), +(54, 'en', 'grp_vdo_msg', 'Videos Have Been Deleted'), +(55, 'en', 'grp_vdo_msg1', 'Videos Has Been Added Successfully'), +(56, 'en', 'grp_vdo_msg2', 'Videos Have Been Approved'), +(57, 'en', 'grp_mem_msg', 'Member Has Been Deleted'), +(58, 'en', 'grp_mem_msg1', 'Member Has Been Approved'), +(59, 'en', 'grp_inv_msg', 'Your Invitation Has Been Sent'), +(60, 'en', 'grp_tpc_msg1', 'Topic Has Been Delete'), +(61, 'en', 'grp_tpc_msg2', 'Topic Has Been Approved'), +(62, 'en', 'grp_fr_msg2', 'Group Has Been Set to UnFeatured'), +(63, 'en', 'grp_inv_msg1', 'Has Invited You To Join '), +(64, 'en', 'grp_av_msg', 'Group Has Been Activated'), +(65, 'en', 'grp_da_msg', 'Group Has Been DeActivated'), +(66, 'en', 'grp_post_msg', 'Post Has Been Delete'), +(67, 'en', 'grp_update_msg', 'Group Has Been Updated'), +(68, 'en', 'grp_owner_err', 'Only Owner Can Add Videos To This Group'), +(69, 'en', 'grp_owner_err1', 'You Are Not Group Owner'), +(70, 'en', 'grp_owner_err2', 'You Are Group Owner , You Cannot Leave Your Group'), +(71, 'en', 'grp_prvt_err1', 'This Group is Private, You require an Invitation from group Owner'), +(72, 'en', 'grp_rmv_msg', 'Selected Groups Have Been Removed From Your Account'), +(73, 'en', 'grp_tpc_err4', 'Sorry, Topic Doesn’t Exist'), +(74, 'en', 'grp_title_topic', 'Groups - Topic - '), +(75, 'en', 'grp_add_title', '- Add Video'), +(76, 'en', 'usr_sadmin_err', 'You Cannot Set SuperAdmin Username as Blank'), +(77, 'en', 'usr_cpass_err', 'Confirm Password Doesn’t Match'), +(78, 'en', 'usr_pass_err', 'Old Password Is Incorrect'), +(79, 'en', 'usr_email_err', 'Please Provide A Valid Email Address'), +(80, 'en', 'usr_cpass_err1', 'Confirm Password Is Incorrect'), +(81, 'en', 'usr_pass_err1', 'Password is Incorrect'), +(82, 'en', 'usr_cmt_err', 'You Must Login First To Comment'), +(83, 'en', 'usr_cmt_err1', 'Please Type Something In Comment Box'), +(84, 'en', 'usr_cmt_err2', 'You Cannot Post Comment on Your Own Video'), +(85, 'en', 'usr_cmt_err3', 'You Have Already Posted a Comment on this channel.'), +(86, 'en', 'usr_cmt_err4', 'Comment Has Been Added'), +(87, 'en', 'usr_cmt_del_msg', 'Comment Has Been Deleted'), +(88, 'en', 'usr_cmt_del_err', 'An Error Occured While deleting a Comment'), +(89, 'en', 'usr_cnt_err', 'You Cannot Add Yourself as a Contact'), +(90, 'en', 'usr_cnt_err1', 'You Have Already Added This User To Your Contact List'), +(91, 'en', 'usr_sub_err', 'You Have Already Subscribed To '), +(92, 'en', 'usr_exist_err', 'User Doesnt Exist'), +(93, 'en', 'usr_ccode_err', 'You Have Entered Wrong Confirmation Code'), +(94, 'en', 'usr_exist_err1', 'Sorry, No User Exists With This Email'), +(95, 'en', 'usr_exist_err2', 'Sorry , User Doesnt Exists'), +(96, 'en', 'usr_uname_err', 'Username is Empty'), +(97, 'en', 'usr_uname_err2', 'Username Already Exists'), +(98, 'en', 'usr_pass_err2', 'Password Is Empty'), +(99, 'en', 'usr_email_err1', 'Email is Empty'), +(100, 'en', 'usr_email_err2', 'Please Enter A Valid Email Address'), +(101, 'en', 'usr_email_err3', 'Email Address Is Already In Use'), +(102, 'en', 'usr_pcode_err', 'Postal Code Only Contains Number'), +(103, 'en', 'usr_fname_err', 'First Name Is Empty'), +(104, 'en', 'usr_lname_err', 'Last Name Is Empty'), +(105, 'en', 'usr_uname_err3', 'Username Contains Unallowed Characters'), +(106, 'en', 'usr_pass_err3', 'Passwords MisMatched'), +(107, 'en', 'usr_dob_err', 'Please Select Date Of Birth'), +(108, 'en', 'usr_ament_err', 'Sorry, you need to agree to the terms of use and privacy policy to create an account'), +(109, 'en', 'usr_reg_err', 'Sorry, Registrations Are Temporarily Not Allowed, Please Try Again Later'), +(110, 'en', 'usr_ban_err', 'User Account Banned.Contact the Site Administrator for further details.'), +(111, 'en', 'usr_login_err', 'Username Password Didn’t Match'), +(112, 'en', 'usr_sadmin_msg', 'Super Admin Has Been Updated'), +(113, 'en', 'usr_pass_msg', 'Your Password Has Been Changed'), +(114, 'en', 'usr_cnt_msg', 'This User Has Been Added To Your Contact List'), +(115, 'en', 'usr_sub_msg', 'You Have Subscribed To '), +(116, 'en', 'usr_uname_email_msg', 'We Have Sent you an Email containing Your Usename, Please Check It'), +(117, 'en', 'usr_rpass_email_msg', 'Email Has Sent To You Please Follow the Instructions to Reset Your Password'), +(118, 'en', 'usr_pass_email_msg', 'Your Password Has Been Changed, Please Check You Inbox For Your New Password'), +(119, 'en', 'usr_email_msg', 'Email Settings Has Been Updated'), +(120, 'en', 'usr_del_msg', 'User Has Been Deleted Successfully'), +(121, 'en', 'usr_dels_msg', 'Selected Users Have Been Deleted'), +(122, 'en', 'usr_ac_msg', 'User Has Been Activated'), +(123, 'en', 'usr_dac_msg', 'User Has Been Deactivated'), +(124, 'en', 'usr_mem_ac', 'Selected Members Have Been Activated'), +(125, 'en', 'usr_mems_ac', 'Selected Members Have Been Dectivated'), +(126, 'en', 'usr_fr_msg', 'User Has Been Made Featured Member'), +(127, 'en', 'usr_ufr_msg', 'User Has Been Unfeatured'), +(128, 'en', 'usr_frs_msg', 'Selected Users Have Been Set As Featured'), +(129, 'en', 'usr_ufrs_msg', 'Selected Users Have Been Removed From The Featured List'), +(130, 'en', 'usr_uban_msg', 'User Has Been Banned'), +(131, 'en', 'usr_uuban_msg', 'User Has Been Unbanned'), +(132, 'en', 'usr_ubans_msg', 'Selected Members Have Been Banned'), +(133, 'en', 'usr_uubans_msg', 'Selected Members Have Been Unbanned'), +(134, 'en', 'usr_pass_reset_conf', 'Password Reset Confirmation'), +(135, 'en', 'usr_dear_user', 'Dear User'), +(136, 'en', 'usr_pass_reset_msg', 'You Requested A Password Reset, Follow The Link To Reset Your Password'), +(137, 'en', 'usr_rpass_msg', 'Password Has Been Reset'), +(138, 'en', 'usr_rpass_req_msg', 'You Requested A Password Reset, Here is your new password : '), +(139, 'en', 'usr_uname_req_msg', 'You Requested to Recover Your Username, Here is you username: '), +(140, 'en', 'usr_uname_recovery', 'Username Recovery Email'), +(141, 'en', 'usr_add_succ_msg', 'User Has Been Added, Successfully'), +(142, 'en', 'usr_upd_succ_msg', 'User Has Been Updated, Successfully'), +(143, 'en', 'usr_activation_msg', 'your account has been activated, Now you can login to your account and upload videos'), +(144, 'en', 'usr_activation_err', 'Sorry This User either has been already Activated or Username and activation code is WRONG'), +(145, 'en', 'usr_activation_em_msg', 'Activation Code Has Been Sent To Your Mail Box, Please Check It'), +(146, 'en', 'usr_activation_em_err', 'Email Doesn’t Exist or User With This Email already Acitvated'), +(147, 'en', 'usr_no_msg_del_err', 'No Message Was Selected To Delete'), +(148, 'en', 'usr_sel_msg_del_msg', 'Selected Messages Have Been Deleted'), +(149, 'en', 'usr_pof_upd_msg', 'Profile Has Been Updated'), +(150, 'en', 'usr_arr_no_ans', 'no answer'), +(151, 'en', 'usr_arr_elementary', 'Elementary'), +(152, 'en', 'usr_arr_hi_school', 'High School'), +(153, 'en', 'usr_arr_some_colg', 'Some College'), +(154, 'en', 'usr_arr_assoc_deg', 'Associates Degree'), +(155, 'en', 'usr_arr_bach_deg', 'Bachelor’s Degree'), +(156, 'en', 'usr_arr_mast_deg', 'Master’s Degree'), +(157, 'en', 'usr_arr_phd', 'Ph.D.'), +(158, 'en', 'usr_arr_post_doc', 'Postdoctoral'), +(159, 'en', 'usr_arr_single', 'Single'), +(160, 'en', 'usr_arr_married', 'Married'), +(161, 'en', 'usr_arr_comitted', 'Comitted'), +(162, 'en', 'usr_arr_open_marriage', 'open marriage'), +(163, 'en', 'usr_arr_open_relate', 'open relationship'), +(164, 'en', 'title_crt_new_msg', ' - Create New Message'), +(165, 'en', 'title_forgot', 'Forgot Something? Find it now !'), +(166, 'en', 'title_inbox', ' - Inbox'), +(167, 'en', 'title_sent', ' - Sent Folder'), +(168, 'en', 'title_usr_contact', '’s Contact List'), +(169, 'en', 'title_usr_fav_vids', '’s Favourite Videos'), +(170, 'en', 'title_view_channel', '’s Channel'), +(171, 'en', 'title_edit_video', 'Edit Video - '), +(172, 'en', 'vdo_title_err', 'Please Enter Video Title'), +(173, 'en', 'vdo_des_err', 'Please Enter Video Description'), +(174, 'en', 'vdo_tags_err', 'Please Enter Tags For The Video'), +(175, 'en', 'vdo_cat_err', 'Please Choose Atleast 1 Category'), +(176, 'en', 'vdo_cat_err1', 'You Can Only Choose Upto 3 Categories'), +(177, 'en', 'vdo_sub_email_msg', ' and therefore this message is sent to you automatically that '), +(178, 'en', 'vdo_has_upload_nv', 'Has Uploaded New Video'), +(179, 'en', 'vdo_del_selected', 'Selected Videos Have Been Deleted'), +(180, 'en', 'vdo_cheat_msg', 'Please Dont Try To Cheat'), +(181, 'en', 'vdo_limits_warn_msg', 'Please Dont Try To Cross Your Limits'), +(182, 'en', 'vdo_cmt_del_msg', 'Comment Has Been Deleted'), +(183, 'en', 'vdo_iac_msg', 'Video Is Inactive - Please Contact Admin For Details'), +(184, 'en', 'vdo_is_in_process', 'Video Is In Process - Please Contact Administrator for further details'), +(185, 'en', 'vdo_upload_allow_err', 'Uploading Is Not Allowed By Website Owner'), +(186, 'en', 'vdo_download_allow_err', 'Video Downloading Is Not Allowed'), +(187, 'en', 'vdo_edit_owner_err', 'You Are Not Video Owner'), +(188, 'en', 'vdo_embed_code_wrong', 'Embed Code Was Wrong'), +(189, 'en', 'vdo_seconds_err', 'Wrong Value Entered For Seconds Field'), +(190, 'en', 'vdo_mins_err', 'Wrong Value Entered For Minutes Field'), +(191, 'en', 'vdo_thumb_up_err', 'Error In Uploading Thumb'), +(192, 'en', 'class_error_occured', 'Sorry, An Error Occured'), +(193, 'en', 'class_cat_del_msg', 'Category Has Been Delete Successfully'), +(194, 'en', 'class_vdo_del_msg', 'Video Has Been Deleted'), +(195, 'en', 'class_vdo_fr_msg', 'Video Has Been Set to Featured'), +(196, 'en', 'class_fr_msg1', 'Video Has Been Set to UnFeatured'), +(197, 'en', 'class_vdo_act_msg', 'Video Has Been Activated'), +(198, 'en', 'class_vdo_act_msg1', 'Video Has Been Deactivated'), +(199, 'en', 'class_vdo_update_msg', 'Video Has Been Updated Successfully'), +(200, 'en', 'class_comment_err', 'You Must Login First To Comment'), +(201, 'en', 'class_comment_err1', 'Please Type Something In Comment Box'), +(202, 'en', 'class_comment_err2', 'You Cannot Post Comment on Your Own Video'), +(203, 'en', 'class_comment_err3', 'You Have Already Posted a Comment, Please Wait for the others.'), +(204, 'en', 'class_comment_err4', 'You Have Already Replied To That a Comment, Please Wait for the others.'), +(205, 'en', 'class_comment_err5', 'You Cannot Post Reply To Yourself'), +(206, 'en', 'class_comment_msg', 'Comment Has Been Added'), +(207, 'en', 'class_comment_err6', 'You Must Login First To Rate Comment'), +(208, 'en', 'class_comment_err7', 'You Have Already Rated The Comment'), +(209, 'en', 'class_vdo_fav_err', 'This Video is Already Added To Your Favourites'), +(210, 'en', 'class_vdo_fav_msg', 'This Video Has Been Added To Your Favourites'), +(211, 'en', 'class_vdo_flag_err', 'You Have Already Flagged This Video'), +(212, 'en', 'class_vdo_flag_msg', 'This Video Has Been Flagged As Inappropriate'), +(213, 'en', 'class_vdo_flag_rm', 'Flag(s) Has/Have Been Removed'), +(214, 'en', 'class_send_msg_err', 'Please Enter a Username or Select any User to Send Message'), +(215, 'en', 'class_invalid_user', 'Invalid Username'), +(216, 'en', 'class_subj_err', 'Please Type Something In Subject Field'), +(217, 'en', 'class_msg_err', 'Please Type Something In Message Box'), +(218, 'en', 'class_sent_you_msg', 'Sent You A Message'), +(219, 'en', 'class_sent_prvt_msg', 'Sent You A Private Message on '), +(220, 'en', 'class_click_inbox', 'Please Click here To View Your Inbox'), +(221, 'en', 'class_click_login', 'Click Here To Login'), +(222, 'en', 'class_email_notify', 'Email Notification'), +(223, 'en', 'class_msg_has_sent_to', 'Message Has Been Sent To '), +(224, 'en', 'class_inbox_del_msg', 'Message Has Been Delete From Inbox '), +(225, 'en', 'class_sent_del_msg', 'Message Has Been Delete From Sent Folder'), +(226, 'en', 'class_msg_exist_err', 'Message Doesnt Exist'), +(227, 'en', 'class_vdo_del_err', 'Video Doesn’t Not Exist'), +(228, 'en', 'class_unsub_msg', 'You Have Unsubscribed'), +(229, 'en', 'class_sub_exist_err', 'Subscription Does Not Exist'), +(230, 'en', 'class_vdo_rm_fav_msg', 'Video Has Been Removed From Favourites'), +(231, 'en', 'class_vdo_fav_err1', 'This Video Is Not In Your Favourite List'), +(232, 'en', 'class_cont_del_msg', 'Contact Has Been Delete'), +(233, 'en', 'class_cot_err', 'Sorry, This Contact Is Not In Your Contact List'), +(234, 'en', 'class_vdo_ep_add_msg', 'Video Has Been Added To Editor’s Pick'), +(235, 'en', 'class_vdo_ep_err', 'Video Is Already In The Editor’s Pick'), +(236, 'en', 'class_vdo_ep_err1', 'You Have Already Picked 10 Videos Please Delete Alteast One to Add More'), +(237, 'en', 'class_vdo_ep_msg', 'Video Has Been Removed From Editor’s Pick'), +(238, 'en', 'class_vdo_exist_err', 'Sorry, Video Doesnt Exist'), +(239, 'en', 'class_img_gif_err', 'Please Upload Gif Image Only'), +(240, 'en', 'class_img_png_err', 'Please Upload Png Image Only'), +(241, 'en', 'class_img_jpg_err', 'Please Upload Jpg Image Only'), +(242, 'en', 'class_logo_msg', 'Logo Has Been ChangedPlease Clear Cache If You Are Not Able To See Changed Logo'), +(243, 'en', 'com_forgot_username', 'Forgot Username | Password'), +(244, 'en', 'com_join_now', 'Join Now'), +(245, 'en', 'com_my_account', 'My Account'), +(246, 'en', 'com_manage_vids', 'Manage Videos'), +(247, 'en', 'com_view_channel', 'View My Channel'), +(248, 'en', 'com_my_inbox', 'My Inbox'), +(249, 'en', 'com_welcome', 'Welcome'), +(250, 'en', 'com_top_mem', 'Top Members '), +(251, 'en', 'com_vidz', 'Videos'), +(252, 'en', 'com_sign_up_now', 'Sign Up Now !'), +(253, 'en', 'com_my_videos', 'My Videos'), +(254, 'en', 'com_my_channel', 'My Channel'), +(255, 'en', 'com_my_subs', 'My Subscriptions'), +(256, 'en', 'com_user_no_contacts', 'User Does Not Have Any Contact'), +(257, 'en', 'com_user_no_vides', 'User Does Not Have Any Favourite Video'), +(258, 'en', 'com_user_no_vid_com', 'User Has No Video Comments'), +(259, 'en', 'com_view_all_contacts', 'View All Contacts of'), +(260, 'en', 'com_view_fav_all_videos', 'View All Favourite Videos Of'), +(261, 'en', 'com_login_success_msg', 'You Have Been Successfully Logged In.'), +(262, 'en', 'com_logout_success_msg', 'You Have Been Successfully Logged Out.'), +(263, 'en', 'com_not_redirecting', 'You are now Redirecting .'), +(264, 'en', 'com_not_redirecting_msg', 'if your are not redirecting'), +(265, 'en', 'com_manage_contacts', 'Manage Contacts '), +(266, 'en', 'com_send_message', 'Send Message'), +(267, 'en', 'com_manage_fav', 'Manage Favourites '), +(268, 'en', 'com_manage_subs', 'Manage Subscriptions'), +(269, 'en', 'com_subscribe_to', 'Subscribe To'), +(270, 'en', 'com_total_subs', 'Total Subscribtions'), +(271, 'en', 'com_total_vids', 'Total Videos'), +(272, 'en', 'com_date_subscribed', 'Date Subscribed'), +(273, 'en', 'com_search_results', 'Search Results'), +(274, 'en', 'com_advance_results', 'Advance Search'), +(275, 'en', 'com_search_results_in', 'Search Results In'), +(276, 'en', 'videos_being_watched', 'Recently Viewed...'), +(277, 'en', 'latest_added_videos', 'Recent Additions'), +(278, 'en', 'most_viewed', 'Most Viewed'), +(279, 'en', 'recently_added', 'Recently Added'), +(280, 'en', 'featured', 'Featured'), +(281, 'en', 'highest_rated', 'Highest Rated'), +(282, 'en', 'most_discussed', 'Most Discussed'), +(283, 'en', 'style_change', 'Style Change'), +(284, 'en', 'rss_feed_latest_title', 'RSS Feed for Most Recent Videos'), +(285, 'en', 'rss_feed_featured_title', 'RSS Feed for Featured Videos'), +(286, 'en', 'rss_feed_most_viewed_title', 'RSS Feed for Most Popular Videos'), +(287, 'en', 'lang_folder', 'en'), +(288, 'en', 'reg_closed', 'Registration Closed'), +(289, 'en', 'reg_for', 'Registration for'), +(290, 'en', 'is_currently_closed', 'is currently closed'), +(291, 'en', 'about_us', 'About Us'), +(292, 'en', 'account', 'Account'), +(293, 'en', 'added', 'Added'), +(294, 'en', 'advertisements', 'Advertisements'), +(295, 'en', 'all', 'All'), +(296, 'en', 'active', 'Active'), +(297, 'en', 'activate', 'Activate'), +(298, 'en', 'age', 'Age'), +(299, 'en', 'approve', 'Approve'), +(300, 'en', 'approved', 'Approved'), +(301, 'en', 'approval', 'Approval'), +(302, 'en', 'books', 'Books'), +(303, 'en', 'browse', 'Browse'), +(304, 'en', 'by', 'by'), +(305, 'en', 'cancel', 'Cancel'), +(306, 'en', 'categories', 'Categories'), +(307, 'en', 'category', 'Category'), +(308, 'en', 'channels', 'channels'), +(309, 'en', 'check_all', 'Check All'), +(310, 'en', 'click_here', 'Click Here'), +(311, 'en', 'comments', 'Comments'), +(312, 'en', 'community', 'Community'), +(313, 'en', 'companies', 'Companies'), +(314, 'en', 'contacts', 'Contacts'), +(315, 'en', 'contact_us', 'Contact Us'), +(316, 'en', 'country', 'Country'), +(317, 'en', 'created', 'Created'), +(318, 'en', 'date', 'Date'), +(319, 'en', 'date_added', 'Date Added'), +(320, 'en', 'date_joined', 'Date Joined'), +(321, 'en', 'dear', 'Dear'), +(322, 'en', 'delete', 'Delete'), +(323, 'en', 'delete_selected', 'Delete Selected'), +(324, 'en', 'des_title', 'Description:'), +(325, 'en', 'duration', 'Duration'), +(326, 'en', 'education', 'Education'), +(327, 'en', 'email', 'email'), +(328, 'en', 'embed', 'Embed'), +(329, 'en', 'embed_code', 'Embed Code'), +(330, 'en', 'favourite', 'Favorite'), +(331, 'en', 'favourited', 'Favorited'), +(332, 'en', 'favourites', 'Favorites'), +(333, 'en', 'female', 'Female'), +(334, 'en', 'filter', 'Filter'), +(335, 'en', 'forgot', 'Forgot'), +(336, 'en', 'friends', 'Friends'), +(337, 'en', 'from', 'From'), +(338, 'en', 'gender', 'Gender'), +(339, 'en', 'groups', 'Groups'), +(340, 'en', 'hello', 'Hello'), +(341, 'en', 'help', 'Help'), +(342, 'en', 'hi', 'Hi'), +(343, 'en', 'hobbies', 'Hobbies'), +(344, 'en', 'Home', 'Home'), +(345, 'en', 'inbox', 'Inbox'), +(346, 'en', 'interests', 'Interests'), +(347, 'en', 'join_now', 'Join Now'), +(348, 'en', 'joined', 'Joined'), +(349, 'en', 'join', 'Join'), +(350, 'en', 'keywords', 'Keywords'), +(351, 'en', 'latest', 'Latest'), +(352, 'en', 'leave', 'Leave'), +(353, 'en', 'location', 'Location'), +(354, 'en', 'login', 'Login'), +(355, 'en', 'logout', 'Logout'), +(356, 'en', 'male', 'Male'), +(357, 'en', 'members', 'Members'), +(358, 'en', 'messages', 'Messages'), +(359, 'en', 'message', 'Message'), +(360, 'en', 'minutes', 'minutes'), +(361, 'en', 'most_members', 'Most Members'), +(362, 'en', 'most_recent', 'Most Recent'), +(363, 'en', 'most_videos', 'Most Videos'), +(364, 'en', 'music', 'Music'), +(365, 'en', 'my_account', 'My Account'), +(366, 'en', 'next', 'Next'), +(367, 'en', 'no', 'No'), +(368, 'en', 'no_user_exists', 'No User Exists'), +(369, 'en', 'no_video_exists', 'No Video Exists'), +(370, 'en', 'occupations', 'Occupations'), +(371, 'en', 'optional', 'optional'), +(372, 'en', 'owner', 'Owner'), +(373, 'en', 'password', 'password'), +(374, 'en', 'please', 'Please'), +(375, 'en', 'privacy', 'Privacy'), +(376, 'en', 'privacy_policy', 'Privacy Policy'), +(377, 'en', 'random', 'Random'), +(378, 'en', 'rate', 'Rate'), +(379, 'en', 'request', 'Request'), +(380, 'en', 'related', 'Related'), +(381, 'en', 'reply', 'Reply'), +(382, 'en', 'results', 'Results'), +(383, 'en', 'relationship', 'Relationship'), +(384, 'en', 'seconds', 'seconds'), +(385, 'en', 'select', 'Select'), +(386, 'en', 'send', 'Send'), +(387, 'en', 'sent', 'Sent'), +(388, 'en', 'signup', 'Signup'), +(389, 'en', 'subject', 'Subject'), +(390, 'en', 'tags', 'Tags'), +(391, 'en', 'times', 'Times'), +(392, 'en', 'to', 'To'), +(393, 'en', 'type', 'Type'), +(394, 'en', 'update', 'Update'), +(395, 'en', 'upload', 'Upload'), +(396, 'en', 'url', 'Url'), +(397, 'en', 'verification', 'Verification'), +(398, 'en', 'videos', 'Videos'), +(399, 'en', 'viewing', 'Viewing'), +(400, 'en', 'welcome', 'Welcome'), +(401, 'en', 'website', 'Website'), +(402, 'en', 'yes', 'Yes'), +(403, 'en', 'of', 'of'), +(404, 'en', 'on', 'on'), +(405, 'en', 'previous', 'Previous'), +(406, 'en', 'rating', 'Rating'), +(407, 'en', 'ratings', 'Ratings'), +(408, 'en', 'remote_upload', 'Remote Upload'), +(409, 'en', 'remove', 'Remove'), +(410, 'en', 'search', 'search'), +(411, 'en', 'services', 'Services'), +(412, 'en', 'show_all', 'Show All'), +(413, 'en', 'signupup', 'Sign Up'), +(414, 'en', 'sort_by', 'Sort By'), +(415, 'en', 'subscriptions', 'Subscriptions'), +(416, 'en', 'subscribers', 'Subscribers'), +(417, 'en', 'tag_title', 'Tags'), +(418, 'en', 'time', 'time'), +(419, 'en', 'top', 'Top'), +(420, 'en', 'tos_title', 'Terms of Use'), +(421, 'en', 'username', 'username'), +(422, 'en', 'views', 'Views'), +(423, 'en', 'proccession_wait', 'Processing, Please Wait'), +(424, 'en', 'mostly_viewed', 'Most Viewed'), +(425, 'en', 'most_comments', 'Most Comments'), +(426, 'en', 'group', 'Group'), +(427, 'en', 'not_logged_in', 'You are not logged in or you do not have permission to access this page. This could be due to one of several reasons:'), +(428, 'en', 'fill_auth_form', 'You are not logged in. Fill in the form below and try again.'), +(429, 'en', 'insufficient_privileges', 'You may not have sufficient privileges to access this page.'), +(430, 'en', 'admin_disabled_you', 'The site administrator may have disabled your account, or it may be awaiting activation.'), +(431, 'en', 'Recover_Password', 'Recover Password'), +(432, 'en', 'Submit', 'Submit'), +(433, 'en', 'Reset_Fields', 'Reset Fields'), +(434, 'en', 'admin_reg_req', 'The administrator may have required you to register before you can view this page.'), +(435, 'en', 'lang_change', 'Language Change'), +(436, 'en', 'lang_changed', 'Your language has been changed'), +(437, 'en', 'lang_choice', 'Language'), +(438, 'en', 'if_not_redir', 'Click here to continue if you are not automatically redirected.'), +(439, 'en', 'style_changed', 'Your style has been changed'), +(440, 'en', 'style_choice', 'Style'), +(441, 'en', 'vdo_edit_vdo', 'Edit Video'), +(442, 'en', 'vdo_stills', 'Video Stills'), +(443, 'en', 'vdo_watch_video', 'Watch Video'), +(444, 'en', 'vdo_video_details', 'Video Details'), +(445, 'en', 'vdo_title', 'Title'), +(446, 'en', 'vdo_desc', 'Description'), +(447, 'en', 'vdo_cat', 'Video Category'), +(448, 'en', 'vdo_cat_msg', 'You May Select Upto 3 Categories'), +(449, 'en', 'vdo_tags_msg', 'Tags are seperated by space , ie home user smile'), +(450, 'en', 'vdo_br_opt', 'Broadcast Options'), +(451, 'en', 'vdo_br_opt1', 'Public Share your video with the Everyone! (Recommended)'), +(452, 'en', 'vdo_br_opt2', 'Private Viewable by you and your friends only.'), +(453, 'en', 'vdo_date_loc', 'Date And Location'), +(454, 'en', 'vdo_date_rec', 'Date Recorded'), +(455, 'en', 'vdo_for_date', 'format MM / DD / YYYY '), +(456, 'en', 'vdo_add_eg', 'e.g London Greenland, Sialkot Mubarak Pura'), +(457, 'en', 'vdo_share_opt', 'Sharing Options'), +(458, 'en', 'vdo_allow_comm', 'Allow Comments '), +(459, 'en', 'vdo_dallow_comm', 'Do Not Allow Comments'), +(460, 'en', 'vdo_comm_vote', 'Comments Voting'), +(461, 'en', 'vdo_allow_com_vote', 'Allow Comments Voting '), +(462, 'en', 'vdo_dallow_com_vote', 'Do Not Allow Comments Voting '), +(463, 'en', 'vdo_allow_rating', 'Yes, Allow Rating on this video'), +(464, 'en', 'vdo_dallow_ratig', 'No, Do Not Allow Rating on this video'), +(465, 'en', 'vdo_embedding', 'Embedding'), +(466, 'en', 'vdo_embed_opt1', 'Yes, People can play this video on other websites'), +(467, 'en', 'vdo_embed_opt2', 'No, People cannot play this video on other websites'), +(468, 'en', 'vdo_update_title', 'Update'), +(469, 'en', 'vdo_inactive_msg', 'Your Account is Inactive Please Activate it to Upload Videos, To Activate your account Please'), +(470, 'en', 'vdo_click_here', 'Click Here'), +(471, 'en', 'vdo_continue_upload', 'Continue to Upload'), +(472, 'en', 'vdo_upload_step1', 'Video Upload'), +(473, 'en', 'vdo_upload_step2', '(Step 1/2) Filling Up Details'), +(474, 'en', 'vdo_upload_step3', '(Step 2/2)'), +(475, 'en', 'vdo_select_vdo', 'Select a video to upload.'), +(476, 'en', 'vdo_enter_remote_url', 'Enter Url Of The Video.'), +(477, 'en', 'vdo_enter_embed_code_msg', 'Enter Embed Video Code from other websites ie Youtube or Metacafe.'), +(478, 'en', 'vdo_enter_embed_code', 'Enter Embed Code'), +(479, 'en', 'vdo_enter_druation', 'Enter Duration'), +(480, 'en', 'vdo_select_vdo_thumb', 'Select Video Thumb'), +(481, 'en', 'vdo_having_trouble', 'Having Trouble?'), +(482, 'en', 'vdo_if_having_problem', 'if you having problem with the uploader'), +(483, 'en', 'vdo_clic_to_manage_all', 'Click Here To Manage All Videos'), +(484, 'en', 'vdo_manage_vdeos', 'Manage Videos '), +(485, 'en', 'vdo_status', 'Status'), +(486, 'en', 'vdo_rawfile', 'RawFile'), +(487, 'en', 'vdo_video_upload_complete', 'Video Upload - Upload Complete'), +(488, 'en', 'vdo_thanks_you_upload_complete_1', 'Thank you! Your upload is complete'), +(489, 'en', 'vdo_thanks_you_upload_complete_2', 'This video will be available in'), +(490, 'en', 'vdo_after_it_has_process', 'after it has finished processing.'), +(491, 'en', 'vdo_embed_this_video_on_web', 'Embed this video on your website.'), +(492, 'en', 'vdo_copy_and_paste_the_code', 'Copy and paste the code below to embed this video.'), +(493, 'en', 'vdo_upload_another_video', 'Upload Another Video'), +(494, 'en', 'vdo_goto_my_videos', 'Goto My Videos'), +(495, 'en', 'vdo_sperate_emails_by', 'seperate emails by commas'), +(496, 'en', 'vdo_personal_msg', 'Personal Message'), +(497, 'en', 'vdo_s_details', '’s Details'), +(498, 'en', 'vdo_s_description', '’s Description'), +(499, 'en', 'vdo_related_tags', 'Related Tags'), +(500, 'en', 'vdo_reply_to_this', 'Reply To This '), +(501, 'en', 'vdo_add_reply', 'Add Reply'), +(502, 'en', 'vdo_share_video', 'Share Video'), +(503, 'en', 'vdo_about_this_video', 'About This Video'), +(504, 'en', 'vdo_post_to_a_services', 'Post to an Aggregating Service'), +(505, 'en', 'vdo_commentary', 'Commentary'), +(506, 'en', 'vdo_post_a_comment', 'Post A Comment'), +(508, 'en', 'grp_no_vdo_msg', 'You Don’t Have Any Video'), +(509, 'en', 'grp_add_to', 'Add To Group'), +(510, 'en', 'grp_add_vdos', 'Add Videos'), +(511, 'en', 'grp_name_title', 'Group Name:'), +(512, 'en', 'grp_tag_title', 'Tags:'), +(513, 'en', 'grp_des_title', 'Description:'), +(514, 'en', 'grp_tags_msg', 'Enter one or more tags, separated by spaces.'), +(515, 'en', 'grp_tags_msg1', 'Tags are keywords used to describe your group so it can be easily found by other users. For example, if you have a group for surfers, you might tag it: surfing, beach, waves.'), +(516, 'en', 'grp_url_title', 'Choose a unique group name URL:'), +(517, 'en', 'grp_url_msg', 'Enter 3-18 characters with no spaces (such as “skateboarding skates”), that will become part of your group’s web address. Please note, the group name URL you pick is permanent and can’t be changed.'), +(518, 'en', 'grp_cat_tile', 'Group Category:'), +(519, 'en', 'grp_vdo_uploads', 'Video Uploads:'), +(520, 'en', 'grp_forum_posting', 'Forums Posting:'), +(521, 'en', 'grp_join_opt1', 'Public, anyone can join.'), +(522, 'en', 'grp_join_opt2', 'Protected, requires founder approval to join.'), +(523, 'en', 'grp_join_opt3', 'Private, by founder invite only, only members can view group details.'), +(524, 'en', 'grp_vdo_opt1', 'Post videos immediately.'), +(525, 'en', 'grp_vdo_opt2', 'Founder approval required before video is available.'), +(526, 'en', 'grp_vdo_opt3', 'Only Founder can add new videos.'), +(527, 'en', 'grp_post_opt1', 'Post topics immediately.'), +(528, 'en', 'grp_post_opt2', 'Founder approval required before topic is available.'), +(529, 'en', 'grp_post_opt3', 'Only Founder can create a new topic.'), +(530, 'en', 'grp_crt_grp', 'Create Group'), +(531, 'en', 'grp_thumb_title', 'Group Thumb'), +(532, 'en', 'grp_upl_thumb', 'Upload Group Thumb'), +(533, 'en', 'grp_must_be', 'Must Be'), +(534, 'en', 'grp_90x90', '90 x 90 Ratio Will Give Best quality'), +(535, 'en', 'grp_thumb_warn', 'Do Not Upload Vulgur or Copyrighted Material'), +(536, 'en', 'grp_del_confirm', 'Are You Sure You Want To Delete This Group'), +(537, 'en', 'grp_del_success', 'You Have Successfully Deleted'), +(538, 'en', 'grp_click_go_grps', 'Click Here To Go To Groups'), +(539, 'en', 'grp_edit_grp_title', 'Edit Group'), +(540, 'en', 'grp_manage_vdos', 'Manage Videos'), +(541, 'en', 'grp_manage_mems', 'Manage Members'), +(542, 'en', 'grp_del_group_title', 'Delete Group'), +(543, 'en', 'grp_add_vdos_title', 'Add Videos'), +(544, 'en', 'grp_join_grp_title', 'Join Group'), +(545, 'en', 'grp_leave_group_title', 'Leave Group'), +(546, 'en', 'grp_invite_grp_title', 'Invite Members'), +(547, 'en', 'grp_view_mems', 'View Members'), +(548, 'en', 'grp_view_vdos', 'View Videos'), +(549, 'en', 'grp_create_grp_title', 'Create A New Group'), +(550, 'en', 'grp_most_members', 'Most Members'), +(551, 'en', 'grp_most_discussed', 'Most Discussed'), +(552, 'en', 'grp_invite_msg', 'Invite Users To This Group'), +(553, 'en', 'grp_invite_msg1', 'Has Invited You To Join'), +(554, 'en', 'grp_invite_msg2', 'Enter Emails or Usernames (seperate by commas)'), +(555, 'en', 'grp_url_title1', 'Group url'), +(556, 'en', 'grp_invite_msg3', 'Send Invitation'), +(557, 'en', 'grp_join_confirm_msg', 'Are You Sure You Want To Join This Group'), +(558, 'en', 'grp_join_msg_succ', 'You Have Successfully Joined'), +(559, 'en', 'grp_click_here_to_go', 'Click Here To Go To'), +(560, 'en', 'grp_leave_confirm', 'Are You Sure You Want To Leave This Group'), +(561, 'en', 'grp_leave_succ_msg', 'You Have Successfully Left'), +(562, 'en', 'grp_manage_members_title', 'Manage Members '), +(563, 'en', 'grp_for_approval', 'For Approval'), +(564, 'en', 'grp_rm_videos', 'Remove Videos'), +(565, 'en', 'grp_rm_mems', 'Remove Members'), +(566, 'en', 'grp_groups_title', 'Manage Groups'), +(567, 'en', 'grp_remove_group', 'Remove Group'), +(568, 'en', 'grp_bo_grp_found', 'No Group Found'), +(569, 'en', 'grp_joined_groups', 'Joined Groups'), +(570, 'en', 'grp_owned_groups', 'Owned Groups'), +(571, 'en', 'grp_edit_this_grp', 'Edit This Group'), +(572, 'en', 'grp_topics_title', 'Topics'), +(573, 'en', 'grp_topic_title', 'Topic'), +(574, 'en', 'grp_posts_title', 'Posts'), +(575, 'en', 'grp_discus_title', 'Discussions'), +(576, 'en', 'grp_author_title', 'Author'), +(577, 'en', 'grp_replies_title', 'Replies'), +(578, 'en', 'grp_last_post_title', 'Last Post '), +(579, 'en', 'grp_viewl_all_videos', 'View All Videos of This Group'), +(580, 'en', 'grp_add_new_topic', 'Add New Topic'), +(581, 'en', 'grp_attach_video', 'Attach Video '), +(582, 'en', 'grp_add_topic', 'Add Topic'), +(583, 'en', 'grp_please_login', 'Please Login To Post Topics'), +(584, 'en', 'grp_please_join', 'Please Join This Group To Post Topics'), +(585, 'en', 'grp_inactive_account', 'Your Account Is Inactive And Required Activation From Group Owner'), +(586, 'en', 'grp_about_this_grp', 'About This Group '), +(587, 'en', 'grp_no_vdo_err', 'This Group Has No Vidoes'), +(588, 'en', 'grp_posted_by', 'Posted by'), +(589, 'en', 'grp_add_new_comment', 'Add New Comment'), +(590, 'en', 'grp_add_comment', 'Add Comment'), +(591, 'en', 'grp_pls_login_comment', 'Please Login To Post Comments'), +(592, 'en', 'grp_pls_join_comment', 'Please Join This Group To Post Comments'), +(593, 'en', 'usr_activation_title', 'User Activation'), +(594, 'en', 'usr_actiavation_msg', 'Enter Your Username and Activation Code that has been sent to your email.'), +(595, 'en', 'usr_actiavation_msg1', 'Request Activation Code'), +(596, 'en', 'usr_activation_code_tl', 'Activation Code'), +(597, 'en', 'usr_compose_msg', 'Compose Message'), +(598, 'en', 'usr_inbox_title', 'Inbox'), +(599, 'en', 'usr_sent_title', 'Sent'), +(600, 'en', 'usr_to_title', 'To: (Enter Username)'), +(601, 'en', 'usr_or_select_frm_list', 'or select from contact list'), +(602, 'en', 'usr_attach_video', 'Attach Video'), +(603, 'en', 'user_attached_video', 'Attached Video'), +(604, 'en', 'usr_send_message', 'Send Message'), +(605, 'en', 'user_no_message', 'No Message'), +(606, 'en', 'user_delete_message_msg', 'Delete This Message'), +(607, 'en', 'user_forgot_message', 'Forgot Username or Password?'), +(608, 'en', 'user_forgot_message_2', 'Dont Worry, recover it now'), +(609, 'en', 'user_pass_reset_msg', 'Password Reset'), +(610, 'en', 'user_pass_forgot_msg', 'if you have forgot your password, please enter you username and verification code in the box, and password reset instructions will be sent to your mail box.'), +(611, 'en', 'user_veri_code', 'Verification Code'), +(612, 'en', 'user_reocover_user', 'Recover Username'), +(613, 'en', 'user_user_forgot_msg', 'Forgot Username?'), +(614, 'en', 'user_recover', 'Recover'), +(615, 'en', 'user_reset', 'Reset'), +(616, 'en', 'user_inactive_msg', 'Your Account is Inactive Please Activate it , To Activate your account Please'), +(617, 'en', 'user_dashboard', 'Dash Board'), +(618, 'en', 'user_manage_prof_chnnl', 'Manage Profile & Channel'), +(619, 'en', 'user_manage_friends', 'Manage Friends & Contacts'), +(620, 'en', 'user_prof_channel', 'Profile/Channel'), +(621, 'en', 'user_message_box', 'Message Box'), +(622, 'en', 'user_new_messages', 'New Messages'), +(623, 'en', 'user_goto_inbox', 'Goto Inbox'), +(624, 'en', 'user_goto_sentbox', 'Goto Sent Box'), +(625, 'en', 'user_compose_new', 'Compose New Messages'), +(626, 'en', 'user_total_subs_users', 'Total Subscribed Users'), +(627, 'en', 'user_you_have', 'You Have'), +(628, 'en', 'user_fav_videos', 'Favourite Videos'), +(629, 'en', 'user_your_vids_watched', 'Your Videos Watched'), +(630, 'en', 'user_times', 'Times'), +(631, 'en', 'user_you_have_watched', 'You Have Watched'), +(632, 'en', 'user_channel_profiles', 'Channel & Profile'), +(633, 'en', 'user_channel_views', 'Channel Views'), +(634, 'en', 'user_channel_comm', 'Channel Comments '), +(635, 'en', 'user_manage_prof', 'Manage Profile / Channel'), +(636, 'en', 'user_you_created', 'You Have Created'), +(637, 'en', 'user_you_joined', 'You Have Joined'), +(638, 'en', 'user_create_group', 'Create New Group'), +(639, 'en', 'user_manage_my_account', 'Manage My Account '), +(640, 'en', 'user_manage_my_videos', 'Manage My Videos'), +(641, 'en', 'user_manage_my_channel', 'Manage My Channe'), +(642, 'en', 'user_sent_box', 'Sent Box'), +(643, 'en', 'user_manage_channel', 'Manage Channel'), +(644, 'en', 'user_manage_my_contacts', 'Manage My Contacts'), +(645, 'en', 'user_manage_contacts', 'Manage Contacts'), +(646, 'en', 'user_manage_favourites', 'Manage Favourite Videos'), +(647, 'en', 'user_mem_login', 'Members Login'), +(648, 'en', 'user_already_have', 'Please Login Here if You Already have an account of'), +(649, 'en', 'user_forgot_username', 'Forgot Username'), +(650, 'en', 'user_forgot_password', 'Forgot Password'), +(651, 'en', 'user_create_your', 'Create Your '), +(652, 'en', 'user_all_fields_req', 'All Fields Are Required'), +(653, 'en', 'user_valid_email_addr', 'Valid Email Address'), +(654, 'en', 'user_allowed_format', 'Letters A-Z or a-z , Numbers 0-9 and Underscores _'), +(655, 'en', 'user_confirm_pass', 'Confirm Password'), +(656, 'en', 'user_reg_msg_0', 'Register as '), +(657, 'en', 'user_reg_msg_1', 'member, its free and easy just fill out the form below'), +(658, 'en', 'user_date_of_birth', 'Date Of Birth'), +(659, 'en', 'user_enter_text_as_img', 'Enter Text As Seen In The Image'), +(660, 'en', 'user_refresh_img', 'Refresh Image'), +(661, 'en', 'user_i_agree_to_the', 'I Agree to the'), +(662, 'en', 'user_thanks_for_reg', 'Thank You For Registering on '), +(663, 'en', 'user_email_has_sent', 'An email has been sent to your inbox containing Your Account'), +(664, 'en', 'user_and_activation', '& Activation'), +(665, 'en', 'user_details_you_now', 'Details. You may now do the following things on our network'), +(666, 'en', 'user_upload_share_vds', 'Upload, Share Videos'), +(667, 'en', 'user_make_friends', 'Make Friends'), +(668, 'en', 'user_send_messages', 'Send Messages'), +(669, 'en', 'user_grow_your_network', 'Grow Your Networks by Inviting more Friends'), +(670, 'en', 'user_rate_comment', 'Rate and Comment Videos'), +(671, 'en', 'user_make_customize', 'Make and Customize Your Channel'), +(672, 'en', 'user_to_upload_vid', 'To Upload Video, You Need to Activate your account first, activation details has been sent to your email account, it may take sometimes to reach your inbox'), +(673, 'en', 'user_click_to_login', 'Click here To Login To Your Account'), +(674, 'en', 'user_view_my_channel', 'View My Channel'), +(675, 'en', 'user_change_pass', 'Change Password'), +(676, 'en', 'user_email_settings', 'Email Settings'), +(677, 'en', 'user_profile_settings', 'Profile Settings'), +(678, 'en', 'user_usr_prof_chnl_edit', 'User Profile & Channel Edit'), +(679, 'en', 'user_personal_info', 'Personal Information'), +(680, 'en', 'user_fname', 'First Name'), +(681, 'en', 'user_lname', 'Last Name'), +(682, 'en', 'user_gender', 'Gender'), +(683, 'en', 'user_relat_status', 'Relationship Status'), +(684, 'en', 'user_display_age', 'Display Age'), +(685, 'en', 'user_about_me', 'About Me'), +(686, 'en', 'user_website_url', 'Website Url'), +(687, 'en', 'user_eg_website', 'e.g www.cafepixie.com'), +(688, 'en', 'user_prof_info', 'Professional Information'), +(689, 'en', 'user_education', 'Education'), +(690, 'en', 'user_school_colleges', 'Schools / Colleges'), +(691, 'en', 'user_occupations', 'Occupations'), +(692, 'en', 'user_companies', 'Companies'), +(693, 'en', 'user_sperate_by_commas', 'seperate with commas'), +(694, 'en', 'user_interests_hobbies', 'Interests and Hobbies'), +(695, 'en', 'user_fav_movs_shows', 'Favourite Movies And Shows:'), +(696, 'en', 'user_fav_music', 'Favourite Music'), +(697, 'en', 'user_fav_books', 'Favourite Books'), +(698, 'en', 'user_user_avatar', 'User Avatar'), +(699, 'en', 'user_upload_avatar', 'Upload Avatar'), +(700, 'en', 'user_channel_info', 'Channel Info'), +(701, 'en', 'user_channel_title', 'Channel Title'), +(702, 'en', 'user_channel_description', 'Channel Description'), +(703, 'en', 'user_channel_permission', 'Channel Permissions'), +(704, 'en', 'user_allow_comments_msg', 'users can comments'), +(705, 'en', 'user_dallow_comments_msg', 'users cannot comments'), +(706, 'en', 'user_allow_rating', 'Allow Rating'), +(707, 'en', 'user_dallow_rating', 'Do Not Allow Rating'), +(708, 'en', 'user_allow_rating_msg1', 'users can rate'), +(709, 'en', 'user_dallow_rating_msg1', 'users cannot rate'), +(710, 'en', 'user_channel_feature_vid', 'Channel Featured Video'), +(711, 'en', 'user_select_vid_for_fr', 'Select Video To set as Featured'), +(712, 'en', 'user_chane_channel_bg', 'Change Channel Background'), +(713, 'en', 'user_remove_bg', 'Remove Background'), +(714, 'en', 'user_currently_you_d_have_pic', 'Currently You Don’t Have Background Picture'), +(715, 'en', 'user_change_email', 'Change Email'), +(716, 'en', 'user_email_address', 'Email Address'), +(717, 'en', 'user_new_email', 'New Email'), +(718, 'en', 'user_notify_me', 'Notify Me When User Sends Me A Message'), +(719, 'en', 'user_old_pass', 'Old Password'), +(720, 'en', 'user_new_pass', 'New Password'), +(721, 'en', 'user_c_new_pass', 'Confirm New Password'), +(722, 'en', 'user_doesnt_exist', 'User Doesn’t Exist'), +(723, 'en', 'user_do_not_have_contact', 'User Does Not Have Any Contact'), +(724, 'en', 'user_no_fav_video_exist', 'User Does Not Have Favourite Video'), +(725, 'en', 'user_have_no_vide', 'User Does Not Have Any Video'), +(726, 'en', 'user_s_channel', '’s Channel '), +(727, 'en', 'user_last_login', 'Last Login'), +(728, 'en', 'user_send_message', 'Send Message'), +(729, 'en', 'user_add_contact', 'Add Contact'), +(730, 'en', 'user_dob', 'Dob'), +(731, 'en', 'user_movies_shows', 'Movies & Shows'), +(732, 'en', 'user_add_comment', 'Add Comment '), +(733, 'en', 'user_view_all_comments', 'View All Comments'), +(734, 'en', 'user_no_fr_video', 'User Has Not Selected Any Video To Set As Featured'), +(735, 'en', 'user_view_all_video_of', 'View All Videos of '), +(736, 'en', 'menu_home', 'Home'), +(737, 'en', 'menu_videos', 'Videos'), +(738, 'en', 'menu_upload', 'Upload'), +(739, 'en', 'menu_signup', 'SignUp'), +(740, 'en', 'menu_account', 'Account'), +(741, 'en', 'menu_groups', 'Groups'), +(742, 'en', 'menu_channels', 'Channels'), +(743, 'en', 'menu_community', 'Community'), +(744, 'en', 'menu_inbox', 'Inbox'), +(745, 'en', 'vdo_cat_err2', 'You cannot select more than %d categories'), +(746, 'en', 'user_subscribe_message', 'Hello %subscriber%\r\nYou Have Subscribed To %user% and therefore this message is sent to you automatically that %user% Has Uploaded New Video\r\n\r\n%website_title%'), +(747, 'en', 'user_subscribe_subject', '%user% has uploaded new video'), +(748, 'en', 'you_already_logged', 'You are already logged in'), +(749, 'en', 'You are not logged in', ''), +(750, 'en', 'you_not_logged_in', 'You are not logged in'), +(751, 'en', 'invalid_user', 'Invalid User\r\n'), +(752, 'va', 'value', 'value'), +(753, 'en', 'vdo_cat_err3', 'Please select atleast 1 category'), +(754, 'en', 'embed_code_invalid_err', 'Invalid video embed code'), +(755, 'en', 'invalid_duration', 'Invalid duration'); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `players` +-- + +CREATE TABLE IF NOT EXISTS `players` ( + `player_id` int(10) NOT NULL AUTO_INCREMENT, + `player_name` varchar(25) NOT NULL, + `player_file` varchar(30) NOT NULL, + `template_id` varchar(15) NOT NULL, + PRIMARY KEY (`player_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=7 ; + +-- +-- Dumping data for table `players` +-- + +INSERT INTO `players` (`player_id`, `player_name`, `player_file`, `template_id`) VALUES +(1, 'ClipBucket Blue', 'clipbucketblue.swf', '1'), +(4, 'YouTube Player', 'youtube.swf', '1'), +(6, 'YouTube Glossy Player', 'youtube_glossy.swf', '1'); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `player_skins` +-- + +CREATE TABLE IF NOT EXISTS `player_skins` ( + `player_skins_id` int(20) NOT NULL AUTO_INCREMENT, + `player_id` int(20) NOT NULL, + `player_skin_name` varchar(60) CHARACTER SET latin1 NOT NULL, + `player_skin_file` text CHARACTER SET latin1 NOT NULL, + `player_skin_type` enum('name','file') CHARACTER SET latin1 NOT NULL DEFAULT 'file', + PRIMARY KEY (`player_skins_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; + +-- +-- Dumping data for table `player_skins` +-- + + +-- -------------------------------------------------------- + +-- +-- Table structure for table `plugins` +-- + +CREATE TABLE IF NOT EXISTS `plugins` ( + `plugin_id` int(255) NOT NULL AUTO_INCREMENT, + `plugin_file` text NOT NULL, + `plugin_version` float NOT NULL, + `plugin_license_type` varchar(10) NOT NULL DEFAULT 'GPL', + `plugin_license_key` varchar(5) NOT NULL, + `plugin_license_code` text NOT NULL, + `plugin_active` enum('yes','no') NOT NULL, + PRIMARY KEY (`plugin_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=11 ; + +-- +-- Dumping data for table `plugins` +-- + + +-- -------------------------------------------------------- + +-- +-- Table structure for table `plugin_config` +-- + +CREATE TABLE IF NOT EXISTS `plugin_config` ( + `plugin_config_id` int(223) NOT NULL AUTO_INCREMENT, + `plugin_id_code` varchar(25) CHARACTER SET latin1 NOT NULL, + `plugin_config_name` text CHARACTER SET latin1 NOT NULL, + `plugin_config_value` text CHARACTER SET latin1 NOT NULL, + `player_type` enum('built-in','plugin') CHARACTER SET latin1 NOT NULL DEFAULT 'built-in', + `player_admin_file` text CHARACTER SET latin1 NOT NULL, + `player_include_file` text CHARACTER SET latin1 NOT NULL, + PRIMARY KEY (`plugin_config_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; + +-- +-- Dumping data for table `plugin_config` +-- + + +-- -------------------------------------------------------- + +-- +-- Table structure for table `stats` +-- + +CREATE TABLE IF NOT EXISTS `stats` ( + `stat_id` int(20) NOT NULL AUTO_INCREMENT, + `name` varchar(60) NOT NULL, + `value` varchar(60) NOT NULL, + PRIMARY KEY (`stat_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=29 ; + +-- +-- Dumping data for table `stats` +-- + +INSERT INTO `stats` (`stat_id`, `name`, `value`) VALUES +(1, 'total_users', '4'), +(2, 'total_active_users', '1'), +(3, 'today_signups', '0'), +(4, 'todays_logins', '0'), +(5, 'months_logins', '1'), +(6, 'total_videos', '5'), +(7, 'total_watched_videos', '51'), +(8, 'videos_added_today', '0'), +(9, 'videos_added_this_month', '0'), +(10, 'total_flagged_videos', '0'), +(11, 'total_added_favorites', '1'), +(12, 'total_video_comments', '14'), +(13, 'total_user_comments', '1'), +(14, 'total_success_videos', '39'), +(15, 'total_videos_processing', '-36'), +(16, 'total_active_videos', '6'), +(17, 'total_failed_videos', '10'), +(18, 'last_update', '2009-07-07 16:06:58'), +(19, 'total_groups', '0'), +(20, 'total_topics', '0'), +(21, 'total_posts', '0'), +(22, 'group_members', '0'), +(23, 'group_invitations', '0'), +(24, 'groups_added_today', '0'), +(25, 'groups_added_month', '0'), +(26, 'cb_ver', '1.7.1'), +(27, 'date_updated', 'January 30, 2009'), +(28, 'stability', 'SVN - Revision 685'); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `subscriptions` +-- + +CREATE TABLE IF NOT EXISTS `subscriptions` ( + `subscription_id` int(225) NOT NULL AUTO_INCREMENT, + `subscribed_user` varchar(20) NOT NULL, + `subscriber_id` int(11) NOT NULL, + `userid` int(11) NOT NULL, + `subscribed_to` mediumtext NOT NULL, + `subscription_type` enum('0','1') NOT NULL DEFAULT '0', + `notification_type` enum('0','1') NOT NULL DEFAULT '0', + `date_added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`subscription_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; + +-- +-- Dumping data for table `subscriptions` +-- + + +-- -------------------------------------------------------- + +-- +-- Table structure for table `template` +-- + +CREATE TABLE IF NOT EXISTS `template` ( + `template_id` int(20) NOT NULL AUTO_INCREMENT, + `template_name` varchar(25) NOT NULL, + `template_dir` varchar(30) NOT NULL, + PRIMARY KEY (`template_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=6 ; + +-- +-- Dumping data for table `template` +-- + +INSERT INTO `template` (`template_id`, `template_name`, `template_dir`) VALUES +(1, 'ClipBucket Blue', 'clipbucketblue'), +(4, 'YouTube', 'youtube'), +(5, 'ClipBucket Black', 'clipbucketblack'); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `users` +-- + +CREATE TABLE IF NOT EXISTS `users` ( + `userid` bigint(20) NOT NULL AUTO_INCREMENT, + `channel_title` mediumtext NOT NULL, + `channel_des` mediumtext NOT NULL, + `featured_video` mediumtext NOT NULL, + `username` text NOT NULL, + `user_session_key` varchar(32) NOT NULL, + `user_session_code` int(5) NOT NULL, + `password` varchar(40) NOT NULL DEFAULT '', + `email` varchar(80) NOT NULL DEFAULT '', + `msg_notify` enum('yes','no') NOT NULL DEFAULT 'yes', + `first_name` varchar(100) NOT NULL DEFAULT '', + `last_name` varchar(100) NOT NULL DEFAULT '', + `avatar` varchar(225) NOT NULL DEFAULT 'no_avatar.jpg', + `sex` enum('male','female') NOT NULL DEFAULT 'male', + `dob` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `show_dob` enum('0','1') DEFAULT '0', + `country` varchar(20) NOT NULL DEFAULT '', + `level` int(6) NOT NULL DEFAULT '4', + `usr_status` enum('Ok','ToActivate','Locked','Deleted') NOT NULL DEFAULT 'ToActivate', + `avcode` mediumtext NOT NULL, + `postal_code` varchar(20) NOT NULL DEFAULT '', + `doj` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `last_logged` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `num_visits` bigint(20) NOT NULL DEFAULT '0', + `session` varchar(32) NOT NULL DEFAULT '', + `ip` varchar(15) NOT NULL DEFAULT '', + `signup_ip` varchar(15) NOT NULL DEFAULT '', + `time_zone` tinyint(4) NOT NULL DEFAULT '0', + `profile_tags` mediumtext, + `web_url` varchar(200) NOT NULL DEFAULT '', + `hometown` varchar(100) NOT NULL DEFAULT '', + `city` varchar(100) NOT NULL DEFAULT '', + `zip` varchar(15) NOT NULL DEFAULT '', + `privacy` enum('Online','Offline','Custom') NOT NULL DEFAULT 'Online', + `show_profile` enum('All','Members','Friends') NOT NULL DEFAULT 'All', + `allow_comment` enum('Yes','No') NOT NULL DEFAULT 'Yes', + `allow_rating` enum('Yes','No') NOT NULL DEFAULT 'Yes', + `content_filter` enum('Nothing','On','Off') NOT NULL DEFAULT 'Nothing', + `featured` enum('No','Yes') NOT NULL DEFAULT 'No', + `profile_hits` bigint(20) DEFAULT '0', + `total_watched` bigint(20) NOT NULL DEFAULT '0', + `total_videos` bigint(20) NOT NULL, + `total_comments` bigint(20) NOT NULL, + `icon_id` bigint(20) NOT NULL DEFAULT '0', + `browse_criteria` mediumtext, + `icon_use_last_uploaded` enum('No','Photo','Video','Both') NOT NULL DEFAULT 'No', + `about_me` mediumtext NOT NULL, + `education` varchar(3) DEFAULT NULL, + `schools` mediumtext NOT NULL, + `occupation` mediumtext NOT NULL, + `companies` mediumtext NOT NULL, + `relation_status` char(3) DEFAULT NULL, + `ban_status` enum('yes','no') NOT NULL DEFAULT 'no', + `hobbies` mediumtext NOT NULL, + `fav_movies` mediumtext NOT NULL, + `fav_music` mediumtext NOT NULL, + `fav_books` mediumtext NOT NULL, + `upload` varchar(20) NOT NULL DEFAULT '1', + `subscribers` varchar(25) NOT NULL DEFAULT '0', + `background` mediumtext NOT NULL, + `total_groups` bigint(20) NOT NULL, + `last_active` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`userid`), + KEY `ind_status_doj` (`usr_status`,`doj`), + KEY `ind_status_id` (`usr_status`,`userid`), + KEY `ind_hits_doj` (`profile_hits`,`doj`), + FULLTEXT KEY `profile_tags` (`profile_tags`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=7 ; + +-- +-- Dumping data for table `users` +-- + +INSERT INTO `users` (`userid`, `channel_title`, `channel_des`, `featured_video`, `username`, `user_session_key`, `user_session_code`, `password`, `email`, `msg_notify`, `first_name`, `last_name`, `avatar`, `sex`, `dob`, `show_dob`, `country`, `level`, `usr_status`, `avcode`, `postal_code`, `doj`, `last_logged`, `num_visits`, `session`, `ip`, `signup_ip`, `time_zone`, `profile_tags`, `web_url`, `hometown`, `city`, `zip`, `privacy`, `show_profile`, `allow_comment`, `allow_rating`, `content_filter`, `featured`, `profile_hits`, `total_watched`, `total_videos`, `total_comments`, `icon_id`, `browse_criteria`, `icon_use_last_uploaded`, `about_me`, `education`, `schools`, `occupation`, `companies`, `relation_status`, `ban_status`, `hobbies`, `fav_movies`, `fav_music`, `fav_books`, `upload`, `subscribers`, `background`, `total_groups`, `last_active`) VALUES +(1, '', '', '', 'admin', '777750fea4d3bd585bf47dc1873619fc', 10192, '38d8e594a1ddbd29fdba0de385d4fefa', '', 'yes', '', '', '1.jpg', 'male', '0000-00-00 00:00:00', '0', '', 1, 'Ok', '', '', '2008-11-23 17:12:43', '2009-07-04 13:11:25', 56, 'pub6e7fq5oj76vakuov2j03hm1', '127.0.0.1', '', 0, NULL, '', '', '', '', 'Online', 'All', 'Yes', 'Yes', 'Nothing', 'No', 7, 190, 5, 1, 0, NULL, 'No', '', '', '', '', '', '0', 'no', '', '', '', '', '1', '1', 'cf6cc2b886.jpg', 3, '2009-06-14 03:00:36'), +(4, '', '', '', 'arslan', '2de50e2ee0c8c8251eda1fa9b9e002a6', 33925, '767a075ceec94a7c6de64d622520644e', 'arslan@localhost.com', 'yes', 'asd', 'asd', 'no_avatar.jpg', 'male', '1962-02-18 00:00:00', '0', 'Afghanistan', 2, 'Ok', 'e799bbc05a', '', '2009-02-01 18:52:35', '2009-06-14 21:02:37', 3, 'kvs4dioh81p5tau5p7214qjvo6', '127.0.0.1', '127.0.0.1', 0, NULL, '', '', '', '', 'Online', 'All', 'Yes', 'Yes', 'Nothing', 'No', 2, 0, 0, 0, 0, NULL, 'No', '', NULL, '', '', '', NULL, 'no', '', '', '', '', '1', '1', '', 0, '2009-06-15 03:22:59'), +(5, '', '', '', 'thisisatestuser', '2de50e2ee0c8c8251eda1fa9b9e002a6', 65689, 'cdc1c35aada927beae13f8b1e42e9a3e', 'test@testtesttest.com', 'yes', '', '', 'no_avatar.jpg', 'male', '1989-05-14 00:00:00', '0', 'PK', 3, 'Ok', 'fe1022cba8', '', '2009-05-30 20:53:09', '2009-06-14 20:42:55', 1, '', '', '127.0.0.1', 0, NULL, '', '', '', '', 'Online', 'All', 'Yes', 'Yes', 'Nothing', 'No', 1, 0, 0, 0, 0, NULL, 'No', '', NULL, '', '', '', NULL, 'no', '', '', '', '', '1', '0', '', 0, '0000-00-00 00:00:00'), +(6, '', '', '', 'iamtesttingit', '96207e6fd7ea376e8a5e4af0b819720d', 55958, 'bc7e2dbd6c83734bb99e2afbbfab370f', 'ahzulasdfi@yahoo.com', 'yes', '', '', 'no_avatar.jpg', 'male', '1989-06-14 00:00:00', '0', 'AD', 3, 'ToActivate', 'e6c9c98653', '', '2009-06-06 04:07:37', '0000-00-00 00:00:00', 0, '', '', '127.0.0.1', 0, NULL, '', '', '', '', 'Online', 'All', 'Yes', 'Yes', 'Nothing', 'No', 0, 0, 0, 0, 0, NULL, 'No', '', NULL, '', '', '', NULL, 'no', '', '', '', '', '1', '0', '', 0, '0000-00-00 00:00:00'); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `user_levels` +-- + +CREATE TABLE IF NOT EXISTS `user_levels` ( + `user_level_id` int(20) NOT NULL AUTO_INCREMENT, + `user_level_active` enum('yes','no') CHARACTER SET latin1 NOT NULL DEFAULT 'yes', + `user_level_name` varchar(100) CHARACTER SET latin1 NOT NULL, + `user_level_is_default` enum('yes','no') NOT NULL DEFAULT 'no', + PRIMARY KEY (`user_level_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=7 ; + +-- +-- Dumping data for table `user_levels` +-- + +INSERT INTO `user_levels` (`user_level_id`, `user_level_active`, `user_level_name`, `user_level_is_default`) VALUES +(1, 'yes', 'Super Admin', 'yes'), +(2, 'yes', 'Admin', 'yes'), +(3, 'yes', 'Registered Users', 'yes'), +(4, 'yes', 'Inactive Users', 'yes'); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `user_levels_permissions` +-- + +CREATE TABLE IF NOT EXISTS `user_levels_permissions` ( + `user_level_permission_id` int(22) NOT NULL AUTO_INCREMENT, + `user_level_id` int(22) NOT NULL, + `admin_access` enum('yes','no') CHARACTER SET latin1 NOT NULL DEFAULT 'no', + `upload_access` enum('yes','no') CHARACTER SET latin1 NOT NULL DEFAULT 'no', + `channel_access` enum('yes','no') NOT NULL DEFAULT 'yes', + PRIMARY KEY (`user_level_permission_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=7 ; + +-- +-- Dumping data for table `user_levels_permissions` +-- + +INSERT INTO `user_levels_permissions` (`user_level_permission_id`, `user_level_id`, `admin_access`, `upload_access`, `channel_access`) VALUES +(1, 1, 'yes', 'yes', 'yes'), +(2, 2, 'yes', 'yes', 'yes'), +(3, 3, 'no', 'yes', 'yes'), +(4, 4, 'no', 'no', 'no'); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `validation_re` +-- + +CREATE TABLE IF NOT EXISTS `validation_re` ( + `re_id` int(25) NOT NULL AUTO_INCREMENT, + `re_name` varchar(60) CHARACTER SET utf8 NOT NULL, + `re_code` varchar(60) CHARACTER SET utf8 NOT NULL, + `re_syntax` text CHARACTER SET utf8 NOT NULL, + PRIMARY KEY (`re_id`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ; + +-- +-- Dumping data for table `validation_re` +-- + +INSERT INTO `validation_re` (`re_id`, `re_name`, `re_code`, `re_syntax`) VALUES +(1, 'Username', 'username', '^^[a-zA-Z0-9_]+$'), +(2, 'Email', 'email', '^[_a-z0-9-]+(\\.[_a-z0-9-]+)*@[a-z0-9-]+(\\.[a-z0-9-]+)*(\\.[a-z]{2,10})$'); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `video` +-- +CREATE TABLE IF NOT EXISTS `video` ( + `videoid` bigint(20) NOT NULL AUTO_INCREMENT, + `videokey` mediumtext NOT NULL, + `username` text NOT NULL, + `userid` int(11) NOT NULL, + `title` mediumtext NOT NULL, + `flv` mediumtext NOT NULL, + `file_name` varchar(32) NOT NULL, + `description` mediumtext NOT NULL, + `tags` mediumtext NOT NULL, + `category` varchar(20) NOT NULL DEFAULT '0', + `broadcast` varchar(10) NOT NULL DEFAULT '', + `location` mediumtext, + `datecreated` date DEFAULT NULL, + `country` mediumtext, + `allow_embedding` char(3) NOT NULL DEFAULT '', + `rating` int(15) NOT NULL DEFAULT '0', + `rated_by` varchar(20) NOT NULL DEFAULT '0', + `voter_ids` mediumtext NOT NULL, + `allow_comments` char(3) NOT NULL DEFAULT '', + `comment_voting` char(3) NOT NULL DEFAULT '', + `comments_count` int(15) NOT NULL DEFAULT '0', + `featured` char(3) NOT NULL DEFAULT 'no', + `featured_description` mediumtext NOT NULL, + `allow_rating` char(3) NOT NULL DEFAULT '', + `active` char(3) NOT NULL DEFAULT '0', + `favourite_count` varchar(15) NOT NULL DEFAULT '0', + `playlist_count` varchar(15) NOT NULL DEFAULT '0', + `views` bigint(22) NOT NULL DEFAULT '0', + `last_viewed` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `date_added` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + `flagged` varchar(3) NOT NULL DEFAULT 'no', + `duration` varchar(20) NOT NULL DEFAULT '00', + `status` enum('Successful','Processing') NOT NULL DEFAULT 'Processing', + `flv_file_url` text, + `default_thumb` int(3) NOT NULL DEFAULT '1', + PRIMARY KEY (`videoid`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; +-- +-- Dumping data for table `video` +-- + + +-- -------------------------------------------------------- + +-- +-- Table structure for table `video_detail` +-- + +CREATE TABLE IF NOT EXISTS `video_detail` ( + `detail_id` int(11) NOT NULL AUTO_INCREMENT, + `flv` mediumtext NOT NULL, + `original` mediumtext NOT NULL, + `duration` varchar(25) NOT NULL, + `status` varchar(15) NOT NULL DEFAULT 'Processing', + PRIMARY KEY (`detail_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; + +-- +-- Dumping data for table `video_detail` +-- + + +-- -------------------------------------------------------- + +-- +-- Table structure for table `video_favourites` +-- + +CREATE TABLE IF NOT EXISTS `video_favourites` ( + `fav_id` int(11) NOT NULL AUTO_INCREMENT, + `videoid` int(11) NOT NULL, + `userid` int(11) NOT NULL, + `date_added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`fav_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; + +-- +-- Dumping data for table `video_favourites` +-- + + +-- -------------------------------------------------------- + +-- +-- Table structure for table `video_files` +-- + +CREATE TABLE IF NOT EXISTS `video_files` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `status` int(2) NOT NULL, + `file_conversion_log` text NOT NULL, + `encoder` char(16) NOT NULL, + `src_path` text NOT NULL, + `src_name` char(64) NOT NULL, + `src_ext` char(8) NOT NULL, + `src_format` char(32) NOT NULL, + `src_duration` char(10) NOT NULL, + `src_size` char(10) NOT NULL, + `src_bitrate` char(6) NOT NULL, + `src_video_width` char(5) NOT NULL, + `src_video_height` char(5) NOT NULL, + `src_video_wh_ratio` char(10) NOT NULL, + `src_video_codec` char(16) NOT NULL, + `src_video_rate` char(10) NOT NULL, + `src_video_bitrate` char(10) NOT NULL, + `src_video_color` char(16) NOT NULL, + `src_audio_codec` char(16) NOT NULL, + `src_audio_bitrate` char(10) NOT NULL, + `src_audio_rate` char(10) NOT NULL, + `src_audio_channels` char(16) NOT NULL, + `output_path` text NOT NULL, + `output_format` char(32) NOT NULL, + `output_duration` char(10) NOT NULL, + `output_size` char(10) NOT NULL, + `output_bitrate` char(6) NOT NULL, + `output_video_width` char(5) NOT NULL, + `output_video_height` char(5) NOT NULL, + `output_video_wh_ratio` char(10) NOT NULL, + `output_video_codec` char(16) NOT NULL, + `output_video_rate` char(10) NOT NULL, + `output_video_bitrate` char(10) NOT NULL, + `output_video_color` char(16) NOT NULL, + `output_audio_codec` char(16) NOT NULL, + `output_audio_bitrate` char(10) NOT NULL, + `output_audio_rate` char(10) NOT NULL, + `output_audio_channels` char(16) NOT NULL, + PRIMARY KEY (`id`), + FULLTEXT KEY `src_bitrate` (`src_bitrate`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; + +-- +-- Dumping data for table `video_files` +-- + diff --git a/sql/upgrade.sql.txt b/sql/upgrade.sql.txt new file mode 100644 index 00000000..51415c3f --- /dev/null +++ b/sql/upgrade.sql.txt @@ -0,0 +1,26 @@ +- Please Put all the DB changes here +- Also add those changes that have been made and not been added + +ALTER TABLE `video` ADD `userid` INT NOT NULL AFTER `username` + +ALTER TABLE `video_comments` ADD `userid` INT NOT NULL AFTER `username` + +ALTER TABLE `channel_comments` ADD `userid` INT NOT NULL AFTER `username` + +ALTER TABLE `groups` ADD `userid` INT NOT NULL AFTER `username` + +ALTER TABLE `group_members` ADD `userid` INT NOT NULL AFTER `username` + +ALTER TABLE `group_posts` ADD `userid` INT NOT NULL AFTER `username` + +ALTER TABLE `group_topics` ADD `userid` INT NOT NULL AFTER `username` + +ALTER TABLE `group_videos` ADD `userid` INT NOT NULL AFTER `username` + +ALTER TABLE `messages` ADD `inbox_user_id` INT NOT NULL AFTER `sender` , +ADD `outbox_user_id` INT NOT NULL AFTER `inbox_user_id` , +ADD `sender_id` INT NOT NULL AFTER `outbox_user_id` , +ADD `reciever_id` INT NOT NULL AFTER `sender_id` + +ALTER TABLE `subscriptions` ADD `subscriber_id` INT NOT NULL AFTER `subscribed_user` , +ADD `userid` INT NOT NULL AFTER `subscriber_id` \ No newline at end of file diff --git a/upload/.htaccess b/upload/.htaccess new file mode 100644 index 00000000..57db4556 --- /dev/null +++ b/upload/.htaccess @@ -0,0 +1,153 @@ +# +# secfilterengine off +# secfilterscanPOST off +# +#Options +Indexes + +php_flag safe_mode off +php_value max_execution_time 1000 +php_value session.gc_maxlifetime 14000 +php_value output_buffering on +php_value upload_max_filesize 2147483648 +php_value post_max_size 2147483648 +#php_flag display_errors off + +Options All -Indexes +FileETag MTime Size +Options +FollowSymlinks +RewriteEngine on + + +order allow,deny +satisfy all + + +########## Begin - Rewrite rules to block out some common exploits +# +# Block out any script trying to set a mosConfig value through the URL +RewriteCond %{QUERY_STRING} mosConfig_[a-zA-Z_]{1,21}(=|\%3D) [OR] +# Block out any script trying to base64_encode crap to send via URL +RewriteCond %{QUERY_STRING} base64_encode.*\(.*\) [OR] +# Block out any script that includes a +
Email Settings
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Email Settings
Website Email
Support Email
Welcome Email
  
Email Templates
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Email Templates Instruction
Username$usernameFrom$from
Email$emailSender Email$from_email
Password$passwordVideoKey$videokey
Activation Code$avcodeVideoThumb$videothumb
Current Date$cur_dateVideoTtle$videotitle
Website Title$titleVideoDescription$videodes
Website URL$baseurlPersonalMessage$message
    
    +
  • Above Given Tags can be used in Email
  • +
  • Do Not Use Double or Single Quotation in Hyperlinks ie <a href="linkgoeshere">clickhere</a> is wrong, just type <a href=linkgoeshere.....
  • +
  • Dont Use Tags That are not allowed for the specific Template
  • +
  • You can add HTML in it
  • +
  • If you want more Templates Please ClipBucket
  • +
Signup Template
+ (Email Verification)
Welcome Message TemplateSubject:
+ +
+Message:
+ +
+ (Allowed Tags:Username,Email,CurrentDate,Websitetitle,WebsiteURL)
Activation Code Request TemplateSubject:
+ +
+Message:
+ +
+(Allowed Tags:Username,Email,ActivationCode,CurrentDate,Websitetitle,WebsiteURL)
Share This Video TemplateSubject:
+ +
+Message:
+ +
+(Allowed Tags:From,SenderEmail,,Websitetitle,WebsiteURL,Videokey,VideoThumb,VideoTtle,VideoDescription,CurrentDate)
  
  
+
+ diff --git a/upload/admin_area/styles/cbadmin/layout/global_header.html b/upload/admin_area/styles/cbadmin/layout/global_header.html new file mode 100644 index 00000000..9186c506 --- /dev/null +++ b/upload/admin_area/styles/cbadmin/layout/global_header.html @@ -0,0 +1,71 @@ + + + + +{$title} admin panel - {$subtitle} + + + + + + + + + + + + + + + + + + + + + +{literal} + + + +{/literal} + + \ No newline at end of file diff --git a/upload/admin_area/styles/cbadmin/layout/header.html b/upload/admin_area/styles/cbadmin/layout/header.html new file mode 100644 index 00000000..36815178 --- /dev/null +++ b/upload/admin_area/styles/cbadmin/layout/header.html @@ -0,0 +1,14 @@ +
+
+
+
hello {$userquery->username}
+ +
+
+ +
diff --git a/upload/admin_area/styles/cbadmin/layout/index.html b/upload/admin_area/styles/cbadmin/layout/index.html new file mode 100644 index 00000000..5a25aec1 --- /dev/null +++ b/upload/admin_area/styles/cbadmin/layout/index.html @@ -0,0 +1 @@ +Test is best \ No newline at end of file diff --git a/upload/admin_area/styles/cbadmin/layout/language_settings.html b/upload/admin_area/styles/cbadmin/layout/language_settings.html new file mode 100644 index 00000000..6dfa249b --- /dev/null +++ b/upload/admin_area/styles/cbadmin/layout/language_settings.html @@ -0,0 +1,80 @@ +{if $edit_lang != 'yes'} +Language Settings + + + + + + + + + +
ID
Default
Language
Language Code
Regular Expression
Actions
+ +
+{section name=l_list loop=$language_list} +
+ + + + + + + + + +
{$language_list[l_list].language_id}{$language_list[l_list].language_name}{$language_list[l_list].language_code}{$language_list[l_list].language_regex} + Edit Phrases
+
+{/section} +
+{else} +Editing {$lang_details.language_name} Phrases + +
+ +
+ + + + + + + + + + + +
ID
Phrase Code
Phrase
+ +{section name=p_list loop=$lang_phrases} +
+ + + + + + + +
{$lang_phrases[p_list].id}{$lang_phrases[p_list].varname}
{$lang_phrases[p_list].text}
+
+{/section} + + +{include file="$style_dir/blocks/pagination.html" } + +{/if} \ No newline at end of file diff --git a/upload/admin_area/styles/cbadmin/layout/left_menu.html b/upload/admin_area/styles/cbadmin/layout/left_menu.html new file mode 100644 index 00000000..900a2a9d --- /dev/null +++ b/upload/admin_area/styles/cbadmin/layout/left_menu.html @@ -0,0 +1,19 @@ +
+{assign var='menu' value = $Cbucket->AdminMenu} +{foreach from=$menu key=name item=menu} + +
+
{$name}
+
+ +
+
+ +{/foreach} + +
+ diff --git a/upload/admin_area/styles/cbadmin/layout/login.html b/upload/admin_area/styles/cbadmin/layout/login.html new file mode 100644 index 00000000..f0a45f06 --- /dev/null +++ b/upload/admin_area/styles/cbadmin/layout/login.html @@ -0,0 +1,32 @@ + +
+
+
+ + + + + + + + + + + + + + + + +
+ +
+ +
+
+
+
+ + diff --git a/upload/admin_area/styles/cbadmin/layout/main.html b/upload/admin_area/styles/cbadmin/layout/main.html new file mode 100644 index 00000000..75cf03ce --- /dev/null +++ b/upload/admin_area/styles/cbadmin/layout/main.html @@ -0,0 +1,391 @@ +
    +
  • Website Settings
  • +
  • Uploading and Conversion Settings
  • +
  • Display and Listing Settings
  • +
  • User & Registeration
  • +
+ +
+ +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Website title
Website slogan
Website closed
Closed message
  
Meta Description
Meta Keywords
  
Default Language
SEO Urls
  
Allow template change
Allow language change
  
Require login to watch videos ?
  
Allow comments +
+ + User can comment on his/her own video/channel
Maximum character count
Allow ratings +
+ + User can rate his/her video/channel
Allow comments rating
Allow video embedding
Allow video download
  
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FFMPEG Binary Path
PHP Binary Path
Allow video uploading
Allowed extensions
Max upload file size + in MegaBytes
Save original file
Activation required
  
Converting video height and thumbs settings
  
Video Width
Video Height
Resize Type 
Thumb Width
Thumb Height
Number of thumbs
Big Thumb Width
Big Thumb Height
  
Change only if you have good knowledge of video conversion
  
Video Rate
Video Bitrate
Audio Rate
Audio Bitrate
  
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current Templatemanage templates
Current FLV Playermanage flv players
  
Videos per page
Videos per tab or section
Channels per page
Channels per tab or section
Search results per page
Recently viewed videos
  
+
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Turn on registerations
Email verification
Image verification (captcha)
Username maximum characters
Disallowed usernames
Minimum age for registeration + leave blank to disable this option
  
+
+
+
+
+
diff --git a/upload/admin_area/styles/cbadmin/layout/msg.html b/upload/admin_area/styles/cbadmin/layout/msg.html new file mode 100644 index 00000000..a70ea544 --- /dev/null +++ b/upload/admin_area/styles/cbadmin/layout/msg.html @@ -0,0 +1,32 @@ + + +{assign var=msg value=$eh->message_list} +{assign var=err value=$eh->error_list} +{if $err.0 neq ''} + + + + +
+
    + + {foreach from=$err item=show_msg} +
  • {$show_msg}
  • + {/foreach} +

+ +{/if} + +{if $msg.0 neq ''} + + + + +
+
    + + {foreach from=$msg item=show_msg} +
  • {$show_msg}
  • + {/foreach} +

+{/if} diff --git a/upload/admin_area/styles/cbadmin/layout/plugin_manager.html b/upload/admin_area/styles/cbadmin/layout/plugin_manager.html new file mode 100644 index 00000000..1f8ae4a9 --- /dev/null +++ b/upload/admin_area/styles/cbadmin/layout/plugin_manager.html @@ -0,0 +1,69 @@ + + +
Installed Plugins
+ + + + + + + +{assign var = bgcolor value = ""} +{foreach from=$installed_plugin_list item=plug name=item} + + + + + + {if $bgcolor == ""} + {assign var = bgcolor value = "#EEEEEE"} + {else} + {assign var = bgcolor value = ""} + {/if} + {foreachelse} + + + + + + {/foreach} +
#Pluin DetailsActions
{$smarty.foreach.item.iteration}{$plug.name} by {$plug.author}
+ {$plug.description} - +{$plug.website}
+Version : {$plug.version} +
{if $plug.plugin_active == 'yes'}Deactivate{else}Activate{/if}
+ Uninstall
 No Installed Plugin Found 
+ +{* Listing New Plugins *} +
Available Plugins
+ + + + + + + +{assign var = bgcolor value = ""} +{foreach from=$new_plugin_list item=plug name=item} + + + + + + {if $bgcolor == ""} + {assign var = bgcolor value = "#EEEEEE"} + {else} + {assign var = bgcolor value = ""} + {/if} + {foreachelse} + + + + + + {/foreach} +
#Pluin DetailsActions
{$smarty.foreach.item.iteration}{$plug.name} by {$plug.author}
+ {$plug.description} - +{$plug.website}
+Version : {$plug.version} +
Install Plugin
 No New Plugin Found 
\ No newline at end of file diff --git a/upload/admin_area/styles/cbadmin/layout/video_manager.html b/upload/admin_area/styles/cbadmin/layout/video_manager.html new file mode 100644 index 00000000..60dab482 --- /dev/null +++ b/upload/admin_area/styles/cbadmin/layout/video_manager.html @@ -0,0 +1,163 @@ + +Video Manager + + + + + + +
+ + + + + + +
+ + + + + + +
+ + + + + + + + + +
+ VID
Details
 
+ + + + + + +{assign var = bgcolor value = ""} +{section name=list loop=$videos} + + + + + + + {if $bgcolor == ""} + {assign var = bgcolor value = "#EEEEEE"} + {else} + {assign var = bgcolor value = ""} + {/if} + +{/section} +
{$videos[list].videoid} + + {$videos[list].title} + — + + Featured:{$videos[list].featured} • + Active:{$videos[list].active} • + Status:{$videos[list].status} + + +
+ +
 
+ + + + + + + +
+ + + + + + +
+ +
+ + +{include file="$style_dir/blocks/pagination.html" } \ No newline at end of file diff --git a/upload/admin_area/styles/cbadmin/layout/view_conversion_log.html b/upload/admin_area/styles/cbadmin/layout/view_conversion_log.html new file mode 100644 index 00000000..eee49d6a --- /dev/null +++ b/upload/admin_area/styles/cbadmin/layout/view_conversion_log.html @@ -0,0 +1,57 @@ +{if $data.id} +
+Conversion Log For File "{$data.src_name}" + + + + + + + +
Source File Information
+ + + {foreach from=$data item=value key=field} + {if $field|truncate:4:'' == src_} + + + + + {/if} + {/foreach} + + + + + + + + {foreach from=$data item=value key=field} + {if $field|truncate:7:'' == output_} + + + + + {/if} + {/foreach} + + + + + +
Source {$field|substr:4:100|replace:'_':' '}{$value}
  
Output File Information
Output File {$field|substr:7:100|replace:'_':' '}{$value}
  
+ + + + + + +
Conversion log for "{$data.src_name}"
+
+
+
{$data.file_conversion_log|nl2br}
+
+ +
+{else} File does not exist +{/if} \ No newline at end of file diff --git a/upload/admin_area/styles/cbadmin/layout/view_video.html b/upload/admin_area/styles/cbadmin/layout/view_video.html new file mode 100644 index 00000000..6c755dec --- /dev/null +++ b/upload/admin_area/styles/cbadmin/layout/view_video.html @@ -0,0 +1,197 @@ +{assign var='requiredFields' value=$Upload->loadRequiredFields($data)} +{assign var='optionFields' value=$Upload->loadOptionFields($data)} +{assign var='locationFields' value=$Upload->loadLocationFields($data)} + +{assign var='custom_fields' value=$Upload->load_custom_upload_fields($data,TRUE)} +{assign var='custom_form_fields' value=$Upload->load_custom_form_fields($data,TRUE)} + + + + + + + +
Viewing {$data.title}  
+ + +
+ + +
+ + + + + + + + + + + + + + + + + + +
+ + + + + + + {foreach from=$requiredFields item=field} + + + + + {/foreach} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {foreach from=$optionFields item=field} + + + + + {/foreach} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {foreach from=$custom_fields item=field} + + + + + + {foreachelse} + + + + + {/foreach} + + + + + + + + {foreach from=$custom_form_fields item=field} + + + + + + {foreachelse} + + + + + {/foreach} + + + + + + + + + + + + + + + + + + + +
 
Information
{$field.title}{ANCHOR place=$field.anchor_before}{input_value input=$field}
  
Important Details and Files information
Video Id{$data.videoid}
Video Key{$data.videokey}
File Name{$data.file_name}
Video Files{get_all_video_files vdetails=$data count_only=true}
Thumb Files {get_thumb vdetails=$data count_only=true}
 {assign var=vidthumbs value=func->get_thumb($data,1,TRUE)} + + {foreach from=$vidthumbs item=vid_thumb} +
+
+ {if $data.default_thumb==$vid_thumb|get_thumb_num}Default{/if} +
+ {/foreach} + +
View File Details and Converion Log
  
Sharing Options
{$field.title}{ANCHOR place=$field.anchor_before}{input_value input=$field}
  
Stats
Views{$data.views}
Rating{$data.rating} + of 10
RatedBy{$data.rated_by}
Duration{$data.duration|SetTime}
  
Custom Upload Options
{$field.title}{$field.value|form_val}
No Custom Fields
  
Custom Form Fields
{$field.title}{$field.value|form_val}
No Custom Fields
  
User Information
User id{$udata.userid}
User name{$udata.username}
Videos Uploaded{$userquery->get_user_vids($data.userid,'',true)}
+ This content requires JavaScript and Macromedia Flash Player 7 or higher. Get Flash

+
+
  
Video Comments
{assign var=id value=$data.videoid}{include file="$style_dir/blocks/comments.html" type=v id=$data.videoid link="video=$id"}
diff --git a/upload/admin_area/styles/cbadmin/theme/cbtab.css b/upload/admin_area/styles/cbadmin/theme/cbtab.css new file mode 100644 index 00000000..4cefecaf --- /dev/null +++ b/upload/admin_area/styles/cbadmin/theme/cbtab.css @@ -0,0 +1,36 @@ +@charset "utf-8"; +/* CSS Document */ + + +.cbtab{margin:0px; padding:0px} + +.cbtab li +{ + list-style-type:none; + padding:0px 10px; + background-color:#009; + margin:2px; background-image:url(../images/bgs/round_bg.png); + background-position:0px -52px; height:26px; line-height:26px; + font-size:12px; color:#FFF; + font-weight:bold; + -moz-border-radius-topleft:5px; + -webkit-border-top-left-radius:5px; + -moz-border-radius-topright:5px; + -webkit-border-top-right-radius:5px; + border:2px #d2d2d2 solid; + border-bottom:none; + cursor:pointer; + float:left; + margin-bottom:0px; +} + +.cbtab .selected{background:#333} + +.main_page_div{min-height:200px; border:1px solid #d2d2d2; width:95%; margin-left:2px; padding:5px; +-moz-border-radius-bottomleft:5px; +-webkit-border-bottom-left-radius:5px; +-moz-border-radius-bottomright:5px; +-webkit-border-bottom-right-radius:5px; +-moz-border-radius-topright:5px; +-webkit-border-top-right-radius:5px; +} \ No newline at end of file diff --git a/upload/admin_area/styles/cbadmin/theme/pagination.css b/upload/admin_area/styles/cbadmin/theme/pagination.css new file mode 100644 index 00000000..7d91ca1b --- /dev/null +++ b/upload/admin_area/styles/cbadmin/theme/pagination.css @@ -0,0 +1,17 @@ +/* Css Document */ + +.pagination +{ + background-image:url(../images/bgs/pagination_bg.png); + background-repeat:repeat-x; + height:23px; + width:99%; + margin:auto; + line-height:23px; + color:#FFF;font-weight:bold; font-size:12px; font-family:Arial, Helvetica, sans-serif; +} + + +.pagination a, .pagination .selected{color:#FFF; font-weight:bold; font-size:13px; font-family:Arial, Helvetica, sans-serif; text-decoration:none; margin:0px 3px 0px 3px; } + +.pagination .selected{color:#FFFF97; text-decoration:underline;} \ No newline at end of file diff --git a/upload/admin_area/styles/cbadmin/theme/slidemenu.css b/upload/admin_area/styles/cbadmin/theme/slidemenu.css new file mode 100644 index 00000000..bbcac4a7 --- /dev/null +++ b/upload/admin_area/styles/cbadmin/theme/slidemenu.css @@ -0,0 +1,81 @@ +.left_menu +{ + width: 230px; + padding-left: 5px; + float:left; +} + +.mainDiv +{ + margin-top:5px; + width:211px; +} + +.topItem,.topItemOver,.topItemClose,.topItemCloseOver +{ + letter-spacing: 0; + background-position:center center; + background-repeat:no-repeat; + border: none; + width: 211px; + height: 26px; + color: #FFFFFF; + cursor:pointer; + text-indent:10px; + font-family: Arial, Helvetica, sans-serif; + font-size: 12px; + font-weight: bold; + line-height:26px; +} +.topItem{background: url("../images/bgs/left_menu_head.png") no-repeat 0 -26px;} +.topItemOver{background: url("../images/bgs/left_menu_head.png") no-repeat 0 -52px;} +.topItemClose{background: url("../images/bgs/left_menu_head.png") no-repeat 0 0;} +.topItemCloseOver{background: url("../images/bgs/left_menu_head.png") no-repeat 0 -26px;} + + + +.dropMenu +{ + font: bold 11px tahoma,verdana,sans-serif; + color: #000; + filter:alpha(opacity=100); + background-image:url(../images/bgs/left_menu_foot.png); + background-position:bottom; + background-repeat:no-repeat; + padding-bottom:15px +} + +.subMenu +{ + display:block; +} + +.subItem,.subItemOver +{ + font: 11px tahoma,verdana,sans-serif; + text-decoration:none; + color: #215dc6; + +} + +.subItem a,.subItemOver a +{ + font-size:12px; + font-weight:bold; + color:#333; + display:block; + padding-left:10px; + text-decoration:none; + font-family:Arial, Helvetica, sans-serif; + margin:2px 0px 2px 0px; +} +.subItem a:hover,.subItemOver a:hover{ +background-color:#e9f6ff; +color:#2b495d; +} + +.drop +{ + border-left:1px solid black; + border-right:1px solid black; +} diff --git a/upload/admin_area/styles/cbadmin/theme/stylesheet.css b/upload/admin_area/styles/cbadmin/theme/stylesheet.css new file mode 100644 index 00000000..1d8bf160 --- /dev/null +++ b/upload/admin_area/styles/cbadmin/theme/stylesheet.css @@ -0,0 +1,116 @@ +@import url("slidemenu.css"); +@import url("pagination.css"); +@import url("cbtab.css"); + +@charset "utf-8"; +/* CSS Document */ + +BODY +{ + margin:0px; + padding:0px; + font-size:12px; + color:#333; + font-family:Arial, Helvetica, sans-serif; + background:#FFF; + min-width:800px +} + +a{font-size:12px; font-weight:bold; text-decoration:none; color:#147dc3; font-family:Arial, Helvetica, sans-serif} + +.clear{clear:both} +#body{background-image:url(../images/bgs/gr_bg.png); background-repeat:repeat-x; min-height:500px; } +.container{margin-left:230px} + +#admin_menu{width:212px; height:25px; background-image:url(../images/bgs/admin_menu_bg.png); background-repeat:no-repeat;color:#FFF; padding-left:5px; padding-top:4px; cursor:pointer} +#admin_menu_bar{ width:212px;background-repeat:no-repeat; float:right; margin-right:10px; } +#menu{margin-top:2px; background-image:url(../images/bgs/menu_bg.png); width:209px; height:209px; position:absolute} + +.admin_logo{background-image:url(../images/logo.png); width:221px; height:29px; margin:5px} + +.page_title{font-size:20px; font-weight:bold; color:#333} + +/** + * Page Table Tops + */ +.head_title,.left_head,.head,.right_head,.head_sep_left,.head_sep_right,.left_head a,.head a,.right_head a,.head_sep_left a,.head_sep_right a{line-height:26px; color:#FFF; font-size:12px; font-family:Arial, Helvetica, sans-serif; font-weight:bold} +.left_head{background-image:url(../images/bgs/round_bg.png); background-position:0px 0px; height:26px} +.head_title,.head{background-image:url(../images/bgs/round_bg.png); background-position:right -52px; height:26px} +.right_head{background-image:url(../images/bgs/round_bg.png); background-position:right -26px; height:26px} +.head_sep_left{background-image:url(../images/bgs/round_bg.png); background-position:left -130px; height:26px; text-indent:10px;} +.head_sep_right{background-image:url(../images/bgs/round_bg.png); background-position:right -156px; height:26px} + + +.admin_td,.video_opt_td{color:#333; font-size:12px;} +.video_opt_td{height:45px; border-bottom:1px solid #ccc; padding-top:5px} +.video_opt_td a{font-size:13px; font-weight:bold; color:#0c4469; text-decoration:none} +.vid_opts{border:1px solid #ccc; padding:2px; display:inline;-moz-border-radius: 5px; +-webkit-border-radius: 5px; border:0px solid #EAEEFF;} .vdo_sets{font-size:11px; text-transform:uppercase; font-family: Consolas, Monaco, Courier, monospace;} + + +/** + * Forms + */ +.button{background-image:url(../images/button_bg.png); height:22px; color:#FFF; font-weight:bold; border:1px; line-height:22px; -moz-border-radius: 8px; +-webkit-border-radius: 8px; border:1px solid #146194; cursor:pointer} + +.button:focus{background-position:-0 -22px} + +.fieldset{-moz-border-radius: 5px; +-webkit-border-radius: 5px; border:2px solid #EAEEFF; width:98%; margin:0px; padding:0px; margin:auto; margin-top:15px} + +.fieldset select,.fieldset input,.fieldset textarea{border:1px solid #CCC; font-size:11px; margin:2px; padding:2px} + +.fieldset .block{margin:5px} +.fieldset legend{margin:2px; font-size:13px; font-weight:bold; color:#147dc3} + + +/** + * Forms End + */ +.block tr td{padding:2px; border-bottom:1px dotted #eee; } +.block tr:hover{background-color:#f8f8f8} + +.head_title{text-indent:5px; padding:0px} + + +#menu, #menu a{color:#FFF; font-size:11px; font-family:Arial, Helvetica, sans-serif; text-decoration:none} +#menu a{font-weight:bold} +#menu ul, #menu ul li{padding:0px; margin:0px; list-style-type:none} +#menu ul{margin:8px} + +.hint{font-size:11px;} + +#login_box{ + height:250px; + width:400px; + background-image:url(../images/login.png); + background-repeat:no-repeat; + margin:auto; + background-position:center; + padding-top: 150px; +} + +#login_box .textfield{ + height:30px; + width: 280px; + margin-bottom: 10px; + -moz-border-radius: 5px; +-webkit-border-radius: 5px; border:1px solid #ccc; +line-height:30px; +padding-left:5px; font-size:16px; font-weight:bold; font-family:Arial, Helvetica, sans-serif; padding-top:5px; color:#6E6E6E +} +#login_box label{ + font-size:18px; + color: #494949; +} + + +.row_white{border-bottom:1px dotted #646464; width:98%; margin:auto} +.row_white:hover{background-color:#F3F3F3} + + + +.search_box{margin:5px; padding:5px; border:1px solid #146194; border-radius:5px; -moz-border-radius:5px; -webkit-border-radius:5px; background:#eff9ff} + +.video_search .input{border:1px solid #666} \ No newline at end of file diff --git a/upload/admin_area/styles/clipbucketblue/images/arrow-down-title-on.jpg b/upload/admin_area/styles/clipbucketblue/images/arrow-down-title-on.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b49c880ba349f48494acb7df26c7074677c8e04d GIT binary patch literal 1655 zcmb`HdoT>E@ydE+FM(B# zc2qk6L;wI+J^jRPi#5W*$1R>=s zghV0#0)<9>293sG6fhVx7K_7Su}a?qLJ)*PqOfQ*R#_3NsI00YM^*Lnr7xS(-`V%N zZ<(wfz$*Z2fEozI0|-0_;Xzp=Ae7sdI|1cBzk*Q!Q3wc)1wjA;<$SFJ01Aykf{?;0 z06;=$6as;RzMO#w2#-Yhis-A=(YnS2HH;0>MIo&8ac0?*<7Z7Ze>P{~RTqx97@UHu2yb3jRM3xS95fHhF%*>;i@B|a1m zGcH9mABeEmBL-W*kym1sMOvw-_65PTmEMUi(_T{o-K)a>Fl*NHDPwtFGIq8S``Af9 zkdS+_ZL^6R0xU8juIy=PUL#H9{nu#(CyB`Pv=qaQ0v^fI!Ap4C_tngc%(BYKF4KwP zEwQ+mGe7yZXB+50;kr*18~HfaCb#fa(00K?;HB{;NeI4)ENndO?l%-lsvRDB#upzM z5E<+|)*-3%v*%$B?<}4#R0&+B#+A-23^h4e)v$C#wQYy4z~$!C>$sUI@a`FDFF$6M z)D)Z(9&F@fm+r^(#$~MRT+m1@zESXCv$uzB@U_Z-S*4TEFsoK710Lxu2K6c=>1IIf#; zH;vOu;qxdj&1SdmHpF!$&Zc1hcsAPjyqQUTQKDwsTDhhn%|G3#g#5DE`Ya+a>Y3+ zml~R?J4Jmr47FCxGA)cd3MDjyGRgqKTHEVHf5EMqATlR`=}cS_Q_6globLhpy3gYkTh=k1tNZlT^5o5mN!!mR9~khlw4W0k7GzFL>hQ}P1X z4jH|QguQ~_&pwpSlBy?+t_k+Nr&LFr8D$-jx9^phV=_@5aI>n;K7=J-vr%& zv+4PQ2)s^Z&`0qe6sb+1IV6S?3K-iCvK{zKQR^$ubr~LNBKw){FN#}f3lmRq4%Gx@5?7=Z@Uk z@+@!bc5Sh)R%TEN-^S8{xY1)uni0};XqkX`AoopbRjrKa#Tm!zHT+F8?abo1PE8++*n!bgRD?;u4-m&aliKL>(g7==V((P*ra0#-q3{W=-z*MB_pX;b_w`&_q{ zNqYcJ4rl^C4B-F*2f;Wi_$yloc6dHqsU^!&~kT3>@ zAz0~C4?@5=Br2@NOGQ-;t%Jvy66EYX%`_5PMo+emZAmJzIBZG70SJarXe0{t_l*z^ z0qfvZkSJ4o&#)iSuM@I*M+s&Q>Mc(fy)8CK9|A>K<_!nq010#+7^p z5|NLywH78dCOII>Y4uiDdOj@YCjiCY}_m(XSA3{o9L`(+*|IpRjktmx1vV^Cd>#Tdac@(?nII5 zOkRn9A~j`YHo)Aj`Hb*PWBZt844E1i%Q;kO9Q3Rxn43neDs3FZ)1$^IsWp6lk~v`~ zLElMOXy{NI!YU{b$L!iwe$R|sO31&o?{ay0YeiARiQ!r6_5g3{q^7=jhRs#SEIRF! zg54wYhAY{asq>Ql?MK8|DF{eiCc4k~sl|6qn!hmRm!S@97|?h$ggB=#tr#1b<%?R( z`O>V1_ucP(8!JM6dNaZbhtC^KUEMM8K@*}8p0r*5qDjI3CA>GzpdX(5#bLvv7z5?( zOpM^H#3y{tnJp+fK(bhr(4|0aQ3_6EP)s#PwAm1Svg)gtbAH@dPrQ6Ej72PYM3#v zwZo-l^-BCycHL4LgBIM}yBeCrePq{^o%pTatHSEXb#<-klz;}bd*=oIt;v?W(RwNH z=B4>b`sp8@SIg&(ai3*Ie!eiZpTTk94snB-mG3H&4JhRaxK$dv!(baxKe#@;*svmp z&SLZi=@w7lcqxeFMluFV9izyBD@#EGTp8fN7Udj8-798oLh-l=ZB$=mZIz z^KhZj(M|u>oKe$vrf|r3&pkIZg10WHyyZ)<`@;*Ca{Y7Psj^#3eahUUTVG~srd?bi z%84mw^vTHI#6Q$TcQxB|sCR~B^0YHNZm%A>9OhisIGWk-YSI=n=ZZejhC5_K zJLTeXx{)XF3fZVQ;XBR{@w2J!o_T@qxh1|&y7Cw(O{edNKWC!432 UjlU?BOp;gZ(3)ZAHcKD;2^=t#?*IS* literal 0 HcmV?d00001 diff --git a/upload/admin_area/styles/clipbucketblue/images/arrow-up-title-on.jpg b/upload/admin_area/styles/clipbucketblue/images/arrow-up-title-on.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ebe9ef754192d5ef26ea8432d6bde7d9c0eda764 GIT binary patch literal 1663 zcmex=uI=H%w(=K}(Mey}1a#RK7?>VxzCA7BvVV31_k$;>Foz$D1XEXer(2*Z4!vw<#Q z1iBLj*f|(knON9385tRv8G!&M&cMLR#?HdX%pm~uJu@3C6B8RZL=I>K&@Y0C3x!45 z426P3*cFumIUEZcH(r!5a+tal_7Jxg?J*?85yY_ z*NPKeK1o{gK!n9Sm0$Bi_vFsbnZ>E87p1&)b=NwrRdv;O%RO(myjbSb87i9Nqv#_j zym_9x)mNn_$vm$w9;OsalpKz@Zh3@lOO#id^Oe?<+mHT}s{1;zai_UU#iuKg2WNUO zK2X{8;zNCyPDbx{wmnr_*DBmh+Q-4Hm5ssMnGSyWcR89R;B>3)>ZxI(+eH1Xt4}>QF)!~juU`3RsZiKr4QXS) zRo=Hw6c;_2z&$gQ{fgM$zAd#0O(nd$w#~0u8ZwhhPf+Q>p1mUH%&oZQwyhNl$(nIk zC~3~+_f7}?Wjx#e{K3D=`#T+Kx!FHyCjVzx;QlA`_K~GlGhUQ&eV=oF%durvvQ6ny z$-%OG2aS6TSN63h%se*Z%5monK97B}k{8}kD_mx3c;St(#bqg=9?m(Ly*?$@Eayz9 zq|rD&bme5fIXuZfd(*YPw z*JIk*l9IiOZo6B*t>dV$YP)vdjht+ac#cbo9Z%x^B6 zE>tw;wjJhs>AC-~sLhQc*Q^6OeiT3E)BG0p=$5usnMPL1(Rr*c9+&y$;$a8NYTvpodh%)JS+{rY49R!V@w7^3^S6$^GWqq5#7Lw0&r0)N%U@V? z3mA~xUguJ8rJXO#t?Ik6He^L;WV!db%gMWV!gekxW~g1Ce{`Lg<&r|y!b?{U25U)f z&|c#4cX!{dQ<+mXCrve!(g@uz_w>M}Z`<{nXCBWkVwYWeLZ)oHLgB4DjU;moUK%`` zwj)YLM^Pe8eZ5HK(%WJ|;rZ`YN?he~we4$mTYGwgYrnSMC(cH}`AZ@!U0bKkW{_ES zAe6u6W#?q&u2lP1;SqV;yAr$ZpSiG&Z}n6yj?|Flr+Rt9Zyqc>sP{Cr5m_ue^O4mv2s;_BCYl$xv@y|B&1Z zr^EY=m!9a(pQThemAl~TcKJ!>(W^~4%UxH7aI3udl9`aiA+WPAMxt)o-lONX9y=dY z*O(xsc6HmSTTisKK6k0UEu8u8_nN!c7K#c_F<82P)=Ja5uV!Z literal 0 HcmV?d00001 diff --git a/upload/admin_area/styles/clipbucketblue/images/arrow-up-title.jpg b/upload/admin_area/styles/clipbucketblue/images/arrow-up-title.jpg new file mode 100644 index 0000000000000000000000000000000000000000..95e70833b57dec25418d3924eb7b48cc17c5d3d6 GIT binary patch literal 1642 zcmex=uI=H%w(=K}(Mey}1a#RK7?>VxzCA7BvVV31_k$;>Foz$D1XEXer(2*Vtpvw zMA!|Lj5r(v3za1{UUZtY=~D4zlM*qrFhP($RyJmk$xw}gOhU|x!oUFdVCWc_II-}c zQ{%;lAC-)PO~f{e|G&k+!wfWAkXewyo?%<`>6)i-rUr%`dB|1Z;ydS+ z<@J@~$`a{ueH7!v%cPF&Jf~o~=u%LM-4Z?Defl3Re_zwXdvcfZ@o9_B@tlg4V?HD9 z-u%lj*(HC6>ErIGOT5#hD{gF_^PeFsq-oK`!x7hXqTfE5$2N1hNvYP9N&7TK)3z$! zO*eg}A00r*5&xzpUz%#aR%VA?)?Mp!(K!{L6Mjq!I5zi_jb&$r@uzjV zolIU~GCO~7?-RK7%x&vM&Tm_!ZF42wg}O~TE*tf)ujcCScXx7k?#)`sYGqOTaqr5L z(&f6pe<<=?*;D)E{?wDJ^#0v8eq0)me5jeZ*3&urChPjb??%cNb5{G`J+?t?_ao+6 z$Gr~sE}XUKQm<umJYcziXo4y>D~{PscFV}q*(Ta%Us zN@;}dv*SK+>DzX_=9$N{i`Zq?o{%Zqu26XEP9w=&gO>)+rtOH5(NUD}@we0XZ2!Y# z%Utf#;73<7LvG|xUlgADuw%2(q>J1!FDrU~oH0Ccn_Jh6t?BY9u7%HM#Vz%?wod+P z*5O_EGC!K=G=~K*^^=O2?`7n=@0|DXji%xIlKeDPj_Tm^SQ(&x_Xg%(ZY99+a7;% zdtI8gQ18W7t;UqOa=kh{j!fc)r|HPRuFLM03`rr1vdX9hL>v)B~ zUHSN3Nb2+Z}M{P)L1xL(H0S8fWG?KIgrA-~G{%CxhbU1NVEr=Wy=jaER6#uAg5%lsOEHE6dDF{0PY+!M+%2!bMa!qG%9 zTM0GgQc4!YKp`%Z+ci-S6@mi8$Va?0&+NL@>Kz^@Iy<9Bzt?z=Ln7hO%dz3;3#9@b z@9#bOxvMzG0z^r*_Dt z#mr|PWhc8^mOgz6SYT7QO0iOXx41m_aAdG2Nt!$G`a|y3%KE)bCf(nMA!9thyO*-n z^Qr8!`@`svtLx(PaCLj{bABK7?H1?h*wBN)zGn8n00RKm?BiJa%q{Bx0000eOSYYtbpBV}~vsBnU!_?2tr-P=|^T zED%wc9ezHgW@NMb!^uT_|SvCpFLJylbx zY%bpaTGI8IYXMN$9w<3j9VkA~NYOKEQXsj?6a9_hcwfU$acAhJhB)zb_w@MVUEy@S zX&I>K-R!bhu3?(6bHWIg$HEl7{9g>>&l_qdd+UYb(1~BCo9LptNq&8>!yoJ3Ui(i5 zRJ|XnYBklL!{@$-7=3mJ>P@1c=7Oc79e-V7yf+%lD2!I;Y&nXBZ>=B!5?CB>LvEx6 znI%n)qqi$#X#wKB(U7XP2P=+4{b@j#r%9-K(8UqtSDk>0UKzf*HM9yqMZ1D!$2MdZ zR=`U>0zhOH1XqN?nY@AQqB7)Fp4{v&dKXvb43hZKvnN8;Po;+jY*}~*Z|W9Q0W%{D z^T}Cc<|r(Su=1K=P5>Z4 zg`et&Va}tdzBS-G-ZcO)zCWpJvGQwrHZ`@wpM420ac@bI5~KkTFfGEM3sPWO8co4^fI6lPnA)Y{ef%@{+SnoUk0+dW+*{8WvF8}}l07*qoM6N<$g7cXs A&j0`b literal 0 HcmV?d00001 diff --git a/upload/admin_area/styles/clipbucketblue/images/icons/info.png b/upload/admin_area/styles/clipbucketblue/images/icons/info.png new file mode 100644 index 0000000000000000000000000000000000000000..12cd1aef900803abba99b26920337ec01ad5c267 GIT binary patch literal 778 zcmV+l1NHogP)BVme|mWaqy4$_pJm?y9KM{-*hp?1+Ey3e-CEDooTa!B;e(Q>TSF?bj>5At13y1p zriN3w3x~5SfZj{@J4M{kp{?=M_Lh2bV+5LH)Q)5W!-ePA$RgE1@5f1cyHki0Y}JyVEYZF(LD$xXlt$7A5CgE@ zpV-&l%vf;=5kZ2-2gi@Y6J&=cuwt>!vJ^#(&n|LcZyUzi6Duj$$hJ1s*HD-#;k-w@ zpdrwAuoDG_N2bvb07G$Zk*?Hc)JLtW4yqOnic_$zO7NZ#l>Fm){;fE?b$IbOaX2fe z0la4g0Dfw2xk7Wi7NapVD8YMPCZu?A1QCK*67dgsvRKBLFtrM>?$%&_lD1882mzdO zWPdw5KWw6IT`m1b_8=lS5jt8D3=RDa=&jWzR-)S@56WMslZ~mKu1)-wpXB>rNBQ>N zU#K`#1B&v|_AQK;7I~B}OdGiUT9LX>f0xm6<;LeP!=vFjPsUQF*wCJ*dO)4YBypgdiuF!=i@6Zyi7F|q#K zz?tlSZULa@t1D?$e;f@b36&N!V2mjOHw|*FaCQnMumK}v9B>c=i3%It0xC9+lSZg2 z0vl0KLp7o(V#6Lgn4zJ2>PF){Jt#f!1AvCp4B-??+=%a<=7K74ro{Q0|g@201xKYjW%Gc)t`>sOP> z^!oMdj~_qw^z?lH{(XFW{MD;hd_I3*VBpQ0Hz!V<$j{Gz^5n_Qn>Rf?JWicDH8nML z`}Xbk@86$0ckaQ12M-@UEG{mtt*uQ(?JX zeE9zT`+B{8baeFbActF5iAfq{Wnu3SkFIg$ zE?ihrQnGH{x`2Ry)YMd0SJ#-Bn7eoH`uO-zD3l#LcDTE{XJ%$@+_=%k#zrU*I3H(2Y`U4joB90aCL?P_?EI4SnMg5FG0)QD{{=ECMCIGq~ zXv4S)ns~Y+JoM@Vx3-V=Hr~_6%a2Cj~U3pe!ldi46ue^8~#U%uzq-~w;KkB z{f`_3K)}ZG0Cc5=+*i~suCqz`s)LNhIX>$W%$#`l=XV`7j$91*9El6?KS9Fweq+DC}=NuDHDn8RJH{fKy^l{U4}O;nEJn1Ll2^6yT;9InFN zkr-$v7C}H2B;wKOj9Y*TpurtkbZUpH$d!OEmMA42YCF%CbjA?>xL*EuwCX{g>M!@x zkz6|?t7o^pzd^@86&!`q*kXHG)i8d}{2iujDLB8a+&P=X?#!Gh24_ivbmD+o!2x`D zs7c1)SIo1IgC>bWs^h=-9yB~M%-p99V%9Nxr#wp`TSocpeEZQ3onuf|bo1ya$f0d% znbMmnToue3#*_-F_&i(?fwZ)lqK`zt>WZu7)eAcQmX@eDIJjF2-|HdcRC@t;&W`>H zu+9K!LShoG3-}5cwAVNOJp7fQkcc9&O>!(6(W3n$vX?HgyRsc5C);^xe!gVyrIrRh#1#N;xyQu55iy;6BIXgk|1a1 z%gmIAN(fm#<4yGBDq!|me-6~5u&tKfq*s>60qyF$jWP+EV(pV!Ts2MmPkxulDra@Z zIJZ#^{)4$p2?E8kL6u1$BLpg}ow&lW+d~Be4GzW1s5Wy|ASy^m18?x~?r0L5NEqpn zqo_2Ucq_6{jl#Q{WN~y1&dLgyB$D_73?R%^#!3VoHFM{c74X!ESXbAGkOOwrG*X>g zV5}?I0I$-8uFD#*V@ZT(SN?mNRkw7`1FdhAi8($;+E77|n&LP-DdN}Z{_I)REdW%5 za0(MLrYqqnDg|BKk|aQCgaCqLmhk0hVmk=}UMcpj0Z42*MWIqM{@P_RH`%CRXEvB* zLf-G?{%M3sVyhXawTVVs{spQL8`{A;Xc2sd?Ldg3~mrAvTO$W1oNmN=l^)b lh7Bq(VS$OPgr!Xd)q;)bRZ!>Z2FN+j@Th;V&E7&A_+Mq3MF{`^ literal 0 HcmV?d00001 diff --git a/upload/admin_area/styles/clipbucketblue/images/login.gif b/upload/admin_area/styles/clipbucketblue/images/login.gif new file mode 100644 index 0000000000000000000000000000000000000000..4b91f456450fa0a27ed43b4e3cf92bec2826a202 GIT binary patch literal 7582 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 literal 0 HcmV?d00001 diff --git a/upload/admin_area/styles/clipbucketblue/images/logo.gif b/upload/admin_area/styles/clipbucketblue/images/logo.gif new file mode 100644 index 0000000000000000000000000000000000000000..2c74f564b3d7b0e673a7512c79893962ca7e9b42 GIT binary patch literal 6217 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 literal 0 HcmV?d00001 diff --git a/upload/admin_area/styles/clipbucketblue/images/menu_bg.png b/upload/admin_area/styles/clipbucketblue/images/menu_bg.png new file mode 100644 index 0000000000000000000000000000000000000000..7f3e63b2ed52d195f1e5e3cba746386e173e614d GIT binary patch literal 576 zcmV-G0>Ax001Wl0{{R3&eckd0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUyR8UM*Me*_R@9*#K?(X;Z_w4NK>gww2 z>+9+1>Ez_(=H}-8{r%%+;=;-MF{{Hy*`0()X?d|RS{QUa*`u6tr_4W1h^Yi=r z`}z6#^z`)q|Nrvx@?XvlXaE2Kf=NU{RCwC#oNac5APhzMQrl@~gi5Fk``>2+>aM;G0;~YW);xYb`ezS8(&e=``QW<`oxgF9iD`(rL0qK|++mN0) z=a!Y1Qh{trVeM;|&Ox`VoG1h75S3QD^qHNPn*GY`KrUUd&$Yay6HCWyk?-AS8q$M{ zjq3AvftzXiEGbQ`({0qpYTlaZLx2AH?;ar7vj`}F?oOJT2 z?n>&rCrDQ+eM(pN4#e}Pdxvyw(x=|Z5!Pmutjf>Gvtv*f8p#V%(ucdr5bY zu15MuI#>5G?m$33wU{^#MsoAcpY#gr3Y^zw#x5J(=M+cMG3zCMl#P=<1{fcKlit7S z2!ev@-pY9?K{|ig(C5e>RW9eH1kXn{$ACHz4(-2p&H#lM4FO&J2rvNC(9Ln?EDARO O0000N=z9P`CV0 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 d0>1$a-ha7T7gVHO|MLQy)?(y{6>-Np$ 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 IM6N<$f_eK;A^-pY literal 0 HcmV?d00001 diff --git a/upload/admin_area/styles/clipbucketblue/images/processing.png b/upload/admin_area/styles/clipbucketblue/images/processing.png new file mode 100644 index 0000000000000000000000000000000000000000..b82bb9d43fda3c4f46d32d3b3fd867cec0fa6035 GIT binary patch literal 3627 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 Kb~t@5;qe9k$|OVp literal 0 HcmV?d00001 diff --git a/upload/admin_area/styles/clipbucketblue/images/top_body_bg.jpg b/upload/admin_area/styles/clipbucketblue/images/top_body_bg.jpg new file mode 100644 index 0000000000000000000000000000000000000000..30f93ce13d13bc24ed588ca504e6149461a3b441 GIT binary patch literal 3857 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 literal 0 HcmV?d00001 diff --git a/upload/admin_area/styles/clipbucketblue/images/top_links_bg.png b/upload/admin_area/styles/clipbucketblue/images/top_links_bg.png new file mode 100644 index 0000000000000000000000000000000000000000..809f8ef495d37748b50a72707a1bbfa41dfa7e6e GIT binary patch literal 761 zcmVX+MNqKuQM2?;uI^a8|5dyH{{R2} z{{Q{{|NQ>{RI%?-uib}~@%Q`wTeR?=)AoME^M=Rsh{*F-y8QF{{%O1M>GuBV_W#N0{;t~h z>-PQ4>;I3;^-!+vQ?c*V>-*mD{D{c(Z@%)g;Qz+u`Ipf4_x%5$*Zoww|G(w`@%a9H z$oh!R{;uBssoegO(fnw-@ov2F==J?lvGCmS|5mZ@Qnvb1xB5@7?o+t^Q@Z|By8lqG z?^3q;Qn&k3xcpPO{ZqOAPp|J#u<%c=?*IS)BL)Nk0004yNklU1KJ$kx9I zhr_X$`yX7uh3=F%(S;NXr6*#q1UVKaAH>cCi&!X93>!r(W8wInSUH9&76uf=!T_3B z=sglMJ?LT~`$pKZFvRLp6%&19EW8pnFk-bS3sajFt94IUTC7;Oz9UB0V8$xE5TgP+ z7Op6b!4*tmMK_3E)GXGii|C!2#X{nXXeD48t4Vcqn&z?MW6Gm3j+@6q>Y1peU=gca zr9djxvQ?~F{*(O3*Q{dUkP4|B!ZOx=of0k8_pM{`4e^1@i4ER57H~czbLaXr##lG$ z3U!iH(l_?8kQ-4c$tVX0v2b=ItbHos=nRfx;WBfu-noQ>%q1MgLh@uNZm!I1wyk0K zrnUutK;hRBWd49}N8w|-4el-MDuN1ec#?$USm3-1yv!rx<`4?u?>L7%Y`kv5YsgpU rj6>yB-jD>E4cY@7ei4f>eG4!Ew=z8ItveSZ00000NkvXXu0mjf5Lum6 literal 0 HcmV?d00001 diff --git a/upload/admin_area/styles/clipbucketblue/images/up.png b/upload/admin_area/styles/clipbucketblue/images/up.png new file mode 100644 index 0000000000000000000000000000000000000000..e55e00e912d85fcbf2e931d0a393e7c68d5f396f GIT binary patch literal 566 zcmV-60?GY}P)A#LbjI7Me zOiYZ7KvTc}`g8x|_r}NU_kS`mU;sCPKgDtkg4`S+Q=fnM)bWVz&JUnV{$eWK{+3bX z|F;O~KP(@={n-EP>(y@@ye$8CSr|B(7=0y}frjsR{rBfzhVTFWfBwU;{vE5pe)#j55$t0&h7Z3PuYCB!^z_{)CT1paHU@Ua|3G9b z#Kg_Q07O6rLSn_|M;sP5NTB&rpq6H0~x@efA;bjI3?6RZsXIGGqQ(a#^>&mBAJX`lx3Y?6bqr8w96U3-80 z{K3Y=fQ+8MeYbMmhEzL!bx9FMcpB*2cC=;VAzf{4H6?i<_vg=Fmv7vXX8V`oXdGao z1r%XKPA=bn{oZ=v*6z!9fNXv)4nHFe8+CcOEI@z(0L}2cL2_G}Qvd(}07*qoM6N<$ Eg4@**J^%m! literal 0 HcmV?d00001 diff --git a/upload/admin_area/styles/clipbucketblue/layout/add_custom_fields.html b/upload/admin_area/styles/clipbucketblue/layout/add_custom_fields.html new file mode 100644 index 00000000..116574cc --- /dev/null +++ b/upload/admin_area/styles/clipbucketblue/layout/add_custom_fields.html @@ -0,0 +1,75 @@ + +
Add Custom Field for Upload Forms
+
+
+ + + + + + + + + + + + + + + +
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Please fill the form
TitleType
NameID
ClassValue
Hint 1Hint 2
DB FieldRequired
Validation FunctionInvalid Error
Anchor BeforeAnchor After
Display Function  
    
   
+
+

 

diff --git a/upload/admin_area/styles/clipbucketblue/layout/ads_add_placements.html b/upload/admin_area/styles/clipbucketblue/layout/ads_add_placements.html new file mode 100644 index 00000000..8f7974fc --- /dev/null +++ b/upload/admin_area/styles/clipbucketblue/layout/ads_add_placements.html @@ -0,0 +1,73 @@ +{if $Cbucket->show_page == true} + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
Add Placement
 
Placement Name
Placement Code
+
 
+
+

+
+ + + Note: If You Delete Any Placement, All Ads Under It, Will Be Deleted + +
+
+ + + + + + + + + +
ID # PlacementNamePlacementCodeTotalAds Action
+{section name=a_list loop=$ads_placements} +{if $ads_placements[a_list].placement_name !=''} + + + + + + + + +
{$ads_placements[a_list].placement_id}{$ads_placements[a_list].placement_name}{literal}{AD place={/literal}{$ads_placements[a_list].placement}{literal}}{/literal}{$ads_placements[a_list].total_ads}{if $ads_placements[a_list].disable == no}Remove{else}Default Placement{/if}
+ {if $bgcolor == ""} + {assign var = bgcolor value = "#EEEEEE"} + {else} + {assign var = bgcolor value = ""} + {/if} +{/if} +{/section} + +{/if} \ No newline at end of file diff --git a/upload/admin_area/styles/clipbucketblue/layout/ads_manager.html b/upload/admin_area/styles/clipbucketblue/layout/ads_manager.html new file mode 100644 index 00000000..06987ef4 --- /dev/null +++ b/upload/admin_area/styles/clipbucketblue/layout/ads_manager.html @@ -0,0 +1,178 @@ + + +{if $edit_ad != "show"} +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Add Advertisement
 * are required fields
Advertisement Name*
Advertisement Placement
Advertisement Code*
Status

+ + +
+

 
+
+{/if} +{if $edit_ad == "show"} +{section name=list loop=$ad_data} +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
Edit Advertisement
 * are required fields
Advertisement Name*
Advertisement Placement*
Advertisement Code*
  + Active +
+
+{/section} +{/if} +
+
Advertisement Manager
+{if $total != 0} + + + + + + + + + + + + + + + {assign var = bgcolor value = ""} +{section name=list loop=$ads} + + + + + + + + + + + {if $bgcolor == ""} + {assign var = bgcolor value = "#EEEEEE"} + {else} + {assign var = bgcolor value = ""} + {/if} + +{/section} +
 
 
Advertisement NameDate AddedImpressionsPlacementAction
{$ads[list].ad_name}{$ads[list].date_added|date_format}{$ads[list].ad_impressions}{$ads[list].placement} +
  • Edit
  • +
  • + {if $ads[list].ad_status == 0 } + Activate It + {else} + Deactivate it + {/if}
  • +
  • Delete
  • Click Here To Preview +

    +
    {$ads[list].ad_code}
    +{else} +No Advertisement Has Been Created Yet +{/if} +
    +
    + \ No newline at end of file diff --git a/upload/admin_area/styles/clipbucketblue/layout/blocks/comments.html b/upload/admin_area/styles/clipbucketblue/layout/blocks/comments.html new file mode 100644 index 00000000..8fb66f33 --- /dev/null +++ b/upload/admin_area/styles/clipbucketblue/layout/blocks/comments.html @@ -0,0 +1,56 @@ + +{assign var=bgcolor value =F2F2F2} +{if $myquery->get_comments($id,$type)} + + + + + + + + + +
    CIDUIDCommentDateVotes 
    + + +{foreach from=$myquery->get_comments($id,$type) item=comment} + + {if $comment.parent_id == 0} + + + + + + + + + + + + {foreach from=$myquery->get_comments($id,$type,false,$comment.comment_id,TRUE) item=reply} + {if $reply.comment !=''} + + + + + + + + + {/if} + {/foreach} + + {if $bgcolor == 'F2F2F2'} + {assign var=bgcolor value =FFF} + {elseif $bgcolor == 'FFF'} + {assign var=bgcolor value =F2F2F2} + {/if} + + {/if} +{/foreach} +{else} + + + +{/if} +
    {$comment.comment_id}{$comment.userid}{$comment.comment}{$comment.date_added|date_format}{$comment.vote}Delete
    {$reply.comment_id}{$reply.userid}{$comment.comment_id} ⇔ {$reply.comment}{$reply.date_added|date_format}{$reply.vote}Delete
    No User Comments For This Video
    \ No newline at end of file diff --git a/upload/admin_area/styles/clipbucketblue/layout/category.html b/upload/admin_area/styles/clipbucketblue/layout/category.html new file mode 100644 index 00000000..74162c16 --- /dev/null +++ b/upload/admin_area/styles/clipbucketblue/layout/category.html @@ -0,0 +1,116 @@ + +{if $edit_category != "show"} +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Add Category
     * are required fields
    Category Name*
    Category Description*
    Category Thumb
     
    +
    +{/if} +{if $edit_category == "show"} +{section name=list loop=$category_data} +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Edit Category
     * are required fields
    Category Name*
    Category Description*
    Category Thumb
     
    +
    +{/section} +{/if} +
    +
    Video » Categories
    +{if $total != 0} + + + + + + + + + {assign var = bgcolor value = ""} +{section name=list loop=$category} + + + + + + + + {if $bgcolor == ""} + {assign var = bgcolor value = "#EEEEEE"} + {else} + {assign var = bgcolor value = ""} + {/if} + +{/section} +
    Category NameThumbDescriptionDate AddedAction
    {$category[list].category_name}View Thumb{$category[list].category_description}{$category[list].date_added|date_format} +
  • Edit
  • +
  • Delete
  • +
    +{else} +No Category Has Been Created Yet +{/if} +
    +
    diff --git a/upload/admin_area/styles/clipbucketblue/layout/edit_announcemnent.html b/upload/admin_area/styles/clipbucketblue/layout/edit_announcemnent.html new file mode 100644 index 00000000..577069bd --- /dev/null +++ b/upload/admin_area/styles/clipbucketblue/layout/edit_announcemnent.html @@ -0,0 +1,13 @@ +
    Edit Announcement
    + + + + +
    +
    + Announcement
    + + +
    + +
    diff --git a/upload/admin_area/styles/clipbucketblue/layout/edit_group.html b/upload/admin_area/styles/clipbucketblue/layout/edit_group.html new file mode 100644 index 00000000..d951e97d --- /dev/null +++ b/upload/admin_area/styles/clipbucketblue/layout/edit_group.html @@ -0,0 +1,136 @@ + +{if $groups.group_name neq ""} + + + + +
    + + + +
    Edit Group
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    « Back
     
    + Group Thumb + + + + + + + + +
    Upload Group Thumb
    +
    +
    +
  • Must Be JPG | GIF | PNG
  • +
  • 90 x 90 Ratio Will Give Best quality
  • +
  • Do Not Upload Vulgur or Copyrighted Material
  • +
    Group Name:
    Tags:
     Enter one or more tags, separated by spaces.
    +
    Tags are keywords used to describe your group so it can be easily found by other users. For example, if you have a group for surfers, you might tag it: surfing, beach, waves.
    Description:
    Group Url: {$view_group_link} + + +
     Enter 3-18 characters with no spaces (such as "skateboarding''), that will become part of your group's web address. Please note, the group name URL you pick is permanent and can't be changed.
    Group Category: {section name=c_list loop=$category} + + {$category[c_list].category_name}
    + {/section}
    Privacy:

    + +
    + +
    + +
    +

    Video Uploads:

    + +
    + +
    + +
    +

    Forums Posting:

    + +
    + +
    + +
    +

    +
    +{/if} \ No newline at end of file diff --git a/upload/admin_area/styles/clipbucketblue/layout/edit_member.html b/upload/admin_area/styles/clipbucketblue/layout/edit_member.html new file mode 100644 index 00000000..25a603d6 --- /dev/null +++ b/upload/admin_area/styles/clipbucketblue/layout/edit_member.html @@ -0,0 +1,126 @@ + +{if $data.username neq ""} +
    Edit Member
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    « Back
    Account Information
    Username*
    Email*
    Change Password
    Confirm Password
      
    User Access Level
    Personal Information
    First Name*
    Last Name*
    Gender

    + + +
    + +

    Location Information
    Hometown
    City
    Country
    Postal Code
      
    +
    {/if} \ No newline at end of file diff --git a/upload/admin_area/styles/clipbucketblue/layout/edit_video.html b/upload/admin_area/styles/clipbucketblue/layout/edit_video.html new file mode 100644 index 00000000..757d5daf --- /dev/null +++ b/upload/admin_area/styles/clipbucketblue/layout/edit_video.html @@ -0,0 +1,180 @@ + + +{assign var='requiredFields' value=$Upload->loadRequiredFields($data)} +{assign var='optionFields' value=$Upload->loadOptionFields($data)} +{assign var='locationFields' value=$Upload->loadLocationFields($data)} + +{assign var='custom_fields' value=$Upload->load_custom_upload_fields($data,TRUE)} +{assign var='custom_form_fields' value=$Upload->load_custom_form_fields($data,TRUE)} + + +{if $data.title neq ""} +
    Edit Video
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {foreach from=$requiredFields item=field} + + + + + {/foreach} + + + + + + + + + + + + + + + + {foreach from=$locationFields item=field} + + + + + {/foreach} + + + + + + + + + + + + + + + + + + + + + + + + {foreach from=$optionFields item=field} + + + + + {/foreach} + + + + {foreach from=$custom_form_fields item=field} + + + + + {/foreach} + + + + + + + + {foreach from=$custom_fields item=field} + + + + + + {/foreach} + + + + + +
    Watch Video | Delete« Back
    Uploader Information
    Useid{$data.userid}
    Important Details
    Video Id
    Video Key
    File Name
    Total Video Files{get_all_video_files vdetails=$data count_only=true}
    Total Thumbnails{get_thumb vdetails=$data count_only=true}
    View File Details and Converion Log
    Thumbnails
    +{if $data.embeded !=yes}Regenerate Thumbs{/if}
    + Manage Thumbs
    + + {assign var=vidthumbs value=func->get_thumb($data,1,TRUE)} + + {foreach from=$vidthumbs item=vid_thumb} +
    +
    + {if $vid_thumb|getname!='processing'} + Delete + {/if} +
    + {/foreach} + +
    {$field.title}* :{$field.hint_1}{ANCHOR place=$field.anchor_before}{$formObj->createField($field)} +{$field.hint_2}
    Important Details
    Duration (seconds) + seconds
    Status
    Recording Details
    {$field.title}* :{$field.hint_1}{ANCHOR place=$field.anchor_before}{$formObj->createField($field)} +{$field.hint_2}
    Video Stats
    Views
    Rating + of 10
    RatedBy
      
    Sharing
    {$field.title}* :{$field.hint_1}{ANCHOR place=$field.anchor_before}{$formObj->createField($field)} +
    + {$field.hint_2}
    Custom Form Fields
    {$field.title}* :{$field.hint_1}{ANCHOR place=$field.anchor_before}{$formObj->createField($field)} +
    + {$field.hint_2}
      
    Customg Uploading Fields
    {$field.title}{$field.hint_1}{ANCHOR place=$field.anchor_before}{$formObj->createField($field)} +
    + {$field.hint_2}
    +
    {/if} \ No newline at end of file diff --git a/upload/admin_area/styles/clipbucketblue/layout/editor_pick.html b/upload/admin_area/styles/clipbucketblue/layout/editor_pick.html new file mode 100644 index 00000000..b36f4379 --- /dev/null +++ b/upload/admin_area/styles/clipbucketblue/layout/editor_pick.html @@ -0,0 +1,27 @@ +
    Editor's Pick
    +
    + + + + + + +
    TitleDate AddedAction
    + + +{assign var = bgcolor value = ""} +{section name=v_list loop=$videos} +{if $videos[v_list].title != ""} + + + + + +{if $bgcolor == ""} + {assign var = bgcolor value = "#EEEEEE"} +{else} + {assign var = bgcolor value = ""} +{/if} +{/if} +{/section} +
    {$videos[v_list].title}{$videos[v_list].date_added}Remove From Editor's Pick {if $smarty.section.v_list.iteration !=1} {/if}{if $smarty.section.v_list.iteration !=$total_videos}{/if}
    diff --git a/upload/admin_area/styles/clipbucketblue/layout/email_settings.html b/upload/admin_area/styles/clipbucketblue/layout/email_settings.html new file mode 100644 index 00000000..93270ee1 --- /dev/null +++ b/upload/admin_area/styles/clipbucketblue/layout/email_settings.html @@ -0,0 +1,151 @@ + +
    Email Settings
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Email Settings
    Website Email
    Support Email
    Welcome Email
      
    Email Templates
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Email Templates Instruction
    Username$usernameFrom$from
    Email$emailSender Email$from_email
    Password$passwordVideoKey$videokey
    Activation Code$avcodeVideoThumb$videothumb
    Current Date$cur_dateVideoTtle$videotitle
    Website Title$titleVideoDescription$videodes
    Website URL$baseurlPersonalMessage$message
        
      +
    • Above Given Tags can be used in Email
    • +
    • Do Not Use Double or Single Quotation in Hyperlinks ie <a href="linkgoeshere">clickhere</a> is wrong, just type <a href=linkgoeshere.....
    • +
    • Dont Use Tags That are not allowed for the specific Template
    • +
    • You can add HTML in it
    • +
    • If you want more Templates Please ClipBucket
    • +
    Signup Template
    + (Email Verification)
    Welcome Message TemplateSubject:
    + +
    +Message:
    + +
    + (Allowed Tags:Username,Email,CurrentDate,Websitetitle,WebsiteURL)
    Activation Code Request TemplateSubject:
    + +
    +Message:
    + +
    +(Allowed Tags:Username,Email,ActivationCode,CurrentDate,Websitetitle,WebsiteURL)
    Share This Video TemplateSubject:
    + +
    +Message:
    + +
    +(Allowed Tags:From,SenderEmail,,Websitetitle,WebsiteURL,Videokey,VideoThumb,VideoTtle,VideoDescription,CurrentDate)
      
      
    +
    + diff --git a/upload/admin_area/styles/clipbucketblue/layout/flagged_videos.html b/upload/admin_area/styles/clipbucketblue/layout/flagged_videos.html new file mode 100644 index 00000000..0c62ca10 --- /dev/null +++ b/upload/admin_area/styles/clipbucketblue/layout/flagged_videos.html @@ -0,0 +1,66 @@ + + +
    Flagged Videos Manager
    + + + + + + + + + + +
     Viewing {math equation=$limit*$cur_page assign=viewing} {if $prepage == 0 } {math equation=$prepage+1} {else} {math equation = $prepage*$limit+1 }{/if} - {if $viewing > $grand_total}{$grand_total}{else}{$viewing}{/if} of {$grand_total}
    + {if $prepage neq 0}Previous{/if}{section name=allpages start=1 loop=$pages} + {if $cur_page == $smarty.section.allpages.index } + {$smarty.section.allpages.index} + {else} {$smarty.section.allpages.index} {/if} + {/section} {if $nextpage neq $smarty.section.allpages.index && $pages!=1}Next{/if}
    + + + + + + + + + +{assign var = bgcolor value = ""} +{section name=list loop=$videos} + + + + + + + + + {if $bgcolor == ""} + {assign var = bgcolor value = "#EEEEEE"} + {else} + {assign var = bgcolor value = ""} + {/if} + {/section} +
    Video IdVideo TitleTypeUsernameTotal FlagsActions
    {$videos[list].videoid}{$videos[list].title}{$videos[list].broadcast}{$videos[list].username}{$videos[list].flags}Remove Flags
    +Delete Video
    + Edit
    + {if $videos[list].active == yes} + Deactivate + {/if} + {if $videos[list].active == no} + Activate + {/if}
    + +
    + + + + + + +
    {if $prepage neq 0}Previous{/if}{section name=allpages start=1 loop=$pages} + {if $cur_page == $smarty.section.allpages.index } + {$smarty.section.allpages.index} + {else} {$smarty.section.allpages.index} {/if} + {/section} {if $nextpage neq $smarty.section.allpages.index && $pages!=1}Next{/if}
    diff --git a/upload/admin_area/styles/clipbucketblue/layout/footer.html b/upload/admin_area/styles/clipbucketblue/layout/footer.html new file mode 100644 index 00000000..83a61e37 --- /dev/null +++ b/upload/admin_area/styles/clipbucketblue/layout/footer.html @@ -0,0 +1,12 @@ + + +
    +
    +
    +
    +
    +
    + +
    © Copyright 2007 - {$smarty.now|date_format:"%Y"} ClipBucket. All Rights Reserved.
    + + diff --git a/upload/admin_area/styles/clipbucketblue/layout/groups_manager.html b/upload/admin_area/styles/clipbucketblue/layout/groups_manager.html new file mode 100644 index 00000000..0d86ea8a --- /dev/null +++ b/upload/admin_area/styles/clipbucketblue/layout/groups_manager.html @@ -0,0 +1,219 @@ + + + + + +
    + + + + + +
    +
    + Show #Result + +
    + Jump To Page + + +
    +
    + + + + + + + + + + + +
     Viewing {math equation=$limit*$cur_page assign=viewing} {if $prepage == 0 } {math equation=$prepage+1} {else} {math equation = $prepage*$limit+1 }{/if} - {if $viewing > $grand_total}{$grand_total}{else}{$viewing}{/if} of {$grand_total}
    + {if $prepage neq 0}Previous{/if}{section name=allpages start=1 loop=$pages} + {if $cur_page == $smarty.section.allpages.index } + {$smarty.section.allpages.index} + {else} {$smarty.section.allpages.index} {/if} + {/section} {if $nextpage neq $smarty.section.allpages.index && $pages!=1}Next{/if}
    +
    + + + + +
    + + + + + + +
    + + + + + + + + + + + +{assign var = bgcolor value = ""} +{section name=list loop=$groups} + + + + + + + + + + + + + {if $bgcolor == ""} + {assign var = bgcolor value = "#EEEEEE"} + {else} + {assign var = bgcolor value = ""} + {/if} + {/section} +
    ID Group Name Properties DetailsMore Details Actions
    {$groups[list].group_id}{$groups[list].group_name}
    + URL:{$groups[list].group_url}
    Owner
    + GroupType
    + VideoType
    + PostType
    {$groups[list].username}
    + {$groups[list].type}
    + {$groups[list].video_type}
    + {$groups[list].post_type}
    +
    Members
    +Videos
    +Topics
    +Replies
    {$groups[list].total_members}
    +{$groups[list].total_videos}
    Featured:
    + Active:
    + Category
    {$groups[list].featured}
    + {$groups[list].active}
    + {$groups[list].category}
    Delete
    + Edit
    + {if $groups[list].featured == yes} + Make Unfeatured + {/if} + {if $groups[list].featured == no} + Make Featured + {/if}
    + {if $groups[list].active == yes} + DeActivate + {/if} + {if $groups[list].active == no} + Activate + {/if}
    +
    +
    + + + + + + +
    {if $prepage neq 0}Previous{/if}{section name=allpages start=1 loop=$pages} + {if $cur_page == $smarty.section.allpages.index } + {$smarty.section.allpages.index} + {else} {$smarty.section.allpages.index} {/if} + {/section} {if $nextpage neq $smarty.section.allpages.index && $pages!=1}Next{/if}
    diff --git a/upload/admin_area/styles/clipbucketblue/layout/header.html b/upload/admin_area/styles/clipbucketblue/layout/header.html new file mode 100644 index 00000000..c323c33a --- /dev/null +++ b/upload/admin_area/styles/clipbucketblue/layout/header.html @@ -0,0 +1,35 @@ + + + + +{if $THIS_PAGE == "ADMIN_LOGIN"} + +{/if} + + + + + + +{$title} {$subtitle} + + + + +{if $THIS_PAGE != "ADMIN_LOGIN"} + + + + + + + + +
    Welcome {$logged_user} {if $smarty.session.superadmin != ''}(Super Admin){/if}
    + {$smarty.now|date_format:"%A, %B %e, %Y %H:%M:%S"}

     

    + + + +
    +{/if} diff --git a/upload/admin_area/styles/clipbucketblue/layout/index.html b/upload/admin_area/styles/clipbucketblue/layout/index.html new file mode 100644 index 00000000..b1074c9c --- /dev/null +++ b/upload/admin_area/styles/clipbucketblue/layout/index.html @@ -0,0 +1,91 @@ +{literal} + +{/literal} +
    General Statistics
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ClipBucket
    ClipBucket Version : {$stats.cb_ver} Date Updated : {$stats.date_updated} Stability : {$stats.stability}
     
    Disk Space
    Total Space : {$server.disk_space} Used : {$server.space_used} Free : {$server.space_free}
     
    PHP & Database
    PHP : {$server.php_ver} Mysql : {$server.mysql_ver} Database Size : {$server.db_size}
     
    +
    +
    Website Statistics
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    User Stats Video Stats Group Stats
    Total Users : {$stats.total_users} Total Videos:{$stats.total_videos}Total Groups : {$stats.total_groups}
    Active Users : {$stats.total_active_users} Flagged Videos:{$stats.total_flagged_videos}Total Topics : {$stats.total_topics}
    Todays Signups: {$stats.today_signups} Added Today : {$stats.videos_added_today}Total Posts : {$stats.total_posts}
    Todays Logins: {$stats.todays_logins} Added This Month : {$stats.videos_added_this_month}Added Today : {$stats.groups_added_today}
    Active This Month: {$stats.months_logins} Total Watched : {$stats.total_watched_videos}Total Invitations : {$stats.group_invitations}
    Click Here To Force Update Stats
    + +
    +
    Last Conversion Log
    +
    +
    +
    {$con_log}
    +
    +
    \ No newline at end of file diff --git a/upload/admin_area/styles/clipbucketblue/layout/language_settings.html b/upload/admin_area/styles/clipbucketblue/layout/language_settings.html new file mode 100644 index 00000000..54455949 --- /dev/null +++ b/upload/admin_area/styles/clipbucketblue/layout/language_settings.html @@ -0,0 +1,23 @@ +
    Edit Video
    + + + + + + + + +{section name=l_list loop=$language_list} + + + + + + + +{/section} +
    IDLanguageLanguage CodeRegular ExpressionActions
    {$language_list[l_list].language_id}{$language_list[l_list].language_name}{$language_list[l_list].language_code}{$language_list[l_list].language_regex} + {if $language_list[l_list].language_default != yes} + Make Default
    + {/if} + Edit Phrases
    \ No newline at end of file diff --git a/upload/admin_area/styles/clipbucketblue/layout/leftmenu.html b/upload/admin_area/styles/clipbucketblue/layout/leftmenu.html new file mode 100644 index 00000000..dce82d9d --- /dev/null +++ b/upload/admin_area/styles/clipbucketblue/layout/leftmenu.html @@ -0,0 +1,38 @@ + + + + + "; + else $form = ""; + + $allowsql = !defined('ADODB_PERF_NO_RUN_SQL'); + + if (empty($_GET['hidem'])) + echo "
    \ No newline at end of file diff --git a/upload/admin_area/styles/clipbucketblue/layout/login.html b/upload/admin_area/styles/clipbucketblue/layout/login.html new file mode 100644 index 00000000..f8d6200a --- /dev/null +++ b/upload/admin_area/styles/clipbucketblue/layout/login.html @@ -0,0 +1,65 @@ +
    + + + +
    + + + + + + + + + +
    + +
    +
    + + + + + + + + + +
     {$title} Message:   Admin Area Login
    +
    +
    +
    You are not logged in or you do not have permission to access this page. +
    +This could be due to one of several reasons:
    +
      +
    1. You are not logged in. Fill in the form at the bottom of this page and try again.
    2. +
    3. You may not have sufficient privileges to access this page.
    4. +
    5. The site administrator may have disabled your account, or it may be awaiting activation.
    6. +
    + +
    +Log in + + + + + + + + + + + + +
    Username:
    Password:
    +Recover Password +
    + + +
    +
    +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/upload/admin_area/styles/clipbucketblue/layout/logo_change.html b/upload/admin_area/styles/clipbucketblue/layout/logo_change.html new file mode 100644 index 00000000..82a63b71 --- /dev/null +++ b/upload/admin_area/styles/clipbucketblue/layout/logo_change.html @@ -0,0 +1,55 @@ + +
    Logo Settings
    + + + + + + + + + + + + + + + + + + + + + + + + +
    Website Logo
    Current Logo +
    + + +
    Website Player Logo
    Current Logo
    +Just Upload PNG Image +
    + + +
    Embedded Player Logo
    Current Logo
    + Just Upload PNG Image +
    + + +
    diff --git a/upload/admin_area/styles/clipbucketblue/layout/main.html b/upload/admin_area/styles/clipbucketblue/layout/main.html new file mode 100644 index 00000000..8afaf828 --- /dev/null +++ b/upload/admin_area/styles/clipbucketblue/layout/main.html @@ -0,0 +1,583 @@ + +
    Main Settings
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Website Settings
    Website Title
    Website Slogan
    Debug Mode + + + + + + + + + + + + + +
    +
    Website Closed +
    Closed Message
    Meta Description
    Meta Keywords
    Default Language +
    Display Language Changer
    Display Template Changer
    Seo URLs
    Modules & Paths
    Conversion Modules + + + + + + + + + +
    +
    FFmpeg Binary Path +
    FFMPEG Type

    + + Static + + Dynamic +

    MEncoder Binary Path
    MPlayer Binary Path
    FLVTool2 Binary Path
    PHP Path
      
    Video, Uploading and Conversion Settings
    Operating System (OS) +
    Allow Upload
    Max Upload File Size + in MegaBytes
    Video Comments +
    +
    Video Embedding
    Video Rating + Allow Video Rating
    + User Can Rate His Own Video
    Comments Rating
    Video Download
    Resize Uploaded Video
    Video Width in px + "320" is recommended
    Video Height in px + "240" is recommended
    Thumb Width in px "120" is recommended
    Thumb Height in px + "90" is recommended
    Video Bit Rate + "500000" is recommended
    Audio Rate +"22050" is recommened
    Audio Bit Rate + "64000" is recommened
    Audio Codec
    Keep Original File + + - If YES then original files after conversion will be saved on server
    Activation Required + -if YES then Every Uploaded Video Must Required Activation from Admin
    Allowed File Types
      
    Display Settings
    Require Login to Watch Videos?
    Template Name
    Flash Player
    Player Div Id +
    Videos List Per page
    Videos List Per Tab
    Channels List Per Page
    Channels List Per Tab
    Search Results Per Page
    Recently Viewed Videos
      
    User Registration Settings
    Allow Registration
    Email Verification
    Captcha
      
    + + +
    +
    \ No newline at end of file diff --git a/upload/admin_area/styles/clipbucketblue/layout/mass_email.html b/upload/admin_area/styles/clipbucketblue/layout/mass_email.html new file mode 100644 index 00000000..466c38e5 --- /dev/null +++ b/upload/admin_area/styles/clipbucketblue/layout/mass_email.html @@ -0,0 +1,100 @@ + +
    Mass Email
    +
    + + + + + + + + + + +
    + + + + + + + + + + +
    Multi User Email
    + + + +
    + + + + + + + + + + + + + +
    From +
    Subject
    Message
    +
    +
    +
    +
     
    + + + + + + + + + +
    Individual
    + + + +
    + + + + + + + + + + + + + + + + + + + + +
    From +
    Subject
    Send To +
    + Seperate Emails With Commas
    Message
    +
    +
     
    diff --git a/upload/admin_area/styles/clipbucketblue/layout/mass_uploader.html b/upload/admin_area/styles/clipbucketblue/layout/mass_uploader.html new file mode 100644 index 00000000..1b7b0d09 --- /dev/null +++ b/upload/admin_area/styles/clipbucketblue/layout/mass_uploader.html @@ -0,0 +1,353 @@ + +
    Mass Uploader
    + + + + + + + + + + +
    {if $step !="2"} +
    + + + + + + + + + + +
    Video Upload
    + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Video Details
    Number of Videos
    Video Catgory* : You May Select Up to 3 Categories
    +
      + {assign var = num value = 0} + + {section name=c_list loop=$category} + +  {$category[c_list].category_name}
      + {math assign = num equation = "$num + 1"} + {/section} +
    + + + + + + + + + + + +
    Broadcast Options
    + + +
    + + +
    + + + + + + + + + + + + + + + +
    Date And Location
    Date Recorded : + / + + / + + format MM / DD / YYYY
    Country
    Location :
    + + + + + + + + + + + + + + + + + + + +
    Sharing Options
    Comments : + Allow Comments
    + + Do Not Allow Comments + +
    +
    Comments Voting :

    + +
    + +
    +
    +

    Ratings :

    + +
    + +
    +
    +

    Embedding : + Yes, People can play this video on other websites
    + + No, People cannot play this video on other websites
      
    +
    +
    +
    + {/if}
     
    {if $step =="2"} + + + + + + + + + + +
    Video Upload (Step 2/2)
    + + {section name=foo start=0 loop=$loop step=1} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {/section} + + + +
    {$smarty.section.foo.iteration}
    Select File
    Enter File Title + + + + + + + + + + +
    Tags
    Enter File Description
    +
    + {/if}
    diff --git a/upload/admin_area/styles/clipbucketblue/layout/members.html b/upload/admin_area/styles/clipbucketblue/layout/members.html new file mode 100644 index 00000000..944be96b --- /dev/null +++ b/upload/admin_area/styles/clipbucketblue/layout/members.html @@ -0,0 +1,401 @@ + +
    Users » {$property.name}
    +{if $property.value neq addmember } + +{/if} +
    +

    +{if $property.value == showall || $property.value == inactive || $property.value == active || $property.value == search} + + + + + + + + + + + + + + +
    +
    + Show #Result + +
    + Jump To Page + + +
    +
     Viewing {math equation=$limit*$cur_page assign=viewing} {if $prepage == 0 } {math equation=$prepage+1} {else} {math equation = $prepage*$limit+1 }{/if} - {if $viewing > $grand_total}{$grand_total}{else}{$viewing}{/if} of {$grand_total}
    + {if $prepage neq 0}Previous{/if}{section name=allpages start=1 loop=$pages} + {if $cur_page == $smarty.section.allpages.index } + {$smarty.section.allpages.index} + {else} {$smarty.section.allpages.index} {/if} + {/section} {if $nextpage neq $smarty.section.allpages.index && $pages!=1}Next{/if}
    +
    +
    +
    + + + + +
    + + + + + + + + + + + +
    +{section name=list loop=$user} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Account InfoPrimary InfoSite InfoStatusAction
    {$user[list].username}Userid{$user[list].userid}Friends{$user[list].total_friends}Active : {$user[list].usr_status}Edit
    Full Name
    + Last Name
    {$user[list].first_name}
    + {$user[list].last_name}
    Email{$user[list].email}    
    Age{$user[list].age}Country{$user[list].country}Videos{$user[list].total_videos}Banned : {$user[list].ban_status} + {if $user[list].usr_status == Ok} + De-Activate + {elseif $user[list].usr_status == ToActivate} + Activate + {/if}
    Date Joined{$user[list].doj|date_format}Singup Ip {$user[list].signup_ip}Groups{$user[list].total_groups}Featured : {$user[list].featured}View
    Last Visit{$user[list].last_logged}  Videos Watch{$user[list].total_watched} Delete
    + + + {if $user[list].featured == Yes} + Unfeatured Member + {/if} + {if $user[list].featured == No} + Featured Member + {/if} + + +
    + {if $user[list].ban_status == yes} + Unban Member + {/if} + {if $user[list].ban_status == no} + Ban Member + {/if}
    +{/section} +
    +
    {if $total ==0} No User Exists In This Category{else}
    +{/if} + + + + + + +
    {if $prepage neq 0}Previous{/if}{section name=allpages start=1 loop=$pages} + {if $cur_page == $smarty.section.allpages.index } + {$smarty.section.allpages.index} + {else} {$smarty.section.allpages.index} {/if} + {/section} {if $nextpage neq $smarty.section.allpages.index && $pages!=1}Next{/if}
    +{/if} {if $property.value == addmember } + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Account Information
     * are required fields
    Username*
    Email*
    Password*
    User Access Level
    Active + + + Yes + +No
    Personal Information
    First Name*
    Last Name*
    Gender

    + + +
    + +

    Date of Birth + + / + + / + + format MM / DD / YYYY
    Location Information
    Hometown
    City
    Country
    Postal Code
      
    +
    +{/if} \ No newline at end of file diff --git a/upload/admin_area/styles/clipbucketblue/layout/message.html b/upload/admin_area/styles/clipbucketblue/layout/message.html new file mode 100644 index 00000000..d8df14b1 --- /dev/null +++ b/upload/admin_area/styles/clipbucketblue/layout/message.html @@ -0,0 +1,32 @@ + + +{assign var=msg value=$eh->message_list} +{assign var=err value=$eh->error_list} +{if $err.0 neq ''} + + + + +
    +
      + + {foreach from=$err item=show_msg} +
    • {$show_msg}
    • + {/foreach} +

    + +{/if} + +{if $msg.0 neq ''} + + + + +
    +
      + + {foreach from=$msg item=show_msg} +
    • {$show_msg}
    • + {/foreach} +

    +{/if} \ No newline at end of file diff --git a/upload/admin_area/styles/clipbucketblue/layout/module_manager.html b/upload/admin_area/styles/clipbucketblue/layout/module_manager.html new file mode 100644 index 00000000..7f0876cf --- /dev/null +++ b/upload/admin_area/styles/clipbucketblue/layout/module_manager.html @@ -0,0 +1,78 @@ + +
    + + + + + + + + + + + + + + + + + + + + + + + +
    Add Module
     * are required fields
    File
    Active
     
    +
    + + +
    +{if $total != 0} + + + + + + + + {assign var = bgcolor value = ""} +{section name=list loop=$modules} + + + + + + + {if $bgcolor == ""} + {assign var = bgcolor value = "#EEEEEE"} + {else} + {assign var = bgcolor value = ""} + {/if} + +{/section} +
    Module NameFileActiveAction
    {$modules[list].module_name}{$modules[list].module_file}{$modules[list].active} + {if $modules[list].active == yes} +
  • Deactivate
  • + {/if} + {if $modules[list].active == no} +
  • Activate
  • + {/if} +
  • Delete
  • +{else} +No Category Has Been Created Yet +{/if} \ No newline at end of file diff --git a/upload/admin_area/styles/clipbucketblue/layout/plugin_manager.html b/upload/admin_area/styles/clipbucketblue/layout/plugin_manager.html new file mode 100644 index 00000000..1f8ae4a9 --- /dev/null +++ b/upload/admin_area/styles/clipbucketblue/layout/plugin_manager.html @@ -0,0 +1,69 @@ + + +
    Installed Plugins
    + + + + + + + +{assign var = bgcolor value = ""} +{foreach from=$installed_plugin_list item=plug name=item} + + + + + + {if $bgcolor == ""} + {assign var = bgcolor value = "#EEEEEE"} + {else} + {assign var = bgcolor value = ""} + {/if} + {foreachelse} + + + + + + {/foreach} +
    #Pluin DetailsActions
    {$smarty.foreach.item.iteration}{$plug.name} by {$plug.author}
    + {$plug.description} - +{$plug.website}
    +Version : {$plug.version} +
    {if $plug.plugin_active == 'yes'}Deactivate{else}Activate{/if}
    + Uninstall
     No Installed Plugin Found 
    + +{* Listing New Plugins *} +
    Available Plugins
    + + + + + + + +{assign var = bgcolor value = ""} +{foreach from=$new_plugin_list item=plug name=item} + + + + + + {if $bgcolor == ""} + {assign var = bgcolor value = "#EEEEEE"} + {else} + {assign var = bgcolor value = ""} + {/if} + {foreachelse} + + + + + + {/foreach} +
    #Pluin DetailsActions
    {$smarty.foreach.item.iteration}{$plug.name} by {$plug.author}
    + {$plug.description} - +{$plug.website}
    +Version : {$plug.version} +
    Install Plugin
     No New Plugin Found 
    \ No newline at end of file diff --git a/upload/admin_area/styles/clipbucketblue/layout/super_admin.html b/upload/admin_area/styles/clipbucketblue/layout/super_admin.html new file mode 100644 index 00000000..300aa1d9 --- /dev/null +++ b/upload/admin_area/styles/clipbucketblue/layout/super_admin.html @@ -0,0 +1,40 @@ + +
    Edit Super Admin
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Account Information
    Username
     
    Old Password
    New Password
    Confirm New Password
     
    +
    + diff --git a/upload/admin_area/styles/clipbucketblue/layout/templates.html b/upload/admin_area/styles/clipbucketblue/layout/templates.html new file mode 100644 index 00000000..484f8406 --- /dev/null +++ b/upload/admin_area/styles/clipbucketblue/layout/templates.html @@ -0,0 +1,77 @@ + + + + +Untitled Document + + + +
    Templates » {$CurTemplate}
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    Select Template
    Template +
     
    Select File From The List To Edit
    + + + + + + + + +
    Editing {$file}
    + + + +
    +
    + + +
    + + diff --git a/upload/admin_area/styles/clipbucketblue/layout/upload_thumbs.html b/upload/admin_area/styles/clipbucketblue/layout/upload_thumbs.html new file mode 100644 index 00000000..bf571c2f --- /dev/null +++ b/upload/admin_area/styles/clipbucketblue/layout/upload_thumbs.html @@ -0,0 +1,30 @@ +{if $data.title neq ""} +
    Manage Video Thumbs
    +
    + « Back to Edit Details | Regenerate Thumbs
    + + {assign var=vidthumbs value=func->get_thumb($data,1,TRUE)} + + {foreach from=$vidthumbs item=vid_thumb} +
    +
    + {if $vid_thumb|getname!='processing'} + Delete + {/if} +
    + {/foreach} +

    + +
    +

    Upload New Thumb

    + +
    + + +
    +

    + + +
    +{/if} \ No newline at end of file diff --git a/upload/admin_area/styles/clipbucketblue/layout/user_levels.html b/upload/admin_area/styles/clipbucketblue/layout/user_levels.html new file mode 100644 index 00000000..d23be8dc --- /dev/null +++ b/upload/admin_area/styles/clipbucketblue/layout/user_levels.html @@ -0,0 +1,104 @@ + +
    User Levels
    + + +{if $view=='view'} + +Add New Level + + + + + + + + + + {assign var=levels value=$userquery->get_levels()} + {section name=l loop=$levels} + + + + + + + + {sectionelse} + + + + {/section} +
    IDNameActiveUsersActions
    {$levels[l].user_level_id}{$levels[l].user_level_name}{$levels[l].user_level_active}{$userquery->get_level_users($levels[l].user_level_id,true)}Edit{if $levels[l].user_level_is_default !=yes} | Remove{/if}
    No Levels Were Found
    + +{elseif $view=='edit'} +
    + + + + +
    Edit Level
    + + + + + +{foreach from=$userquery->access_type_list key=access item=name} + + + + +{/foreach} +
    Level Name +
    {$name} + + +
    + + + + +
    +
    +
    +{elseif $view=='add'} +
    + + + + +
    ADD Level
    + + + + + +{foreach from=$userquery->access_type_list key=access item=name} + + + + +{/foreach} +
    Level Name + + + +
    {$name} + + +
    + + + + +
    +
    +
    +{/if} \ No newline at end of file diff --git a/upload/admin_area/styles/clipbucketblue/layout/video_manager.html b/upload/admin_area/styles/clipbucketblue/layout/video_manager.html new file mode 100644 index 00000000..4afff729 --- /dev/null +++ b/upload/admin_area/styles/clipbucketblue/layout/video_manager.html @@ -0,0 +1,229 @@ + + + + + + +
    + + + + + + + + +
    +
    + Show #Result + +
    + Jump To Page + + +
    +
     
    + + + + + + + + + + + +
     Viewing {math equation=$limit*$cur_page assign=viewing} {if $prepage == 0 } {math equation=$prepage+1} {else} {math equation = $prepage*$limit+1 }{/if} - {if $viewing > $grand_total}{$grand_total}{else}{$viewing}{/if} of {$grand_total}
    + {if $prepage neq 0}Previous{/if}{$show_pages}{if $nextpage neq $smarty.section.allpages.index && $pages!=1}Next{/if}
    +
    + + + + +
    + + + + + + + + {assign var = bgcolor value = ""} + {section name=list loop=$videos} + + + + + + + {if $bgcolor == ""} + {assign var = bgcolor value = "#EEEEEE"} + {else} + {assign var = bgcolor value = ""} + {/if} + {/section} +
    + + VIDDetails 
    {$videos[list].videoid} + + {$videos[list].title} + -- + + Featured:{$videos[list].featured} | + Active:{$videos[list].active} | + Status:{$videos[list].status} + + +
    + +
     
    +
    + +
    + + + + + + +
    + {if $prepage neq 0}Previous{/if}{$show_pages}{if $nextpage neq $smarty.section.allpages.index && $pages!=1}Next{/if}
    diff --git a/upload/admin_area/styles/clipbucketblue/layout/view_conversion_log.html b/upload/admin_area/styles/clipbucketblue/layout/view_conversion_log.html new file mode 100644 index 00000000..3c8b41a3 --- /dev/null +++ b/upload/admin_area/styles/clipbucketblue/layout/view_conversion_log.html @@ -0,0 +1,52 @@ + +{if $data.id} + +
    Conversion Log For File "{$data.src_name}"
    + + + + + + {foreach from=$data item=value key=field} + {if $field|truncate:4:'' == src_} + + + + + {/if} + {/foreach} + + + + + + + + {foreach from=$data item=value key=field} + {if $field|truncate:7:'' == output_} + + + + + {/if} + {/foreach} + + + + + + + + + + + + + + +
    Source File Information
    Source {$field|substr:4:100|replace:'_':' '}{$value}
      
    Output File Information
    Output File {$field|substr:7:100|replace:'_':' '}{$value}
      
    Conversion Log For "{$data.src_name}
    +
    +
    {$data.file_conversion_log|nl2br}
    +
      
    +{else} File does not exist +{/if} \ No newline at end of file diff --git a/upload/admin_area/styles/clipbucketblue/layout/view_video.html b/upload/admin_area/styles/clipbucketblue/layout/view_video.html new file mode 100644 index 00000000..c4a2b106 --- /dev/null +++ b/upload/admin_area/styles/clipbucketblue/layout/view_video.html @@ -0,0 +1,186 @@ + +
    {$data.title}
    +{assign var='requiredFields' value=$Upload->loadRequiredFields($data)} +{assign var='optionFields' value=$Upload->loadOptionFields($data)} +{assign var='locationFields' value=$Upload->loadLocationFields($data)} + +{assign var='custom_fields' value=$Upload->load_custom_upload_fields($data,TRUE)} +{assign var='custom_form_fields' value=$Upload->load_custom_form_fields($data,TRUE)} + + + + + + + + + + + + + + + + + + + + +
    Video DetailsWatch on Front End | Edit Video
    + + + + + + + {foreach from=$requiredFields item=field} + + + + + {/foreach} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {foreach from=$optionFields item=field} + + + + + {/foreach} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {foreach from=$custom_fields item=field} + + + + + + {foreachelse} + + + + + {/foreach} + + + + + + + + {foreach from=$custom_form_fields item=field} + + + + + + {foreachelse} + + + + + {/foreach} + + + + + + + + + + + + + + + + + + + +
     
    Information
    {$field.title}{ANCHOR place=$field.anchor_before}{input_value input=$field}
      
    Important Details and Files information
    Video Id{$data.videoid}
    Video Key{$data.videokey}
    File Name{$data.file_name}
    Video Files{get_all_video_files vdetails=$data count_only=true}
    Thumb Files {get_thumb vdetails=$data count_only=true}
     {assign var=vidthumbs value=func->get_thumb($data,1,TRUE)} + + {foreach from=$vidthumbs item=vid_thumb} +
    +
    + {if $data.default_thumb==$vid_thumb|get_thumb_num}Default{/if} +
    + {/foreach} + +
    View File Details and Converion Log
      
    Sharing Options
    {$field.title}{ANCHOR place=$field.anchor_before}{input_value input=$field}
      
    Stats
    Views{$data.views}
    Rating{$data.rating} + of 10
    RatedBy{$data.rated_by}
    Duration{$data.duration|SetTime}
      
    Custom Upload Options
    {$field.title}{$field.value|form_val}
    No Custom Fields
      
    Custom Form Fields
    {$field.title}{$field.value|form_val}
    No Custom Fields
      
    User Information
    User id{$udata.userid}
    User name{$udata.username}
    Videos Uploaded{$userquery->get_user_vids($data.userid,'',true)}
    + This content requires JavaScript and Macromedia Flash Player 7 or higher. Get Flash

    +
    +
      
    Video Comments
    {assign var=id value=$data.videoid}{include file="$style_dir/blocks/comments.html" type=v id=$data.videoid link="video=$id"}
    diff --git a/upload/admin_area/styles/clipbucketblue/theme/login.css b/upload/admin_area/styles/clipbucketblue/theme/login.css new file mode 100644 index 00000000..f64c999c --- /dev/null +++ b/upload/admin_area/styles/clipbucketblue/theme/login.css @@ -0,0 +1,14 @@ +top_head { + background-color: #ffffff; + background-image: url(../images/top_bg.jpg); + background-position: left bottom; + background-repeat: repeat-x; +} + +.top_head { + background-image: url(../images/top_body_bg.jpg); + background-position: top right; + background-repeat: no-repeat; + margin: 0; + border-bottom: 2px solid #53bafe; +} \ No newline at end of file diff --git a/upload/admin_area/styles/clipbucketblue/theme/slidemenu.css b/upload/admin_area/styles/clipbucketblue/theme/slidemenu.css new file mode 100644 index 00000000..abd66f3d --- /dev/null +++ b/upload/admin_area/styles/clipbucketblue/theme/slidemenu.css @@ -0,0 +1,146 @@ +.navbar +{ + width: 200px; + padding-left: 5px; +} + +.mainDiv +{ + width:185px; +} + +.topItem +{ + letter-spacing: 0; + background: url("../images/arrow-up-title-on.jpg") no-repeat 0 0; + background-position:center center; + background-repeat:no-repeat; + border: none; + width: 185px; + height: 25px; + color: #FFFFFF; + cursor:pointer; + text-indent:10px; + padding-top: 10px; + font-family: Arial, Helvetica, sans-serif; + font-size: 12px; + font-weight: bold; +} + +.topItemOver +{ + text-indent:10px; + letter-spacing: 0; + background: url("../images/arrow-up-title.jpg") no-repeat 0 0; + background-position:center center; + background-repeat:no-repeat; + height: 25px; + width: 185px; + color: #FFFFFF; + cursor:pointer; + font-family: Arial, Helvetica, sans-serif; + font-size: 12px; + font-weight: bold; + text-decoration: underline; + padding-top: 10px; +} + +.topItemClose +{ + text-indent:10px; + letter-spacing: 0; + background: url("../images/arrow-down-title-on.jpg") no-repeat 0 0; + background-position:center center; + background-repeat:no-repeat; + height: 25px; + width: 185px; + color: #FFFFFF; + cursor:pointer; + font-family: Arial, Helvetica, sans-serif; + font-size: 12px; + font-weight: bold; + padding-top: 10px; +} + + +.topItemCloseOver +{ + text-indent:10px; + letter-spacing: 0; + background: url("../images/arrow-down-title.jpg") no-repeat 0 0; + background-position:center center; + background-repeat:no-repeat; + height: 25px; + width: 185px; + color: #FFFFFF; + cursor:pointer; + font-family: Arial, Helvetica, sans-serif; + font-size: 12px; + font-weight: bold; + text-decoration: underline; + padding-top: 10px; +} + + + +.dropMenu +{ + font: bold 11px tahoma,verdana,sans-serif; + background-color: #F7F7F7; + color: #000; + border: 1px solid #FFFFFF; + border-width: 0 1px 1px 1px; + filter:alpha(opacity=100); + padding-top:5px; + padding-bottom:5px; +} + +.subMenu +{ + display:block; +} + +.subItem +{ + margin-left:10px; + margin-top:2px; + height:18px; + font: 11px tahoma,verdana,sans-serif; + text-decoration:none; + color: #215dc6; + +} + +.subItem a +{ + margin-left:23px; + font: 11px tahoma,verdana,sans-serif; + text-decoration:none; + color: #215dc6; +} + +.subItemOver +{ + margin-left:10px; + margin-top:2px; + font: 11px tahoma,verdana,sans-serif; + height:18px; + color: #428eff; +} + +.subItemOver a +{ + margin-left:23px; + font: 11px tahoma,verdana,sans-serif; + cursor:pointer; + color: #428eff; + text-decoration:underline; + cursor:pointer; +} + + +.drop +{ + border-left:1px solid black; + border-right:1px solid black; +} diff --git a/upload/admin_area/styles/clipbucketblue/theme/stylesheet.css b/upload/admin_area/styles/clipbucketblue/theme/stylesheet.css new file mode 100644 index 00000000..7dfa92b5 --- /dev/null +++ b/upload/admin_area/styles/clipbucketblue/theme/stylesheet.css @@ -0,0 +1,240 @@ +@import url("slidemenu.css"); + +body { + font-family: Arial, Helvetica, sans-serif; + font-size: 11px; + margin: 0px; + min-width:950px; +} +h3 { + font-family: Arial, Helvetica, sans-serif; + font-size: 12px; + font-weight: bold; + color: #0537AB; + margin: 0px; + padding: 0px; +} + +h2 { + font-family: Arial, Helvetica, sans-serif; + font-size: 14px; + color: #0537AB; +} + +h1 { + font-family: Arial, Helvetica, sans-serif; + font-size: 18px; + font-weight: bold; + color: #0537AB; +} +a { + font-family: Arial, Helvetica, sans-serif; + font-size: 12px; + font-weight:bold; + color:#041B55; + text-decoration:none; +} +a:hover{text-decoration:underline;} + +.top_links{ + height: 35px; + width: 300px; + min-height:inherit; + right: 0px; + background-image: url(../images/top_links_bg.png); + background-repeat:no-repeat; + background-position:right; + top: 10px; + color: #FFFFFF; +} +.top_links a{ + color: #FFFFFF; + text-decoration: none; +} +.top_links a:link{ + color: #FFFFFF; + text-decoration: none; +} +.top_links a:visited{ + color: #FFFFFF; + text-decoration: none; +} +.top_links a:hover{ + color: #FFFFFF; + text-decoration: underline; +} + +.tr_head { + font-family: Calibri; + font-size: 12px; + color: #3399FF; + font-weight: bold; + background-color: #F2F2F2; + height: 10px; + vertical-align: middle; + padding: 5px; +} +.td_body { + border: 1px solid #F2F2F2; + padding: 3px; +} + + +.setting_title{ + font-family: Calibri; + font-size: 18px; + font-weight: bold; + color: #3399FF; + text-decoration: none; + height: 39px; + width: 500px; + padding-left: 10px; + padding-top: 7px; + background-image: url(../images/menu_bg.png); + background-repeat: no-repeat; + margin-left: 4px; +} +.title{ + font-family: Arial, Helvetica, sans-serif; + color: #3399FF; + font-size: 12px; + font-weight: bold; +} +#button { + font-family: Arial, Helvetica, sans-serif; + font-size: 13px; + font-weight: bold; + color: #FFFFFF; + background-color: #3399FF; + border: 1px solid #333333; + height: 20px; +} +hr { + border-top-width: 1px; + border-top-style: none; + border-top-color: #C0C0C0; + height: 1px; +} +.pagination{ + font-family: Arial, Helvetica, sans-serif; + font-size: 12px; + font-weight: bold; + color: #FFFFFF; +} +.pagination a{ + font-family: Arial, Helvetica, sans-serif; + font-size: 11px; + color: #FFFFFF; + text-decoration:none; +} +.pagination a:link{ +text-decoration:none; +} +.pagination a:visited{ +text-decoration:none; +} +.pagination a:hover{ +text-decoration:none; +} + + + +#fixedtipdiv{ +position:absolute; +padding: 0px; +border:0px; +font:normal 12px Verdana; +line-height:18px; +z-index:100; +} + +.des_table{ + border: 1px solid #999999; +} + +.tborder { +background:#D1D1E1 none repeat scroll 0%; +border:1px solid #000000; +color:#000000; +} + +.tcat { +background:#53bafe url("../images/navbar_bg.png") repeat-x scroll right top; +color:#FFFFFF; +font-family:verdana,geneva,lucida,'lucida grande',arial,helvetica,sans-serif; +font-size:10pt; +font-size-adjust:none; +font-stretch:normal; +font-style:normal; +font-variant:normal; +font-weight:bold; +line-height:normal; +} +.tcat a:link, .tcat_alink { +color:#FFFFFF; +text-decoration:none; +} +.tcat a:visited, .tcat_avisited { +color:#FFFFFF; +text-decoration:none; +} +.tcat a:hover, .tcat a:active, .tcat_ahover { +color:#FFFFFF; +text-decoration:underline; +} + +.panelsurround { +background:#FAFAF8 none repeat scroll 0%; +color:#000000; +} + +.panel { +background:#FAFAF8 none repeat scroll 0%; +border:1px solid #D1D1E1; +color:#000000; +padding:10px; +} + +.fieldset, .fieldset td, .fieldset p, .fieldset li { +font-size:11px; +} +.fieldset { +margin-bottom:6px; +} + +.smallfont, .smallfont a:link, .smallfont a:visited, .smallfont a:hover { +font-size-adjust:none; +font-stretch:normal; +font-style:normal; +font-variant:normal; +font-weight:normal; +line-height:normal; +color: #000000; +white-space:nowrap; +} + +.smallfontfoot, .smallfontfoot a:link, .smallfontfoot a:visited, .smallfontfoot a:hover { +font-size-adjust:none; +font-stretch:normal; +font-style:normal; +font-variant:normal; +font-weight:normal; +line-height:normal; +color: #000000; +white-space:nowrap; +} + +form { +margin:0px; +} + + +.td_body:hover{background-color:#DFF3FF}.head_title { + font-family: Arial, Helvetica, sans-serif; + font-size: 12px; + font-style: normal; + font-weight: bold; + color: #FFF; + background-color: #53baff; + padding: 2px; +} diff --git a/upload/admin_area/super_admin.php b/upload/admin_area/super_admin.php new file mode 100644 index 00000000..71f71742 --- /dev/null +++ b/upload/admin_area/super_admin.php @@ -0,0 +1,32 @@ +SuperAdminCheck(); +$pages->page_redir(); + +//Updatingh Super Admin Details +if(isset($_POST['button'])){ + $msg = $userquery->UpdateSuperAdmin(); +} + +//Getting Details of the Super admin +$query = mysql_query("SELECT * FROM admin WHERE admin_id = '1' "); +$data = mysql_fetch_array($query); + +Assign('data',$data); + +Assign('msg',$msg); +Template('header.html'); +Template('leftmenu.html'); +Template('message.html'); +Template('super_admin.html'); +Template('footer.html'); + +?> diff --git a/upload/admin_area/templates.php b/upload/admin_area/templates.php new file mode 100644 index 00000000..01b6d3d3 --- /dev/null +++ b/upload/admin_area/templates.php @@ -0,0 +1,74 @@ +admin_login_check(); +//$pages->page_redir(); + +//Getting And Listing Files +if(!file_exists(BASEDIR.'/'.TEMPLATEFOLDER.'/'.@$_GET['temp']) || @$_GET['temp']==''){ +$dir = SITETEMPLATEDIR.'/layout/'; +$cur_dir = TEMPLATE; +}else{ +$dir = BASEDIR.'/'.TEMPLATEFOLDER.'/'.$_GET['temp'].'/layout/'; +$cur_dir = $_GET['temp']; +} +if(!($dp = opendir($dir))) die("Cannot open $dir."); +while($file = readdir($dp)){ +$ext = GetExt($file); +if($ext == 'html' || $ext == 'HTML'){ +$files[] = $file; +} +} +closedir($dp +); +sort($files); +Assign('files',$files); + +//Writng File +if(isset($_POST['save'])){ + $file = $dir.$_POST['file']; + $data = stripslashes($_POST['data']); + $open_file = fopen($file, "w"); + fwrite($open_file, $data); + $msg = $_POST['file']." Has Been Saved And Updated"; +} + +//Getting Data from File +if(isset($_POST['file'])){ +$file = $dir.$_POST['file']; +$_file = $_POST['file']; +}else{ +$file = $dir.$files[0]; +$_file = $files[0]; +} +$open_file = fopen($file, "r"); +$data = htmlentities(file_get_contents($file)); + +//Getting Template List +$query = "SELECT * FROM template ORDER by template_name"; +$TmpExe = $db->Execute($query); +$Temps = $TmpExe->getrows(); +Assign('Temps',$Temps); + +//Checking Which Template Currently Using +$query = mysql_query("SELECT template_name,template_dir FROM template WHERE template_dir='".mysql_clean($cur_dir)."'"); +$TempArr = mysql_fetch_assoc($query); + +Assign('CurTemplate',$TempArr['template_name']); +Assign('CurDir',$TempArr['template_dir']); +Assign('data',$data); +Assign('file',$_file); + +Assign('msg',@$msg); +Template('header.html'); +Template('leftmenu.html'); +Template('templates.html'); +Template('footer.html'); +?> \ No newline at end of file diff --git a/upload/admin_area/upload_thumbs.php b/upload/admin_area/upload_thumbs.php new file mode 100644 index 00000000..3de97bc5 --- /dev/null +++ b/upload/admin_area/upload_thumbs.php @@ -0,0 +1,69 @@ +admin_login_check(); +$pages->page_redir(); + +if(@$_GET['msg']){ +$msg[] = clean($_GET['msg']); +} + +$video = mysql_clean($_GET['video']); + + +//Check Video Exists or Not +if($myquery->VideoExists($video)){ + + # Setting Default thumb + if(isset($_POST['update_default_thumb'])) + { + $myquery->set_default_thumb($video,$_POST['default_thumb']); + } + + $data = get_video_details($video);; + $vid_file = get_video_file($data); + + # Uploading Thumbs + if(isset($_POST['upload_thumbs'])){ + $Upload->upload_thumbs($data['file_name'],$_FILES['vid_thumb']); + } + + # Delete Thumb + if(isset($_GET['delete'])) + delete_video_thumb($_GET['delete']); + + # Generating more thumbs + if(isset($_GET['gen_more'])) + { + require_once(BASEDIR.'/includes/classes/conversion/ffmpeg.win32.php'); + $ffmpeg = new ffmpeg($file_details['output_path']); + $ffmpeg->generate_thumbs($vid_file,$data['duration'],$dim='120x90',$num=3,$rand=true); + } + + Assign('data',$data); + Assign('rand',rand(44,444)); + +}else{ + $msg[] = $LANG['class_vdo_del_err']; +} + + + + + +//Assing Template +Assign('msg',@$msg); +Template('header.html'); +Template('leftmenu.html'); +Template('message.html'); +Template('upload_thumbs.html'); +Template('footer.html'); + +?> \ No newline at end of file diff --git a/upload/admin_area/user_levels.php b/upload/admin_area/user_levels.php new file mode 100644 index 00000000..adf125e5 --- /dev/null +++ b/upload/admin_area/user_levels.php @@ -0,0 +1,75 @@ +page_redir(); +$userquery->login_check('admin_access'); + +$mode = $_GET['mode']; +$lid = mysql_clean($_GET['lid']); +$action = mysql_clean($_GET['action']); + +//Deleteing Level +if($action=='delete') + $userquery->delete_user_level($lid); + +switch($mode) +{ + case 'view': + default: + { + Assign('view','view'); + } + break; + + case 'edit': + { + //Updating Level permissions + if(isset($_POST['update_level_perms'])) + { + $perm_array = $_POST; + $userquery->update_user_level($lid,$perm_array); + } + + + //Getting Details of $level + $levelDetails = $userquery->get_level_details($lid); + Assign('level_details',$levelDetails); + + //GettinG Level Permission + $level_perms = $userquery->get_level_permissions($lid); + Assign('level_perms',$level_perms); + + Assign('view','edit'); + } + break; + + case 'add': + { + if(isset($_POST['add_new_level'])) + { + $array = $_POST; + if($userquery->add_user_level($array)); + redirect_to('user_levels.php'); + } + Assign('view','add'); + } +} + + + +Assign('msg', @$msg); +Template('header.html'); +Template('leftmenu.html'); +Template('message.html'); +Template('user_levels.html'); +Template('footer.html'); + +?> \ No newline at end of file diff --git a/upload/admin_area/vid_check.php b/upload/admin_area/vid_check.php new file mode 100644 index 00000000..825c94ca --- /dev/null +++ b/upload/admin_area/vid_check.php @@ -0,0 +1,22 @@ +admin_login_check(); +$pages->page_redir(); + +$check = $_REQUEST['check']; + +Template('header.html'); +Template('leftmenu.html'); +Template('message.html'); +test_exec( 'bash -version' ); +test_exec( $check.' -version' ); + +Template('footer.html'); +?> \ No newline at end of file diff --git a/upload/admin_area/vid_test.php b/upload/admin_area/vid_test.php new file mode 100644 index 00000000..3059206e --- /dev/null +++ b/upload/admin_area/vid_test.php @@ -0,0 +1,30 @@ +admin_login_check(); +$pages->page_redir(); + +Template('header.html'); +Template('leftmenu.html'); +Template('message.html'); +test_exec( 'bash -version' ); +test_exec( 'which ffmpeg' ); +test_exec( 'which mencoder' ); +test_exec( 'which mplayer' ); +test_exec( 'which flvtool2' ); +test_exec( 'which php' ); + +Template('footer.html'); +?> \ No newline at end of file diff --git a/upload/admin_area/video_manager.php b/upload/admin_area/video_manager.php new file mode 100644 index 00000000..6e901626 --- /dev/null +++ b/upload/admin_area/video_manager.php @@ -0,0 +1,273 @@ +admin_login_check(); +$pages->page_redir(); + +//Feature / UnFeature Video +if(isset($_GET['make_feature'])){ + $video = mysql_clean($_GET['make_feature']); + if($myquery->VideoExists($video)){ + $msg[] = $myquery->MakeFeaturedVideo($video); + }else{ + $msg[] = $LANG['class_vdo_del_err']; + } +} +if(isset($_GET['make_unfeature'])){ + $video = mysql_clean($_GET['make_unfeature']); + if($myquery->VideoExists($video)){ + $msg[] = $myquery->MakeUnFeaturedVideo($video); + }else{ + $msg[] = $LANG['class_vdo_del_err']; + } +} + +//Using Multple Action + if(isset($_POST['make_featured_selected'])){ + for($id=0;$id<=RESULTS;$id++){ + $myquery->MakeFeaturedVideo($_POST['check_video'][$id]); + } + $msg = "Selected Videos Have Been Set As Featured"; + } + if(isset($_POST['make_unfeatured_selected'])){ + for($id=0;$id<=RESULTS;$id++){ + $myquery->MakeUnFeaturedVideo($_POST['check_video'][$id]); + } + $msg = "Selected Videos Have Been Removed From The Featured Video List"; + } + + + +//Add To Editor's Pick +if(isset($_GET['editor_pick'])){ + $video = mysql_clean($_GET['editor_pick']); + if($myquery->VideoExists($video)){ + $msg[] = $myquery->AddToEditorPick($video); + }else{ + $msg[] = $LANG['class_vdo_del_err']; + } +} + +//Activate / Deactivate + +if(isset($_GET['activate'])){ + $video = mysql_clean($_GET['activate']); + if($myquery->VideoExists($video)){ + $msg[] = $myquery->ActivateVideo($video); + }else{ + $msg[] = $LANG['class_vdo_del_err']; + } +} +if(isset($_GET['deactivate'])){ + $video = mysql_clean($_GET['deactivate']); + if($myquery->DeActivateVideo($video)){ + $msg[] = $myquery->DeActivateVideo($video); + }else{ + $msg[] = $LANG['class_vdo_del_err']; + } +} + + //Using Multple Action + if(isset($_POST['activate_selected'])){ + for($id=0;$id<=RESULTS;$id++){ + $myquery->ActivateVideo($_POST['check_video'][$id]); + } + $msg = "Selected Videos Have Been Activated"; + } + if(isset($_POST['deactivate_selected'])){ + for($id=0;$id<=RESULTS;$id++){ + $myquery->DeActivateVideo($_POST['check_video'][$id]); + } + $msg = "Selected Videos Have Been Dectivated"; + } + + +//Delete Video +if(isset($_GET['delete_video'])){ + $video = mysql_clean($_GET['delete_video']); + if($myquery->VideoExists($video)){ + $msg[] = $myquery->DeleteVideo($video); + }else{ + $msg[] = $LANG['class_vdo_del_err']; + } +} + +//Deleting Multiple Videos +if(isset($_POST['delete_selected'])){ + for($id=0;$id<=RESULTS;$id++){ + if($myquery->VideoExists($_POST['check_video'][$id])){ + $msg[] = $myquery->DeleteVideo($_POST['check_video'][$id]); + } + } + $msg = $LANG['vdo_del_selected']; +} + +//Assigning Default Values +@$values_search= array( + 'search_uname' => mysql_clean($_GET['username']), + 'search_flagged' => mysql_clean($_GET['flagged']), + 'search_tags' => mysql_clean($_GET['tags']), + 'search_category' => mysql_clean($_GET['category']), + 'search_title' => mysql_clean($_GET['title']), + 'search_active' => mysql_clean($_GET['active']), + 'search_featured' => mysql_clean($_GET['featured']), + 'search_sort' => mysql_clean($_GET['sort']), + 'search_order' => mysql_clean($_GET['order']) + ); + while(list($name,$value) = each($values_search)){ + DoTemplate::assign($name,$value); + } + + +//Jump To The page +if(isset($_POST['display_page'])){ + redirect_to($_POST['page_number']); +} + +//Pagination + + $limit = RESULTS; + Assign('limit',$limit); + $page = clean(@$_GET['page']); + Assign('limit',$limit); + if(empty($page) || $page == 0){ + $page = 1; + } + $from = $page-1; + $from = $from*$limit; + + $query_limit = "limit $from,$limit"; + $order = "ORDER BY date_added DESC"; + $sql = "SELECT * from video $order $query_limit"; + $sql_p = "SELECT * from video"; + +//Search +if(isset($_GET['search'])){ + $username = mysql_clean($_GET['username']); + $title = mysql_clean($_GET['title']); + $flagged = mysql_clean($_GET['flagged']); + $featured = mysql_clean($_GET['featured']); + $active = mysql_clean($_GET['active']); + $featured = mysql_clean($_GET['featured']); + $tags = mysql_clean($_GET['tags']); + $category = mysql_clean($_GET['category']); + $sort = mysql_clean($_GET['sort']); + $order = mysql_clean($_GET['order']); + + if($order == 'ASC'){ + if($sort == 'username'){ $orderby = 'ORDER BY username ASC';} + if($sort == 'title'){ $orderby = 'ORDER BY title ASC';} + if($sort == 'date_added'){ $orderby = 'ORDER BY date_added ASC';} + if($sort == 'views'){ $orderby = 'ORDER BY views ASC';} + if($sort == 'rating'){ $orderby = 'ORDER BY rating ASC';} + }else{ + if($sort == 'username'){ $orderby = 'ORDER BY username DESC';} + if($sort == 'title'){ $orderby = 'ORDER BY title DESC';} + if($sort == 'date_added'){ $orderby = 'ORDER BY date_added DESC';} + if($sort == 'views'){ $orderby = 'ORDER BY views DESC';} + if($sort == 'rating'){ $orderby = 'ORDER BY rating DESC';} + } + + $category = "AND + ( + category01 = '".$category."' OR + category02 = '".$category."' OR + category03 = '".$category."' + ) + "; + + if(!empty($flagged)){ + $query_flagged = "AND flagged = '".$flagged."'"; + } + if(!empty($featured)){ + $query_featured = "AND featured = '".$featured."'"; + } + if(!empty($active)){ + $query_active = "AND active = '".$active."'"; + } + + + $sql = "SELECT * from video "; + $sql .= "WHERE + username like '%$username%' AND + title like '%$title%' + $query_flagged + $query_featured + $query_active AND + tags like '%$tags%' + $category $orderby $query_limit + "; + + $sql_p = "SELECT * from video WHERE + username like '%$username%' AND + title like '%$title%' + $query_flagged + $query_featured + $query_active + AND tags like '%$tags%' + $category "; +} + + //Assing User Data Values + $rs = $db->Execute($sql); + $total = $rs->recordcount() + 0; + $videos = $rs->getrows(); + + for($id=0;$id<$total;$id++){ + $videos[$id]['thumb'] = substr($videos[$id]['flv'], 0, strrpos($videos[$id]['flv'], '.')); + $videos[$id]['description'] = nl2br($videos[$id]['description']); + $videos[$id]['category1'] = $myquery->GetCategory($videos[$id]['category01'],'category_name'); + $videos[$id]['category2'] = $myquery->GetCategory($videos[$id]['category02'],'category_name'); + $videos[$id]['category3'] = $myquery->GetCategory($videos[$id]['category03'],'category_name'); + } + + Assign('total', $total + 0); + Assign('videos', $videos); + +//Pagination #A Tough Job# +$view = clean(@$_GET['view']); +if($view == 'search'){ +$link = '&username=' .mysql_clean($_GET['username']). '&title=' .mysql_clean($_GET['title']).'&flagged=' .mysql_clean($_GET['flagged']).'&featured=' .mysql_clean($_GET['featured']).'&active='.mysql_clean($_GET['active']).'&tags='.mysql_clean($_GET['tags']).'&category01='.mysql_clean($_GET['category01']).'&category02='.mysql_clean($_GET['category02']).'&category03='.mysql_clean($_GET['category03']).'&sort='.mysql_clean($_GET['sort']).'&order='.mysql_clean($_GET['order']).'&search='.mysql_clean($_GET['search']); +Assign('link',$link); +} + + $query = mysql_query($sql_p); + Assign('grand_total',mysql_num_rows($query)); + $total_rows = mysql_num_rows($query); + $page_id=1; + $id = 1; + //$all_pages[0]['page'] = $page_id; + $records = $total_rows/$limit; + $total_pages = round($records+0.49,0); +if(empty($link)){ +$link = "?view=Videos"; +} + +$pages->paginate($total_pages,$page,$link); + + +//Assigning Category List + $sql = "SELECT * from category"; + $rs = $db->Execute($sql); + $total_categories = $rs->recordcount() + 0; + $category = $rs->getrows(); + Assign('category', $category); + +Assign('msg', @$msg); +/*Template('header.html'); +Template('leftmenu.html'); +Template('message.html'); +Template('video_manager.html'); +Template('footer.html');*/ + +template_files('video_manager.html'); +display_it(); + +?> \ No newline at end of file diff --git a/upload/admin_area/view_conversion_log.php b/upload/admin_area/view_conversion_log.php new file mode 100644 index 00000000..29b615e7 --- /dev/null +++ b/upload/admin_area/view_conversion_log.php @@ -0,0 +1,24 @@ +admin_login_check(); +$pages->page_redir(); + +$file_name = mysql_clean($_GET['file_name']); +$file_details = $myquery->file_details($file_name); +if($file_details) +{ + assign('data',$file_details); +} + + +template_files('view_conversion_log.html'); +display_it(); +?> \ No newline at end of file diff --git a/upload/admin_area/view_lang_vars.php b/upload/admin_area/view_lang_vars.php new file mode 100644 index 00000000..b4e34004 --- /dev/null +++ b/upload/admin_area/view_lang_vars.php @@ -0,0 +1,72 @@ +admin_login_check(); +$pages->page_redir(); + +//Adding new phrase +if(isset($_POST['button'])) +{ + $name = $_POST['name']; + $text = $_POST['text']; + $lang_obj->add_phrase($name,$text); +} + +//Getting lang variables + +$query = mysql_query("SELECT * FROM phrases ORDER BY text ASC"); + +?> +
    + + + + + + + + + + + + + + + + + + +
    Add New 
    +
    +  
      
    +
    + + + + + + + + + + + + + +
    Phrase Code +Sentence +
    + +
    diff --git a/upload/admin_area/view_video.php b/upload/admin_area/view_video.php new file mode 100644 index 00000000..8597c044 --- /dev/null +++ b/upload/admin_area/view_video.php @@ -0,0 +1,51 @@ +admin_login_check(); +$pages->page_redir(); + +if(@$_GET['msg']){ +$msg[] = clean($_GET['msg']); +} + + $video = mysql_clean($_GET['video']); + + //Check Video Exists or Not + if($myquery->VideoExists($video)){ + //Deleting Comment + $cid = mysql_clean($_GET['delete_comment']); + if(!empty($cid)) + { + $myquery->delete_comment($cid); + } + + //Get Video Details + $data = get_video_details($video); + Assign('udata',$userquery->get_user_details($data['userid'])); + Assign('data',$data); + }else{ + $msg[] = $LANG['class_vdo_del_err']; + } + + + + +Assign('msg',@$msg); +/*Template('header.html'); +Template('leftmenu.html'); +Template('message.html'); +Template('view_video.html'); +Template('footer.html');*/ + +template_files('view_video.html'); +display_it(); + + +?> \ No newline at end of file diff --git a/upload/cUrldownload.php b/upload/cUrldownload.php new file mode 100644 index 00000000..5bd9e50f --- /dev/null +++ b/upload/cUrldownload.php @@ -0,0 +1,170 @@ + 0) { + if (isset($matches)) { + $file_size = $matches[1]; + $file_size_kb = round($file_size/1024, 2); + } else { + $no_filesize = true; + unset($file_size); + } + } else { + } + $copy_fail = false; + if($file_size > $sizelimit && $sizelimit > 0) + $copy_fail = true; + + if($copy_fail == false && $file_size > 0) { + $header = array( + "User-Agent: ". $_SERVER['HTTP_USER_AGENT'], + "Accept: " . $_SERVER['HTTP_ACCEPT'], + "Accept-Language: " . $_SERVER['HTTP_ACCEPT_LANGUAGE'], + "Accept-Charset: ". $_SERVER ['HTTP_ACCEPT_CHARSET'], + "Accept-Encoding: " . $_SERVER['HTTP_ACCEPT_ENCODING'], + "Connection: " . $_SERVER['HTTP_CONNECTION'] + ); + $ch = curl_init($file); + $fp = fopen($ds, 'w'); + curl_setopt($ch, CURLOPT_FILE, $fp); + curl_setopt($ch, CURLOPT_HEADER, 0); + curl_setopt($ch, CURLOPT_HTTPHEADER, $header); + curl_exec($ch); + $curl_info = curl_getinfo($ch); + curl_close($ch); + fclose($fp); + } + + //incase curl doesnt not work + }elseif($snatch_system == 'url_open' || !file_exists($newfile_ds)){ + if (!copy($file, $ds)) + $copy_fail = true; + } + + if ($copy_fail == false) { + if ($sizelimit > 0 && filesize($ds) > $sizelimit) { + unlink($ds); + } else { + if ($snatch_system == 'curl') { + $size_dl = round($curl_info['size_download']/1024, 2); + $speed_dl = round($curl_info['speed_download']/1024, 2); + } + } + } + + $_SESSION['is_upload'] = "Success"; + + $php_path = PHP_PATH; + exec("$php_path convert_process.php $newfilename $flvname >> ".BASEDIR."/logs/logs.txt &"); + } +} + +?> \ No newline at end of file diff --git a/upload/captcha.php b/upload/captcha.php new file mode 100644 index 00000000..623e87d0 --- /dev/null +++ b/upload/captcha.php @@ -0,0 +1,12 @@ +generates_image($word,true); +?> \ No newline at end of file diff --git a/upload/channels.php b/upload/channels.php new file mode 100644 index 00000000..f95a0c41 --- /dev/null +++ b/upload/channels.php @@ -0,0 +1,102 @@ +page_redir(); +subtitle('channels'); + +//Getting Order + @$order = $_GET['order']; + if(empty($order) || is_array($_GET['order'])){ + $order = "ra"; + } +$orders = array( + "mv" => "ORDER BY profile_hits DESC", + "fr" => "WHERE featured='yes'", + "ra" => "ORDER BY doj DESC", + "vd" => "ORDER BY total_videos DESC", + "ct" => "ORDER BY total_comments DESC" + ); + +@$show_order = array( + "mv" => $LANG['mostly_viewed'], + "fr" => $LANG['featured'], + "ra" => $LANG['recently_added'], + "vd" => $LANG['most_videos'], + "ct" => $LANG['most_comments'] + ); +Assign('show_order',$show_order[$order]); + +//Setting Up Queries + + $limit = CLISTPP; + Assign('limit',$limit); + @$page = clean($_GET['page']); + if(empty($page) || $page == 0 || !is_numeric($page) || $page < 0){ + $page = 1; + } + $from = $page-1; + $from = $from*$limit; + $query_limit = "limit $from,$limit"; + + $orderby = $orders[$order]; + + //$sql = "SELECT * FROM users WHERE usr_status='Ok' $orderby $query_limit"; + //$sql_p = "SELECT * FROM users WHERE usr_status='Ok' $orderby"; + + $sql = "SELECT * FROM users $orderby $query_limit"; + $sql_p = "SELECT * FROM users $orderby "; + + $user_data = $db->Execute($sql); + $total_users = $user_data->recordcount() + 0; + $users = $user_data->getrows(); + + for($id=0;$id<$total_users;$id++){ + + $sql = "Select * FROM channel_comments WHERE channel_user='".$users[$id]['username']."'"; + $rs = $db->Execute($sql); + $users[$id]['total_comments'] = $rs->recordcount() + 0; + + $sql = "Select * FROM video WHERE username='".$users[$id]['username']."'"; + $rs = $db->Execute($sql); + $users[$id]['total_videos'] = $rs->recordcount() + 0; + + } + + Assign('users',$users); + +//Pagination +$link = '?order='.$order; +Assign('link',$link); + + $query = mysql_query($sql_p); + Assign('grand_total',mysql_num_rows($query)); + $total_rows = mysql_num_rows($query); + $page_id=1; + $id = 1; + //$all_pages[0]['page'] = $page_id; + $records = $total_rows/$limit; + $pages = round($records+0.49,0); + + +$show_pages = ShowPagination($pages,$page,$link); +Assign('show_pages',$show_pages); + +Assign('pages',$pages); +Assign('cur_page',$page); +Assign('nextpage',$page+1); +Assign('prepage',$page-1); +Assign('total_pages',$page_id); + +@Assign('msg',$msg); +Template('header.html'); +Template('message.html'); +Template('channels.html'); +Template('footer.html'); + +?> \ No newline at end of file diff --git a/upload/compose.php b/upload/compose.php new file mode 100644 index 00000000..30b02dfe --- /dev/null +++ b/upload/compose.php @@ -0,0 +1,77 @@ +logincheck(); +$pages->page_redir(); + +$user = $_SESSION['username']; + + +//Getting User Videos + $sql = "SELECT * from video WHERE username = '".$user."'"; + $rs = $db->Execute($sql); + $videos = $rs->getrows(); + Assign('videos',$videos); + +//Getting User Contacts + $sql = "SELECT * from contacts WHERE username = '".$user."'"; + $rs = $db->Execute($sql); + $contacts = $rs->getrows(); + Assign('contacts',$contacts); + @$msg = $_GET['msg']; + +//Checking If Reply To A Message +if(isset($_POST['reply_to'])){ + $reply_to = $_POST['reply_to']; + $username = $_POST['username']; + $subject = $_POST['subject']; + $message = $_POST['message']; + Assign('reply_to',$reply_to); + Assign('default_username',$username); + Assign('default_subj',$subject); + Assign('default_message',$message); + } + +//Checking If Sendint Somene A Message +if(isset($_POST['send_message'])){ + $username = $_POST['username']; + Assign('default_username',$username); + } +//Sending Composed Message + if(isset($_POST['send_msg'])){ + $message = mysql_clean($_POST['message']); + $user = mysql_clean($_POST['username']); + if(empty($user)){ + $user = $_POST['user_list']; + } + $subj = mysql_clean(clean($_POST['subj'])); + $video = $_POST['video']; + $reply_to = $_POST['reply_to']; + $msg = $myquery->SendMessage($user,$_SESSION['username'],$subj,$message,$video,$reply_to,1); + $values= array( + 'default_username' => mysql_clean($_POST['username']), + 'default_user_list' => mysql_clean($_POST['user_list']), + 'default_subj' => mysql_clean($_POST['subj']), + 'default_video' => mysql_clean($_POST['video']), + 'default_message' => mysql_clean($_POST['message']), + 'reply_to' => $_POST['reply_to'] + ); + while(list($name,$value) = each($values)){ + Assign($name,$value); + } + + } + +Assign('subtitle',$user.$LANG['title_crt_new_msg']); +Assign('msg',clean($msg)); +Template('header.html'); +Template('message.html'); +Template('compose.html'); +Template('footer.html'); +?> \ No newline at end of file diff --git a/upload/contactus.php b/upload/contactus.php new file mode 100644 index 00000000..1ed3043c --- /dev/null +++ b/upload/contactus.php @@ -0,0 +1,16 @@ +page_redir(); +subtitle('contactus'); +Template('header.html'); +Template('message.html'); +Template('contactus.html'); +Template('footer.html'); +?> \ No newline at end of file diff --git a/upload/convert_process.php b/upload/convert_process.php new file mode 100644 index 00000000..7af9ec05 --- /dev/null +++ b/upload/convert_process.php @@ -0,0 +1,13 @@ +ConvertFile($newfilename,$filename); +} + +?> \ No newline at end of file diff --git a/upload/create_group.php b/upload/create_group.php new file mode 100644 index 00000000..bc3bb764 --- /dev/null +++ b/upload/create_group.php @@ -0,0 +1,49 @@ +logincheck(); +$pages->page_redir(); +subtitle('create_group'); + +//Assigning Category List + $sql = "SELECT * from category"; + $rs = $db->Execute($sql); + $total_categories = $rs->recordcount() + 0; + $category = $rs->getrows(); + Assign('category', $category); + +//Form Validation And Submition + if(isset($_POST['create'])){ + $msg = $groups->CreateGroup(); + } + +//Assigning Default Values +@$values= array( + 'default_name' => mysql_clean($_POST['name']), + 'default_des' => mysql_clean($_POST['description']), + 'default_tags' => mysql_clean($_POST['tags']), + 'default_url' => mysql_clean($_POST['url']), + 'default_category' => mysql_clean($_POST['category']), + 'default_type' => mysql_clean($_POST['group_type']), + 'default_vtype' => mysql_clean($_POST['video_type']), + 'default_ptype' => mysql_clean($_POST['post_type']) + ); + while(list($name,$value) = each($values)){ + Assign($name,$value); + } + + +@Assign('msg',$msg); +Template('header.html'); +Template('message.html'); +Template('create_group.html'); +Template('footer.html'); + +?> \ No newline at end of file diff --git a/upload/delete_group.php b/upload/delete_group.php new file mode 100644 index 00000000..d536ea39 --- /dev/null +++ b/upload/delete_group.php @@ -0,0 +1,42 @@ +page_redir(); +$userquery->logincheck(); + +$url = mysql_clean($_GET['url']); +if(isset($_POST['update'])){ + $msg = $groups->UpdateGroup(); +} + include('group_inc.php'); + //Delete Group + $details = $groups->GetDetails($url); + $group = $details['group_id']; + $user = $_SESSION['username']; + if($details['username'] !== $user){ + $msg = $LANG['grp_owner_err1']; + $show_delete = 'No'; + } +Assign('groups',$details); + +if(isset($_POST['delete_group'])){ + $groups->DeleteGroup($_POST['group_id']); + Assign('show_succes','yes'); + $show_delete = 'No'; +} + +Assign('show_delete',@$show_delete); +Assign('subtitle',' Edit '.$details['group_name']); +Assign('msg',@$msg); +Template('header.html'); +Template('message.html'); +Template('delete_group.html'); +Template('footer.html'); +?> \ No newline at end of file diff --git a/upload/download.php b/upload/download.php new file mode 100644 index 00000000..384b5917 --- /dev/null +++ b/upload/download.php @@ -0,0 +1,52 @@ +CheckVideoExists($vkey)){ + $videos = $myquery->GetVideDetails($vkey); + $query = mysql_query("SELECT * FROM video_detail WHERE flv ='".$videos['flv']."'"); + $data = mysql_fetch_array($query); + $flv_folder = 'files/videos'; + $original_folder = 'files/original'; + $flv = $flv_folder.'/'.$data['flv']; + $original = $original_folder.'/'.$data['original']; + if(!empty($data['original']) && file_exists($original)){ + $file = $original; + }elseif(file_exists($flv)){ + $file = $flv; + }else{ + $msg = $LANG['class_vdo_del_err']; + } + if(VIDEO_DOWNLOAD != 1){ + $msg = $LANG['vdo_download_allow_err']; + } + + if(empty($msg)){ + header("Pragma: public"); // required + header("Expires: 0"); + header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); + header("Cache-Control: private",false); // required for certain browsers + header("Content-type: application/force-download"); + header("Content-Length: ".filesize($file)); + header("Content-Disposition: attachment; filename=\"".basename($file)."\""); + readfile("$file"); + } +} +if(!empty($msg) || empty($vkey) || !$myquery->CheckVideoExists($vkey)){ +Assign('msg',$msg); +if(empty($msg)) +Assign('msg',$LANG['class_vdo_del_err']); +Assign('subtitle',$LANG['class_vdo_del_err']); +Template('header.html'); +Template('message.html'); +Template('footer.html'); +} +?> \ No newline at end of file diff --git a/upload/edit_group.php b/upload/edit_group.php new file mode 100644 index 00000000..f3f0200e --- /dev/null +++ b/upload/edit_group.php @@ -0,0 +1,51 @@ +page_redir(); +$userquery->logincheck(); + +$url = mysql_clean($_GET['url']); + //Updating Group + if(isset($_POST['update'])){ + $msg = $groups->UpdateGroup(); + } + //Checks Group exists Or Not + include('group_inc.php'); + + $details = $groups->GetDetails($url); + $group = $details['group_id']; + $user = $_SESSION['username']; + if($details['username'] != $user){ + $msg = $LANG['grp_owner_err1']; + $show_group = 'No'; + } +Assign('groups',$details); + + +//Assigning Category List + $sql = "SELECT * from category"; + $rs = $db->Execute($sql); + $total_categories = $rs->recordcount() + 0; + $category = $rs->getrows(); + Assign('category', $category); + +//If Update is true +$update = mysql_clean(@$_GET['update']); +if($update==true){ + $msg = $LANG['grp_update_msg']; +} +Assign('show_group',@$show_group); +Assign('subtitle',' Edit '.$details['group_name']); +Assign('msg',@$msg); +Template('header.html'); +Template('message.html'); +Template('edit_group.html'); +Template('footer.html'); +?> \ No newline at end of file diff --git a/upload/edit_video.php b/upload/edit_video.php new file mode 100644 index 00000000..fd783c20 --- /dev/null +++ b/upload/edit_video.php @@ -0,0 +1,60 @@ +logincheck(); +$pages->page_redir(); +$user = $_SESSION['username']; + +$videoid = $_REQUEST['videoid']; + +if($userquery->CheckVideoOwner($videoid,$user) == 1 || $is_admin == 1) +{ +//Getting Video Id + + if($myquery->VideoExists($videoid)){ + //Updating Video + if(isset($_POST['update'])){ + $msg = $Upload->ValidateUploadForm(); + if(empty($msg)){ + $msg = $myquery->UpdateVideo($videoid); + } + } + + $data = $myquery->GetVideoDetails($videoid); + //Assigning Thumbs + $data['thumb1'] = GetThumb($data['flv'],1); + $data['thumb2'] = GetThumb($data['flv'],2); + $data['thumb3'] = GetThumb($data['flv'],3); + $data['url'] = VideoLink($data['videokey'],$data['title']); + Assign('data',$data); + Assign('country',$signup->country()); + }else{ + $msg = $LANG['class_vdo_del_err']; + Assign('show_form','no'); + } + + //Assigning Category List + $sql = "SELECT * from category"; + $rs = $db->Execute($sql); + $total_categories = $rs->recordcount() + 0; + $category = $rs->getrows(); + Assign('category', $category); + +Assign('subtitle',$LANG['title_edit_video'].$data['title']); +@Assign('msg',$msg); +Template('header.html'); +Template('message.html'); +Template('edit_video.html'); +Template('footer.html'); +} +else +{ +header( 'Location: '.videos_link.'' ) ; +} +?> \ No newline at end of file diff --git a/upload/error_pages/403.php b/upload/error_pages/403.php new file mode 100644 index 00000000..3debf5ab --- /dev/null +++ b/upload/error_pages/403.php @@ -0,0 +1,23 @@ + \ No newline at end of file diff --git a/upload/error_pages/404.php b/upload/error_pages/404.php new file mode 100644 index 00000000..fcb3211c --- /dev/null +++ b/upload/error_pages/404.php @@ -0,0 +1,15 @@ + \ No newline at end of file diff --git a/upload/favicon.ico b/upload/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..9d50d31110f9f53d781f3f5491b67a9ccaa260b3 GIT binary patch literal 1150 zcmbuoWus@J<;qESL*KK!WZp&}y{(|7Tr?~g>Irsj)zjMxo^KcnE z!0(zG#>b=V%0b4CFvct#k9hJo=MTnsZ~wLZ&;cWU&e&l@{DB=tYz1u~vo54wk0AT) zDKZ-&$k9H^-v$Is4z|GG-$up;TCsSq316oi)Q@TF#U|vEUr;O-b<&?6K^$~I5QHk1 zTAcWP--gZUb4ac)K~WSazhuZCM53e;kk-Z#ymcBDi-m;lp2gf9E9#FQqk8)0DQpJq zkhbHHBnk28Fzu)98Cz(hp6ELXlgUJ0j+{Ycpb@o)4^bWHIsrM{4q4{k)kH2r79Bdz zhO97~%~h-ob^P3INQaxDsw&x8zJc^(r_LL{3m%V$3||w_d(}Zj?*As8lLCyNP#rHQo-N z&sU|tuNTP$H?m7El3(dTIrSNPzsuMw6;Mj7L4AH1AA_x!8tu`E_&f1qu9?>5LIR9X W!vc)RM+6vAc;bc;`~L_3TmJz{0oTa@ literal 0 HcmV?d00001 diff --git a/upload/files/.htaccess b/upload/files/.htaccess new file mode 100644 index 00000000..f7d805db --- /dev/null +++ b/upload/files/.htaccess @@ -0,0 +1,5 @@ +#Error Pages +ErrorDocument 403 /error_pages/403.php + +Options -ExecCGI +AddHandler cgi-script .php .pl .py .jsp .asp .htm .shtml .sh .cgi .exe .html .ruby .pearl \ No newline at end of file diff --git a/upload/files/thumbs/processing.jpg b/upload/files/thumbs/processing.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d9ecc7f1e5c7c86d73735f7023e5307e6593e95c GIT binary patch literal 4063 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 W!DbfcfrGvZ>)I{5$)8e(qyGVbR_c8K literal 0 HcmV?d00001 diff --git a/upload/forgot.php b/upload/forgot.php new file mode 100644 index 00000000..ae4f5cfb --- /dev/null +++ b/upload/forgot.php @@ -0,0 +1,42 @@ +ResetPassword(1); + } + + //Reseting + if($action =='reset_pass'){ + $msg = $userquery->ResetPassword(2); + } + +//Recover Username + + if(isset($_POST['recover'])){ + $msg = $userquery->RecoverUsername(); + } + + +if($row['captcha_type']==2){ +Assign('captcha',BASEURL.'/includes/classes/captcha/img.php'); +}elseif($row['captcha_type']==1){ +Assign('captcha',BASEURL.'/includes/classes/captcha_simple.img.php'); +} + +Assign('subtitle',$LANG['title_forgot']); + +Assign('msg',$msg); +Template('header.html'); +Template('message.html'); +Template('forgot.html'); +Template('footer.html'); +?> \ No newline at end of file diff --git a/upload/group_check.php b/upload/group_check.php new file mode 100644 index 00000000..fd0738b5 --- /dev/null +++ b/upload/group_check.php @@ -0,0 +1,34 @@ +is_userinvite($_SESSION['username'],$details['username'],$details['group_id']) && !$groups->is_Joined($_SESSION['username'],$group)){ + $msg = $LANG['grp_prvt_err1']; + $show_join = 'No'; + $show_group = 'No'; + } + } + + if($details['active'] == no){ + $msg = $LANG['grp_inact_error']; + $show_group = 'No'; + } + + if($details['video_type'] == 2 && $manage_vids==TRUE && @$_SESSION['username'] != $details['username']){ + $msg = $LANG['grp_owner_err']; + $show_group = 'No'; + } + if(@$_SESSION['username'] == $details['username']){ + Assign('owner','yes'); + } + //Chceking Logged in user is group user or not + if(!$groups->is_joined(@$_SESSION['username'],$group)){ + Assign('join','yes'); + }else{ + Assign('join','no'); + } + if(@$MustJoin != 'No'){ + if(!$groups->is_Joined($_SESSION['username'],$group) && $_SESSION['username'] != $details['username']){ + $msg = $LANG['grp_join_error1']; + $show_group = 'No'; + } + } +?> \ No newline at end of file diff --git a/upload/group_inc.php b/upload/group_inc.php new file mode 100644 index 00000000..798d87f4 --- /dev/null +++ b/upload/group_inc.php @@ -0,0 +1,14 @@ +ExistsURL($url) || $url == 'Array'){ + $msg = $LANG['grp_exist_error']; + $show_group = 'No'; + Assign('subtitle',@$details['group_name']); + Assign('msg',$msg); + Assign('show_group',$show_group); + Template('header.html'); + Template('message.html'); + //Template('group_header.html'); + Template('add_group_videos.html'); + Template('footer.html'); + exit(); +} \ No newline at end of file diff --git a/upload/groups.php b/upload/groups.php new file mode 100644 index 00000000..bc8ef38f --- /dev/null +++ b/upload/groups.php @@ -0,0 +1,98 @@ +page_redir(); +subtitle('groups'); + +//Getting List Of Categories + $sql = "SELECT * FROM category ORDER BY category_name"; + $data = $db->Execute($sql); + $total_data = $data->recordcount() + 0; + $category = $data->getrows(); + Assign('category',$category); + + +//Listing Videos + $limit = GLISTPP; + Assign('limit',$limit); + @$page = clean($_GET['page']); + if(empty($page) || $page == 0 || !is_numeric($page)){ + $page = 1; + } + $from = $page-1; + $from = $from*$limit; + $query_limit = "limit $from,$limit"; + + //Getting Category + @$cat = mysql_clean($_GET['ct']); + if(empty($cat) || !is_numeric($cat)){ + $cat_query = " group_category <>'' "; + }else{ + $cat_query = "group_category ='".$cat."' "; + } + + $cur_cat = $myquery->GetCategory($cat); + Assign('cur_cat',$cur_cat); + + //Getting Order + @$order = mysql_clean($_GET['order']); + if(empty($order)){ + $order = 'all'; + } + Assign('order',$order); + $orders = array( + 'all' => '', + 'mr' => 'ORDER BY date_added DESC', + 'mv' => 'ORDER BY total_videos DESC', + 'mt' => 'ORDER BY total_topics DESC', + 'mm' => 'ORDER BY total_members DESC', + 'fr' => "AND featured='yes'", + 'ra' => 'ORDER by RAND()' + ); + + $group_type = " AND (group_type ='0' OR group_type = '1' )"; + $orderby = $orders[$order]; + $sql = "SELECT * FROM groups WHERE $cat_query $group_type $orderby $query_limit"; + $sql_p = "SELECT * FROM groups WHERE $cat_query $group_type $orderby"; + $groups_data = $db->Execute($sql); + $total_groups = $groups_data->recordcount() + 0; + $groups = $groups_data->getrows(); + + Assign('groups',$groups); + Assign('ct','&ct='.$cat); + +//Pagination +$link = '&ct='.$cat.'&order='.$order; +Assign('link',$link); + + $query = mysql_query($sql_p); + Assign('grand_total',mysql_num_rows($query)); + $total_rows = mysql_num_rows($query); + $page_id=1; + $id = 1; + //$all_pages[0]['page'] = $page_id; + $records = $total_rows/$limit; + $pages = round($records+0.49,0); + + +$show_pages = ShowPagination($pages,$page,$link); +Assign('show_pages',$show_pages); + +Assign('pages',$pages); +Assign('cur_page',$page); +Assign('nextpage',$page+1); +Assign('prepage',$page-1); +Assign('total_pages',$page_id); + + +Template('header.html'); +Template('message.html'); +Template('groups.html'); +Template('footer.html'); +?> \ No newline at end of file diff --git a/upload/help.php b/upload/help.php new file mode 100644 index 00000000..1dfd60d1 --- /dev/null +++ b/upload/help.php @@ -0,0 +1,16 @@ +page_redir(); +subtitle('termofuse'); +Template('header.html'); +Template('message.html'); +Template('help.html'); +Template('footer.html'); +?> \ No newline at end of file diff --git a/upload/images/avatars/no_avatar-small.jpg b/upload/images/avatars/no_avatar-small.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e40158db23aeb6499b4cab1d6bbf8f0077ce2dc5 GIT binary patch literal 852 zcmex=R#4GXS5VScl9tgh z)6mv8G&V7oSF^COFtX7zGB#x7;N;}t;t}WN6*p9rQ8XkO{6E6Dh=GBTl@SaWpn#Ey znFZ)F4o)s^Mh0ex9FT;_B1sA`FflSSGqEtUva+xMjj097F|Y`-3Mm>ovIz$!vMUve z7&T5@$f4}C@t|nX#SbdRNkvVZTw>x9l2WQ_>Kd9_CZ=ZQ7M51dF0O9w9-dyoA)#U6 z5s^{JDXD4c8JStdC8cHM6_r)ZEv;?s9i3g1CQq3GGAU*RJ2VdF$b$$4{OPfBE|D`;VW$1c6Rw zVqsxsVFx*xk*OSrnFU!`6%E;h90S=C3x$=88aYIqCNA7~kW<+>=!0ld(M2vX6_bam zA3?4LJDNB*H<9INxSQcl{(pc$kb^;vL5`Ub=z2j$W{$%^^O+7ZbO@a?{=WOkvj(AO_s_e=9_8BhRC(h9u0GXm38^<8 OeBgQ_f2zU$|4jg)tSvkM literal 0 HcmV?d00001 diff --git a/upload/images/avatars/no_avatar.jpg b/upload/images/avatars/no_avatar.jpg new file mode 100644 index 0000000000000000000000000000000000000000..02e363a2576fe4ed5cb89eabb783e52b33b4e967 GIT binary patch literal 2065 zcmbW0c~q0v62RxnPFNEoiy#md0hMS10#zZwCn{i(tyGp4At2GJDTYPyK?1Zch-`gC zOREMEP~4tR6afWPK!sK#`zEMSHVd*NOY${HUr+yhuQTV~bMBovGryU+7i~jdftK4A z*DZi3b(c~BRe;fU7w65!zTsTn0scOI#GY`0vFiaY!`P3>Sjz;o6TSlyoO*bDb^?os8W)pfaNrkMfqpP>f ze1(Oj)k@oScJ>aRt^dbnmn~bjxw`rIe&P4!PX7RISorP;-k!aJsOXs3Lx`cLLRkO&`qwX)C8{~4ppAksff=-q4FCA4Jx^JP&m&Me&|5q zdobeOF&Y~p%IAVdB!t`dFHDw*gq`b9AVb9I-RyVWnsZZ?uQ_D;E%w-lMK9t>cWy(+ z;=StB2I0(9vO<32qbDZ*uUYinBT-;Tg+2KTv1-av=+Ty1wIHZ{@SdX|V=C9^QIuLJ zk}NSbKupYmt6}29_fBqRxi-BT$!j{-gd{XN`;7P0h4Y8$EAwV^;I{lkq40T;B4VD0 zWcB;4K9gpn8WYCNlv`r$2J6N>@NF|Anli7t^hmi2tk?5%!G8{HT?sBE1**zXNH4AI z;rDU$?bxGzd=!FyK*5=YglSk}u635P9+7^@T3+P%EAR)VymnTZ9uGU`pYG>WAX+U& zIC#*NXb60Ymqjz3u_A#v$#OBJ`N0SouSvWfQ+PcyDsUz_k_$>+ER^G7gi{C5}<0ex4 zY1QJ1Co-b|kV?oo#YViw-t>x>^}lU3o$(~BOP^EU^0=TY9bX zeTuN(L}blP^~9}T8*9@WnN6y$USyf0@)`vth_XT2}_^uez`mu zCZ=e}4Jt|I`*jMFvou}ttZGeq%tQ^ibuDCMHz=#SermoS%l9zq z_v@LgVNXyv+Ba*!<)VG|mCyBLzoeTgFv8ghq(nI&@1}bD(-;H3EfU&IOImx}sjx+4 zE+Ll{S8Vy|TlqsRr@};KDAq$q@nD6B4B0gxXgxnVZ7+{ncoPA!^M^Wxt+Y==3&f^C zVRTtbul_~vZl8ZvMXx->?&}cQTNk9g!HKoI(pZ{qkR_sv5wp?yyGdv7^DukC607fD zszc3B^*0Z)ef)21hEr(`xG&qsVRF6&v>p7bnKR5Cb4B@Qlpc zUsMBr()Rpj^K8n!JZ*a!{5&=Jfur99EvNL7SyrZ{G#G@-SFYUo@!(CX2xbNh^02Es z%2O@G30uD=XC|@9P;tF5S33kIQ3}e_F;C4&-uoD2*x3z$P}ptNJUru}hJyk690lis?w=~L!!6XJzu!B;$ZBuMp109`&@B&2Y3OJYf_K3Z|* zMlB*U=?bwUgPOHIi?A)!rUruNzIr}C@2>nVIpEYPK!Hs~p=Y;9^L7^s&#Nn^+a=hc nSoZkn8u=6t{;soE^tT>rV;M(uY?1nI%ekN~%?f2h*l7FjkC1&T literal 0 HcmV?d00001 diff --git a/upload/images/category_thumbs/no_thumb.jpg b/upload/images/category_thumbs/no_thumb.jpg new file mode 100644 index 0000000000000000000000000000000000000000..509366f17a3fc417ff36c3ba49b40abec33eecd5 GIT binary patch literal 4293 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 literal 0 HcmV?d00001 diff --git a/upload/images/icons/XPButton.png b/upload/images/icons/XPButton.png new file mode 100644 index 0000000000000000000000000000000000000000..df7aa6eab8cb94069d2bc5d640eba51bc9ce5fc4 GIT binary patch literal 1855 zcmV-F2f+A=P)?00007bV*G`2iOS* z76>od-3GY;000SaNLh0L01FZT01FZU(%pXi00004XF*Lt006O%3;baP000KgNkl4+2tEi3zEmZMMSKzj zse<%DBKYJ5gah8i}0n|dlOd0|w-qe(W#l`t$ z?~{|JD&r|gD+XETf+z4|zrVOYm;2(iPi>~L;&u_ElzOsP8|MX1eWG74CDMAu&44PA zZfR+Ug@qY@)PZ%Y_Hv9l&Wq0*Y4D%4KB)QmJ7t5E>ll|xb(Go6adtkdc4+fD(~2WY zk1!7^iYQ&v<;O~(4tDC$#yKvPT3bW^c4IRwWPYZ%m0z|w#kIDsgSolsGCSJb_HQ>f zi-k;gRwg_MT4K|E~ab4#2jCyg@7xrwW=^`RDaQ(k0r*&nHn zbmsCXEG|S#a^epg?12gik6)kRvJrXn(_xyqc?XW{-3$X;I>H{K|D-`I+Y>kE;rPfU z*w))6@_6X$AL+NhosYdR`0{go@cBDO2)_*#%1Qi@F9_X$tD)_6^YGe%$Dw_VT4T4- z#gdwYFMj$PX7jB;wjchOo;lVBt&4vFsc)~n_lSb#W?-)A2^c(jL8zhaiD|xr(QWTS zB==cAF!~|1CI2(jP$-K1%h1Z=2FjnIiJIdzaYt6n#hNtk)r!PZ%(S{Zq{CE0Wu8Jg zQI~Xg#j>*1P~<6z{ghXTFCs#5rH2IO9p8u+;csk6|07_Y$iNR(Me}n0{Ao2 zQB^}BkJ*fI&8t`q<<~TED%8U&#N_UkF zh8nt2JqxdPd=~Z)1ILN!x8YXf-~%-@_9#D6E-9imL`qD0VYWsRfBsPE5o5-<%R^=+k`Lrv*rNzB)6$c4l>BaS|| z5UV!kQOD}^h;Q+k^hDZ4@X{Uuc6s|3$8?X)^q zT6yjIkmIcS*XxyhUO>*AI!PbfwY#cs%#5IC-4C2U_s{CQIa!^gQAR;k!4E_|wUH;6 tgHbm^8RhQXg|NpIIAP?8d{?C~_&=p96%WXS@Jj#y002ovPDHLkV1n~|kk$YI literal 0 HcmV?d00001 diff --git a/upload/images/icons/cb_powered.gif b/upload/images/icons/cb_powered.gif new file mode 100644 index 0000000000000000000000000000000000000000..7af31cadaa19b6d7c7dc191c535b7984c2b3ad9e GIT binary patch literal 2359 zcmeH``#;lr9LGO1Z8&*waL}TY%b3j(r$RZW#>ApiIO>#AvrfxBv?D1+xvW`bl)|uz z#>&o8iHgmg<1%qbBXe0Ub2;vY@;!9Ue^Jk0UXS;0@7MeBemd`Uvfbem0=@?e;6ETh zga8!+s|g??6(X{rg9o`33MDKoj0zyC0J?mcdzs5+Fc?XCh-6ietOrZ}9+9#h+%{Cb zL)f0?yfZB=jim-yM2O|>!JwWbb58^0kUbxs z^5S5W^8!wA*Z7+k;9Xc)_#6d_z3?w}fPe}K)_?>ONB}`XZ6LhQs-R!2O1)Y2@Ln}N zswU`QO-@$rgUotbWTQT4Y;0`ua%#GIwka;6nUf_l1fnfSQACg^Dn#_`$s06y!;EVs z9caB6+WM-f%?Pv=7q**#4lH;}i+Ee~=iAEC&d$zvl%rydf*7wa4h`xuRp<&1?h=%A zRSCOsuau% zsSiGXFl47Obi#8eFLUT6Z%9-NmToz#~(P^HbT(so~yf z`i<%Q)ag~^b2H}xW|CrN?%$eeu9^{5%wD-L%egZPLG#z*=I3V@8p`Cc7v#{#rNzaM z5CpMu*Dkxd_wwZG^#3D#d10`q2m?S7n6Fh|b0XpM4Za%j)rc=ohR=t3dD0i7rt<->6K~-Rj?cSbd$E18e8?mnoIV+7!&MEY z2?>8?*q-4MeP~SMU&xzccEX*j(pkim__wEAHQmn?v!}I)``4@8AlOht{Mxy$d2z&=oSMBRd#=p;UgHy?3kPv7E3|V$|9B}<)7Y~( zy7JXB(!zvLChfJ4T96A|Q^zW*b3ds`hmOM)4Wse!PX+kwDA=ah@~i4jn7&x8L%w}+ zx)hoZ+~K2%;y0?BNj+#BOUJ-ocOR#pZeBFppJ-Ww8DRXV;X4px*vzM2SIMKn=-Ut@ zWZbAH}gxYNv%}Y~1~bT-$Q#^>m4)(HK@W zw$&}Du{7Kb+d9ni+R8y)P?0^A7wQ%;Z!T?!Za}dbEbo^hNbn+(>(X?a+W_keOSYYtbpBV}~vsBnU!_?2tr-P=|^T zED%wc9ezHgW@NMb!^uT_|SvCpFLJylbx zY%bpaTGI8IYXMN$9w<3j9VkA~NYOKEQXsj?6a9_hcwfU$acAhJhB)zb_w@MVUEy@S zX&I>K-R!bhu3?(6bHWIg$HEl7{9g>>&l_qdd+UYb(1~BCo9LptNq&8>!yoJ3Ui(i5 zRJ|XnYBklL!{@$-7=3mJ>P@1c=7Oc79e-V7yf+%lD2!I;Y&nXBZ>=B!5?CB>LvEx6 znI%n)qqi$#X#wKB(U7XP2P=+4{b@j#r%9-K(8UqtSDk>0UKzf*HM9yqMZ1D!$2MdZ zR=`U>0zhOH1XqN?nY@AQqB7)Fp4{v&dKXvb43hZKvnN8;Po;+jY*}~*Z|W9Q0W%{D z^T}Cc<|r(Su=1K=P5>Z4 zg`et&Va}tdzBS-G-ZcO)zCWpJvGQwrHZ`@wpM420ac@bI5~KkTFfGEM3sPWO8co4^fI6lPnA)Y{ef%@{+SnoUk0+dW+*{8WvF8}}l07*qoM6N<$g7cXs A&j0`b literal 0 HcmV?d00001 diff --git a/upload/images/icons/ico_lightsoff.gif b/upload/images/icons/ico_lightsoff.gif new file mode 100644 index 0000000000000000000000000000000000000000..5caf4b3c12091aaddd430f901ed399fbf1e37035 GIT binary patch literal 1510 zcmeH`dsos20ET}e9<7rsvkcADRxML2%i3%eqtpcZW1g*@Wv83Vty!+kT$eLDD{0kg zU0mhN)WU8mk(ZDRG49CicjF>Akx*0!H4um-6IS10fA0MN?|IJio;R1gHFJI8ULXN@ za}6+?%}q^B1qB5#4EOiFw>+>2zwf zTCdj!gF&@c>z|r}A@StfDOP(i3`wQ~)6F~qOC}SjRCIxmkD?7ss&T}o8ya@Ke$8yn zG234{oGuvTTJ2V*w5RFu0Z6F~1Orb&$ouBaE4QcPaZcZ`6$1H6Xm_U+(F|JZI&K<< zhcsrR%4B>uJ^dU-w0b>*wo!;6d`<6kAfS+t1?mrE6Fy%pgUxKo=b%c&{G#7(DVOp=5VcsvYBh+WTm(gpdi~&l&;J%hK^T^?+X(Egbs~-CJ%vQ47r?O7 zZ8PfjGDISs<%QGhz0<{JiG{58?-`OFE|!x9LtderXp*g2dHqc1DE zAaK|*AOsb5*8~Se5x7So>*Om{QUvBI|4c-5$}VYJgRlYjgfDcZhO`?ApA2r zbq|Pl^01YQt~R(kk6d5+cg7(z$YR(KYF5_o@v&DDS5^ggx{|t>qq?@-@SDVP%Ho_0 zE!bugMO15KhD87?cb#wzN{Sb(x^i+$nFX#%{24x(>8*%*lDjWNET6G%!~K#VFJB~z z9XFo6ca=&gFZaC)6Mebr6yc=T*~jhV5~he@07joXCog`DG_mYHa4vEo7Ek>JmjWz0 z9sPM`;aU95*#l?dzS0+-O*o9VoWk8IjKHn8CxyoCOy`FtEubV9p3msnvG9D1e8>Jj zGh%EFSEF!Per5K@ls_Ua7p)dW5Q$rct_wEJ*nA^vYr(E6%s%pxs{9`e!~g6#(){2? zHqOhd`H_$x9$RV|z{DhyDnGd;fC_9i$48a}x69q+#yiDk|LNPueCusBp=7H4?i{RO zb0h_?%t^SkW@kMXT=CoThnVD)x`*|YxPuRBkK{R;s`AojW9UyW^5Rmng;9dYJ)p($ z_}K_;w58kUIMniJu#1FWJJ+4FAo(3_>D=uulA7h`Q*s9R+g90kUJwb{qFk}=a;l~hpwQy z1hYOHa|vhXrcH?EeoJ=|LyPDWJ@LoKCL~Gc)7;V}2QHP$k{ju6`QneZ^AzclG!M8| jSK@&(ZFG-frE|=K5X0-s0L-Q$uadN^zj8@P2(aN_PkpxM literal 0 HcmV?d00001 diff --git a/upload/images/icons/info.png b/upload/images/icons/info.png new file mode 100644 index 0000000000000000000000000000000000000000..12cd1aef900803abba99b26920337ec01ad5c267 GIT binary patch literal 778 zcmV+l1NHogP)BVme|mWaqy4$_pJm?y9KM{-*hp?1+Ey3e-CEDooTa!B;e(Q>TSF?bj>5At13y1p zriN3w3x~5SfZj{@J4M{kp{?=M_Lh2bV+5LH)Q)5W!-ePA$RgE1@5f1cyHki0Y}JyVEYZF(LD$xXlt$7A5CgE@ zpV-&l%vf;=5kZ2-2gi@Y6J&=cuwt>!vJ^#(&n|LcZyUzi6Duj$$hJ1s*HD-#;k-w@ zpdrwAuoDG_N2bvb07G$Zk*?Hc)JLtW4yqOnic_$zO7NZ#l>Fm){;fE?b$IbOaX2fe z0la4g0Dfw2xk7Wi7NapVD8YMPCZu?A1QCK*67dgsvRKBLFtrM>?$%&_lD1882mzdO zWPdw5KWw6IT`m1b_8=lS5jt8D3=RDa=&jWzR-)S@56WMslZ~mKu1)-wpXB>rNBQ>N zU#K`#1B&v|_AQK;7I~B}OdGiUT9LX>f0xm6<;LeP!=vFjPsUQF*wCJ*dO)4YBypgdiuF!=i@6Zyi7F|q#K zz?tlSZULa@t1D?$e;f@b36&N!V2mjOHw|*FaCQnMumK}v9B>c=i3%It0xC9+lSZg2 z0vl0KLp7o(V#6Lgn4zJ2>PF){Jt#f!1AvCp4B-??+=%a<=7K74ro{Q0|g@201xKYjW%Gc)t`>sOP> z^!oMdj~_qw^z?lH{(XFW{MD;hd_I3*VBpQ0Hz!V<$j{Gz^5n_Qn>Rf?JWicDH8nML z`}Xbk@86$0ckaQ12M-@UEG{mtt*uQ(?JX zeE9zT`+B{8baeFbActF5iAfq{Wnu3SkFIg$ zE?ihrQnGH{x`2Ry)YMd0SJ#-Bn7eoH`uO-zD3l#LcDTE{XJ%$@+_=%k#zrU*I3H(2Y`U4joB90aCL?P_?EI4SnMg5FG0)QD{{=ECMCIGq~ zXv4S)ns~Y+JoM@Vx3-V=Hr~_6%a2Cj~U3pe!ldi46ue^8~#U%uzq-~w;KkB z{f`_3K)}ZG0Cc5=+*i~suCqz`s)LNhIX>$W%$#`l=XV`7j$91*9El6?KS9Fweq+DC}=NuDHDn8RJH{fKy^l{U4}O;nEJn1Ll2^6yT;9InFN zkr-$v7C}H2B;wKOj9Y*TpurtkbZUpH$d!OEmMA42YCF%CbjA?>xL*EuwCX{g>M!@x zkz6|?t7o^pzd^@86&!`q*kXHG)i8d}{2iujDLB8a+&P=X?#!Gh24_ivbmD+o!2x`D zs7c1)SIo1IgC>bWs^h=-9yB~M%-p99V%9Nxr#wp`TSocpeEZQ3onuf|bo1ya$f0d% znbMmnToue3#*_-F_&i(?fwZ)lqK`zt>WZu7)eAcQmX@eDIJjF2-|HdcRC@t;&W`>H zu+9K!LShoG3-}5cwAVNOJp7fQkcc9&O>!(6(W3n$vX?HgyRsc5C);^xe!gVyrIrRh#1#N;xyQu55iy;6BIXgk|1a1 z%gmIAN(fm#<4yGBDq!|me-6~5u&tKfq*s>60qyF$jWP+EV(pV!Ts2MmPkxulDra@Z zIJZ#^{)4$p2?E8kL6u1$BLpg}ow&lW+d~Be4GzW1s5Wy|ASy^m18?x~?r0L5NEqpn zqo_2Ucq_6{jl#Q{WN~y1&dLgyB$D_73?R%^#!3VoHFM{c74X!ESXbAGkOOwrG*X>g zV5}?I0I$-8uFD#*V@ZT(SN?mNRkw7`1FdhAi8($;+E77|n&LP-DdN}Z{_I)REdW%5 za0(MLrYqqnDg|BKk|aQCgaCqLmhk0hVmk=}UMcpj0Z42*MWIqM{@P_RH`%CRXEvB* zLf-G?{%M3sVyhXawTVVs{spQL8`{A;Xc2sd?Ldg3~mrAvTO$W1oNmN=l^)b lh7Bq(VS$OPgr!Xd)q;)bRZ!>Z2FN+j@Th;V&E7&A_+Mq3MF{`^ literal 0 HcmV?d00001 diff --git a/upload/inactive.php b/upload/inactive.php new file mode 100644 index 00000000..74015184 --- /dev/null +++ b/upload/inactive.php @@ -0,0 +1,15 @@ + \ No newline at end of file diff --git a/upload/inbox.php b/upload/inbox.php new file mode 100644 index 00000000..f685588e --- /dev/null +++ b/upload/inbox.php @@ -0,0 +1,82 @@ +logincheck(); +$pages->page_redir(); + +$user = $_SESSION['username']; + +//Delete Message +if(isset($_GET['delete_msg'])){ + $msgid = $_GET['delete_msg']; + if(empty($msgid)){ + $msg = $LANG['usr_no_msg_del_err']; + }else{ + $msg = $myquery->DeleteMessage($msgid,$user,'inbox'); + } + } + + //Deleting Multiple + $sql = "SELECT message_id FROM messages WHERE inbox_user = '".$user."' ORDER BY date_added DESC"; + $rs = $db->Execute($sql); + $totalmsg = $rs->recordcount() + 0; + if(isset($_POST['delete_selected_message'])){ + for($id=0;$id<=$totalmsg;$id++){ + $msgid = $_POST['check_msg'][$id]; + if(!empty($msgid)) + $msg = $myquery->DeleteMessage($msgid,$user,'inbox'); + } + $msg = $LANG['usr_sel_msg_del_msg']; + } + +//Getting User Messages +$sql = "SELECT * FROM messages WHERE inbox_user = '".$user."' ORDER BY date_added DESC"; +$rs = $db->Execute($sql); +$totalmsg = $rs->recordcount() + 0; +$msgs = $rs->getrows(); +Assign('msgs',$msgs); +Assign('totalmsg',$totalmsg); + +//Getting Message + @$msgid= mysql_clean($_GET['msgid']); + if(!empty($msgid)){ + $msgdata = $myquery->GetMsg($msgid,$_SESSION['username']); + if(empty($msgdata['subject'])){ + $msg = "Sorry Message Doesn't Exists"; + }else{ + mysql_query("UPDATE messages SET status='1' WHERE message_id='".$msgid."'"); + $msgdata = $myquery->GetMsg($msgid,$_SESSION['username']); + Assign('show_msg','yes'); + if(!empty($msgdata['attachment'])){ + $videos = $myquery->GetVideDetails($msgdata['attachment']); + if(!empty($videos['videokey'])){ + $videos['thumb1'] = GetName($videos['flv']).'-1.jpg'; + $videos['thumb1'] = GetName($videos['flv']).'-2.jpg'; + $videos['url'] = VideoLink($videos['videokey'],$videos['title']); + Assign('attachment',$videos); + }else{ + $msgdata['attachment'] = ''; + } + } + Assign('msgdata',$msgdata); + } + } + +Assign('subtitle',$user.$LANG['title_inbox']); +@Assign('msg',$msg); +if(@$_GET['show']!='inbox'){ +Template('header.html'); +Template('message.html'); +Template('inbox.html'); +Template('footer.html'); +}else{ +Template('inbox.html'); +} +?> \ No newline at end of file diff --git a/upload/includes/.htaccess b/upload/includes/.htaccess new file mode 100644 index 00000000..e69de29b diff --git a/upload/includes/active.php b/upload/includes/active.php new file mode 100644 index 00000000..2d0318f0 --- /dev/null +++ b/upload/includes/active.php @@ -0,0 +1,73 @@ + 0){ + $scriptName = $arrayScriptName[(sizeof($arrayScriptName)-1)]; + $homecurrent = ""; + $uploadcurrent = ""; + $watchcurrent = ""; + $acountactive = ""; + $friendcurrent = ""; + $channelscurrent = ""; + $communitycurrent = ""; + + $listCurrent = array( + "activation.php" => "signupactive", + "channels.php" => "channelactive", + "index.php" => "homeactive", + "myaccount.php" => "accountactive", + "signup.php" => "signupactive", + "signup_success.php" => "signupactive", + "upload.php" => "uploadactive", + "user_account.php" => "accountactive", + "user_videos.php" => "watchactive", + "user_fav_videos.php" => "watchactive", + "user_contacts.php" => "channelactive", + "videos.php" => "watchactive", + "view_channel.php" => "channelactive", + "watch_video.php" => "watchactive", + "inbox.php" => "accountactive", + "sent.php" => "accountactive", + "groups.php" => "groupactive", + "view_group.php" => "groupactive", + "view_group_videos.php" => "groupactive", + "view_group_members.php" => "groupactive", + "edit_group.php" => "groupactive", + "manage_group_videos.php" => "groupactive", + "manage_group_members.php" => "groupactive", + "invite_group.php" => "groupactive", + "join_group.php" => "groupactive", + "add_group_video.php" => "groupactive", + "view_topic.php" => "groupactive", + "manage_groups.php" => "groupactive", + "create_group.php" => "groupactive", + "view_channel.php" => "view_channel_active", + "login_success.php" => "login_success", + "logout_success.php" => "logout_success" + + ); + $resultCurrent = @$listCurrent[$scriptName] ; + /*if ($resultCurrent != ""){ + ${$resultCurrent} = " id='currentTab' "; + } + else{ + $homeactive = " id='currentTab' "; + } */ + if ($resultCurrent != ""){ + ${$resultCurrent} = "current"; + Assign('curActive',$resultCurrent); + } + else{ + $global = "current"; + } + + @Assign('accountactive',$accountactive); + @Assign('homeactive',$homeactive); + @Assign('signupactive',$signupactive); + @Assign('uploadactive',$uploadactive); + @Assign('watchactive',$watchactive); + @Assign('channelactive',$channelactive); + @Assign('groupactive',$groupactive); + @Assign('view_channel_active',$view_channel_active); +} +?> \ No newline at end of file diff --git a/upload/includes/admin_config.php b/upload/includes/admin_config.php new file mode 100644 index 00000000..fe0a1e8b --- /dev/null +++ b/upload/includes/admin_config.php @@ -0,0 +1,63 @@ + \ No newline at end of file diff --git a/upload/includes/adminfunctions.php b/upload/includes/adminfunctions.php new file mode 100644 index 00000000..bfb93369 --- /dev/null +++ b/upload/includes/adminfunctions.php @@ -0,0 +1,14 @@ + \ No newline at end of file diff --git a/upload/includes/adodb/adodb-active-record.inc.php b/upload/includes/adodb/adodb-active-record.inc.php new file mode 100644 index 00000000..92836be7 --- /dev/null +++ b/upload/includes/adodb/adodb-active-record.inc.php @@ -0,0 +1,626 @@ +_dbat +$_ADODB_ACTIVE_DBS = array(); +$ACTIVE_RECORD_SAFETY = true; + +class ADODB_Active_DB { + var $db; // ADOConnection + var $tables; // assoc array of ADODB_Active_Table objects, indexed by tablename +} + +class ADODB_Active_Table { + var $name; // table name + var $flds; // assoc array of adofieldobjs, indexed by fieldname + var $keys; // assoc array of primary keys, indexed by fieldname + var $_created; // only used when stored as a cached file +} + +// returns index into $_ADODB_ACTIVE_DBS +function ADODB_SetDatabaseAdapter(&$db) +{ + global $_ADODB_ACTIVE_DBS; + + foreach($_ADODB_ACTIVE_DBS as $k => $d) { + if (PHP_VERSION >= 5) { + if ($d->db === $db) return $k; + } else { + if ($d->db->_connectionID === $db->_connectionID && $db->database == $d->db->database) + return $k; + } + } + + $obj = new ADODB_Active_DB(); + $obj->db =& $db; + $obj->tables = array(); + + $_ADODB_ACTIVE_DBS[] = $obj; + + return sizeof($_ADODB_ACTIVE_DBS)-1; +} + + +class ADODB_Active_Record { + var $_dbat; // associative index pointing to ADODB_Active_DB eg. $ADODB_Active_DBS[_dbat] + var $_table; // tablename, if set in class definition then use it as table name + var $_tableat; // associative index pointing to ADODB_Active_Table, eg $ADODB_Active_DBS[_dbat]->tables[$this->_tableat] + var $_where; // where clause set in Load() + var $_saved = false; // indicates whether data is already inserted. + var $_lasterr = false; // last error message + var $_original = false; // the original values loaded or inserted, refreshed on update + + // should be static + function SetDatabaseAdapter(&$db) + { + return ADODB_SetDatabaseAdapter($db); + } + + // php4 constructor + function ADODB_Active_Record($table = false, $pkeyarr=false, $db=false) + { + ADODB_Active_Record::__construct($table,$pkeyarr,$db); + } + + // php5 constructor + function __construct($table = false, $pkeyarr=false, $db=false) + { + global $ADODB_ASSOC_CASE,$_ADODB_ACTIVE_DBS; + + if ($db == false && is_object($pkeyarr)) { + $db = $pkeyarr; + $pkeyarr = false; + } + + if (!$table) { + if (!empty($this->_table)) $table = $this->_table; + else $table = $this->_pluralize(get_class($this)); + } + if ($db) { + $this->_dbat = ADODB_Active_Record::SetDatabaseAdapter($db); + } else + $this->_dbat = sizeof($_ADODB_ACTIVE_DBS)-1; + + + if ($this->_dbat < 0) $this->Error("No database connection set; use ADOdb_Active_Record::SetDatabaseAdapter(\$db)",'ADODB_Active_Record::__constructor'); + + $this->_table = $table; + $this->_tableat = $table; # reserved for setting the assoc value to a non-table name, eg. the sql string in future + $this->UpdateActiveTable($pkeyarr); + } + + function __wakeup() + { + $class = get_class($this); + new $class; + } + + function _pluralize($table) + { + $ut = strtoupper($table); + $len = strlen($table); + $lastc = $ut[$len-1]; + $lastc2 = substr($ut,$len-2); + switch ($lastc) { + case 'S': + return $table.'es'; + case 'Y': + return substr($table,0,$len-1).'ies'; + case 'X': + return $table.'es'; + case 'H': + if ($lastc2 == 'CH' || $lastc2 == 'SH') + return $table.'es'; + default: + return $table.'s'; + } + } + + ////////////////////////////////// + + // update metadata + function UpdateActiveTable($pkeys=false,$forceUpdate=false) + { + global $ADODB_ASSOC_CASE,$_ADODB_ACTIVE_DBS , $ADODB_CACHE_DIR, $ADODB_ACTIVE_CACHESECS; + + $activedb =& $_ADODB_ACTIVE_DBS[$this->_dbat]; + + $table = $this->_table; + $tables = $activedb->tables; + $tableat = $this->_tableat; + if (!$forceUpdate && !empty($tables[$tableat])) { + $tobj =& $tables[$tableat]; + foreach($tobj->flds as $name => $fld) + $this->$name = null; + return; + } + + $db =& $activedb->db; + $fname = $ADODB_CACHE_DIR . '/adodb_' . $db->databaseType . '_active_'. $table . '.cache'; + if (!$forceUpdate && $ADODB_ACTIVE_CACHESECS && $ADODB_CACHE_DIR && file_exists($fname)) { + $fp = fopen($fname,'r'); + @flock($fp, LOCK_SH); + $acttab = unserialize(fread($fp,100000)); + fclose($fp); + if ($acttab->_created + $ADODB_ACTIVE_CACHESECS - (abs(rand()) % 16) > time()) { + // abs(rand()) randomizes deletion, reducing contention to delete/refresh file + // ideally, you should cache at least 32 secs + $activedb->tables[$table] = $acttab; + + //if ($db->debug) ADOConnection::outp("Reading cached active record file: $fname"); + return; + } else if ($db->debug) { + ADOConnection::outp("Refreshing cached active record file: $fname"); + } + } + $activetab = new ADODB_Active_Table(); + $activetab->name = $table; + + + $cols = $db->MetaColumns($table); + if (!$cols) { + $this->Error("Invalid table name: $table",'UpdateActiveTable'); + return false; + } + $fld = reset($cols); + if (!$pkeys) { + if (isset($fld->primary_key)) { + $pkeys = array(); + foreach($cols as $name => $fld) { + if (!empty($fld->primary_key)) $pkeys[] = $name; + } + } else + $pkeys = $this->GetPrimaryKeys($db, $table); + } + if (empty($pkeys)) { + $this->Error("No primary key found for table $table",'UpdateActiveTable'); + return false; + } + + $attr = array(); + $keys = array(); + + switch($ADODB_ASSOC_CASE) { + case 0: + foreach($cols as $name => $fldobj) { + $name = strtolower($name); + $this->$name = null; + $attr[$name] = $fldobj; + } + foreach($pkeys as $k => $name) { + $keys[strtolower($name)] = strtolower($name); + } + break; + + case 1: + foreach($cols as $name => $fldobj) { + $name = strtoupper($name); + $this->$name = null; + $attr[$name] = $fldobj; + } + + foreach($pkeys as $k => $name) { + $keys[strtoupper($name)] = strtoupper($name); + } + break; + default: + foreach($cols as $name => $fldobj) { + $name = ($fldobj->name); + $this->$name = null; + $attr[$name] = $fldobj; + } + foreach($pkeys as $k => $name) { + $keys[$name] = $cols[$name]->name; + } + break; + } + + $activetab->keys = $keys; + $activetab->flds = $attr; + + if ($ADODB_ACTIVE_CACHESECS && $ADODB_CACHE_DIR) { + $activetab->_created = time(); + $s = serialize($activetab); + if (!function_exists('adodb_write_file')) include(ADODB_DIR.'/adodb-csvlib.inc.php'); + adodb_write_file($fname,$s); + } + $activedb->tables[$table] = $activetab; + } + + function GetPrimaryKeys(&$db, $table) + { + return $db->MetaPrimaryKeys($table); + } + + // error handler for both PHP4+5. + function Error($err,$fn) + { + global $_ADODB_ACTIVE_DBS; + + $fn = get_class($this).'::'.$fn; + $this->_lasterr = $fn.': '.$err; + + if ($this->_dbat < 0) $db = false; + else { + $activedb = $_ADODB_ACTIVE_DBS[$this->_dbat]; + $db =& $activedb->db; + } + + if (function_exists('adodb_throw')) { + if (!$db) adodb_throw('ADOdb_Active_Record', $fn, -1, $err, 0, 0, false); + else adodb_throw($db->databaseType, $fn, -1, $err, 0, 0, $db); + } else + if (!$db || $db->debug) ADOConnection::outp($this->_lasterr); + + } + + // return last error message + function ErrorMsg() + { + if (!function_exists('adodb_throw')) { + if ($this->_dbat < 0) $db = false; + else $db = $this->DB(); + + // last error could be database error too + if ($db && $db->ErrorMsg()) return $db->ErrorMsg(); + } + return $this->_lasterr; + } + + function ErrorNo() + { + if ($this->_dbat < 0) return -9999; // no database connection... + $db = $this->DB(); + + return (int) $db->ErrorNo(); + } + + + // retrieve ADOConnection from _ADODB_Active_DBs + function &DB() + { + global $_ADODB_ACTIVE_DBS; + + if ($this->_dbat < 0) { + $false = false; + $this->Error("No database connection set: use ADOdb_Active_Record::SetDatabaseAdaptor(\$db)", "DB"); + return $false; + } + $activedb = $_ADODB_ACTIVE_DBS[$this->_dbat]; + $db =& $activedb->db; + return $db; + } + + // retrieve ADODB_Active_Table + function &TableInfo() + { + global $_ADODB_ACTIVE_DBS; + + $activedb = $_ADODB_ACTIVE_DBS[$this->_dbat]; + $table =& $activedb->tables[$this->_tableat]; + return $table; + } + + // set a numeric array (using natural table field ordering) as object properties + function Set(&$row) + { + global $ACTIVE_RECORD_SAFETY; + + $db =& $this->DB(); + + if (!$row) { + $this->_saved = false; + return false; + } + + $this->_saved = true; + + $table =& $this->TableInfo(); + if ($ACTIVE_RECORD_SAFETY && sizeof($table->flds) != sizeof($row)) { + $this->Error("Table structure of $this->_table has changed","Load"); + return false; + } + + $keys = array_keys($row); + $cnt = 0; + foreach($table->flds as $name=>$fld) { + $this->$name = $row[$keys[$cnt]]; + $cnt += 1; + } + $this->_original = $row; + return true; + } + + // get last inserted id for INSERT + function LastInsertID(&$db,$fieldname) + { + if ($db->hasInsertID) + $val = $db->Insert_ID($this->_table,$fieldname); + else + $val = false; + + if (is_null($val) || $val === false) { + // this might not work reliably in multi-user environment + return $db->GetOne("select max(".$fieldname.") from ".$this->_table); + } + return $val; + } + + // quote data in where clause + function doquote(&$db, $val,$t) + { + switch($t) { + case 'D': + case 'T': + if (empty($val)) return 'null'; + + case 'C': + case 'X': + if (is_null($val)) return 'null'; + + if (strncmp($val,"'",1) != 0 && substr($val,strlen($val)-1,1) != "'") { + return $db->qstr($val); + break; + } + default: + return $val; + break; + } + } + + // generate where clause for an UPDATE/SELECT + function GenWhere(&$db, &$table) + { + $keys = $table->keys; + $parr = array(); + + foreach($keys as $k) { + $f = $table->flds[$k]; + if ($f) { + $parr[] = $k.' = '.$this->doquote($db,$this->$k,$db->MetaType($f->type)); + } + } + return implode(' and ', $parr); + } + + + //------------------------------------------------------------ Public functions below + + function Load($where,$bindarr=false) + { + $db =& $this->DB(); if (!$db) return false; + $this->_where = $where; + + $save = $db->SetFetchMode(ADODB_FETCH_NUM); + $row = $db->GetRow("select * from ".$this->_table.' WHERE '.$where,$bindarr); + $db->SetFetchMode($save); + + return $this->Set($row); + } + + // false on error + function Save() + { + if ($this->_saved) $ok = $this->Update(); + else $ok = $this->Insert(); + + return $ok; + } + + // false on error + function Insert() + { + $db =& $this->DB(); if (!$db) return false; + $cnt = 0; + $table =& $this->TableInfo(); + + $valarr = array(); + $names = array(); + $valstr = array(); + + foreach($table->flds as $name=>$fld) { + $val = $this->$name; + if(!is_null($val) || !array_key_exists($name, $table->keys)) { + $valarr[] = $val; + $names[] = $name; + $valstr[] = $db->Param($cnt); + $cnt += 1; + } + } + + if (empty($names)){ + foreach($table->flds as $name=>$fld) { + $valarr[] = null; + $names[] = $name; + $valstr[] = $db->Param($cnt); + $cnt += 1; + } + } + $sql = 'INSERT INTO '.$this->_table."(".implode(',',$names).') VALUES ('.implode(',',$valstr).')'; + $ok = $db->Execute($sql,$valarr); + + if ($ok) { + $this->_saved = true; + $autoinc = false; + foreach($table->keys as $k) { + if (is_null($this->$k)) { + $autoinc = true; + break; + } + } + if ($autoinc && sizeof($table->keys) == 1) { + $k = reset($table->keys); + $this->$k = $this->LastInsertID($db,$k); + } + } + + $this->_original = $valarr; + return !empty($ok); + } + + function Delete() + { + $db =& $this->DB(); if (!$db) return false; + $table =& $this->TableInfo(); + + $where = $this->GenWhere($db,$table); + $sql = 'DELETE FROM '.$this->_table.' WHERE '.$where; + $ok = $db->Execute($sql); + + return $ok ? true : false; + } + + // returns an array of active record objects + function &Find($whereOrderBy,$bindarr=false,$pkeysArr=false) + { + $db =& $this->DB(); if (!$db || empty($this->_table)) return false; + $arr =& $db->GetActiveRecordsClass(get_class($this),$this->_table, $whereOrderBy,$bindarr,$pkeysArr); + return $arr; + } + + // returns 0 on error, 1 on update, 2 on insert + function Replace() + { + global $ADODB_ASSOC_CASE; + + $db =& $this->DB(); if (!$db) return false; + $table =& $this->TableInfo(); + + $pkey = $table->keys; + + foreach($table->flds as $name=>$fld) { + $val = $this->$name; + /* + if (is_null($val)) { + if (isset($fld->not_null) && $fld->not_null) { + if (isset($fld->default_value) && strlen($fld->default_value)) continue; + else { + $this->Error("Cannot update null into $name","Replace"); + return false; + } + } + }*/ + if (is_null($val) && !empty($fld->auto_increment)) { + continue; + } + $t = $db->MetaType($fld->type); + $arr[$name] = $this->doquote($db,$val,$t); + $valarr[] = $val; + } + + if (!is_array($pkey)) $pkey = array($pkey); + + + if ($ADODB_ASSOC_CASE == 0) + foreach($pkey as $k => $v) + $pkey[$k] = strtolower($v); + elseif ($ADODB_ASSOC_CASE == 0) + foreach($pkey as $k => $v) + $pkey[$k] = strtoupper($v); + + $ok = $db->Replace($this->_table,$arr,$pkey); + if ($ok) { + $this->_saved = true; // 1= update 2=insert + if ($ok == 2) { + $autoinc = false; + foreach($table->keys as $k) { + if (is_null($this->$k)) { + $autoinc = true; + break; + } + } + if ($autoinc && sizeof($table->keys) == 1) { + $k = reset($table->keys); + $this->$k = $this->LastInsertID($db,$k); + } + } + + $this->_original =& $valarr; + } + return $ok; + } + + // returns 0 on error, 1 on update, -1 if no change in data (no update) + function Update() + { + $db =& $this->DB(); if (!$db) return false; + $table =& $this->TableInfo(); + + $where = $this->GenWhere($db, $table); + + if (!$where) { + $this->error("Where missing for table $table", "Update"); + return false; + } + $valarr = array(); + $neworig = array(); + $pairs = array(); + $i = -1; + $cnt = 0; + foreach($table->flds as $name=>$fld) { + $i += 1; + $val = $this->$name; + $neworig[] = $val; + + if (isset($table->keys[$name])) { + continue; + } + + if (is_null($val)) { + if (isset($fld->not_null) && $fld->not_null) { + if (isset($fld->default_value) && strlen($fld->default_value)) continue; + else { + $this->Error("Cannot set field $name to NULL","Update"); + return false; + } + } + } + + if (isset($this->_original[$i]) && $val == $this->_original[$i]) { + continue; + } + $valarr[] = $val; + $pairs[] = $name.'='.$db->Param($cnt); + $cnt += 1; + } + + + if (!$cnt) return -1; + $sql = 'UPDATE '.$this->_table." SET ".implode(",",$pairs)." WHERE ".$where; + $ok = $db->Execute($sql,$valarr); + if ($ok) { + $this->_original =& $neworig; + return 1; + } + return 0; + } + + function GetAttributeNames() + { + $table =& $this->TableInfo(); + if (!$table) return false; + return array_keys($table->flds); + } + +}; + +?> \ No newline at end of file diff --git a/upload/includes/adodb/adodb-csvlib.inc.php b/upload/includes/adodb/adodb-csvlib.inc.php new file mode 100644 index 00000000..5662b6e0 --- /dev/null +++ b/upload/includes/adodb/adodb-csvlib.inc.php @@ -0,0 +1,312 @@ +FieldCount() : 0; + + if ($sql) $sql = urlencode($sql); + // metadata setup + + if ($max <= 0 || $rs->dataProvider == 'empty') { // is insert/update/delete + if (is_object($conn)) { + $sql .= ','.$conn->Affected_Rows(); + $sql .= ','.$conn->Insert_ID(); + } else + $sql .= ',,'; + + $text = "====-1,0,$sql\n"; + return $text; + } + $tt = ($rs->timeCreated) ? $rs->timeCreated : time(); + + ## changed format from ====0 to ====1 + $line = "====1,$tt,$sql\n"; + + if ($rs->databaseType == 'array') { + $rows =& $rs->_array; + } else { + $rows = array(); + while (!$rs->EOF) { + $rows[] = $rs->fields; + $rs->MoveNext(); + } + } + + for($i=0; $i < $max; $i++) { + $o =& $rs->FetchField($i); + $flds[] = $o; + } + + $savefetch = isset($rs->adodbFetchMode) ? $rs->adodbFetchMode : $rs->fetchMode; + $class = $rs->connection->arrayClass; + $rs2 = new $class(); + $rs2->sql = $rs->sql; + $rs2->oldProvider = $rs->dataProvider; + $rs2->InitArrayFields($rows,$flds); + $rs2->fetchMode = $savefetch; + return $line.serialize($rs2); + } + + +/** +* Open CSV file and convert it into Data. +* +* @param url file/ftp/http url +* @param err returns the error message +* @param timeout dispose if recordset has been alive for $timeout secs +* +* @return recordset, or false if error occured. If no +* error occurred in sql INSERT/UPDATE/DELETE, +* empty recordset is returned +*/ + function &csv2rs($url,&$err,$timeout=0, $rsclass='ADORecordSet_array') + { + $false = false; + $err = false; + $fp = @fopen($url,'rb'); + if (!$fp) { + $err = $url.' file/URL not found'; + return $false; + } + @flock($fp, LOCK_SH); + $arr = array(); + $ttl = 0; + + if ($meta = fgetcsv($fp, 32000, ",")) { + // check if error message + if (strncmp($meta[0],'****',4) === 0) { + $err = trim(substr($meta[0],4,1024)); + fclose($fp); + return $false; + } + // check for meta data + // $meta[0] is -1 means return an empty recordset + // $meta[1] contains a time + + if (strncmp($meta[0], '====',4) === 0) { + + if ($meta[0] == "====-1") { + if (sizeof($meta) < 5) { + $err = "Corrupt first line for format -1"; + fclose($fp); + return $false; + } + fclose($fp); + + if ($timeout > 0) { + $err = " Illegal Timeout $timeout "; + return $false; + } + + $rs = new $rsclass($val=true); + $rs->fields = array(); + $rs->timeCreated = $meta[1]; + $rs->EOF = true; + $rs->_numOfFields = 0; + $rs->sql = urldecode($meta[2]); + $rs->affectedrows = (integer)$meta[3]; + $rs->insertid = $meta[4]; + return $rs; + } + # Under high volume loads, we want only 1 thread/process to _write_file + # so that we don't have 50 processes queueing to write the same data. + # We use probabilistic timeout, ahead of time. + # + # -4 sec before timeout, give processes 1/32 chance of timing out + # -2 sec before timeout, give processes 1/16 chance of timing out + # -1 sec after timeout give processes 1/4 chance of timing out + # +0 sec after timeout, give processes 100% chance of timing out + if (sizeof($meta) > 1) { + if($timeout >0){ + $tdiff = (integer)( $meta[1]+$timeout - time()); + if ($tdiff <= 2) { + switch($tdiff) { + case 4: + case 3: + if ((rand() & 31) == 0) { + fclose($fp); + $err = "Timeout 3"; + return $false; + } + break; + case 2: + if ((rand() & 15) == 0) { + fclose($fp); + $err = "Timeout 2"; + return $false; + } + break; + case 1: + if ((rand() & 3) == 0) { + fclose($fp); + $err = "Timeout 1"; + return $false; + } + break; + default: + fclose($fp); + $err = "Timeout 0"; + return $false; + } // switch + + } // if check flush cache + }// (timeout>0) + $ttl = $meta[1]; + } + //================================================ + // new cache format - use serialize extensively... + if ($meta[0] === '====1') { + // slurp in the data + $MAXSIZE = 128000; + + $text = fread($fp,$MAXSIZE); + if (strlen($text)) { + while ($txt = fread($fp,$MAXSIZE)) { + $text .= $txt; + } + } + fclose($fp); + $rs = unserialize($text); + if (is_object($rs)) $rs->timeCreated = $ttl; + else { + $err = "Unable to unserialize recordset"; + //echo htmlspecialchars($text),' !--END--!

    '; + } + return $rs; + } + + $meta = false; + $meta = fgetcsv($fp, 32000, ","); + if (!$meta) { + fclose($fp); + $err = "Unexpected EOF 1"; + return $false; + } + } + + // Get Column definitions + $flds = array(); + foreach($meta as $o) { + $o2 = explode(':',$o); + if (sizeof($o2)!=3) { + $arr[] = $meta; + $flds = false; + break; + } + $fld = new ADOFieldObject(); + $fld->name = urldecode($o2[0]); + $fld->type = $o2[1]; + $fld->max_length = $o2[2]; + $flds[] = $fld; + } + } else { + fclose($fp); + $err = "Recordset had unexpected EOF 2"; + return $false; + } + + // slurp in the data + $MAXSIZE = 128000; + + $text = ''; + while ($txt = fread($fp,$MAXSIZE)) { + $text .= $txt; + } + + fclose($fp); + @$arr = unserialize($text); + //var_dump($arr); + if (!is_array($arr)) { + $err = "Recordset had unexpected EOF (in serialized recordset)"; + if (get_magic_quotes_runtime()) $err .= ". Magic Quotes Runtime should be disabled!"; + return $false; + } + $rs = new $rsclass(); + $rs->timeCreated = $ttl; + $rs->InitArrayFields($arr,$flds); + return $rs; + } + + + /** + * Save a file $filename and its $contents (normally for caching) with file locking + */ + function adodb_write_file($filename, $contents,$debug=false) + { + # http://www.php.net/bugs.php?id=9203 Bug that flock fails on Windows + # So to simulate locking, we assume that rename is an atomic operation. + # First we delete $filename, then we create a $tempfile write to it and + # rename to the desired $filename. If the rename works, then we successfully + # modified the file exclusively. + # What a stupid need - having to simulate locking. + # Risks: + # 1. $tempfile name is not unique -- very very low + # 2. unlink($filename) fails -- ok, rename will fail + # 3. adodb reads stale file because unlink fails -- ok, $rs timeout occurs + # 4. another process creates $filename between unlink() and rename() -- ok, rename() fails and cache updated + if (strncmp(PHP_OS,'WIN',3) === 0) { + // skip the decimal place + $mtime = substr(str_replace(' ','_',microtime()),2); + // getmypid() actually returns 0 on Win98 - never mind! + $tmpname = $filename.uniqid($mtime).getmypid(); + if (!($fd = @fopen($tmpname,'a'))) return false; + $ok = ftruncate($fd,0); + if (!fwrite($fd,$contents)) $ok = false; + fclose($fd); + chmod($tmpname,0644); + // the tricky moment + @unlink($filename); + if (!@rename($tmpname,$filename)) { + unlink($tmpname); + $ok = false; + } + if (!$ok) { + if ($debug) ADOConnection::outp( " Rename $tmpname ".($ok? 'ok' : 'failed')); + } + return $ok; + } + if (!($fd = @fopen($filename, 'a'))) return false; + if (flock($fd, LOCK_EX) && ftruncate($fd, 0)) { + $ok = fwrite( $fd, $contents ); + fclose($fd); + chmod($filename,0644); + }else { + fclose($fd); + if ($debug)ADOConnection::outp( " Failed acquiring lock for $filename
    \n"); + $ok = false; + } + + return $ok; + } +?> \ No newline at end of file diff --git a/upload/includes/adodb/adodb-datadict.inc.php b/upload/includes/adodb/adodb-datadict.inc.php new file mode 100644 index 00000000..cadea1d8 --- /dev/null +++ b/upload/includes/adodb/adodb-datadict.inc.php @@ -0,0 +1,997 @@ +$str

    "; +$a= Lens_ParseArgs($str); +print "
    ";
    +print_r($a);
    +print "
    "; +} + + +if (!function_exists('ctype_alnum')) { + function ctype_alnum($text) { + return preg_match('/^[a-z0-9]*$/i', $text); + } +} + +//Lens_ParseTest(); + +/** + Parse arguments, treat "text" (text) and 'text' as quotation marks. + To escape, use "" or '' or )) + + Will read in "abc def" sans quotes, as: abc def + Same with 'abc def'. + However if `abc def`, then will read in as `abc def` + + @param endstmtchar Character that indicates end of statement + @param tokenchars Include the following characters in tokens apart from A-Z and 0-9 + @returns 2 dimensional array containing parsed tokens. +*/ +function Lens_ParseArgs($args,$endstmtchar=',',$tokenchars='_.-') +{ + $pos = 0; + $intoken = false; + $stmtno = 0; + $endquote = false; + $tokens = array(); + $tokens[$stmtno] = array(); + $max = strlen($args); + $quoted = false; + $tokarr = array(); + + while ($pos < $max) { + $ch = substr($args,$pos,1); + switch($ch) { + case ' ': + case "\t": + case "\n": + case "\r": + if (!$quoted) { + if ($intoken) { + $intoken = false; + $tokens[$stmtno][] = implode('',$tokarr); + } + break; + } + + $tokarr[] = $ch; + break; + + case '`': + if ($intoken) $tokarr[] = $ch; + case '(': + case ')': + case '"': + case "'": + + if ($intoken) { + if (empty($endquote)) { + $tokens[$stmtno][] = implode('',$tokarr); + if ($ch == '(') $endquote = ')'; + else $endquote = $ch; + $quoted = true; + $intoken = true; + $tokarr = array(); + } else if ($endquote == $ch) { + $ch2 = substr($args,$pos+1,1); + if ($ch2 == $endquote) { + $pos += 1; + $tokarr[] = $ch2; + } else { + $quoted = false; + $intoken = false; + $tokens[$stmtno][] = implode('',$tokarr); + $endquote = ''; + } + } else + $tokarr[] = $ch; + + }else { + + if ($ch == '(') $endquote = ')'; + else $endquote = $ch; + $quoted = true; + $intoken = true; + $tokarr = array(); + if ($ch == '`') $tokarr[] = '`'; + } + break; + + default: + + if (!$intoken) { + if ($ch == $endstmtchar) { + $stmtno += 1; + $tokens[$stmtno] = array(); + break; + } + + $intoken = true; + $quoted = false; + $endquote = false; + $tokarr = array(); + + } + + if ($quoted) $tokarr[] = $ch; + else if (ctype_alnum($ch) || strpos($tokenchars,$ch) !== false) $tokarr[] = $ch; + else { + if ($ch == $endstmtchar) { + $tokens[$stmtno][] = implode('',$tokarr); + $stmtno += 1; + $tokens[$stmtno] = array(); + $intoken = false; + $tokarr = array(); + break; + } + $tokens[$stmtno][] = implode('',$tokarr); + $tokens[$stmtno][] = $ch; + $intoken = false; + } + } + $pos += 1; + } + if ($intoken) $tokens[$stmtno][] = implode('',$tokarr); + + return $tokens; +} + + +class ADODB_DataDict { + var $connection; + var $debug = false; + var $dropTable = 'DROP TABLE %s'; + var $renameTable = 'RENAME TABLE %s TO %s'; + var $dropIndex = 'DROP INDEX %s'; + var $addCol = ' ADD'; + var $alterCol = ' ALTER COLUMN'; + var $dropCol = ' DROP COLUMN'; + var $renameColumn = 'ALTER TABLE %s RENAME COLUMN %s TO %s'; // table, old-column, new-column, column-definitions (not used by default) + var $nameRegex = '\w'; + var $nameRegexBrackets = 'a-zA-Z0-9_\(\)'; + var $schema = false; + var $serverInfo = array(); + var $autoIncrement = false; + var $dataProvider; + var $invalidResizeTypes4 = array('CLOB','BLOB','TEXT','DATE','TIME'); // for changetablesql + var $blobSize = 100; /// any varchar/char field this size or greater is treated as a blob + /// in other words, we use a text area for editting. + + function GetCommentSQL($table,$col) + { + return false; + } + + function SetCommentSQL($table,$col,$cmt) + { + return false; + } + + function MetaTables() + { + if (!$this->connection->IsConnected()) return array(); + return $this->connection->MetaTables(); + } + + function MetaColumns($tab, $upper=true, $schema=false) + { + if (!$this->connection->IsConnected()) return array(); + return $this->connection->MetaColumns($this->TableName($tab), $upper, $schema); + } + + function MetaPrimaryKeys($tab,$owner=false,$intkey=false) + { + if (!$this->connection->IsConnected()) return array(); + return $this->connection->MetaPrimaryKeys($this->TableName($tab), $owner, $intkey); + } + + function MetaIndexes($table, $primary = false, $owner = false) + { + if (!$this->connection->IsConnected()) return array(); + return $this->connection->MetaIndexes($this->TableName($table), $primary, $owner); + } + + + function MetaType($t,$len=-1,$fieldobj=false) + { + static $typeMap = array( + 'VARCHAR' => 'C', + 'VARCHAR2' => 'C', + 'CHAR' => 'C', + 'C' => 'C', + 'STRING' => 'C', + 'NCHAR' => 'C', + 'NVARCHAR' => 'C', + 'VARYING' => 'C', + 'BPCHAR' => 'C', + 'CHARACTER' => 'C', + 'INTERVAL' => 'C', # Postgres + 'MACADDR' => 'C', # postgres + ## + 'LONGCHAR' => 'X', + 'TEXT' => 'X', + 'NTEXT' => 'X', + 'M' => 'X', + 'X' => 'X', + 'CLOB' => 'X', + 'NCLOB' => 'X', + 'LVARCHAR' => 'X', + ## + 'BLOB' => 'B', + 'IMAGE' => 'B', + 'BINARY' => 'B', + 'VARBINARY' => 'B', + 'LONGBINARY' => 'B', + 'B' => 'B', + ## + 'YEAR' => 'D', // mysql + 'DATE' => 'D', + 'D' => 'D', + ## + 'UNIQUEIDENTIFIER' => 'C', # MS SQL Server + ## + 'TIME' => 'T', + 'TIMESTAMP' => 'T', + 'DATETIME' => 'T', + 'TIMESTAMPTZ' => 'T', + 'T' => 'T', + 'TIMESTAMP WITHOUT TIME ZONE' => 'T', // postgresql + ## + 'BOOL' => 'L', + 'BOOLEAN' => 'L', + 'BIT' => 'L', + 'L' => 'L', + ## + 'COUNTER' => 'R', + 'R' => 'R', + 'SERIAL' => 'R', // ifx + 'INT IDENTITY' => 'R', + ## + 'INT' => 'I', + 'INT2' => 'I', + 'INT4' => 'I', + 'INT8' => 'I', + 'INTEGER' => 'I', + 'INTEGER UNSIGNED' => 'I', + 'SHORT' => 'I', + 'TINYINT' => 'I', + 'SMALLINT' => 'I', + 'I' => 'I', + ## + 'LONG' => 'N', // interbase is numeric, oci8 is blob + 'BIGINT' => 'N', // this is bigger than PHP 32-bit integers + 'DECIMAL' => 'N', + 'DEC' => 'N', + 'REAL' => 'N', + 'DOUBLE' => 'N', + 'DOUBLE PRECISION' => 'N', + 'SMALLFLOAT' => 'N', + 'FLOAT' => 'N', + 'NUMBER' => 'N', + 'NUM' => 'N', + 'NUMERIC' => 'N', + 'MONEY' => 'N', + + ## informix 9.2 + 'SQLINT' => 'I', + 'SQLSERIAL' => 'I', + 'SQLSMINT' => 'I', + 'SQLSMFLOAT' => 'N', + 'SQLFLOAT' => 'N', + 'SQLMONEY' => 'N', + 'SQLDECIMAL' => 'N', + 'SQLDATE' => 'D', + 'SQLVCHAR' => 'C', + 'SQLCHAR' => 'C', + 'SQLDTIME' => 'T', + 'SQLINTERVAL' => 'N', + 'SQLBYTES' => 'B', + 'SQLTEXT' => 'X', + ## informix 10 + "SQLINT8" => 'I8', + "SQLSERIAL8" => 'I8', + "SQLNCHAR" => 'C', + "SQLNVCHAR" => 'C', + "SQLLVARCHAR" => 'X', + "SQLBOOL" => 'L' + ); + + if (!$this->connection->IsConnected()) { + $t = strtoupper($t); + if (isset($typeMap[$t])) return $typeMap[$t]; + return 'N'; + } + return $this->connection->MetaType($t,$len,$fieldobj); + } + + function NameQuote($name = NULL,$allowBrackets=false) + { + if (!is_string($name)) { + return FALSE; + } + + $name = trim($name); + + if ( !is_object($this->connection) ) { + return $name; + } + + $quote = $this->connection->nameQuote; + + // if name is of the form `name`, quote it + if ( preg_match('/^`(.+)`$/', $name, $matches) ) { + return $quote . $matches[1] . $quote; + } + + // if name contains special characters, quote it + $regex = ($allowBrackets) ? $this->nameRegexBrackets : $this->nameRegex; + + if ( !preg_match('/^[' . $regex . ']+$/', $name) ) { + return $quote . $name . $quote; + } + + return $name; + } + + function TableName($name) + { + if ( $this->schema ) { + return $this->NameQuote($this->schema) .'.'. $this->NameQuote($name); + } + return $this->NameQuote($name); + } + + // Executes the sql array returned by GetTableSQL and GetIndexSQL + function ExecuteSQLArray($sql, $continueOnError = true) + { + $rez = 2; + $conn = &$this->connection; + $saved = $conn->debug; + foreach($sql as $line) { + + if ($this->debug) $conn->debug = true; + $ok = $conn->Execute($line); + $conn->debug = $saved; + if (!$ok) { + if ($this->debug) ADOConnection::outp($conn->ErrorMsg()); + if (!$continueOnError) return 0; + $rez = 1; + } + } + return $rez; + } + + /** + Returns the actual type given a character code. + + C: varchar + X: CLOB (character large object) or largest varchar size if CLOB is not supported + C2: Multibyte varchar + X2: Multibyte CLOB + + B: BLOB (binary large object) + + D: Date + T: Date-time + L: Integer field suitable for storing booleans (0 or 1) + I: Integer + F: Floating point number + N: Numeric or decimal number + */ + + function ActualType($meta) + { + return $meta; + } + + function CreateDatabase($dbname,$options=false) + { + $options = $this->_Options($options); + $sql = array(); + + $s = 'CREATE DATABASE ' . $this->NameQuote($dbname); + if (isset($options[$this->upperName])) + $s .= ' '.$options[$this->upperName]; + + $sql[] = $s; + return $sql; + } + + /* + Generates the SQL to create index. Returns an array of sql strings. + */ + function CreateIndexSQL($idxname, $tabname, $flds, $idxoptions = false) + { + if (!is_array($flds)) { + $flds = explode(',',$flds); + } + + foreach($flds as $key => $fld) { + # some indexes can use partial fields, eg. index first 32 chars of "name" with NAME(32) + $flds[$key] = $this->NameQuote($fld,$allowBrackets=true); + } + + return $this->_IndexSQL($this->NameQuote($idxname), $this->TableName($tabname), $flds, $this->_Options($idxoptions)); + } + + function DropIndexSQL ($idxname, $tabname = NULL) + { + return array(sprintf($this->dropIndex, $this->NameQuote($idxname), $this->TableName($tabname))); + } + + function SetSchema($schema) + { + $this->schema = $schema; + } + + function AddColumnSQL($tabname, $flds) + { + $tabname = $this->TableName ($tabname); + $sql = array(); + list($lines,$pkey,$idxs) = $this->_GenFields($flds); + // genfields can return FALSE at times + if ($lines == null) $lines = array(); + $alter = 'ALTER TABLE ' . $tabname . $this->addCol . ' '; + foreach($lines as $v) { + $sql[] = $alter . $v; + } + if (is_array($idxs)) { + foreach($idxs as $idx => $idxdef) { + $sql_idxs = $this->CreateIndexSql($idx, $tabname, $idxdef['cols'], $idxdef['opts']); + $sql = array_merge($sql, $sql_idxs); + } + } + return $sql; + } + + /** + * Change the definition of one column + * + * As some DBM's can't do that on there own, you need to supply the complete defintion of the new table, + * to allow, recreating the table and copying the content over to the new table + * @param string $tabname table-name + * @param string $flds column-name and type for the changed column + * @param string $tableflds='' complete defintion of the new table, eg. for postgres, default '' + * @param array/string $tableoptions='' options for the new table see CreateTableSQL, default '' + * @return array with SQL strings + */ + function AlterColumnSQL($tabname, $flds, $tableflds='',$tableoptions='') + { + $tabname = $this->TableName ($tabname); + $sql = array(); + list($lines,$pkey,$idxs) = $this->_GenFields($flds); + // genfields can return FALSE at times + if ($lines == null) $lines = array(); + $alter = 'ALTER TABLE ' . $tabname . $this->alterCol . ' '; + foreach($lines as $v) { + $sql[] = $alter . $v; + } + if (is_array($idxs)) { + foreach($idxs as $idx => $idxdef) { + $sql_idxs = $this->CreateIndexSql($idx, $tabname, $idxdef['cols'], $idxdef['opts']); + $sql = array_merge($sql, $sql_idxs); + } + + } + return $sql; + } + + /** + * Rename one column + * + * Some DBM's can only do this together with changeing the type of the column (even if that stays the same, eg. mysql) + * @param string $tabname table-name + * @param string $oldcolumn column-name to be renamed + * @param string $newcolumn new column-name + * @param string $flds='' complete column-defintion-string like for AddColumnSQL, only used by mysql atm., default='' + * @return array with SQL strings + */ + function RenameColumnSQL($tabname,$oldcolumn,$newcolumn,$flds='') + { + $tabname = $this->TableName ($tabname); + if ($flds) { + list($lines,$pkey,$idxs) = $this->_GenFields($flds); + // genfields can return FALSE at times + if ($lines == null) $lines = array(); + list(,$first) = each($lines); + list(,$column_def) = split("[\t ]+",$first,2); + } + return array(sprintf($this->renameColumn,$tabname,$this->NameQuote($oldcolumn),$this->NameQuote($newcolumn),$column_def)); + } + + /** + * Drop one column + * + * Some DBM's can't do that on there own, you need to supply the complete defintion of the new table, + * to allow, recreating the table and copying the content over to the new table + * @param string $tabname table-name + * @param string $flds column-name and type for the changed column + * @param string $tableflds='' complete defintion of the new table, eg. for postgres, default '' + * @param array/string $tableoptions='' options for the new table see CreateTableSQL, default '' + * @return array with SQL strings + */ + function DropColumnSQL($tabname, $flds, $tableflds='',$tableoptions='') + { + $tabname = $this->TableName ($tabname); + if (!is_array($flds)) $flds = explode(',',$flds); + $sql = array(); + $alter = 'ALTER TABLE ' . $tabname . $this->dropCol . ' '; + foreach($flds as $v) { + $sql[] = $alter . $this->NameQuote($v); + } + return $sql; + } + + function DropTableSQL($tabname) + { + return array (sprintf($this->dropTable, $this->TableName($tabname))); + } + + function RenameTableSQL($tabname,$newname) + { + return array (sprintf($this->renameTable, $this->TableName($tabname),$this->TableName($newname))); + } + + /** + Generate the SQL to create table. Returns an array of sql strings. + */ + function CreateTableSQL($tabname, $flds, $tableoptions=array()) + { + list($lines,$pkey,$idxs) = $this->_GenFields($flds, true); + // genfields can return FALSE at times + if ($lines == null) $lines = array(); + + $taboptions = $this->_Options($tableoptions); + $tabname = $this->TableName ($tabname); + $sql = $this->_TableSQL($tabname,$lines,$pkey,$taboptions); + + // ggiunta - 2006/10/12 - KLUDGE: + // if we are on autoincrement, and table options includes REPLACE, the + // autoincrement sequence has already been dropped on table creation sql, so + // we avoid passing REPLACE to trigger creation code. This prevents + // creating sql that double-drops the sequence + if ($this->autoIncrement && isset($taboptions['REPLACE'])) + unset($taboptions['REPLACE']); + $tsql = $this->_Triggers($tabname,$taboptions); + foreach($tsql as $s) $sql[] = $s; + + if (is_array($idxs)) { + foreach($idxs as $idx => $idxdef) { + $sql_idxs = $this->CreateIndexSql($idx, $tabname, $idxdef['cols'], $idxdef['opts']); + $sql = array_merge($sql, $sql_idxs); + } + } + + return $sql; + } + + function _GenFields($flds,$widespacing=false) + { + if (is_string($flds)) { + $padding = ' '; + $txt = $flds.$padding; + $flds = array(); + $flds0 = Lens_ParseArgs($txt,','); + $hasparam = false; + foreach($flds0 as $f0) { + $f1 = array(); + foreach($f0 as $token) { + switch (strtoupper($token)) { + case 'INDEX': + $f1['INDEX'] = ''; + // fall through intentionally + case 'CONSTRAINT': + case 'DEFAULT': + $hasparam = $token; + break; + default: + if ($hasparam) $f1[$hasparam] = $token; + else $f1[] = $token; + $hasparam = false; + break; + } + } + // 'index' token without a name means single column index: name it after column + if (array_key_exists('INDEX', $f1) && $f1['INDEX'] == '') { + $f1['INDEX'] = isset($f0['NAME']) ? $f0['NAME'] : $f0[0]; + // check if column name used to create an index name was quoted + if (($f1['INDEX'][0] == '"' || $f1['INDEX'][0] == "'" || $f1['INDEX'][0] == "`") && + ($f1['INDEX'][0] == substr($f1['INDEX'], -1))) { + $f1['INDEX'] = $f1['INDEX'][0].'idx_'.substr($f1['INDEX'], 1, -1).$f1['INDEX'][0]; + } + else + $f1['INDEX'] = 'idx_'.$f1['INDEX']; + } + // reset it, so we don't get next field 1st token as INDEX... + $hasparam = false; + + $flds[] = $f1; + + } + } + $this->autoIncrement = false; + $lines = array(); + $pkey = array(); + $idxs = array(); + foreach($flds as $fld) { + $fld = _array_change_key_case($fld); + + $fname = false; + $fdefault = false; + $fautoinc = false; + $ftype = false; + $fsize = false; + $fprec = false; + $fprimary = false; + $fnoquote = false; + $fdefts = false; + $fdefdate = false; + $fconstraint = false; + $fnotnull = false; + $funsigned = false; + $findex = ''; + $funiqueindex = false; + + //----------------- + // Parse attributes + foreach($fld as $attr => $v) { + if ($attr == 2 && is_numeric($v)) $attr = 'SIZE'; + else if (is_numeric($attr) && $attr > 1 && !is_numeric($v)) $attr = strtoupper($v); + + switch($attr) { + case '0': + case 'NAME': $fname = $v; break; + case '1': + case 'TYPE': $ty = $v; $ftype = $this->ActualType(strtoupper($v)); break; + + case 'SIZE': + $dotat = strpos($v,'.'); if ($dotat === false) $dotat = strpos($v,','); + if ($dotat === false) $fsize = $v; + else { + $fsize = substr($v,0,$dotat); + $fprec = substr($v,$dotat+1); + } + break; + case 'UNSIGNED': $funsigned = true; break; + case 'AUTOINCREMENT': + case 'AUTO': $fautoinc = true; $fnotnull = true; break; + case 'KEY': + // a primary key col can be non unique in itself (if key spans many cols...) + case 'PRIMARY': $fprimary = $v; $fnotnull = true; /*$funiqueindex = true;*/ break; + case 'DEF': + case 'DEFAULT': $fdefault = $v; break; + case 'NOTNULL': $fnotnull = $v; break; + case 'NOQUOTE': $fnoquote = $v; break; + case 'DEFDATE': $fdefdate = $v; break; + case 'DEFTIMESTAMP': $fdefts = $v; break; + case 'CONSTRAINT': $fconstraint = $v; break; + // let INDEX keyword create a 'very standard' index on column + case 'INDEX': $findex = $v; break; + case 'UNIQUE': $funiqueindex = true; break; + } //switch + } // foreach $fld + + //-------------------- + // VALIDATE FIELD INFO + if (!strlen($fname)) { + if ($this->debug) ADOConnection::outp("Undefined NAME"); + return false; + } + + $fid = strtoupper(preg_replace('/^`(.+)`$/', '$1', $fname)); + $fname = $this->NameQuote($fname); + + if (!strlen($ftype)) { + if ($this->debug) ADOConnection::outp("Undefined TYPE for field '$fname'"); + return false; + } else { + $ftype = strtoupper($ftype); + } + + $ftype = $this->_GetSize($ftype, $ty, $fsize, $fprec); + + if ($ty == 'X' || $ty == 'X2' || $ty == 'B') $fnotnull = false; // some blob types do not accept nulls + + if ($fprimary) $pkey[] = $fname; + + // some databases do not allow blobs to have defaults + if ($ty == 'X') $fdefault = false; + + // build list of indexes + if ($findex != '') { + if (array_key_exists($findex, $idxs)) { + $idxs[$findex]['cols'][] = ($fname); + if (in_array('UNIQUE', $idxs[$findex]['opts']) != $funiqueindex) { + if ($this->debug) ADOConnection::outp("Index $findex defined once UNIQUE and once not"); + } + if ($funiqueindex && !in_array('UNIQUE', $idxs[$findex]['opts'])) + $idxs[$findex]['opts'][] = 'UNIQUE'; + } + else + { + $idxs[$findex] = array(); + $idxs[$findex]['cols'] = array($fname); + if ($funiqueindex) + $idxs[$findex]['opts'] = array('UNIQUE'); + else + $idxs[$findex]['opts'] = array(); + } + } + + //-------------------- + // CONSTRUCT FIELD SQL + if ($fdefts) { + if (substr($this->connection->databaseType,0,5) == 'mysql') { + $ftype = 'TIMESTAMP'; + } else { + $fdefault = $this->connection->sysTimeStamp; + } + } else if ($fdefdate) { + if (substr($this->connection->databaseType,0,5) == 'mysql') { + $ftype = 'TIMESTAMP'; + } else { + $fdefault = $this->connection->sysDate; + } + } else if ($fdefault !== false && !$fnoquote) { + if ($ty == 'C' or $ty == 'X' or + ( substr($fdefault,0,1) != "'" && !is_numeric($fdefault))) { + + if (($ty == 'D' || $ty == 'T') && strtolower($fdefault) != 'null') { + // convert default date into database-aware code + if ($ty == 'T') + { + $fdefault = $this->connection->DBTimeStamp($fdefault); + } + else + { + $fdefault = $this->connection->DBDate($fdefault); + } + } + else + if (strlen($fdefault) != 1 && substr($fdefault,0,1) == ' ' && substr($fdefault,strlen($fdefault)-1) == ' ') + $fdefault = trim($fdefault); + else if (strtolower($fdefault) != 'null') + $fdefault = $this->connection->qstr($fdefault); + } + } + $suffix = $this->_CreateSuffix($fname,$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned); + + // add index creation + if ($widespacing) $fname = str_pad($fname,24); + + // check for field names appearing twice + if (array_key_exists($fid, $lines)) { + ADOConnection::outp("Field '$fname' defined twice"); + } + + $lines[$fid] = $fname.' '.$ftype.$suffix; + + if ($fautoinc) $this->autoIncrement = true; + } // foreach $flds + + return array($lines,$pkey,$idxs); + } + + /** + GENERATE THE SIZE PART OF THE DATATYPE + $ftype is the actual type + $ty is the type defined originally in the DDL + */ + function _GetSize($ftype, $ty, $fsize, $fprec) + { + if (strlen($fsize) && $ty != 'X' && $ty != 'B' && strpos($ftype,'(') === false) { + $ftype .= "(".$fsize; + if (strlen($fprec)) $ftype .= ",".$fprec; + $ftype .= ')'; + } + return $ftype; + } + + + // return string must begin with space + function _CreateSuffix($fname,$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint) + { + $suffix = ''; + if (strlen($fdefault)) $suffix .= " DEFAULT $fdefault"; + if ($fnotnull) $suffix .= ' NOT NULL'; + if ($fconstraint) $suffix .= ' '.$fconstraint; + return $suffix; + } + + function _IndexSQL($idxname, $tabname, $flds, $idxoptions) + { + $sql = array(); + + if ( isset($idxoptions['REPLACE']) || isset($idxoptions['DROP']) ) { + $sql[] = sprintf ($this->dropIndex, $idxname); + if ( isset($idxoptions['DROP']) ) + return $sql; + } + + if ( empty ($flds) ) { + return $sql; + } + + $unique = isset($idxoptions['UNIQUE']) ? ' UNIQUE' : ''; + + $s = 'CREATE' . $unique . ' INDEX ' . $idxname . ' ON ' . $tabname . ' '; + + if ( isset($idxoptions[$this->upperName]) ) + $s .= $idxoptions[$this->upperName]; + + if ( is_array($flds) ) + $flds = implode(', ',$flds); + $s .= '(' . $flds . ')'; + $sql[] = $s; + + return $sql; + } + + function _DropAutoIncrement($tabname) + { + return false; + } + + function _TableSQL($tabname,$lines,$pkey,$tableoptions) + { + $sql = array(); + + if (isset($tableoptions['REPLACE']) || isset ($tableoptions['DROP'])) { + $sql[] = sprintf($this->dropTable,$tabname); + if ($this->autoIncrement) { + $sInc = $this->_DropAutoIncrement($tabname); + if ($sInc) $sql[] = $sInc; + } + if ( isset ($tableoptions['DROP']) ) { + return $sql; + } + } + $s = "CREATE TABLE $tabname (\n"; + $s .= implode(",\n", $lines); + if (sizeof($pkey)>0) { + $s .= ",\n PRIMARY KEY ("; + $s .= implode(", ",$pkey).")"; + } + if (isset($tableoptions['CONSTRAINTS'])) + $s .= "\n".$tableoptions['CONSTRAINTS']; + + if (isset($tableoptions[$this->upperName.'_CONSTRAINTS'])) + $s .= "\n".$tableoptions[$this->upperName.'_CONSTRAINTS']; + + $s .= "\n)"; + if (isset($tableoptions[$this->upperName])) $s .= $tableoptions[$this->upperName]; + $sql[] = $s; + + return $sql; + } + + /** + GENERATE TRIGGERS IF NEEDED + used when table has auto-incrementing field that is emulated using triggers + */ + function _Triggers($tabname,$taboptions) + { + return array(); + } + + /** + Sanitize options, so that array elements with no keys are promoted to keys + */ + function _Options($opts) + { + if (!is_array($opts)) return array(); + $newopts = array(); + foreach($opts as $k => $v) { + if (is_numeric($k)) $newopts[strtoupper($v)] = $v; + else $newopts[strtoupper($k)] = $v; + } + return $newopts; + } + + /** + "Florian Buzin [ easywe ]" + + This function changes/adds new fields to your table. You don't + have to know if the col is new or not. It will check on its own. + */ + function ChangeTableSQL($tablename, $flds, $tableoptions = false) + { + global $ADODB_FETCH_MODE; + + $save = $ADODB_FETCH_MODE; + $ADODB_FETCH_MODE = ADODB_FETCH_ASSOC; + if ($this->connection->fetchMode !== false) $savem = $this->connection->SetFetchMode(false); + + // check table exists + $save_handler = $this->connection->raiseErrorFn; + $this->connection->raiseErrorFn = ''; + $cols = $this->MetaColumns($tablename); + $this->connection->raiseErrorFn = $save_handler; + + if (isset($savem)) $this->connection->SetFetchMode($savem); + $ADODB_FETCH_MODE = $save; + + if ( empty($cols)) { + return $this->CreateTableSQL($tablename, $flds, $tableoptions); + } + + if (is_array($flds)) { + // Cycle through the update fields, comparing + // existing fields to fields to update. + // if the Metatype and size is exactly the + // same, ignore - by Mark Newham + $holdflds = array(); + foreach($flds as $k=>$v) { + if ( isset($cols[$k]) && is_object($cols[$k]) ) { + // If already not allowing nulls, then don't change + $obj = $cols[$k]; + if (isset($obj->not_null) && $obj->not_null) + $v = str_replace('NOT NULL','',$v); + + $c = $cols[$k]; + $ml = $c->max_length; + $mt = $this->MetaType($c->type,$ml); + if ($ml == -1) $ml = ''; + if ($mt == 'X') $ml = $v['SIZE']; + if (($mt != $v['TYPE']) || $ml != $v['SIZE']) { + $holdflds[$k] = $v; + } + } else { + $holdflds[$k] = $v; + } + } + $flds = $holdflds; + } + + + // already exists, alter table instead + list($lines,$pkey,$idxs) = $this->_GenFields($flds); + // genfields can return FALSE at times + if ($lines == null) $lines = array(); + $alter = 'ALTER TABLE ' . $this->TableName($tablename); + $sql = array(); + + foreach ( $lines as $id => $v ) { + if ( isset($cols[$id]) && is_object($cols[$id]) ) { + + $flds = Lens_ParseArgs($v,','); + + // We are trying to change the size of the field, if not allowed, simply ignore the request. + if ($flds && in_array(strtoupper(substr($flds[0][1],0,4)),$this->invalidResizeTypes4)) { + echo "

    $this->alterCol cannot be changed to $flds currently

    "; + continue; + } + $sql[] = $alter . $this->alterCol . ' ' . $v; + } else { + $sql[] = $alter . $this->addCol . ' ' . $v; + } + } + + return $sql; + } +} // class +?> \ No newline at end of file diff --git a/upload/includes/adodb/adodb-error.inc.php b/upload/includes/adodb/adodb-error.inc.php new file mode 100644 index 00000000..fc8fd004 --- /dev/null +++ b/upload/includes/adodb/adodb-error.inc.php @@ -0,0 +1,258 @@ + DB_ERROR_NOSUCHTABLE, + '/Relation [\"\'].*[\"\'] already exists|Cannot insert a duplicate key into (a )?unique index.*/' => DB_ERROR_ALREADY_EXISTS, + '/divide by zero$/' => DB_ERROR_DIVZERO, + '/pg_atoi: error in .*: can\'t parse /' => DB_ERROR_INVALID_NUMBER, + '/ttribute [\"\'].*[\"\'] not found|Relation [\"\'].*[\"\'] does not have attribute [\"\'].*[\"\']/' => DB_ERROR_NOSUCHFIELD, + '/parser: parse error at or near \"/' => DB_ERROR_SYNTAX, + '/referential integrity violation/' => DB_ERROR_CONSTRAINT, + '/Relation [\"\'].*[\"\'] already exists|Cannot insert a duplicate key into (a )?unique index.*|duplicate key violates unique constraint/' + => DB_ERROR_ALREADY_EXISTS + ); + reset($error_regexps); + while (list($regexp,$code) = each($error_regexps)) { + if (preg_match($regexp, $errormsg)) { + return $code; + } + } + // Fall back to DB_ERROR if there was no mapping. + return DB_ERROR; +} + +function adodb_error_odbc() +{ +static $MAP = array( + '01004' => DB_ERROR_TRUNCATED, + '07001' => DB_ERROR_MISMATCH, + '21S01' => DB_ERROR_MISMATCH, + '21S02' => DB_ERROR_MISMATCH, + '22003' => DB_ERROR_INVALID_NUMBER, + '22008' => DB_ERROR_INVALID_DATE, + '22012' => DB_ERROR_DIVZERO, + '23000' => DB_ERROR_CONSTRAINT, + '24000' => DB_ERROR_INVALID, + '34000' => DB_ERROR_INVALID, + '37000' => DB_ERROR_SYNTAX, + '42000' => DB_ERROR_SYNTAX, + 'IM001' => DB_ERROR_UNSUPPORTED, + 'S0000' => DB_ERROR_NOSUCHTABLE, + 'S0001' => DB_ERROR_NOT_FOUND, + 'S0002' => DB_ERROR_NOSUCHTABLE, + 'S0011' => DB_ERROR_ALREADY_EXISTS, + 'S0012' => DB_ERROR_NOT_FOUND, + 'S0021' => DB_ERROR_ALREADY_EXISTS, + 'S0022' => DB_ERROR_NOT_FOUND, + 'S1000' => DB_ERROR_NOSUCHTABLE, + 'S1009' => DB_ERROR_INVALID, + 'S1090' => DB_ERROR_INVALID, + 'S1C00' => DB_ERROR_NOT_CAPABLE + ); + return $MAP; +} + +function adodb_error_ibase() +{ +static $MAP = array( + -104 => DB_ERROR_SYNTAX, + -150 => DB_ERROR_ACCESS_VIOLATION, + -151 => DB_ERROR_ACCESS_VIOLATION, + -155 => DB_ERROR_NOSUCHTABLE, + -157 => DB_ERROR_NOSUCHFIELD, + -158 => DB_ERROR_VALUE_COUNT_ON_ROW, + -170 => DB_ERROR_MISMATCH, + -171 => DB_ERROR_MISMATCH, + -172 => DB_ERROR_INVALID, + -204 => DB_ERROR_INVALID, + -205 => DB_ERROR_NOSUCHFIELD, + -206 => DB_ERROR_NOSUCHFIELD, + -208 => DB_ERROR_INVALID, + -219 => DB_ERROR_NOSUCHTABLE, + -297 => DB_ERROR_CONSTRAINT, + -530 => DB_ERROR_CONSTRAINT, + -803 => DB_ERROR_CONSTRAINT, + -551 => DB_ERROR_ACCESS_VIOLATION, + -552 => DB_ERROR_ACCESS_VIOLATION, + -922 => DB_ERROR_NOSUCHDB, + -923 => DB_ERROR_CONNECT_FAILED, + -924 => DB_ERROR_CONNECT_FAILED + ); + + return $MAP; +} + +function adodb_error_ifx() +{ +static $MAP = array( + '-201' => DB_ERROR_SYNTAX, + '-206' => DB_ERROR_NOSUCHTABLE, + '-217' => DB_ERROR_NOSUCHFIELD, + '-329' => DB_ERROR_NODBSELECTED, + '-1204' => DB_ERROR_INVALID_DATE, + '-1205' => DB_ERROR_INVALID_DATE, + '-1206' => DB_ERROR_INVALID_DATE, + '-1209' => DB_ERROR_INVALID_DATE, + '-1210' => DB_ERROR_INVALID_DATE, + '-1212' => DB_ERROR_INVALID_DATE + ); + + return $MAP; +} + +function adodb_error_oci8() +{ +static $MAP = array( + 1 => DB_ERROR_ALREADY_EXISTS, + 900 => DB_ERROR_SYNTAX, + 904 => DB_ERROR_NOSUCHFIELD, + 923 => DB_ERROR_SYNTAX, + 942 => DB_ERROR_NOSUCHTABLE, + 955 => DB_ERROR_ALREADY_EXISTS, + 1476 => DB_ERROR_DIVZERO, + 1722 => DB_ERROR_INVALID_NUMBER, + 2289 => DB_ERROR_NOSUCHTABLE, + 2291 => DB_ERROR_CONSTRAINT, + 2449 => DB_ERROR_CONSTRAINT + ); + + return $MAP; +} + +function adodb_error_mssql() +{ +static $MAP = array( + 208 => DB_ERROR_NOSUCHTABLE, + 2601 => DB_ERROR_ALREADY_EXISTS + ); + + return $MAP; +} + +function adodb_error_sqlite() +{ +static $MAP = array( + 1 => DB_ERROR_SYNTAX + ); + + return $MAP; +} + +function adodb_error_mysql() +{ +static $MAP = array( + 1004 => DB_ERROR_CANNOT_CREATE, + 1005 => DB_ERROR_CANNOT_CREATE, + 1006 => DB_ERROR_CANNOT_CREATE, + 1007 => DB_ERROR_ALREADY_EXISTS, + 1008 => DB_ERROR_CANNOT_DROP, + 1045 => DB_ERROR_ACCESS_VIOLATION, + 1046 => DB_ERROR_NODBSELECTED, + 1049 => DB_ERROR_NOSUCHDB, + 1050 => DB_ERROR_ALREADY_EXISTS, + 1051 => DB_ERROR_NOSUCHTABLE, + 1054 => DB_ERROR_NOSUCHFIELD, + 1062 => DB_ERROR_ALREADY_EXISTS, + 1064 => DB_ERROR_SYNTAX, + 1100 => DB_ERROR_NOT_LOCKED, + 1136 => DB_ERROR_VALUE_COUNT_ON_ROW, + 1146 => DB_ERROR_NOSUCHTABLE, + 1048 => DB_ERROR_CONSTRAINT, + 2002 => DB_ERROR_CONNECT_FAILED, + 2005 => DB_ERROR_CONNECT_FAILED + ); + + return $MAP; +} +?> \ No newline at end of file diff --git a/upload/includes/adodb/adodb-errorhandler.inc.php b/upload/includes/adodb/adodb-errorhandler.inc.php new file mode 100644 index 00000000..0eac241a --- /dev/null +++ b/upload/includes/adodb/adodb-errorhandler.inc.php @@ -0,0 +1,79 @@ +$s

    "; + trigger_error($s,ADODB_ERROR_HANDLER_TYPE); +} +?> diff --git a/upload/includes/adodb/adodb-errorpear.inc.php b/upload/includes/adodb/adodb-errorpear.inc.php new file mode 100644 index 00000000..d2f39c4c --- /dev/null +++ b/upload/includes/adodb/adodb-errorpear.inc.php @@ -0,0 +1,88 @@ +!$s

    "; +} + +/** +* Returns last PEAR_Error object. This error might be for an error that +* occured several sql statements ago. +*/ +function &ADODB_PEAR_Error() +{ +global $ADODB_Last_PEAR_Error; + + return $ADODB_Last_PEAR_Error; +} + +?> \ No newline at end of file diff --git a/upload/includes/adodb/adodb-exceptions.inc.php b/upload/includes/adodb/adodb-exceptions.inc.php new file mode 100644 index 00000000..2eb0f84a --- /dev/null +++ b/upload/includes/adodb/adodb-exceptions.inc.php @@ -0,0 +1,82 @@ +sql = $p1; + $this->params = $p2; + $s = "$dbms error: [$errno: $errmsg] in $fn(\"$p1\")\n"; + break; + + case 'PCONNECT': + case 'CONNECT': + $user = $thisConnection->user; + $s = "$dbms error: [$errno: $errmsg] in $fn($p1, '$user', '****', $p2)\n"; + break; + default: + $s = "$dbms error: [$errno: $errmsg] in $fn($p1, $p2)\n"; + break; + } + + $this->dbms = $dbms; + if ($thisConnection) { + $this->host = $thisConnection->host; + $this->database = $thisConnection->database; + } + $this->fn = $fn; + $this->msg = $errmsg; + + if (!is_numeric($errno)) $errno = -1; + parent::__construct($s,$errno); + } +} + +/** +* Default Error Handler. This will be called with the following params +* +* @param $dbms the RDBMS you are connecting to +* @param $fn the name of the calling function (in uppercase) +* @param $errno the native error number from the database +* @param $errmsg the native error msg from the database +* @param $p1 $fn specific parameter - see below +* @param $P2 $fn specific parameter - see below +*/ + +function adodb_throw($dbms, $fn, $errno, $errmsg, $p1, $p2, $thisConnection) +{ +global $ADODB_EXCEPTION; + + if (error_reporting() == 0) return; // obey @ protocol + if (is_string($ADODB_EXCEPTION)) $errfn = $ADODB_EXCEPTION; + else $errfn = 'ADODB_EXCEPTION'; + throw new $errfn($dbms, $fn, $errno, $errmsg, $p1, $p2, $thisConnection); +} + + +?> \ No newline at end of file diff --git a/upload/includes/adodb/adodb-iterator.inc.php b/upload/includes/adodb/adodb-iterator.inc.php new file mode 100644 index 00000000..4cdb821c --- /dev/null +++ b/upload/includes/adodb/adodb-iterator.inc.php @@ -0,0 +1,85 @@ +Execute("select * from adoxyz"); + foreach($rs as $k => $v) { + echo $k; print_r($v); echo "
    "; + } + + + Iterator code based on http://cvs.php.net/cvs.php/php-src/ext/spl/examples/cachingiterator.inc?login=2 + */ + + + class ADODB_Iterator implements Iterator { + + private $rs; + + function __construct($rs) + { + $this->rs = $rs; + } + function rewind() + { + $this->rs->MoveFirst(); + } + + function valid() + { + return !$this->rs->EOF; + } + + function key() + { + return $this->rs->_currentRow; + } + + function current() + { + return $this->rs->fields; + } + + function next() + { + $this->rs->MoveNext(); + } + + function __call($func, $params) + { + return call_user_func_array(array($this->rs, $func), $params); + } + + + function hasMore() + { + return !$this->rs->EOF; + } + +} + + +class ADODB_BASE_RS implements IteratorAggregate { + function getIterator() { + return new ADODB_Iterator($this); + } + + /* this is experimental - i don't really know what to return... */ + function __toString() + { + include_once(ADODB_DIR.'/toexport.inc.php'); + return _adodb_export($this,',',',',false,true); + } +} + + +?> \ No newline at end of file diff --git a/upload/includes/adodb/adodb-lib.inc.php b/upload/includes/adodb/adodb-lib.inc.php new file mode 100644 index 00000000..f752dcf0 --- /dev/null +++ b/upload/includes/adodb/adodb-lib.inc.php @@ -0,0 +1,1174 @@ + sizeof($array)) $max = sizeof($array); + else $max = $probe; + + + for ($j=0;$j < $max; $j++) { + $row =& $array[$j]; + if (!$row) break; + $i = -1; + foreach($row as $v) { + $i += 1; + + if (isset($types[$i]) && $types[$i]=='C') continue; + + //print " ($i ".$types[$i]. "$v) "; + $v = trim($v); + + if (!preg_match('/^[+-]{0,1}[0-9\.]+$/',$v)) { + $types[$i] = 'C'; // once C, always C + + continue; + } + if ($j == 0) { + // If empty string, we presume is character + // test for integer for 1st row only + // after that it is up to testing other rows to prove + // that it is not an integer + if (strlen($v) == 0) $types[$i] = 'C'; + if (strpos($v,'.') !== false) $types[$i] = 'N'; + else $types[$i] = 'I'; + continue; + } + + if (strpos($v,'.') !== false) $types[$i] = 'N'; + + } + } + +} + +function adodb_transpose(&$arr, &$newarr, &$hdr, &$fobjs) +{ + $oldX = sizeof(reset($arr)); + $oldY = sizeof($arr); + + if ($hdr) { + $startx = 1; + $hdr = array('Fields'); + for ($y = 0; $y < $oldY; $y++) { + $hdr[] = $arr[$y][0]; + } + } else + $startx = 0; + + for ($x = $startx; $x < $oldX; $x++) { + if ($fobjs) { + $o = $fobjs[$x]; + $newarr[] = array($o->name); + } else + $newarr[] = array(); + + for ($y = 0; $y < $oldY; $y++) { + $newarr[$x-$startx][] = $arr[$y][$x]; + } + } +} + +// Force key to upper. +// See also http://www.php.net/manual/en/function.array-change-key-case.php +function _array_change_key_case($an_array) +{ + if (is_array($an_array)) { + $new_array = array(); + foreach($an_array as $key=>$value) + $new_array[strtoupper($key)] = $value; + + return $new_array; + } + + return $an_array; +} + +function _adodb_replace(&$zthis, $table, $fieldArray, $keyCol, $autoQuote, $has_autoinc) +{ + if (count($fieldArray) == 0) return 0; + $first = true; + $uSet = ''; + + if (!is_array($keyCol)) { + $keyCol = array($keyCol); + } + foreach($fieldArray as $k => $v) { + if ($v === null) { + $v = 'NULL'; + $fieldArray[$k] = $v; + } else if ($autoQuote && !is_numeric($v) /*and strncmp($v,"'",1) !== 0 -- sql injection risk*/ and strcasecmp($v,$zthis->null2null)!=0) { + $v = $zthis->qstr($v); + $fieldArray[$k] = $v; + } + if (in_array($k,$keyCol)) continue; // skip UPDATE if is key + + if ($first) { + $first = false; + $uSet = "$k=$v"; + } else + $uSet .= ",$k=$v"; + } + + $where = false; + foreach ($keyCol as $v) { + if (isset($fieldArray[$v])) { + if ($where) $where .= ' and '.$v.'='.$fieldArray[$v]; + else $where = $v.'='.$fieldArray[$v]; + } + } + + if ($uSet && $where) { + $update = "UPDATE $table SET $uSet WHERE $where"; + + $rs = $zthis->Execute($update); + + + if ($rs) { + if ($zthis->poorAffectedRows) { + /* + The Select count(*) wipes out any errors that the update would have returned. + http://phplens.com/lens/lensforum/msgs.php?id=5696 + */ + if ($zthis->ErrorNo()<>0) return 0; + + # affected_rows == 0 if update field values identical to old values + # for mysql - which is silly. + + $cnt = $zthis->GetOne("select count(*) from $table where $where"); + if ($cnt > 0) return 1; // record already exists + } else { + if (($zthis->Affected_Rows()>0)) return 1; + } + } else + return 0; + } + + // print "

    Error=".$this->ErrorNo().'

    '; + $first = true; + foreach($fieldArray as $k => $v) { + if ($has_autoinc && in_array($k,$keyCol)) continue; // skip autoinc col + + if ($first) { + $first = false; + $iCols = "$k"; + $iVals = "$v"; + } else { + $iCols .= ",$k"; + $iVals .= ",$v"; + } + } + $insert = "INSERT INTO $table ($iCols) VALUES ($iVals)"; + $rs = $zthis->Execute($insert); + return ($rs) ? 2 : 0; +} + +// Requires $ADODB_FETCH_MODE = ADODB_FETCH_NUM +function _adodb_getmenu(&$zthis, $name,$defstr='',$blank1stItem=true,$multiple=false, + $size=0, $selectAttr='',$compareFields0=true) +{ + $hasvalue = false; + + if ($multiple or is_array($defstr)) { + if ($size==0) $size=5; + $attr = ' multiple size="'.$size.'"'; + if (!strpos($name,'[]')) $name .= '[]'; + } else if ($size) $attr = ' size="'.$size.'"'; + else $attr =''; + + $s = '\n"; +} + +// Requires $ADODB_FETCH_MODE = ADODB_FETCH_NUM +function _adodb_getmenu_gp(&$zthis, $name,$defstr='',$blank1stItem=true,$multiple=false, + $size=0, $selectAttr='',$compareFields0=true) +{ + $hasvalue = false; + + if ($multiple or is_array($defstr)) { + if ($size==0) $size=5; + $attr = ' multiple size="'.$size.'"'; + if (!strpos($name,'[]')) $name .= '[]'; + } else if ($size) $attr = ' size="'.$size.'"'; + else $attr =''; + + $s = '\n"; +} + + +/* + Count the number of records this sql statement will return by using + query rewriting heuristics... + + Does not work with UNIONs, except with postgresql and oracle. + + Usage: + + $conn->Connect(...); + $cnt = _adodb_getcount($conn, $sql); + +*/ +function _adodb_getcount(&$zthis, $sql,$inputarr=false,$secs2cache=0) +{ + $qryRecs = 0; + + if (!empty($zthis->_nestedSQL) || preg_match("/^\s*SELECT\s+DISTINCT/is", $sql) || + preg_match('/\s+GROUP\s+BY\s+/is',$sql) || + preg_match('/\s+UNION\s+/is',$sql)) { + + $rewritesql = adodb_strip_order_by($sql); + + // ok, has SELECT DISTINCT or GROUP BY so see if we can use a table alias + // but this is only supported by oracle and postgresql... + if ($zthis->dataProvider == 'oci8') { + // Allow Oracle hints to be used for query optimization, Chris Wrye + if (preg_match('#/\\*+.*?\\*\\/#', $sql, $hint)) { + $rewritesql = "SELECT ".$hint[0]." COUNT(*) FROM (".$rewritesql.")"; + } else + $rewritesql = "SELECT COUNT(*) FROM (".$rewritesql.")"; + + } else if (strncmp($zthis->databaseType,'postgres',8) == 0) { + $rewritesql = "SELECT COUNT(*) FROM ($rewritesql) _ADODB_ALIAS_"; + } + } else { + // now replace SELECT ... FROM with SELECT COUNT(*) FROM + $rewritesql = preg_replace( + '/^\s*SELECT\s.*\s+FROM\s/Uis','SELECT COUNT(*) FROM ',$sql); + // fix by alexander zhukov, alex#unipack.ru, because count(*) and 'order by' fails + // with mssql, access and postgresql. Also a good speedup optimization - skips sorting! + // also see http://phplens.com/lens/lensforum/msgs.php?id=12752 + $rewritesql = adodb_strip_order_by($rewritesql); + } + + if (isset($rewritesql) && $rewritesql != $sql) { + if (preg_match('/\sLIMIT\s+[0-9]+/i',$sql,$limitarr)) $rewritesql .= $limitarr[0]; + + if ($secs2cache) { + // we only use half the time of secs2cache because the count can quickly + // become inaccurate if new records are added + $qryRecs = $zthis->CacheGetOne($secs2cache/2,$rewritesql,$inputarr); + + } else { + $qryRecs = $zthis->GetOne($rewritesql,$inputarr); + } + if ($qryRecs !== false) return $qryRecs; + } + //-------------------------------------------- + // query rewrite failed - so try slower way... + + + // strip off unneeded ORDER BY if no UNION + if (preg_match('/\s*UNION\s*/is', $sql)) $rewritesql = $sql; + else $rewritesql = $rewritesql = adodb_strip_order_by($sql); + + if (preg_match('/\sLIMIT\s+[0-9]+/i',$sql,$limitarr)) $rewritesql .= $limitarr[0]; + + $rstest = &$zthis->Execute($rewritesql,$inputarr); + if (!$rstest) $rstest = $zthis->Execute($sql,$inputarr); + + if ($rstest) { + $qryRecs = $rstest->RecordCount(); + if ($qryRecs == -1) { + global $ADODB_EXTENSION; + // some databases will return -1 on MoveLast() - change to MoveNext() + if ($ADODB_EXTENSION) { + while(!$rstest->EOF) { + adodb_movenext($rstest); + } + } else { + while(!$rstest->EOF) { + $rstest->MoveNext(); + } + } + $qryRecs = $rstest->_currentRow; + } + $rstest->Close(); + if ($qryRecs == -1) return 0; + } + return $qryRecs; +} + +/* + Code originally from "Cornel G" + + This code might not work with SQL that has UNION in it + + Also if you are using CachePageExecute(), there is a strong possibility that + data will get out of synch. use CachePageExecute() only with tables that + rarely change. +*/ +function &_adodb_pageexecute_all_rows(&$zthis, $sql, $nrows, $page, + $inputarr=false, $secs2cache=0) +{ + $atfirstpage = false; + $atlastpage = false; + $lastpageno=1; + + // If an invalid nrows is supplied, + // we assume a default value of 10 rows per page + if (!isset($nrows) || $nrows <= 0) $nrows = 10; + + $qryRecs = false; //count records for no offset + + $qryRecs = _adodb_getcount($zthis,$sql,$inputarr,$secs2cache); + $lastpageno = (int) ceil($qryRecs / $nrows); + $zthis->_maxRecordCount = $qryRecs; + + + + // ***** Here we check whether $page is the last page or + // whether we are trying to retrieve + // a page number greater than the last page number. + if ($page >= $lastpageno) { + $page = $lastpageno; + $atlastpage = true; + } + + // If page number <= 1, then we are at the first page + if (empty($page) || $page <= 1) { + $page = 1; + $atfirstpage = true; + } + + // We get the data we want + $offset = $nrows * ($page-1); + if ($secs2cache > 0) + $rsreturn = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $offset, $inputarr); + else + $rsreturn = &$zthis->SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache); + + + // Before returning the RecordSet, we set the pagination properties we need + if ($rsreturn) { + $rsreturn->_maxRecordCount = $qryRecs; + $rsreturn->rowsPerPage = $nrows; + $rsreturn->AbsolutePage($page); + $rsreturn->AtFirstPage($atfirstpage); + $rsreturn->AtLastPage($atlastpage); + $rsreturn->LastPageNo($lastpageno); + } + return $rsreturn; +} + +// Ivn Oliva version +function &_adodb_pageexecute_no_last_page(&$zthis, $sql, $nrows, $page, $inputarr=false, $secs2cache=0) +{ + + $atfirstpage = false; + $atlastpage = false; + + if (!isset($page) || $page <= 1) { // If page number <= 1, then we are at the first page + $page = 1; + $atfirstpage = true; + } + if ($nrows <= 0) $nrows = 10; // If an invalid nrows is supplied, we assume a default value of 10 rows per page + + // ***** Here we check whether $page is the last page or whether we are trying to retrieve a page number greater than + // the last page number. + $pagecounter = $page + 1; + $pagecounteroffset = ($pagecounter * $nrows) - $nrows; + if ($secs2cache>0) $rstest = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $pagecounteroffset, $inputarr); + else $rstest = &$zthis->SelectLimit($sql, $nrows, $pagecounteroffset, $inputarr, $secs2cache); + if ($rstest) { + while ($rstest && $rstest->EOF && $pagecounter>0) { + $atlastpage = true; + $pagecounter--; + $pagecounteroffset = $nrows * ($pagecounter - 1); + $rstest->Close(); + if ($secs2cache>0) $rstest = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $pagecounteroffset, $inputarr); + else $rstest = &$zthis->SelectLimit($sql, $nrows, $pagecounteroffset, $inputarr, $secs2cache); + } + if ($rstest) $rstest->Close(); + } + if ($atlastpage) { // If we are at the last page or beyond it, we are going to retrieve it + $page = $pagecounter; + if ($page == 1) $atfirstpage = true; // We have to do this again in case the last page is the same as the first + //... page, that is, the recordset has only 1 page. + } + + // We get the data we want + $offset = $nrows * ($page-1); + if ($secs2cache > 0) $rsreturn = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $offset, $inputarr); + else $rsreturn = &$zthis->SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache); + + // Before returning the RecordSet, we set the pagination properties we need + if ($rsreturn) { + $rsreturn->rowsPerPage = $nrows; + $rsreturn->AbsolutePage($page); + $rsreturn->AtFirstPage($atfirstpage); + $rsreturn->AtLastPage($atlastpage); + } + return $rsreturn; +} + +function _adodb_getupdatesql(&$zthis,&$rs, $arrFields,$forceUpdate=false,$magicq=false,$force=2) +{ + global $ADODB_QUOTE_FIELDNAMES; + + if (!$rs) { + printf(ADODB_BAD_RS,'GetUpdateSQL'); + return false; + } + + $fieldUpdatedCount = 0; + $arrFields = _array_change_key_case($arrFields); + + $hasnumeric = isset($rs->fields[0]); + $setFields = ''; + + // Loop through all of the fields in the recordset + for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++) { + // Get the field from the recordset + $field = $rs->FetchField($i); + + // If the recordset field is one + // of the fields passed in then process. + $upperfname = strtoupper($field->name); + if (adodb_key_exists($upperfname,$arrFields,$force)) { + + // If the existing field value in the recordset + // is different from the value passed in then + // go ahead and append the field name and new value to + // the update query. + + if ($hasnumeric) $val = $rs->fields[$i]; + else if (isset($rs->fields[$upperfname])) $val = $rs->fields[$upperfname]; + else if (isset($rs->fields[$field->name])) $val = $rs->fields[$field->name]; + else if (isset($rs->fields[strtolower($upperfname)])) $val = $rs->fields[strtolower($upperfname)]; + else $val = ''; + + + if ($forceUpdate || strcmp($val, $arrFields[$upperfname])) { + // Set the counter for the number of fields that will be updated. + $fieldUpdatedCount++; + + // Based on the datatype of the field + // Format the value properly for the database + $type = $rs->MetaType($field->type); + + + if ($type == 'null') { + $type = 'C'; + } + + if ((strpos($upperfname,' ') !== false) || ($ADODB_QUOTE_FIELDNAMES)) + $fnameq = $zthis->nameQuote.$upperfname.$zthis->nameQuote; + else + $fnameq = $upperfname; + + + // is_null requires php 4.0.4 + //********************************************************// + if (is_null($arrFields[$upperfname]) + || (empty($arrFields[$upperfname]) && strlen($arrFields[$upperfname]) == 0) + || $arrFields[$upperfname] === $zthis->null2null + ) + { + switch ($force) { + + //case 0: + // //Ignore empty values. This is allready handled in "adodb_key_exists" function. + //break; + + case 1: + //Set null + $setFields .= $field->name . " = null, "; + break; + + case 2: + //Set empty + $arrFields[$upperfname] = ""; + $setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq,$arrFields, $magicq); + break; + default: + case 3: + //Set the value that was given in array, so you can give both null and empty values + if (is_null($arrFields[$upperfname]) || $arrFields[$upperfname] === $zthis->null2null) { + $setFields .= $field->name . " = null, "; + } else { + $setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq,$arrFields, $magicq); + } + break; + } + //********************************************************// + } else { + //we do this so each driver can customize the sql for + //DB specific column types. + //Oracle needs BLOB types to be handled with a returning clause + //postgres has special needs as well + $setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq, + $arrFields, $magicq); + } + } + } + } + + // If there were any modified fields then build the rest of the update query. + if ($fieldUpdatedCount > 0 || $forceUpdate) { + // Get the table name from the existing query. + if (!empty($rs->tableName)) $tableName = $rs->tableName; + else { + preg_match("/FROM\s+".ADODB_TABLE_REGEX."/is", $rs->sql, $tableName); + $tableName = $tableName[1]; + } + // Get the full where clause excluding the word "WHERE" from + // the existing query. + preg_match('/\sWHERE\s(.*)/is', $rs->sql, $whereClause); + + $discard = false; + // not a good hack, improvements? + if ($whereClause) { + #var_dump($whereClause); + if (preg_match('/\s(ORDER\s.*)/is', $whereClause[1], $discard)); + else if (preg_match('/\s(LIMIT\s.*)/is', $whereClause[1], $discard)); + else if (preg_match('/\s(FOR UPDATE.*)/is', $whereClause[1], $discard)); + else preg_match('/\s.*(\) WHERE .*)/is', $whereClause[1], $discard); # see http://sourceforge.net/tracker/index.php?func=detail&aid=1379638&group_id=42718&atid=433976 + } else + $whereClause = array(false,false); + + if ($discard) + $whereClause[1] = substr($whereClause[1], 0, strlen($whereClause[1]) - strlen($discard[1])); + + $sql = 'UPDATE '.$tableName.' SET '.substr($setFields, 0, -2); + if (strlen($whereClause[1]) > 0) + $sql .= ' WHERE '.$whereClause[1]; + + return $sql; + + } else { + return false; + } +} + +function adodb_key_exists($key, &$arr,$force=2) +{ + if ($force<=0) { + // the following is the old behaviour where null or empty fields are ignored + return (!empty($arr[$key])) || (isset($arr[$key]) && strlen($arr[$key])>0); + } + + if (isset($arr[$key])) return true; + ## null check below + if (ADODB_PHPVER >= 0x4010) return array_key_exists($key,$arr); + return false; +} + +/** + * There is a special case of this function for the oci8 driver. + * The proper way to handle an insert w/ a blob in oracle requires + * a returning clause with bind variables and a descriptor blob. + * + * + */ +function _adodb_getinsertsql(&$zthis,&$rs,$arrFields,$magicq=false,$force=2) +{ +static $cacheRS = false; +static $cacheSig = 0; +static $cacheCols; + global $ADODB_QUOTE_FIELDNAMES; + + $tableName = ''; + $values = ''; + $fields = ''; + $recordSet = null; + $arrFields = _array_change_key_case($arrFields); + $fieldInsertedCount = 0; + + if (is_string($rs)) { + //ok we have a table name + //try and get the column info ourself. + $tableName = $rs; + + //we need an object for the recordSet + //because we have to call MetaType. + //php can't do a $rsclass::MetaType() + $rsclass = $zthis->rsPrefix.$zthis->databaseType; + $recordSet = new $rsclass(-1,$zthis->fetchMode); + $recordSet->connection = &$zthis; + + if (is_string($cacheRS) && $cacheRS == $rs) { + $columns =& $cacheCols; + } else { + $columns = $zthis->MetaColumns( $tableName ); + $cacheRS = $tableName; + $cacheCols = $columns; + } + } else if (is_subclass_of($rs, 'adorecordset')) { + if (isset($rs->insertSig) && is_integer($cacheRS) && $cacheRS == $rs->insertSig) { + $columns =& $cacheCols; + } else { + for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++) + $columns[] = $rs->FetchField($i); + $cacheRS = $cacheSig; + $cacheCols = $columns; + $rs->insertSig = $cacheSig++; + } + $recordSet =& $rs; + + } else { + printf(ADODB_BAD_RS,'GetInsertSQL'); + return false; + } + + // Loop through all of the fields in the recordset + foreach( $columns as $field ) { + $upperfname = strtoupper($field->name); + if (adodb_key_exists($upperfname,$arrFields,$force)) { + $bad = false; + if ((strpos($upperfname,' ') !== false) || ($ADODB_QUOTE_FIELDNAMES)) + $fnameq = $zthis->nameQuote.$upperfname.$zthis->nameQuote; + else + $fnameq = $upperfname; + + $type = $recordSet->MetaType($field->type); + + /********************************************************/ + if (is_null($arrFields[$upperfname]) + || (empty($arrFields[$upperfname]) && strlen($arrFields[$upperfname]) == 0) + || $arrFields[$upperfname] === $zthis->null2null + ) + { + switch ($force) { + + case 0: // we must always set null if missing + $bad = true; + break; + + case 1: + $values .= "null, "; + break; + + case 2: + //Set empty + $arrFields[$upperfname] = ""; + $values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq,$arrFields, $magicq); + break; + + default: + case 3: + //Set the value that was given in array, so you can give both null and empty values + if (is_null($arrFields[$upperfname]) || $arrFields[$upperfname] === $zthis->null2null) { + $values .= "null, "; + } else { + $values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq, $arrFields, $magicq); + } + break; + } // switch + + /*********************************************************/ + } else { + //we do this so each driver can customize the sql for + //DB specific column types. + //Oracle needs BLOB types to be handled with a returning clause + //postgres has special needs as well + $values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq, + $arrFields, $magicq); + } + + if ($bad) continue; + // Set the counter for the number of fields that will be inserted. + $fieldInsertedCount++; + + + // Get the name of the fields to insert + $fields .= $fnameq . ", "; + } + } + + + // If there were any inserted fields then build the rest of the insert query. + if ($fieldInsertedCount <= 0) return false; + + // Get the table name from the existing query. + if (!$tableName) { + if (!empty($rs->tableName)) $tableName = $rs->tableName; + else if (preg_match("/FROM\s+".ADODB_TABLE_REGEX."/is", $rs->sql, $tableName)) + $tableName = $tableName[1]; + else + return false; + } + + // Strip off the comma and space on the end of both the fields + // and their values. + $fields = substr($fields, 0, -2); + $values = substr($values, 0, -2); + + // Append the fields and their values to the insert query. + return 'INSERT INTO '.$tableName.' ( '.$fields.' ) VALUES ( '.$values.' )'; +} + + +/** + * This private method is used to help construct + * the update/sql which is generated by GetInsertSQL and GetUpdateSQL. + * It handles the string construction of 1 column -> sql string based on + * the column type. We want to do 'safe' handling of BLOBs + * + * @param string the type of sql we are trying to create + * 'I' or 'U'. + * @param string column data type from the db::MetaType() method + * @param string the column name + * @param array the column value + * + * @return string + * + */ +function _adodb_column_sql_oci8(&$zthis,$action, $type, $fname, $fnameq, $arrFields, $magicq) +{ + $sql = ''; + + // Based on the datatype of the field + // Format the value properly for the database + switch($type) { + case 'B': + //in order to handle Blobs correctly, we need + //to do some magic for Oracle + + //we need to create a new descriptor to handle + //this properly + if (!empty($zthis->hasReturningInto)) { + if ($action == 'I') { + $sql = 'empty_blob(), '; + } else { + $sql = $fnameq. '=empty_blob(), '; + } + //add the variable to the returning clause array + //so the user can build this later in + //case they want to add more to it + $zthis->_returningArray[$fname] = ':xx'.$fname.'xx'; + } else if (empty($arrFields[$fname])){ + if ($action == 'I') { + $sql = 'empty_blob(), '; + } else { + $sql = $fnameq. '=empty_blob(), '; + } + } else { + //this is to maintain compatibility + //with older adodb versions. + $sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq,false); + } + break; + + case "X": + //we need to do some more magic here for long variables + //to handle these correctly in oracle. + + //create a safe bind var name + //to avoid conflicts w/ dupes. + if (!empty($zthis->hasReturningInto)) { + if ($action == 'I') { + $sql = ':xx'.$fname.'xx, '; + } else { + $sql = $fnameq.'=:xx'.$fname.'xx, '; + } + //add the variable to the returning clause array + //so the user can build this later in + //case they want to add more to it + $zthis->_returningArray[$fname] = ':xx'.$fname.'xx'; + } else { + //this is to maintain compatibility + //with older adodb versions. + $sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq,false); + } + break; + + default: + $sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq,false); + break; + } + + return $sql; +} + +function _adodb_column_sql(&$zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq, $recurse=true) +{ + + if ($recurse) { + switch($zthis->dataProvider) { + case 'postgres': + if ($type == 'L') $type = 'C'; + break; + case 'oci8': + return _adodb_column_sql_oci8($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq); + + } + } + + switch($type) { + case "C": + case "X": + case 'B': + $val = $zthis->qstr($arrFields[$fname],$magicq); + break; + + case "D": + $val = $zthis->DBDate($arrFields[$fname]); + break; + + + case "T": + $val = $zthis->DBTimeStamp($arrFields[$fname]); + break; + + case "N": + $val = $arrFields[$fname]; + if (!is_numeric($val)) $val = str_replace(',', '.', (float)$val); + break; + + case "I": + case "R": + $val = $arrFields[$fname]; + if (!is_numeric($val)) $val = (integer) $val; + break; + + default: + $val = str_replace(array("'"," ","("),"",$arrFields[$fname]); // basic sql injection defence + if (empty($val)) $val = '0'; + break; + } + + if ($action == 'I') return $val . ", "; + + + return $fnameq . "=" . $val . ", "; + +} + + + +function _adodb_debug_execute(&$zthis, $sql, $inputarr) +{ + $ss = ''; + if ($inputarr) { + foreach($inputarr as $kk=>$vv) { + if (is_string($vv) && strlen($vv)>64) $vv = substr($vv,0,64).'...'; + if (is_null($vv)) $ss .= "($kk=>null) "; + else $ss .= "($kk=>'$vv') "; + } + $ss = "[ $ss ]"; + } + $sqlTxt = is_array($sql) ? $sql[0] : $sql; + /*str_replace(', ','##1#__^LF',is_array($sql) ? $sql[0] : $sql); + $sqlTxt = str_replace(',',', ',$sqlTxt); + $sqlTxt = str_replace('##1#__^LF', ', ' ,$sqlTxt); + */ + // check if running from browser or command-line + $inBrowser = isset($_SERVER['HTTP_USER_AGENT']); + + $dbt = $zthis->databaseType; + if (isset($zthis->dsnType)) $dbt .= '-'.$zthis->dsnType; + if ($inBrowser) { + if ($ss) { + $ss = ''.htmlspecialchars($ss).''; + } + if ($zthis->debug === -1) + ADOConnection::outp( "
    \n($dbt): ".htmlspecialchars($sqlTxt)."   $ss\n
    \n",false); + else + ADOConnection::outp( "


    \n($dbt): ".htmlspecialchars($sqlTxt)."   $ss\n
    \n",false); + } else { + ADOConnection::outp("-----\n($dbt): ".$sqlTxt."\n-----\n",false); + } + + $qID = $zthis->_query($sql,$inputarr); + + /* + Alexios Fakios notes that ErrorMsg() must be called before ErrorNo() for mssql + because ErrorNo() calls Execute('SELECT @ERROR'), causing recursion + */ + if ($zthis->databaseType == 'mssql') { + // ErrorNo is a slow function call in mssql, and not reliable in PHP 4.0.6 + if($emsg = $zthis->ErrorMsg()) { + if ($err = $zthis->ErrorNo()) ADOConnection::outp($err.': '.$emsg); + } + } else if (!$qID) { + ADOConnection::outp($zthis->ErrorNo() .': '. $zthis->ErrorMsg()); + } + + if ($zthis->debug === 99) _adodb_backtrace(true,9999,2); + return $qID; +} + +# pretty print the debug_backtrace function +function _adodb_backtrace($printOrArr=true,$levels=9999,$skippy=0) +{ + if (!function_exists('debug_backtrace')) return ''; + + $html = (isset($_SERVER['HTTP_USER_AGENT'])); + $fmt = ($html) ? " %% line %4d, file: %s" : "%% line %4d, file: %s"; + + $MAXSTRLEN = 128; + + $s = ($html) ? '
    ' : '';
    +	
    +	if (is_array($printOrArr)) $traceArr = $printOrArr;
    +	else $traceArr = debug_backtrace();
    +	array_shift($traceArr);
    +	array_shift($traceArr);
    +	$tabs = sizeof($traceArr)-2;
    +	
    +	foreach ($traceArr as $arr) {
    +		if ($skippy) {$skippy -= 1; continue;}
    +		$levels -= 1;
    +		if ($levels < 0) break;
    +		
    +		$args = array();
    +		for ($i=0; $i < $tabs; $i++) $s .=  ($html) ? '   ' : "\t";
    +		$tabs -= 1;
    +		if ($html) $s .= '';
    +		if (isset($arr['class'])) $s .= $arr['class'].'.';
    +		if (isset($arr['args']))
    +		 foreach($arr['args'] as $v) {
    +			if (is_null($v)) $args[] = 'null';
    +			else if (is_array($v)) $args[] = 'Array['.sizeof($v).']';
    +			else if (is_object($v)) $args[] = 'Object:'.get_class($v);
    +			else if (is_bool($v)) $args[] = $v ? 'true' : 'false';
    +			else {
    +				$v = (string) @$v;
    +				$str = htmlspecialchars(substr($v,0,$MAXSTRLEN));
    +				if (strlen($v) > $MAXSTRLEN) $str .= '...';
    +				$args[] = $str;
    +			}
    +		}
    +		$s .= $arr['function'].'('.implode(', ',$args).')';
    +		
    +		
    +		$s .= @sprintf($fmt, $arr['line'],$arr['file'],basename($arr['file']));
    +			
    +		$s .= "\n";
    +	}	
    +	if ($html) $s .= '
    '; + if ($printOrArr) print $s; + + return $s; +} +/* +function _adodb_find_from($sql) +{ + + $sql = str_replace(array("\n","\r"), ' ', $sql); + $charCount = strlen($sql); + + $inString = false; + $quote = ''; + $parentheseCount = 0; + $prevChars = ''; + $nextChars = ''; + + + for($i = 0; $i < $charCount; $i++) { + + $char = substr($sql,$i,1); + $prevChars = substr($sql,0,$i); + $nextChars = substr($sql,$i+1); + + if((($char == "'" || $char == '"' || $char == '`') && substr($prevChars,-1,1) != '\\') && $inString === false) { + $quote = $char; + $inString = true; + } + + elseif((($char == "'" || $char == '"' || $char == '`') && substr($prevChars,-1,1) != '\\') && $inString === true && $quote == $char) { + $quote = ""; + $inString = false; + } + + elseif($char == "(" && $inString === false) + $parentheseCount++; + + elseif($char == ")" && $inString === false && $parentheseCount > 0) + $parentheseCount--; + + elseif($parentheseCount <= 0 && $inString === false && $char == " " && strtoupper(substr($prevChars,-5,5)) == " FROM") + return $i; + + } +} +*/ + +?> \ No newline at end of file diff --git a/upload/includes/adodb/adodb-memcache.lib.inc.php b/upload/includes/adodb/adodb-memcache.lib.inc.php new file mode 100644 index 00000000..bc6b420b --- /dev/null +++ b/upload/includes/adodb/adodb-memcache.lib.inc.php @@ -0,0 +1,118 @@ +pconnect($host, $port)) { + $err = 'Can\'t connect to memcache server on: '.$host.':'.$port; + return $false; + } + + $rs = $memcache->get($key); + if (!$rs) { + $err = 'Item with such key doesn\'t exists on the memcached server.'; + return $false; + } + + $tdiff = intval($rs->timeCreated+$timeout - time()); + if ($tdiff <= 2) { + switch($tdiff) { + case 2: + if ((rand() & 15) == 0) { + $err = "Timeout 2"; + return $false; + } + break; + case 1: + if ((rand() & 3) == 0) { + $err = "Timeout 1"; + return $false; + } + break; + default: + $err = "Timeout 0"; + return $false; + } + } + return $rs; + } + + function putmemcache($key, $rs, $host, $port, $compress, $debug=false) + { + $false = false; + $true = true; + + if (!function_exists('memcache_pconnect')) { + if ($debug) ADOConnection::outp(" Memcache module PECL extension not found!
    \n"); + return $false; + } + + $memcache = new Memcache; + if (!@$memcache->pconnect($host, $port)) { + if ($debug) ADOConnection::outp(" Can't connect to memcache server on: $host:$port
    \n"); + return $false; + } + + $rs->timeCreated = time(); + if (!$memcache->set($key, $rs, $compress, 0)) { + if ($debug) ADOConnection::outp(" Failed to save data at the memcached server!
    \n"); + return $false; + } + return $true; + } + + function flushmemcache($key=false, $host, $port, $debug=false) + { + if (!function_exists('memcache_pconnect')) { + if ($debug) ADOConnection::outp(" Memcache module PECL extension not found!
    \n"); + return; + } + + $memcache = new Memcache; + if (!@$memcache->pconnect($host, $port)) { + if ($debug) ADOConnection::outp(" Can't connect to memcache server on: $host:$port
    \n"); + return; + } + + if ($key) { + if (!$memcache->delete($key)) { + if ($debug) ADOConnection::outp("CacheFlush: $key entery doesn't exist on memcached server!
    \n"); + } else { + if ($debug) ADOConnection::outp("CacheFlush: $key entery flushed from memcached server!
    \n"); + } + } else { + if (!$memcache->flush()) { + if ($debug) ADOConnection::outp("CacheFlush: Failure flushing all enteries from memcached server!
    \n"); + } else { + if ($debug) ADOConnection::outp("CacheFlush: All enteries flushed from memcached server!
    \n"); + } + } + return; + } +?> diff --git a/upload/includes/adodb/adodb-pager.inc.php b/upload/includes/adodb/adodb-pager.inc.php new file mode 100644 index 00000000..cefadac8 --- /dev/null +++ b/upload/includes/adodb/adodb-pager.inc.php @@ -0,0 +1,290 @@ + implemented Render_PageLinks(). + + Please note, this class is entirely unsupported, + and no free support requests except for bug reports + will be entertained by the author. + +*/ +class ADODB_Pager { + var $id; // unique id for pager (defaults to 'adodb') + var $db; // ADODB connection object + var $sql; // sql used + var $rs; // recordset generated + var $curr_page; // current page number before Render() called, calculated in constructor + var $rows; // number of rows per page + var $linksPerPage=10; // number of links per page in navigation bar + var $showPageLinks; + + var $gridAttributes = 'width=100% border=1 bgcolor=white'; + + // Localize text strings here + var $first = '|<'; + var $prev = '<<'; + var $next = '>>'; + var $last = '>|'; + var $moreLinks = '...'; + var $startLinks = '...'; + var $gridHeader = false; + var $htmlSpecialChars = true; + var $page = 'Page'; + var $linkSelectedColor = 'red'; + var $cache = 0; #secs to cache with CachePageExecute() + + //---------------------------------------------- + // constructor + // + // $db adodb connection object + // $sql sql statement + // $id optional id to identify which pager, + // if you have multiple on 1 page. + // $id should be only be [a-z0-9]* + // + function ADODB_Pager(&$db,$sql,$id = 'adodb', $showPageLinks = false) + { + global $PHP_SELF; + + $curr_page = $id.'_curr_page'; + if (empty($PHP_SELF)) $PHP_SELF = htmlspecialchars($_SERVER['PHP_SELF']); // htmlspecialchars() to prevent XSS attacks + + $this->sql = $sql; + $this->id = $id; + $this->db = $db; + $this->showPageLinks = $showPageLinks; + + $next_page = $id.'_next_page'; + + if (isset($_GET[$next_page])) { + $_SESSION[$curr_page] = (integer) $_GET[$next_page]; + } + if (empty($_SESSION[$curr_page])) $_SESSION[$curr_page] = 1; ## at first page + + $this->curr_page = $_SESSION[$curr_page]; + + } + + //--------------------------- + // Display link to first page + function Render_First($anchor=true) + { + global $PHP_SELF; + if ($anchor) { + ?> + first;?>   + first   "; + } + } + + //-------------------------- + // Display link to next page + function render_next($anchor=true) + { + global $PHP_SELF; + + if ($anchor) { + ?> + next;?>   + next   "; + } + } + + //------------------ + // Link to last page + // + // for better performance with large recordsets, you can set + // $this->db->pageExecuteCountRows = false, which disables + // last page counting. + function render_last($anchor=true) + { + global $PHP_SELF; + + if (!$this->db->pageExecuteCountRows) return; + + if ($anchor) { + ?> + last;?>   + last   "; + } + } + + //--------------------------------------------------- + // original code by "Pablo Costa" + function render_pagelinks() + { + global $PHP_SELF; + $pages = $this->rs->LastPageNo(); + $linksperpage = $this->linksPerPage ? $this->linksPerPage : $pages; + for($i=1; $i <= $pages; $i+=$linksperpage) + { + if($this->rs->AbsolutePage() >= $i) + { + $start = $i; + } + } + $numbers = ''; + $end = $start+$linksperpage-1; + $link = $this->id . "_next_page"; + if($end > $pages) $end = $pages; + + + if ($this->startLinks && $start > 1) { + $pos = $start - 1; + $numbers .= "$this->startLinks "; + } + + for($i=$start; $i <= $end; $i++) { + if ($this->rs->AbsolutePage() == $i) + $numbers .= "linkSelectedColor>$i "; + else + $numbers .= "$i "; + + } + if ($this->moreLinks && $end < $pages) + $numbers .= "$this->moreLinks "; + print $numbers . '   '; + } + // Link to previous page + function render_prev($anchor=true) + { + global $PHP_SELF; + if ($anchor) { + ?> + prev;?>   + prev   "; + } + } + + //-------------------------------------------------------- + // Simply rendering of grid. You should override this for + // better control over the format of the grid + // + // We use output buffering to keep code clean and readable. + function RenderGrid() + { + global $gSQLBlockRows; // used by rs2html to indicate how many rows to display + include_once(ADODB_DIR.'/tohtml.inc.php'); + ob_start(); + $gSQLBlockRows = $this->rows; + rs2html($this->rs,$this->gridAttributes,$this->gridHeader,$this->htmlSpecialChars); + $s = ob_get_contents(); + ob_end_clean(); + return $s; + } + + //------------------------------------------------------- + // Navigation bar + // + // we use output buffering to keep the code easy to read. + function RenderNav() + { + ob_start(); + if (!$this->rs->AtFirstPage()) { + $this->Render_First(); + $this->Render_Prev(); + } else { + $this->Render_First(false); + $this->Render_Prev(false); + } + if ($this->showPageLinks){ + $this->Render_PageLinks(); + } + if (!$this->rs->AtLastPage()) { + $this->Render_Next(); + $this->Render_Last(); + } else { + $this->Render_Next(false); + $this->Render_Last(false); + } + $s = ob_get_contents(); + ob_end_clean(); + return $s; + } + + //------------------- + // This is the footer + function RenderPageCount() + { + if (!$this->db->pageExecuteCountRows) return ''; + $lastPage = $this->rs->LastPageNo(); + if ($lastPage == -1) $lastPage = 1; // check for empty rs. + if ($this->curr_page > $lastPage) $this->curr_page = 1; + return "$this->page ".$this->curr_page."/".$lastPage.""; + } + + //----------------------------------- + // Call this class to draw everything. + function Render($rows=10) + { + global $ADODB_COUNTRECS; + + $this->rows = $rows; + + if ($this->db->dataProvider == 'informix') $this->db->cursorType = IFX_SCROLL; + + $savec = $ADODB_COUNTRECS; + if ($this->db->pageExecuteCountRows) $ADODB_COUNTRECS = true; + if ($this->cache) + $rs = &$this->db->CachePageExecute($this->cache,$this->sql,$rows,$this->curr_page); + else + $rs = &$this->db->PageExecute($this->sql,$rows,$this->curr_page); + $ADODB_COUNTRECS = $savec; + + $this->rs = &$rs; + if (!$rs) { + print "

    Query failed: $this->sql

    "; + return; + } + + if (!$rs->EOF && (!$rs->AtFirstPage() || !$rs->AtLastPage())) + $header = $this->RenderNav(); + else + $header = " "; + + $grid = $this->RenderGrid(); + $footer = $this->RenderPageCount(); + + $this->RenderLayout($header,$grid,$footer); + + $rs->Close(); + $this->rs = false; + } + + //------------------------------------------------------ + // override this to control overall layout and formating + function RenderLayout($header,$grid,$footer,$attributes='border=1 bgcolor=beige') + { + echo "
    ", + $header, + "
    ", + $grid, + "
    ", + $footer, + "
    "; + } +} + + +?> \ No newline at end of file diff --git a/upload/includes/adodb/adodb-pear.inc.php b/upload/includes/adodb/adodb-pear.inc.php new file mode 100644 index 00000000..7edee370 --- /dev/null +++ b/upload/includes/adodb/adodb-pear.inc.php @@ -0,0 +1,374 @@ + | + * and Tomas V.V.Cox . Portions (c)1997-2002 The PHP Group. + */ + + /* + We support: + + DB_Common + --------- + query - returns PEAR_Error on error + limitQuery - return PEAR_Error on error + prepare - does not return PEAR_Error on error + execute - does not return PEAR_Error on error + setFetchMode - supports ASSOC and ORDERED + errorNative + quote + nextID + disconnect + + getOne + getAssoc + getRow + getCol + getAll + + DB_Result + --------- + numRows - returns -1 if not supported + numCols + fetchInto - does not support passing of fetchmode + fetchRows - does not support passing of fetchmode + free + */ + +define('ADODB_PEAR',dirname(__FILE__)); +include_once "PEAR.php"; +include_once ADODB_PEAR."/adodb-errorpear.inc.php"; +include_once ADODB_PEAR."/adodb.inc.php"; + +if (!defined('DB_OK')) { +define("DB_OK", 1); +define("DB_ERROR",-1); + +// autoExecute constants +define('DB_AUTOQUERY_INSERT', 1); +define('DB_AUTOQUERY_UPDATE', 2); + +/** + * This is a special constant that tells DB the user hasn't specified + * any particular get mode, so the default should be used. + */ + +define('DB_FETCHMODE_DEFAULT', 0); + +/** + * Column data indexed by numbers, ordered from 0 and up + */ + +define('DB_FETCHMODE_ORDERED', 1); + +/** + * Column data indexed by column names + */ + +define('DB_FETCHMODE_ASSOC', 2); + +/* for compatibility */ + +define('DB_GETMODE_ORDERED', DB_FETCHMODE_ORDERED); +define('DB_GETMODE_ASSOC', DB_FETCHMODE_ASSOC); + +/** + * these are constants for the tableInfo-function + * they are bitwised or'ed. so if there are more constants to be defined + * in the future, adjust DB_TABLEINFO_FULL accordingly + */ + +define('DB_TABLEINFO_ORDER', 1); +define('DB_TABLEINFO_ORDERTABLE', 2); +define('DB_TABLEINFO_FULL', 3); +} + +/** + * The main "DB" class is simply a container class with some static + * methods for creating DB objects as well as some utility functions + * common to all parts of DB. + * + */ + +class DB +{ + /** + * Create a new DB object for the specified database type + * + * @param $type string database type, for example "mysql" + * + * @return object a newly created DB object, or a DB error code on + * error + */ + + function &factory($type) + { + include_once(ADODB_DIR."/drivers/adodb-$type.inc.php"); + $obj = &NewADOConnection($type); + if (!is_object($obj)) $obj =& new PEAR_Error('Unknown Database Driver: '.$dsninfo['phptype'],-1); + return $obj; + } + + /** + * Create a new DB object and connect to the specified database + * + * @param $dsn mixed "data source name", see the DB::parseDSN + * method for a description of the dsn format. Can also be + * specified as an array of the format returned by DB::parseDSN. + * + * @param $options mixed if boolean (or scalar), tells whether + * this connection should be persistent (for backends that support + * this). This parameter can also be an array of options, see + * DB_common::setOption for more information on connection + * options. + * + * @return object a newly created DB connection object, or a DB + * error object on error + * + * @see DB::parseDSN + * @see DB::isError + */ + function &connect($dsn, $options = false) + { + if (is_array($dsn)) { + $dsninfo = $dsn; + } else { + $dsninfo = DB::parseDSN($dsn); + } + switch ($dsninfo["phptype"]) { + case 'pgsql': $type = 'postgres7'; break; + case 'ifx': $type = 'informix9'; break; + default: $type = $dsninfo["phptype"]; break; + } + + if (is_array($options) && isset($options["debug"]) && + $options["debug"] >= 2) { + // expose php errors with sufficient debug level + @include_once("adodb-$type.inc.php"); + } else { + @include_once("adodb-$type.inc.php"); + } + + @$obj =& NewADOConnection($type); + if (!is_object($obj)) { + $obj =& new PEAR_Error('Unknown Database Driver: '.$dsninfo['phptype'],-1); + return $obj; + } + if (is_array($options)) { + foreach($options as $k => $v) { + switch(strtolower($k)) { + case 'persist': + case 'persistent': $persist = $v; break; + #ibase + case 'dialect': $obj->dialect = $v; break; + case 'charset': $obj->charset = $v; break; + case 'buffers': $obj->buffers = $v; break; + #ado + case 'charpage': $obj->charPage = $v; break; + #mysql + case 'clientflags': $obj->clientFlags = $v; break; + } + } + } else { + $persist = false; + } + + if (isset($dsninfo['socket'])) $dsninfo['hostspec'] .= ':'.$dsninfo['socket']; + else if (isset($dsninfo['port'])) $dsninfo['hostspec'] .= ':'.$dsninfo['port']; + + if($persist) $ok = $obj->PConnect($dsninfo['hostspec'], $dsninfo['username'],$dsninfo['password'],$dsninfo['database']); + else $ok = $obj->Connect($dsninfo['hostspec'], $dsninfo['username'],$dsninfo['password'],$dsninfo['database']); + + if (!$ok) $obj = ADODB_PEAR_Error(); + return $obj; + } + + /** + * Return the DB API version + * + * @return int the DB API version number + */ + function apiVersion() + { + return 2; + } + + /** + * Tell whether a result code from a DB method is an error + * + * @param $value int result code + * + * @return bool whether $value is an error + */ + function isError($value) + { + if (!is_object($value)) return false; + $class = get_class($value); + return $class == 'pear_error' || is_subclass_of($value, 'pear_error') || + $class == 'db_error' || is_subclass_of($value, 'db_error'); + } + + + /** + * Tell whether a result code from a DB method is a warning. + * Warnings differ from errors in that they are generated by DB, + * and are not fatal. + * + * @param $value mixed result value + * + * @return bool whether $value is a warning + */ + function isWarning($value) + { + return false; + /* + return is_object($value) && + (get_class( $value ) == "db_warning" || + is_subclass_of($value, "db_warning"));*/ + } + + /** + * Parse a data source name + * + * @param $dsn string Data Source Name to be parsed + * + * @return array an associative array with the following keys: + * + * phptype: Database backend used in PHP (mysql, odbc etc.) + * dbsyntax: Database used with regards to SQL syntax etc. + * protocol: Communication protocol to use (tcp, unix etc.) + * hostspec: Host specification (hostname[:port]) + * database: Database to use on the DBMS server + * username: User name for login + * password: Password for login + * + * The format of the supplied DSN is in its fullest form: + * + * phptype(dbsyntax)://username:password@protocol+hostspec/database + * + * Most variations are allowed: + * + * phptype://username:password@protocol+hostspec:110//usr/db_file.db + * phptype://username:password@hostspec/database_name + * phptype://username:password@hostspec + * phptype://username@hostspec + * phptype://hostspec/database + * phptype://hostspec + * phptype(dbsyntax) + * phptype + * + * @author Tomas V.V.Cox + */ + function parseDSN($dsn) + { + if (is_array($dsn)) { + return $dsn; + } + + $parsed = array( + 'phptype' => false, + 'dbsyntax' => false, + 'protocol' => false, + 'hostspec' => false, + 'database' => false, + 'username' => false, + 'password' => false + ); + + // Find phptype and dbsyntax + if (($pos = strpos($dsn, '://')) !== false) { + $str = substr($dsn, 0, $pos); + $dsn = substr($dsn, $pos + 3); + } else { + $str = $dsn; + $dsn = NULL; + } + + // Get phptype and dbsyntax + // $str => phptype(dbsyntax) + if (preg_match('|^(.+?)\((.*?)\)$|', $str, $arr)) { + $parsed['phptype'] = $arr[1]; + $parsed['dbsyntax'] = (empty($arr[2])) ? $arr[1] : $arr[2]; + } else { + $parsed['phptype'] = $str; + $parsed['dbsyntax'] = $str; + } + + if (empty($dsn)) { + return $parsed; + } + + // Get (if found): username and password + // $dsn => username:password@protocol+hostspec/database + if (($at = strpos($dsn,'@')) !== false) { + $str = substr($dsn, 0, $at); + $dsn = substr($dsn, $at + 1); + if (($pos = strpos($str, ':')) !== false) { + $parsed['username'] = urldecode(substr($str, 0, $pos)); + $parsed['password'] = urldecode(substr($str, $pos + 1)); + } else { + $parsed['username'] = urldecode($str); + } + } + + // Find protocol and hostspec + // $dsn => protocol+hostspec/database + if (($pos=strpos($dsn, '/')) !== false) { + $str = substr($dsn, 0, $pos); + $dsn = substr($dsn, $pos + 1); + } else { + $str = $dsn; + $dsn = NULL; + } + + // Get protocol + hostspec + // $str => protocol+hostspec + if (($pos=strpos($str, '+')) !== false) { + $parsed['protocol'] = substr($str, 0, $pos); + $parsed['hostspec'] = urldecode(substr($str, $pos + 1)); + } else { + $parsed['hostspec'] = urldecode($str); + } + + // Get dabase if any + // $dsn => database + if (!empty($dsn)) { + $parsed['database'] = $dsn; + } + + return $parsed; + } + + /** + * Load a PHP database extension if it is not loaded already. + * + * @access public + * + * @param $name the base name of the extension (without the .so or + * .dll suffix) + * + * @return bool true if the extension was already or successfully + * loaded, false if it could not be loaded + */ + function assertExtension($name) + { + if (!extension_loaded($name)) { + $dlext = (strncmp(PHP_OS,'WIN',3) === 0) ? '.dll' : '.so'; + @dl($name . $dlext); + } + if (!extension_loaded($name)) { + return false; + } + return true; + } +} + +?> \ No newline at end of file diff --git a/upload/includes/adodb/adodb-perf.inc.php b/upload/includes/adodb/adodb-perf.inc.php new file mode 100644 index 00000000..f6eb10d7 --- /dev/null +++ b/upload/includes/adodb/adodb-perf.inc.php @@ -0,0 +1,1079 @@ +=2) return (integer) $memarr[1]; + + return 0; +} + +// avoids localization problems where , is used instead of . +function adodb_round($n,$prec) +{ + return number_format($n, $prec, '.', ''); +} + +/* return microtime value as a float */ +function adodb_microtime() +{ + $t = microtime(); + $t = explode(' ',$t); + return (float)$t[1]+ (float)$t[0]; +} + +/* sql code timing */ +function& adodb_log_sql(&$connx,$sql,$inputarr) +{ + $perf_table = adodb_perf::table(); + $connx->fnExecute = false; + $t0 = microtime(); + $rs =& $connx->Execute($sql,$inputarr); + $t1 = microtime(); + + if (!empty($connx->_logsql) && (empty($connx->_logsqlErrors) || !$rs)) { + global $ADODB_LOG_CONN; + + if (!empty($ADODB_LOG_CONN)) { + $conn = &$ADODB_LOG_CONN; + if ($conn->databaseType != $connx->databaseType) + $prefix = '/*dbx='.$connx->databaseType .'*/ '; + else + $prefix = ''; + } else { + $conn =& $connx; + $prefix = ''; + } + + $conn->_logsql = false; // disable logsql error simulation + $dbT = $conn->databaseType; + + $a0 = split(' ',$t0); + $a0 = (float)$a0[1]+(float)$a0[0]; + + $a1 = split(' ',$t1); + $a1 = (float)$a1[1]+(float)$a1[0]; + + $time = $a1 - $a0; + + if (!$rs) { + $errM = $connx->ErrorMsg(); + $errN = $connx->ErrorNo(); + $conn->lastInsID = 0; + $tracer = substr('ERROR: '.htmlspecialchars($errM),0,250); + } else { + $tracer = ''; + $errM = ''; + $errN = 0; + $dbg = $conn->debug; + $conn->debug = false; + if (!is_object($rs) || $rs->dataProvider == 'empty') + $conn->_affected = $conn->affected_rows(true); + $conn->lastInsID = @$conn->Insert_ID(); + $conn->debug = $dbg; + } + if (isset($_SERVER['HTTP_HOST'])) { + $tracer .= '
    '.$_SERVER['HTTP_HOST']; + if (isset($_SERVER['PHP_SELF'])) $tracer .= $_SERVER['PHP_SELF']; + } else + if (isset($_SERVER['PHP_SELF'])) $tracer .= '
    '.$_SERVER['PHP_SELF']; + //$tracer .= (string) adodb_backtrace(false); + + $tracer = (string) substr($tracer,0,500); + + if (is_array($inputarr)) { + if (is_array(reset($inputarr))) $params = 'Array sizeof='.sizeof($inputarr); + else { + // Quote string parameters so we can see them in the + // performance stats. This helps spot disabled indexes. + $xar_params = $inputarr; + foreach ($xar_params as $xar_param_key => $xar_param) { + if (gettype($xar_param) == 'string') + $xar_params[$xar_param_key] = '"' . $xar_param . '"'; + } + $params = implode(', ', $xar_params); + if (strlen($params) >= 3000) $params = substr($params, 0, 3000); + } + } else { + $params = ''; + } + + if (is_array($sql)) $sql = $sql[0]; + if ($prefix) $sql = $prefix.$sql; + $arr = array('b'=>strlen($sql).'.'.crc32($sql), + 'c'=>substr($sql,0,3900), 'd'=>$params,'e'=>$tracer,'f'=>adodb_round($time,6)); + //var_dump($arr); + $saved = $conn->debug; + $conn->debug = 0; + + $d = $conn->sysTimeStamp; + if (empty($d)) $d = date("'Y-m-d H:i:s'"); + if ($conn->dataProvider == 'oci8' && $dbT != 'oci8po') { + $isql = "insert into $perf_table values($d,:b,:c,:d,:e,:f)"; + } else if ($dbT == 'odbc_mssql' || $dbT == 'informix' || strncmp($dbT,'odbtp',4)==0) { + $timer = $arr['f']; + if ($dbT == 'informix') $sql2 = substr($sql2,0,230); + + $sql1 = $conn->qstr($arr['b']); + $sql2 = $conn->qstr($arr['c']); + $params = $conn->qstr($arr['d']); + $tracer = $conn->qstr($arr['e']); + + $isql = "insert into $perf_table (created,sql0,sql1,params,tracer,timer) values($d,$sql1,$sql2,$params,$tracer,$timer)"; + if ($dbT == 'informix') $isql = str_replace(chr(10),' ',$isql); + $arr = false; + } else { + if ($dbT == 'db2') $arr['f'] = (float) $arr['f']; + $isql = "insert into $perf_table (created,sql0,sql1,params,tracer,timer) values( $d,?,?,?,?,?)"; + } + $ok = $conn->Execute($isql,$arr); + $conn->debug = $saved; + + if ($ok) { + $conn->_logsql = true; + } else { + $err2 = $conn->ErrorMsg(); + $conn->_logsql = true; // enable logsql error simulation + $perf =& NewPerfMonitor($conn); + if ($perf) { + if ($perf->CreateLogTable()) $ok = $conn->Execute($isql,$arr); + } else { + $ok = $conn->Execute("create table $perf_table ( + created varchar(50), + sql0 varchar(250), + sql1 varchar(4000), + params varchar(3000), + tracer varchar(500), + timer decimal(16,6))"); + } + if (!$ok) { + ADOConnection::outp( "

    LOGSQL Insert Failed: $isql
    $err2

    "); + $conn->_logsql = false; + } + } + $connx->_errorMsg = $errM; + $connx->_errorCode = $errN; + } + $connx->fnExecute = 'adodb_log_sql'; + return $rs; +} + + +/* +The settings data structure is an associative array that database parameter per element. + +Each database parameter element in the array is itself an array consisting of: + +0: category code, used to group related db parameters +1: either + a. sql string to retrieve value, eg. "select value from v\$parameter where name='db_block_size'", + b. array holding sql string and field to look for, e.g. array('show variables','table_cache'), + c. a string prefixed by =, then a PHP method of the class is invoked, + e.g. to invoke $this->GetIndexValue(), set this array element to '=GetIndexValue', +2: description of the database parameter +*/ + +class adodb_perf { + var $conn; + var $color = '#F0F0F0'; + var $table = ''; + var $titles = ''; + var $warnRatio = 90; + var $tablesSQL = false; + var $cliFormat = "%32s => %s \r\n"; + var $sql1 = 'sql1'; // used for casting sql1 to text for mssql + var $explain = true; + var $helpurl = "LogSQL help"; + var $createTableSQL = false; + var $maxLength = 2000; + + // Sets the tablename to be used + function table($newtable = false) + { + static $_table; + + if (!empty($newtable)) $_table = $newtable; + if (empty($_table)) $_table = 'adodb_logsql'; + return $_table; + } + + // returns array with info to calculate CPU Load + function _CPULoad() + { +/* + +cpu 524152 2662 2515228 336057010 +cpu0 264339 1408 1257951 168025827 +cpu1 259813 1254 1257277 168031181 +page 622307 25475680 +swap 24 1891 +intr 890153570 868093576 6 0 4 4 0 6 1 2 0 0 0 124 0 8098760 2 13961053 0 0 0 0 0 0 0 0 0 0 0 0 0 16 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +disk_io: (3,0):(3144904,54369,610378,3090535,50936192) (3,1):(3630212,54097,633016,3576115,50951320) +ctxt 66155838 +btime 1062315585 +processes 69293 + +*/ + // Algorithm is taken from + // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/example__obtaining_raw_performance_data.asp + if (strncmp(PHP_OS,'WIN',3)==0) { + if (PHP_VERSION == '5.0.0') return false; + if (PHP_VERSION == '5.0.1') return false; + if (PHP_VERSION == '5.0.2') return false; + if (PHP_VERSION == '5.0.3') return false; + if (PHP_VERSION == '4.3.10') return false; # see http://bugs.php.net/bug.php?id=31737 + + @$c = new COM("WinMgmts:{impersonationLevel=impersonate}!Win32_PerfRawData_PerfOS_Processor.Name='_Total'"); + if (!$c) return false; + + $info[0] = $c->PercentProcessorTime; + $info[1] = 0; + $info[2] = 0; + $info[3] = $c->TimeStamp_Sys100NS; + //print_r($info); + return $info; + } + + // Algorithm - Steve Blinch (BlitzAffe Online, http://www.blitzaffe.com) + $statfile = '/proc/stat'; + if (!file_exists($statfile)) return false; + + $fd = fopen($statfile,"r"); + if (!$fd) return false; + + $statinfo = explode("\n",fgets($fd, 1024)); + fclose($fd); + foreach($statinfo as $line) { + $info = explode(" ",$line); + if($info[0]=="cpu") { + array_shift($info); // pop off "cpu" + if(!$info[0]) array_shift($info); // pop off blank space (if any) + return $info; + } + } + + return false; + + } + + /* NOT IMPLEMENTED */ + function MemInfo() + { + /* + + total: used: free: shared: buffers: cached: +Mem: 1055289344 917299200 137990144 0 165437440 599773184 +Swap: 2146775040 11055104 2135719936 +MemTotal: 1030556 kB +MemFree: 134756 kB +MemShared: 0 kB +Buffers: 161560 kB +Cached: 581384 kB +SwapCached: 4332 kB +Active: 494468 kB +Inact_dirty: 322856 kB +Inact_clean: 24256 kB +Inact_target: 168316 kB +HighTotal: 131064 kB +HighFree: 1024 kB +LowTotal: 899492 kB +LowFree: 133732 kB +SwapTotal: 2096460 kB +SwapFree: 2085664 kB +Committed_AS: 348732 kB + */ + } + + + /* + Remember that this is client load, not db server load! + */ + var $_lastLoad; + function CPULoad() + { + $info = $this->_CPULoad(); + if (!$info) return false; + + if (empty($this->_lastLoad)) { + sleep(1); + $this->_lastLoad = $info; + $info = $this->_CPULoad(); + } + + $last = $this->_lastLoad; + $this->_lastLoad = $info; + + $d_user = $info[0] - $last[0]; + $d_nice = $info[1] - $last[1]; + $d_system = $info[2] - $last[2]; + $d_idle = $info[3] - $last[3]; + + //printf("Delta - User: %f Nice: %f System: %f Idle: %f
    ",$d_user,$d_nice,$d_system,$d_idle); + + if (strncmp(PHP_OS,'WIN',3)==0) { + if ($d_idle < 1) $d_idle = 1; + return 100*(1-$d_user/$d_idle); + }else { + $total=$d_user+$d_nice+$d_system+$d_idle; + if ($total<1) $total=1; + return 100*($d_user+$d_nice+$d_system)/$total; + } + } + + function Tracer($sql) + { + $perf_table = adodb_perf::table(); + $saveE = $this->conn->fnExecute; + $this->conn->fnExecute = false; + + global $ADODB_FETCH_MODE; + $save = $ADODB_FETCH_MODE; + $ADODB_FETCH_MODE = ADODB_FETCH_NUM; + if ($this->conn->fetchMode !== false) $savem = $this->conn->SetFetchMode(false); + + $sqlq = $this->conn->qstr($sql); + $arr = $this->conn->GetArray( +"select count(*),tracer + from $perf_table where sql1=$sqlq + group by tracer + order by 1 desc"); + $s = ''; + if ($arr) { + $s .= '

    Scripts Affected

    '; + foreach($arr as $k) { + $s .= sprintf("%4d",$k[0]).'   '.strip_tags($k[1]).'
    '; + } + } + + if (isset($savem)) $this->conn->SetFetchMode($savem); + $ADODB_CACHE_MODE = $save; + $this->conn->fnExecute = $saveE; + return $s; + } + + /* + Explain Plan for $sql. + If only a snippet of the $sql is passed in, then $partial will hold the crc32 of the + actual sql. + */ + function Explain($sql,$partial=false) + { + return false; + } + + function InvalidSQL($numsql = 10) + { + + if (isset($_GET['sql'])) return; + $s = '

    Invalid SQL

    '; + $saveE = $this->conn->fnExecute; + $this->conn->fnExecute = false; + $perf_table = adodb_perf::table(); + $rs =& $this->conn->SelectLimit("select distinct count(*),sql1,tracer as error_msg from $perf_table where tracer like 'ERROR:%' group by sql1,tracer order by 1 desc",$numsql);//,$numsql); + $this->conn->fnExecute = $saveE; + if ($rs) { + $s .= rs2html($rs,false,false,false,false); + } else + return "

    $this->helpurl. ".$this->conn->ErrorMsg()."

    "; + + return $s; + } + + + /* + This script identifies the longest running SQL + */ + function _SuspiciousSQL($numsql = 10) + { + global $ADODB_FETCH_MODE; + + $perf_table = adodb_perf::table(); + $saveE = $this->conn->fnExecute; + $this->conn->fnExecute = false; + + if (isset($_GET['exps']) && isset($_GET['sql'])) { + $partial = !empty($_GET['part']); + echo "".$this->Explain($_GET['sql'],$partial)."\n"; + } + + if (isset($_GET['sql'])) return; + $sql1 = $this->sql1; + + $save = $ADODB_FETCH_MODE; + $ADODB_FETCH_MODE = ADODB_FETCH_NUM; + if ($this->conn->fetchMode !== false) $savem = $this->conn->SetFetchMode(false); + //$this->conn->debug=1; + $rs =& $this->conn->SelectLimit( + "select avg(timer) as avg_timer,$sql1,count(*),max(timer) as max_timer,min(timer) as min_timer + from $perf_table + where {$this->conn->upperCase}({$this->conn->substr}(sql0,1,5)) not in ('DROP ','INSER','COMMI','CREAT') + and (tracer is null or tracer not like 'ERROR:%') + group by sql1 + order by 1 desc",$numsql); + if (isset($savem)) $this->conn->SetFetchMode($savem); + $ADODB_FETCH_MODE = $save; + $this->conn->fnExecute = $saveE; + + if (!$rs) return "

    $this->helpurl. ".$this->conn->ErrorMsg()."

    "; + $s = "

    Suspicious SQL

    +The following SQL have high average execution times
    +
    ParameterValueDescription
    \n"; + $max = $this->maxLength; + while (!$rs->EOF) { + $sql = $rs->fields[1]; + $raw = urlencode($sql); + if (strlen($raw)>$max-100) { + $sql2 = substr($sql,0,$max-500); + $raw = urlencode($sql2).'&part='.crc32($sql); + } + $prefix = ""; + $suffix = ""; + if ($this->explain == false || strlen($prefix)>$max) { + $suffix = ' ... String too long for GET parameter: '.strlen($prefix).''; + $prefix = ''; + } + $s .= ""; + $rs->MoveNext(); + } + return $s."
    Avg TimeCountSQLMaxMin
    ".adodb_round($rs->fields[0],6)."".$rs->fields[2]."".$prefix.htmlspecialchars($sql).$suffix."". + "".$rs->fields[3]."".$rs->fields[4]."
    "; + + } + + function CheckMemory() + { + return ''; + } + + + function SuspiciousSQL($numsql=10) + { + return adodb_perf::_SuspiciousSQL($numsql); + } + + function ExpensiveSQL($numsql=10) + { + return adodb_perf::_ExpensiveSQL($numsql); + } + + + /* + This reports the percentage of load on the instance due to the most + expensive few SQL statements. Tuning these statements can often + make huge improvements in overall system performance. + */ + function _ExpensiveSQL($numsql = 10) + { + global $ADODB_FETCH_MODE; + + $perf_table = adodb_perf::table(); + $saveE = $this->conn->fnExecute; + $this->conn->fnExecute = false; + + if (isset($_GET['expe']) && isset($_GET['sql'])) { + $partial = !empty($_GET['part']); + echo "".$this->Explain($_GET['sql'],$partial)."\n"; + } + + if (isset($_GET['sql'])) return; + + $sql1 = $this->sql1; + $save = $ADODB_FETCH_MODE; + $ADODB_FETCH_MODE = ADODB_FETCH_NUM; + if ($this->conn->fetchMode !== false) $savem = $this->conn->SetFetchMode(false); + + $rs =& $this->conn->SelectLimit( + "select sum(timer) as total,$sql1,count(*),max(timer) as max_timer,min(timer) as min_timer + from $perf_table + where {$this->conn->upperCase}({$this->conn->substr}(sql0,1,5)) not in ('DROP ','INSER','COMMI','CREAT') + and (tracer is null or tracer not like 'ERROR:%') + group by sql1 + having count(*)>1 + order by 1 desc",$numsql); + if (isset($savem)) $this->conn->SetFetchMode($savem); + $this->conn->fnExecute = $saveE; + $ADODB_FETCH_MODE = $save; + if (!$rs) return "

    $this->helpurl. ".$this->conn->ErrorMsg()."

    "; + $s = "

    Expensive SQL

    +Tuning the following SQL could reduce the server load substantially
    +\n"; + $max = $this->maxLength; + while (!$rs->EOF) { + $sql = $rs->fields[1]; + $raw = urlencode($sql); + if (strlen($raw)>$max-100) { + $sql2 = substr($sql,0,$max-500); + $raw = urlencode($sql2).'&part='.crc32($sql); + } + $prefix = ""; + $suffix = ""; + if($this->explain == false || strlen($prefix>$max)) { + $prefix = ''; + $suffix = ''; + } + $s .= ""; + $rs->MoveNext(); + } + return $s."
    LoadCountSQLMaxMin
    ".adodb_round($rs->fields[0],6)."".$rs->fields[2]."".$prefix.htmlspecialchars($sql).$suffix."". + "".$rs->fields[3]."".$rs->fields[4]."
    "; + } + + /* + Raw function to return parameter value from $settings. + */ + function DBParameter($param) + { + if (empty($this->settings[$param])) return false; + $sql = $this->settings[$param][1]; + return $this->_DBParameter($sql); + } + + /* + Raw function returning array of poll paramters + */ + function &PollParameters() + { + $arr[0] = (float)$this->DBParameter('data cache hit ratio'); + $arr[1] = (float)$this->DBParameter('data reads'); + $arr[2] = (float)$this->DBParameter('data writes'); + $arr[3] = (integer) $this->DBParameter('current connections'); + return $arr; + } + + /* + Low-level Get Database Parameter + */ + function _DBParameter($sql) + { + $savelog = $this->conn->LogSQL(false); + if (is_array($sql)) { + global $ADODB_FETCH_MODE; + + $sql1 = $sql[0]; + $key = $sql[1]; + if (sizeof($sql)>2) $pos = $sql[2]; + else $pos = 1; + if (sizeof($sql)>3) $coef = $sql[3]; + else $coef = false; + $ret = false; + $save = $ADODB_FETCH_MODE; + $ADODB_FETCH_MODE = ADODB_FETCH_NUM; + if ($this->conn->fetchMode !== false) $savem = $this->conn->SetFetchMode(false); + + $rs = $this->conn->Execute($sql1); + + if (isset($savem)) $this->conn->SetFetchMode($savem); + $ADODB_FETCH_MODE = $save; + if ($rs) { + while (!$rs->EOF) { + $keyf = reset($rs->fields); + if (trim($keyf) == $key) { + $ret = $rs->fields[$pos]; + if ($coef) $ret *= $coef; + break; + } + $rs->MoveNext(); + } + $rs->Close(); + } + $this->conn->LogSQL($savelog); + return $ret; + } else { + if (strncmp($sql,'=',1) == 0) { + $fn = substr($sql,1); + return $this->$fn(); + } + $sql = str_replace('$DATABASE',$this->conn->database,$sql); + $ret = $this->conn->GetOne($sql); + $this->conn->LogSQL($savelog); + + return $ret; + } + } + + /* + Warn if cache ratio falls below threshold. Displayed in "Description" column. + */ + function WarnCacheRatio($val) + { + if ($val < $this->warnRatio) + return 'Cache ratio should be at least '.$this->warnRatio.'%'; + else return ''; + } + + function clearsql() + { + $perf_table = adodb_perf::table(); + $this->conn->Execute("delete from $perf_table where created<".$this->conn->sysTimeStamp); + } + + /***********************************************************************************************/ + // HIGH LEVEL UI FUNCTIONS + /***********************************************************************************************/ + + + function UI($pollsecs=5) + { + global $ADODB_LOG_CONN; + + $perf_table = adodb_perf::table(); + $conn = $this->conn; + + $app = $conn->host; + if ($conn->host && $conn->database) $app .= ', db='; + $app .= $conn->database; + + if ($app) $app .= ', '; + $savelog = $this->conn->LogSQL(false); + $info = $conn->ServerInfo(); + if (isset($_GET['clearsql'])) { + $this->clearsql(); + } + $this->conn->LogSQL($savelog); + + // magic quotes + + if (isset($_GET['sql']) && get_magic_quotes_gpc()) { + $_GET['sql'] = $_GET['sql'] = str_replace(array("\\'",'\"'),array("'",'"'),$_GET['sql']); + } + + if (!isset($_SESSION['ADODB_PERF_SQL'])) $nsql = $_SESSION['ADODB_PERF_SQL'] = 10; + else $nsql = $_SESSION['ADODB_PERF_SQL']; + + $app .= $info['description']; + + + if (isset($_GET['do'])) $do = $_GET['do']; + else if (isset($_POST['do'])) $do = $_POST['do']; + else if (isset($_GET['sql'])) $do = 'viewsql'; + else $do = 'stats'; + + if (isset($_GET['nsql'])) { + if ($_GET['nsql'] > 0) $nsql = $_SESSION['ADODB_PERF_SQL'] = (integer) $_GET['nsql']; + } + echo "ADOdb Performance Monitor on $app"; + if ($do == 'viewsql') $form = "
    # SQL:
     
    + ADOdb Performance Monitor for $app
    + Performance Stats   View SQL +   View Tables   Poll Stats", + $allowsql ? '   Run SQL' : '', + "$form", + "
    "; + + + switch ($do) { + default: + case 'stats': + + if (empty($ADODB_LOG_CONN)) + echo "

      Clear SQL Log
    "; + echo $this->HealthCheck(); + //$this->conn->debug=1; + echo $this->CheckMemory(); + global $ADODB_LOG_CONN; + break; + case 'poll': + echo ""; + break; + case 'poll2': + echo "

    ";
    +			$this->Poll($pollsecs);
    +			break;
    +		
    +		case 'dosql':
    +			if (!$allowsql) break;
    +			
    +			$this->DoSQLForm();
    +			break;
    +		case 'viewsql':
    +			if (empty($_GET['hidem']))
    +				echo "  Clear SQL Log
    "; + echo($this->SuspiciousSQL($nsql)); + echo($this->ExpensiveSQL($nsql)); + echo($this->InvalidSQL($nsql)); + break; + case 'tables': + echo $this->Tables(); break; + } + global $ADODB_vers; + echo "

    $ADODB_vers Sponsored by phpLens
    "; + } + + /* + Runs in infinite loop, returning real-time statistics + */ + function Poll($secs=5) + { + $this->conn->fnExecute = false; + //$this->conn->debug=1; + if ($secs <= 1) $secs = 1; + echo "Accumulating statistics, every $secs seconds...\n";flush(); + $arro =& $this->PollParameters(); + $cnt = 0; + set_time_limit(0); + sleep($secs); + while (1) { + + $arr =& $this->PollParameters(); + + $hits = sprintf('%2.2f',$arr[0]); + $reads = sprintf('%12.4f',($arr[1]-$arro[1])/$secs); + $writes = sprintf('%12.4f',($arr[2]-$arro[2])/$secs); + $sess = sprintf('%5d',$arr[3]); + + $load = $this->CPULoad(); + if ($load !== false) { + $oslabel = 'WS-CPU%'; + $osval = sprintf(" %2.1f ",(float) $load); + }else { + $oslabel = ''; + $osval = ''; + } + if ($cnt % 10 == 0) echo " Time ".$oslabel." Hit% Sess Reads/s Writes/s\n"; + $cnt += 1; + echo date('H:i:s').' '.$osval."$hits $sess $reads $writes\n"; + flush(); + + if (connection_aborted()) return; + + sleep($secs); + $arro = $arr; + } + } + + /* + Returns basic health check in a command line interface + */ + function HealthCheckCLI() + { + return $this->HealthCheck(true); + } + + + /* + Returns basic health check as HTML + */ + function HealthCheck($cli=false) + { + $saveE = $this->conn->fnExecute; + $this->conn->fnExecute = false; + if ($cli) $html = ''; + else $html = $this->table.'

    '.$this->conn->databaseType.'

    '.$this->titles; + + $oldc = false; + $bgc = ''; + foreach($this->settings as $name => $arr) { + if ($arr === false) break; + + if (!is_string($name)) { + if ($cli) $html .= " -- $arr -- \n"; + else $html .= "color>$arr  "; + continue; + } + + if (!is_array($arr)) break; + $category = $arr[0]; + $how = $arr[1]; + if (sizeof($arr)>2) $desc = $arr[2]; + else $desc = '   '; + + + if ($category == 'HIDE') continue; + + $val = $this->_DBParameter($how); + + if ($desc && strncmp($desc,"=",1) === 0) { + $fn = substr($desc,1); + $desc = $this->$fn($val); + } + + if ($val === false) { + $m = $this->conn->ErrorMsg(); + $val = "Error: $m"; + } else { + if (is_numeric($val) && $val >= 256*1024) { + if ($val % (1024*1024) == 0) { + $val /= (1024*1024); + $val .= 'M'; + } else if ($val % 1024 == 0) { + $val /= 1024; + $val .= 'K'; + } + //$val = htmlspecialchars($val); + } + } + if ($category != $oldc) { + $oldc = $category; + //$bgc = ($bgc == ' bgcolor='.$this->color) ? ' bgcolor=white' : ' bgcolor='.$this->color; + } + if (strlen($desc)==0) $desc = ' '; + if (strlen($val)==0) $val = ' '; + if ($cli) { + $html .= str_replace(' ','',sprintf($this->cliFormat,strip_tags($name),strip_tags($val),strip_tags($desc))); + + }else { + $html .= "".$name.''.$val.''.$desc."\n"; + } + } + + if (!$cli) $html .= "\n"; + $this->conn->fnExecute = $saveE; + + return $html; + } + + function Tables($orderby='1') + { + if (!$this->tablesSQL) return false; + + $savelog = $this->conn->LogSQL(false); + $rs = $this->conn->Execute($this->tablesSQL.' order by '.$orderby); + $this->conn->LogSQL($savelog); + $html = rs2html($rs,false,false,false,false); + return $html; + } + + + function CreateLogTable() + { + if (!$this->createTableSQL) return false; + + $table = $this->table(); + $sql = str_replace('adodb_logsql',$table,$this->createTableSQL); + $savelog = $this->conn->LogSQL(false); + $ok = $this->conn->Execute($sql); + $this->conn->LogSQL($savelog); + return ($ok) ? true : false; + } + + function DoSQLForm() + { + + + $PHP_SELF = $_SERVER['PHP_SELF']; + $sql = isset($_REQUEST['sql']) ? $_REQUEST['sql'] : ''; + + if (isset($_SESSION['phplens_sqlrows'])) $rows = $_SESSION['phplens_sqlrows']; + else $rows = 3; + + if (isset($_REQUEST['SMALLER'])) { + $rows /= 2; + if ($rows < 3) $rows = 3; + $_SESSION['phplens_sqlrows'] = $rows; + } + if (isset($_REQUEST['BIGGER'])) { + $rows *= 2; + $_SESSION['phplens_sqlrows'] = $rows; + } + +?> + +
    + + + + + + +
    Form size: + + +
    +
    +
    + +undomq(trim($sql)); + if (substr($sql,strlen($sql)-1) === ';') { + $print = true; + $sqla = $this->SplitSQL($sql); + } else { + $print = false; + $sqla = array($sql); + } + foreach($sqla as $sqls) { + + if (!$sqls) continue; + + if ($print) { + print "

    ".htmlspecialchars($sqls)."

    "; + flush(); + } + $savelog = $this->conn->LogSQL(false); + $rs = $this->conn->Execute($sqls); + $this->conn->LogSQL($savelog); + if ($rs && is_object($rs) && !$rs->EOF) { + rs2html($rs); + while ($rs->NextRecordSet()) { + print "
     
    "; + rs2html($rs); + } + } else { + $e1 = (integer) $this->conn->ErrorNo(); + $e2 = $this->conn->ErrorMsg(); + if (($e1) || ($e2)) { + if (empty($e1)) $e1 = '-1'; // postgresql fix + print '   '.$e1.': '.$e2; + } else { + print "

    No Recordset returned

    "; + } + } + } // foreach + } + + function SplitSQL($sql) + { + $arr = explode(';',$sql); + return $arr; + } + + function undomq($m) + { + if (get_magic_quotes_gpc()) { + // undo the damage + $m = str_replace('\\\\','\\',$m); + $m = str_replace('\"','"',$m); + $m = str_replace('\\\'','\'',$m); + } + return $m; +} + + + /************************************************************************/ + + /** + * Reorganise multiple table-indices/statistics/.. + * OptimizeMode could be given by last Parameter + * + * @example + *
    +     *          optimizeTables( 'tableA');
    +     *      
    + *
    +     *          optimizeTables( 'tableA', 'tableB', 'tableC');
    +     *      
    + *
    +     *          optimizeTables( 'tableA', 'tableB', ADODB_OPT_LOW);
    +     *      
    + * + * @param string table name of the table to optimize + * @param int mode optimization-mode + * ADODB_OPT_HIGH for full optimization + * ADODB_OPT_LOW for CPU-less optimization + * Default is LOW ADODB_OPT_LOW + * @author Markus Staab + * @return Returns true on success and false on error + */ + function OptimizeTables() + { + $args = func_get_args(); + $numArgs = func_num_args(); + + if ( $numArgs == 0) return false; + + $mode = ADODB_OPT_LOW; + $lastArg = $args[ $numArgs - 1]; + if ( !is_string($lastArg)) { + $mode = $lastArg; + unset( $args[ $numArgs - 1]); + } + + foreach( $args as $table) { + $this->optimizeTable( $table, $mode); + } + } + + /** + * Reorganise the table-indices/statistics/.. depending on the given mode. + * Default Implementation throws an error. + * + * @param string table name of the table to optimize + * @param int mode optimization-mode + * ADODB_OPT_HIGH for full optimization + * ADODB_OPT_LOW for CPU-less optimization + * Default is LOW ADODB_OPT_LOW + * @author Markus Staab + * @return Returns true on success and false on error + */ + function OptimizeTable( $table, $mode = ADODB_OPT_LOW) + { + ADOConnection::outp( sprintf( "

    %s: '%s' not implemented for driver '%s'

    ", __CLASS__, __FUNCTION__, $this->conn->databaseType)); + return false; + } + + /** + * Reorganise current database. + * Default implementation loops over all MetaTables() and + * optimize each using optmizeTable() + * + * @author Markus Staab + * @return Returns true on success and false on error + */ + function optimizeDatabase() + { + $conn = $this->conn; + if ( !$conn) return false; + + $tables = $conn->MetaTables( 'TABLES'); + if ( !$tables ) return false; + + foreach( $tables as $table) { + if ( !$this->optimizeTable( $table)) { + return false; + } + } + + return true; + } + // end hack +} + +?> \ No newline at end of file diff --git a/upload/includes/adodb/adodb-php4.inc.php b/upload/includes/adodb/adodb-php4.inc.php new file mode 100644 index 00000000..9547027c --- /dev/null +++ b/upload/includes/adodb/adodb-php4.inc.php @@ -0,0 +1,16 @@ + \ No newline at end of file diff --git a/upload/includes/adodb/adodb-time.inc.php b/upload/includes/adodb/adodb-time.inc.php new file mode 100644 index 00000000..e0a6a5de --- /dev/null +++ b/upload/includes/adodb/adodb-time.inc.php @@ -0,0 +1,1409 @@ + 4 digit year conversion. The maximum is billions of years in the +future, but this is a theoretical limit as the computation of that year +would take too long with the current implementation of adodb_mktime(). + +This library replaces native functions as follows: + +
    	
    +	getdate()  with  adodb_getdate()
    +	date()     with  adodb_date() 
    +	gmdate()   with  adodb_gmdate()
    +	mktime()   with  adodb_mktime()
    +	gmmktime() with  adodb_gmmktime()
    +	strftime() with  adodb_strftime()
    +	strftime() with  adodb_gmstrftime()
    +
    + +The parameters are identical, except that adodb_date() accepts a subset +of date()'s field formats. Mktime() will convert from local time to GMT, +and date() will convert from GMT to local time, but daylight savings is +not handled currently. + +This library is independant of the rest of ADOdb, and can be used +as standalone code. + +PERFORMANCE + +For high speed, this library uses the native date functions where +possible, and only switches to PHP code when the dates fall outside +the 32-bit signed integer range. + +GREGORIAN CORRECTION + +Pope Gregory shortened October of A.D. 1582 by ten days. Thursday, +October 4, 1582 (Julian) was followed immediately by Friday, October 15, +1582 (Gregorian). + +Since 0.06, we handle this correctly, so: + +adodb_mktime(0,0,0,10,15,1582) - adodb_mktime(0,0,0,10,4,1582) + == 24 * 3600 (1 day) + +============================================================================= + +COPYRIGHT + +(c) 2003-2005 John Lim and released under BSD-style license except for code by +jackbbs, which includes adodb_mktime, adodb_get_gmt_diff, adodb_is_leap_year +and originally found at http://www.php.net/manual/en/function.mktime.php + +============================================================================= + +BUG REPORTS + +These should be posted to the ADOdb forums at + + http://phplens.com/lens/lensforum/topics.php?id=4 + +============================================================================= + +FUNCTION DESCRIPTIONS + + +** FUNCTION adodb_getdate($date=false) + +Returns an array containing date information, as getdate(), but supports +dates greater than 1901 to 2038. The local date/time format is derived from a +heuristic the first time adodb_getdate is called. + + +** FUNCTION adodb_date($fmt, $timestamp = false) + +Convert a timestamp to a formatted local date. If $timestamp is not defined, the +current timestamp is used. Unlike the function date(), it supports dates +outside the 1901 to 2038 range. + +The format fields that adodb_date supports: + +
    +	a - "am" or "pm" 
    +	A - "AM" or "PM" 
    +	d - day of the month, 2 digits with leading zeros; i.e. "01" to "31" 
    +	D - day of the week, textual, 3 letters; e.g. "Fri" 
    +	F - month, textual, long; e.g. "January" 
    +	g - hour, 12-hour format without leading zeros; i.e. "1" to "12" 
    +	G - hour, 24-hour format without leading zeros; i.e. "0" to "23" 
    +	h - hour, 12-hour format; i.e. "01" to "12" 
    +	H - hour, 24-hour format; i.e. "00" to "23" 
    +	i - minutes; i.e. "00" to "59" 
    +	j - day of the month without leading zeros; i.e. "1" to "31" 
    +	l (lowercase 'L') - day of the week, textual, long; e.g. "Friday"  
    +	L - boolean for whether it is a leap year; i.e. "0" or "1" 
    +	m - month; i.e. "01" to "12" 
    +	M - month, textual, 3 letters; e.g. "Jan" 
    +	n - month without leading zeros; i.e. "1" to "12" 
    +	O - Difference to Greenwich time in hours; e.g. "+0200" 
    +	Q - Quarter, as in 1, 2, 3, 4 
    +	r - RFC 2822 formatted date; e.g. "Thu, 21 Dec 2000 16:01:07 +0200" 
    +	s - seconds; i.e. "00" to "59" 
    +	S - English ordinal suffix for the day of the month, 2 characters; 
    +	   			i.e. "st", "nd", "rd" or "th" 
    +	t - number of days in the given month; i.e. "28" to "31"
    +	T - Timezone setting of this machine; e.g. "EST" or "MDT" 
    +	U - seconds since the Unix Epoch (January 1 1970 00:00:00 GMT)  
    +	w - day of the week, numeric, i.e. "0" (Sunday) to "6" (Saturday) 
    +	Y - year, 4 digits; e.g. "1999" 
    +	y - year, 2 digits; e.g. "99" 
    +	z - day of the year; i.e. "0" to "365" 
    +	Z - timezone offset in seconds (i.e. "-43200" to "43200"). 
    +	   			The offset for timezones west of UTC is always negative, 
    +				and for those east of UTC is always positive. 
    +
    + +Unsupported: +
    +	B - Swatch Internet time 
    +	I (capital i) - "1" if Daylight Savings Time, "0" otherwise.
    +	W - ISO-8601 week number of year, weeks starting on Monday 
    +
    +
    + + +** FUNCTION adodb_date2($fmt, $isoDateString = false) +Same as adodb_date, but 2nd parameter accepts iso date, eg. + + adodb_date2('d-M-Y H:i','2003-12-25 13:01:34'); + + +** FUNCTION adodb_gmdate($fmt, $timestamp = false) + +Convert a timestamp to a formatted GMT date. If $timestamp is not defined, the +current timestamp is used. Unlike the function date(), it supports dates +outside the 1901 to 2038 range. + + +** FUNCTION adodb_mktime($hr, $min, $sec[, $month, $day, $year]) + +Converts a local date to a unix timestamp. Unlike the function mktime(), it supports +dates outside the 1901 to 2038 range. All parameters are optional. + + +** FUNCTION adodb_gmmktime($hr, $min, $sec [, $month, $day, $year]) + +Converts a gmt date to a unix timestamp. Unlike the function gmmktime(), it supports +dates outside the 1901 to 2038 range. Differs from gmmktime() in that all parameters +are currently compulsory. + +** FUNCTION adodb_gmstrftime($fmt, $timestamp = false) +Convert a timestamp to a formatted GMT date. + +** FUNCTION adodb_strftime($fmt, $timestamp = false) + +Convert a timestamp to a formatted local date. Internally converts $fmt into +adodb_date format, then echo result. + +For best results, you can define the local date format yourself. Define a global +variable $ADODB_DATE_LOCALE which is an array, 1st element is date format using +adodb_date syntax, and 2nd element is the time format, also in adodb_date syntax. + + eg. $ADODB_DATE_LOCALE = array('d/m/Y','H:i:s'); + + Supported format codes: + +
    +	%a - abbreviated weekday name according to the current locale 
    +	%A - full weekday name according to the current locale 
    +	%b - abbreviated month name according to the current locale 
    +	%B - full month name according to the current locale 
    +	%c - preferred date and time representation for the current locale 
    +	%d - day of the month as a decimal number (range 01 to 31) 
    +	%D - same as %m/%d/%y 
    +	%e - day of the month as a decimal number, a single digit is preceded by a space (range ' 1' to '31') 
    +	%h - same as %b
    +	%H - hour as a decimal number using a 24-hour clock (range 00 to 23) 
    +	%I - hour as a decimal number using a 12-hour clock (range 01 to 12) 
    +	%m - month as a decimal number (range 01 to 12) 
    +	%M - minute as a decimal number 
    +	%n - newline character 
    +	%p - either `am' or `pm' according to the given time value, or the corresponding strings for the current locale 
    +	%r - time in a.m. and p.m. notation 
    +	%R - time in 24 hour notation 
    +	%S - second as a decimal number 
    +	%t - tab character 
    +	%T - current time, equal to %H:%M:%S 
    +	%x - preferred date representation for the current locale without the time 
    +	%X - preferred time representation for the current locale without the date 
    +	%y - year as a decimal number without a century (range 00 to 99) 
    +	%Y - year as a decimal number including the century 
    +	%Z - time zone or name or abbreviation 
    +	%% - a literal `%' character 
    +
    + + Unsupported codes: +
    +	%C - century number (the year divided by 100 and truncated to an integer, range 00 to 99) 
    +	%g - like %G, but without the century. 
    +	%G - The 4-digit year corresponding to the ISO week number (see %V). 
    +	     This has the same format and value as %Y, except that if the ISO week number belongs 
    +		 to the previous or next year, that year is used instead. 
    +	%j - day of the year as a decimal number (range 001 to 366) 
    +	%u - weekday as a decimal number [1,7], with 1 representing Monday 
    +	%U - week number of the current year as a decimal number, starting 
    +	    with the first Sunday as the first day of the first week 
    +	%V - The ISO 8601:1988 week number of the current year as a decimal number, 
    +	     range 01 to 53, where week 1 is the first week that has at least 4 days in the 
    +		 current year, and with Monday as the first day of the week. (Use %G or %g for 
    +		 the year component that corresponds to the week number for the specified timestamp.) 
    +	%w - day of the week as a decimal, Sunday being 0 
    +	%W - week number of the current year as a decimal number, starting with the 
    +	     first Monday as the first day of the first week 
    +
    + +============================================================================= + +NOTES + +Useful url for generating test timestamps: + http://www.4webhelp.net/us/timestamp.php + +Possible future optimizations include + +a. Using an algorithm similar to Plauger's in "The Standard C Library" +(page 428, xttotm.c _Ttotm() function). Plauger's algorithm will not +work outside 32-bit signed range, so i decided not to implement it. + +b. Implement daylight savings, which looks awfully complicated, see + http://webexhibits.org/daylightsaving/ + + +CHANGELOG +- 15 July 2007 0.30 +Added PHP 5.2.0 compatability fixes. + * gmtime behaviour for 1970 has changed. We use the actual date if it is between 1970 to 2038 to get the + * timezone, otherwise we use the current year as the baseline to retrieve the timezone. + * Also the timezone's in php 5.2.* support historical data better, eg. if timezone today was +8, but + in 1970 it was +7:30, then php 5.2 return +7:30, while this library will use +8. + * + +- 19 March 2006 0.24 +Changed strftime() locale detection, because some locales prepend the day of week to the date when %c is used. + +- 10 Feb 2006 0.23 +PHP5 compat: when we detect PHP5, the RFC2822 format for gmt 0000hrs is changed from -0000 to +0000. + In PHP4, we will still use -0000 for 100% compat with PHP4. + +- 08 Sept 2005 0.22 +In adodb_date2(), $is_gmt not supported properly. Fixed. + +- 18 July 2005 0.21 +In PHP 4.3.11, the 'r' format has changed. Leading 0 in day is added. Changed for compat. +Added support for negative months in adodb_mktime(). + +- 24 Feb 2005 0.20 +Added limited strftime/gmstrftime support. x10 improvement in performance of adodb_date(). + +- 21 Dec 2004 0.17 +In adodb_getdate(), the timestamp was accidentally converted to gmt when $is_gmt is false. +Also adodb_mktime(0,0,0) did not work properly. Both fixed thx Mauro. + +- 17 Nov 2004 0.16 +Removed intval typecast in adodb_mktime() for secs, allowing: + adodb_mktime(0,0,0 + 2236672153,1,1,1934); +Suggested by Ryan. + +- 18 July 2004 0.15 +All params in adodb_mktime were formerly compulsory. Now only the hour, min, secs is compulsory. +This brings it more in line with mktime (still not identical). + +- 23 June 2004 0.14 + +Allow you to define your own daylights savings function, adodb_daylight_sv. +If the function is defined (somewhere in an include), then you can correct for daylights savings. + +In this example, we apply daylights savings in June or July, adding one hour. This is extremely +unrealistic as it does not take into account time-zone, geographic location, current year. + +function adodb_daylight_sv(&$arr, $is_gmt) +{ + if ($is_gmt) return; + $m = $arr['mon']; + if ($m == 6 || $m == 7) $arr['hours'] += 1; +} + +This is only called by adodb_date() and not by adodb_mktime(). + +The format of $arr is +Array ( + [seconds] => 0 + [minutes] => 0 + [hours] => 0 + [mday] => 1 # day of month, eg 1st day of the month + [mon] => 2 # month (eg. Feb) + [year] => 2102 + [yday] => 31 # days in current year + [leap] => # true if leap year + [ndays] => 28 # no of days in current month + ) + + +- 28 Apr 2004 0.13 +Fixed adodb_date to properly support $is_gmt. Thx to Dimitar Angelov. + +- 20 Mar 2004 0.12 +Fixed month calculation error in adodb_date. 2102-June-01 appeared as 2102-May-32. + +- 26 Oct 2003 0.11 +Because of daylight savings problems (some systems apply daylight savings to +January!!!), changed adodb_get_gmt_diff() to ignore daylight savings. + +- 9 Aug 2003 0.10 +Fixed bug with dates after 2038. +See http://phplens.com/lens/lensforum/msgs.php?id=6980 + +- 1 July 2003 0.09 +Added support for Q (Quarter). +Added adodb_date2(), which accepts ISO date in 2nd param + +- 3 March 2003 0.08 +Added support for 'S' adodb_date() format char. Added constant ADODB_ALLOW_NEGATIVE_TS +if you want PHP to handle negative timestamps between 1901 to 1969. + +- 27 Feb 2003 0.07 +All negative numbers handled by adodb now because of RH 7.3+ problems. +See http://bugs.php.net/bug.php?id=20048&edit=2 + +- 4 Feb 2003 0.06 +Fixed a typo, 1852 changed to 1582! This means that pre-1852 dates +are now correctly handled. + +- 29 Jan 2003 0.05 + +Leap year checking differs under Julian calendar (pre 1582). Also +leap year code optimized by checking for most common case first. + +We also handle month overflow correctly in mktime (eg month set to 13). + +Day overflow for less than one month's days is supported. + +- 28 Jan 2003 0.04 + +Gregorian correction handled. In PHP5, we might throw an error if +mktime uses invalid dates around 5-14 Oct 1582. Released with ADOdb 3.10. +Added limbo 5-14 Oct 1582 check, when we set to 15 Oct 1582. + +- 27 Jan 2003 0.03 + +Fixed some more month problems due to gmt issues. Added constant ADODB_DATE_VERSION. +Fixed calculation of days since start of year for <1970. + +- 27 Jan 2003 0.02 + +Changed _adodb_getdate() to inline leap year checking for better performance. +Fixed problem with time-zones west of GMT +0000. + +- 24 Jan 2003 0.01 + +First implementation. +*/ + + +/* Initialization */ + +/* + Version Number +*/ +define('ADODB_DATE_VERSION',0.30); + +$ADODB_DATETIME_CLASS = (PHP_VERSION >= 5.2); + +/* + This code was originally for windows. But apparently this problem happens + also with Linux, RH 7.3 and later! + + glibc-2.2.5-34 and greater has been changed to return -1 for dates < + 1970. This used to work. The problem exists with RedHat 7.3 and 8.0 + echo (mktime(0, 0, 0, 1, 1, 1960)); // prints -1 + + References: + http://bugs.php.net/bug.php?id=20048&edit=2 + http://lists.debian.org/debian-glibc/2002/debian-glibc-200205/msg00010.html +*/ + +if (!defined('ADODB_ALLOW_NEGATIVE_TS')) define('ADODB_NO_NEGATIVE_TS',1); + +function adodb_date_test_date($y1,$m,$d=13) +{ + $h = round(rand()% 24); + $t = adodb_mktime($h,0,0,$m,$d,$y1); + $rez = adodb_date('Y-n-j H:i:s',$t); + if ($h == 0) $h = '00'; + else if ($h < 10) $h = '0'.$h; + if ("$y1-$m-$d $h:00:00" != $rez) { + print "$y1 error, expected=$y1-$m-$d $h:00:00, adodb=$rez
    "; + return false; + } + return true; +} + +function adodb_date_test_strftime($fmt) +{ + $s1 = strftime($fmt); + $s2 = adodb_strftime($fmt); + + if ($s1 == $s2) return true; + + echo "error for $fmt, strftime=$s1, adodb=$s2
    "; + return false; +} + +/** + Test Suite +*/ +function adodb_date_test() +{ + + error_reporting(E_ALL); + print "

    Testing adodb_date and adodb_mktime. version=".ADODB_DATE_VERSION.' PHP='.PHP_VERSION."

    "; + @set_time_limit(0); + $fail = false; + + // This flag disables calling of PHP native functions, so we can properly test the code + if (!defined('ADODB_TEST_DATES')) define('ADODB_TEST_DATES',1); + + $t = time(); + + + $fmt = 'Y-m-d H:i:s'; + echo '
    ';
    +	echo 'adodb: ',adodb_date($fmt,$t),'
    '; + echo 'php : ',date($fmt,$t),'
    '; + echo '
    '; + + adodb_date_test_strftime('%Y %m %x %X'); + adodb_date_test_strftime("%A %d %B %Y"); + adodb_date_test_strftime("%H %M S"); + + $t = adodb_mktime(0,0,0); + if (!(adodb_date('Y-m-d') == date('Y-m-d'))) print 'Error in '.adodb_mktime(0,0,0).'
    '; + + $t = adodb_mktime(0,0,0,6,1,2102); + if (!(adodb_date('Y-m-d',$t) == '2102-06-01')) print 'Error in '.adodb_date('Y-m-d',$t).'
    '; + + $t = adodb_mktime(0,0,0,2,1,2102); + if (!(adodb_date('Y-m-d',$t) == '2102-02-01')) print 'Error in '.adodb_date('Y-m-d',$t).'
    '; + + + print "

    Testing gregorian <=> julian conversion

    "; + $t = adodb_mktime(0,0,0,10,11,1492); + //http://www.holidayorigins.com/html/columbus_day.html - Friday check + if (!(adodb_date('D Y-m-d',$t) == 'Fri 1492-10-11')) print 'Error in Columbus landing
    '; + + $t = adodb_mktime(0,0,0,2,29,1500); + if (!(adodb_date('Y-m-d',$t) == '1500-02-29')) print 'Error in julian leap years
    '; + + $t = adodb_mktime(0,0,0,2,29,1700); + if (!(adodb_date('Y-m-d',$t) == '1700-03-01')) print 'Error in gregorian leap years
    '; + + print adodb_mktime(0,0,0,10,4,1582).' '; + print adodb_mktime(0,0,0,10,15,1582); + $diff = (adodb_mktime(0,0,0,10,15,1582) - adodb_mktime(0,0,0,10,4,1582)); + if ($diff != 3600*24) print " Error in gregorian correction = ".($diff/3600/24)." days
    "; + + print " 15 Oct 1582, Fri=".(adodb_dow(1582,10,15) == 5 ? 'Fri' : 'Error')."
    "; + print " 4 Oct 1582, Thu=".(adodb_dow(1582,10,4) == 4 ? 'Thu' : 'Error')."
    "; + + print "

    Testing overflow

    "; + + $t = adodb_mktime(0,0,0,3,33,1965); + if (!(adodb_date('Y-m-d',$t) == '1965-04-02')) print 'Error in day overflow 1
    '; + $t = adodb_mktime(0,0,0,4,33,1971); + if (!(adodb_date('Y-m-d',$t) == '1971-05-03')) print 'Error in day overflow 2
    '; + $t = adodb_mktime(0,0,0,1,60,1965); + if (!(adodb_date('Y-m-d',$t) == '1965-03-01')) print 'Error in day overflow 3 '.adodb_date('Y-m-d',$t).'
    '; + $t = adodb_mktime(0,0,0,12,32,1965); + if (!(adodb_date('Y-m-d',$t) == '1966-01-01')) print 'Error in day overflow 4 '.adodb_date('Y-m-d',$t).'
    '; + $t = adodb_mktime(0,0,0,12,63,1965); + if (!(adodb_date('Y-m-d',$t) == '1966-02-01')) print 'Error in day overflow 5 '.adodb_date('Y-m-d',$t).'
    '; + $t = adodb_mktime(0,0,0,13,3,1965); + if (!(adodb_date('Y-m-d',$t) == '1966-01-03')) print 'Error in mth overflow 1
    '; + + print "Testing 2-digit => 4-digit year conversion

    "; + if (adodb_year_digit_check(00) != 2000) print "Err 2-digit 2000
    "; + if (adodb_year_digit_check(10) != 2010) print "Err 2-digit 2010
    "; + if (adodb_year_digit_check(20) != 2020) print "Err 2-digit 2020
    "; + if (adodb_year_digit_check(30) != 2030) print "Err 2-digit 2030
    "; + if (adodb_year_digit_check(40) != 1940) print "Err 2-digit 1940
    "; + if (adodb_year_digit_check(50) != 1950) print "Err 2-digit 1950
    "; + if (adodb_year_digit_check(90) != 1990) print "Err 2-digit 1990
    "; + + // Test string formating + print "

    Testing date formating

    "; + + $fmt = '\d\a\t\e T Y-m-d H:i:s a A d D F g G h H i j l L m M n O \R\F\C2822 r s t U w y Y z Z 2003'; + $s1 = date($fmt,0); + $s2 = adodb_date($fmt,0); + if ($s1 != $s2) { + print " date() 0 failed
    $s1
    $s2
    "; + } + flush(); + for ($i=100; --$i > 0; ) { + + $ts = 3600.0*((rand()%60000)+(rand()%60000))+(rand()%60000); + $s1 = date($fmt,$ts); + $s2 = adodb_date($fmt,$ts); + //print "$s1
    $s2

    "; + $pos = strcmp($s1,$s2); + + if (($s1) != ($s2)) { + for ($j=0,$k=strlen($s1); $j < $k; $j++) { + if ($s1[$j] != $s2[$j]) { + print substr($s1,$j).' '; + break; + } + } + print "Error date(): $ts

     
    +  \"$s1\" (date len=".strlen($s1).")
    +  \"$s2\" (adodb_date len=".strlen($s2).")

    "; + $fail = true; + } + + $a1 = getdate($ts); + $a2 = adodb_getdate($ts); + $rez = array_diff($a1,$a2); + if (sizeof($rez)>0) { + print "Error getdate() $ts
    "; + print_r($a1); + print "
    "; + print_r($a2); + print "

    "; + $fail = true; + } + } + + // Test generation of dates outside 1901-2038 + print "

    Testing random dates between 100 and 4000

    "; + adodb_date_test_date(100,1); + for ($i=100; --$i >= 0;) { + $y1 = 100+rand(0,1970-100); + $m = rand(1,12); + adodb_date_test_date($y1,$m); + + $y1 = 3000-rand(0,3000-1970); + adodb_date_test_date($y1,$m); + } + print '

    '; + $start = 1960+rand(0,10); + $yrs = 12; + $i = 365.25*86400*($start-1970); + $offset = 36000+rand(10000,60000); + $max = 365*$yrs*86400; + $lastyear = 0; + + // we generate a timestamp, convert it to a date, and convert it back to a timestamp + // and check if the roundtrip broke the original timestamp value. + print "Testing $start to ".($start+$yrs).", or $max seconds, offset=$offset: "; + $cnt = 0; + for ($max += $i; $i < $max; $i += $offset) { + $ret = adodb_date('m,d,Y,H,i,s',$i); + $arr = explode(',',$ret); + if ($lastyear != $arr[2]) { + $lastyear = $arr[2]; + print " $lastyear "; + flush(); + } + $newi = adodb_mktime($arr[3],$arr[4],$arr[5],$arr[0],$arr[1],$arr[2]); + if ($i != $newi) { + print "Error at $i, adodb_mktime returned $newi ($ret)"; + $fail = true; + break; + } + $cnt += 1; + } + echo "Tested $cnt dates
    "; + if (!$fail) print "

    Passed !

    "; + else print "

    Failed :-(

    "; +} + +/** + Returns day of week, 0 = Sunday,... 6=Saturday. + Algorithm from PEAR::Date_Calc +*/ +function adodb_dow($year, $month, $day) +{ +/* +Pope Gregory removed 10 days - October 5 to October 14 - from the year 1582 and +proclaimed that from that time onwards 3 days would be dropped from the calendar +every 400 years. + +Thursday, October 4, 1582 (Julian) was followed immediately by Friday, October 15, 1582 (Gregorian). +*/ + if ($year <= 1582) { + if ($year < 1582 || + ($year == 1582 && ($month < 10 || ($month == 10 && $day < 15)))) $greg_correction = 3; + else + $greg_correction = 0; + } else + $greg_correction = 0; + + if($month > 2) + $month -= 2; + else { + $month += 10; + $year--; + } + + $day = floor((13 * $month - 1) / 5) + + $day + ($year % 100) + + floor(($year % 100) / 4) + + floor(($year / 100) / 4) - 2 * + floor($year / 100) + 77 + $greg_correction; + + return $day - 7 * floor($day / 7); +} + + +/** + Checks for leap year, returns true if it is. No 2-digit year check. Also + handles julian calendar correctly. +*/ +function _adodb_is_leap_year($year) +{ + if ($year % 4 != 0) return false; + + if ($year % 400 == 0) { + return true; + // if gregorian calendar (>1582), century not-divisible by 400 is not leap + } else if ($year > 1582 && $year % 100 == 0 ) { + return false; + } + + return true; +} + + +/** + checks for leap year, returns true if it is. Has 2-digit year check +*/ +function adodb_is_leap_year($year) +{ + return _adodb_is_leap_year(adodb_year_digit_check($year)); +} + +/** + Fix 2-digit years. Works for any century. + Assumes that if 2-digit is more than 30 years in future, then previous century. +*/ +function adodb_year_digit_check($y) +{ + if ($y < 100) { + + $yr = (integer) date("Y"); + $century = (integer) ($yr /100); + + if ($yr%100 > 50) { + $c1 = $century + 1; + $c0 = $century; + } else { + $c1 = $century; + $c0 = $century - 1; + } + $c1 *= 100; + // if 2-digit year is less than 30 years in future, set it to this century + // otherwise if more than 30 years in future, then we set 2-digit year to the prev century. + if (($y + $c1) < $yr+30) $y = $y + $c1; + else $y = $y + $c0*100; + } + return $y; +} + +function adodb_get_gmt_diff_ts($ts) +{ + if (0 <= $ts && $ts <= 0x7FFFFFFF) { // check if number in 32-bit signed range) { + $arr = getdate($ts); + $y = $arr['year']; + $m = $arr['mon']; + $d = $arr['mday']; + return adodb_get_gmt_diff($y,$m,$d); +} else { + return adodb_get_gmt_diff(false,false,false); + } + +} + +/** + get local time zone offset from GMT. Does not handle historical timezones before 1970. +*/ +function adodb_get_gmt_diff($y,$m,$d) +{ +static $TZ,$tzo; +global $ADODB_DATETIME_CLASS; + + if (!defined('ADODB_TEST_DATES')) $y = false; + else if ($y < 1970 || $y >= 2038) $y = false; + + if ($ADODB_DATETIME_CLASS && $y !== false) { + $dt = new DateTime(); + $dt->setISODate($y,$m,$d); + if (empty($tzo)) { + $tzo = new DateTimeZone(date_default_timezone_get()); + # $tzt = timezone_transitions_get( $tzo ); + } + return -$tzo->getOffset($dt); + } else { + if (isset($TZ)) return $TZ; + $y = date('Y'); + $TZ = mktime(0,0,0,12,2,$y,0) - gmmktime(0,0,0,12,2,$y,0); + } + + return $TZ; +} + +/** + Returns an array with date info. +*/ +function adodb_getdate($d=false,$fast=false) +{ + if ($d === false) return getdate(); + if (!defined('ADODB_TEST_DATES')) { + if ((abs($d) <= 0x7FFFFFFF)) { // check if number in 32-bit signed range + if (!defined('ADODB_NO_NEGATIVE_TS') || $d >= 0) // if windows, must be +ve integer + return @getdate($d); + } + } + return _adodb_getdate($d); +} + +/* +// generate $YRS table for _adodb_getdate() +function adodb_date_gentable($out=true) +{ + + for ($i=1970; $i >= 1600; $i-=10) { + $s = adodb_gmmktime(0,0,0,1,1,$i); + echo "$i => $s,
    "; + } +} +adodb_date_gentable(); + +for ($i=1970; $i > 1500; $i--) { + +echo "
    $i "; + adodb_date_test_date($i,1,1); +} + +*/ + + +$_month_table_normal = array("",31,28,31,30,31,30,31,31,30,31,30,31); +$_month_table_leaf = array("",31,29,31,30,31,30,31,31,30,31,30,31); + +function adodb_validdate($y,$m,$d) +{ +global $_month_table_normal,$_month_table_leaf; + + if (_adodb_is_leap_year($y)) $marr = $_month_table_leaf; + else $marr = $_month_table_normal; + + if ($m > 12 || $m < 1) return false; + + if ($d > 31 || $d < 1) return false; + + if ($marr[$m] < $d) return false; + + if ($y < 1000 && $y > 3000) return false; + + return true; +} + +/** + Low-level function that returns the getdate() array. We have a special + $fast flag, which if set to true, will return fewer array values, + and is much faster as it does not calculate dow, etc. +*/ +function _adodb_getdate($origd=false,$fast=false,$is_gmt=false) +{ +static $YRS; +global $_month_table_normal,$_month_table_leaf; + + $d = $origd - ($is_gmt ? 0 : adodb_get_gmt_diff_ts($origd)); + $_day_power = 86400; + $_hour_power = 3600; + $_min_power = 60; + + if ($d < -12219321600) $d -= 86400*10; // if 15 Oct 1582 or earlier, gregorian correction + + $_month_table_normal = array("",31,28,31,30,31,30,31,31,30,31,30,31); + $_month_table_leaf = array("",31,29,31,30,31,30,31,31,30,31,30,31); + + $d366 = $_day_power * 366; + $d365 = $_day_power * 365; + + if ($d < 0) { + + if (empty($YRS)) $YRS = array( + 1970 => 0, + 1960 => -315619200, + 1950 => -631152000, + 1940 => -946771200, + 1930 => -1262304000, + 1920 => -1577923200, + 1910 => -1893456000, + 1900 => -2208988800, + 1890 => -2524521600, + 1880 => -2840140800, + 1870 => -3155673600, + 1860 => -3471292800, + 1850 => -3786825600, + 1840 => -4102444800, + 1830 => -4417977600, + 1820 => -4733596800, + 1810 => -5049129600, + 1800 => -5364662400, + 1790 => -5680195200, + 1780 => -5995814400, + 1770 => -6311347200, + 1760 => -6626966400, + 1750 => -6942499200, + 1740 => -7258118400, + 1730 => -7573651200, + 1720 => -7889270400, + 1710 => -8204803200, + 1700 => -8520336000, + 1690 => -8835868800, + 1680 => -9151488000, + 1670 => -9467020800, + 1660 => -9782640000, + 1650 => -10098172800, + 1640 => -10413792000, + 1630 => -10729324800, + 1620 => -11044944000, + 1610 => -11360476800, + 1600 => -11676096000); + + if ($is_gmt) $origd = $d; + // The valid range of a 32bit signed timestamp is typically from + // Fri, 13 Dec 1901 20:45:54 GMT to Tue, 19 Jan 2038 03:14:07 GMT + // + + # old algorithm iterates through all years. new algorithm does it in + # 10 year blocks + + /* + # old algo + for ($a = 1970 ; --$a >= 0;) { + $lastd = $d; + + if ($leaf = _adodb_is_leap_year($a)) $d += $d366; + else $d += $d365; + + if ($d >= 0) { + $year = $a; + break; + } + } + */ + + $lastsecs = 0; + $lastyear = 1970; + foreach($YRS as $year => $secs) { + if ($d >= $secs) { + $a = $lastyear; + break; + } + $lastsecs = $secs; + $lastyear = $year; + } + + $d -= $lastsecs; + if (!isset($a)) $a = $lastyear; + + //echo ' yr=',$a,' ', $d,'.'; + + for (; --$a >= 0;) { + $lastd = $d; + + if ($leaf = _adodb_is_leap_year($a)) $d += $d366; + else $d += $d365; + + if ($d >= 0) { + $year = $a; + break; + } + } + /**/ + + $secsInYear = 86400 * ($leaf ? 366 : 365) + $lastd; + + $d = $lastd; + $mtab = ($leaf) ? $_month_table_leaf : $_month_table_normal; + for ($a = 13 ; --$a > 0;) { + $lastd = $d; + $d += $mtab[$a] * $_day_power; + if ($d >= 0) { + $month = $a; + $ndays = $mtab[$a]; + break; + } + } + + $d = $lastd; + $day = $ndays + ceil(($d+1) / ($_day_power)); + + $d += ($ndays - $day+1)* $_day_power; + $hour = floor($d/$_hour_power); + + } else { + for ($a = 1970 ;; $a++) { + $lastd = $d; + + if ($leaf = _adodb_is_leap_year($a)) $d -= $d366; + else $d -= $d365; + if ($d < 0) { + $year = $a; + break; + } + } + $secsInYear = $lastd; + $d = $lastd; + $mtab = ($leaf) ? $_month_table_leaf : $_month_table_normal; + for ($a = 1 ; $a <= 12; $a++) { + $lastd = $d; + $d -= $mtab[$a] * $_day_power; + if ($d < 0) { + $month = $a; + $ndays = $mtab[$a]; + break; + } + } + $d = $lastd; + $day = ceil(($d+1) / $_day_power); + $d = $d - ($day-1) * $_day_power; + $hour = floor($d /$_hour_power); + } + + $d -= $hour * $_hour_power; + $min = floor($d/$_min_power); + $secs = $d - $min * $_min_power; + if ($fast) { + return array( + 'seconds' => $secs, + 'minutes' => $min, + 'hours' => $hour, + 'mday' => $day, + 'mon' => $month, + 'year' => $year, + 'yday' => floor($secsInYear/$_day_power), + 'leap' => $leaf, + 'ndays' => $ndays + ); + } + + + $dow = adodb_dow($year,$month,$day); + + return array( + 'seconds' => $secs, + 'minutes' => $min, + 'hours' => $hour, + 'mday' => $day, + 'wday' => $dow, + 'mon' => $month, + 'year' => $year, + 'yday' => floor($secsInYear/$_day_power), + 'weekday' => gmdate('l',$_day_power*(3+$dow)), + 'month' => gmdate('F',mktime(0,0,0,$month,2,1971)), + 0 => $origd + ); +} +/* + if ($isphp5) + $dates .= sprintf('%s%04d',($gmt<=0)?'+':'-',abs($gmt)/36); + else + $dates .= sprintf('%s%04d',($gmt<0)?'+':'-',abs($gmt)/36); + break;*/ +function adodb_tz_offset($gmt,$isphp5) +{ + $zhrs = abs($gmt)/3600; + $hrs = floor($zhrs); + if ($isphp5) + return sprintf('%s%02d%02d',($gmt<=0)?'+':'-',floor($zhrs),($zhrs-$hrs)*60); + else + return sprintf('%s%02d%02d',($gmt<0)?'+':'-',floor($zhrs),($zhrs-$hrs)*60); + break; +} + + +function adodb_gmdate($fmt,$d=false) +{ + return adodb_date($fmt,$d,true); +} + +// accepts unix timestamp and iso date format in $d +function adodb_date2($fmt, $d=false, $is_gmt=false) +{ + if ($d !== false) { + if (!preg_match( + "|^([0-9]{4})[-/\.]?([0-9]{1,2})[-/\.]?([0-9]{1,2})[ -]?(([0-9]{1,2}):?([0-9]{1,2}):?([0-9\.]{1,4}))?|", + ($d), $rr)) return adodb_date($fmt,false,$is_gmt); + + if ($rr[1] <= 100 && $rr[2]<= 1) return adodb_date($fmt,false,$is_gmt); + + // h-m-s-MM-DD-YY + if (!isset($rr[5])) $d = adodb_mktime(0,0,0,$rr[2],$rr[3],$rr[1],false,$is_gmt); + else $d = @adodb_mktime($rr[5],$rr[6],$rr[7],$rr[2],$rr[3],$rr[1],false,$is_gmt); + } + + return adodb_date($fmt,$d,$is_gmt); +} + + +/** + Return formatted date based on timestamp $d +*/ +function adodb_date($fmt,$d=false,$is_gmt=false) +{ +static $daylight; +global $ADODB_DATETIME_CLASS; + + if ($d === false) return ($is_gmt)? @gmdate($fmt): @date($fmt); + if (!defined('ADODB_TEST_DATES')) { + if ((abs($d) <= 0x7FFFFFFF)) { // check if number in 32-bit signed range + if (!defined('ADODB_NO_NEGATIVE_TS') || $d >= 0) // if windows, must be +ve integer + return ($is_gmt)? @gmdate($fmt,$d): @date($fmt,$d); + + } + } + $_day_power = 86400; + + $arr = _adodb_getdate($d,true,$is_gmt); + + if (!isset($daylight)) $daylight = function_exists('adodb_daylight_sv'); + if ($daylight) adodb_daylight_sv($arr, $is_gmt); + + $year = $arr['year']; + $month = $arr['mon']; + $day = $arr['mday']; + $hour = $arr['hours']; + $min = $arr['minutes']; + $secs = $arr['seconds']; + + $max = strlen($fmt); + $dates = ''; + + $isphp5 = PHP_VERSION >= 5; + + /* + at this point, we have the following integer vars to manipulate: + $year, $month, $day, $hour, $min, $secs + */ + for ($i=0; $i < $max; $i++) { + switch($fmt[$i]) { + case 'T': + if ($ADODB_DATETIME_CLASS) { + $dt = new DateTime(); + $dt->SetDate($year,$month,$day); + $dates .= $dt->Format('T'); + } else + $dates .= date('T'); + break; + // YEAR + case 'L': $dates .= $arr['leap'] ? '1' : '0'; break; + case 'r': // Thu, 21 Dec 2000 16:01:07 +0200 + + // 4.3.11 uses '04 Jun 2004' + // 4.3.8 uses ' 4 Jun 2004' + $dates .= gmdate('D',$_day_power*(3+adodb_dow($year,$month,$day))).', ' + . ($day<10?'0'.$day:$day) . ' '.date('M',mktime(0,0,0,$month,2,1971)).' '.$year.' '; + + if ($hour < 10) $dates .= '0'.$hour; else $dates .= $hour; + + if ($min < 10) $dates .= ':0'.$min; else $dates .= ':'.$min; + + if ($secs < 10) $dates .= ':0'.$secs; else $dates .= ':'.$secs; + + $gmt = adodb_get_gmt_diff($year,$month,$day); + + $dates .= ' '.adodb_tz_offset($gmt,$isphp5); + break; + + case 'Y': $dates .= $year; break; + case 'y': $dates .= substr($year,strlen($year)-2,2); break; + // MONTH + case 'm': if ($month<10) $dates .= '0'.$month; else $dates .= $month; break; + case 'Q': $dates .= ($month+3)>>2; break; + case 'n': $dates .= $month; break; + case 'M': $dates .= date('M',mktime(0,0,0,$month,2,1971)); break; + case 'F': $dates .= date('F',mktime(0,0,0,$month,2,1971)); break; + // DAY + case 't': $dates .= $arr['ndays']; break; + case 'z': $dates .= $arr['yday']; break; + case 'w': $dates .= adodb_dow($year,$month,$day); break; + case 'l': $dates .= gmdate('l',$_day_power*(3+adodb_dow($year,$month,$day))); break; + case 'D': $dates .= gmdate('D',$_day_power*(3+adodb_dow($year,$month,$day))); break; + case 'j': $dates .= $day; break; + case 'd': if ($day<10) $dates .= '0'.$day; else $dates .= $day; break; + case 'S': + $d10 = $day % 10; + if ($d10 == 1) $dates .= 'st'; + else if ($d10 == 2 && $day != 12) $dates .= 'nd'; + else if ($d10 == 3) $dates .= 'rd'; + else $dates .= 'th'; + break; + + // HOUR + case 'Z': + $dates .= ($is_gmt) ? 0 : -adodb_get_gmt_diff($year,$month,$day); break; + case 'O': + $gmt = ($is_gmt) ? 0 : adodb_get_gmt_diff($year,$month,$day); + + $dates .= adodb_tz_offset($gmt,$isphp5); + break; + + case 'H': + if ($hour < 10) $dates .= '0'.$hour; + else $dates .= $hour; + break; + case 'h': + if ($hour > 12) $hh = $hour - 12; + else { + if ($hour == 0) $hh = '12'; + else $hh = $hour; + } + + if ($hh < 10) $dates .= '0'.$hh; + else $dates .= $hh; + break; + + case 'G': + $dates .= $hour; + break; + + case 'g': + if ($hour > 12) $hh = $hour - 12; + else { + if ($hour == 0) $hh = '12'; + else $hh = $hour; + } + $dates .= $hh; + break; + // MINUTES + case 'i': if ($min < 10) $dates .= '0'.$min; else $dates .= $min; break; + // SECONDS + case 'U': $dates .= $d; break; + case 's': if ($secs < 10) $dates .= '0'.$secs; else $dates .= $secs; break; + // AM/PM + // Note 00:00 to 11:59 is AM, while 12:00 to 23:59 is PM + case 'a': + if ($hour>=12) $dates .= 'pm'; + else $dates .= 'am'; + break; + case 'A': + if ($hour>=12) $dates .= 'PM'; + else $dates .= 'AM'; + break; + default: + $dates .= $fmt[$i]; break; + // ESCAPE + case "\\": + $i++; + if ($i < $max) $dates .= $fmt[$i]; + break; + } + } + return $dates; +} + +/** + Returns a timestamp given a GMT/UTC time. + Note that $is_dst is not implemented and is ignored. +*/ +function adodb_gmmktime($hr,$min,$sec,$mon=false,$day=false,$year=false,$is_dst=false) +{ + return adodb_mktime($hr,$min,$sec,$mon,$day,$year,$is_dst,true); +} + +/** + Return a timestamp given a local time. Originally by jackbbs. + Note that $is_dst is not implemented and is ignored. + + Not a very fast algorithm - O(n) operation. Could be optimized to O(1). +*/ +function adodb_mktime($hr,$min,$sec,$mon=false,$day=false,$year=false,$is_dst=false,$is_gmt=false) +{ + if (!defined('ADODB_TEST_DATES')) { + + if ($mon === false) { + return $is_gmt? @gmmktime($hr,$min,$sec): @mktime($hr,$min,$sec); + } + + // for windows, we don't check 1970 because with timezone differences, + // 1 Jan 1970 could generate negative timestamp, which is illegal + if (1971 < $year && $year < 2038 + || !defined('ADODB_NO_NEGATIVE_TS') && (1901 < $year && $year < 2038) + ) { + return $is_gmt ? + @gmmktime($hr,$min,$sec,$mon,$day,$year): + @mktime($hr,$min,$sec,$mon,$day,$year); + } + } + + $gmt_different = ($is_gmt) ? 0 : adodb_get_gmt_diff($year,$mon,$day); + + /* + # disabled because some people place large values in $sec. + # however we need it for $mon because we use an array... + $hr = intval($hr); + $min = intval($min); + $sec = intval($sec); + */ + $mon = intval($mon); + $day = intval($day); + $year = intval($year); + + + $year = adodb_year_digit_check($year); + + if ($mon > 12) { + $y = floor($mon / 12); + $year += $y; + $mon -= $y*12; + } else if ($mon < 1) { + $y = ceil((1-$mon) / 12); + $year -= $y; + $mon += $y*12; + } + + $_day_power = 86400; + $_hour_power = 3600; + $_min_power = 60; + + $_month_table_normal = array("",31,28,31,30,31,30,31,31,30,31,30,31); + $_month_table_leaf = array("",31,29,31,30,31,30,31,31,30,31,30,31); + + $_total_date = 0; + if ($year >= 1970) { + for ($a = 1970 ; $a <= $year; $a++) { + $leaf = _adodb_is_leap_year($a); + if ($leaf == true) { + $loop_table = $_month_table_leaf; + $_add_date = 366; + } else { + $loop_table = $_month_table_normal; + $_add_date = 365; + } + if ($a < $year) { + $_total_date += $_add_date; + } else { + for($b=1;$b<$mon;$b++) { + $_total_date += $loop_table[$b]; + } + } + } + $_total_date +=$day-1; + $ret = $_total_date * $_day_power + $hr * $_hour_power + $min * $_min_power + $sec + $gmt_different; + + } else { + for ($a = 1969 ; $a >= $year; $a--) { + $leaf = _adodb_is_leap_year($a); + if ($leaf == true) { + $loop_table = $_month_table_leaf; + $_add_date = 366; + } else { + $loop_table = $_month_table_normal; + $_add_date = 365; + } + if ($a > $year) { $_total_date += $_add_date; + } else { + for($b=12;$b>$mon;$b--) { + $_total_date += $loop_table[$b]; + } + } + } + $_total_date += $loop_table[$mon] - $day; + + $_day_time = $hr * $_hour_power + $min * $_min_power + $sec; + $_day_time = $_day_power - $_day_time; + $ret = -( $_total_date * $_day_power + $_day_time - $gmt_different); + if ($ret < -12220185600) $ret += 10*86400; // if earlier than 5 Oct 1582 - gregorian correction + else if ($ret < -12219321600) $ret = -12219321600; // if in limbo, reset to 15 Oct 1582. + } + //print " dmy=$day/$mon/$year $hr:$min:$sec => " .$ret; + return $ret; +} + +function adodb_gmstrftime($fmt, $ts=false) +{ + return adodb_strftime($fmt,$ts,true); +} + +// hack - convert to adodb_date +function adodb_strftime($fmt, $ts=false,$is_gmt=false) +{ +global $ADODB_DATE_LOCALE; + + if (!defined('ADODB_TEST_DATES')) { + if ((abs($ts) <= 0x7FFFFFFF)) { // check if number in 32-bit signed range + if (!defined('ADODB_NO_NEGATIVE_TS') || $ts >= 0) // if windows, must be +ve integer + return ($is_gmt)? @gmstrftime($fmt,$ts): @strftime($fmt,$ts); + + } + } + + if (empty($ADODB_DATE_LOCALE)) { + /* + $tstr = strtoupper(gmstrftime('%c',31366800)); // 30 Dec 1970, 1 am + $sep = substr($tstr,2,1); + $hasAM = strrpos($tstr,'M') !== false; + */ + # see http://phplens.com/lens/lensforum/msgs.php?id=14865 for reasoning, and changelog for version 0.24 + $dstr = gmstrftime('%x',31366800); // 30 Dec 1970, 1 am + $sep = substr($dstr,2,1); + $tstr = strtoupper(gmstrftime('%X',31366800)); // 30 Dec 1970, 1 am + $hasAM = strrpos($tstr,'M') !== false; + + $ADODB_DATE_LOCALE = array(); + $ADODB_DATE_LOCALE[] = strncmp($tstr,'30',2) == 0 ? 'd'.$sep.'m'.$sep.'y' : 'm'.$sep.'d'.$sep.'y'; + $ADODB_DATE_LOCALE[] = ($hasAM) ? 'h:i:s a' : 'H:i:s'; + + } + $inpct = false; + $fmtdate = ''; + for ($i=0,$max = strlen($fmt); $i < $max; $i++) { + $ch = $fmt[$i]; + if ($ch == '%') { + if ($inpct) { + $fmtdate .= '%'; + $inpct = false; + } else + $inpct = true; + } else if ($inpct) { + + $inpct = false; + switch($ch) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case 'E': + case 'O': + /* ignore format modifiers */ + $inpct = true; + break; + + case 'a': $fmtdate .= 'D'; break; + case 'A': $fmtdate .= 'l'; break; + case 'h': + case 'b': $fmtdate .= 'M'; break; + case 'B': $fmtdate .= 'F'; break; + case 'c': $fmtdate .= $ADODB_DATE_LOCALE[0].$ADODB_DATE_LOCALE[1]; break; + case 'C': $fmtdate .= '\C?'; break; // century + case 'd': $fmtdate .= 'd'; break; + case 'D': $fmtdate .= 'm/d/y'; break; + case 'e': $fmtdate .= 'j'; break; + case 'g': $fmtdate .= '\g?'; break; //? + case 'G': $fmtdate .= '\G?'; break; //? + case 'H': $fmtdate .= 'H'; break; + case 'I': $fmtdate .= 'h'; break; + case 'j': $fmtdate .= '?z'; $parsej = true; break; // wrong as j=1-based, z=0-basd + case 'm': $fmtdate .= 'm'; break; + case 'M': $fmtdate .= 'i'; break; + case 'n': $fmtdate .= "\n"; break; + case 'p': $fmtdate .= 'a'; break; + case 'r': $fmtdate .= 'h:i:s a'; break; + case 'R': $fmtdate .= 'H:i:s'; break; + case 'S': $fmtdate .= 's'; break; + case 't': $fmtdate .= "\t"; break; + case 'T': $fmtdate .= 'H:i:s'; break; + case 'u': $fmtdate .= '?u'; $parseu = true; break; // wrong strftime=1-based, date=0-based + case 'U': $fmtdate .= '?U'; $parseU = true; break;// wrong strftime=1-based, date=0-based + case 'x': $fmtdate .= $ADODB_DATE_LOCALE[0]; break; + case 'X': $fmtdate .= $ADODB_DATE_LOCALE[1]; break; + case 'w': $fmtdate .= '?w'; $parseu = true; break; // wrong strftime=1-based, date=0-based + case 'W': $fmtdate .= '?W'; $parseU = true; break;// wrong strftime=1-based, date=0-based + case 'y': $fmtdate .= 'y'; break; + case 'Y': $fmtdate .= 'Y'; break; + case 'Z': $fmtdate .= 'T'; break; + } + } else if (('A' <= ($ch) && ($ch) <= 'Z' ) || ('a' <= ($ch) && ($ch) <= 'z' )) + $fmtdate .= "\\".$ch; + else + $fmtdate .= $ch; + } + //echo "fmt=",$fmtdate,"
    "; + if ($ts === false) $ts = time(); + $ret = adodb_date($fmtdate, $ts, $is_gmt); + return $ret; +} + + +?> \ No newline at end of file diff --git a/upload/includes/adodb/adodb.inc.php b/upload/includes/adodb/adodb.inc.php new file mode 100644 index 00000000..955b57d7 --- /dev/null +++ b/upload/includes/adodb/adodb.inc.php @@ -0,0 +1,4242 @@ +fields is available on EOF + $ADODB_FETCH_MODE, // DEFAULT, NUM, ASSOC or BOTH. Default follows native driver default... + $ADODB_QUOTE_FIELDNAMES; // Allows you to force quotes (backticks) around field names in queries generated by getinsertsql and getupdatesql. + + //============================================================================================== + // GLOBAL SETUP + //============================================================================================== + + $ADODB_EXTENSION = defined('ADODB_EXTENSION'); + + //********************************************************// + /* + Controls $ADODB_FORCE_TYPE mode. Default is ADODB_FORCE_VALUE (3). + Used in GetUpdateSql and GetInsertSql functions. Thx to Niko, nuko#mbnet.fi + + 0 = ignore empty fields. All empty fields in array are ignored. + 1 = force null. All empty, php null and string 'null' fields are changed to sql NULL values. + 2 = force empty. All empty, php null and string 'null' fields are changed to sql empty '' or 0 values. + 3 = force value. Value is left as it is. Php null and string 'null' are set to sql NULL values and empty fields '' are set to empty '' sql values. + */ + define('ADODB_FORCE_IGNORE',0); + define('ADODB_FORCE_NULL',1); + define('ADODB_FORCE_EMPTY',2); + define('ADODB_FORCE_VALUE',3); + //********************************************************// + + + if (!$ADODB_EXTENSION || ADODB_EXTENSION < 4.0) { + + define('ADODB_BAD_RS','

    Bad $rs in %s. Connection or SQL invalid. Try using $connection->debug=true;

    '); + + // allow [ ] @ ` " and . in table names + define('ADODB_TABLE_REGEX','([]0-9a-z_\:\"\`\.\@\[-]*)'); + + // prefetching used by oracle + if (!defined('ADODB_PREFETCH_ROWS')) define('ADODB_PREFETCH_ROWS',10); + + + /* + Controls ADODB_FETCH_ASSOC field-name case. Default is 2, use native case-names. + This currently works only with mssql, odbc, oci8po and ibase derived drivers. + + 0 = assoc lowercase field names. $rs->fields['orderid'] + 1 = assoc uppercase field names. $rs->fields['ORDERID'] + 2 = use native-case field names. $rs->fields['OrderID'] + */ + + define('ADODB_FETCH_DEFAULT',0); + define('ADODB_FETCH_NUM',1); + define('ADODB_FETCH_ASSOC',2); + define('ADODB_FETCH_BOTH',3); + + if (!defined('TIMESTAMP_FIRST_YEAR')) define('TIMESTAMP_FIRST_YEAR',100); + + // PHP's version scheme makes converting to numbers difficult - workaround + $_adodb_ver = (float) PHP_VERSION; + if ($_adodb_ver >= 5.2) { + define('ADODB_PHPVER',0x5200); + } else if ($_adodb_ver >= 5.0) { + define('ADODB_PHPVER',0x5000); + } else if ($_adodb_ver > 4.299999) { # 4.3 + define('ADODB_PHPVER',0x4300); + } else if ($_adodb_ver > 4.199999) { # 4.2 + define('ADODB_PHPVER',0x4200); + } else if (strnatcmp(PHP_VERSION,'4.0.5')>=0) { + define('ADODB_PHPVER',0x4050); + } else { + define('ADODB_PHPVER',0x4000); + } + } + + //if (!defined('ADODB_ASSOC_CASE')) define('ADODB_ASSOC_CASE',2); + + + /** + Accepts $src and $dest arrays, replacing string $data + */ + function ADODB_str_replace($src, $dest, $data) + { + if (ADODB_PHPVER >= 0x4050) return str_replace($src,$dest,$data); + + $s = reset($src); + $d = reset($dest); + while ($s !== false) { + $data = str_replace($s,$d,$data); + $s = next($src); + $d = next($dest); + } + return $data; + } + + function ADODB_Setup() + { + GLOBAL + $ADODB_vers, // database version + $ADODB_COUNTRECS, // count number of records returned - slows down query + $ADODB_CACHE_DIR, // directory to cache recordsets + $ADODB_FETCH_MODE, + $ADODB_FORCE_TYPE, + $ADODB_QUOTE_FIELDNAMES; + + $ADODB_FETCH_MODE = ADODB_FETCH_DEFAULT; + $ADODB_FORCE_TYPE = ADODB_FORCE_VALUE; + + + if (!isset($ADODB_CACHE_DIR)) { + $ADODB_CACHE_DIR = '/tmp'; //(isset($_ENV['TMP'])) ? $_ENV['TMP'] : '/tmp'; + } else { + // do not accept url based paths, eg. http:/ or ftp:/ + if (strpos($ADODB_CACHE_DIR,'://') !== false) + die("Illegal path http:// or ftp://"); + } + + + // Initialize random number generator for randomizing cache flushes + // -- note Since PHP 4.2.0, the seed becomes optional and defaults to a random value if omitted. + srand(((double)microtime())*1000000); + + /** + * ADODB version as a string. + */ + $ADODB_vers = 'V4.96 24 Sept 2007 (c) 2000-2007 John Lim (jlim#natsoft.com.my). All rights reserved. Released BSD & LGPL.'; + + /** + * Determines whether recordset->RecordCount() is used. + * Set to false for highest performance -- RecordCount() will always return -1 then + * for databases that provide "virtual" recordcounts... + */ + if (!isset($ADODB_COUNTRECS)) $ADODB_COUNTRECS = true; + } + + + //============================================================================================== + // CHANGE NOTHING BELOW UNLESS YOU ARE DESIGNING ADODB + //============================================================================================== + + ADODB_Setup(); + + //============================================================================================== + // CLASS ADOFieldObject + //============================================================================================== + /** + * Helper class for FetchFields -- holds info on a column + */ + class ADOFieldObject { + var $name = ''; + var $max_length=0; + var $type=""; +/* + // additional fields by dannym... (danny_milo@yahoo.com) + var $not_null = false; + // actually, this has already been built-in in the postgres, fbsql AND mysql module? ^-^ + // so we can as well make not_null standard (leaving it at "false" does not harm anyways) + + var $has_default = false; // this one I have done only in mysql and postgres for now ... + // others to come (dannym) + var $default_value; // default, if any, and supported. Check has_default first. +*/ + } + + + + function ADODB_TransMonitor($dbms, $fn, $errno, $errmsg, $p1, $p2, &$thisConnection) + { + //print "Errorno ($fn errno=$errno m=$errmsg) "; + $thisConnection->_transOK = false; + if ($thisConnection->_oldRaiseFn) { + $fn = $thisConnection->_oldRaiseFn; + $fn($dbms, $fn, $errno, $errmsg, $p1, $p2,$thisConnection); + } + } + + //============================================================================================== + // CLASS ADOConnection + //============================================================================================== + + /** + * Connection object. For connecting to databases, and executing queries. + */ + class ADOConnection { + // + // PUBLIC VARS + // + var $dataProvider = 'native'; + var $databaseType = ''; /// RDBMS currently in use, eg. odbc, mysql, mssql + var $database = ''; /// Name of database to be used. + var $host = ''; /// The hostname of the database server + var $user = ''; /// The username which is used to connect to the database server. + var $password = ''; /// Password for the username. For security, we no longer store it. + var $debug = false; /// if set to true will output sql statements + var $maxblobsize = 262144; /// maximum size of blobs or large text fields (262144 = 256K)-- some db's die otherwise like foxpro + var $concat_operator = '+'; /// default concat operator -- change to || for Oracle/Interbase + var $substr = 'substr'; /// substring operator + var $length = 'length'; /// string length ofperator + var $random = 'rand()'; /// random function + var $upperCase = 'upper'; /// uppercase function + var $fmtDate = "'Y-m-d'"; /// used by DBDate() as the default date format used by the database + var $fmtTimeStamp = "'Y-m-d, h:i:s A'"; /// used by DBTimeStamp as the default timestamp fmt. + var $true = '1'; /// string that represents TRUE for a database + var $false = '0'; /// string that represents FALSE for a database + var $replaceQuote = "\\'"; /// string to use to replace quotes + var $nameQuote = '"'; /// string to use to quote identifiers and names + var $charSet=false; /// character set to use - only for interbase, postgres and oci8 + var $metaDatabasesSQL = ''; + var $metaTablesSQL = ''; + var $uniqueOrderBy = false; /// All order by columns have to be unique + var $emptyDate = ' '; + var $emptyTimeStamp = ' '; + var $lastInsID = false; + //-- + var $hasInsertID = false; /// supports autoincrement ID? + var $hasAffectedRows = false; /// supports affected rows for update/delete? + var $hasTop = false; /// support mssql/access SELECT TOP 10 * FROM TABLE + var $hasLimit = false; /// support pgsql/mysql SELECT * FROM TABLE LIMIT 10 + var $readOnly = false; /// this is a readonly database - used by phpLens + var $hasMoveFirst = false; /// has ability to run MoveFirst(), scrolling backwards + var $hasGenID = false; /// can generate sequences using GenID(); + var $hasTransactions = true; /// has transactions + //-- + var $genID = 0; /// sequence id used by GenID(); + var $raiseErrorFn = false; /// error function to call + var $isoDates = false; /// accepts dates in ISO format + var $cacheSecs = 3600; /// cache for 1 hour + + // memcache + var $memCache = false; /// should we use memCache instead of caching in files + var $memCacheHost; /// memCache host + var $memCachePort = 11211; /// memCache port + var $memCacheCompress = false; /// Use 'true' to store the item compressed (uses zlib) + + var $sysDate = false; /// name of function that returns the current date + var $sysTimeStamp = false; /// name of function that returns the current timestamp + var $arrayClass = 'ADORecordSet_array'; /// name of class used to generate array recordsets, which are pre-downloaded recordsets + + var $noNullStrings = false; /// oracle specific stuff - if true ensures that '' is converted to ' ' + var $numCacheHits = 0; + var $numCacheMisses = 0; + var $pageExecuteCountRows = true; + var $uniqueSort = false; /// indicates that all fields in order by must be unique + var $leftOuter = false; /// operator to use for left outer join in WHERE clause + var $rightOuter = false; /// operator to use for right outer join in WHERE clause + var $ansiOuter = false; /// whether ansi outer join syntax supported + var $autoRollback = false; // autoRollback on PConnect(). + var $poorAffectedRows = false; // affectedRows not working or unreliable + + var $fnExecute = false; + var $fnCacheExecute = false; + var $blobEncodeType = false; // false=not required, 'I'=encode to integer, 'C'=encode to char + var $rsPrefix = "ADORecordSet_"; + + var $autoCommit = true; /// do not modify this yourself - actually private + var $transOff = 0; /// temporarily disable transactions + var $transCnt = 0; /// count of nested transactions + + var $fetchMode=false; + var $num_rows = 0; + var $null2null = 'null'; // in autoexecute/getinsertsql/getupdatesql, this value will be converted to a null + // + // PRIVATE VARS + // + var $_oldRaiseFn = false; + var $_transOK = null; + var $_connectionID = false; /// The returned link identifier whenever a successful database connection is made. + var $_errorMsg = false; /// A variable which was used to keep the returned last error message. The value will + /// then returned by the errorMsg() function + var $_errorCode = false; /// Last error code, not guaranteed to be used - only by oci8 + var $_queryID = false; /// This variable keeps the last created result link identifier + + var $_isPersistentConnection = false; /// A boolean variable to state whether its a persistent connection or normal connection. */ + var $_bindInputArray = false; /// set to true if ADOConnection.Execute() permits binding of array parameters. + var $_evalAll = false; + var $_affected = false; + var $_logsql = false; + var $_transmode = ''; // transaction mode + var $db_query = NULL; + + + /** + * Constructor + */ + function ADOConnection() + { + die('Virtual Class -- cannot instantiate'); + } + + function Version() + { + global $ADODB_vers; + + return (float) substr($ADODB_vers,1); + } + + /** + Get server version info... + + @returns An array with 2 elements: $arr['string'] is the description string, + and $arr[version] is the version (also a string). + */ + function ServerInfo() + { + return array('description' => '', 'version' => ''); + } + + function IsConnected() + { + return !empty($this->_connectionID); + } + + function _findvers($str) + { + if (preg_match('/([0-9]+\.([0-9\.])+)/',$str, $arr)) return $arr[1]; + else return ''; + } + + /** + * All error messages go through this bottleneck function. + * You can define your own handler by defining the function name in ADODB_OUTP. + */ + function outp($msg,$newline=true) + { + global $ADODB_FLUSH,$ADODB_OUTP; + + if (defined('ADODB_OUTP')) { + $fn = ADODB_OUTP; + $fn($msg,$newline); + return; + } else if (isset($ADODB_OUTP)) { + $fn = $ADODB_OUTP; + $fn($msg,$newline); + return; + } + + if ($newline) $msg .= "
    \n"; + + if (isset($_SERVER['HTTP_USER_AGENT']) || !$newline) echo $msg; + else echo strip_tags($msg); + + + if (!empty($ADODB_FLUSH) && ob_get_length() !== false) flush(); // do not flush if output buffering enabled - useless - thx to Jesse Mullan + + } + + function Time() + { + $rs =& $this->_Execute("select $this->sysTimeStamp"); + if ($rs && !$rs->EOF) return $this->UnixTimeStamp(reset($rs->fields)); + + return false; + } + + /** + * Connect to database + * + * @param [argHostname] Host to connect to + * @param [argUsername] Userid to login + * @param [argPassword] Associated password + * @param [argDatabaseName] database + * @param [forceNew] force new connection + * + * @return true or false + */ + function Connect($argHostname = "", $argUsername = "", $argPassword = "", $argDatabaseName = "", $forceNew = false) + { + if ($argHostname != "") $this->host = $argHostname; + if ($argUsername != "") $this->user = $argUsername; + if ($argPassword != "") $this->password = $argPassword; // not stored for security reasons + if ($argDatabaseName != "") $this->database = $argDatabaseName; + + $this->_isPersistentConnection = false; + if ($forceNew) { + if ($rez=$this->_nconnect($this->host, $this->user, $this->password, $this->database)) return true; + } else { + if ($rez=$this->_connect($this->host, $this->user, $this->password, $this->database)) return true; + } + if (isset($rez)) { + $err = $this->ErrorMsg(); + if (empty($err)) $err = "Connection error to server '$argHostname' with user '$argUsername'"; + $ret = false; + } else { + $err = "Missing extension for ".$this->dataProvider; + $ret = 0; + } + if ($fn = $this->raiseErrorFn) + $fn($this->databaseType,'CONNECT',$this->ErrorNo(),$err,$this->host,$this->database,$this); + + + $this->_connectionID = false; + if ($this->debug) ADOConnection::outp( $this->host.': '.$err); + return $ret; + } + + function _nconnect($argHostname, $argUsername, $argPassword, $argDatabaseName) + { + return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabaseName); + } + + + /** + * Always force a new connection to database - currently only works with oracle + * + * @param [argHostname] Host to connect to + * @param [argUsername] Userid to login + * @param [argPassword] Associated password + * @param [argDatabaseName] database + * + * @return true or false + */ + function NConnect($argHostname = "", $argUsername = "", $argPassword = "", $argDatabaseName = "") + { + return $this->Connect($argHostname, $argUsername, $argPassword, $argDatabaseName, true); + } + + /** + * Establish persistent connect to database + * + * @param [argHostname] Host to connect to + * @param [argUsername] Userid to login + * @param [argPassword] Associated password + * @param [argDatabaseName] database + * + * @return return true or false + */ + function PConnect($argHostname = "", $argUsername = "", $argPassword = "", $argDatabaseName = "") + { + if (defined('ADODB_NEVER_PERSIST')) + return $this->Connect($argHostname,$argUsername,$argPassword,$argDatabaseName); + + if ($argHostname != "") $this->host = $argHostname; + if ($argUsername != "") $this->user = $argUsername; + if ($argPassword != "") $this->password = $argPassword; + if ($argDatabaseName != "") $this->database = $argDatabaseName; + + $this->_isPersistentConnection = true; + if ($rez = $this->_pconnect($this->host, $this->user, $this->password, $this->database)) return true; + if (isset($rez)) { + $err = $this->ErrorMsg(); + if (empty($err)) $err = "Connection error to server '$argHostname' with user '$argUsername'"; + $ret = false; + } else { + $err = "Missing extension for ".$this->dataProvider; + $ret = 0; + } + if ($fn = $this->raiseErrorFn) { + $fn($this->databaseType,'PCONNECT',$this->ErrorNo(),$err,$this->host,$this->database,$this); + } + + $this->_connectionID = false; + if ($this->debug) ADOConnection::outp( $this->host.': '.$err); + return $ret; + } + + // Format date column in sql string given an input format that understands Y M D + function SQLDate($fmt, $col=false) + { + if (!$col) $col = $this->sysDate; + return $col; // child class implement + } + + /** + * Should prepare the sql statement and return the stmt resource. + * For databases that do not support this, we return the $sql. To ensure + * compatibility with databases that do not support prepare: + * + * $stmt = $db->Prepare("insert into table (id, name) values (?,?)"); + * $db->Execute($stmt,array(1,'Jill')) or die('insert failed'); + * $db->Execute($stmt,array(2,'Joe')) or die('insert failed'); + * + * @param sql SQL to send to database + * + * @return return FALSE, or the prepared statement, or the original sql if + * if the database does not support prepare. + * + */ + function Prepare($sql) + { + return $sql; + } + + /** + * Some databases, eg. mssql require a different function for preparing + * stored procedures. So we cannot use Prepare(). + * + * Should prepare the stored procedure and return the stmt resource. + * For databases that do not support this, we return the $sql. To ensure + * compatibility with databases that do not support prepare: + * + * @param sql SQL to send to database + * + * @return return FALSE, or the prepared statement, or the original sql if + * if the database does not support prepare. + * + */ + function PrepareSP($sql,$param=true) + { + return $this->Prepare($sql,$param); + } + + /** + * PEAR DB Compat + */ + function Quote($s) + { + return $this->qstr($s,false); + } + + /** + Requested by "Karsten Dambekalns" + */ + function QMagic($s) + { + return $this->qstr($s,get_magic_quotes_gpc()); + } + + function q(&$s) + { + #if (!empty($this->qNull)) if ($s == 'null') return $s; + $s = $this->qstr($s,false); + } + + /** + * PEAR DB Compat - do not use internally. + */ + function ErrorNative() + { + return $this->ErrorNo(); + } + + + /** + * PEAR DB Compat - do not use internally. + */ + function nextId($seq_name) + { + return $this->GenID($seq_name); + } + + /** + * Lock a row, will escalate and lock the table if row locking not supported + * will normally free the lock at the end of the transaction + * + * @param $table name of table to lock + * @param $where where clause to use, eg: "WHERE row=12". If left empty, will escalate to table lock + */ + function RowLock($table,$where) + { + return false; + } + + function CommitLock($table) + { + return $this->CommitTrans(); + } + + function RollbackLock($table) + { + return $this->RollbackTrans(); + } + + /** + * PEAR DB Compat - do not use internally. + * + * The fetch modes for NUMERIC and ASSOC for PEAR DB and ADODB are identical + * for easy porting :-) + * + * @param mode The fetchmode ADODB_FETCH_ASSOC or ADODB_FETCH_NUM + * @returns The previous fetch mode + */ + function SetFetchMode($mode) + { + $old = $this->fetchMode; + $this->fetchMode = $mode; + + if ($old === false) { + global $ADODB_FETCH_MODE; + return $ADODB_FETCH_MODE; + } + return $old; + } + + + /** + * PEAR DB Compat - do not use internally. + */ + function &Query($sql, $inputarr=false) + { + $rs = &$this->Execute($sql, $inputarr); + if (!$rs && defined('ADODB_PEAR')) return ADODB_PEAR_Error(); + return $rs; + } + + + /** + * PEAR DB Compat - do not use internally + */ + function &LimitQuery($sql, $offset, $count, $params=false) + { + $rs = &$this->SelectLimit($sql, $count, $offset, $params); + if (!$rs && defined('ADODB_PEAR')) return ADODB_PEAR_Error(); + return $rs; + } + + + /** + * PEAR DB Compat - do not use internally + */ + function Disconnect() + { + return $this->Close(); + } + + /* + Returns placeholder for parameter, eg. + $DB->Param('a') + + will return ':a' for Oracle, and '?' for most other databases... + + For databases that require positioned params, eg $1, $2, $3 for postgresql, + pass in Param(false) before setting the first parameter. + */ + function Param($name,$type='C') + { + return '?'; + } + + /* + InParameter and OutParameter are self-documenting versions of Parameter(). + */ + function InParameter(&$stmt,&$var,$name,$maxLen=4000,$type=false) + { + return $this->Parameter($stmt,$var,$name,false,$maxLen,$type); + } + + /* + */ + function OutParameter(&$stmt,&$var,$name,$maxLen=4000,$type=false) + { + return $this->Parameter($stmt,$var,$name,true,$maxLen,$type); + + } + + + /* + Usage in oracle + $stmt = $db->Prepare('select * from table where id =:myid and group=:group'); + $db->Parameter($stmt,$id,'myid'); + $db->Parameter($stmt,$group,'group',64); + $db->Execute(); + + @param $stmt Statement returned by Prepare() or PrepareSP(). + @param $var PHP variable to bind to + @param $name Name of stored procedure variable name to bind to. + @param [$isOutput] Indicates direction of parameter 0/false=IN 1=OUT 2= IN/OUT. This is ignored in oci8. + @param [$maxLen] Holds an maximum length of the variable. + @param [$type] The data type of $var. Legal values depend on driver. + + */ + function Parameter(&$stmt,&$var,$name,$isOutput=false,$maxLen=4000,$type=false) + { + return false; + } + + + function IgnoreErrors($saveErrs=false) + { + if (!$saveErrs) { + $saveErrs = array($this->raiseErrorFn,$this->_transOK); + $this->raiseErrorFn = false; + return $saveErrs; + } else { + $this->raiseErrorFn = $saveErrs[0]; + $this->_transOK = $saveErrs[1]; + } + } + + /** + Improved method of initiating a transaction. Used together with CompleteTrans(). + Advantages include: + + a. StartTrans/CompleteTrans is nestable, unlike BeginTrans/CommitTrans/RollbackTrans. + Only the outermost block is treated as a transaction.
    + b. CompleteTrans auto-detects SQL errors, and will rollback on errors, commit otherwise.
    + c. All BeginTrans/CommitTrans/RollbackTrans inside a StartTrans/CompleteTrans block + are disabled, making it backward compatible. + */ + function StartTrans($errfn = 'ADODB_TransMonitor') + { + if ($this->transOff > 0) { + $this->transOff += 1; + return; + } + + $this->_oldRaiseFn = $this->raiseErrorFn; + $this->raiseErrorFn = $errfn; + $this->_transOK = true; + + if ($this->debug && $this->transCnt > 0) ADOConnection::outp("Bad Transaction: StartTrans called within BeginTrans"); + $this->BeginTrans(); + $this->transOff = 1; + } + + + /** + Used together with StartTrans() to end a transaction. Monitors connection + for sql errors, and will commit or rollback as appropriate. + + @autoComplete if true, monitor sql errors and commit and rollback as appropriate, + and if set to false force rollback even if no SQL error detected. + @returns true on commit, false on rollback. + */ + function CompleteTrans($autoComplete = true) + { + if ($this->transOff > 1) { + $this->transOff -= 1; + return true; + } + $this->raiseErrorFn = $this->_oldRaiseFn; + + $this->transOff = 0; + if ($this->_transOK && $autoComplete) { + if (!$this->CommitTrans()) { + $this->_transOK = false; + if ($this->debug) ADOConnection::outp("Smart Commit failed"); + } else + if ($this->debug) ADOConnection::outp("Smart Commit occurred"); + } else { + $this->_transOK = false; + $this->RollbackTrans(); + if ($this->debug) ADOCOnnection::outp("Smart Rollback occurred"); + } + + return $this->_transOK; + } + + /* + At the end of a StartTrans/CompleteTrans block, perform a rollback. + */ + function FailTrans() + { + if ($this->debug) + if ($this->transOff == 0) { + ADOConnection::outp("FailTrans outside StartTrans/CompleteTrans"); + } else { + ADOConnection::outp("FailTrans was called"); + adodb_backtrace(); + } + $this->_transOK = false; + } + + /** + Check if transaction has failed, only for Smart Transactions. + */ + function HasFailedTrans() + { + if ($this->transOff > 0) return $this->_transOK == false; + return false; + } + + /** + * Execute SQL + * + * @param sql SQL statement to execute, or possibly an array holding prepared statement ($sql[0] will hold sql text) + * @param [inputarr] holds the input data to bind to. Null elements will be set to null. + * @return RecordSet or false + */ + function &Execute($sql,$inputarr=false) + { + if ($this->fnExecute) { + $fn = $this->fnExecute; + $ret =& $fn($this,$sql,$inputarr); + if (isset($ret)) return $ret; + } + if ($inputarr) { + if (!is_array($inputarr)) $inputarr = array($inputarr); + + $element0 = reset($inputarr); + # is_object check because oci8 descriptors can be passed in + $array_2d = is_array($element0) && !is_object(reset($element0)); + //remove extra memory copy of input -mikefedyk + unset($element0); + + if (!is_array($sql) && !$this->_bindInputArray) { + $sqlarr = explode('?',$sql); + + if (!$array_2d) $inputarr = array($inputarr); + foreach($inputarr as $arr) { + $sql = ''; $i = 0; + //Use each() instead of foreach to reduce memory usage -mikefedyk + while(list(, $v) = each($arr)) { + $sql .= $sqlarr[$i]; + // from Ron Baldwin + // Only quote string types + $typ = gettype($v); + if ($typ == 'string') + //New memory copy of input created here -mikefedyk + $sql .= $this->qstr($v); + else if ($typ == 'double') + $sql .= str_replace(',','.',$v); // locales fix so 1.1 does not get converted to 1,1 + else if ($typ == 'boolean') + $sql .= $v ? $this->true : $this->false; + else if ($typ == 'object') { + if (method_exists($v, '__toString')) $sql .= $this->qstr($v->__toString()); + else $sql .= $this->qstr((string) $v); + } else if ($v === null) + $sql .= 'NULL'; + else + $sql .= $v; + $i += 1; + } + if (isset($sqlarr[$i])) { + $sql .= $sqlarr[$i]; + if ($i+1 != sizeof($sqlarr)) ADOConnection::outp( "Input Array does not match ?: ".htmlspecialchars($sql)); + } else if ($i != sizeof($sqlarr)) + ADOConnection::outp( "Input array does not match ?: ".htmlspecialchars($sql)); + + $ret =& $this->_Execute($sql); + if (!$ret) return $ret; + } + } else { + if ($array_2d) { + if (is_string($sql)) + $stmt = $this->Prepare($sql); + else + $stmt = $sql; + + foreach($inputarr as $arr) { + $ret =& $this->_Execute($stmt,$arr); + if (!$ret) return $ret; + } + } else { + $ret =& $this->_Execute($sql,$inputarr); + } + } + } else { + $ret =& $this->_Execute($sql,false); + } + + return $ret; + } + + + function &_Execute($sql,$inputarr=false) + { + if ($this->debug) { + global $ADODB_INCLUDED_LIB; + if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php'); + $this->_queryID = _adodb_debug_execute($this, $sql,$inputarr); + } else { + $this->_queryID = @$this->_query($sql,$inputarr); + } + + /************************ + // OK, query executed + *************************/ + + if ($this->_queryID === false) { // error handling if query fails + if ($this->debug == 99) adodb_backtrace(true,5); + $fn = $this->raiseErrorFn; + if ($fn) { + $fn($this->databaseType,'EXECUTE',$this->ErrorNo(),$this->ErrorMsg(),$sql,$inputarr,$this); + } + $false = false; + return $false; + } + + if ($this->_queryID === true) { // return simplified recordset for inserts/updates/deletes with lower overhead + $rsclass = $this->rsPrefix.'empty'; + $rs = (class_exists($rsclass)) ? new $rsclass(): new ADORecordSet_empty(); + + return $rs; + } + + // return real recordset from select statement + $rsclass = $this->rsPrefix.$this->databaseType; + $rs = new $rsclass($this->_queryID,$this->fetchMode); + $rs->connection = &$this; // Pablo suggestion + $rs->Init(); + if (is_array($sql)) $rs->sql = $sql[0]; + else $rs->sql = $sql; + if ($rs->_numOfRows <= 0) { + global $ADODB_COUNTRECS; + if ($ADODB_COUNTRECS) { + if (!$rs->EOF) { + $rs = &$this->_rs2rs($rs,-1,-1,!is_array($sql)); + $rs->_queryID = $this->_queryID; + } else + $rs->_numOfRows = 0; + } + } + return $rs; + } + + function CreateSequence($seqname='adodbseq',$startID=1) + { + if (empty($this->_genSeqSQL)) return false; + return $this->Execute(sprintf($this->_genSeqSQL,$seqname,$startID)); + } + + function DropSequence($seqname='adodbseq') + { + if (empty($this->_dropSeqSQL)) return false; + return $this->Execute(sprintf($this->_dropSeqSQL,$seqname)); + } + + /** + * Generates a sequence id and stores it in $this->genID; + * GenID is only available if $this->hasGenID = true; + * + * @param seqname name of sequence to use + * @param startID if sequence does not exist, start at this ID + * @return 0 if not supported, otherwise a sequence id + */ + function GenID($seqname='adodbseq',$startID=1) + { + if (!$this->hasGenID) { + return 0; // formerly returns false pre 1.60 + } + + $getnext = sprintf($this->_genIDSQL,$seqname); + + $holdtransOK = $this->_transOK; + + $save_handler = $this->raiseErrorFn; + $this->raiseErrorFn = ''; + @($rs = $this->Execute($getnext)); + $this->raiseErrorFn = $save_handler; + + if (!$rs) { + $this->_transOK = $holdtransOK; //if the status was ok before reset + $createseq = $this->Execute(sprintf($this->_genSeqSQL,$seqname,$startID)); + $rs = $this->Execute($getnext); + } + if ($rs && !$rs->EOF) $this->genID = reset($rs->fields); + else $this->genID = 0; // false + + if ($rs) $rs->Close(); + + return $this->genID; + } + + /** + * @param $table string name of the table, not needed by all databases (eg. mysql), default '' + * @param $column string name of the column, not needed by all databases (eg. mysql), default '' + * @return the last inserted ID. Not all databases support this. + */ + function Insert_ID($table='',$column='') + { + if ($this->_logsql && $this->lastInsID) return $this->lastInsID; + if ($this->hasInsertID) return $this->_insertid($table,$column); + if ($this->debug) { + ADOConnection::outp( '

    Insert_ID error

    '); + adodb_backtrace(); + } + return false; + } + + + /** + * Portable Insert ID. Pablo Roca + * + * @return the last inserted ID. All databases support this. But aware possible + * problems in multiuser environments. Heavy test this before deploying. + */ + function PO_Insert_ID($table="", $id="") + { + if ($this->hasInsertID){ + return $this->Insert_ID($table,$id); + } else { + return $this->GetOne("SELECT MAX($id) FROM $table"); + } + } + + /** + * @return # rows affected by UPDATE/DELETE + */ + function Affected_Rows() + { + if ($this->hasAffectedRows) { + if ($this->fnExecute === 'adodb_log_sql') { + if ($this->_logsql && $this->_affected !== false) return $this->_affected; + } + $val = $this->_affectedrows(); + return ($val < 0) ? false : $val; + } + + if ($this->debug) ADOConnection::outp( '

    Affected_Rows error

    ',false); + return false; + } + + + /** + * @return the last error message + */ + function ErrorMsg() + { + if ($this->_errorMsg) return '!! '.strtoupper($this->dataProvider.' '.$this->databaseType).': '.$this->_errorMsg; + else return ''; + } + + + /** + * @return the last error number. Normally 0 means no error. + */ + function ErrorNo() + { + return ($this->_errorMsg) ? -1 : 0; + } + + function MetaError($err=false) + { + include_once(ADODB_DIR."/adodb-error.inc.php"); + if ($err === false) $err = $this->ErrorNo(); + return adodb_error($this->dataProvider,$this->databaseType,$err); + } + + function MetaErrorMsg($errno) + { + include_once(ADODB_DIR."/adodb-error.inc.php"); + return adodb_errormsg($errno); + } + + /** + * @returns an array with the primary key columns in it. + */ + function MetaPrimaryKeys($table, $owner=false) + { + // owner not used in base class - see oci8 + $p = array(); + $objs =& $this->MetaColumns($table); + if ($objs) { + foreach($objs as $v) { + if (!empty($v->primary_key)) + $p[] = $v->name; + } + } + if (sizeof($p)) return $p; + if (function_exists('ADODB_VIEW_PRIMARYKEYS')) + return ADODB_VIEW_PRIMARYKEYS($this->databaseType, $this->database, $table, $owner); + return false; + } + + /** + * @returns assoc array where keys are tables, and values are foreign keys + */ + function MetaForeignKeys($table, $owner=false, $upper=false) + { + return false; + } + /** + * Choose a database to connect to. Many databases do not support this. + * + * @param dbName is the name of the database to select + * @return true or false + */ + function SelectDB($dbName) + {return false;} + + + /** + * Will select, getting rows from $offset (1-based), for $nrows. + * This simulates the MySQL "select * from table limit $offset,$nrows" , and + * the PostgreSQL "select * from table limit $nrows offset $offset". Note that + * MySQL and PostgreSQL parameter ordering is the opposite of the other. + * eg. + * SelectLimit('select * from table',3); will return rows 1 to 3 (1-based) + * SelectLimit('select * from table',3,2); will return rows 3 to 5 (1-based) + * + * Uses SELECT TOP for Microsoft databases (when $this->hasTop is set) + * BUG: Currently SelectLimit fails with $sql with LIMIT or TOP clause already set + * + * @param sql + * @param [offset] is the row to start calculations from (1-based) + * @param [nrows] is the number of rows to get + * @param [inputarr] array of bind variables + * @param [secs2cache] is a private parameter only used by jlim + * @return the recordset ($rs->databaseType == 'array') + */ + function &SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0) + { + if ($this->hasTop && $nrows > 0) { + // suggested by Reinhard Balling. Access requires top after distinct + // Informix requires first before distinct - F Riosa + $ismssql = (strpos($this->databaseType,'mssql') !== false); + if ($ismssql) $isaccess = false; + else $isaccess = (strpos($this->databaseType,'access') !== false); + + if ($offset <= 0) { + + // access includes ties in result + if ($isaccess) { + $sql = preg_replace( + '/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 '.$this->hasTop.' '.((integer)$nrows).' ',$sql); + + if ($secs2cache != 0) { + $ret =& $this->CacheExecute($secs2cache, $sql,$inputarr); + } else { + $ret =& $this->Execute($sql,$inputarr); + } + return $ret; // PHP5 fix + } else if ($ismssql){ + $sql = preg_replace( + '/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 '.$this->hasTop.' '.((integer)$nrows).' ',$sql); + } else { + $sql = preg_replace( + '/(^\s*select\s)/i','\\1 '.$this->hasTop.' '.((integer)$nrows).' ',$sql); + } + } else { + $nn = $nrows + $offset; + if ($isaccess || $ismssql) { + $sql = preg_replace( + '/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 '.$this->hasTop.' '.$nn.' ',$sql); + } else { + $sql = preg_replace( + '/(^\s*select\s)/i','\\1 '.$this->hasTop.' '.$nn.' ',$sql); + } + } + } + + // if $offset>0, we want to skip rows, and $ADODB_COUNTRECS is set, we buffer rows + // 0 to offset-1 which will be discarded anyway. So we disable $ADODB_COUNTRECS. + global $ADODB_COUNTRECS; + + $savec = $ADODB_COUNTRECS; + $ADODB_COUNTRECS = false; + + if ($offset>0){ + if ($secs2cache != 0) $rs = &$this->CacheExecute($secs2cache,$sql,$inputarr); + else $rs = &$this->Execute($sql,$inputarr); + } else { + if ($secs2cache != 0) $rs = &$this->CacheExecute($secs2cache,$sql,$inputarr); + else $rs = &$this->Execute($sql,$inputarr); + } + $ADODB_COUNTRECS = $savec; + if ($rs && !$rs->EOF) { + $rs =& $this->_rs2rs($rs,$nrows,$offset); + } + //print_r($rs); + return $rs; + } + + /** + * Create serializable recordset. Breaks rs link to connection. + * + * @param rs the recordset to serialize + */ + function &SerializableRS(&$rs) + { + $rs2 =& $this->_rs2rs($rs); + $ignore = false; + $rs2->connection =& $ignore; + + return $rs2; + } + + /** + * Convert database recordset to an array recordset + * input recordset's cursor should be at beginning, and + * old $rs will be closed. + * + * @param rs the recordset to copy + * @param [nrows] number of rows to retrieve (optional) + * @param [offset] offset by number of rows (optional) + * @return the new recordset + */ + function &_rs2rs(&$rs,$nrows=-1,$offset=-1,$close=true) + { + if (! $rs) { + $false = false; + return $false; + } + $dbtype = $rs->databaseType; + if (!$dbtype) { + $rs = &$rs; // required to prevent crashing in 4.2.1, but does not happen in 4.3.1 -- why ? + return $rs; + } + if (($dbtype == 'array' || $dbtype == 'csv') && $nrows == -1 && $offset == -1) { + $rs->MoveFirst(); + $rs = &$rs; // required to prevent crashing in 4.2.1, but does not happen in 4.3.1-- why ? + return $rs; + } + $flds = array(); + for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++) { + $flds[] = $rs->FetchField($i); + } + + $arr =& $rs->GetArrayLimit($nrows,$offset); + //print_r($arr); + if ($close) $rs->Close(); + + $arrayClass = $this->arrayClass; + + $rs2 = new $arrayClass(); + $rs2->connection = &$this; + $rs2->sql = $rs->sql; + $rs2->dataProvider = $this->dataProvider; + $rs2->InitArrayFields($arr,$flds); + $rs2->fetchMode = isset($rs->adodbFetchMode) ? $rs->adodbFetchMode : $rs->fetchMode; + return $rs2; + } + + /* + * Return all rows. Compat with PEAR DB + */ + function &GetAll($sql, $inputarr=false) + { + $arr =& $this->GetArray($sql,$inputarr); + return $arr; + } + + function &GetAssoc($sql, $inputarr=false,$force_array = false, $first2cols = false) + { + $rs =& $this->Execute($sql, $inputarr); + if (!$rs) { + $false = false; + return $false; + } + $arr =& $rs->GetAssoc($force_array,$first2cols); + return $arr; + } + + function &CacheGetAssoc($secs2cache, $sql=false, $inputarr=false,$force_array = false, $first2cols = false) + { + if (!is_numeric($secs2cache)) { + $first2cols = $force_array; + $force_array = $inputarr; + } + $rs =& $this->CacheExecute($secs2cache, $sql, $inputarr); + if (!$rs) { + $false = false; + return $false; + } + $arr =& $rs->GetAssoc($force_array,$first2cols); + return $arr; + } + + /** + * Return first element of first row of sql statement. Recordset is disposed + * for you. + * + * @param sql SQL statement + * @param [inputarr] input bind array + */ + function GetOne($sql,$inputarr=false) + { + global $ADODB_COUNTRECS; + $crecs = $ADODB_COUNTRECS; + $ADODB_COUNTRECS = false; + + $ret = false; + $rs = &$this->Execute($sql,$inputarr); + if ($rs) { + if ($rs->EOF) $ret = null; + else $ret = reset($rs->fields); + + $rs->Close(); + } + $ADODB_COUNTRECS = $crecs; + return $ret; + } + + function CacheGetOne($secs2cache,$sql=false,$inputarr=false) + { + $ret = false; + $rs = &$this->CacheExecute($secs2cache,$sql,$inputarr); + if ($rs) { + if ($rs->EOF) $ret = null; + else $ret = reset($rs->fields); + $rs->Close(); + } + + return $ret; + } + + function GetCol($sql, $inputarr = false, $trim = false) + { + $rv = false; + $rs = &$this->Execute($sql, $inputarr); + if ($rs) { + $rv = array(); + if ($trim) { + while (!$rs->EOF) { + $rv[] = trim(reset($rs->fields)); + $rs->MoveNext(); + } + } else { + while (!$rs->EOF) { + $rv[] = reset($rs->fields); + $rs->MoveNext(); + } + } + $rs->Close(); + } + return $rv; + } + + function CacheGetCol($secs, $sql = false, $inputarr = false,$trim=false) + { + $rv = false; + $rs = &$this->CacheExecute($secs, $sql, $inputarr); + if ($rs) { + if ($trim) { + while (!$rs->EOF) { + $rv[] = trim(reset($rs->fields)); + $rs->MoveNext(); + } + } else { + while (!$rs->EOF) { + $rv[] = reset($rs->fields); + $rs->MoveNext(); + } + } + $rs->Close(); + } + return $rv; + } + + function &Transpose(&$rs,$addfieldnames=true) + { + $rs2 =& $this->_rs2rs($rs); + $false = false; + if (!$rs2) return $false; + + $rs2->_transpose($addfieldnames); + return $rs2; + } + + /* + Calculate the offset of a date for a particular database and generate + appropriate SQL. Useful for calculating future/past dates and storing + in a database. + + If dayFraction=1.5 means 1.5 days from now, 1.0/24 for 1 hour. + */ + function OffsetDate($dayFraction,$date=false) + { + if (!$date) $date = $this->sysDate; + return '('.$date.'+'.$dayFraction.')'; + } + + + /** + * + * @param sql SQL statement + * @param [inputarr] input bind array + */ + function &GetArray($sql,$inputarr=false) + { + global $ADODB_COUNTRECS; + + $savec = $ADODB_COUNTRECS; + $ADODB_COUNTRECS = false; + $rs =& $this->Execute($sql,$inputarr); + $ADODB_COUNTRECS = $savec; + if (!$rs) + if (defined('ADODB_PEAR')) { + $cls = ADODB_PEAR_Error(); + return $cls; + } else { + $false = false; + return $false; + } + $arr =& $rs->GetArray(); + $rs->Close(); + return $arr; + } + + function &CacheGetAll($secs2cache,$sql=false,$inputarr=false) + { + $arr =& $this->CacheGetArray($secs2cache,$sql,$inputarr); + return $arr; + } + + function &CacheGetArray($secs2cache,$sql=false,$inputarr=false) + { + global $ADODB_COUNTRECS; + + $savec = $ADODB_COUNTRECS; + $ADODB_COUNTRECS = false; + $rs =& $this->CacheExecute($secs2cache,$sql,$inputarr); + $ADODB_COUNTRECS = $savec; + + if (!$rs) + if (defined('ADODB_PEAR')) { + $cls = ADODB_PEAR_Error(); + return $cls; + } else { + $false = false; + return $false; + } + $arr =& $rs->GetArray(); + $rs->Close(); + return $arr; + } + + function GetRandRow($sql, $arr= false) + { + $rezarr = $this->GetAll($sql, $arr); + $sz = sizeof($rez); + return $rezarr[abs(rand()) % $sz]; + } + + /** + * Return one row of sql statement. Recordset is disposed for you. + * + * @param sql SQL statement + * @param [inputarr] input bind array + */ + function &GetRow($sql,$inputarr=false) + { + global $ADODB_COUNTRECS; + $crecs = $ADODB_COUNTRECS; + $ADODB_COUNTRECS = false; + + $rs =& $this->Execute($sql,$inputarr); + + $ADODB_COUNTRECS = $crecs; + if ($rs) { + if (!$rs->EOF) $arr = $rs->fields; + else $arr = array(); + $rs->Close(); + return $arr; + } + + $false = false; + return $false; + } + + function &CacheGetRow($secs2cache,$sql=false,$inputarr=false) + { + $rs =& $this->CacheExecute($secs2cache,$sql,$inputarr); + if ($rs) { + $arr = false; + if (!$rs->EOF) $arr = $rs->fields; + $rs->Close(); + return $arr; + } + $false = false; + return $false; + } + + /** + * Insert or replace a single record. Note: this is not the same as MySQL's replace. + * ADOdb's Replace() uses update-insert semantics, not insert-delete-duplicates of MySQL. + * Also note that no table locking is done currently, so it is possible that the + * record be inserted twice by two programs... + * + * $this->Replace('products', array('prodname' =>"'Nails'","price" => 3.99), 'prodname'); + * + * $table table name + * $fieldArray associative array of data (you must quote strings yourself). + * $keyCol the primary key field name or if compound key, array of field names + * autoQuote set to true to use a hueristic to quote strings. Works with nulls and numbers + * but does not work with dates nor SQL functions. + * has_autoinc the primary key is an auto-inc field, so skip in insert. + * + * Currently blob replace not supported + * + * returns 0 = fail, 1 = update, 2 = insert + */ + + function Replace($table, $fieldArray, $keyCol, $autoQuote=false, $has_autoinc=false) + { + global $ADODB_INCLUDED_LIB; + if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php'); + + return _adodb_replace($this, $table, $fieldArray, $keyCol, $autoQuote, $has_autoinc); + } + + + /** + * Will select, getting rows from $offset (1-based), for $nrows. + * This simulates the MySQL "select * from table limit $offset,$nrows" , and + * the PostgreSQL "select * from table limit $nrows offset $offset". Note that + * MySQL and PostgreSQL parameter ordering is the opposite of the other. + * eg. + * CacheSelectLimit(15,'select * from table',3); will return rows 1 to 3 (1-based) + * CacheSelectLimit(15,'select * from table',3,2); will return rows 3 to 5 (1-based) + * + * BUG: Currently CacheSelectLimit fails with $sql with LIMIT or TOP clause already set + * + * @param [secs2cache] seconds to cache data, set to 0 to force query. This is optional + * @param sql + * @param [offset] is the row to start calculations from (1-based) + * @param [nrows] is the number of rows to get + * @param [inputarr] array of bind variables + * @return the recordset ($rs->databaseType == 'array') + */ + function &CacheSelectLimit($secs2cache,$sql,$nrows=-1,$offset=-1,$inputarr=false) + { + if (!is_numeric($secs2cache)) { + if ($sql === false) $sql = -1; + if ($offset == -1) $offset = false; + // sql, nrows, offset,inputarr + $rs =& $this->SelectLimit($secs2cache,$sql,$nrows,$offset,$this->cacheSecs); + } else { + if ($sql === false) ADOConnection::outp( "Warning: \$sql missing from CacheSelectLimit()"); + $rs =& $this->SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache); + } + return $rs; + } + + + /** + * Flush cached recordsets that match a particular $sql statement. + * If $sql == false, then we purge all files in the cache. + */ + + /** + * Flush cached recordsets that match a particular $sql statement. + * If $sql == false, then we purge all files in the cache. + */ + function CacheFlush($sql=false,$inputarr=false) + { + global $ADODB_CACHE_DIR; + + if ($this->memCache) { + global $ADODB_INCLUDED_MEMCACHE; + + $key = false; + if (empty($ADODB_INCLUDED_MEMCACHE)) include(ADODB_DIR.'/adodb-memcache.lib.inc.php'); + if ($sql) $key = $this->_gencachename($sql.serialize($inputarr),false,true); + FlushMemCache($key, $this->memCacheHost, $this->memCachePort, $this->debug); + return; + } + + if (strlen($ADODB_CACHE_DIR) > 1 && !$sql) { + /*if (strncmp(PHP_OS,'WIN',3) === 0) + $dir = str_replace('/', '\\', $ADODB_CACHE_DIR); + else */ + $dir = $ADODB_CACHE_DIR; + + if ($this->debug) { + ADOConnection::outp( "CacheFlush: $dir
    \n". $this->_dirFlush($dir)."
    "); + } else { + $this->_dirFlush($dir); + } + return; + } + + global $ADODB_INCLUDED_CSV; + if (empty($ADODB_INCLUDED_CSV)) include(ADODB_DIR.'/adodb-csvlib.inc.php'); + + $f = $this->_gencachename($sql.serialize($inputarr),false); + adodb_write_file($f,''); // is adodb_write_file needed? + if (!@unlink($f)) { + if ($this->debug) ADOConnection::outp( "CacheFlush: failed for $f"); + } + } + + /** + * Private function to erase all of the files and subdirectories in a directory. + * + * Just specify the directory, and tell it if you want to delete the directory or just clear it out. + * Note: $kill_top_level is used internally in the function to flush subdirectories. + */ + function _dirFlush($dir, $kill_top_level = false) + { + if(!$dh = @opendir($dir)) return; + + while (($obj = readdir($dh))) { + if($obj=='.' || $obj=='..') continue; + $f = $dir.'/'.$obj; + + if (strpos($obj,'.cache')) @unlink($f); + if (is_dir($f)) $this->_dirFlush($f, true); + } + if ($kill_top_level === true) @rmdir($dir); + return true; + } + + + function xCacheFlush($sql=false,$inputarr=false) + { + global $ADODB_CACHE_DIR; + + if ($this->memCache) { + global $ADODB_INCLUDED_MEMCACHE; + $key = false; + if (empty($ADODB_INCLUDED_MEMCACHE)) include(ADODB_DIR.'/adodb-memcache.lib.inc.php'); + if ($sql) $key = $this->_gencachename($sql.serialize($inputarr),false,true); + flushmemCache($key, $this->memCacheHost, $this->memCachePort, $this->debug); + return; + } + + if (strlen($ADODB_CACHE_DIR) > 1 && !$sql) { + if (strncmp(PHP_OS,'WIN',3) === 0) { + $cmd = 'del /s '.str_replace('/','\\',$ADODB_CACHE_DIR).'\adodb_*.cache'; + } else { + //$cmd = 'find "'.$ADODB_CACHE_DIR.'" -type f -maxdepth 1 -print0 | xargs -0 rm -f'; + $cmd = 'rm -rf '.$ADODB_CACHE_DIR.'/[0-9a-f][0-9a-f]/'; + // old version 'rm -f `find '.$ADODB_CACHE_DIR.' -name adodb_*.cache`'; + } + if ($this->debug) { + ADOConnection::outp( "CacheFlush: $cmd
    \n", system($cmd),"
    "); + } else { + exec($cmd); + } + return; + } + + global $ADODB_INCLUDED_CSV; + if (empty($ADODB_INCLUDED_CSV)) include(ADODB_DIR.'/adodb-csvlib.inc.php'); + + $f = $this->_gencachename($sql.serialize($inputarr),false); + adodb_write_file($f,''); // is adodb_write_file needed? + if (!@unlink($f)) { + if ($this->debug) ADOConnection::outp( "CacheFlush: failed for $f"); + } + } + + /** + * Private function to generate filename for caching. + * Filename is generated based on: + * + * - sql statement + * - database type (oci8, ibase, ifx, etc) + * - database name + * - userid + * - setFetchMode (adodb 4.23) + * + * When not in safe mode, we create 256 sub-directories in the cache directory ($ADODB_CACHE_DIR). + * Assuming that we can have 50,000 files per directory with good performance, + * then we can scale to 12.8 million unique cached recordsets. Wow! + */ + function _gencachename($sql,$createdir,$memcache=false) + { + global $ADODB_CACHE_DIR; + static $notSafeMode; + + if ($this->fetchMode === false) { + global $ADODB_FETCH_MODE; + $mode = $ADODB_FETCH_MODE; + } else { + $mode = $this->fetchMode; + } + $m = md5($sql.$this->databaseType.$this->database.$this->user.$mode); + if ($memcache) return $m; + + if (!isset($notSafeMode)) $notSafeMode = !ini_get('safe_mode'); + $dir = ($notSafeMode) ? $ADODB_CACHE_DIR.'/'.substr($m,0,2) : $ADODB_CACHE_DIR; + + if ($createdir && $notSafeMode && !file_exists($dir)) { + $oldu = umask(0); + if (!mkdir($dir,0771)) + if ($this->debug) ADOConnection::outp( "Unable to mkdir $dir for $sql"); + umask($oldu); + } + return $dir.'/adodb_'.$m.'.cache'; + } + + + /** + * Execute SQL, caching recordsets. + * + * @param [secs2cache] seconds to cache data, set to 0 to force query. + * This is an optional parameter. + * @param sql SQL statement to execute + * @param [inputarr] holds the input data to bind to + * @return RecordSet or false + */ + function &CacheExecute($secs2cache,$sql=false,$inputarr=false) + { + + + if (!is_numeric($secs2cache)) { + $inputarr = $sql; + $sql = $secs2cache; + $secs2cache = $this->cacheSecs; + } + + if (is_array($sql)) { + $sqlparam = $sql; + $sql = $sql[0]; + } else + $sqlparam = $sql; + + if ($this->memCache) { + global $ADODB_INCLUDED_MEMCACHE; + if (empty($ADODB_INCLUDED_MEMCACHE)) include(ADODB_DIR.'/adodb-memcache.lib.inc.php'); + $md5file = $this->_gencachename($sql.serialize($inputarr),false,true); + } else { + global $ADODB_INCLUDED_CSV; + if (empty($ADODB_INCLUDED_CSV)) include(ADODB_DIR.'/adodb-csvlib.inc.php'); + $md5file = $this->_gencachename($sql.serialize($inputarr),true); + } + + $err = ''; + + if ($secs2cache > 0){ + if ($this->memCache) + $rs = &getmemCache($md5file,$err,$secs2cache, $this->memCacheHost, $this->memCachePort); + else + $rs = &csv2rs($md5file,$err,$secs2cache,$this->arrayClass); + $this->numCacheHits += 1; + } else { + $err='Timeout 1'; + $rs = false; + $this->numCacheMisses += 1; + } + if (!$rs) { + // no cached rs found + if ($this->debug) { + if (get_magic_quotes_runtime() && !$this->memCache) { + ADOConnection::outp("Please disable magic_quotes_runtime - it corrupts cache files :("); + } + if ($this->debug !== -1) ADOConnection::outp( " $md5file cache failure: $err (see sql below)"); + } + + $rs = &$this->Execute($sqlparam,$inputarr); + + if ($rs && $this->memCache) { + $rs = &$this->_rs2rs($rs); // read entire recordset into memory immediately + if(!putmemCache($md5file, $rs, $this->memCacheHost, $this->memCachePort, $this->memCacheCompress, $this->debug)) { + if ($fn = $this->raiseErrorFn) + $fn($this->databaseType,'CacheExecute',-32000,"Cache write error",$md5file,$sql,$this); + if ($this->debug) ADOConnection::outp( " Cache write error"); + } + } else + if ($rs) { + $eof = $rs->EOF; + $rs = &$this->_rs2rs($rs); // read entire recordset into memory immediately + $txt = _rs2serialize($rs,false,$sql); // serialize + + if (!adodb_write_file($md5file,$txt,$this->debug)) { + if ($fn = $this->raiseErrorFn) { + $fn($this->databaseType,'CacheExecute',-32000,"Cache write error",$md5file,$sql,$this); + } + if ($this->debug) ADOConnection::outp( " Cache write error"); + } + if ($rs->EOF && !$eof) { + $rs->MoveFirst(); + //$rs = &csv2rs($md5file,$err); + $rs->connection = &$this; // Pablo suggestion + } + + } else + if (!$this->memCache) + @unlink($md5file); + } else { + $this->_errorMsg = ''; + $this->_errorCode = 0; + + if ($this->fnCacheExecute) { + $fn = $this->fnCacheExecute; + $fn($this, $secs2cache, $sql, $inputarr); + } + // ok, set cached object found + $rs->connection = &$this; // Pablo suggestion + if ($this->debug){ + + $inBrowser = isset($_SERVER['HTTP_USER_AGENT']); + $ttl = $rs->timeCreated + $secs2cache - time(); + $s = is_array($sql) ? $sql[0] : $sql; + if ($inBrowser) $s = ''.htmlspecialchars($s).''; + + ADOConnection::outp( " $md5file reloaded, ttl=$ttl [ $s ]"); + } + } + return $rs; + } + + + /* + Similar to PEAR DB's autoExecute(), except that + $mode can be 'INSERT' or 'UPDATE' or DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE + If $mode == 'UPDATE', then $where is compulsory as a safety measure. + + $forceUpdate means that even if the data has not changed, perform update. + */ + function& AutoExecute($table, $fields_values, $mode = 'INSERT', $where = FALSE, $forceUpdate=true, $magicq=false) + { + $false = false; + $sql = 'SELECT * FROM '.$table; + if ($where!==FALSE) $sql .= ' WHERE '.$where; + else if ($mode == 'UPDATE' || $mode == 2 /* DB_AUTOQUERY_UPDATE */) { + ADOConnection::outp('AutoExecute: Illegal mode=UPDATE with empty WHERE clause'); + return $false; + } + + $rs =& $this->SelectLimit($sql,1); + if (!$rs) return $false; // table does not exist + $rs->tableName = $table; + + switch((string) $mode) { + case 'UPDATE': + case '2': + $sql = $this->GetUpdateSQL($rs, $fields_values, $forceUpdate, $magicq); + break; + case 'INSERT': + case '1': + $sql = $this->GetInsertSQL($rs, $fields_values, $magicq); + break; + default: + ADOConnection::outp("AutoExecute: Unknown mode=$mode"); + return $false; + } + $ret = false; + if ($sql) $ret = $this->Execute($sql); + if ($ret) $ret = true; + return $ret; + } + + + /** + * Generates an Update Query based on an existing recordset. + * $arrFields is an associative array of fields with the value + * that should be assigned. + * + * Note: This function should only be used on a recordset + * that is run against a single table and sql should only + * be a simple select stmt with no groupby/orderby/limit + * + * "Jonathan Younger" + */ + function GetUpdateSQL(&$rs, $arrFields,$forceUpdate=false,$magicq=false,$force=null) + { + global $ADODB_INCLUDED_LIB; + + //********************************************************// + //This is here to maintain compatibility + //with older adodb versions. Sets force type to force nulls if $forcenulls is set. + if (!isset($force)) { + global $ADODB_FORCE_TYPE; + $force = $ADODB_FORCE_TYPE; + } + //********************************************************// + + if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php'); + return _adodb_getupdatesql($this,$rs,$arrFields,$forceUpdate,$magicq,$force); + } + + /** + * Generates an Insert Query based on an existing recordset. + * $arrFields is an associative array of fields with the value + * that should be assigned. + * + * Note: This function should only be used on a recordset + * that is run against a single table. + */ + function GetInsertSQL(&$rs, $arrFields,$magicq=false,$force=null) + { + global $ADODB_INCLUDED_LIB; + if (!isset($force)) { + global $ADODB_FORCE_TYPE; + $force = $ADODB_FORCE_TYPE; + + } + if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php'); + return _adodb_getinsertsql($this,$rs,$arrFields,$magicq,$force); + } + + + /** + * Update a blob column, given a where clause. There are more sophisticated + * blob handling functions that we could have implemented, but all require + * a very complex API. Instead we have chosen something that is extremely + * simple to understand and use. + * + * Note: $blobtype supports 'BLOB' and 'CLOB', default is BLOB of course. + * + * Usage to update a $blobvalue which has a primary key blob_id=1 into a + * field blobtable.blobcolumn: + * + * UpdateBlob('blobtable', 'blobcolumn', $blobvalue, 'blob_id=1'); + * + * Insert example: + * + * $conn->Execute('INSERT INTO blobtable (id, blobcol) VALUES (1, null)'); + * $conn->UpdateBlob('blobtable','blobcol',$blob,'id=1'); + */ + + function UpdateBlob($table,$column,$val,$where,$blobtype='BLOB') + { + return $this->Execute("UPDATE $table SET $column=? WHERE $where",array($val)) != false; + } + + /** + * Usage: + * UpdateBlob('TABLE', 'COLUMN', '/path/to/file', 'ID=1'); + * + * $blobtype supports 'BLOB' and 'CLOB' + * + * $conn->Execute('INSERT INTO blobtable (id, blobcol) VALUES (1, null)'); + * $conn->UpdateBlob('blobtable','blobcol',$blobpath,'id=1'); + */ + function UpdateBlobFile($table,$column,$path,$where,$blobtype='BLOB') + { + $fd = fopen($path,'rb'); + if ($fd === false) return false; + $val = fread($fd,filesize($path)); + fclose($fd); + return $this->UpdateBlob($table,$column,$val,$where,$blobtype); + } + + function BlobDecode($blob) + { + return $blob; + } + + function BlobEncode($blob) + { + return $blob; + } + + function SetCharSet($charset) + { + return false; + } + + function IfNull( $field, $ifNull ) + { + return " CASE WHEN $field is null THEN $ifNull ELSE $field END "; + } + + function LogSQL($enable=true) + { + include_once(ADODB_DIR.'/adodb-perf.inc.php'); + + if ($enable) $this->fnExecute = 'adodb_log_sql'; + else $this->fnExecute = false; + + $old = $this->_logsql; + $this->_logsql = $enable; + if ($enable && !$old) $this->_affected = false; + return $old; + } + + function GetCharSet() + { + return false; + } + + /** + * Usage: + * UpdateClob('TABLE', 'COLUMN', $var, 'ID=1', 'CLOB'); + * + * $conn->Execute('INSERT INTO clobtable (id, clobcol) VALUES (1, null)'); + * $conn->UpdateClob('clobtable','clobcol',$clob,'id=1'); + */ + function UpdateClob($table,$column,$val,$where) + { + return $this->UpdateBlob($table,$column,$val,$where,'CLOB'); + } + + // not the fastest implementation - quick and dirty - jlim + // for best performance, use the actual $rs->MetaType(). + function MetaType($t,$len=-1,$fieldobj=false) + { + + if (empty($this->_metars)) { + $rsclass = $this->rsPrefix.$this->databaseType; + $this->_metars = new $rsclass(false,$this->fetchMode); + $this->_metars->connection =& $this; + } + return $this->_metars->MetaType($t,$len,$fieldobj); + } + + + /** + * Change the SQL connection locale to a specified locale. + * This is used to get the date formats written depending on the client locale. + */ + function SetDateLocale($locale = 'En') + { + $this->locale = $locale; + switch (strtoupper($locale)) + { + case 'EN': + $this->fmtDate="'Y-m-d'"; + $this->fmtTimeStamp = "'Y-m-d H:i:s'"; + break; + + case 'US': + $this->fmtDate = "'m-d-Y'"; + $this->fmtTimeStamp = "'m-d-Y H:i:s'"; + break; + + case 'PT_BR': + case 'NL': + case 'FR': + case 'RO': + case 'IT': + $this->fmtDate="'d-m-Y'"; + $this->fmtTimeStamp = "'d-m-Y H:i:s'"; + break; + + case 'GE': + $this->fmtDate="'d.m.Y'"; + $this->fmtTimeStamp = "'d.m.Y H:i:s'"; + break; + + default: + $this->fmtDate="'Y-m-d'"; + $this->fmtTimeStamp = "'Y-m-d H:i:s'"; + break; + } + } + + function &GetActiveRecordsClass($class, $table,$whereOrderBy=false,$bindarr=false, $primkeyArr=false) + { + global $_ADODB_ACTIVE_DBS; + + $save = $this->SetFetchMode(ADODB_FETCH_NUM); + if (empty($whereOrderBy)) $whereOrderBy = '1=1'; + $rows = $this->GetAll("select * from ".$table.' WHERE '.$whereOrderBy,$bindarr); + $this->SetFetchMode($save); + + $false = false; + + if ($rows === false) { + return $false; + } + + + if (!isset($_ADODB_ACTIVE_DBS)) { + include(ADODB_DIR.'/adodb-active-record.inc.php'); + } + if (!class_exists($class)) { + ADOConnection::outp("Unknown class $class in GetActiveRcordsClass()"); + return $false; + } + $arr = array(); + foreach($rows as $row) { + + $obj = new $class($table,$primkeyArr,$this); + if ($obj->ErrorMsg()){ + $this->_errorMsg = $obj->ErrorMsg(); + return $false; + } + $obj->Set($row); + $arr[] = $obj; + } + return $arr; + } + + function &GetActiveRecords($table,$where=false,$bindarr=false,$primkeyArr=false) + { + $arr =& $this->GetActiveRecordsClass('ADODB_Active_Record', $table, $where, $bindarr, $primkeyArr); + return $arr; + } + + /** + * Close Connection + */ + function Close() + { + $rez = $this->_close(); + $this->_connectionID = false; + return $rez; + } + + /** + * Begin a Transaction. Must be followed by CommitTrans() or RollbackTrans(). + * + * @return true if succeeded or false if database does not support transactions + */ + function BeginTrans() + { + if ($this->debug) ADOConnection::outp("BeginTrans: Transactions not supported for this driver"); + return false; + } + + /* set transaction mode */ + function SetTransactionMode( $transaction_mode ) + { + $transaction_mode = $this->MetaTransaction($transaction_mode, $this->dataProvider); + $this->_transmode = $transaction_mode; + } +/* +http://msdn2.microsoft.com/en-US/ms173763.aspx +http://dev.mysql.com/doc/refman/5.0/en/innodb-transaction-isolation.html +http://www.postgresql.org/docs/8.1/interactive/sql-set-transaction.html +http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_10005.htm +*/ + function MetaTransaction($mode,$db) + { + $mode = strtoupper($mode); + $mode = str_replace('ISOLATION LEVEL ','',$mode); + + switch($mode) { + + case 'READ UNCOMMITTED': + switch($db) { + case 'oci8': + case 'oracle': + return 'ISOLATION LEVEL READ COMMITTED'; + default: + return 'ISOLATION LEVEL READ UNCOMMITTED'; + } + break; + + case 'READ COMMITTED': + return 'ISOLATION LEVEL READ COMMITTED'; + break; + + case 'REPEATABLE READ': + switch($db) { + case 'oci8': + case 'oracle': + return 'ISOLATION LEVEL SERIALIZABLE'; + default: + return 'ISOLATION LEVEL REPEATABLE READ'; + } + break; + + case 'SERIALIZABLE': + return 'ISOLATION LEVEL SERIALIZABLE'; + break; + + default: + return $mode; + } + } + + /** + * If database does not support transactions, always return true as data always commited + * + * @param $ok set to false to rollback transaction, true to commit + * + * @return true/false. + */ + function CommitTrans($ok=true) + { return true;} + + + /** + * If database does not support transactions, rollbacks always fail, so return false + * + * @return true/false. + */ + function RollbackTrans() + { return false;} + + + /** + * return the databases that the driver can connect to. + * Some databases will return an empty array. + * + * @return an array of database names. + */ + function MetaDatabases() + { + global $ADODB_FETCH_MODE; + + if ($this->metaDatabasesSQL) { + $save = $ADODB_FETCH_MODE; + $ADODB_FETCH_MODE = ADODB_FETCH_NUM; + + if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false); + + $arr = $this->GetCol($this->metaDatabasesSQL); + if (isset($savem)) $this->SetFetchMode($savem); + $ADODB_FETCH_MODE = $save; + + return $arr; + } + + return false; + } + + + /** + * @param ttype can either be 'VIEW' or 'TABLE' or false. + * If false, both views and tables are returned. + * "VIEW" returns only views + * "TABLE" returns only tables + * @param showSchema returns the schema/user with the table name, eg. USER.TABLE + * @param mask is the input mask - only supported by oci8 and postgresql + * + * @return array of tables for current database. + */ + function &MetaTables($ttype=false,$showSchema=false,$mask=false) + { + global $ADODB_FETCH_MODE; + + + $false = false; + if ($mask) { + return $false; + } + if ($this->metaTablesSQL) { + $save = $ADODB_FETCH_MODE; + $ADODB_FETCH_MODE = ADODB_FETCH_NUM; + + if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false); + + $rs = $this->Execute($this->metaTablesSQL); + if (isset($savem)) $this->SetFetchMode($savem); + $ADODB_FETCH_MODE = $save; + + if ($rs === false) return $false; + $arr =& $rs->GetArray(); + $arr2 = array(); + + if ($hast = ($ttype && isset($arr[0][1]))) { + $showt = strncmp($ttype,'T',1); + } + + for ($i=0; $i < sizeof($arr); $i++) { + if ($hast) { + if ($showt == 0) { + if (strncmp($arr[$i][1],'T',1) == 0) $arr2[] = trim($arr[$i][0]); + } else { + if (strncmp($arr[$i][1],'V',1) == 0) $arr2[] = trim($arr[$i][0]); + } + } else + $arr2[] = trim($arr[$i][0]); + } + $rs->Close(); + return $arr2; + } + return $false; + } + + + function _findschema(&$table,&$schema) + { + if (!$schema && ($at = strpos($table,'.')) !== false) { + $schema = substr($table,0,$at); + $table = substr($table,$at+1); + } + } + + /** + * List columns in a database as an array of ADOFieldObjects. + * See top of file for definition of object. + * + * @param $table table name to query + * @param $normalize makes table name case-insensitive (required by some databases) + * @schema is optional database schema to use - not supported by all databases. + * + * @return array of ADOFieldObjects for current table. + */ + function &MetaColumns($table,$normalize=true) + { + global $ADODB_FETCH_MODE; + + $false = false; + + if (!empty($this->metaColumnsSQL)) { + + $schema = false; + $this->_findschema($table,$schema); + + $save = $ADODB_FETCH_MODE; + $ADODB_FETCH_MODE = ADODB_FETCH_NUM; + if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false); + $rs = $this->Execute(sprintf($this->metaColumnsSQL,($normalize)?strtoupper($table):$table)); + if (isset($savem)) $this->SetFetchMode($savem); + $ADODB_FETCH_MODE = $save; + if ($rs === false || $rs->EOF) return $false; + + $retarr = array(); + while (!$rs->EOF) { //print_r($rs->fields); + $fld = new ADOFieldObject(); + $fld->name = $rs->fields[0]; + $fld->type = $rs->fields[1]; + if (isset($rs->fields[3]) && $rs->fields[3]) { + if ($rs->fields[3]>0) $fld->max_length = $rs->fields[3]; + $fld->scale = $rs->fields[4]; + if ($fld->scale>0) $fld->max_length += 1; + } else + $fld->max_length = $rs->fields[2]; + + if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] = $fld; + else $retarr[strtoupper($fld->name)] = $fld; + $rs->MoveNext(); + } + $rs->Close(); + return $retarr; + } + return $false; + } + + /** + * List indexes on a table as an array. + * @param table table name to query + * @param primary true to only show primary keys. Not actually used for most databases + * + * @return array of indexes on current table. Each element represents an index, and is itself an associative array. + + Array ( + [name_of_index] => Array + ( + [unique] => true or false + [columns] => Array + ( + [0] => firstname + [1] => lastname + ) + ) + */ + function &MetaIndexes($table, $primary = false, $owner = false) + { + $false = false; + return $false; + } + + /** + * List columns names in a table as an array. + * @param table table name to query + * + * @return array of column names for current table. + */ + function &MetaColumnNames($table, $numIndexes=false,$useattnum=false /* only for postgres */) + { + $objarr =& $this->MetaColumns($table); + if (!is_array($objarr)) { + $false = false; + return $false; + } + $arr = array(); + if ($numIndexes) { + $i = 0; + if ($useattnum) { + foreach($objarr as $v) + $arr[$v->attnum] = $v->name; + + } else + foreach($objarr as $v) $arr[$i++] = $v->name; + } else + foreach($objarr as $v) $arr[strtoupper($v->name)] = $v->name; + + return $arr; + } + + /** + * Different SQL databases used different methods to combine strings together. + * This function provides a wrapper. + * + * param s variable number of string parameters + * + * Usage: $db->Concat($str1,$str2); + * + * @return concatenated string + */ + function Concat() + { + $arr = func_get_args(); + return implode($this->concat_operator, $arr); + } + + + /** + * Converts a date "d" to a string that the database can understand. + * + * @param d a date in Unix date time format. + * + * @return date string in database date format + */ + function DBDate($d) + { + if (empty($d) && $d !== 0) return 'null'; + + if (is_string($d) && !is_numeric($d)) { + if ($d === 'null' || strncmp($d,"'",1) === 0) return $d; + if ($this->isoDates) return "'$d'"; + $d = ADOConnection::UnixDate($d); + } + + return adodb_date($this->fmtDate,$d); + } + + function BindDate($d) + { + $d = $this->DBDate($d); + if (strncmp($d,"'",1)) return $d; + + return substr($d,1,strlen($d)-2); + } + + function BindTimeStamp($d) + { + $d = $this->DBTimeStamp($d); + if (strncmp($d,"'",1)) return $d; + + return substr($d,1,strlen($d)-2); + } + + + /** + * Converts a timestamp "ts" to a string that the database can understand. + * + * @param ts a timestamp in Unix date time format. + * + * @return timestamp string in database timestamp format + */ + function DBTimeStamp($ts) + { + if (empty($ts) && $ts !== 0) return 'null'; + + # strlen(14) allows YYYYMMDDHHMMSS format + if (!is_string($ts) || (is_numeric($ts) && strlen($ts)<14)) + return adodb_date($this->fmtTimeStamp,$ts); + + if ($ts === 'null') return $ts; + if ($this->isoDates && strlen($ts) !== 14) return "'$ts'"; + + $ts = ADOConnection::UnixTimeStamp($ts); + return adodb_date($this->fmtTimeStamp,$ts); + } + + /** + * Also in ADORecordSet. + * @param $v is a date string in YYYY-MM-DD format + * + * @return date in unix timestamp format, or 0 if before TIMESTAMP_FIRST_YEAR, or false if invalid date format + */ + function UnixDate($v) + { + if (is_object($v)) { + // odbtp support + //( [year] => 2004 [month] => 9 [day] => 4 [hour] => 12 [minute] => 44 [second] => 8 [fraction] => 0 ) + return adodb_mktime($v->hour,$v->minute,$v->second,$v->month,$v->day, $v->year); + } + + if (is_numeric($v) && strlen($v) !== 8) return $v; + if (!preg_match( "|^([0-9]{4})[-/\.]?([0-9]{1,2})[-/\.]?([0-9]{1,2})|", + ($v), $rr)) return false; + + if ($rr[1] <= TIMESTAMP_FIRST_YEAR) return 0; + // h-m-s-MM-DD-YY + return @adodb_mktime(0,0,0,$rr[2],$rr[3],$rr[1]); + } + + + /** + * Also in ADORecordSet. + * @param $v is a timestamp string in YYYY-MM-DD HH-NN-SS format + * + * @return date in unix timestamp format, or 0 if before TIMESTAMP_FIRST_YEAR, or false if invalid date format + */ + function UnixTimeStamp($v) + { + if (is_object($v)) { + // odbtp support + //( [year] => 2004 [month] => 9 [day] => 4 [hour] => 12 [minute] => 44 [second] => 8 [fraction] => 0 ) + return adodb_mktime($v->hour,$v->minute,$v->second,$v->month,$v->day, $v->year); + } + + if (!preg_match( + "|^([0-9]{4})[-/\.]?([0-9]{1,2})[-/\.]?([0-9]{1,2})[ ,-]*(([0-9]{1,2}):?([0-9]{1,2}):?([0-9\.]{1,4}))?|", + ($v), $rr)) return false; + + if ($rr[1] <= TIMESTAMP_FIRST_YEAR && $rr[2]<= 1) return 0; + + // h-m-s-MM-DD-YY + if (!isset($rr[5])) return adodb_mktime(0,0,0,$rr[2],$rr[3],$rr[1]); + return @adodb_mktime($rr[5],$rr[6],$rr[7],$rr[2],$rr[3],$rr[1]); + } + + /** + * Also in ADORecordSet. + * + * Format database date based on user defined format. + * + * @param v is the character date in YYYY-MM-DD format, returned by database + * @param fmt is the format to apply to it, using date() + * + * @return a date formated as user desires + */ + + function UserDate($v,$fmt='Y-m-d',$gmt=false) + { + $tt = $this->UnixDate($v); + + // $tt == -1 if pre TIMESTAMP_FIRST_YEAR + if (($tt === false || $tt == -1) && $v != false) return $v; + else if ($tt == 0) return $this->emptyDate; + else if ($tt == -1) { // pre-TIMESTAMP_FIRST_YEAR + } + + return ($gmt) ? adodb_gmdate($fmt,$tt) : adodb_date($fmt,$tt); + + } + + /** + * + * @param v is the character timestamp in YYYY-MM-DD hh:mm:ss format + * @param fmt is the format to apply to it, using date() + * + * @return a timestamp formated as user desires + */ + function UserTimeStamp($v,$fmt='Y-m-d H:i:s',$gmt=false) + { + if (!isset($v)) return $this->emptyTimeStamp; + # strlen(14) allows YYYYMMDDHHMMSS format + if (is_numeric($v) && strlen($v)<14) return ($gmt) ? adodb_gmdate($fmt,$v) : adodb_date($fmt,$v); + $tt = $this->UnixTimeStamp($v); + // $tt == -1 if pre TIMESTAMP_FIRST_YEAR + if (($tt === false || $tt == -1) && $v != false) return $v; + if ($tt == 0) return $this->emptyTimeStamp; + return ($gmt) ? adodb_gmdate($fmt,$tt) : adodb_date($fmt,$tt); + } + + function escape($s,$magic_quotes=false) + { + return $this->addq($s,$magic_quotes); + } + + /** + * Quotes a string, without prefixing nor appending quotes. + */ + function addq($s,$magic_quotes=false) + { + if (!$magic_quotes) { + + if ($this->replaceQuote[0] == '\\'){ + // only since php 4.0.5 + $s = adodb_str_replace(array('\\',"\0"),array('\\\\',"\\\0"),$s); + //$s = str_replace("\0","\\\0", str_replace('\\','\\\\',$s)); + } + return str_replace("'",$this->replaceQuote,$s); + } + + // undo magic quotes for " + $s = str_replace('\\"','"',$s); + + if ($this->replaceQuote == "\\'") // ' already quoted, no need to change anything + return $s; + else {// change \' to '' for sybase/mssql + $s = str_replace('\\\\','\\',$s); + return str_replace("\\'",$this->replaceQuote,$s); + } + } + + /** + * Correctly quotes a string so that all strings are escaped. We prefix and append + * to the string single-quotes. + * An example is $db->qstr("Don't bother",magic_quotes_runtime()); + * + * @param s the string to quote + * @param [magic_quotes] if $s is GET/POST var, set to get_magic_quotes_gpc(). + * This undoes the stupidity of magic quotes for GPC. + * + * @return quoted string to be sent back to database + */ + function qstr($s,$magic_quotes=false) + { + if (!$magic_quotes) { + + if ($this->replaceQuote[0] == '\\'){ + // only since php 4.0.5 + $s = adodb_str_replace(array('\\',"\0"),array('\\\\',"\\\0"),$s); + //$s = str_replace("\0","\\\0", str_replace('\\','\\\\',$s)); + } + return "'".str_replace("'",$this->replaceQuote,$s)."'"; + } + + // undo magic quotes for " + $s = str_replace('\\"','"',$s); + + if ($this->replaceQuote == "\\'") // ' already quoted, no need to change anything + return "'$s'"; + else {// change \' to '' for sybase/mssql + $s = str_replace('\\\\','\\',$s); + return "'".str_replace("\\'",$this->replaceQuote,$s)."'"; + } + } + + + /** + * Will select the supplied $page number from a recordset, given that it is paginated in pages of + * $nrows rows per page. It also saves two boolean values saying if the given page is the first + * and/or last one of the recordset. Added by Ivn Oliva to provide recordset pagination. + * + * See readme.htm#ex8 for an example of usage. + * + * @param sql + * @param nrows is the number of rows per page to get + * @param page is the page number to get (1-based) + * @param [inputarr] array of bind variables + * @param [secs2cache] is a private parameter only used by jlim + * @return the recordset ($rs->databaseType == 'array') + * + * NOTE: phpLens uses a different algorithm and does not use PageExecute(). + * + */ + function &PageExecute($sql, $nrows, $page, $inputarr=false, $secs2cache=0) + { + global $ADODB_INCLUDED_LIB; + if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php'); + if ($this->pageExecuteCountRows) $rs =& _adodb_pageexecute_all_rows($this, $sql, $nrows, $page, $inputarr, $secs2cache); + else $rs =& _adodb_pageexecute_no_last_page($this, $sql, $nrows, $page, $inputarr, $secs2cache); + return $rs; + } + + + /** + * Will select the supplied $page number from a recordset, given that it is paginated in pages of + * $nrows rows per page. It also saves two boolean values saying if the given page is the first + * and/or last one of the recordset. Added by Ivn Oliva to provide recordset pagination. + * + * @param secs2cache seconds to cache data, set to 0 to force query + * @param sql + * @param nrows is the number of rows per page to get + * @param page is the page number to get (1-based) + * @param [inputarr] array of bind variables + * @return the recordset ($rs->databaseType == 'array') + */ + function &CachePageExecute($secs2cache, $sql, $nrows, $page,$inputarr=false) + { + /*switch($this->dataProvider) { + case 'postgres': + case 'mysql': + break; + default: $secs2cache = 0; break; + }*/ + $rs =& $this->PageExecute($sql,$nrows,$page,$inputarr,$secs2cache); + return $rs; + } + +} // end class ADOConnection + + + + //============================================================================================== + // CLASS ADOFetchObj + //============================================================================================== + + /** + * Internal placeholder for record objects. Used by ADORecordSet->FetchObj(). + */ + class ADOFetchObj { + }; + + //============================================================================================== + // CLASS ADORecordSet_empty + //============================================================================================== + + /** + * Lightweight recordset when there are no records to be returned + */ + class ADORecordSet_empty + { + var $dataProvider = 'empty'; + var $databaseType = false; + var $EOF = true; + var $_numOfRows = 0; + var $fields = false; + var $connection = false; + function RowCount() {return 0;} + function RecordCount() {return 0;} + function PO_RecordCount(){return 0;} + function Close(){return true;} + function FetchRow() {return false;} + function FieldCount(){ return 0;} + function Init() {} + } + + //============================================================================================== + // DATE AND TIME FUNCTIONS + //============================================================================================== + if (!defined('ADODB_DATE_VERSION')) include(ADODB_DIR.'/adodb-time.inc.php'); + + //============================================================================================== + // CLASS ADORecordSet + //============================================================================================== + + if (PHP_VERSION < 5) include_once(ADODB_DIR.'/adodb-php4.inc.php'); + else include_once(ADODB_DIR.'/adodb-iterator.inc.php'); + /** + * RecordSet class that represents the dataset returned by the database. + * To keep memory overhead low, this class holds only the current row in memory. + * No prefetching of data is done, so the RecordCount() can return -1 ( which + * means recordcount not known). + */ + class ADORecordSet extends ADODB_BASE_RS { + /* + * public variables + */ + var $dataProvider = "native"; + var $fields = false; /// holds the current row data + var $blobSize = 100; /// any varchar/char field this size or greater is treated as a blob + /// in other words, we use a text area for editing. + var $canSeek = false; /// indicates that seek is supported + var $sql; /// sql text + var $EOF = false; /// Indicates that the current record position is after the last record in a Recordset object. + + var $emptyTimeStamp = ' '; /// what to display when $time==0 + var $emptyDate = ' '; /// what to display when $time==0 + var $debug = false; + var $timeCreated=0; /// datetime in Unix format rs created -- for cached recordsets + + var $bind = false; /// used by Fields() to hold array - should be private? + var $fetchMode; /// default fetch mode + var $connection = false; /// the parent connection + /* + * private variables + */ + var $_numOfRows = -1; /** number of rows, or -1 */ + var $_numOfFields = -1; /** number of fields in recordset */ + var $_queryID = -1; /** This variable keeps the result link identifier. */ + var $_currentRow = -1; /** This variable keeps the current row in the Recordset. */ + var $_closed = false; /** has recordset been closed */ + var $_inited = false; /** Init() should only be called once */ + var $_obj; /** Used by FetchObj */ + var $_names; /** Used by FetchObj */ + + var $_currentPage = -1; /** Added by Ivn Oliva to implement recordset pagination */ + var $_atFirstPage = false; /** Added by Ivn Oliva to implement recordset pagination */ + var $_atLastPage = false; /** Added by Ivn Oliva to implement recordset pagination */ + var $_lastPageNo = -1; + var $_maxRecordCount = 0; + var $datetime = false; + + /** + * Constructor + * + * @param queryID this is the queryID returned by ADOConnection->_query() + * + */ + function ADORecordSet($queryID) + { + $this->_queryID = $queryID; + } + + + + function Init() + { + if ($this->_inited) return; + $this->_inited = true; + if ($this->_queryID) @$this->_initrs(); + else { + $this->_numOfRows = 0; + $this->_numOfFields = 0; + } + if ($this->_numOfRows != 0 && $this->_numOfFields && $this->_currentRow == -1) { + + $this->_currentRow = 0; + if ($this->EOF = ($this->_fetch() === false)) { + $this->_numOfRows = 0; // _numOfRows could be -1 + } + } else { + $this->EOF = true; + } + } + + + /** + * Generate a SELECT tag string from a recordset, and return the string. + * If the recordset has 2 cols, we treat the 1st col as the containing + * the text to display to the user, and 2nd col as the return value. Default + * strings are compared with the FIRST column. + * + * @param name name of SELECT tag + * @param [defstr] the value to hilite. Use an array for multiple hilites for listbox. + * @param [blank1stItem] true to leave the 1st item in list empty + * @param [multiple] true for listbox, false for popup + * @param [size] #rows to show for listbox. not used by popup + * @param [selectAttr] additional attributes to defined for SELECT tag. + * useful for holding javascript onChange='...' handlers. + & @param [compareFields0] when we have 2 cols in recordset, we compare the defstr with + * column 0 (1st col) if this is true. This is not documented. + * + * @return HTML + * + * changes by glen.davies@cce.ac.nz to support multiple hilited items + */ + function GetMenu($name,$defstr='',$blank1stItem=true,$multiple=false, + $size=0, $selectAttr='',$compareFields0=true) + { + global $ADODB_INCLUDED_LIB; + if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php'); + return _adodb_getmenu($this, $name,$defstr,$blank1stItem,$multiple, + $size, $selectAttr,$compareFields0); + } + + + + /** + * Generate a SELECT tag string from a recordset, and return the string. + * If the recordset has 2 cols, we treat the 1st col as the containing + * the text to display to the user, and 2nd col as the return value. Default + * strings are compared with the SECOND column. + * + */ + function GetMenu2($name,$defstr='',$blank1stItem=true,$multiple=false,$size=0, $selectAttr='') + { + return $this->GetMenu($name,$defstr,$blank1stItem,$multiple, + $size, $selectAttr,false); + } + + /* + Grouped Menu + */ + function GetMenu3($name,$defstr='',$blank1stItem=true,$multiple=false, + $size=0, $selectAttr='') + { + global $ADODB_INCLUDED_LIB; + if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php'); + return _adodb_getmenu_gp($this, $name,$defstr,$blank1stItem,$multiple, + $size, $selectAttr,false); + } + + /** + * return recordset as a 2-dimensional array. + * + * @param [nRows] is the number of rows to return. -1 means every row. + * + * @return an array indexed by the rows (0-based) from the recordset + */ + function &GetArray($nRows = -1) + { + global $ADODB_EXTENSION; if ($ADODB_EXTENSION) { + $results = adodb_getall($this,$nRows); + return $results; + } + $results = array(); + $cnt = 0; + while (!$this->EOF && $nRows != $cnt) { + $results[] = $this->fields; + $this->MoveNext(); + $cnt++; + } + return $results; + } + + function &GetAll($nRows = -1) + { + $arr =& $this->GetArray($nRows); + return $arr; + } + + /* + * Some databases allow multiple recordsets to be returned. This function + * will return true if there is a next recordset, or false if no more. + */ + function NextRecordSet() + { + return false; + } + + /** + * return recordset as a 2-dimensional array. + * Helper function for ADOConnection->SelectLimit() + * + * @param offset is the row to start calculations from (1-based) + * @param [nrows] is the number of rows to return + * + * @return an array indexed by the rows (0-based) from the recordset + */ + function &GetArrayLimit($nrows,$offset=-1) + { + if ($offset <= 0) { + $arr =& $this->GetArray($nrows); + return $arr; + } + + $this->Move($offset); + + $results = array(); + $cnt = 0; + while (!$this->EOF && $nrows != $cnt) { + $results[$cnt++] = $this->fields; + $this->MoveNext(); + } + + return $results; + } + + + /** + * Synonym for GetArray() for compatibility with ADO. + * + * @param [nRows] is the number of rows to return. -1 means every row. + * + * @return an array indexed by the rows (0-based) from the recordset + */ + function &GetRows($nRows = -1) + { + $arr =& $this->GetArray($nRows); + return $arr; + } + + /** + * return whole recordset as a 2-dimensional associative array if there are more than 2 columns. + * The first column is treated as the key and is not included in the array. + * If there is only 2 columns, it will return a 1 dimensional array of key-value pairs unless + * $force_array == true. + * + * @param [force_array] has only meaning if we have 2 data columns. If false, a 1 dimensional + * array is returned, otherwise a 2 dimensional array is returned. If this sounds confusing, + * read the source. + * + * @param [first2cols] means if there are more than 2 cols, ignore the remaining cols and + * instead of returning array[col0] => array(remaining cols), return array[col0] => col1 + * + * @return an associative array indexed by the first column of the array, + * or false if the data has less than 2 cols. + */ + function &GetAssoc($force_array = false, $first2cols = false) + { + global $ADODB_EXTENSION; + + $cols = $this->_numOfFields; + if ($cols < 2) { + $false = false; + return $false; + } + $numIndex = isset($this->fields[0]); + $results = array(); + + if (!$first2cols && ($cols > 2 || $force_array)) { + if ($ADODB_EXTENSION) { + if ($numIndex) { + while (!$this->EOF) { + $results[trim($this->fields[0])] = array_slice($this->fields, 1); + adodb_movenext($this); + } + } else { + while (!$this->EOF) { + // Fix for array_slice re-numbering numeric associative keys + $keys = array_slice(array_keys($this->fields), 1); + $sliced_array = array(); + + foreach($keys as $key) { + $sliced_array[$key] = $this->fields[$key]; + } + + $results[trim(reset($this->fields))] = $sliced_array; + adodb_movenext($this); + } + } + } else { + if ($numIndex) { + while (!$this->EOF) { + $results[trim($this->fields[0])] = array_slice($this->fields, 1); + $this->MoveNext(); + } + } else { + while (!$this->EOF) { + // Fix for array_slice re-numbering numeric associative keys + $keys = array_slice(array_keys($this->fields), 1); + $sliced_array = array(); + + foreach($keys as $key) { + $sliced_array[$key] = $this->fields[$key]; + } + + $results[trim(reset($this->fields))] = $sliced_array; + $this->MoveNext(); + } + } + } + } else { + if ($ADODB_EXTENSION) { + // return scalar values + if ($numIndex) { + while (!$this->EOF) { + // some bug in mssql PHP 4.02 -- doesn't handle references properly so we FORCE creating a new string + $results[trim(($this->fields[0]))] = $this->fields[1]; + adodb_movenext($this); + } + } else { + while (!$this->EOF) { + // some bug in mssql PHP 4.02 -- doesn't handle references properly so we FORCE creating a new string + $v1 = trim(reset($this->fields)); + $v2 = ''.next($this->fields); + $results[$v1] = $v2; + adodb_movenext($this); + } + } + } else { + if ($numIndex) { + while (!$this->EOF) { + // some bug in mssql PHP 4.02 -- doesn't handle references properly so we FORCE creating a new string + $results[trim(($this->fields[0]))] = $this->fields[1]; + $this->MoveNext(); + } + } else { + while (!$this->EOF) { + // some bug in mssql PHP 4.02 -- doesn't handle references properly so we FORCE creating a new string + $v1 = trim(reset($this->fields)); + $v2 = ''.next($this->fields); + $results[$v1] = $v2; + $this->MoveNext(); + } + } + } + } + + $ref =& $results; # workaround accelerator incompat with PHP 4.4 :( + return $ref; + } + + + /** + * + * @param v is the character timestamp in YYYY-MM-DD hh:mm:ss format + * @param fmt is the format to apply to it, using date() + * + * @return a timestamp formated as user desires + */ + function UserTimeStamp($v,$fmt='Y-m-d H:i:s') + { + if (is_numeric($v) && strlen($v)<14) return adodb_date($fmt,$v); + $tt = $this->UnixTimeStamp($v); + // $tt == -1 if pre TIMESTAMP_FIRST_YEAR + if (($tt === false || $tt == -1) && $v != false) return $v; + if ($tt === 0) return $this->emptyTimeStamp; + return adodb_date($fmt,$tt); + } + + + /** + * @param v is the character date in YYYY-MM-DD format, returned by database + * @param fmt is the format to apply to it, using date() + * + * @return a date formated as user desires + */ + function UserDate($v,$fmt='Y-m-d') + { + $tt = $this->UnixDate($v); + // $tt == -1 if pre TIMESTAMP_FIRST_YEAR + if (($tt === false || $tt == -1) && $v != false) return $v; + else if ($tt == 0) return $this->emptyDate; + else if ($tt == -1) { // pre-TIMESTAMP_FIRST_YEAR + } + return adodb_date($fmt,$tt); + } + + + /** + * @param $v is a date string in YYYY-MM-DD format + * + * @return date in unix timestamp format, or 0 if before TIMESTAMP_FIRST_YEAR, or false if invalid date format + */ + function UnixDate($v) + { + return ADOConnection::UnixDate($v); + } + + + /** + * @param $v is a timestamp string in YYYY-MM-DD HH-NN-SS format + * + * @return date in unix timestamp format, or 0 if before TIMESTAMP_FIRST_YEAR, or false if invalid date format + */ + function UnixTimeStamp($v) + { + return ADOConnection::UnixTimeStamp($v); + } + + + /** + * PEAR DB Compat - do not use internally + */ + function Free() + { + return $this->Close(); + } + + + /** + * PEAR DB compat, number of rows + */ + function NumRows() + { + return $this->_numOfRows; + } + + + /** + * PEAR DB compat, number of cols + */ + function NumCols() + { + return $this->_numOfFields; + } + + /** + * Fetch a row, returning false if no more rows. + * This is PEAR DB compat mode. + * + * @return false or array containing the current record + */ + function &FetchRow() + { + if ($this->EOF) { + $false = false; + return $false; + } + $arr = $this->fields; + $this->_currentRow++; + if (!$this->_fetch()) $this->EOF = true; + return $arr; + } + + + /** + * Fetch a row, returning PEAR_Error if no more rows. + * This is PEAR DB compat mode. + * + * @return DB_OK or error object + */ + function FetchInto(&$arr) + { + if ($this->EOF) return (defined('PEAR_ERROR_RETURN')) ? new PEAR_Error('EOF',-1): false; + $arr = $this->fields; + $this->MoveNext(); + return 1; // DB_OK + } + + + /** + * Move to the first row in the recordset. Many databases do NOT support this. + * + * @return true or false + */ + function MoveFirst() + { + if ($this->_currentRow == 0) return true; + return $this->Move(0); + } + + + /** + * Move to the last row in the recordset. + * + * @return true or false + */ + function MoveLast() + { + if ($this->_numOfRows >= 0) return $this->Move($this->_numOfRows-1); + if ($this->EOF) return false; + while (!$this->EOF) { + $f = $this->fields; + $this->MoveNext(); + } + $this->fields = $f; + $this->EOF = false; + return true; + } + + + /** + * Move to next record in the recordset. + * + * @return true if there still rows available, or false if there are no more rows (EOF). + */ + function MoveNext() + { + if (!$this->EOF) { + $this->_currentRow++; + if ($this->_fetch()) return true; + } + $this->EOF = true; + /* -- tested error handling when scrolling cursor -- seems useless. + $conn = $this->connection; + if ($conn && $conn->raiseErrorFn && ($errno = $conn->ErrorNo())) { + $fn = $conn->raiseErrorFn; + $fn($conn->databaseType,'MOVENEXT',$errno,$conn->ErrorMsg().' ('.$this->sql.')',$conn->host,$conn->database); + } + */ + return false; + } + + + /** + * Random access to a specific row in the recordset. Some databases do not support + * access to previous rows in the databases (no scrolling backwards). + * + * @param rowNumber is the row to move to (0-based) + * + * @return true if there still rows available, or false if there are no more rows (EOF). + */ + function Move($rowNumber = 0) + { + $this->EOF = false; + if ($rowNumber == $this->_currentRow) return true; + if ($rowNumber >= $this->_numOfRows) + if ($this->_numOfRows != -1) $rowNumber = $this->_numOfRows-2; + + if ($this->canSeek) { + + if ($this->_seek($rowNumber)) { + $this->_currentRow = $rowNumber; + if ($this->_fetch()) { + return true; + } + } else { + $this->EOF = true; + return false; + } + } else { + if ($rowNumber < $this->_currentRow) return false; + global $ADODB_EXTENSION; + if ($ADODB_EXTENSION) { + while (!$this->EOF && $this->_currentRow < $rowNumber) { + adodb_movenext($this); + } + } else { + + while (! $this->EOF && $this->_currentRow < $rowNumber) { + $this->_currentRow++; + + if (!$this->_fetch()) $this->EOF = true; + } + } + return !($this->EOF); + } + + $this->fields = false; + $this->EOF = true; + return false; + } + + + /** + * Get the value of a field in the current row by column name. + * Will not work if ADODB_FETCH_MODE is set to ADODB_FETCH_NUM. + * + * @param colname is the field to access + * + * @return the value of $colname column + */ + function Fields($colname) + { + return $this->fields[$colname]; + } + + function GetAssocKeys($upper=true) + { + $this->bind = array(); + for ($i=0; $i < $this->_numOfFields; $i++) { + $o = $this->FetchField($i); + if ($upper === 2) $this->bind[$o->name] = $i; + else $this->bind[($upper) ? strtoupper($o->name) : strtolower($o->name)] = $i; + } + } + + /** + * Use associative array to get fields array for databases that do not support + * associative arrays. Submitted by Paolo S. Asioli paolo.asioli#libero.it + * + * If you don't want uppercase cols, set $ADODB_FETCH_MODE = ADODB_FETCH_ASSOC + * before you execute your SQL statement, and access $rs->fields['col'] directly. + * + * $upper 0 = lowercase, 1 = uppercase, 2 = whatever is returned by FetchField + */ + function &GetRowAssoc($upper=1) + { + $record = array(); + // if (!$this->fields) return $record; + + if (!$this->bind) { + $this->GetAssocKeys($upper); + } + + foreach($this->bind as $k => $v) { + $record[$k] = $this->fields[$v]; + } + + return $record; + } + + + /** + * Clean up recordset + * + * @return true or false + */ + function Close() + { + // free connection object - this seems to globally free the object + // and not merely the reference, so don't do this... + // $this->connection = false; + if (!$this->_closed) { + $this->_closed = true; + return $this->_close(); + } else + return true; + } + + /** + * synonyms RecordCount and RowCount + * + * @return the number of rows or -1 if this is not supported + */ + function RecordCount() {return $this->_numOfRows;} + + + /* + * If we are using PageExecute(), this will return the maximum possible rows + * that can be returned when paging a recordset. + */ + function MaxRecordCount() + { + return ($this->_maxRecordCount) ? $this->_maxRecordCount : $this->RecordCount(); + } + + /** + * synonyms RecordCount and RowCount + * + * @return the number of rows or -1 if this is not supported + */ + function RowCount() {return $this->_numOfRows;} + + + /** + * Portable RecordCount. Pablo Roca + * + * @return the number of records from a previous SELECT. All databases support this. + * + * But aware possible problems in multiuser environments. For better speed the table + * must be indexed by the condition. Heavy test this before deploying. + */ + function PO_RecordCount($table="", $condition="") { + + $lnumrows = $this->_numOfRows; + // the database doesn't support native recordcount, so we do a workaround + if ($lnumrows == -1 && $this->connection) { + IF ($table) { + if ($condition) $condition = " WHERE " . $condition; + $resultrows = &$this->connection->Execute("SELECT COUNT(*) FROM $table $condition"); + if ($resultrows) $lnumrows = reset($resultrows->fields); + } + } + return $lnumrows; + } + + + /** + * @return the current row in the recordset. If at EOF, will return the last row. 0-based. + */ + function CurrentRow() {return $this->_currentRow;} + + /** + * synonym for CurrentRow -- for ADO compat + * + * @return the current row in the recordset. If at EOF, will return the last row. 0-based. + */ + function AbsolutePosition() {return $this->_currentRow;} + + /** + * @return the number of columns in the recordset. Some databases will set this to 0 + * if no records are returned, others will return the number of columns in the query. + */ + function FieldCount() {return $this->_numOfFields;} + + + /** + * Get the ADOFieldObject of a specific column. + * + * @param fieldoffset is the column position to access(0-based). + * + * @return the ADOFieldObject for that column, or false. + */ + function &FetchField($fieldoffset = -1) + { + // must be defined by child class + + $false = false; + return $false; + } + + /** + * Get the ADOFieldObjects of all columns in an array. + * + */ + function& FieldTypesArray() + { + $arr = array(); + for ($i=0, $max=$this->_numOfFields; $i < $max; $i++) + $arr[] = $this->FetchField($i); + return $arr; + } + + /** + * Return the fields array of the current row as an object for convenience. + * The default case is lowercase field names. + * + * @return the object with the properties set to the fields of the current row + */ + function &FetchObj() + { + $o =& $this->FetchObject(false); + return $o; + } + + /** + * Return the fields array of the current row as an object for convenience. + * The default case is uppercase. + * + * @param $isupper to set the object property names to uppercase + * + * @return the object with the properties set to the fields of the current row + */ + function &FetchObject($isupper=true) + { + if (empty($this->_obj)) { + $this->_obj = new ADOFetchObj(); + $this->_names = array(); + for ($i=0; $i <$this->_numOfFields; $i++) { + $f = $this->FetchField($i); + $this->_names[] = $f->name; + } + } + $i = 0; + if (PHP_VERSION >= 5) $o = clone($this->_obj); + else $o = $this->_obj; + + for ($i=0; $i <$this->_numOfFields; $i++) { + $name = $this->_names[$i]; + if ($isupper) $n = strtoupper($name); + else $n = $name; + + $o->$n = $this->Fields($name); + } + return $o; + } + + /** + * Return the fields array of the current row as an object for convenience. + * The default is lower-case field names. + * + * @return the object with the properties set to the fields of the current row, + * or false if EOF + * + * Fixed bug reported by tim@orotech.net + */ + function &FetchNextObj() + { + $o =& $this->FetchNextObject(false); + return $o; + } + + + /** + * Return the fields array of the current row as an object for convenience. + * The default is upper case field names. + * + * @param $isupper to set the object property names to uppercase + * + * @return the object with the properties set to the fields of the current row, + * or false if EOF + * + * Fixed bug reported by tim@orotech.net + */ + function &FetchNextObject($isupper=true) + { + $o = false; + if ($this->_numOfRows != 0 && !$this->EOF) { + $o = $this->FetchObject($isupper); + $this->_currentRow++; + if ($this->_fetch()) return $o; + } + $this->EOF = true; + return $o; + } + + /** + * Get the metatype of the column. This is used for formatting. This is because + * many databases use different names for the same type, so we transform the original + * type to our standardised version which uses 1 character codes: + * + * @param t is the type passed in. Normally is ADOFieldObject->type. + * @param len is the maximum length of that field. This is because we treat character + * fields bigger than a certain size as a 'B' (blob). + * @param fieldobj is the field object returned by the database driver. Can hold + * additional info (eg. primary_key for mysql). + * + * @return the general type of the data: + * C for character < 250 chars + * X for teXt (>= 250 chars) + * B for Binary + * N for numeric or floating point + * D for date + * T for timestamp + * L for logical/Boolean + * I for integer + * R for autoincrement counter/integer + * + * + */ + function MetaType($t,$len=-1,$fieldobj=false) + { + if (is_object($t)) { + $fieldobj = $t; + $t = $fieldobj->type; + $len = $fieldobj->max_length; + } + // changed in 2.32 to hashing instead of switch stmt for speed... + static $typeMap = array( + 'VARCHAR' => 'C', + 'VARCHAR2' => 'C', + 'CHAR' => 'C', + 'C' => 'C', + 'STRING' => 'C', + 'NCHAR' => 'C', + 'NVARCHAR' => 'C', + 'VARYING' => 'C', + 'BPCHAR' => 'C', + 'CHARACTER' => 'C', + 'INTERVAL' => 'C', # Postgres + 'MACADDR' => 'C', # postgres + ## + 'LONGCHAR' => 'X', + 'TEXT' => 'X', + 'NTEXT' => 'X', + 'M' => 'X', + 'X' => 'X', + 'CLOB' => 'X', + 'NCLOB' => 'X', + 'LVARCHAR' => 'X', + ## + 'BLOB' => 'B', + 'IMAGE' => 'B', + 'BINARY' => 'B', + 'VARBINARY' => 'B', + 'LONGBINARY' => 'B', + 'B' => 'B', + ## + 'YEAR' => 'D', // mysql + 'DATE' => 'D', + 'D' => 'D', + ## + 'UNIQUEIDENTIFIER' => 'C', # MS SQL Server + ## + 'TIME' => 'T', + 'TIMESTAMP' => 'T', + 'DATETIME' => 'T', + 'TIMESTAMPTZ' => 'T', + 'T' => 'T', + 'TIMESTAMP WITHOUT TIME ZONE' => 'T', // postgresql + ## + 'BOOL' => 'L', + 'BOOLEAN' => 'L', + 'BIT' => 'L', + 'L' => 'L', + ## + 'COUNTER' => 'R', + 'R' => 'R', + 'SERIAL' => 'R', // ifx + 'INT IDENTITY' => 'R', + ## + 'INT' => 'I', + 'INT2' => 'I', + 'INT4' => 'I', + 'INT8' => 'I', + 'INTEGER' => 'I', + 'INTEGER UNSIGNED' => 'I', + 'SHORT' => 'I', + 'TINYINT' => 'I', + 'SMALLINT' => 'I', + 'I' => 'I', + ## + 'LONG' => 'N', // interbase is numeric, oci8 is blob + 'BIGINT' => 'N', // this is bigger than PHP 32-bit integers + 'DECIMAL' => 'N', + 'DEC' => 'N', + 'REAL' => 'N', + 'DOUBLE' => 'N', + 'DOUBLE PRECISION' => 'N', + 'SMALLFLOAT' => 'N', + 'FLOAT' => 'N', + 'NUMBER' => 'N', + 'NUM' => 'N', + 'NUMERIC' => 'N', + 'MONEY' => 'N', + + ## informix 9.2 + 'SQLINT' => 'I', + 'SQLSERIAL' => 'I', + 'SQLSMINT' => 'I', + 'SQLSMFLOAT' => 'N', + 'SQLFLOAT' => 'N', + 'SQLMONEY' => 'N', + 'SQLDECIMAL' => 'N', + 'SQLDATE' => 'D', + 'SQLVCHAR' => 'C', + 'SQLCHAR' => 'C', + 'SQLDTIME' => 'T', + 'SQLINTERVAL' => 'N', + 'SQLBYTES' => 'B', + 'SQLTEXT' => 'X', + ## informix 10 + "SQLINT8" => 'I8', + "SQLSERIAL8" => 'I8', + "SQLNCHAR" => 'C', + "SQLNVCHAR" => 'C', + "SQLLVARCHAR" => 'X', + "SQLBOOL" => 'L' + ); + + $tmap = false; + $t = strtoupper($t); + $tmap = (isset($typeMap[$t])) ? $typeMap[$t] : 'N'; + switch ($tmap) { + case 'C': + + // is the char field is too long, return as text field... + if ($this->blobSize >= 0) { + if ($len > $this->blobSize) return 'X'; + } else if ($len > 250) { + return 'X'; + } + return 'C'; + + case 'I': + if (!empty($fieldobj->primary_key)) return 'R'; + return 'I'; + + case false: + return 'N'; + + case 'B': + if (isset($fieldobj->binary)) + return ($fieldobj->binary) ? 'B' : 'X'; + return 'B'; + + case 'D': + if (!empty($this->connection) && !empty($this->connection->datetime)) return 'T'; + return 'D'; + + default: + if ($t == 'LONG' && $this->dataProvider == 'oci8') return 'B'; + return $tmap; + } + } + + + function _close() {} + + /** + * set/returns the current recordset page when paginating + */ + function AbsolutePage($page=-1) + { + if ($page != -1) $this->_currentPage = $page; + return $this->_currentPage; + } + + /** + * set/returns the status of the atFirstPage flag when paginating + */ + function AtFirstPage($status=false) + { + if ($status != false) $this->_atFirstPage = $status; + return $this->_atFirstPage; + } + + function LastPageNo($page = false) + { + if ($page != false) $this->_lastPageNo = $page; + return $this->_lastPageNo; + } + + /** + * set/returns the status of the atLastPage flag when paginating + */ + function AtLastPage($status=false) + { + if ($status != false) $this->_atLastPage = $status; + return $this->_atLastPage; + } + +} // end class ADORecordSet + + //============================================================================================== + // CLASS ADORecordSet_array + //============================================================================================== + + /** + * This class encapsulates the concept of a recordset created in memory + * as an array. This is useful for the creation of cached recordsets. + * + * Note that the constructor is different from the standard ADORecordSet + */ + + class ADORecordSet_array extends ADORecordSet + { + var $databaseType = 'array'; + + var $_array; // holds the 2-dimensional data array + var $_types; // the array of types of each column (C B I L M) + var $_colnames; // names of each column in array + var $_skiprow1; // skip 1st row because it holds column names + var $_fieldobjects; // holds array of field objects + var $canSeek = true; + var $affectedrows = false; + var $insertid = false; + var $sql = ''; + var $compat = false; + /** + * Constructor + * + */ + function ADORecordSet_array($fakeid=1) + { + global $ADODB_FETCH_MODE,$ADODB_COMPAT_FETCH; + + // fetch() on EOF does not delete $this->fields + $this->compat = !empty($ADODB_COMPAT_FETCH); + $this->ADORecordSet($fakeid); // fake queryID + $this->fetchMode = $ADODB_FETCH_MODE; + } + + function _transpose($addfieldnames=true) + { + global $ADODB_INCLUDED_LIB; + + if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php'); + $hdr = true; + + $fobjs = $addfieldnames ? $this->_fieldobjects : false; + adodb_transpose($this->_array, $newarr, $hdr, $fobjs); + //adodb_pr($newarr); + + $this->_skiprow1 = false; + $this->_array =& $newarr; + $this->_colnames = $hdr; + + adodb_probetypes($newarr,$this->_types); + + $this->_fieldobjects = array(); + + foreach($hdr as $k => $name) { + $f = new ADOFieldObject(); + $f->name = $name; + $f->type = $this->_types[$k]; + $f->max_length = -1; + $this->_fieldobjects[] = $f; + } + $this->fields = reset($this->_array); + + $this->_initrs(); + + } + + /** + * Setup the array. + * + * @param array is a 2-dimensional array holding the data. + * The first row should hold the column names + * unless paramter $colnames is used. + * @param typearr holds an array of types. These are the same types + * used in MetaTypes (C,B,L,I,N). + * @param [colnames] array of column names. If set, then the first row of + * $array should not hold the column names. + */ + function InitArray($array,$typearr,$colnames=false) + { + $this->_array = $array; + $this->_types = $typearr; + if ($colnames) { + $this->_skiprow1 = false; + $this->_colnames = $colnames; + } else { + $this->_skiprow1 = true; + $this->_colnames = $array[0]; + } + $this->Init(); + } + /** + * Setup the Array and datatype file objects + * + * @param array is a 2-dimensional array holding the data. + * The first row should hold the column names + * unless paramter $colnames is used. + * @param fieldarr holds an array of ADOFieldObject's. + */ + function InitArrayFields(&$array,&$fieldarr) + { + $this->_array =& $array; + $this->_skiprow1= false; + if ($fieldarr) { + $this->_fieldobjects =& $fieldarr; + } + $this->Init(); + } + + function &GetArray($nRows=-1) + { + if ($nRows == -1 && $this->_currentRow <= 0 && !$this->_skiprow1) { + return $this->_array; + } else { + $arr =& ADORecordSet::GetArray($nRows); + return $arr; + } + } + + function _initrs() + { + $this->_numOfRows = sizeof($this->_array); + if ($this->_skiprow1) $this->_numOfRows -= 1; + + $this->_numOfFields =(isset($this->_fieldobjects)) ? + sizeof($this->_fieldobjects):sizeof($this->_types); + } + + /* Use associative array to get fields array */ + function Fields($colname) + { + $mode = isset($this->adodbFetchMode) ? $this->adodbFetchMode : $this->fetchMode; + + if ($mode & ADODB_FETCH_ASSOC) { + if (!isset($this->fields[$colname])) $colname = strtolower($colname); + return $this->fields[$colname]; + } + if (!$this->bind) { + $this->bind = array(); + for ($i=0; $i < $this->_numOfFields; $i++) { + $o = $this->FetchField($i); + $this->bind[strtoupper($o->name)] = $i; + } + } + return $this->fields[$this->bind[strtoupper($colname)]]; + } + + function &FetchField($fieldOffset = -1) + { + if (isset($this->_fieldobjects)) { + return $this->_fieldobjects[$fieldOffset]; + } + $o = new ADOFieldObject(); + $o->name = $this->_colnames[$fieldOffset]; + $o->type = $this->_types[$fieldOffset]; + $o->max_length = -1; // length not known + + return $o; + } + + function _seek($row) + { + if (sizeof($this->_array) && 0 <= $row && $row < $this->_numOfRows) { + $this->_currentRow = $row; + if ($this->_skiprow1) $row += 1; + $this->fields = $this->_array[$row]; + return true; + } + return false; + } + + function MoveNext() + { + if (!$this->EOF) { + $this->_currentRow++; + + $pos = $this->_currentRow; + + if ($this->_numOfRows <= $pos) { + if (!$this->compat) $this->fields = false; + } else { + if ($this->_skiprow1) $pos += 1; + $this->fields = $this->_array[$pos]; + return true; + } + $this->EOF = true; + } + + return false; + } + + function _fetch() + { + $pos = $this->_currentRow; + + if ($this->_numOfRows <= $pos) { + if (!$this->compat) $this->fields = false; + return false; + } + if ($this->_skiprow1) $pos += 1; + $this->fields = $this->_array[$pos]; + return true; + } + + function _close() + { + return true; + } + + } // ADORecordSet_array + + //============================================================================================== + // HELPER FUNCTIONS + //============================================================================================== + + /** + * Synonym for ADOLoadCode. Private function. Do not use. + * + * @deprecated + */ + function ADOLoadDB($dbType) + { + return ADOLoadCode($dbType); + } + + /** + * Load the code for a specific database driver. Private function. Do not use. + */ + function ADOLoadCode($dbType) + { + global $ADODB_LASTDB; + + if (!$dbType) return false; + $db = strtolower($dbType); + switch ($db) { + case 'ado': + if (PHP_VERSION >= 5) $db = 'ado5'; + $class = 'ado'; + break; + case 'ifx': + case 'maxsql': $class = $db = 'mysqlt'; break; + case 'postgres': + case 'postgres8': + case 'pgsql': $class = $db = 'postgres7'; break; + default: + $class = $db; break; + } + + $file = ADODB_DIR."/drivers/adodb-".$db.".inc.php"; + @include_once($file); + $ADODB_LASTDB = $class; + if (class_exists("ADODB_" . $class)) return $class; + + //ADOConnection::outp(adodb_pr(get_declared_classes(),true)); + if (!file_exists($file)) ADOConnection::outp("Missing file: $file"); + else ADOConnection::outp("Syntax error in file: $file"); + return false; + } + + /** + * synonym for ADONewConnection for people like me who cannot remember the correct name + */ + function &NewADOConnection($db='') + { + $tmp =& ADONewConnection($db); + return $tmp; + } + + /** + * Instantiate a new Connection class for a specific database driver. + * + * @param [db] is the database Connection object to create. If undefined, + * use the last database driver that was loaded by ADOLoadCode(). + * + * @return the freshly created instance of the Connection class. + */ + function &ADONewConnection($db='') + { + GLOBAL $ADODB_NEWCONNECTION, $ADODB_LASTDB; + + if (!defined('ADODB_ASSOC_CASE')) define('ADODB_ASSOC_CASE',2); + $errorfn = (defined('ADODB_ERROR_HANDLER')) ? ADODB_ERROR_HANDLER : false; + $false = false; + if ($at = strpos($db,'://')) { + $origdsn = $db; + if (PHP_VERSION < 5) $dsna = @parse_url($db); + else { + $fakedsn = 'fake'.substr($db,$at); + $dsna = @parse_url($fakedsn); + $dsna['scheme'] = substr($db,0,$at); + + if (strncmp($db,'pdo',3) == 0) { + $sch = explode('_',$dsna['scheme']); + if (sizeof($sch)>1) { + $dsna['host'] = isset($dsna['host']) ? rawurldecode($dsna['host']) : ''; + $dsna['host'] = rawurlencode($sch[1].':host='.rawurldecode($dsna['host'])); + $dsna['scheme'] = 'pdo'; + } + } + } + + if (!$dsna) { + // special handling of oracle, which might not have host + $db = str_replace('@/','@adodb-fakehost/',$db); + $dsna = parse_url($db); + if (!$dsna) return $false; + $dsna['host'] = ''; + } + $db = @$dsna['scheme']; + if (!$db) return $false; + $dsna['host'] = isset($dsna['host']) ? rawurldecode($dsna['host']) : ''; + $dsna['user'] = isset($dsna['user']) ? rawurldecode($dsna['user']) : ''; + $dsna['pass'] = isset($dsna['pass']) ? rawurldecode($dsna['pass']) : ''; + $dsna['path'] = isset($dsna['path']) ? rawurldecode(substr($dsna['path'],1)) : ''; # strip off initial / + + if (isset($dsna['query'])) { + $opt1 = explode('&',$dsna['query']); + foreach($opt1 as $k => $v) { + $arr = explode('=',$v); + $opt[$arr[0]] = isset($arr[1]) ? rawurldecode($arr[1]) : 1; + } + } else $opt = array(); + } + /* + * phptype: Database backend used in PHP (mysql, odbc etc.) + * dbsyntax: Database used with regards to SQL syntax etc. + * protocol: Communication protocol to use (tcp, unix etc.) + * hostspec: Host specification (hostname[:port]) + * database: Database to use on the DBMS server + * username: User name for login + * password: Password for login + */ + if (!empty($ADODB_NEWCONNECTION)) { + $obj = $ADODB_NEWCONNECTION($db); + + } else { + + if (!isset($ADODB_LASTDB)) $ADODB_LASTDB = ''; + if (empty($db)) $db = $ADODB_LASTDB; + + if ($db != $ADODB_LASTDB) $db = ADOLoadCode($db); + + if (!$db) { + if (isset($origdsn)) $db = $origdsn; + if ($errorfn) { + // raise an error + $ignore = false; + $errorfn('ADONewConnection', 'ADONewConnection', -998, + "could not load the database driver for '$db'", + $db,false,$ignore); + } else + ADOConnection::outp( "

    ADONewConnection: Unable to load database driver '$db'

    ",false); + + return $false; + } + + $cls = 'ADODB_'.$db; + if (!class_exists($cls)) { + adodb_backtrace(); + return $false; + } + + $obj = new $cls(); + } + + # constructor should not fail + if ($obj) { + if ($errorfn) $obj->raiseErrorFn = $errorfn; + if (isset($dsna)) { + if (isset($dsna['port'])) $obj->port = $dsna['port']; + foreach($opt as $k => $v) { + switch(strtolower($k)) { + case 'new': + $nconnect = true; $persist = true; break; + case 'persist': + case 'persistent': $persist = $v; break; + case 'debug': $obj->debug = (integer) $v; break; + #ibase + case 'role': $obj->role = $v; break; + case 'dialect': $obj->dialect = (integer) $v; break; + case 'charset': $obj->charset = $v; $obj->charSet=$v; break; + case 'buffers': $obj->buffers = $v; break; + case 'fetchmode': $obj->SetFetchMode($v); break; + #ado + case 'charpage': $obj->charPage = $v; break; + #mysql, mysqli + case 'clientflags': $obj->clientFlags = $v; break; + #mysql, mysqli, postgres + case 'port': $obj->port = $v; break; + #mysqli + case 'socket': $obj->socket = $v; break; + #oci8 + case 'nls_date_format': $obj->NLS_DATE_FORMAT = $v; break; + } + } + if (empty($persist)) + $ok = $obj->Connect($dsna['host'], $dsna['user'], $dsna['pass'], $dsna['path']); + else if (empty($nconnect)) + $ok = $obj->PConnect($dsna['host'], $dsna['user'], $dsna['pass'], $dsna['path']); + else + $ok = $obj->NConnect($dsna['host'], $dsna['user'], $dsna['pass'], $dsna['path']); + + if (!$ok) return $false; + } + } + return $obj; + } + + + + // $perf == true means called by NewPerfMonitor(), otherwise for data dictionary + function _adodb_getdriver($provider,$drivername,$perf=false) + { + switch ($provider) { + case 'odbtp': if (strncmp('odbtp_',$drivername,6)==0) return substr($drivername,6); + case 'odbc' : if (strncmp('odbc_',$drivername,5)==0) return substr($drivername,5); + case 'ado' : if (strncmp('ado_',$drivername,4)==0) return substr($drivername,4); + case 'native': break; + default: + return $provider; + } + + switch($drivername) { + case 'mysqlt': + case 'mysqli': + $drivername='mysql'; + break; + case 'postgres7': + case 'postgres8': + $drivername = 'postgres'; + break; + case 'firebird15': $drivername = 'firebird'; break; + case 'oracle': $drivername = 'oci8'; break; + case 'access': if ($perf) $drivername = ''; break; + case 'db2' : break; + case 'sapdb' : break; + default: + $drivername = 'generic'; + break; + } + return $drivername; + } + + function &NewPerfMonitor(&$conn) + { + $false = false; + $drivername = _adodb_getdriver($conn->dataProvider,$conn->databaseType,true); + if (!$drivername || $drivername == 'generic') return $false; + include_once(ADODB_DIR.'/adodb-perf.inc.php'); + @include_once(ADODB_DIR."/perf/perf-$drivername.inc.php"); + $class = "Perf_$drivername"; + if (!class_exists($class)) return $false; + $perf = new $class($conn); + + return $perf; + } + + function &NewDataDictionary(&$conn,$drivername=false) + { + $false = false; + if (!$drivername) $drivername = _adodb_getdriver($conn->dataProvider,$conn->databaseType); + + include_once(ADODB_DIR.'/adodb-lib.inc.php'); + include_once(ADODB_DIR.'/adodb-datadict.inc.php'); + $path = ADODB_DIR."/datadict/datadict-$drivername.inc.php"; + + if (!file_exists($path)) { + ADOConnection::outp("Dictionary driver '$path' not available"); + return $false; + } + include_once($path); + $class = "ADODB2_$drivername"; + $dict = new $class(); + $dict->dataProvider = $conn->dataProvider; + $dict->connection = &$conn; + $dict->upperName = strtoupper($drivername); + $dict->quote = $conn->nameQuote; + if (!empty($conn->_connectionID)) + $dict->serverInfo = $conn->ServerInfo(); + + return $dict; + } + + + + /* + Perform a print_r, with pre tags for better formatting. + */ + function adodb_pr($var,$as_string=false) + { + if ($as_string) ob_start(); + + if (isset($_SERVER['HTTP_USER_AGENT'])) { + echo "
    \n";print_r($var);echo "
    \n"; + } else + print_r($var); + + if ($as_string) { + $s = ob_get_contents(); + ob_end_clean(); + return $s; + } + } + + /* + Perform a stack-crawl and pretty print it. + + @param printOrArr Pass in a boolean to indicate print, or an $exception->trace array (assumes that print is true then). + @param levels Number of levels to display + */ + function adodb_backtrace($printOrArr=true,$levels=9999) + { + global $ADODB_INCLUDED_LIB; + if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php'); + return _adodb_backtrace($printOrArr,$levels); + } + + + +} +?> diff --git a/upload/includes/adodb/adodb.php b/upload/includes/adodb/adodb.php new file mode 100644 index 00000000..db8b8bf7 --- /dev/null +++ b/upload/includes/adodb/adodb.php @@ -0,0 +1,7 @@ +debug = true; + @$db->Connect($server, $user, $password, $database); + +?> \ No newline at end of file diff --git a/upload/includes/adodb/drivers/adodb-mysql.inc.php b/upload/includes/adodb/drivers/adodb-mysql.inc.php new file mode 100644 index 00000000..2ee0e397 --- /dev/null +++ b/upload/includes/adodb/drivers/adodb-mysql.inc.php @@ -0,0 +1,849 @@ +rsPrefix .= 'ext_'; + } + + function ServerInfo() + { + $arr['description'] = ADOConnection::GetOne("select version()"); + $arr['version'] = ADOConnection::_findvers($arr['description']); + return $arr; + } + + function IfNull( $field, $ifNull ) + { + return " IFNULL($field, $ifNull) "; // if MySQL + } + + + function &MetaTables($ttype=false,$showSchema=false,$mask=false) + { + $save = $this->metaTablesSQL; + if ($showSchema && is_string($showSchema)) { + $this->metaTablesSQL .= " from $showSchema"; + } + + if ($mask) { + $mask = $this->qstr($mask); + $this->metaTablesSQL .= " like $mask"; + } + $ret =& ADOConnection::MetaTables($ttype,$showSchema); + + $this->metaTablesSQL = $save; + return $ret; + } + + + function &MetaIndexes ($table, $primary = FALSE, $owner=false) + { + // save old fetch mode + global $ADODB_FETCH_MODE; + + $false = false; + $save = $ADODB_FETCH_MODE; + $ADODB_FETCH_MODE = ADODB_FETCH_NUM; + if ($this->fetchMode !== FALSE) { + $savem = $this->SetFetchMode(FALSE); + } + + // get index details + $rs = $this->Execute(sprintf('SHOW INDEX FROM %s',$table)); + + // restore fetchmode + if (isset($savem)) { + $this->SetFetchMode($savem); + } + $ADODB_FETCH_MODE = $save; + + if (!is_object($rs)) { + return $false; + } + + $indexes = array (); + + // parse index data into array + while ($row = $rs->FetchRow()) { + if ($primary == FALSE AND $row[2] == 'PRIMARY') { + continue; + } + + if (!isset($indexes[$row[2]])) { + $indexes[$row[2]] = array( + 'unique' => ($row[1] == 0), + 'columns' => array() + ); + } + + $indexes[$row[2]]['columns'][$row[3] - 1] = $row[4]; + } + + // sort columns by order in the index + foreach ( array_keys ($indexes) as $index ) + { + ksort ($indexes[$index]['columns']); + } + + return $indexes; + } + + + // if magic quotes disabled, use mysql_real_escape_string() + function qstr($s,$magic_quotes=false) + { + if (is_null($s)) return 'NULL'; + + if (!$magic_quotes) { + + if (ADODB_PHPVER >= 0x4300) { + if (is_resource($this->_connectionID)) + return "'".mysql_real_escape_string($s,$this->_connectionID)."'"; + } + if ($this->replaceQuote[0] == '\\'){ + $s = adodb_str_replace(array('\\',"\0"),array('\\\\',"\\\0"),$s); + } + return "'".str_replace("'",$this->replaceQuote,$s)."'"; + } + + // undo magic quotes for " + $s = str_replace('\\"','"',$s); + return "'$s'"; + } + + function _insertid() + { + return ADOConnection::GetOne('SELECT LAST_INSERT_ID()'); + //return mysql_insert_id($this->_connectionID); + } + + function GetOne($sql,$inputarr=false) + { + if ($this->compat323 == false && strncasecmp($sql,'sele',4) == 0) { + $rs =& $this->SelectLimit($sql,1,-1,$inputarr); + if ($rs) { + $rs->Close(); + if ($rs->EOF) return false; + return reset($rs->fields); + } + } else { + return ADOConnection::GetOne($sql,$inputarr); + } + return false; + } + + function BeginTrans() + { + if ($this->debug) ADOConnection::outp("Transactions not supported in 'mysql' driver. Use 'mysqlt' or 'mysqli' driver"); + } + + function _affectedrows() + { + return mysql_affected_rows($this->_connectionID); + } + + // See http://www.mysql.com/doc/M/i/Miscellaneous_functions.html + // Reference on Last_Insert_ID on the recommended way to simulate sequences + var $_genIDSQL = "update %s set id=LAST_INSERT_ID(id+1);"; + var $_genSeqSQL = "create table %s (id int not null)"; + var $_genSeqCountSQL = "select count(*) from %s"; + var $_genSeq2SQL = "insert into %s values (%s)"; + var $_dropSeqSQL = "drop table %s"; + + function CreateSequence($seqname='adodbseq',$startID=1) + { + if (empty($this->_genSeqSQL)) return false; + $u = strtoupper($seqname); + + $ok = $this->Execute(sprintf($this->_genSeqSQL,$seqname)); + if (!$ok) return false; + return $this->Execute(sprintf($this->_genSeq2SQL,$seqname,$startID-1)); + } + + + function GenID($seqname='adodbseq',$startID=1) + { + // post-nuke sets hasGenID to false + if (!$this->hasGenID) return false; + + $savelog = $this->_logsql; + $this->_logsql = false; + $getnext = sprintf($this->_genIDSQL,$seqname); + $holdtransOK = $this->_transOK; // save the current status + $rs = @$this->Execute($getnext); + if (!$rs) { + if ($holdtransOK) $this->_transOK = true; //if the status was ok before reset + $u = strtoupper($seqname); + $this->Execute(sprintf($this->_genSeqSQL,$seqname)); + $cnt = $this->GetOne(sprintf($this->_genSeqCountSQL,$seqname)); + if (!$cnt) $this->Execute(sprintf($this->_genSeq2SQL,$seqname,$startID-1)); + $rs = $this->Execute($getnext); + } + + if ($rs) { + $this->genID = mysql_insert_id($this->_connectionID); + $rs->Close(); + } else + $this->genID = 0; + + $this->_logsql = $savelog; + return $this->genID; + } + + function &MetaDatabases() + { + $qid = mysql_list_dbs($this->_connectionID); + $arr = array(); + $i = 0; + $max = mysql_num_rows($qid); + while ($i < $max) { + $db = mysql_tablename($qid,$i); + if ($db != 'mysql') $arr[] = $db; + $i += 1; + } + return $arr; + } + + + // Format date column in sql string given an input format that understands Y M D + function SQLDate($fmt, $col=false) + { + if (!$col) $col = $this->sysTimeStamp; + $s = 'DATE_FORMAT('.$col.",'"; + $concat = false; + $len = strlen($fmt); + for ($i=0; $i < $len; $i++) { + $ch = $fmt[$i]; + switch($ch) { + + default: + if ($ch == '\\') { + $i++; + $ch = substr($fmt,$i,1); + } + /** FALL THROUGH */ + case '-': + case '/': + $s .= $ch; + break; + + case 'Y': + case 'y': + $s .= '%Y'; + break; + case 'M': + $s .= '%b'; + break; + + case 'm': + $s .= '%m'; + break; + case 'D': + case 'd': + $s .= '%d'; + break; + + case 'Q': + case 'q': + $s .= "'),Quarter($col)"; + + if ($len > $i+1) $s .= ",DATE_FORMAT($col,'"; + else $s .= ",('"; + $concat = true; + break; + + case 'H': + $s .= '%H'; + break; + + case 'h': + $s .= '%I'; + break; + + case 'i': + $s .= '%i'; + break; + + case 's': + $s .= '%s'; + break; + + case 'a': + case 'A': + $s .= '%p'; + break; + + case 'w': + $s .= '%w'; + break; + + case 'W': + $s .= '%U'; + break; + + case 'l': + $s .= '%W'; + break; + } + } + $s.="')"; + if ($concat) $s = "CONCAT($s)"; + return $s; + } + + + // returns concatenated string + // much easier to run "mysqld --ansi" or "mysqld --sql-mode=PIPES_AS_CONCAT" and use || operator + function Concat() + { + $s = ""; + $arr = func_get_args(); + + // suggestion by andrew005@mnogo.ru + $s = implode(',',$arr); + if (strlen($s) > 0) return "CONCAT($s)"; + else return ''; + } + + function OffsetDate($dayFraction,$date=false) + { + if (!$date) $date = $this->sysDate; + + $fraction = $dayFraction * 24 * 3600; + return $date . ' + INTERVAL ' . $fraction.' SECOND'; + +// return "from_unixtime(unix_timestamp($date)+$fraction)"; + } + + // returns true or false + function _connect($argHostname, $argUsername, $argPassword, $argDatabasename) + { + if (!empty($this->port)) $argHostname .= ":".$this->port; + + if (ADODB_PHPVER >= 0x4300) + $this->_connectionID = mysql_connect($argHostname,$argUsername,$argPassword, + $this->forceNewConnect,$this->clientFlags); + else if (ADODB_PHPVER >= 0x4200) + $this->_connectionID = mysql_connect($argHostname,$argUsername,$argPassword, + $this->forceNewConnect); + else + $this->_connectionID = mysql_connect($argHostname,$argUsername,$argPassword); + + if ($this->_connectionID === false) return false; + if ($argDatabasename) return $this->SelectDB($argDatabasename); + return true; + } + + // returns true or false + function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename) + { + if (!empty($this->port)) $argHostname .= ":".$this->port; + + if (ADODB_PHPVER >= 0x4300) + $this->_connectionID = mysql_pconnect($argHostname,$argUsername,$argPassword,$this->clientFlags); + else + $this->_connectionID = mysql_pconnect($argHostname,$argUsername,$argPassword); + if ($this->_connectionID === false) return false; + if ($this->autoRollback) $this->RollbackTrans(); + if ($argDatabasename) return $this->SelectDB($argDatabasename); + return true; + } + + function _nconnect($argHostname, $argUsername, $argPassword, $argDatabasename) + { + $this->forceNewConnect = true; + return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename); + } + + function &MetaColumns($table) + { + $this->_findschema($table,$schema); + if ($schema) { + $dbName = $this->database; + $this->SelectDB($schema); + } + global $ADODB_FETCH_MODE; + $save = $ADODB_FETCH_MODE; + $ADODB_FETCH_MODE = ADODB_FETCH_NUM; + + if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false); + $rs = $this->Execute(sprintf($this->metaColumnsSQL,$table)); + + if ($schema) { + $this->SelectDB($dbName); + } + + if (isset($savem)) $this->SetFetchMode($savem); + $ADODB_FETCH_MODE = $save; + if (!is_object($rs)) { + $false = false; + return $false; + } + + $retarr = array(); + while (!$rs->EOF){ + $fld = new ADOFieldObject(); + $fld->name = $rs->fields[0]; + $type = $rs->fields[1]; + + // split type into type(length): + $fld->scale = null; + if (preg_match("/^(.+)\((\d+),(\d+)/", $type, $query_array)) { + $fld->type = $query_array[1]; + $fld->max_length = is_numeric($query_array[2]) ? $query_array[2] : -1; + $fld->scale = is_numeric($query_array[3]) ? $query_array[3] : -1; + } elseif (preg_match("/^(.+)\((\d+)/", $type, $query_array)) { + $fld->type = $query_array[1]; + $fld->max_length = is_numeric($query_array[2]) ? $query_array[2] : -1; + } elseif (preg_match("/^(enum)\((.*)\)$/i", $type, $query_array)) { + $fld->type = $query_array[1]; + $arr = explode(",",$query_array[2]); + $fld->enums = $arr; + $zlen = max(array_map("strlen",$arr)) - 2; // PHP >= 4.0.6 + $fld->max_length = ($zlen > 0) ? $zlen : 1; + } else { + $fld->type = $type; + $fld->max_length = -1; + } + $fld->not_null = ($rs->fields[2] != 'YES'); + $fld->primary_key = ($rs->fields[3] == 'PRI'); + $fld->auto_increment = (strpos($rs->fields[5], 'auto_increment') !== false); + $fld->binary = (strpos($type,'blob') !== false); + $fld->unsigned = (strpos($type,'unsigned') !== false); + $fld->zerofill = (strpos($type,'zerofill') !== false); + + if (!$fld->binary) { + $d = $rs->fields[4]; + if ($d != '' && $d != 'NULL') { + $fld->has_default = true; + $fld->default_value = $d; + } else { + $fld->has_default = false; + } + } + + if ($save == ADODB_FETCH_NUM) { + $retarr[] = $fld; + } else { + $retarr[strtoupper($fld->name)] = $fld; + } + $rs->MoveNext(); + } + + $rs->Close(); + return $retarr; + } + + // returns true or false + function SelectDB($dbName) + { + $this->database = $dbName; + $this->databaseName = $dbName; # obsolete, retained for compat with older adodb versions + if ($this->_connectionID) { + return @mysql_select_db($dbName,$this->_connectionID); + } + else return false; + } + + // parameters use PostgreSQL convention, not MySQL + function &SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs=0) + { + $offsetStr =($offset>=0) ? ((integer)$offset)."," : ''; + // jason judge, see http://phplens.com/lens/lensforum/msgs.php?id=9220 + if ($nrows < 0) $nrows = '18446744073709551615'; + + if ($secs) + $rs =& $this->CacheExecute($secs,$sql." LIMIT $offsetStr".((integer)$nrows),$inputarr); + else + $rs =& $this->Execute($sql." LIMIT $offsetStr".((integer)$nrows),$inputarr); + return $rs; + } + + // returns queryID or false + function _query($sql,$inputarr) + { + //global $ADODB_COUNTRECS; + //if($ADODB_COUNTRECS) + $this->db_query = $sql; + return mysql_query($sql,$this->_connectionID); + //else return @mysql_unbuffered_query($sql,$this->_connectionID); // requires PHP >= 4.0.6 + } + + /* Returns: the last error message from previous database operation */ + function ErrorMsg() + { + + if ($this->_logsql) return $this->_errorMsg; + if (empty($this->_connectionID)) $this->_errorMsg = @mysql_error(); + else $this->_errorMsg = @mysql_error($this->_connectionID); + + $msg = $this->db_query.'
    '; + return $msg.$this->_errorMsg; + } + + /* Returns: the last error number from previous database operation */ + function ErrorNo() + { + if ($this->_logsql) return $this->_errorCode; + if (empty($this->_connectionID)) return @mysql_errno(); + else return @mysql_errno($this->_connectionID); + } + + // returns true or false + function _close() + { + @mysql_close($this->_connectionID); + $this->_connectionID = false; + } + + + /* + * Maximum size of C field + */ + function CharMax() + { + return 255; + } + + /* + * Maximum size of X field + */ + function TextMax() + { + return 4294967295; + } + + // "Innox - Juan Carlos Gonzalez" + function MetaForeignKeys( $table, $owner = FALSE, $upper = FALSE, $associative = FALSE ) + { + global $ADODB_FETCH_MODE; + if ($ADODB_FETCH_MODE == ADODB_FETCH_ASSOC || $this->fetchMode == ADODB_FETCH_ASSOC) $associative = true; + + if ( !empty($owner) ) { + $table = "$owner.$table"; + } + $a_create_table = $this->getRow(sprintf('SHOW CREATE TABLE %s', $table)); + if ($associative) $create_sql = $a_create_table["Create Table"]; + else $create_sql = $a_create_table[1]; + + $matches = array(); + + if (!preg_match_all("/FOREIGN KEY \(`(.*?)`\) REFERENCES `(.*?)` \(`(.*?)`\)/", $create_sql, $matches)) return false; + $foreign_keys = array(); + $num_keys = count($matches[0]); + for ( $i = 0; $i < $num_keys; $i ++ ) { + $my_field = explode('`, `', $matches[1][$i]); + $ref_table = $matches[2][$i]; + $ref_field = explode('`, `', $matches[3][$i]); + + if ( $upper ) { + $ref_table = strtoupper($ref_table); + } + + $foreign_keys[$ref_table] = array(); + $num_fields = count($my_field); + for ( $j = 0; $j < $num_fields; $j ++ ) { + if ( $associative ) { + $foreign_keys[$ref_table][$ref_field[$j]] = $my_field[$j]; + } else { + $foreign_keys[$ref_table][] = "{$my_field[$j]}={$ref_field[$j]}"; + } + } + } + + return $foreign_keys; + } + + +} + +/*-------------------------------------------------------------------------------------- + Class Name: Recordset +--------------------------------------------------------------------------------------*/ + + +class ADORecordSet_mysql extends ADORecordSet{ + + var $databaseType = "mysql"; + var $canSeek = true; + + function ADORecordSet_mysql($queryID,$mode=false) + { + if ($mode === false) { + global $ADODB_FETCH_MODE; + $mode = $ADODB_FETCH_MODE; + } + switch ($mode) + { + case ADODB_FETCH_NUM: $this->fetchMode = MYSQL_NUM; break; + case ADODB_FETCH_ASSOC:$this->fetchMode = MYSQL_ASSOC; break; + case ADODB_FETCH_DEFAULT: + case ADODB_FETCH_BOTH: + default: + $this->fetchMode = MYSQL_BOTH; break; + } + $this->adodbFetchMode = $mode; + $this->ADORecordSet($queryID); + } + + function _initrs() + { + //GLOBAL $ADODB_COUNTRECS; + // $this->_numOfRows = ($ADODB_COUNTRECS) ? @mysql_num_rows($this->_queryID):-1; + $this->_numOfRows = @mysql_num_rows($this->_queryID); + $this->_numOfFields = @mysql_num_fields($this->_queryID); + $this->num_rows = @mysql_num_rows($this->_queryID); + } + + function &FetchField($fieldOffset = -1) + { + if ($fieldOffset != -1) { + $o = @mysql_fetch_field($this->_queryID, $fieldOffset); + $f = @mysql_field_flags($this->_queryID,$fieldOffset); + $o->max_length = @mysql_field_len($this->_queryID,$fieldOffset); // suggested by: Jim Nicholson (jnich#att.com) + //$o->max_length = -1; // mysql returns the max length less spaces -- so it is unrealiable + $o->binary = (strpos($f,'binary')!== false); + } + else if ($fieldOffset == -1) { /* The $fieldOffset argument is not provided thus its -1 */ + $o = @mysql_fetch_field($this->_queryID); + $o->max_length = @mysql_field_len($this->_queryID); // suggested by: Jim Nicholson (jnich#att.com) + //$o->max_length = -1; // mysql returns the max length less spaces -- so it is unrealiable + } + + return $o; + } + + function &GetRowAssoc($upper=true) + { + if ($this->fetchMode == MYSQL_ASSOC && !$upper) $row = $this->fields; + else $row =& ADORecordSet::GetRowAssoc($upper); + return $row; + } + + /* Use associative array to get fields array */ + function Fields($colname) + { + // added @ by "Michael William Miller" + if ($this->fetchMode != MYSQL_NUM) return @$this->fields[$colname]; + + if (!$this->bind) { + $this->bind = array(); + for ($i=0; $i < $this->_numOfFields; $i++) { + $o = $this->FetchField($i); + $this->bind[strtoupper($o->name)] = $i; + } + } + return $this->fields[$this->bind[strtoupper($colname)]]; + } + + function _seek($row) + { + if ($this->_numOfRows == 0) return false; + return @mysql_data_seek($this->_queryID,$row); + } + + function MoveNext() + { + //return adodb_movenext($this); + //if (defined('ADODB_EXTENSION')) return adodb_movenext($this); + if (@$this->fields = mysql_fetch_array($this->_queryID,$this->fetchMode)) { + $this->_currentRow += 1; + return true; + } + if (!$this->EOF) { + $this->_currentRow += 1; + $this->EOF = true; + } + return false; + } + + function _fetch() + { + $this->fields = @mysql_fetch_array($this->_queryID,$this->fetchMode); + return is_array($this->fields); + } + + function my_fetch() + { + $this->_fetch(); + } + + function _close() { + @mysql_free_result($this->_queryID); + $this->_queryID = false; + } + + function MetaType($t,$len=-1,$fieldobj=false) + { + if (is_object($t)) { + $fieldobj = $t; + $t = $fieldobj->type; + $len = $fieldobj->max_length; + } + + $len = -1; // mysql max_length is not accurate + switch (strtoupper($t)) { + case 'STRING': + case 'CHAR': + case 'VARCHAR': + case 'TINYBLOB': + case 'TINYTEXT': + case 'ENUM': + case 'SET': + if ($len <= $this->blobSize) return 'C'; + + case 'TEXT': + case 'LONGTEXT': + case 'MEDIUMTEXT': + return 'X'; + + // php_mysql extension always returns 'blob' even if 'text' + // so we have to check whether binary... + case 'IMAGE': + case 'LONGBLOB': + case 'BLOB': + case 'MEDIUMBLOB': + return !empty($fieldobj->binary) ? 'B' : 'X'; + + case 'YEAR': + case 'DATE': return 'D'; + + case 'TIME': + case 'DATETIME': + case 'TIMESTAMP': return 'T'; + + case 'INT': + case 'INTEGER': + case 'BIGINT': + case 'TINYINT': + case 'MEDIUMINT': + case 'SMALLINT': + + if (!empty($fieldobj->primary_key)) return 'R'; + else return 'I'; + + default: return 'N'; + } + } + +} + +class ADORecordSet_ext_mysql extends ADORecordSet_mysql { + function ADORecordSet_ext_mysql($queryID,$mode=false) + { + if ($mode === false) { + global $ADODB_FETCH_MODE; + $mode = $ADODB_FETCH_MODE; + } + switch ($mode) + { + case ADODB_FETCH_NUM: $this->fetchMode = MYSQL_NUM; break; + case ADODB_FETCH_ASSOC:$this->fetchMode = MYSQL_ASSOC; break; + case ADODB_FETCH_DEFAULT: + case ADODB_FETCH_BOTH: + default: + $this->fetchMode = MYSQL_BOTH; break; + } + $this->adodbFetchMode = $mode; + $this->ADORecordSet($queryID); + } + + function MoveNext() + { + return @adodb_movenext($this); + } + +} + + + +} +?> \ No newline at end of file diff --git a/upload/includes/adodb/index.php b/upload/includes/adodb/index.php new file mode 100644 index 00000000..403f2e18 --- /dev/null +++ b/upload/includes/adodb/index.php @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/upload/includes/adodb/pivottable.inc.php b/upload/includes/adodb/pivottable.inc.php new file mode 100644 index 00000000..0e0e7b1f --- /dev/null +++ b/upload/includes/adodb/pivottable.inc.php @@ -0,0 +1,187 @@ +databaseType,'access') !== false; + // note - vfp 6 still doesn' work even with IIF enabled || $db->databaseType == 'vfp'; + + //$hidecnt = false; + + if ($where) $where = "\nWHERE $where"; + if (!is_array($colfield)) $colarr = $db->GetCol("select distinct $colfield from $tables $where order by 1"); + if (!$aggfield) $hidecnt = false; + + $sel = "$rowfields, "; + if (is_array($colfield)) { + foreach ($colfield as $k => $v) { + $k = trim($k); + if (!$hidecnt) { + $sel .= $iif ? + "\n\t$aggfn(IIF($v,1,0)) AS \"$k\", " + : + "\n\t$aggfn(CASE WHEN $v THEN 1 ELSE 0 END) AS \"$k\", "; + } + if ($aggfield) { + $sel .= $iif ? + "\n\t$aggfn(IIF($v,$aggfield,0)) AS \"$sumlabel$k\", " + : + "\n\t$aggfn(CASE WHEN $v THEN $aggfield ELSE 0 END) AS \"$sumlabel$k\", "; + } + } + } else { + foreach ($colarr as $v) { + if (!is_numeric($v)) $vq = $db->qstr($v); + else $vq = $v; + $v = trim($v); + if (strlen($v) == 0 ) $v = 'null'; + if (!$hidecnt) { + $sel .= $iif ? + "\n\t$aggfn(IIF($colfield=$vq,1,0)) AS \"$v\", " + : + "\n\t$aggfn(CASE WHEN $colfield=$vq THEN 1 ELSE 0 END) AS \"$v\", "; + } + if ($aggfield) { + if ($hidecnt) $label = $v; + else $label = "{$v}_$aggfield"; + $sel .= $iif ? + "\n\t$aggfn(IIF($colfield=$vq,$aggfield,0)) AS \"$label\", " + : + "\n\t$aggfn(CASE WHEN $colfield=$vq THEN $aggfield ELSE 0 END) AS \"$label\", "; + } + } + } + if ($aggfield && $aggfield != '1'){ + $agg = "$aggfn($aggfield)"; + $sel .= "\n\t$agg as \"$sumlabel$aggfield\", "; + } + + if ($showcount) + $sel .= "\n\tSUM(1) as Total"; + else + $sel = substr($sel,0,strlen($sel)-2); + + + // Strip aliases + $rowfields = preg_replace('/ AS (\w+)/i', '', $rowfields); + + $sql = "SELECT $sel \nFROM $tables $where \nGROUP BY $rowfields"; + + return $sql; + } + +/* EXAMPLES USING MS NORTHWIND DATABASE */ +if (0) { + +# example1 +# +# Query the main "product" table +# Set the rows to CompanyName and QuantityPerUnit +# and the columns to the Categories +# and define the joins to link to lookup tables +# "categories" and "suppliers" +# + + $sql = PivotTableSQL( + $gDB, # adodb connection + 'products p ,categories c ,suppliers s', # tables + 'CompanyName,QuantityPerUnit', # row fields + 'CategoryName', # column fields + 'p.CategoryID = c.CategoryID and s.SupplierID= p.SupplierID' # joins/where +); + print "
    $sql";
    + $rs = $gDB->Execute($sql);
    + rs2html($rs);
    + 
    +/*
    +Generated SQL:
    +
    +SELECT CompanyName,QuantityPerUnit, 
    +	SUM(CASE WHEN CategoryName='Beverages' THEN 1 ELSE 0 END) AS "Beverages", 
    +	SUM(CASE WHEN CategoryName='Condiments' THEN 1 ELSE 0 END) AS "Condiments", 
    +	SUM(CASE WHEN CategoryName='Confections' THEN 1 ELSE 0 END) AS "Confections", 
    +	SUM(CASE WHEN CategoryName='Dairy Products' THEN 1 ELSE 0 END) AS "Dairy Products", 
    +	SUM(CASE WHEN CategoryName='Grains/Cereals' THEN 1 ELSE 0 END) AS "Grains/Cereals", 
    +	SUM(CASE WHEN CategoryName='Meat/Poultry' THEN 1 ELSE 0 END) AS "Meat/Poultry", 
    +	SUM(CASE WHEN CategoryName='Produce' THEN 1 ELSE 0 END) AS "Produce", 
    +	SUM(CASE WHEN CategoryName='Seafood' THEN 1 ELSE 0 END) AS "Seafood", 
    +	SUM(1) as Total 
    +FROM products p ,categories c ,suppliers s  WHERE p.CategoryID = c.CategoryID and s.SupplierID= p.SupplierID 
    +GROUP BY CompanyName,QuantityPerUnit
    +*/
    +//=====================================================================
    +
    +# example2
    +#
    +# Query the main "product" table
    +# Set the rows to CompanyName and QuantityPerUnit
    +# and the columns to the UnitsInStock for diiferent ranges
    +# and define the joins to link to lookup tables 
    +# "categories" and "suppliers"
    +#
    + $sql = PivotTableSQL(
    + 	$gDB,										# adodb connection
    + 	'products p ,categories c ,suppliers s',	# tables
    +	'CompanyName,QuantityPerUnit',				# row fields
    +												# column ranges
    +array(										
    +' 0 ' => 'UnitsInStock <= 0',
    +"1 to 5" => '0 < UnitsInStock and UnitsInStock <= 5',
    +"6 to 10" => '5 < UnitsInStock and UnitsInStock <= 10',
    +"11 to 15"  => '10 < UnitsInStock and UnitsInStock <= 15',
    +"16+" =>'15 < UnitsInStock'
    +),
    +	' p.CategoryID = c.CategoryID and s.SupplierID= p.SupplierID', # joins/where
    +	'UnitsInStock', 							# sum this field
    +	'Sum'										# sum label prefix
    +);
    + print "
    $sql";
    + $rs = $gDB->Execute($sql);
    + rs2html($rs);
    + /*
    + Generated SQL:
    + 
    +SELECT CompanyName,QuantityPerUnit, 
    +	SUM(CASE WHEN UnitsInStock <= 0 THEN UnitsInStock ELSE 0 END) AS "Sum  0 ", 
    +	SUM(CASE WHEN 0 < UnitsInStock and UnitsInStock <= 5 THEN UnitsInStock ELSE 0 END) AS "Sum 1 to 5", 
    +	SUM(CASE WHEN 5 < UnitsInStock and UnitsInStock <= 10 THEN UnitsInStock ELSE 0 END) AS "Sum 6 to 10", 
    +	SUM(CASE WHEN 10 < UnitsInStock and UnitsInStock <= 15 THEN UnitsInStock ELSE 0 END) AS "Sum 11 to 15", 
    +	SUM(CASE WHEN 15 < UnitsInStock THEN UnitsInStock ELSE 0 END) AS "Sum 16+",
    +	SUM(UnitsInStock) AS "Sum UnitsInStock", 
    +	SUM(1) as Total 
    +FROM products p ,categories c ,suppliers s  WHERE  p.CategoryID = c.CategoryID and s.SupplierID= p.SupplierID 
    +GROUP BY CompanyName,QuantityPerUnit
    + */
    +}
    +?>
    \ No newline at end of file
    diff --git a/upload/includes/adodb/rsfilter.inc.php b/upload/includes/adodb/rsfilter.inc.php
    new file mode 100644
    index 00000000..29662a21
    --- /dev/null
    +++ b/upload/includes/adodb/rsfilter.inc.php
    @@ -0,0 +1,61 @@
    + $v) {
    +			$arr[$k] = ucwords($v);
    +		}
    +	}
    +	$rs = RSFilter($rs,'do_ucwords');
    + */
    +function &RSFilter($rs,$fn)
    +{
    +	if ($rs->databaseType != 'array') {
    +		if (!$rs->connection) return false;
    +		
    +		$rs = &$rs->connection->_rs2rs($rs);
    +	}
    +	$rows = $rs->RecordCount();
    +	for ($i=0; $i < $rows; $i++) {
    +		if (is_array ($fn)) {
    +        	$obj = $fn[0];
    +        	$method = $fn[1];
    +        	$obj->$method ($rs->_array[$i],$rs);
    +      } else {
    +			$fn($rs->_array[$i],$rs);
    +      }
    +	  
    +	}
    +	if (!$rs->EOF) {
    +		$rs->_currentRow = 0;
    +		$rs->fields = $rs->_array[0];
    +	}
    +	
    +	return $rs;
    +}
    +?>
    \ No newline at end of file
    diff --git a/upload/includes/adodb/server.php b/upload/includes/adodb/server.php
    new file mode 100644
    index 00000000..a39f9c77
    --- /dev/null
    +++ b/upload/includes/adodb/server.php
    @@ -0,0 +1,100 @@
    +Connect($host,$uid,$pwd,$database)) err($conn->ErrorNo(). $sep . $conn->ErrorMsg());
    +$sql = undomq($_REQUEST['sql']);
    +
    +if (isset($_REQUEST['fetch']))
    +	$ADODB_FETCH_MODE = $_REQUEST['fetch'];
    +	
    +if (isset($_REQUEST['nrows'])) {
    +	$nrows = $_REQUEST['nrows'];
    +	$offset = isset($_REQUEST['offset']) ? $_REQUEST['offset'] : -1;
    +	$rs = $conn->SelectLimit($sql,$nrows,$offset);
    +} else 
    +	$rs = $conn->Execute($sql);
    +if ($rs){ 
    +	//$rs->timeToLive = 1;
    +	echo _rs2serialize($rs,$conn,$sql);
    +	$rs->Close();
    +} else
    +	err($conn->ErrorNo(). $sep .$conn->ErrorMsg());
    +
    +?>
    \ No newline at end of file
    diff --git a/upload/includes/adodb/toexport.inc.php b/upload/includes/adodb/toexport.inc.php
    new file mode 100644
    index 00000000..ba3f37a2
    --- /dev/null
    +++ b/upload/includes/adodb/toexport.inc.php
    @@ -0,0 +1,133 @@
    +FieldTypesArray();
    +		reset($fieldTypes);
    +		while(list(,$o) = each($fieldTypes)) {
    +			
    +			$v = $o->name;
    +			if ($escquote) $v = str_replace($quote,$escquotequote,$v);
    +			$v = strip_tags(str_replace("\n", $replaceNewLine, str_replace("\r\n",$replaceNewLine,str_replace($sep,$sepreplace,$v))));
    +			$elements[] = $v;
    +			
    +		}
    +		$s .= implode($sep, $elements).$NEWLINE;
    +	}
    +	$hasNumIndex = isset($rs->fields[0]);
    +	
    +	$line = 0;
    +	$max = $rs->FieldCount();
    +	
    +	while (!$rs->EOF) {
    +		$elements = array();
    +		$i = 0;
    +		
    +		if ($hasNumIndex) {
    +			for ($j=0; $j < $max; $j++) {
    +				$v = $rs->fields[$j];
    +				if (!is_object($v)) $v = trim($v);
    +				else $v = 'Object';
    +				if ($escquote) $v = str_replace($quote,$escquotequote,$v);
    +				$v = strip_tags(str_replace("\n", $replaceNewLine, str_replace("\r\n",$replaceNewLine,str_replace($sep,$sepreplace,$v))));
    +				
    +				if (strpos($v,$sep) !== false || strpos($v,$quote) !== false) $elements[] = "$quote$v$quote";
    +				else $elements[] = $v;
    +			}
    +		} else { // ASSOCIATIVE ARRAY
    +			foreach($rs->fields as $v) {
    +				if ($escquote) $v = str_replace($quote,$escquotequote,trim($v));
    +				$v = strip_tags(str_replace("\n", $replaceNewLine, str_replace("\r\n",$replaceNewLine,str_replace($sep,$sepreplace,$v))));
    +				
    +				if (strpos($v,$sep) !== false || strpos($v,$quote) !== false) $elements[] = "$quote$v$quote";
    +				else $elements[] = $v;
    +			}
    +		}
    +		$s .= implode($sep, $elements).$NEWLINE;
    +		$rs->MoveNext();
    +		$line += 1;
    +		if ($fp && ($line % $BUFLINES) == 0) {
    +			if ($fp === true) echo $s;
    +			else fwrite($fp,$s);
    +			$s = '';
    +		}
    +	}
    +	
    +	if ($fp) {
    +		if ($fp === true) echo $s;
    +		else fwrite($fp,$s);
    +		$s = '';
    +	}
    +	
    +	return $s;
    +}
    +?>
    \ No newline at end of file
    diff --git a/upload/includes/adodb/tohtml.inc.php b/upload/includes/adodb/tohtml.inc.php
    new file mode 100644
    index 00000000..b9bef03f
    --- /dev/null
    +++ b/upload/includes/adodb/tohtml.inc.php
    @@ -0,0 +1,195 @@
    +
    +*/ 
    +  
    +// specific code for tohtml
    +GLOBAL $gSQLMaxRows,$gSQLBlockRows,$ADODB_ROUND;
    +
    +$ADODB_ROUND=4; // rounding
    +$gSQLMaxRows = 1000; // max no of rows to download
    +$gSQLBlockRows=20; // max no of rows per table block
    +
    +// RecordSet to HTML Table
    +//------------------------------------------------------------
    +// Convert a recordset to a html table. Multiple tables are generated
    +// if the number of rows is > $gSQLBlockRows. This is because
    +// web browsers normally require the whole table to be downloaded
    +// before it can be rendered, so we break the output into several
    +// smaller faster rendering tables.
    +//
    +// $rs: the recordset
    +// $ztabhtml: the table tag attributes (optional)
    +// $zheaderarray: contains the replacement strings for the headers (optional)
    +//
    +//  USAGE:
    +//	include('adodb.inc.php');
    +//	$db = ADONewConnection('mysql');
    +//	$db->Connect('mysql','userid','password','database');
    +//	$rs = $db->Execute('select col1,col2,col3 from table');
    +//	rs2html($rs, 'BORDER=2', array('Title1', 'Title2', 'Title3'));
    +//	$rs->Close();
    +//
    +// RETURNS: number of rows displayed
    +
    +
    +function rs2html(&$rs,$ztabhtml=false,$zheaderarray=false,$htmlspecialchars=true,$echo = true)
    +{
    +$s ='';$rows=0;$docnt = false;
    +GLOBAL $gSQLMaxRows,$gSQLBlockRows,$ADODB_ROUND;
    +
    +	if (!$rs) {
    +		printf(ADODB_BAD_RS,'rs2html');
    +		return false;
    +	}
    +	
    +	if (! $ztabhtml) $ztabhtml = "BORDER='1' WIDTH='98%'";
    +	//else $docnt = true;
    +	$typearr = array();
    +	$ncols = $rs->FieldCount();
    +	$hdr = "\n\n";
    +	for ($i=0; $i < $ncols; $i++) {	
    +		$field = $rs->FetchField($i);
    +		if ($field) {
    +			if ($zheaderarray) $fname = $zheaderarray[$i];
    +			else $fname = htmlspecialchars($field->name);	
    +			$typearr[$i] = $rs->MetaType($field->type,$field->max_length);
    + 			//print " $field->name $field->type $typearr[$i] ";
    +		} else {
    +			$fname = 'Field '.($i+1);
    +			$typearr[$i] = 'C';
    +		}
    +		if (strlen($fname)==0) $fname = ' ';
    +		$hdr .= "";
    +	}
    +	$hdr .= "\n";
    +	if ($echo) print $hdr."\n\n";
    +	else $html = $hdr;
    +	
    +	// smart algorithm - handles ADODB_FETCH_MODE's correctly by probing...
    +	$numoffset = isset($rs->fields[0]) ||isset($rs->fields[1]) || isset($rs->fields[2]);
    +	while (!$rs->EOF) {
    +		
    +		$s .= "\n";
    +		
    +		for ($i=0; $i < $ncols; $i++) {
    +			if ($i===0) $v=($numoffset) ? $rs->fields[0] : reset($rs->fields);
    +			else $v = ($numoffset) ? $rs->fields[$i] : next($rs->fields);
    +			
    +			$type = $typearr[$i];
    +			switch($type) {
    +			case 'D':
    +				if (empty($v)) $s .= "\n";
    +				else if (!strpos($v,':')) {
    +					$s .= "	\n";
    +				}
    +				break;
    +			case 'T':
    +				if (empty($v)) $s .= "\n";
    +				else $s .= "	\n";
    +			break;
    +			
    +			case 'N':
    +				if (abs(abs($v) - round($v,0)) < 0.00000001)
    +					$v = round($v);
    +				else
    +					$v = round($v,$ADODB_ROUND);
    +			case 'I':
    +				$s .= "	\n";
    +			   	
    +			break;
    +			/*
    +			case 'B':
    +				if (substr($v,8,2)=="BM" ) $v = substr($v,8);
    +				$mtime = substr(str_replace(' ','_',microtime()),2);
    +				$tmpname = "tmp/".uniqid($mtime).getmypid();
    +				$fd = @fopen($tmpname,'a');
    +				@ftruncate($fd,0);
    +				@fwrite($fd,$v);
    +				@fclose($fd);
    +				if (!function_exists ("mime_content_type")) {
    +				  function mime_content_type ($file) {
    +				    return exec("file -bi ".escapeshellarg($file));
    +				  }
    +				}
    +				$t = mime_content_type($tmpname);
    +				$s .= (substr($t,0,5)=="image") ? " \\n" : " \\n";
    +				break;
    +			*/
    +
    +			default:
    +				if ($htmlspecialchars) $v = htmlspecialchars(trim($v));
    +				$v = trim($v);
    +				if (strlen($v) == 0) $v = ' ';
    +				$s .= "	\n";
    +			  
    +			}
    +		} // for
    +		$s .= "\n\n";
    +			  
    +		$rows += 1;
    +		if ($rows >= $gSQLMaxRows) {
    +			$rows = "

    Truncated at $gSQLMaxRows

    "; + break; + } // switch + + $rs->MoveNext(); + + // additional EOF check to prevent a widow header + if (!$rs->EOF && $rows % $gSQLBlockRows == 0) { + + //if (connection_aborted()) break;// not needed as PHP aborts script, unlike ASP + if ($echo) print $s . "
    $fname
      ".$rs->UserDate($v,"D d, M Y") ."    ".$rs->UserTimeStamp($v,"D d, M Y, h:i:s") ." ".stripslashes((trim($v))) ." $t$t". str_replace("\n",'
    ',stripslashes($v)) ."
    \n\n"; + else $html .= $s ."\n\n"; + $s = $hdr; + } + } // while + + if ($echo) print $s."\n\n"; + else $html .= $s."\n\n"; + + if ($docnt) if ($echo) print "

    ".$rows." Rows

    "; + + return ($echo) ? $rows : $html; + } + +// pass in 2 dimensional array +function arr2html(&$arr,$ztabhtml='',$zheaderarray='') +{ + if (!$ztabhtml) $ztabhtml = 'BORDER=1'; + + $s = "";//';print_r($arr); + + if ($zheaderarray) { + $s .= ''; + for ($i=0; $i\n"; + } else $s .= " \n"; + $s .= "\n\n"; + } + $s .= '
     
    '; + print $s; +} + +?> \ No newline at end of file diff --git a/upload/includes/adodb/xmlschema.dtd b/upload/includes/adodb/xmlschema.dtd new file mode 100644 index 00000000..337a9930 --- /dev/null +++ b/upload/includes/adodb/xmlschema.dtd @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +] > \ No newline at end of file diff --git a/upload/includes/adodb/xmlschema03.dtd b/upload/includes/adodb/xmlschema03.dtd new file mode 100644 index 00000000..a7c8864f --- /dev/null +++ b/upload/includes/adodb/xmlschema03.dtd @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]> \ No newline at end of file diff --git a/upload/includes/classes/ClipBucket.class.php b/upload/includes/classes/ClipBucket.class.php new file mode 100644 index 00000000..4ecad8ec --- /dev/null +++ b/upload/includes/classes/ClipBucket.class.php @@ -0,0 +1,296 @@ + tag + var $anchor_function_list = array(); + var $show_page = true; + var $upload_opt_list = array();//this will have array of upload opts like upload file, emebed or remote upload + var $temp_exts = array(); //Temp extensions + var $actions_play_video = array(); + var $template_files = array(); + + function ClipBucket () + { + global $pages; + //Assign Configs + $this->configs = $this->get_configs(); + //Get Current Page and Redirects it to without www. + $pages->redirectOrig(); + //Get Base Directory + $this->BASEDIR = $this->getBasedir(); + //Listing Common JS File + $this->addJS(array + ( + 'ajax.js' => 'homeactive', + 'jquery.js' => 'global', + 'dropdown.js' => 'global', + 'flashobject.js' => 'global', + 'rating_update.js' => 'global', + 'checkall.js' => 'global', + 'redir.js' => 'global', + 'functions.js' => 'global', + 'jquery_plugs/date_picker.js' => 'global', + )); + + //This is used to create Admin Menu + $this->AdminMenu = $this->get_admin_menu(); + + //Updating Upload Options + $this->upload_opt_list = array + ( + 'file_upload_div' => array( + 'title' => 'Upload File', + 'func_class' => 'Upload', + 'load_func' => 'load_upload_form', + ), + 'remote_upload_div' => array( + 'title' => 'Remote Upload', + 'func_class' => 'Upload', + 'load_func' => 'load_remote_upload_form', + ) + ); + + $this->temp_exts = array('ahz','jhz','abc','xyz','cb2','tmp','olo'); + } + + + function getBasedir() + { + $dirname = dirname(__FILE__); + $dirname = preg_replace(array('/includes/','/classes/'),'',$dirname); + $dirname = substr($dirname,0,strlen($dirname) -2); + return $dirname == '/' ? '' : $dirname; + } + + function addJS($files) + { + if(is_array($files)) + { + foreach($files as $key=> $file) + $this->JSArray[$key] = $file; + }else{ + $this->JSArray[$files] = 'global'; + } + + } + function add_js($files) + { + $this->addJS($files); + } + + /** + * Function add_header() + * this will be used to add new files in header array + * this is basically for plugins + * for specific page array('page'=>'file') + * ie array('uploadactive'=>'datepicker.js') + */ + function add_header($files) + { + if(is_array($files)) + { + foreach($files as $key=> $file) + $this->header_files[$key] = $file; + }else{ + $this->header_files[$files] = 'global'; + } + } + + /** + * Function used to get list of function of any type + * @param : type (category,title,date etc) + */ + function getFunctionList($type) + { + return $this->actionList[$type]; + } + + + /** + * Function used to get anchors that are registered in plugins + */ + function get_anchor_codes($place) + { + //Geting list of codes available for $place + $list = $this->anchorList[$place]; + return $list; + } + + /** + * Function used to get function of anchors that are registered in plugins + */ + function get_anchor_function_list($place) + { + //Geting list of functions + $list = $this->anchor_function_list[$place]; + return $list; + } + + /** + * Function used to create admin menu + */ + function get_admin_menu() + { + $menu_array = array + ( + //Statistics + 'Statiscs & Reports' => + array( + 'Daily Stats'=>'statiscts.php', + 'Full Reports'=>'reports.php' + ), + + //Language Editor + 'Language'=> + array( + 'Language Settings' => 'language_settings.php', + 'Add New Phrases' => 'add_phrase.php', + ), + //Configurations + 'Configurations' => + array( + 'Website Configurations'=>'main.php', + 'Email Settings'=>'email_settings.php', + ), + + //Video + 'Videos' => + array( + 'Videos Manager'=>'video_manager.php', + 'Manage Categories'=>'category.php', + 'List Flagged Videos'=>'flagged_videos.php', + 'Upload Videos' =>'mass_uploader.php', + 'List Inavtive Videos'=>'video_manager.php?view=search&&active=no' + ), + + //Users + 'Users' => + array( + 'Manage Members' => 'members.php?view=showall', + 'Add Member'=>'members.php?view=addmember', + 'User Levels'=>'user_levels.php', + 'Search Members'=>'members.php?view=search', + 'Inactive Only'=>'members.php?view=inactive', + 'Active Only'=>'members.php?view=active', + 'Mass Email'=>'mass_email.php' + ), + + //Groups + 'Groups' => + array( + 'Manage Groups'=>'groups_manager.php', + 'Manage Categories'=>'category.php?view=show_category' + ), + + //Advertisments + 'Advertisement' => + array( + 'Manage Advertisments'=>'ads_manager.php', + 'Manage Placements'=>'ads_add_placements.php', + ), + + //Template Manager + 'Template Manager'=> + array( + 'Template Editor'=>'templates.php', + 'Logo Changer' =>'logo_change.php' + + ), + + + //Plugin Manager + 'Plugin Manager'=> + array( + 'Plugin Manager'=>'plugin_manager.php' + ), + + //Tool Box + 'Tool Box'=> + array( + 'Module Manager'=>'module_manager.php', + 'PHP Info' => 'phpinfo.php', + 'FFMPEG Info'=>'', + 'All Modules Info'=>'', + 'View Encoding Status'=>'', + ), + + ); + + return $menu_array; + } + + /** + * Function used to assign ClipBucket configurations + */ + function get_configs() + { + global $myquery; + return $myquery->Get_Website_Details(); + } + + /** + * Funtion cused to get list of countries + */ + function get_countries($type=iso2) + { + global $db; + $results = $db->select("countries","*"); + + switch($type) + { + case id: + foreach($results as $result) + { + $carray[$result['id']] = $result['name_en']; + } + break; + case iso2: + foreach($results as $result) + { + $carray[$result['iso2']] = $result['name_en']; + } + break; + case iso3: + foreach($results as $result) + { + $carray[$result['iso3']] = $result['name_en']; + } + break; + default: + foreach($results as $result) + { + $carray[$result['id']] = $result['name_en']; + } + break; + } + + return $carray; + } + + /** + * Function used to set show_page = false or true + */ + function show_page($val=true) + { + $this->show_page = $val; + } +} + +?> \ No newline at end of file diff --git a/upload/includes/classes/ads.class.php b/upload/includes/classes/ads.class.php new file mode 100644 index 00000000..62f9b07d --- /dev/null +++ b/upload/includes/classes/ads.class.php @@ -0,0 +1,198 @@ +0){ + $msg = e($LANG['ad_exists_error2']); + } + if(empty($msg)){ + mysql_query("INSERT INTO ads_data (ad_category,ad_name,ad_placement,ad_code,ad_status)VALUES('".$category."','".$name."','".$placement."','".$code."','".$status."')"); + + $msg = e($LANG['ad_add_msg'],m); + } + return $msg; + } + + //Function Used To Change Ad Status + + function ChangeAdStatus($status,$id){ + global $LANG; + if($status >1 || $status <0 ){ + $status = 0; + } + $status; + mysql_query("UPDATE ads_data SET ad_status = '".$status."' WHERE ad_id ='".$id."' "); + if($status == '0'){ + $show_status = $LANG['ad_deactive']; + }else{ + $show_status = $LANG['ad_active']; + } + $msg = e($LANG['ad_msg'].$show_status,m); + return $msg; + } + + //Function Used To Edit Advertisment + + function EditAd($id){ + global $LANG; + $placement = mysql_clean($_POST['type']); + $name = mysql_clean($_POST['name']); + //Replacing Single Quotes With Double Codes + $code = addslashes($_POST['code']); + $category = mysql_clean(@$_POST['category']); + if(empty($name)){ + $msg = e($LANG['ad_name_error']); + } + if(empty($code)){ + // $msg = e($LANG['ad_code_error']); + } + if(empty($msg)){ + mysql_query("UPDATE ads_data SET + ad_placement = '".$placement."', + ad_name = '".$name."', + ad_category = '".$category."', + ad_code = '".$code."', + ad_status = '".$_POST['status']."' + Where ad_id = '".$id."'"); + $msg = e($LANG['ad_update_msg'],m); + } + return $msg; + } + + //Function Used To delete AD + + function DeleteAd($id){ + global $LANG; + $query = mysql_query("SELECT * FROM ads_data WHERE ad_id ='".$id."'"); + if(mysql_num_rows($query)!=1){ + $msg = e($LANG['ad_exists_error1']); + }else{ + mysql_query("DELETE FROM ads_data WHERE ad_id='".$id."'"); + $msg = e($LANG['ad_del_msg'],m); + } + return $msg; + } + + //Function Used To Remove Add Placement + function RemovePlacement($placement){ + global $LANG; + if(!mysql_query("Delete from ads_data WHERE ad_placement='".$placement."'"))die(mysql_error()); + if(!mysql_query("Delete from ads_placements WHERE placement='".$placement."'"))die(mysql_error()); + $msg = e($LANG['ad_placment_delete_msg'],m); + return $msg; + } + + + //Function Used To Add Placement + //FUNCTION ADDPLACEMENT + //ARRAY : 0=> Placement Name + // 1=> Placement Code + function AddPlacement($array){ + global $LANG; + if(empty($array[0])){ + $msg = e($LANG['ad_placement_err2']); + }elseif(empty($array[1])){ + $msg = e($LANG['ad_placement_err3']); + } + if(empty($msg)){ + $query = mysql_query("SELECT * FROM ads_placements WHERE placement = '".$array[1]."'"); + if(mysql_num_rows($query) > 0){ + $msg = e($LANG['ad_placement_err1']); + }else{ + if(!mysql_query("INSERT INTO ads_placements (placement_name,placement)VALUES('".$array[0]."','".$array[1]."')"))die(mysql_error()); + $msg = e($LANG['ad_placement_msg'],m); + } + } + return $msg; + } + + /** + * FUNCTION USED TO GET ADVERTISMENT FROM DATABSE WITH LOWEST IMPRESSION + * @param : placement_code + * @param : num_of_ads + * return advertisment + */ + function getAd($placement_code,$limit=1) + { + global $db,$ads_array; + if($limit==1) + { + //Creating Query, Not to select duplicate Ads + foreach($ads_array as $ad_id) + { + if(is_numeric($ad_id)) + $query_param .= " AND ad_id <> '".$ad_id."' "; + } + $limit_query = ' LIMIT 1'; + $order = ' ORDER BY ad_impressions ASC '; + //Return Ad + $query = "SELECT ad_id,ad_code FROM ads_data + WHERE ad_placement = '".$placement_code."' + AND ad_status='1' + "; + $code_array = $db->GetRow($query.$query_param.$order.$limit_query); + + //Checking If there is no code, then try to get duplicate ad + if(empty($code_array['ad_id'])) + $code_array = $db->GetRow($query.$order.$limit_query); + + $ads_array[] = $code_array['ad_id']; + + //Incrementing Ad Impression + $this->incrementImpression($code_array['ad_id']); + return $code_array['ad_code']; + + }else{ + /*In that case, get all '$limit' + ads from database and do the same + as we did with the single ad*/ + } + } + + + /** + * FUNCTION USED TO INCREASE AD IMPRESSIONGS + * @param ad_id + */ + function incrementImpression($ad_id) + { + global $db; + $query = "SELECT ad_impressions FROM ads_data WHERE ad_id='".$ad_id."'"; + $query_results = $db->GetRow($query); + $ad_imp = $query_results['ad_impressions'] + 1; + $query = "UPDATE ads_data SET ad_impressions = '".$ad_imp."' WHERE ad_id='".$ad_id."'"; + $db->Execute($query); + } + +} +?> \ No newline at end of file diff --git a/upload/includes/classes/calcdate.class.php b/upload/includes/classes/calcdate.class.php new file mode 100644 index 00000000..1ece5d2a --- /dev/null +++ b/upload/includes/classes/calcdate.class.php @@ -0,0 +1,28 @@ + \ No newline at end of file diff --git a/upload/includes/classes/captcha/class.files.php b/upload/includes/classes/captcha/class.files.php new file mode 100644 index 00000000..5345dd1c --- /dev/null +++ b/upload/includes/classes/captcha/class.files.php @@ -0,0 +1,116 @@ +_error("Invalid Directory: " . $diretorio, E_USER_ERROR); + } + + // File types regex + Switch($type) + { + Case "img_creation": + $types_regex = "jpeg|jpg|png"; + break; + + Case "img": + $types_regex = "gif|jpeg|jpg|png|bmp"; + break; + + Case "pag": + $types_regex = "txt|htm|html|php|asp|aspx"; + break; + + Case "vid": + $types_regex = "avi|swf|mpg|mpeg|wmv|asx|mov"; + break; + + Case "doc": + $types_regex = "txt|doc|rtf|xsl"; + break; + + Default: + $types_regex = false; + } + + // Open dir handle + if(!$dir_handle = @opendir($directory)) + { + $this->_error("I couldn't open the dir: " . $directory, E_USER_ERROR); + } + + // Initilization of the list array + $file_list = array(); + + // Starts dir navigation + while (false !== ($file = @readdir($dir_handle))) + { + if ($file == "." || $file == "..") + { + continue; + } + + // The list will be generate with specific types, according to the regex + if($types_regex) + { + if(eregi( "\.(" . $types_regex . ")$", $file)) + { + $file_list[] = $file; + } + } + + // The list will be generate with all dir's files + else + { + // Add only files to the list + if(is_file($directory . $file)) + { + $file_list[] = $file; + } + } + } + + // Close dir handle + @closedir($dir_handle); + + // Has no files in the dir + if(!sizeof($file_list)) + { + $this->_error("The directory: " . $directory . " is empty!", E_USER_NOTICE); + } + + // If debugging... + if($print_list) + { + echo "
    ";
    +            print_r($file_list);
    +            echo "
    "; + } + + // Returns file list + return $file_list; + } + + function _error($mensagem, $tipo) + { + if($tipo == E_USER_ERROR) + { + $topo = "Error!"; + } + else + { + $topo = "Notification"; + } + + echo "" . $topo . ": " . $mensagem . "

    "; + + if($tipo == E_USER_ERROR) + { + exit; + } + } +} +?> \ No newline at end of file diff --git a/upload/includes/classes/captcha/class.img_validator.php b/upload/includes/classes/captcha/class.img_validator.php new file mode 100644 index 00000000..0efe6b08 --- /dev/null +++ b/upload/includes/classes/captcha/class.img_validator.php @@ -0,0 +1,326 @@ + background image color + * 1 => background image border + * 2 => text color + * @var array $themes + */ + var $themes = array ( + 1 => array(array(205, 255, 204), array(205, 255, 204), array(0, 0, 0)), + 2 => array(array(255, 255, 203), array(255, 255, 203), array(0, 0, 0)), + 3 => array(array(102, 203, 255), array(102, 203, 255), array(0, 0, 0)), + 4 => array(array(0, 0, 0), array(82, 82, 82), array(255, 255, 255)), + 5 => array(array(153, 1, 0), array(0, 0, 0), array(255, 255, 255)), + ); + /** + * Colors themes for the done BG images + * + * 0 => background image name + * 1 => Red, 2 => Green, 3 => Blue + * @var array $themes + */ + var $themes_bg_images = array ( + 1 => array("bg1.jpg", 0, 0, 0), + 2 => array("bg2.jpg", 0, 0, 0), + 3 => array("bg3.jpg", 0, 0, 0), + 4 => array("bg4.jpg", 0, 0, 0), + + ); + /** + * Fonts data + * 0 => font file, + * 1 => initial X position for a letter in size 14 texts + * 2 => initial X position for a letter in size 40 texts + * 3 => value to reduce of X each new letter in size 14 texts + * 4 => value to reduce of X each new letter in size 40 texts + * + * -> P.S.: The indexes 1, 2, 3 and 4 are used only when the text will be centralized + */ + var $fonts = array ( + /* With this font, all letters are uppercase and the characters limit decrease + array("acmesab.ttf", 84, 62, 7.0, 18.0),*/ + array("arial.ttf" , 85, 70, 5.1, 11.6), + array("verdana.ttf", 82, 67, 5.6, 12.9), + array("comicbd.ttf", 83, 68, 5.1, 11.5), + array("impact.ttf" , 80, 55, 5.7, 12.9) + ); + /** + * Image Width + * @var integer $_width + */ + var $_width = 180; + /** + * Image Height + * @var integer $_height + */ + var $_height = 50; + + /** + * Checks if the system has GD support + * + */ + function img_validator($folder = false, $img_folder = false) + { + // If doesn't given, uses the default fonts folder + if(!$folder) + { + $folder = "./img/fonts/"; + } + + // If doesn't given, uses the default background images folder + if(!$img_folder) + { + $img_folder = "./img/"; + } + + // Sets the background images and fonts dir + $this->folder = $folder; + $this->img_folder = $img_folder; + + // Checks if the system has GD loaded on PHP + if(!function_exists("ImageCreateTrueColor")) // gd 2.* + { + if(!function_exists("ImageCreate")) // gd 1.* + { + $this->_error("You can't run this script because your PHP doesn't have GD library (1.* or 2.*) loaded.", E_USER_ERROR); + } + } + } + + /** + * Encrypts a word to record the data + * + * @param string $word + */ + function encrypts_word($word) + { + return substr(md5($word), 1, 10); + } + + /** + * Record a word in SESSION + * + * @param string $word + */ + function records_word($word) + { + session_register('word_validator'); + $_SESSION["word_validator"] = base64_encode($this->encrypts_word($word)); + if(empty($_SESSION['word_validator'])){ + setcookie('word_validator', base64_encode($this->encrypts_word($word))); + } + } + + /** + * Checks the recorded word with the given on + * + * @param string $wordc + */ + function checks_word($word) + { + if(isset($_SESSION["word_validator"])){ + $recorded = base64_decode($_SESSION["word_validator"]); + }else{ + $recorded = base64_decode($_COOKIE["word_validator"]); + } + $given = $this->encrypts_word($word); + if(ereg($given, $recorded)) + { + $msg = true; + } + else + { + $msg = false; + } + return $msg; + } + + /** + * Generates a random text, whether a word isn't give or + * the given word is more than the letters limit + * + */ + function generates_text() + { + $temp = md5(uniqid(microtime())); + $temp = hexdec($temp); + $word = substr($temp, 2, 3) . "-" . substr($temp, 6, 3); + + return $word; + } + + /** + * Generates the validation imagem with a given word. + * If the word isn't provide generate a random word. + * + * @param string $word + * @param boolean $use_done_images + * @param string $align + */ + function generates_image($word = false, $use_done_images = false, $align = "center") + { + /** + * Didn't give a word, generates a random text + */ + if(!$word) + { + $word = $this->generates_text(); + } + else + { + $word_size = strlen($word); + + if($word_size > $this->letters_limit) + { + $word = $this->generates_text(); + } + } + + $this->records_word($word); + $word_size = strlen($word); + + srand((double) microtime() * 1000000); + + /** + * Chooses a random font + */ + $fnt = rand(0, count($this->fonts)-1); + $font = $this->folder . $this->fonts[$fnt][0]; + + /** + * Sets the X values according to the chosen alignment + */ + if($align == "center") + { + /** + * X position value for only 1 letter of the size 14 text + */ + $x_small = $this->fonts[$fnt][1]; + $d_small = $this->fonts[$fnt][3]; + /** + * X position value for only 1 letter of the size 40 text + */ + $x_big = $this->fonts[$fnt][2]; + $d_big = $this->fonts[$fnt][4]; + + /** + * For each letter of the given word, decreases $d_small of the size 14 text's X position + * and decreases $d_big of the size 40 text's X position. + * Remember: if you change the size of the background image, the font and the text's size + * you must manually recalculate those numbers ($d_small and $d_big), + * so the text will be always right centered + */ + for($i = 1; $i < $word_size; $x_small -= $d_small, $i++); + for($i = 1; $i < $word_size; $x_big -= $d_big, $i++); + } + /** + * Left + */ + else + { + $x_small = 2; + $x_big = 2; + } + + srand((double) microtime() * 1000000); + + /** + * The background is already done, so, create the image handle from done BG + */ + if($use_done_images) + { + // Chooses randomly a theme + $theme = rand(1, count($this->themes_bg_images)); + // Start image handle from file + $background_image = ImageCreateFromJPEG($this->img_folder . $this->themes_bg_images[$theme][0]); + // Text's colors + $R = $this->themes_bg_images[$theme][1]; + $G = $this->themes_bg_images[$theme][2]; + $B = $this->themes_bg_images[$theme][3]; + } + /** + * GD Creates the background rectangle + */ + else + { + // Chooses randomly a theme + $theme = rand(1, count($this->themes)); + // Start image handle + $background_image = imagecreatetruecolor($this->_width, $this->_height); + // Alocates the rectangle's colors + $fill = ImageColorAllocate($background_image, $this->themes[$theme][0][0], $this->themes[$theme][0][1], $this->themes[$theme][0][2]); + $border = ImageColorAllocate($background_image, $this->themes[$theme][1][0], $this->themes[$theme][1][1], $this->themes[$theme][1][2]); + // Creates the rectangle + ImageFilledRectangle($background_image, 2, 2, 177, 47, $fill); + ImageRectangle($background_image, 0, 0, 179, 49, $border); + // Text's colors + $R = $this->themes[$theme][2][0]; + $G = $this->themes[$theme][2][1]; + $B = $this->themes[$theme][2][2]; + } + + /** + * Allocate the texts' colors + */ + $transp_color = imagecolorallocatealpha($background_image, $R, $G, $B, 100); + $color = imagecolorallocate($background_image, $R, $G, $B); + + /** + * Writes the word with transparency in the background + */ + imagettftext($background_image, 40, 0, $x_big, 45, $transp_color, $font, $word); + /** + * Writes the main word + */ + imagettftext($background_image, 14, 0, $x_small, 30, $color, $font, $word); + + /** + * Prints header and the image + */ + if($this->image_type == "jpeg") + { + header("Content-type: image/jpeg"); + imagejpeg($background_image, false, 100); + } + else + { + header("Content-type: image/png"); + imagepng($background_image); + } + + imagedestroy($background_image); + } +} +?> \ No newline at end of file diff --git a/upload/includes/classes/captcha/img.php b/upload/includes/classes/captcha/img.php new file mode 100644 index 00000000..e6592146 --- /dev/null +++ b/upload/includes/classes/captcha/img.php @@ -0,0 +1,12 @@ +generates_image($word,true); +?> \ No newline at end of file diff --git a/upload/includes/classes/captcha/img/bg1.jpg b/upload/includes/classes/captcha/img/bg1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..11a9448d1e9db0ee460f0767f302e5bf306166a0 GIT binary patch literal 3801 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 literal 0 HcmV?d00001 diff --git a/upload/includes/classes/captcha/img/bg2.jpg b/upload/includes/classes/captcha/img/bg2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..560d09c02d2c97264cad4620ea57bb2407e6f687 GIT binary patch literal 2558 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 literal 0 HcmV?d00001 diff --git a/upload/includes/classes/captcha/img/fonts/arial.ttf b/upload/includes/classes/captcha/img/fonts/arial.ttf new file mode 100644 index 0000000000000000000000000000000000000000..ff0815cd8c64b0a245ec780eb8d21867509155b5 GIT binary patch literal 367112 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≺9Wiv@#qpl#qL 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≪P+Tw+*$qa@!i>|Uj$m6(YG+< z@59k=oQ05SlCJ>f-BY|(^Z#86{O*I_m-6+4ul^i6=jXppMXvRofu*|bv~Xuul=$;} zIeyzZTV{dZHYive45P@F8Z0ddmioehV6m;FFel#D+ZXozn@XKIGTX3VVHs~0vh^!Q zJ4aHIy%T<%@wVi`Lfge{neAN9`N{Wu+C!UdH7XoZv6@p?l#{zb{;bOT0l&8M+wa#6rP5uxYT6S5{aE z(BKv1i-I5$D9$Ylg^jL;!WD)7>XP7t6XI0-rA2{a2m=*^Oc3ia+;_Y@@+d+Yx z(jXtBc1Ep1nZ{wQEwdD3U*szt$9v3&Sz`O^^gv(op@e?u8|RIWN7gXg5MS7Kvn_Lw zEh8^4-eAmM81k1Fpj!OkjLd%N{Zf-N`(+HaWu)5%_DfA0JS@$Y+-GQ7+Mu+-nKff; z#%2~^D5Rvh9&yCz9C{r#M#16-GcTB5>MJRzFz9gQ=W@!fuvG-hc*`8Fq2R8pIM>iV z=mZqX&}-;K0NRY|zWh=@hP*f&ZySkb1wN=wFq=<3v<&}=87{4Iu7Z9{9bn82l=^eR z(2YFEJ|ZVR?7@7@7gRAOnbi)%360M#3j;OS3}O~S$g)FiLXs&czaM#!s7fFYL*a#l{!GY_N54FSL8Eir;*Br!!w5p7VJma|rNyELrGjsxa;P9! zR+tN2oe=Ps8@lwjfj8=5B>k`&Vj^>$v-$|O3}c)VwuZ{+m``vmEa%_!i4UP1Tbr;I z0uku=!d-ZUtYOKvPPVpQS7JL`qQl$Cjt>dN#AFRXq21wdx$v8qkZ8l#Vv^iRHDe3H z;gT+$JC~Q2#}|oZD?TS!WRWpequ!;yaxM!@K`;eOLxb6vp@U%~gD~(N`6Mk3h%3b|J!};cJQiWO*j>1@+pTu9}`Y<>S=5084T5`!^@&egGUd7+bpf0i@ z)<>*CL*+VT5pRTibd8lJi1lcO+y~9!|J|gtP+B6wpf&be+Q1)fhpZVLu=mvoK2>MK z({;krb-};&z~A-4TkL||pWT%1N)Ke3?FFV&u-nobJ1FVcPw9(2mj3XW2P%Wm)eLx` zw_uND7)IKGdOXWUx`Fht`Z$|6HRCAe!U zHSU?pAhvSsPF7&2ZnAQha<_61^4m^PDwQhbK4q#hO_{FDP-ZH#l-bC7J4bmynXAlG z9#rNl4=E2Tk0=Y2g(_7ZQx++URi-?SJV;Ab9r5eSl@-cLWtH-jvRYZAti>~u^~%$T ziFsCePI+E=LD{HmQZ_4F@NWG}%2wrN zJIcGtd&(Z=ePyrmf%2iUPx(mMuY95$P(D>YQ$AO|P`*?SDqksIE8i%Gly8;ql<$?p z$`R$La!fg{oPc8fpqx^ERDM!^R!%EtlwXvy$~om%k4`QLk4UsW+&N)h23FwV8UO+FZ3E$7l<+ zrP>NvT5nd{sBP7DYJ0rx-x2Tb$K!2%yXwHZ`3b5^btAWEqUu$X)GlgQwVT>q?Saof z^g`HiikhnSR*_Ft?W6Wp`>Fla0qQ_?kUCh+P=~0us6*9ZYNncnv;o8M6^oJTD0Q@Y z8@{=8hkBR5H0TBsJO#cB`IP?xGts>{^n>I!wGx=MXYU9GNB*Q)E(_3G2=2K5>BS@k(g z#TV3#>LzuwxIdqFNUiyi`mwrS{X{*WeyV<^ey)C@eyJW*zf!+ezfljV->ToK->Zk!BkEE0 zn0j12p`KKKP*15psz0eetEbg7h+jCXo>PBSe?z3f1@$5#0sc@gsh8C&>Q(g`-o{ro zO(Pn`8}mBeh>ynmD-oCD>)xvwub+o!#J*~dhKx?Qxsa?n4VaB`2jqwI?Q>~eH zBi`$^X*X#tw3b>c+G`!Oj#?)zUhAycHHYTZ5_qaL#GWT=UM&f4 zv3A89pLlx{Z$|dQ8;dDgD&AF0!yATu@J3)iype~u>+ts0V7xswM7u>Big%_mwJiQ- z6W%5oi8qHv;~gBlZG(4V#^7z1Y%K@xpZM{{NxoK~1@L~zIK0V$cP;QHM2R+DE7d|; zSS!Q34dvQItwNimP1f$x?$++n?$xGfm0Fc{pEgySrcKvoXfw50+HCE9yg~4QHdmX6 ztSq)NL#Ee(H_^H(3WaXYRk0c+6pAwT%|pwt=86PYqfRS zdhKa#gZ7N}toEGty!L{&5ve#gYg@DzwU@N5+RNH2+BR*wwnN*gy{hffUejLJ-q7CE z-qPOIc5Clw?`rR9d$jkpz1j!bhuS{vBkf~tzxIiCK>JktO#58>LiB{BDa#^ zWCR&WMv>9vHgY?;1DWl{5Fg1VIm!-_OZ+5{wOF*4tkknyCHgh&`) ze4Rkb$wX2?CXvbHE^;@y2YH02kV;ZT?juvlG%}scAT!A}w8Y$Th=X0nC6NM1tvBJK)oBirE=?1XEui@Zi&CvT89$y?-YvYWg^-X-smJ>-3| zmwZ4zB>Tumo^rOn`uG)Kahn`jH#lD49) z>CLnaZA;tH_Ot`-NITJZ+L_wnvN&l1b>Um!9-2tKG>LYhU1>KsF+GrCwiivNDKwS# zrfD=Cu1#OskM@UqGms9VgJ}j*%iKbT(qS}{X3<;ea5{pHq@(C)dK0x?=9;L_Vae9KDq(9J8^hf#={h6MoXXr2VEImhm zrN7bh^a8y|f2V)YOY}0mLa)+mOhJkrjS)uisSF)?eWFscdq18dBhu%@gTyAf$=Z0si1g0*C=SZj7OYs1>IcC0X=~kd?6UtdxaVn3b^!tej0`6>Jil% z_p>?d0XCP-V-K?V>>>6rdxR}u3)!RWF}8>;W=q)P>)F$61AB%&%bsJ;vlrM#wux2CAO8l%wA#J*mkyq?PRaAUF=Sl?eab##pR+I6m+T<>iha$#VTaha z>^t^7JIs!-qwE+v&Q7qC><4y={m6b|KeN;94Eu$hW#`zh>^F9vU0@g4@9YnDiCtz_ z*j08-S9Dd^bfQxvu+@V3VU#~aPZ_pd- zP4uREGyO)rxo*>M(p%^)^;UXo{bs$5-d1m?x7R!99raFnyxv*2>ki$iC+IHSt$XxD z-K!_*UG%PcH@&;w1IcrH>B)MEo~rlO)AV$`kKR}Br}x(f=mYgZ`d~dnAEMu)57me1 znR=Fft3F&Gp^wx@>7(`A^xO42ka~BF?$fjN96eX}>v?*_v>@? z2lTltz8Kqvb&7+OlzwR>*QOQB<75c|T`OKr-#LD<@OqRqSQzjvOl!J`(nok&=QyO>^6T z3meE|{1bBueMKB94wYe}E)Xo$OR&Eg_Qm*0OM~Tw{=9IM0hN`+8b@Pi$-J10y&)6I z4u%U%sH`NnxQ1wuTbv#8$70vCfRBllceq53tm&9yzi#K;$9klQmB~fK1*@eNJaZwmUeq`oZVV-#`4U6+| zr~sSJ%=nGU9cLV4@}TL^uHeL26XJWVQT%~Hep!imEEVUu#pZcoo}LpZ%_;Q91d1nQ z^JflW4vDf5w(*U}K2V?u)(Huf73+D}@GkUI{==}rp6jPMg=N{S01pYmQFzFJt+w2_ zqOy=sDu1nNFtlFl*Ix^ajVtz*;K2rVstdRUD&~_JT8gGIzPv!d<8ZpX67nYLeKF#R z33^|L*X=S7ZijJ}kPwT_?qZYwsASW)MfuEQTq^HPSy5i0e_~ut1g5EcGUwnYDowON zpSW4n(@ZPqHx4w7*Yo2iu1}OFxsBfN7EY31b^Dk8%AY7~{r9;OGI8k8uL1F^+HA7Z>8W zM<6G9puAitfx!}hRWJ-DNh{7L{^IC0mKc9un`xEz%-M0 zILteoWp)^k|9FS91b#fOGlZXI;x98hoFzJ3COSMkf-$bV8a%QZToHj8>~MZ477uEQ z^9>UYTPne*t&BG?;WZsxiZdTllg*W zfHl(0^~yMjPQ!BuUOlE?P(U>@iui-CVzY8qwaT#>MgDxVdffo3|A_)KD9{uvX{@)g zE($ty6kjw!hjJ2Z03I#+;3pJi=lZlkW!m5}ZA1WCXVBD!1jx{WARA^ZrJ266C_$g3 z76izUP@o3KA?el@7v*`Zu_~K>>KTad?s5-rFyxxnmBl4Tyd1z9va zl7_=&;d5A692ORbg~e%M!H0Ocf#=*yEOw{GpVPwUwD@ycn4K18r-eDe!kl1XPOva1 zSTabkXe3xP5-b`C7L5dpMuJ7dWzoPy72LZl8ZL{5%c2pHi_4cC@>nerEv^zRUJ@-{5-na5EzF4)=0po~qJ=rp!tAv$d#(O@EgD{nhS#Fu zwP<)P8eWTr*P`LIXe3!Qk}MiY7L6o}Mv_G%$)b^D(MYmrBu21E8j!CTEr(rRb=V~h zhh5Te*d+~zUD9yaB@KsN(s0;iKOA<8hQp!};n^+A>`7(|D7$FuaU{5%@ZJ0qe6cXX zzPyk>KUipjB{(mLGfKz9g9(RNL7+4+o`vzo3tTN;kr{P#c^MBVi}dkjct#%5bA9># zPys9Q!-Z!>zVW_1TI$R5qeaL+K8im{hL-}v#1GMUT#NFu@f5329)Yc6`2oDi!E$jP z)(ZS&f^PzwWLgFenU;Y=re)xeX&E?VVRoDI92^K6#vzF%LD(=}Cb1+48^+5dmIPrfc$vki zuwkGkY#6QztBf*_Y1cdn4zX5nu4G%>Dhau`#p;Kvf)|g|E3R_L>?Max{yZ++g&S=- zBxxjB(nt`i0l#WW4Q(y1+`^uMQ?XhB5~~%5One-Y5>F887B7<$PY~-C%ESr*?ya`C ztv37SbXu}^3!Ck6CW$f*iO~WiYp<~;PXI0=J;|*j36MvUjn|2 zV2)ryqR=|@O-Ry%JrT2)pdmaSl!>(rW!9)B39p4;mH52E??jpK+yDtr3s6Lxq?SOY zqAegx*M!f&C2sbTw~ataQDwyer`?$>jw#~UTO8BGG1WYJ(xQ#}p7gGwKs5BEhzqIm zf`K93ZZ|66Xkf1PfrzcOcHwS!9J9jCx9f!Nm8OvS21@0$=Q)4yjZlA z^9hodW0hph#p;lSSxN=kXU#>qJ%TbhE=j`g0F6jJVbyq9q@IOY&J$dyy8!aOEBK%o0uq<(+ zWr-6lOY9Q&d!Q@UR}NV^6j>j{-5|eejkH*Yd6_kC;$D%LSsaKJnU|T|qaWf<5;jV# zzWk~jOKkee@s-vO^<*!-;!cCNHKoh(MXpK-d8I8uJxgCK8xgU|5sU4u=EunKwXCz# zYt19Cm_49t*%zy+YeLJ}F(VrD0x6cfCS8c|EBcUQ2VV z)x#-Q4_?obhPcN^nKe_qLYsI!Ia*$!5xmSA4>9^Ela|nFtxJI9Jn}|HH8LJzR{*0W zb_FyK`OCH(Mq5c0`XK1L5@kC`D#7Zps~YU+lpt$kJrnKRk{*1)YIVKU;KT?FNkwoc zRfFBtU}uC5Rs}%^D}aPdioCZH8;2!z4toSP4$IzfSW@9IsK_2eQWEBpioj?qslwI^ z`ib&7*C|&uNkw2sCu@XZ-DNwktP4p+>Uyiei4ho*iquJ}2D_`l&IldYbwLOAT0$m8 z-dl-{!;(6OJpvntWp6kvsc;xns!2-1Tv8DjZ6#G$a6uoI*@XDckA&nn@|_=9CZ)`G zeq@=P8GPqQmdT#+ogZ0d(SZFFWw5vsvS`3dk!2PQ*jZU-(SUW8Wfl$CUQq^{Dj|yo zEUqlGXke|DWfl#mWm8;sYnI~9H==KVT`Z#@Sc=zAjNdHdw~YTve3tFN#+6m(;Vw2j zWqC{#=SlVO>;Z4j<2g$~FgVVajkgTUOAfm@CWs?8$2kgzaJn7t23Aw!;gI=2LsG>0 zAo}O>nhl+)(YgEq4|aW`@x%my7Nxl{;c`3_2M{vrL`DtwN20ykEv}^t2AtyP5=YS| zhv<_-&~q5~BVbtEH8{jwgTuT_usZ}kr|76tbkOOHbj)}bWOgi4XgoqP3k3(g>sq3~ zUR}1oFj#J0aSGu%1uy2kQM%nJcyWq8I7J_wqAyO-7pIh+xWjP@-kpN?1i?F2%4A77 z#wVfJWNS=geHK_JIr7NO=t>>mUkj?$FeFgDhEdRBWT2a)U2XZosw8a*LDNW*h5V;4^p-?F_h<*-nzJWj2$i zG5iU$F~TwYF|z^1rddd1{T8UF8R&Gsaj28_S0N)@Nj~Z}hoM>xQ|i@fm{PA+!y?n5 zS}m)vIyIAgwOU3&{c5;mKk8SjB+Fv^Sx93878uh{UXKY_P=*BsB@_!=C9Fy;43+@v zWc;=3!M_$%t6|EbS`AYc)oNIX8&s=h6;`Ka%A#5=Qx?^5NzUt6t0c>KZ%WPgo_KF0 zXp|aEnWY9;%P6&&sAbf*PEAY(akGs9)->8kYBh}}@(eFLNxdtRP%Ny!lrEM42^wpH zp;EEN!eD|%smY~LYI13mT1{&iSFBTxzZ8*kc=B&zGPyKLB@Z=?Ch{z1qy<$-D0XB7 zVTA?iBMoGFg>m545-W>g<#05t9FB&SvpaelRt`tQLgQ$x05}@f6-UF0;%Hb=91Saq zqhUpHG^{9&h84!qSP^hEtT2wLVy$uFUe#Q6u+?KhawWpXjlriY$)xW}GU>aLOnR;) zlb$Qd#P3Qn@w<|YB@>Sh&HlNPMf+sYKH2QAE7|O?E5+=uE5+=uD@D{#5%p8d{DbaF-{` zq$iYsyF5{bdpikPG;kj$%Pbm}zmkw(%GcvI`{{9; z=bhjZEwL9P=(q&VM0b=?;xfkwpP{vCm{Rgset3d~*UOAH#;AJ|je6-R9&>F@@tA9K zibu9L{frd1xi+VG%(XeiBe^u!{1mfy=_zLKaFiTMElj}9l;9paP7;z-ddm{*GKp)E z{wK=*OCF4K@ND`SDIP(~D|mBDo=m4M#cgV+2m40?H+G05Wa)xeVzEZkx})IFb7XzN zu~+bb4^eUlG9^*S&6KCz;}yJ_yyLn&msBjxv+fr7Zlp;C&sfaS@k;D@CKcI3ue>g( zdL>s_p9VESb#W*^ZP(?3fwxxsn5#9(@tb`SQz1m~u2 zh!TTZdWu)b-m*d1r!zUTY!P=SAyUbyJrG#g5VXqW3og@61!xwM9hMSL=z-t zOA6K=i3`sbL_0aZk}Sz!UrAoG=*c;jBsH4v_=sBA=aG=)Txv9biYKpG{gbmJDb2cO z^#Z%ZvcBZrlDC|7$re5A6^q)~4VI9QOtRo5+3Kk^^IUi$CTdIjlWbwKW}eHkI4)Cv z?Ve;g=foWI2;K3BaZa`*haFr&!J2n2uW9o=$>tqFibu?7lLyQa$+0C3uW98y$(B@- zguP6*#x$Z^5uHjh_yoV!m_{@wqA^JlyBt%zE-ScpW2e>R-))y%i+N$L%;_oS%8aAX z=wvyX{7IZ_E9H#Wh)pd|u_$0)RMfKW(%lZhx4BBDroE<6F*yA~lz=CHs5|Vt&`Rq1VK;V(H(v4>`qP8^~-R9b4_oRw7DOt?PRH5Oi zqNl0CuBBT2lye}}Xpx?hCR>O(Bm6v1su)w@2YONsPN9v4rhu|B#%M1o$ob-yc0E-{ zqPLJts?|qn=~FF@#&Z$TN6Xf`O&bqNmL!Dl=rMg;(3X7=yr&5Z-P@X5QWH(@H$6po ziyqSpPEQfuqDOec9y!;97wnO}7hbSON=JCX9x099!ansjy;6_tbDGc+DdjXVE>ddv zBE6yAW>4&%G@*O4C&CN$q=^}oW_qojG()ziFX*OA>Eo%kkfg`*CGp;bNhMucD~~n5 zJeDWvk)9-;1e;@lC+-#`X8@j;3S5%1SiPmqO%{5RZ1G{Ob{=bA++*!@d91nRvDQ0} zwcdG5uQENwA#9^VYK-u6aYbr}$C_UrYkqmG)egBbWM8b^Z;!S6?Xl*V$C_gvYsK^6 zS*MT)o^?vdl8v?Md8}0rUbn1gd7KfC+mo2UGd&PwbkLB)LB-cCk^fmy25GOh(30rQ ziqh*#_6p8L9wM9ghc8%PQ+i&znmlyiP`e$qI2N=+MhNqtrrdyt<1YR z;d_?RBpSc5qy~QLk$MV2yl@l1%}ERVwjmz;_8|jMju>3P_mX=R4RN?r09TSZfFB^g z0{#u(?A3ULs$xW^;uo>0_^nBSlgFdtcOV^%Ox*btS;|>^y--mR>ov>Zk@Fdgyb>!E z6={~T(f3$I9h5xOhMX1nfH`tpsE`IRa$WFq9i?Uo1soj+1q&6Y@$1FTYgp-l*YW~N zZ~n%c(%<+UQW(hhDYus5fcz7tWcV+q%rWs_WaGdux`1DXU(Lv@!OuVg*)-ZJ>FQb% z%QB;uM(;u?|IbGW64Xoi89P+1w1z?u+t!Rcj51=z-c`H$tdfan>~^FxzUh1p5zO-u zt-J&g$}16-ya|!V+YoL11|p32AgXvjB8d+odiXFRhEL)DIU{OwAfhcZ5n*{7qAGI{ zNr@LD5jQyzv63qg+qfR_j2jWhxE1l8I}o+_79th*lKnUyKuqG-h(kPz*u$R?Z}=Nx z46h)rkRg_^CL5?XBsU>qa2(?Qx*=vSTh9a6nb3zeh!S@oGJF=|tQR1z`U%8RKZSVd zEr^lcfw<_m5DUE*@y`bk^ZYg9oR1>5`4ssDF{T|^e?*54MMUT*M1f`_@^dVrJxdYc zISCP&s}O~`0g;!R5pl_5Enh`^3BUN9GfFvu?u1h$LP6#k#Gydx7&#e@ziq=7ycOHz?UKRdoAL-w<4x{7vi|z zLG1QE#A|j^)X}tw;tRoS->O;J005PiL5tmwlSk#q>9eo<{ zqMHyW`Z8+nL{#Y8hy?wBe1hYri23{mah}Hz+xau%InN`8^D5#tb;N4cf`qRlEfA4e zi1^Cxh>6V6^Z#c`SZ$%qB{pOc=t$!6ZE_DH^QR&ze#9f+PEJgjWZBkJRA|lcOr^7ACbdBL<^TALik=p2H%IM;2DSrz8}%R^VodE0WUxd z@FK+jK7rWZ<%s!Rhd5t+@feZ4uOOy(7vgx|LG126#O!{8SlzGm5F&F=AR6}!B5*IV z%ZRt7h_S7KxY~M%scnQu?S|7a%Gw&r3pE6TVP zB8=N2y0{}Ei|vRib|IR$3!;d7A%gfXbM^mwnuJL2|6h~-D>nVVrb!gpulQQ5sv10p z#>m3DQQ3~nO#6^`=?HQvT}0`1$a{4&@>@BP%L?CkM7F9S@MQ?B{txC+Z%%%L4^u@h z;CCwd9lta2J#mf9)hFW9xIOhr_)XUD!f&cR6TjUJub>g|wnFYKJMv_8Bj*ha7Yz)5 z7#O%;G*_=MFibWu+-+c(Wnh56q2I%6fPboU-^zrhSWu+}Raww|7Btm@rU@vP=NaMo z0*qV%JWl{}1i-6_G9`p8UR+Z6@(OZ;HCA}G^^WlSH0>AC2ft@YU;LgU{qXxM>5t#v z;QeVD|I&@BT`+tjctnPmRs&f0Kc<}_P0VZ_#<}Skalc7voR5+QMyb;HPJ313(Rxh# z>3yePsHsM2%c>d=L{VRSJlIjoUPF&IuV{=Z_Az>F2VJFVRidWSWkc;l>>aC>G+lAy zl%~i<#{Xv^j~LHV%#*P3tkOOBf4l9^_-LI~X?wRnc4TJyAJ3e=nECyfmdmOdY`0fw z{I9iEr~eHfd*@V*Z2Hvgp*tJi{?$r*O^Z(z-^a06E_F1wH`7TLjjewj@?r*t;h{TH zUm_!^ZLlBD+)KwfuD3Vj72@jGk`+1{*lz2yOeQ>uVx0AmVnM2|N$rsQ>;QsC=@z%#o>$R6YQ?&(bO@mHqLyGX-~b>=a+w z^aXw6nz)zh)*Sxju+Pg5znjp0<0t21M!U|PeDG>ajeQ53jCy(R@$)lZcw*O#)~D_s zQ71HZ;-2vhue?3te7mPd+_8{e>6Be}L}kC{pLaaPyXDs z#WS}qy62|H3#aeu-{;Y>n^$`dT#o6qe{<3jjX$R;LDd)tH|Bql)Y=Nl zW3?((Rd!AC%{aAj4asTJp|S6qDK9l_w(R}~yKigr(9{M=r>1?-?jb#|?<$h>OTXQ-cn|r=pqrD|_hrIFA!fm|{?reP` zCF|4k)6VM0?_bo^agNmfWZ>hi+JDug$-Js_&!1j1=x~EI-_HAVcfsqv5$j4nxoGd3 z@kQrgj_r$C?^R8HeZcm%Z&el?KUURiLwc8GzxVX)9k?wsWz;19 zPTAe~!kY<|mG8D+aOvJVy3Ba6!NK?A%g&x2cdYxmF*{S#^%?6&ukG2w@npS*zlWCJ zSam<`@I$&buxMWMA@K_aw4bO?4R@bEuVWvFF_l(UZnal#vG>xWVdEK#QdJ78XSd69 zyE?s<$Q2sQ36;eEX;64cXPz&%EM$+tpfszGNubz!bI?Y++xa-hjhWt8oqjP*1!{YH zds~TEQ?G0KAC0!XKF89U*09IQCM4P(#|vvyN;G{}^}!WZpwqdGoG~36efe9f+Cw+h zIJIee{&L$J z*wJ3Y-(sy#JojAPvFna@-E*?#`A6E_-Ye_eQ^THk$I~Ur9~}yo7=h>Jwm%eXu_)2o@*oCkH^{|TlVOoLONKJWvw{A1*e$?Z9&X0$B{e@wB ziKBzP9Xf<{szoZ2=$7(0d#>d?33;N;%JOVvZ;p4|Xm4s(ZusXbBJH{3CVO*!oz!m> zxz3j{TXGrluapMD6=G@PX;X|`A(+)pyTh4)#fi`IQU4b>`gfCbownn(l4D)Z4sO!+ z$ww#NVgF&px(8a{dGYFkfh%9S`os!bkGpPJv1G-(G0t%xrQ}xpykWw-nO~kg_4xFr z^PZfVx9P2Mld@ZW+N|3*wbh4CEPV6TPI-$L7u>vPUzd)r*4Q%Q=GW4X$M*0p?6|IN z(%K*U-IsEBYVB={3$uJ1s_t4orc?RAlZ!Uzc3nKAsUx~ogD2M=pWmU;vF?xMG#E32 z`JZf-ICRE^HK!lZ-fpu0)vUBlv!=Y-<;ToN20wdc&7`96;O82>zc8llP0H{G#{?3$ z4X78@?bd6fFRjXpjb8n6<*ma{zu5JT>nh9Xm*;mrJ7vMu=l96*r+w{?4O`w$BRHgf;8Rc-ZodEIljjd4D?G;U81Hh<>4ce@Fk-| z4|m+Mtj{~yr!Rl@e%G#})_F1mS6dbJeE0qJ->|#Bc0ADi$vP!tw_UB5(I~L%^1jr= zbw}AUe#oBu-1-~d>5$mE(@y{Ldb3;C&RKaOv+3_Qz58jyb3->20NW((Ri9(16Y_S7#^z9pMS|N6q$?+pLh-*5NO%ojJ4w)L(( z`01JGdG~C6^sT28J06*IWNrE33ComyV|%{#v1j(T$@SK{$2J*z(EZ&fP3e)fY4n{@ z3EtvCO>1Vq6uV;1{sWmk)Au&bT3vFmUY8jUmp!@W<7Kc4@4`2DLHGt^;}&J?QodPV z_mj_iEnd6x*nbPNV22%mSumD+zSz4R4mhypsl9TwBhE1JRIjgP4Rh4D*X5Qbx_<0% zB;JDCj64vII`&$;FsgpkP=7AZx+4u%Z2f;>u>O_xk{`cxG_r`@%`fDdoMrn zYTxqmXXkuz?1s07Z*II}^UHT?%hSdtjr{%PHjj52wDj_dBi`BG+!iT^Uhdrf!uas1E_i_6n)%4`rd@heZU6bH8FQM>8BlTOmVSTS;S6+Xp7~7KphLOG?cEOM_UnD= z(wj|F#vfbOJ?-al%99&XcDzz|)2&A?9az!6^7H0{S7hyMGp}Uziozz>GG|w9uN<&? z`3rfI)?L45kG`wVsnwfKIvNh^-k!dCE!6j```e^m&N=aOs~MwrdOkYg_|5sn9fv9= zy<*=GnBM==oVu?zc_4G7y^7U_F}q+IvshnL-Be>w!Bt&YeB0oEjM3n?I!?Qr=WKJk zU0!be5@7uB=7*i1+AEj;pSFI^zga)w`;mWPN-?4T<9nU;i*_WfZPe!14&CDh_Pnb+ ze$AdOAI+)xdYABL4{!N)*?^uS@Ax1sV{t{hU;4e@xX;g7uSfT&XSibG>Z|1yD9w7dMqt?$k29X%~;_MUfYrw_>5GiPCW{~0INCF{Gd)jU}+Jg4-H z!0^qfA3D3(ziM*wKDS_a;mCN)0=iQ*mFF;SIq9~=4)9Wq^4}%+vN7= z&pB!LdPkeBiCQynkEx+4zq|x15`>0QKcyq*_jk5~x zyt2RJo58IuH`ct??QGq&@YxuBQKPSeyQZs+>NV?d-E+5|_9ra=A%F0%1FD`rS^F#X zk3(bb&Fgdfo{lB&Pagb*zO{HxjjP!=ru_c!T`QiBUAnJjoo5G4ZZki4^Ui`lR`-0e z<*9d`*fzsqm_!zb%~O6a{XfOi5xj^h+9*uA$8QFbw)+eXZDZ&xt~3G*@4e@PTyxATdjEw$8Gje z%j{F)jn8qI-!QY`+ZO!mk^BpH|KdBV%Ws|{_bQB!to%u_@qrTg#i8mt3>T4BsmkEQ z>%VWDxM*aXxOX3Ie`?6LKJC+%)B8Sg=8+wXnvHp_eV^xEnm5wR&aJxd(FK!#p{=5a zy9gxC z9N0Im=CwQDnBDbM*)h!p)?|#$z#pgB-JlXBLAqyX!c45e(&t^94`Plps^-{jfoHTXGDyOIS zuBR`oTpHc*`pX4b%Z7Cu@zdMwe_ed{UVF-%=}iCl?W0W=pZ?9cZ~v@A+n+3Z;DaR< z*&Y69(4qdORX0Yj8s2lx$UiQ<^~dx3FE6jsu>Y_1jf|4+sM3;91 za_2wj)9P`pyMCYf@pBiBC(fIn@tHEbu4mcG%oFQl8pgixeQi3?yYJ-AZ(@7SNq+44 zjw8C>`rE$L-uu64dh_~8$4|HW=Ej-5f@2>{IaF_Qy%$~?-(c;jH7je)3Y{cVHZOdm z&e3Cs6DBPA^7uVPKYANFUc2(+O=D+eULLalYW4$OmUm{N_i$zNadSI#bk5)U`L(Fn zsj~(y>{;~r6VrTMZ(h`6TjY{5GvFu_+bX5@RuCAzSTU#>U_j6`~pu7G)-{0%^-|us8?sLyQ_mro+pXZ!& zXXb`+#+V&MVxIce(IY3F^XlDb{)u-6qDYm3_;5 z`p#$jY8dl>i1ME>(iM&)u`hqvX|4K}#p;m3*q!Nx)98HP;`iSQ#SPr4KdO5L<@8~( za07L8uMFJDn86>48$6~zDq5l{kxf-iIiTB^mMvu()Kpl2wd3{y`2(iLU9SF4^$6}T z%~hHrG?^MctFL4Cs#Y0vYO7wQR;yGh3GJLW)GnRJwR$`Z`%fx)?!aG(6V+r7WBX2( zQ8OL-GcX*_>)jwm1QH%F9TN%=aVXWiA2H2BorF4BU3-D{CF<-bR1lPIqjI7Axx`WTTf z^sg6vnS}oJO?6BA)-3OxH-CjEeRhVYprWG0Gp={`@}>Pt=dSS7EnVKXbb0rR-la=& zJtGz^@`#fCp5;CLJ@z$CiVxVBM?^foU=8 zWwQ}XT5-LE^&>S7Y0s}pu3#&<8TUW=-8#RNnu{Lh{BGHBiAKT6ir+06DWg7L{iyn& z`f?J~C(!p|QqaVjyQHpf4ob?IXjhtSj zmatru9>Er2_ng)yX^nK+k7GGoC1lV29Ug1Z)*|R60 z9D7(HxGrG%r|~mnYqE3>8>;u8+wK*Z=!S$VAX_)M?g3`HkzR;A(iS1+f3CmZE1S#O z(9#mvq6d_0MLaFRPW|<;dK@IzJme6*JZu(h`=9zx6I}m(YuTu|0+e|qo~Z31p5}}49w3u?3uDbA&dY@^2(f)=Wf96PM~kb`3Q6g~b@+-b zNHyqwuaJXu7`9{|uBkrtpDX-j1+FSt9`@B@&y7Tk(@~onk(m7J|E7E%O0PltOCc*^ zs}DV{K~FbXut<;GzepUiklD;nT~FMcFyf`tRfZmr|!|@AvDRS@QI&{|o#4zxK@` z6#t%KzW9<$_gr@Q6<6-P>gqpSbM3zCuD{{Nn{K}4 z*4u8sC#;{y-=>A*t||M`(eAA9_XC!c!y;4_DweeU@e{_@wuFTV8h zE9}+Rj=X;KjW_@H*4ytKJO1toCP`Z%^D3+*HLR3v;2ZfRJfwP7^}OnsdV_kqdWZUY z^^1~8YL;e5ozlgL+Y-O_M0pZDDIUKk-&5qN^i+AOJ@uZAo|`Yb@Cq`s8;@t2yPR9I6o3>ep;-ycY$rSc{*zsh&9V`j;!!9cTr| zZ#UJIBJVDCBiqWhsfJ-~{dcUjFJc$6YuN4VCaz)I;R)xkOW7CfOSY3;!Omw-vt#UY zb}hSueZ~I8zGgSDyRi;`mfeF8KAY`ENcjsw(R1tt_7eLmJIr2W|G=>DDtno|!tTZJ z`z^bez0O`^M=*eX%KphNU<(k07Gkhpgm8Bqg3>YsvgMe*&;(@_rUIX^voNVy!_H>w z**bQBUC%bM4QvzJ%)Vitv4?phAIWuG&kb1X53oT#ijU@FcoPfZ!H0>PxrK8+mXG7( zc{6X}6S$Qt+{W#EB5!5ivmf{*KAE@iDZHIe<fKIEy~&(nB1U(L_rYxr7zHebir^9?+MXYwqb z4d2_uH}ft09KMzPndk6ap2zdqN9<#MKEHr(=NGD~_zu1kPeD$wx7ge49riAJlO5*` z{93+`U&OED*Yg|rP5fql3%`}$hN0y)emlQ|-^mO4UHoo-55JcO`F?&Mzn}k+KfoX4 zf8s^_0G@R0;}7#c^GEoj{4v#V{x~n@Pw*#s2`}YO@u&Gg{tQ3FpXDn49Dkm_z^>+h z;eX|2yqq8A75qj15`US$!e8aD@gw|ob|1T6Rm>~dgX~Z2AdWw>2iP-g3ww&4$NtT) zWP903;Ol1g1bdQis5K*>;Ew#~AAW8Z22 z$#I!8)p@=%6t&r9bZv`Hh`z~fao-zL7jtLqq}W?x-;T?U>xnxnZeP3UE8`M%dv$E7~tAK`yBEhFtGyJHKvE-COmy)qm2E(eO>@S(Bcq=iePm4Tn0aINk2%rgXew=5 z(sXOnXJb>x&K&#ExcYG|<7SMTKdyh=t>Zo8FByMrv%Yy{^Nr1)wG3~$c*58TKTmvo z;tQ>w*7Vlm*3qrgT9>x2Z9TX3>egWEGp&D{v}n?&lfIht<7CxjcTQe7 zdDGHFJyX_Axpd0yQy!c0+LV7x`KG<0{gJ6xObtz2G412&f$2ME=w^(Y z(LLkwjz>G5@A#-lotJms+4)50k*4P6XJyR_%$huF!K{t5_RP9{)*oj*G3)i&<7UsCy>#~HvwxVQ znPZz1Kj)5~?4A)llY18QZ0On5b9GO!=aIP`^W=GP^YZ4^&ugEzc;4oDJLm14ch9`1 z=DjiRpYv1a_srir|H%ALdwH*`H>)?$JGysfZ-4Lkz1Q^qvG;}EcYD8C5Vzoig++@> z7q={#vvlUt2bMm&^sS|z_wl}{zKp)AzEOQGeeHc+ee?VJ`p)Xx)c3c(_xe6rws2Yh zvVSiNE#JBPvgOw-zqvoNe?)(K|Dyg){d@ZFT9LV8*Gl`!^H#~LEUPxJdTZ7DtCy`_ zv-*Xza?Vnhg0vwr#d z^Va`iL-K}<4Oeftal@S(D>v3|{BF~R&HBxWn=juYZ?SA~ZAskX-;%qfbW8P?+qdlB z^3XXY=Ulb5Wb3=zTDNs>d-B};b00r%_<0TI1<%hrf7SWloj-WN1KSI?U%LI)3-d0# zbw}2YeLLRS*|f8D=k%R7?Y!%vNf*ty=#5>)yI$G7Y4;BoKX{4rk_#?%U%KMbjeG2S z()L`k=c+w7?73&pgO@d4_QK_DmoL10>t}FLn`OK9c?N#k9+WXkv z*Y>_k*-z;*8q@GHhN}!88ZgBJHXta&ed7^u+=B8M54!)3?Yv2xts8Q%8 z7P7Joxx643>~WiidO#Oub2c_n=uG0l*n~C;Vn`a=aL(tpY)=~4A0 zLs)o=<8de#*+ff27u@KlWL91{15Ht7RJVzpYoM?2&Y`!{x6@jr?1G4ve<^~TJR@D& zq5AOVHhXyXFX}Hy%grtb-$@1E*r3@|s9aK%hEu7EFClz^jqd< znV@Mb8#Gzu>UB&7^hYMQG>O-Hi8rA?BU?W2( z@z8V>(zT!`v3MR6`V0^Anm`-aSkOi`4s;|NANnU7#afUa4f;x`>?xx)}5XX4Gpym$J2>eQaImUCgeDE@vA+``O0O zam=zefv#kmL07RYpsU$Ap<|eJZv$P!&IMh|&I`SR8932(>;lmBY&+-%c46pk%*S_t zZelw@H?v)#w=kz8dJfwSx|LlFx{X~L`WsdkdqB?<^n7-C=uOQ3uK?Z7t^~c1?G3%b zcCf2Jcd|c#UL@!)c5Ub=))quBX4ipU!mba!j&;cmpnKSjpqH_mKrd&vgpOdHLi9>@ zE9hQ!d+0TG6}toUYIY~+9|XOI-5q)r>zI2%_X&C(3x;07>f%1o8`%AzH-f&*Zeo7~ zy_x+9^cF#HWd}kpvD?@~ptrL>gWdu9BD<440(uvF4D@dHIOsj>iO^xJdx!?vQ=t3V z!O&kZ6DE2;I|TYiK_6hxh5mw>G0{J<7eEiNzl2_353#?3KFnSO{WIwE>=E`7=%egq z(8t)TppUcHLeF8=O!P_iI_OjEXy{qYrQZNO$le5fhW!on5PLgx2&*-s&#`wvpJ&HH z&tSFoF6dv_3DCa^dYHW*I*8TV2cR#p4?$mMABCRAD(+*@SJ^*6Ujuy#E4fcWUl;T! z`wZzf*yo`qvHl?XH}(bSTkOlw6Ihpg1^SMl$Jp0MA7|f&9>-ecJJ1vC-=Ob-KE~c> zKZ1TB=!fhlq(5RmhaP1gvq8|mvk>S%Kp$bBa1Qz@SA+f&^v~=wE`grp8qm+V7W50y zhuN202l_8=0R4&^Ll3d9xe4?eZU+69TR^|#*3bd0MHJBQxgGQe&_A&sxfAp!L4W2h zqz8C(=s~PD-Jl^J3;N$;y6OLSG5ue^iRoXm{~Xi5_)Sdz9N!cO$MnWCV*1JdaZLZ` z|HkzHjp_dz)BiW7|9=qESzu~k!KMOLUV2S>b9!g`(sWIpFE3MNx9I|^LoUA2x68NB zr}kPJQcMlWh6azWAxUmXlo}FL4e_iYR_E5abWWXJr|2v?lg^;i>13UxQ|U1KZwfv! zn>Eey1ix$b9^i%v(}EgrEf3n8Skt6h_d^T=+qRvqtTQ(E(3QJ?Kj#g-o*3DArobn_AlU>u^;!BYeJJWi;69+PmVCr`GcR z{(dY{0!^c*v`rq>P+wO&B2ZI3ylPlwMR{3iNpVqOL4ICtPIgviMtYh*)#pt~_9P`H z#K*_xyTKkau|+f{m-@Z*S~ZvMKkKuhVD7RmI>_*^>N9`Q**L|yl%F4 zR*-pXgVrojgw=^|f^uC@E4uOY1|bf+(6c}LiS0WMC~Q_&mT8W6PWO!Vpt>7vGz4u~ z!3=MGFk|h9?wsrc{1zZUUw4252@hdOwrPLXruzD+D7jtTuzmY^XBN-NZkpJh41T-~ zJ3PeT#CE|OigR}!TJJecg#C&wEb)GeHIguyPfzqf8{vB*C5lrDeGG}rsTc2PU^M8N z4Y*Eh_Xbs|j-0A| z%jhPV?Ud<*yn84e%*qO8W|GCUbx<)ls}|QKIoYd%Io>|S6U=Dk_x20p{9W63Oa;0c;a%IeH+nsd+q<@R z9|&!l<@G4u?fY|bw)Zu_E5afj2t9FOTrjX>>U<8R28+VlXz(_4MgCUJcLz7k^5CB2 z7k{ZiDHZo&G=JBu+4Je#-Lu_W9|p7tHuXSupgV%-hW+_@DBs-$3-qE;(}eb5p0_XP z^wx$Uj|_pc-qtYC!nqAWXI+qW&5qOx<~5)$3A>%#ff%H=yc2-vqR@%`#h$qPi!iC2 zN_+%eb#MiL!}j($bAw4;adQwb=6c%Wl7oS%WJYg$&s1^{uM*5S5kXg^7G(QX>7l|9 zJE%?7dD>NR>Zt@iWOy1uytP%hp#Py-2toc6OL1WVz(!DaiYEz7Xnx@-+|PeyEnJ!y%J4Mw)St%S8I9sXFc@j= zKl7;~T||@t7Idi6Fp8we$yOol!EGJfxsLL}R&)~pJ?-8e?^G`^6liHD^aqT z>3Wq}eGQ(b;ET!lc2KowcYpv9a=Fp^r2>Shu{JE!0#o zulg*WqxzhUq(d6cw9@0vtLVZ8)akNW?J?M+wU3 zqV7?ozr^vV^gd6O&SR6b{j5>*7MrdyvaQnBtWa}^?UF)lrt~)J(Dbo1IhFNEoy@D5 z$V#OT*dl2@8?IH@D0wq$m1namsg70QJH4rzBsK%Q=W8xz2F*uoyk;&NrJI2EUSLK| zROnmWGpW_=JZUbw0OxA(aJNPZJs|b7#nN(CEx|U>PUa5xJrG2bd zRn0C`SB4Hr6WL5v0XtVNW0RzORxg#H{7BX;WiY4uP1dUZh!v}!VKKNaQGdu>nl-rp z5cIQ%$yu2$N~PkaKxyp zL(6eo8sRMq{Iy1oa5@9Bo_@T~V!_8dIGW|Dp#hDPY{lovE|w%Uur|4a72zm^zEh#6 zyKy{$vXAQS!*{S}vn=^Owh-5QaXg6Q85{-D`=OsDJ8Rec$TZq|HbNsar)Dop$GvSh z?$+MJVzf;xPO3*Aus^UzxVch#hZ&>?Lk}aJCQoNpO+3CYPRBg9UHuZivk=i0`dy*l z$);&@m`{B^lfYXXaFv9kh`+?f(SbJhYMy0I(z_;#CCKYTUrAqwb|4?v!!HsVfTtQ@ z^APO&K7WQVt?pyx`pY>4dveXZWO?zzPIkrEe1iN^eQ)I40v~~Y5)MzD$yebol}@1fB5(ocwqQ7l!&S<0g_I8&a8;fI-uY$v^nu?N^D z9t0n-v5tlQrG16zrQv9UGyEsaBS6uv)k@4U}=sW2p7OVLQ@stj# z^9kZAjei&yPnVxCE96I;>{c|V}Sk^HeYjsFVgt<797iP zoP}d9Y^$R22JO)|eDDoBRX}glKme7bleMy>R%>KQ#`h~vZIXnf1`ii-8(+J`9b9NN zI^=3)J+jprHS&fwd^c02r3*=tG!o^jCAF-j>ZtY0rpETmm1qo&YqdI!MmA`vbu=12 z>yf8IOXyFQB{XBia~yE2B5o)TC1pu6YUzU7L=kMKH?KwsjfCQ8CA{IRrz@~Xbx08K zO&pMz=uiXpMTSraDFq^+fVhh?bRXZ;Z0^lB0nHD%ZWYQhy1ih3k51W}`fNK%Ndl}VNO z)9ay4QIxVEo)-4g2|eHfZ5yC*Vh+_wNC}-#MPdggKzWJeAbHhlNe2c|SJFYY!iXM@_wjH&h|Tpe%YK3`Pn9 zb-%_Bgw$!ECX_JZQJ*NNMK7{!(8EG>O?rSpI+I?~hw&rwMC+1d0x!gZ2CYCtTA=#W zCMk+Ip~FS43-Q!z1~3hA-ikwq)?|9h9xvXUU8gq z7u2IPbxugo8b~%W0NNv~Q3I$?{K7x=2AxsX8pG|7F(Cq#rDjP=dg==I3U>tj0E{G~ zMh|tVmq{Q{zw*S~BTzfla2T#t1jaQ{#$?z@>G1vq58kFRO@~ za7kj*0$zv_$b_zRy3?CSaE06yVTUBcnLLR6f$A91j+zRQRFoqkRyY!ng@xVGUw9Yp zL>PbpEoND(q6k8*pSkPc*Jw!WT8X-WYKGbrEk@dd8VNtRG68W$9qni;?4tmSQE$*2 z)sPO>)as0|l!4rlu1+Bq42QvsQY5;LsuOaIBpd0GvM7PZQJ<7W!N;gGX|)0jPzA*& ziu$BSL@uhM*8)6{1J@eh#{dR#TVpVzJ~o5eWDVoT0Bij>{Aj^*828kz(O{q$q0=K0 zAQVxLXi0R6&>6uGdL$vB7~lth&>0L7TcaS1^=te9p+KdvFAiQj~pe9NZk|_(7v5R7`4mBip5xBMLaEn824xz~e zzRBVB5M9=o@No;}pf&`CS_~$=(O^=OQxFvJS%twUfqMz#!s#^tBiTPe(|t52TvG4=HqaXC7!8O#Fr*%hAd;d}Vig3@NTWpnrXENx6eh(0 zJ35Fh^64HnxEoDnA{+Wa350FJkIn+8piOHq5hP4-5H($s9sn_eVuC;r27uJ`g#Uzbdq&BHVO3@BAlA0)mfy)B5QVzN!sdWaU z*Yx(b%f~XoZ^dCZ#F|m7^a|3@B>R2U~N1%P>1>N>G(lk7!;vg zBOFg}HDUzArZt$UQ!^Yy9rhc_GZ<}V8IumR8cLyR*l5~h122LRoe^CDKh#Zl(_@AK zxykrLl0gpG3aTPg>$GOHqb2}Cxgw5miW0)kupYGoF(@3P7RGU{UBT2=2HRkU zioz~opplOu8&iGS34XW;w@7V@wjva2q&Xwnwqj7V8fZr|q-<;klf`HsfIm<=Pc&SBRX)H2wHwNLF-$beF2{Sba&8E^*G zoZe=5reoA8FfY`ECKQuSs~BhpHptqL&1klo%w~%e*1z6>Puoov3g<@R29~9k1%60) z2qr`aG(^-fSgo)X89?v@*D}I>h&j}<3CcApdV`IcfGQv={vZitq;(4Fm@reu_$K59 ze#|Dw40W6BRCT^@Jbd2OGGCi^>K>NrM?(iw&hv?hO2(3kV5)n=NR`W+rq(gC;A*TB{Ys(FGL| z5OY|x7IFqupgeFwY&uQEA+>ErS0_KW18_o*23*$krBOOan6;KW! zqZNtV$gHECpdc&_?=hhrR6{r>8PToI>Cj`m0NY@OilQ=TckFr z#UV7=pj5(-NpHin)MlieAMgoz2}K%A z*G2RYa={i6{1}ZEOE{{a5H^Hs40}TxGR#Kk3u?k`y9E+s)0@!?>}*{E+Yy1zyO_C}08M=F^%tVqF8j0r4j*c2tI*L@_fBLsF9 zk9Me$1`JfPTl8AHiFQnKplsSq7Ms~>Q8Z)%nABvon4l)aSm1|(B~*_C3=78uFofu4 z1aCru(Po3*02>4(qZM9^aE6~vBleIvjaJ2MHy9DSNgzy%AQI^u*BJSz4$5Oj0d)bU z7-HdQ7$7mwLfzO5ipCzTXB4lkCM$v`MK5TD?u9o55frnTF=mn|H2UHjOPIqVrkWgP zqX}@M06?lkFBrt3Bq0*SL1DP4)(9?)_?i=eK$z~=_(2yC(qgb!5V(y_i&gZkH!IYs z4S5n}SP&d2L`5n1QW$1XG_RzRG+gO)E=Wp@0B2$RP%^v;{1`A{rjxBqf^W@_|lpOah~plxA1hr4%^|+3;>%9 zHmeoR3qzWn2!+5884&V9Lq@E%G*BkRB7lgv27VBJO(v_A;zzh39@=6H8obT+~d%`1_IGBoXW!!0RH(}0HvX~C1>q0NNJ z9sCCN5M5E*0G$JPMm#|#z7L3YG*Fe%0`Df*ggM}3VkS%Y5tasn7J?XhKna+Q1`xLk zOC!u+P?wsb$}o&5W~E^$f*&&m6vB^a(F)vBi_{+NPDlX!z`#+MlsV0`qZt&V&7wH0 zHpQ+9>)&LySuIwZ0izhgG=(XGyTL^GA>mX2Y-R}`b&jIqWNWiewWr$ZbhB4fVPBFNT_|RZpNe8fOD@GGx;9wR3+#+M;D?Hs31W)duD6pj zKu};_1VRMr7z&^ws4D2nYL$o3L#qu~$q4+AXN5PMog(B3qZ^=Ov&IUIMeu_sOc-Ot zOjdva^)c-u>l4U~G@Ogzt~bWGF<$5Zd(!q0egqPYunwMGg?Cs6{6IC>jR>oR8_eLt zJJd*P3pl(Bld>qNm2zNh48u^1&8gUJ4w+1VPAqoC0yQC=0~83B&>kH!rAY5^MQ9da zv7szvcRDejgaI&CfgjAKt#&Kwn+Skbligu;nat7T=ol?52=DkYDB>0Q2Xu?^4LHR7 zi134_h&nhL=}>QXTLp7=IV#R5@ME{y5Il8akQa>8eaw`_bkvE`__F}O7`1FR;D@~2 z1#S?o#C#R4!uG(AtdQkM8sLXQybfi}W}A&-1vX(q!p~_2#%(i3E1S&$I7Hj*qHCk# zpiZ3#uo`qhMMQ{-ap)a{A6l0n4|*gvW5ElBX$*Mi3it{4M%1h&XkgBU+oEM^%^U^o zBAz1CWF#GH2!K|M4&<6Lpr8-WWGR>kJ43PI-DHCo!EET(7#9QN>0uAD5O!3CVJMP8 z|Cq)^@MF=DkICT{ZNQIcG18t3N(Fvk;Aops@3PR2W^4!>kj-k3QtWmo@ME?DQWl5J zYI7I~2;|MMEFsfO_z?;posBgd= z7Lh|lIU3FpZfF3BkHvVQ2istV8bg@IN<{27vjd-wg?FnSsxZmn7VRiXEmC{5M`O^W znTuj_V^S7vr5!VaFn%z6xoi$clnm*hf3wwLSL{yAf-DNU1RD{>lgdf&W{XWmCgwFL z3kh8=2W+Pxk|T>Op*U=)k3eg|L&a+<>&-c7(WNxBsr&WQf-8QR2 z<2V_S0%90Hb}}MKV+7=A(QE-17W`D;l4vDduY*7RW zR}?&)uI+#NO8gj=LGsYPm!b~l0^@Pn`x1N^uZ+A&EMF&=t%M%$fEmkbj? z{}#mw`$w7Zy9*oShczi&nk;y-ha{zdADjRUltsvjb~!NLvB48D)qy229NJMIQ*sL? zKT$4QjKvyDw!_e(V0vJ*LJ}y-XohZK5es4~EI?73@MDK!05WGh#dyqMWOpLrM@9&D zDwucSQkApp}wZR8R~(HVraW3CqkiDMm3(Ywj+qE4e-W{V6~sR$-sc1MEC7)AJj zpp*wBBQ6;d?HJg>h#9RQLfRwEQ-)O!E13yDNQXC^-Ow&U$_fNUqaE3f_zwJtaS%_W zu^IvZFodE6>KkoViXH?qGp2(WUoeIk&57{>KR~T0NR_Q-3=-I39Sc3`q#c$4Bie9_ z)F!n!6pdmc__3Q~F{zJHXh$;?Eijd{JKc^bXS9|~fKF^tPMgC;(*c1W8ZE(#RZA)- zy<4nyEi&y^;0LTK?r3O}3}Cifqc93!IJBcaY1W3xPqaPOs>G2zgdd1x5+Ei2z!(Ev zS`k|@MIxYLiXY{mr$<&}R03MW=A!p7Z^Ad9H_3DH7B($oMYd#HYO*bPlbQ`|Qn5iM z&;8-5P51_}3cuHXjIWRz@D2nI^9SrK*5~jin;1S-j`k%gJ~>%AK5*pZdgb6jH>**; z8F;ZE-;v@kDaN0@q`0)G&=qBK%IcIfWZ;T^z$AZFK3bz0Q&u)+^suVpyotqCMR^l= zMq^3Z)oI&R>Dx<2jx71vN3X4X8ld0`CM(`Uhq-ocT{uY%PI2| zFcsm_DMvXePo1piqsq%t@h%OMwzjHlj687v`7&`U8(K6=2X884rXsiJ+k zDe-0T8!fzMSo5&XVM~W?9JVTOZa_QCXYna^e;{CQ473I22KwxM0i8YI(~q?_BsDZQ zENzgi4ZLBJalLxgO|=K%o#I1zP#z|#eb_UAHFr0_rzv{vh#W_m{VVz z_^^6IN4$k^8vJQnF}+)6%E7aG3w}Jjrn$b@!mYU(1wD9K$vK1T_*OUs>mFRMNtOSI z_eSgSK8vdZJuVHe7@p|u!yE8?zP@T+?epjZ`b~O#xaP_$w7Hlsd$_Mq(bRMT}k((=cfnKThhDI`_gsk^<E4OO1N*gO$91hjsVQyQ9A6jVeu8sHQW%2^NVI`AQ zum-%{V^3fS^F0xGIdCGN4)`m5x+34E#@&tAH3l1{M*rCOvA!(rM4jZ9%6xszo0@kw zU)LOLexmv1<`d1jX8&kkUmnlPNE&YP1?za7f4J`n>19c!NFFI4Zy9Zox}-j7leAm9 zP6|p!X;&+ssB}Qr1A`qWm7~Xwi3Gv}6n#*kJlq(7Y9sgzM=Pz&fn2TlN)167+KuC- zjxgxeXB0&|p&(LJ2($RlNdI}?jL9pOEW4?D#>#oB{l3g9L;YsySW;u!sQmF)9GDsG zo>w@|b7jxMjyX5)S-$!0pHq{|bFy=*OI1IVmDSbN7fn{5SlGR%uXB3u?5oai9nEhq z@7NZ#ZSX6@VB?tGBWnvw@K&7#kMa#4Hxzh&tZtui>DBZ5T4r2&{ac!gGn|!`-l*YK zKM${~&&jQ6NiGD=y`dX4@p3#~m`!##H_)~*lNVZID#`dxmCWjT?zXVR0%#W-cgh` z62Ku1;K#R3#WgVRm#(PGPON(V%jb9Ry*!^ADrd}Ib^esr&l@Ktr?d?7CC$2i;-D|y zZgoWQLU zFf^qbuzWmvaNr=T`Oia;s^Ztf&2PsT{M3n!9Bfg&FE`>%Lb-uNy_H)nG0bI1l~wUA zraqI(B>R}dh~pLVs^7dFOyq53D@z+~qoJ5rj93eV&yJrJW; zah1iz9GS*UTc>6tzA$R^S>t(pQiPcyULvDMS*Zj9ARr&t3H~1R|9)DwbK|w=qQFF?U!M_ZCKKRW5{)q`^TD4jI zPq~s6u;M^sPLkiM^)r^w^HnwOfU4R3WxhtruzT|};xoK?hY>(U5M9PQw)argaV@@j=yQttUFqY%PKN6)018rT{6BXJ15?@ZrFs;WeLyH+@?wW zU{l#h={$?^u9|{|io$~2goC5!r7W(F{k`R6eq-A>i$*7^6C` zWW1I~o17D({+g1iGHTT+WsUZty1F9sLsD$=@bPYZyQ0eR+=xP@&eq7KHTm9Dvc#K% zx2Y!MO+q%NJRq6v3cl=d^e|J79EN`bho|f>cv0C45>lE<#sn%7QtL{_teaI{TbCWX zd3oNj`fR)qmb16{&G^#yK6q3{0RNf7U{;&cRaRS)EzeeCYqoXTWLt&|2Rqq;nM)N} zl}5(oQ&HI$4jSqO+Xwem=arS^RX6jh=IXpEey<@urLr<5K_BC(Sq$HGhOSi2V7KF~ zVBSEqoR@^xXw_i))`{0SZNwDWq|Z~E&<`Z(fFo;Y7ziUl<`31)npHP)M%Vn-;*!ZN zl_e92^X$+q>aXP)c>kC6foPQ>AUL|Kq0)*M2G=tr8FQ%In^Jhjj3O^ zcyZKqsV&86nfhiPY_3We-%ym6skwGiaQ`QVo=qRTqdD1E936dFt$FF1^1UimvacwK z-g*`l`kVALerst#uOk9Eczu{I)9R0wtUg_|4@~XG8()KXbJ5G}1p5*~X%lo(tk0C_ z@JR`nEi3Pwq)7*+BFae$#~!ucrj*%}J<%?k!Z;>#6h(>(?Y3gSYWCm*mo2&Y9*jGQ z*KQkpdGPZaX0_#xIe61em!}6y)s$Yp_|7~tyC!Tv{IbGoO*mbca|Tiet)%~@O7+|2pvbGdqTRZB@( z<-}Q~i&hV|3@-hOU{Cg17aEXO$qa8gs|v*DI}77uN(*Crew|e4W7U4igV~&`(&fvn zQI27^Ls=LIVgfCOHd*~; zOmFnyTmGxkjG4x19%pM{*Lmk&yP;~q$?TH!!ooGvwp@7kh5N=2-@1PNW0taoug_?k zG(R;>W#bOr=-jS9Z|Lrx+TMSOzvCN^kMC;F0Nb7S&jXT}6$HL>ZbzP#8z3%5l1Hfna^w-LtD zJjrLvi}$5HZhXn8$*M6n8&$@<_?q~Q@w@Q4R@iD+Kz#P9eD~?7MRY$8Gv~fj=SUuq!5;QmXOFIre%&!v;&A5N)gx$W|qA8fy3vO2SW z;ID%pju^Wm%3YqCQrM;|T;B3SvSo3r-yIWGpLf~niN%vAHO*S|+>)!wi*%unr59y4 zy{C^Y35@snjEc_<>C_311l9J0OA~HPxIf|Pgx3;2NccKIm!S0-C5YZ-A&zj;>`@B9p@nAl8DnbZgJOJnbHt%#`2vR=mSccezYiJ|c zLt4PnNN6I;K`{XlJVr>wrX`Ni?#u3r<*{0`k2!sws{E?HDs|OHwhJ0D)@MuQmA(XDvfGy+)fd`)fd<5jgUUNc zP98a^3_K&Gz@VfI965yP-a$lRjfcQ~%Ahn)gAY*L3l9N!I1sU@t4Kq`5rB{kufZ}g zEW4tWRfU5uUL4a_R-WD{51W70yxFto1Q%vzl@70Hwk3Ou(o3BaoculeDo1JK;4ALY zrop3X*EtV6zJjNAyC=B|W1U)VYAC%- zHGF5_fy>?>{PMns$@0@e2c+Gy6VWr91pwSHAt!A=M z%E|P_A3^L92U<*=vu55gl1Ip2R}M* z5x=&$cyxZ*B$aAK>%C9)dWhh6$>+vHL_dkT)#PI1)6>$nykcRQ_oLdAcnq&`Iue8jrPU{%JEf>Rb^wWQL#m3W6R5T9u5pX zpYf;d<15CLWnJ_0&)kpI$hgo8(nT72V`duOT(%`J)1XRqdOVq#nWZx_XOwE4vd5Q{ z&eP+4rhH$-9OdaIX{%w6fhOF}W;x(&F?1RF3|glmC;INyJ&w2jWc#FYpRZZzRF*2V zNZF^zO0myf0gGV}2Y^8#atF+ohhdM*)^W0;VrV6zDiZ*uk(o@UC0`V#J9FI;4p`xJ zh-&Wfi*8nHp1t_;T`zpGdTyF`;@Xnow_fqy+baG@Z~Dmm^#0wsb&`7e$eGs+%bhU1 zbmo%Rc-p4^d!E^{PNmx1_tfIrVfppb=G=I6&0;TwMyYD9PLZ`@#0Q8=Fcnt2hWDgDfBAt&t{r&( znwvSFwcxZ+=%8`FE|&B6OxbJ^Ld9;p}4^W1pO=(1XtS{}E& zWRWaZCwDTvY;?&kMaqJnZrbIalXoRbDw! z?HN;H%r%vdK2$MgVEU)!e(&EanxMs_p=wp1Gzaq~4~q?$q8Jt|%pfPZO>*AhBZtEs z{nAgQ^)viH#4Y~*@CkeX=Cl;IsGZ{~O*y6tf9ms<<9;4UHYYol zjV>LzW#_2Ed>VznWKXI0NvVYUfJ>#)$1;3trqR)b=Sv!Wv@FM}l)Pg{Fw;2P5d-Vx zft3ghVWm7CUYyWyA-GVloP1x?wT0tK$|tSpnB4QnC6^~<__cpWj`bdM|F6>zCtiWSdz z^87XaW`Cz&_G|rEMTudo1HYi{peYbN{QWNc*wsygn3(^F85%-6oCdbRTdX31pW;en zp0;-|J9=7l`KUuCcM^ZCeDvtX+QIK@6IUlzG@VUv(bCl-Pc~v(5=x1 ziWlLR19XKMV=8-Cio-9hV^~%o24BZwQVo9AYL~TE>r(4RtJ>OP%{&Es>+wHc8$p|OKZNdwP!<7!N}~7 zC#MAppub5NF$!cA@RN^qd5oNq>@SG2`{Gp|E6+*YsOS2PZtk`wiOHF&^E68vhn2LJw#=S1c~*1Bjb~3OnbSIQ@QIfW|9pureOP_v$fC@O z;U)DzU}I>7mdi8ohTVpMzb2_U>E0xDk|jNs#cGu*URCa^v*i1l>Y5UgUD>{7m!a4< zGH>Ac;bQ}~iVBv8sEN`4P{+~3fI#@EWD1tgrv{1e8guC3L*$8ZWDyY#m|l-o#%FD= zU}SqHRBe|3|mzE$fEHDHS^8s+Q7=} zj0bK%Ir!C8J8!y^o4Ws9Vjni~qd#3Vc+p^J@cVZ@$3JZ7`k9;7Y~Wk#YID5)r`J63 zhkZRw=_A#Ftrk}tS2b>FT;mw$Ox5wiywz`Bu<_~rgJ1sp_Isx~rj+$GR($y_{;$M3 zy!+ermp2FR`)K1f@|x+P6PiA}rzI8tW^H9)5_!i`zuKQ2qw}RpJ|)|et;)`h!G9)I z1TX@4nQ<3h2)v2uf3pJ1jZrD-3;kO;s^d*=c`ELXQ+W;6yu%cMI&9HmQt@ravhV|7 zdW0qhDEK}pnsxypho9nr!!9P!_^gP=Dtd5~B9$(geiA5!K zTy)Qml}l2cS;O14*}f@*lg3|=)7h8cPE`MC)m8W)*}CM|sHVyyo|Y7sANL*p<;U6E z79JfuF}O2+ep^=Mcu6|<@A#37w1u9UZw0;E z|B&9+(0jPYAV$aB2nXSA-G9JXN6Q3=KWuPXP zi_Z&HLrVq;&m3sdC7$JQf2u7JQ)es&ONx2yuoj1YK~?g$s}p$YOaGocdCx6_uZ`~P z=U;XYKAF~2{pQT6y$0S~K8Np~vy?xwv}|$p7=7onCkNlV`w#oN7DdHMxx>%-IVC2h zs^Z{+?`a&K8M;P#7oTy~vMU1f>^`&0m!z-J@4|;XNqGHaO=fduXXet(jhVYLwVB#F zu9ZrMOTJ+$e~m_oQc{%?Mfz6Z9;Hv&rd+1ntURDRqr9$sr05l`KGx;VEq43#zF+~z zqM#s9&{c4vKvPghpZT1O44%p}?qm1_h#n?DC6NJ@G(*Gd5jQOiVSbFDTBo`+H9Xpr zZZwftikwr1PsX~-MjyRm@(M7}iX-eB(qyOWhP_R9b?eJ{^W#OsCT(olchTVc+Gt~c z^^eug@s7%jyp?kXpBcn|hfZ_u$WC4HO2^Mv%?n8O7|f-AtZV5F^n-JJqJ0V-0F=ko<@3N9atkxF0ejxdieO#pBJ!j zG`i$cq;Q;|HjVVBY_tq~dA(@LtS-9tNa@}g1abSUBU`WSNJn3fHXNFoE~zJ5GY-SD z7h0}*?9c7gM|mEp^ypT*OuDk9Md}~kUeYoyO|5p`<4m^zej<==Npbl==g2d>t3gMG zvFfao30QF}<5v_y@{L(S^;3fsN%13M!lSb?nA9A?Lpp{Z$>{<}6}&d8{f3VRhP%Ph zg82||G|U)abjK6{ng`Mk$ehAafm$sx4JZh=$3Zoyl)OasYj3chvfr`a{dD5Sy)zy> z(UCEpoG|5%4?@vhcPv|z{_IhcsmyK1=f8?eGwnn(`_`e~!c9wB93ylOF0bvJ9-pxE z1@;s6sRuLV6Q>=Nk1O!Iqj!{ATT%^ZxBEsO>Ki(@tyZw^a*@~tgx)4 zT2#UmGJ-mzE*4BM2}Z|wYQgb@10o$l4u^*OnR7j0>${g`q+lmA0XQ<<+?j#X0e?YZ z%HapjN`iVp%Yy!l4Z%qn!zrM*@@cgl8B+K!cW`*;lp}g{aC$(Q2sg7?y|=xojs1n)`Z>EJw?A`|HPJ)ZOLRS&(@kuwnutxEbExaV}bGX@JFuMQ(7Xw2vex#F$<^QINFM={wF@tcQ z3P0*6ctKT=u*v&^8-u%o`-6vrL%}n_^TCTjVUQ9!bPjM%wmSAW4mgfDUUr;yTyR`+ zXq$d3R;IT!E2d<2y7wGMkgCAGp&#+UA?U8Ia^**`!{bXBPa>^Y~R8-;@ z!fmNC_NV8M%$c*I*{-n8@Ves9B+-hMj@(DhqiOJPR%fSZ805F-+;$!$Msrw#qZD*v z8+rMvd}3q%uKfM^hx3Q>&*Y!azX%OF1g}U10bo&I(Z-@(Mf-~m7Y!AiDLP+tu}D~C zqJ>h(u7VsIVNHhD4M|Txe}9dFCvuslI1Q*CXj;m_Ifw*6Ee-|voep}EzMJVt-c zW8sFEtFw)mHb5#o^p5zx_`&$m`0H_AoS!xl3L;=G!c?+i#sR?$JgO}0sB{nxvy4%h znWCsl8)dS|wq##&Ah|EegIZcL0KQD>1n6dPSdqVqQcMu2a2Y4qXz=x5n_-io<~6p< z2{2sX&mkqNki(yxzE#7IxgCb|29TH_O^s3=1R?XaE9CCQH7;w-9D%{;o7Xng>+%;* zylQ4LzI0KnP+Kx-a-cY|D3%N+eRDH*SFC4xIN3rL-pf9{wC|>XD{=4t;N6Zrdrohk zHj({?{gFKd_x)Y*$>0N3PqAH4zMb5#VNl&k+@*9m@p$OuyrL!HteQfy26!x{o?U9ivWBf2F>m_$0s` ziLH{IlKUiwB*!GDB!88B1HFtCKOQ8kguY0}(jfxJ3Ot#f}t`KmEI9+Tz@>ya?H&;;$1Dc9FdV*A-5n!lr= z*qJY&HFGK(r@&Q$M{pq!lizY5L4Oxscx@{_mAH!iDc#Dx(8~VV=SsQmb*2B7E@#U# zf6rv54-Btl=a^UGUp#7Pt#xf>^F%vY3L=8c$T6A$EnEQi8%@k+1C&`5P&m|PeM&={ zD5=P#km}ts9#@1Mg!SZ`1Oy{sBvC_bRsyY-QB$$AtT+%A(;Zjb6628REX#8AF0NG18 z;AmS>>J{0C09W<0Iw9==l8ro1z+%Y9{7xu(a7kB?d(K>-02aSnRz)|aQcX&@aO`I5 z%C6&&KL5&ZUo?kgI3bJ3?wYfB&J~28zl}W_Yi^F=>O0{&tk~^1>Rs=@>D3Wz_eSCy zoCr)`^0}a~b;E?pEX>x63Zg;A440|Ja@z$59%lOUo*^#*ISGJA<95!@Sj+&)m+}ftsNx51 z6C{41@`t>IT-p{T)sf)RiyPQk5A0)K`1Z$>@5nr15_A9ttbMB>Y*pI$qH?uGPCB9%vSxLfOOmBbSp>JMb zpC`9Z%DC*Mizn^;6Rv#V2&}=hk#p3yG#{#bA?&JbI|&Uo#MZo>dH3ZV$~%^KD(|m( z-#{;Z&=e#LU{f88(yhd?JbqXScgFTv28aR64gv_j#1!Lz>YhnjE=8q=ekd~dEq+E9 zK}BM;I-I|%;lvqqBM3n5Gy~cRvtRa1Y&O zcTpdoR50cKem~*&i>!7=H^9gFB8EH1aUG$R;BH2pN2%jR2@?hlhNgV_B;W_eTp~zd z?yGsd|SEG(PxBqsCqeG;V43mNm^)Q#`4c9{tsWa~nT+ z?1raF65sRBnL7?KuJXV$!E2YTY-kwhfB)K>*s~v&E}g!nymQ)`rg78Oy9_+4wDZnm zc#SXF5Ow)ncxhRKBLsc3vV|*8v+Ty%XwE|5p}rfKsAJg9?A)NkXEtC^A)^@I|Dw7b zaUYQ{VhVW?RfOn^Y>e!R?2jCd3`NdF&POgr^0E;;k`Tg0%S69*t96g{fc1#=W$Rh% z1?weio;9v01aUG1hSve6mb3k+0<~27)4%8lbeNF0H0o$O_+TPoO~zcGF^%seoH-ki z6C5rHFq&HDNn7^s9Z#uM1!i}1!V?hYt29*fgX@+so@(3LD@sehDQ(7s&6)Og>T!_> zzlwd2WpA@?vNmPL*_`Qul*E4|u<1O`pJmq1jkrTRLL#D6EvZy1tXIp(?|9dP?g(Kk zv(v0x__|8E2}r9qGC<1~mh(I+53$j+%d_8e*fZog<2moS2tX8K0WptRPp!970m4B$ z%x+tnh?`4nsgOW~i5NYmVO9lsMOtVCV+3Ibx!tvY-1 zu`4RuX8wu5LN9~>ir!W?opEGRpOyq)2;RAIZ@Gn_@DrZ{^fFo#w)@!S=h#PJHR?wW z@?zjod9eDd7qe+GHNHc=Pkm5*RQ;CvXBfWE|F#^+c2vq)%+*w=@tb!bemHr4gM~nNHL(&B6fV zwlbQ8kdaCgOd27uU{WY9I{it`{mXfPkh&dn0J+IP?jq*~qT`RIhR}Dp5#;v4pUZQU zD=x?4Xj^mtLfZ=ehk%l)WscO^{)C$e^rrlA$}cW%sc7o6?|_r__ff{IYZ`Ir{pq1~rFs6DEEUHhT- zOD$jP$RvnjLP_bZRwfLYb4n4RiiCc~T@+_Z3K$I9aLqzeSgK}DHlaDWbpE2g2OjvcJsH68k&D20 z{uQi~2dm1uFq6{crMyt{HE9HVuZFM_#Ra&jz$Vr)O0SrqZHyTr%VHEwj?NrBWA5ZY zIf|P$N$^3qa#~S=glkli!0UjT$YoK22J-~h_n+TP&5WZl^M-SkwR(pxdUbRxpes*Z?9eBKE+Z4u` zwjx_19y!Td&pQwC)qU9kuboMRq6)2u&!D{~wET3Gc!vKj|8xG2eCkI2fc;MX4*Mhg zSNKQm{4_skZ{la|Q~7Q71^iz78h)Q0y+v$iQhX*LH0TicXpiB5;fUd7!&$=x!zBP8 zrTYL0%uA_K#KzRF)c(}r)KKb7>U`>AN|4F`^mZwD9B;u_h{re$3Q3(|P&r^)hKF)u zLedg^G_FJ-6=Z>}kjlxa8BPz;Hm;zXOILt>VNkk)x|C>p_|xC~hHAjo?`{~3tfa`0 zCv8|}xP5rItxw8BI{l_1~I zBHiRlhlMY(FctMzm{z`f_NTi+HsSfXl=n30B}SGBULi z1A;7_lQA+PkM#5~6e5p9g%^qn(sB-eGzy0WPypl;a%BbZq;iS_rYA!-Gnc(0<`|Y6 z)RWZ@^XRT5SZqa;BHi${xRx;|%C(95dbWqh+x=VOwL>%T4KosrJYGZk2IA62bbD=c zBH0Yjc*Drml!^B(RG}q@^9f8RRF7djk;{Xm5Xm7rX-Ep?+^HmQZ*)7_rw?TxQ*|UN zy=w=qymHB8Y1{UyvM2wJzq11`W~{MsrN3d{`~IKo#V0LAv2jSg%3w8+ui}P!cOhC0 zvf$qq!z(@g?RR5~@k#k72#clQ<{b%h3jxakTb$cyu$SP8$(#OJ)F|0*VR!jj;r-y>(b|6XOup0=1k~xQL99kIk5J=OH#{M~VMLr(#)b0Fwa%`L@ z_Jb>0*_Ca3f$PB1MiVs1m8p_gG z06?N-%%W=I-NQb31h8E=@Z0Yp=F#f_mt1gI1i)CYBmng%cpvv9ut}pEguL#Lv+iIp zUXf^ucigtKo!S#FE3NP{(c;=WcUSqds0x+@WK|P|kYYZpG;6`!49~`hc0k#Z?-$X< zW`j;*V3Yv|V-oBGB$6MgtQ=evd39VY2&VFj4CfRh91bCij(Nca_+_v@9*rmb@G9CG z5Z;7?9P-bawk`D4SNN>&d)Dn%3q^X;>uhIF<>e_&qAjoX_LeOP87pTM`*67Y_$z#3 zyrPTIyH>S7KR&OgOB|~uer@iI2=mTt+qBv3`a8^I%E(*PeA)?UM;|sRTTWqSM&o3@ z{3TeJ#`w8v%<})N#z-&?w2Bl3RCY!P^Bm4_Fk+O?`WCW6C?Uj6GPl=phEi2KfihN-TO{Nw@kqC8)o+3UsdY~+3Vw) zD>T%i`efa*{8T=Bt=s*`zK=iq)qb)&lj&ifOh2+=!-Pq&@65;_$kUV)V*uA{4@d#) zDh(R@rF}+Psxaymj6k0YX6!&cXK|<*xXK4?%lio43k5jz_#Chy7rTu5lbo;OfMN^m z3x`(a6bZsBzPIb{?fXv8z42iylk%=wHEv2*bNz~{7j*G)2W~H4cl|prp8h&nGbQA3 zckjMs{=7`;%9e0TOAV5!5Fm1|gboH1WNN#zNgHEuGqN3p`w9;h9xbE_`5_*qqKJ*u zE^0q@m>QzaQ0J+Olz@WEJpg{f09y$7%sR-lf(M4ON5f~hfFidKqv%rbE4e2nRMIie zUux-Fv1x_cGQZ*0TldW$=h9cm zqy+f|K4HU(=ETjzFWk)Dvr?L$sH=3l2XFZZF8OXUv-``-9(iQp9=SMLAPb@s3Ul>S zaJL6^a!$^c^=Sq)J2dypD6=N3Y18y-`ZPR^Qf4tS0!X-GIm|kR@tp#?P#mY0*{`=# zcCpSSV*rEcgc*M!eU*dOa62~q)=3mmjfI;(ZyBG*)sQ*q%cWV6m+c^?|Ks+DHs1Q< zudm*{CiyV?cyP<4P2HX0xesppUHA2_rG1;*s{B{2KR^8V3(3a27Ef?C?TSVdq1ji} zXUO)oYeT`(r~~O2+ej~YhAxNQ+mgM~3UK>k#w7sIFiQVj_aEs$7uG8@MXO>F%W`z!idW z4N@$CCm%4gwcwsB??7} z2ohs}ECL=A_7Zt`02JV`5Xfl(Cl6|$oW2H?0ei?P&=}wt5d;EUUORU(bFU!4G$Q#v|ZL<+67k{JIvNNM^lN`Wvbm~b$?RWUv$AK(q~2GQO4#{%BQH?X;ijuBwj$f^ z6v}mSVyk?Q{DAz3{AKxB`33nUxnNL^%lQ>xuIc~9S%cC7SPXt;+!HCq?0`0pm?IxX z$VdfOCOEDc8sc)our3G?z!gvsb^=^GSdp9}MehDDTz*&~q)xf5g~Z~Rv2{SM{c^gP z3%u~bh6j5dX-bNDw3I4P@+PEa8#PKfkI3^bnc{D=IVU71ih!*blF5pWk}IqVnkIMF z*Y(!#TC?_7wk4e^X|iEf`_AoCwX?O2;>4AaLH4%Bj;4gdTKN4-_-V@umuZzL)i6J^ zcGjGkAQd-`e1v}rcYZ*x4K_1dM?%scmTaf|KKUW}G5IO^U*+G(1#$-iX=S6zNNhCj zGVV7XHVzrj7|$Co8U>h<&SOZGUSpAn8M7t`3WL-zxs^h$j|Ksn!R`G5rCgDP&lz_V z3@NxCZ*D1I@N%h%z#FsEr)RU>-70=dCey-KqOVHoiLSD;F7)59E%j5Xq^YR{zD>r( zlhKcp*>6E}kDM5Og!mor9hi+DWZVxA4Tv9Nqhgn0zv8fBNO4ASUU3l!UlmRtV=7S4 zB$KDMi6x9$%;*8`lk4wAPh1YJIeO|}J~4^B*PIqZrIK8rJQmlW{f>n3Q}Ezfm_T2( z&0XR5hY7JtKXvwPU*9Py_9n9-#_sY)smHp?%O_4OFYmf^`#f^P_)IWvvKBwj-pcA1 z-@IxQ-eoZ)T=tr5MGeUG^pUrza=Hp~Vq3BcgLEG~K<}XU(L9U*Zgmw=H-aHX`WuCCpPML>G$go>xcAb^yl>#0n>pM4?sf9Xt6`eUt?$b=e9*hxi*~tqW$`ul-L-lit}5<``@PriV84B-D#3Z< zn?}yydjL0-515V^357FaE3uQfk2pjeBTf;2CB7j91Rt2upyK}T)pmgp<1v^7wx28g zadK)0EsP2RIV+9t*_vtbxYFt7oxg9+@aB}*t#u{H(u^Ouo|aKvSRJ-MyJpb;xc_-S znXr;TaYSsD?vWml9+AE*Jth6C^c$%lmy^!H-;Y-DrTlsiLueR&6&&S!MxMtY|AH_T z=CHnfg#(2<3i*Y46JysiCQsJW=Na%&9)CH;0FpdyP6yL%>Av)i^wBgw4d5iOKH%7{ zdrJdO2W(tUH31$NSs+e1ah>X5hDPffDEkj-c>I{_(|g%Xsm813Jo{SLp=p+@-gasSx41f{DPOSF6vRo zO@_wsB79l+58=u6Qzk}HE~k3rX}Axd8ge;TWt#)CMBs55sTV@&gjj-Y#r9waup@B$ z^I7Zyb_vVNbtmvM1&k*^6XH~a7Bi7jjml?%({E;iOqOY5`j{P{+n~*#Lr-g@8F1CO z;vaH0Avys0N2`~)EcKiw2c?acj9Vcj+W(@&a)-c_>l!j3Y5-35SFb@#J$%YL?Kfet znfXvHZV?yp+tb(O;kVrTTzwGtw$-hgGk5U}-Fh8ACGUKDza`=G7A-AGH8rK+TQA<# zYrMvgY`9yr^Pc&q>imk9@5UveUycC3dWign%7>DT^bXsGPl99@m}K{7mpJ&xt-D-g0t38Z_ zALbXRX$MoT=uz}51{Hf1JVh`szc?tN@aL&NQ6EtMphiICgNza7;MV~@L3$h&D?nby zRsx~WINO>#upGk&K+d?t5jbMJuo_N%A)q5+Yjc~+g%nXxREO1SZA)e=)Z5(F&vx#8 z{7F0(v)Y(c2m5AN_`rnPO!ev-tB(}t=5bfMkbc9~5voa7HHA7KMs4$je5aCrlG` zlmhKNBn&Qt24Si)CHZLHhV{I^%z#}kvzn=@vL&kDyz@umjXO5XW{$CWsU{bbBnC}u zOv$FJu4liC!1G2&j+1*RFJwPwWXo53aDzZgjm0~!178Nk*bDmrfX56%rIqis)BRXK zy++w@p_DY!rytM{T1bnYa6{>~7&Z#(Zm>gRU6$Pd&4;biKnkAAjlvV#tYeu40bm=)6-t-qtD8^M-n{SHXE!ds?Hd2D1FzuQUn|*uX5GlFU?uThC%@8J zIW;ox`bQ_%xs!`#m2^bPrn;`U>7`n?&Ndxg!>k=SNm63&C8mznhTmsnmn_w&o`(U@a@&?@V)Ni`*<3a5I|v0#=v7N2D7S9 zHK5v|qErEp;p1Sr&>2T?QTPITjj%Z7ufm>x%x(M^LsFC|MOjgPt_GJ|I8esqSo(Y{ zd8E3GEhSy5l*%2K6E`PZ#k9Qa$L5TEBTi8rCASh~&Z|9bEu@_kunX7b*A;$ZW#V8D zR^i)8{jy|>*xZ=4B^!U}$deRJPoeB$Y~&#M8Qg*y0$f7I#^fQ$ACb=wtN;75_-M1v zz^F`$C2+Jy6qEu8DMXNp#^5Z2K%4~ZB%qDq_`*MsX3G`T;NQsaL{Q0`Z9&O7WT(f> zFGr6Am4ckOjE?dN@=XHlNvC7rhMQ(AQaO#vt4lfz3WYXMxMU+vC?u=W<4FZkS;c-` zrRr2A8=3-{n(HqOZFq2LL$dhU(DqX`BC&bg%;k}jyRKfd)|Cwb+B!Hz22_kMQ2Hjp3VU1Yg0u*XURe>uojc~ z`o>=O(j_)+kvlK%*1|cdiR4mtC3|#APbE%#HSNb@$y)YDkG6^=x+dPR7T-4|l4w|v z>{y{{`OPc1f5XjJ-uH#iL{xM&CWNpqs*%&wgB09QjBU!!pj=89;Ue>kD7#`u-oCtp zc}MeJhb}mN#82C4hK!PR#;lp5oN^~4^2(TEUQs^jqUge?z1mo9Ut_<~ewUrLGgcX6 zF6=2J3h81dBx0m=fDY1aKwmQorH57H+*FSF3e}X+!kr$gnn`ekPRU6=EZ)yCGsgrn znj;1`>#|r-<*6xm;33QSc(QoPpV|+^i;5HR&W_5;(rc5cn$l=%qHf*3t_kz~-pcp{ z(i>{KiM`S7inau2jH3zIX%TNc+CKPNef_kG(&lIdvS;-0bJS!C z`o^(X)}YHT6cm_2;C1;%k%m#&L=1GgN^LpGCB(d z6d^`ufa<6}PoaL%-v+8wK4w~~>-6G(XtesSWTpM4=N72zs=ZC%Kacw>t7CtBv~2bC z#$-4C@}KbspmOMlcZ8l}um2*nYiWIR!hoJOG;)Yi!?_J$k7YMHirp52iE$UGWCD`e zA=@WAC_5^9UG|~uOBr9r4??&oQi+I-qFti>qQjyg(HYTs(M7o00fCqQ6S|ydGm}9> z57|%l83xG#!(MWSAx~m3Ln}`?7)TMY;+XwGf7ajT@Adcj2mCwydHxWX!;=t4p6u=( z$|-h$B7)XK83JS*xgSD73^p1aaxOIrdyiB-Cjv;xjS*_)-T-tWU>+B(e9&F$a^2y~ zw6>JOw-1l$=b?* zStwhYXi>?ooC4L0_t^pBFK}OM4D!<^5xAm3C8H|1$hwb0u>CG<3PsL z35lsuSSw0K;?G`35aSZbT3lyiZ~NY`L`~E2+Pc{H7h`UO$i2KqNvO4$bqN_GvN2v! zffvXK6O=Pw#qc!@6|pb@BNHk4{A}`a4M<2u z!a6+_2*hQR79TlYZtpFzYNhia6w9BtNZr(uu4ruhfa2lRm^rB7ze90X{)!sCh5i#?mK}4UsK=cHk!KGC#`qi>a}E>(ohA*{P-zq2l)VGNtI6- zcnWPEW`c4V7C3(L+)3njf*}qd$YX9Rb0?S6-Gyi)xd>|F`kB$Wh1r?zI$-!HNOfOz z?aXn!1!ZZ0AvpEAi9PtK8fKYxN5*LOYjg|hCzVo5$|<~cL;w8g^RST->^kUZyq(_- z`FI9W(|qhEd=LJ@J0wO43os>r0ljrq>E0lpMSNWwIilzi%m$>&1?&&QU_~-OZ^oTuORNWX*CnR+lP1H zGjK1>_pQ!sPI&^bI$YnF;00J6STtC*?f49$0>(MSF#j_c4{_t~U@zfs!8nJM$VRw!E zaC!XR(Qz7kdsr|w%DeOO=uO7Up8>d~+-K9+JEwt@XY`ZbzdZULK%jA~f~_LIf*M*1 zo0F|o!IjjE1Pj>9?fv$?2xWIgf-c4ogpj(#K+DN^(9&iBe57TE<)DSO6bp-)KJ9?^ zXSB?&{{|fa%{>rd8=(j~D(^@&BLE~=uQ7Ktmo^wx)xWI4 zk+fXCb93+1#S5KRG6q9w*&}n8jF#l=$zPV_8Y;Y|tYzR9Z?toA0M}|vakXP*|KV5O z{w`HBE$sC4?74N}g3^+?tq~~rpf%&_R@{En=k@~|;`Spqz7AF`H(rI^^DpCjM#o`4 ze!ToCyq_+Q-sGPFpWQq15wVQ>?6*LeXl(l-^jUfN>Fh_B$8QXL})obBX(n9Y6sK(u*D9 z-rYGeL|M7t*#R5@e5?wGJEP(KXgorr*`RTljbijusC@2sqEDf*o3vx^y^Z^gx%a-~ zK%61colXLSa@>pujPIt8i(I_`BS{yZ_JI}lt417 z8wpa+(!T=l~(Ukn|GtO~M7pwm%73q>9d zC!ydB6X$GL6PK$KWZ@Wcg|fxBN7@BI*TyB2aG`3K@rUM&`C1F_DiNgjT15?R`z=hS znS5ACz6fAp==6syC;mPD12LFr7ZJFt0%e!#*mp>Idtx!lAiYPvMt(x?;8?@VS((~} zNnF4S=8^(+g2DyNV5lP*>?q*+ayt8RNQkPaW0^ZtQX-ljy|Q~n-<^-18(2M<@rP}W ziuy&9$k&$4zV)_Qy>Hxe^A$b#w@y#G!s~C1H+7+m9o!$kjy?%p<7vo&r1O&6q&rF4 zT){v#Km^>pJUwJh7`eJ2&kYTLM8xPWP`lg^DHJ67fF)xGwCKi|EIcS6;<|_5g4#c# zuLWc+BC;I{KqUdidMMiCGSLJN`9naH3dm88bS)7_#s-3*QLB@SdAWx19H{o5X z@7+t5!+9Pana_KdZp0>F3$vBUvOEf76d=6{epjWh!^c?4m=I;Q1V?r4KG3#&3t!yV zIM7JM8pYW7O2%jJU@YSqixxBCra<@c6W|D)JcEiWAbnDBFuK8k{1`GE(r+PnfN_-N zvU4S+vA7pCVE+qu2Z!3eETd^WMvP@~Ic1$IHmW%J9qkNsfOSV6R8#A=EgjE$c)IpX zt$G4`a}WD&SN0)&v?)}t422`r&(C){XiT{8ZUM1Q1#lH#&wPuEVpH(C>&kRKgb zc0?emi^Xci^s6&_kgSh`7^R<{hh?xP?6&Me2j# zY<_ETTYhhTfAK(mUOZ7ziW#e_8a2SUSsY;OsQZ!tYI%mHo9zTm0AaeNkbs1Pg^npGL@i?xnt)KoUCyKm8DbpgmqIiGnHC^k9!1CxBhef_ez^;-8|%*XM~r&yxfp#E z7sFXUlyn+%-(k(s@}hLVI@e|CgkuP1atuO5dFt=k`0|&xJ<*UHXOPJwU-m8e+gIb( z%(qx??|i;Z!cFX2G<7U~P`~*GonxnHP^j`g8ytbmO zY*$m`%2>Rl`-9o@DrZ_A?rGcaiw2u_gFESOvrZZRgS)J1ayiq|6b_5Vi)O~@m=JU_ zK8Ns=_2lzV8P#W{hzMW_M+3m4u{=bk2m*MS#wT|GX=2i>?b~Nvv3(oiU*6fdVnt`? za=>+&Ml!s+=v9Cz%V3RIQ`T7uj(-i~^~$XT)C($@K$EAg)Ww)f8Jz?%p^BOQLcFjU zIT@%XB^`n)E21pnLXhKu)3OwhbRh&J;(^II6^hHXMC4pRTnWi*1T?t(`q&R+?l)vi zxR{IcTcJyjdeqYZzPF&UzS-2A=rvd-PCG}0OKT0&V3Zb=NW#c#?#OUM$bOF)QSdixUKPOmU!yuqq$ zCR^23)tl+9qN_3zC~7NQOMn*~A{=CTPM+%qJAeFS_iaIP~vd4toG4in4J4O-F*}gvHD)E^yVuapxL@NgK@vN)r-iUp)5axliy% zaLw<3%l`P)e)bgm=5^P+dGfyB;`q`PpEwtJXgS_JaiVsWyui{NDAG2_9__Le;jP`t zPb11god2hNkKs{#!E0}w{v-Q6`@45vqV8tDX1{*v%IVkL^5Mb$jl-`>t4(}`xu;UG z;!0B`ftQ5K?!d9k3X1r4YYBtb&R8Yh+y*BzjQx|=(c`(^zYMJEga%2ix=K4)(xvXw z&XZiJo~K`-7Gf^7$t6vg6T!s7G?gfi;!!{5ltTZC#KkA(=?79fQu|Vr$ffU1;VF06 zC9&Z)g{zh7p_Wi2RhnDi;nSzP5z#AJ+jDPqABROBMoC)=wFY9`qM}+NGv<+Sw#tFS zI_5McXZn$xjzadhxH-)39(t3=!<+HwZyz~x{vi9|Zys6Scj)Y6&rF!cp1AYs>+Zkh z*T0!AbPDHmbr96{vi*+EMOXYt?R^-cK{@`LXP;otfB(@p)O2Fgz>BA@ntj8qXMcUg z!eN}O?;L!1@yxzi!bCJVd;a{%nFO3oJJ~}2KsP{bv?Uv8^YxVVRQLLplr5>It9@mp zIN-HpvbAC*0l844g{XuWfRlcDPre>i|ykGR4K2d>R1M(Kve?Z|JDm*493`qDWVq#yi;GPbj^e zeXq=Gvee8ex<>%(_84^^@dt<-lz`op@;nN!U=+KHQg<+cvB%CC5u&T5Bj^moT0C}U zfnsWHY#eWA*A$zf+Gj7eT9?Z@YKtSt7dT37Bfo_>0(vnpV6avOfG?>4^9Y?(p%arz zrHIgFK+2N_x`*F~6P*D-%9#I~%bp?MC?{HcBzW$0wCweGth74G5=Wr-@DF%xDYeb) zDA~riQ&o23O+k-yN7&6EE&UwU3AnhIAU`lQoASApT7lf9bp;K$0f^UKCYM{T6&Qeo z-7N?PK`ZHl(4Hwly_f-}oM~lx06yTR!r)Rsl`rSuLJAxCyc{3{zCw`z9+q1gbvyyM z0q(~LFAgOf4$8z9hOEetE3&$;t)|nQ+VQb#4LoS%} zYpXhtjke+Zs`w_}LsO}`@Ou0dfmeiN?Xp?d^1BX_HIYay)n%!wjA+m*(<2WHUZ*F( zJs6X**Rxvy<|gW55|fxUr!bOT^cvgO&Amjmv5BslJA!vmJi9#$j{3!%JT*Q zaHq-RGvhTn5i@>LOvjib!3g{xk={sOgpNQt;LK^@VTB?o9HVtm>&q3mxuOuNs6g3U z12G$_kwJav1iTGZ5YA}0FHkZ(tr^Zq1Hxp$D(0H=(GReeza-|#4T4tZdSQWq1UU|4 za*M$g7$8mn9003;{%^1ga8w1gGR>2lfUSpDFaZz05Gd_f+x{z{>!DSWrHHO)oU*)g zpkk+|woT8zGJ6KSk3HIXud~xvm7Ju-lb_=8&u;NLfWZfsY?|V5|9CO^_SS3ic{19k z(YQ=&U*egSE$O9&h{|VC?@KBPU))?e$0h^J_`F$oX!ha)?c%RWS3q+NG458595m zXi`m}ValkG09TX(SHz4lrWJaP_kwy)LZ1pq?CI{|lgJPL7vMFj%W%q#^TjL>Dd)~Q zxD==rd^Bp~fl7xQP#kxtVO1qKNHtRZbh#p2|Hr?wcl>nh=0L3dj`@H75}$)x_HS`V zJBG=R_ui}>#{b#%_t`to6@ItqhL3L905#&!jc3^X&>nu`+Pj(}zB}$Xicbdmo5b7= zwbA11KX~OI)#X3oKQR}k-~Mso_o)w0d;`orB(?w#(>3G^z+1@x`geA=20{r@3@Z^$ zz@~_1WAov1+yG{vd`_(^-{}efABNB5Qu$oOY{PsAaz*f()#K999-5%7R#&0SAtPjA zv?x%l8b+llIM@)MK@dLL?1k1O=Z+%LLH}`*gB%70^1}+bhG7TK0kR3P0j!6Eykh73 zcV4~f-FqK@?vA$~oZmNh?jzT9MgCC}wnkU3uMW2kFQ}`j?(C^qG&_u+Kh!;A$M(Z_ z-O@4fjyooFkp$cwGS8??Zl}p?YcSyQ*QY}1wZQO1V0VlRP$+teV$I-}dt&LjvxCPCRU8uQ;xG%bVOGjwxXf~&Y$Ub-%Y9*i zvO@_Z_X%-OJdNEk4Jhz;SK@Sq{T+}iKG!eI^bpMvhZ@^+xU&r8bQu8zp6 z<#jl3eTZ=kZ{_F1ODlxLI`|i?%#$Mn#n8&W--c$>i2EA59o6v=**W1?joV$(P*Z(LYKoONhm)cwP-8LFk8MOTm-(j!O^=^<}tRG_McGr#V8^$Ps_P0b;I9w&jBW(4!s6Mck>dxqA>%-O6VdF~U7BQvks@E%dB;=@mV&_w* z0h^M-8nPZmo{!1rmqg997cToP!l8mGV=xHB+l+n2eQ<3>G9aSUVJ4Xd#|6TF1YrQB z2B{FlCJM_3_Z^{SgQWo20*A#wN8qxl1ha@(W5(1SpXLsK;%BZdYQM&!uB4^;lS?{v zo43@&%bd)_`1rOC;Hz*h^v?@h9j*|+#O1zbTXP`pT^zKzh#xyv%wb>icExI%`~`=m zbk@d=r``#9$K$hqnr|?L{R^)z`sq%I(u&W0b4Q=v7%qa7F=^y&@+7p~=zy=fG;3E2 za6Kac%s$^G0c$7I2=D?%p*ArTVC>ZW>b+`G?FO=Ut}*&!(B^^ee?>wf7m{no&H3tM zAa8`+7%go8>ESmIuU#>?>5V1x0{(bQtl0JYN1vX(u4#YGv{)#zaH0G9{(Z0BvnzIb zB4ZDQ!p)|g?8oeDZ-24xMdG46(|S)$JpB0M9`HMP?2Ej2c&`D|VRP0VmP(Ue#%a`J zWNDHios6E;6Mb1+DaNzbuvaY&C)Ige5fZtR0FFWxJjk1@JCXA_H5@6i<^*in&pE~p|s2XK?D14gR7$<^oOQ^WoEE>&DtyHyndzyPqk#)+SnJ(`E7~#oLeie zz3ckWi5vGc`h)FGL%!RY*eWIP!>h*`I(*TZNXPzd+ePB$REooISFoS+(N#y)*fZIi z;KJaHPOi&P{qp|IR{7S<9{HZk0r`Q<5&4nK%kq~qXXR%z7vvW*m*kf+@{kdzZyW?u zoRJq3LK`ojv#EeQ#nu8Q!sAf5^cYBP)ln0(ZC?&tZ2Y3zYaMTf`NNnaoJvog%l<`sy((s^>HsC zeu@-KAcprDaj6mAj*|sdv%^Tk4LN{E9|8@10#ppTeu6Vl@b%m74EXW@XB|~Emkljw zXgGyP4d)D(V(bT$;RYcENd`HkRyeB))wQmsbWc;OMiZMSl=HNTC5eu>EfIFc$LnX| zrZ&91&Ah>!X(c8L@r~@oxXB-{Da%f=zITM+HSJ#Z@$BkYHU1&r$uvY5`xXIJl>*EJ z=3*D}8tC5v|4=jFSYUv})KaxW0X)d+B1T3s4w<6|p+Qwx2jaw0c7lo3I$Q366k_`_ZD!ktl?db(tidVx`t?-4pm zyN?{$u=&PqkMe?Qp+fGQgnOsYUNMQ+F!ONL3zh75l~J}derm>TOO`!w>#b{{duwg# z?CW?te)k=CS6Rc%Bw|(CNUos>`WEnwZ4hI_{a{kF*-V(NOdckYX=#&;lu4{bbl}`u z=TO2CGCQ2_FzVdqFb=3`Am;^=j+{n}1FrjjR{Uz~yeY#6_Pf^y02Nh4`dlS3hv$vr z31W%vAdt8GedcW&mfiL-j?=PgqyG{1XsI0#N%;F@r_bq45jYR^3O`1!g_`DrkORtcC1f4~=M#fM9^iX5SZ=72CF|$~)q-^=cK4XZIb! zTfcno>0RvGY>K^>R242vw4n$~Kk_HO8~R0yAcFM#>`06g66Eb&D?9|o8jJ?3WkKfd0^f`>q?TMTDbI?mfC=)(F`cM ztgX$~YlHF)C~_U-S*jDcmEIBC7vsfB850m60sSaS^#aQP#AZ;%ft5u|o5{R~m`~uu zp^FL7cSuWe{tLH^$o~BtrSW;7iIH6dZNiB)>;!;&&`EUQ(Xn=KE=LJrn>>AW^7CCc zKmW||qFYSz%|{=)`tCKcN7=`F51t;+BqFV^Jbd#*YZSfR_&Y~h-xUmWRSwTkxC+8I zzBI0NUUDjUAq=x?$Gd-f=mFriToG^FyJWn*dDq;9{@TzrT@B@FviXN;B(Q3-voGGN zB;UPZUT2rhIv=gMY2+EI82UR9dv6+Bm7Um^#LbSNqs`IpqRb8`bUT9nYDcx77OVYn zN5n)4Y*L{OkRVB>L0D^;EbKD$3kQX?P?Ryyen%uuVTxi#i_rmXxwZ$CJf)2=bSXqU zuw-D+P_PezdJzdKC~Fk=qAp$>7HJF%gtYURXo7Fel^$W;U@0Ngb#U$yRBhwHubE>{ zgIJ{~oLIZ{!k*QRB8!DdYRtZBN&uZD(%a`37_5vv$!-7wnc57cd;VpD8W(%k8|=z9 zk_UBqZ+g|O&|@;yqc@I*Z zs4)bw_H4prmU_${(&L2N9hiOq@QXqiBOoY7>@$OrB8&{PPXSk61r=FEucA*epxB|{ zD?;EWqTBn9Bd{E51NuS=-WFPi(c?Pi{gPIUa~yN?N1}x0527_DS;P-DPK(*o1UCcN zeb4=w-Pcoc$33Nil9CAn*Q^|X>jR!a*9YvRegJC3vRF0Ho7BXsEk^$9Bxd)eGkcGBSrBH=+1p*gV6hP2+C@uaSeTV;$2<4>4Ihq?l5|hgg zAT6w zq=FF|H;2bX50=|LiZ+Hyl;%>`1KKz{ZPQSi0Dxy9?Q|URPr_f&b%9*g2Bj#hD0Iy! zFfLjfozIv^qD~<0XNcD<@IK1-#-cglgR>mBsV0+IS4nu=;M$bKHfLu=%w8CXdRJc= z-8{8tFRr|oSIAD}FX}523B>G^C$H`6?sYq2Gjxv5>ix?;r54P!$|=0&roYYG1JdZk zzN3CaJr20Z8mu)Nky!GoO%`pnoA0)`J??6OL6L_kcv=Yv3A)XX!m@E!F%UQb8lut+ zS2$G$fs_P!Nl=JBe)`<;Gu?3K0*Y-$&)a_oU2@8s%PYYK{-55mX=Qh4mNGNVRULM? z3*wU(t(o3H&rT<3y?@gBj;Uu?P7lpe{I{2Vli_9J)jIo1?ap$OHK-|C+&Hz2?yI0$ zHebJJ=0es}=eXwIUuxZiUV@d8jQox+gLWarZ5YYwP~CuFG=SW5`RTCVsza9$1Bgaf z$lWpl&H^Sqa}L;OA=}N>;wI`PObgv(&~8?H=O(Plgkr}CTv?n!)+1I^KZ<#Z`6Np*AWlwx^FtwXv*;l^2l|4_2`T1vY+a;uZ1lXfIC6`l6V&z#I zaKf5Q(LBr{br23sl%}P6T+iJONyu!{1fDSYxZKpa?sK3}A;AEt8dS;7WPo=CvJ7ze z|Cb~iBwwWLr-s+_SUW=qZl146mMW2$FEk==z=M==z=8jV{Q+kyRb{ zG;DQ7f{k^liKPMg z4oH%JIYKQ6xgs(=e|69mHn@g=3^_ySuLJ(Fo{%G)`*+w;Dpz~OPC=_eT^zJW2)V`^ z@M`3v-vscYC-+Z}S1m{AMh-(QXaE#r4ntiV-O4RU^gJXNY>j-OSMsELZ$H0RgDOAUGPN0vags@r)@MNR}sCll@6vvV0m} zC}yS^fL#9nBkn!m+p6xq@q4bWu7;N^OY)Shac#?%EXk6sW!aYZ9!c!P8Fri_Q!cGV~tS}1{N?KMLC|y1Bza*=7yxB|I8r;&x zR|mh_gWeY3dEehVT_{)y%Y0V0&ThEknbTTbtQ|(H3sn+pb)k1w>^b|KA3ue{w*4fB zM9a#O8~U^08DlLkLT~^2Zx5Wc^zE0w|2;|yLxx6lzLf){jO4FDGQS3E!p1eSaxqVjhGg39b8D_Xm<$YVAMDyomWcMiOC|*M^jTv zqZN`m3VkqjWQ;Kep(x*qjwPo~Xa)g@>Lx&_iqM)P4WrY3bdby^qKV-amRQOpEOl zb=-JXW^Q3)OZkR5or)QMFE6jID9n?yzAK`Q=OXKyZ~|{pEam^k8M%z7I5EYcFlcD< z1cg!7sGx``y9rGUFhq$y|90?15NxWd_m;pj_$OKs@RsD{NZBl-IyvHUMlf$KZxxU6 zpCTSV{Yjk$)2isS36T;iG}LG+;!v}irIyHNqKxNWko%7X)ibuc4s0TS+C;84w?vxT zs(7oQ2$l^ZP*6<*j-WXUcwQjXDSToNDw5f`K&((}5c3NRCfF7A&O8nLMp{LVq8Ba9 zJjz;Sk8&YeYFpuJp&BN=xd~bw0B$l_iDz7xZj2JZQ;%Ts5&1`lYb>tP;=qb5F;LbU z&zo&eD=l+6DhKn`^LmB4AN8MKQf?`jZ@TVW$yTsqr6dGrZPvHo2N`oQ*s#vN*%NrrLtfIhC0vS8^@s#)75?h zTAhLVWoJZ+6+)1jeu4xL(|)?p8Hsh057|0row3Z?GgnzVwMg7nm(WaBi+*TdsZVlF z4VQuzelRHEdlM&ui(>r#%Sd6aXm1FP=LpL$8-ewz3Fj$U#Pt!9Bl6(u@vgWylz2ju(4Jej(k#; z>`kFPyj$Z-105X!ln7UBZ}eBz)Boe!RLQy4nx3o_)XccR+aBN7TwdPNQeMtT#Jt+lkkSqP z0l9ZfkEa$%=s%}|m6-O!Q9zYD(Njf?{()2pW`JUyfs7*MWee^*`|Mc__1^eHf2#S* zbEv-Ib4CUh&se0{fk)l-Gs$9Nyt1pTdi0`s z%U9f6+DKlsv@MM{KNA1z6U2WT<SBdw*b*O*3AemTF3+?HEEFHo@m=KAoSyc6=f2K?mfNDw!Ay3J~W=?KR zx8eBQpWV@L?BNSto^YSL<;s;SE*QG><=4hKz2VS+@;y(qGb{e(%HQ5l`{^$h+GYkS z%IbEEj9k*Uae^eRnOD&nf=8B2UY+PHwv4+BeTmCQ%lUb|P5H@gHD{?JRVx~nH}$tQ z_81o$d1H}VYIIvhkb~8ok1*zWWZt}?+EGY~<rp_XM_tGUlY;{&5zulN>8kYa{%U~;-pA7_9?=#^5+M2QE zXGuiC7vz;V%mtzl4k`=s93^=L3dQPMPHTvE$D0Bjl4l77EbRT+vxy@a&Cx(P{$Ka< z{D0pI6BY2#Dy#}rubVp%yIAYWaq*j6SGxAN9(EmYz2bVu^@-~{mqweNlg)3+zA}4H z_QTl+vR}!5C;OA^@3J-2@52YB7>(aXzd#8!EwYn(P<0SmD?D>iep3`axhVW`QTXDb z@WVwlD5aIrnp_l(1wBE(B$X89Sqe;OQjpOL4>OffAp*$N5ZQ|?6v#lJ(KxH|FpdT^ z5M&{-!Wqp3SDK%5CizvuOavnp=soByL+_%>j3T>@#&=CWqC5=7Ncnvk_2qD93iT>s zS)#Dm#O>s|^fwK1d9ie3N*TmeH7m1cA>nyWsqk_+%%e3j$SkLQU~1^CFTDOuf@&nv$baG5_j zEX2hbh|hU3wp)u}U4D~zrMO3YSUe!UBEBPjB7P@oXmdVZ>&$WTo19lV_c$MR9&o5T^E;DJFF_Wr?i4&DsCd+(x5~&+X^+kzJHSq{4tsi|~(5Ie2W2|B608^uB|!Zl?bLtX?f>kz~%{7ls0VEsjD z=o4-Xk0`~F+XR7cAY313jgUGx-$w*_>(u(kY``}7T|xdQ}u6P}qV2y@NsW>SlMB%S!OE5n9pk5-{OKYm;1 z4O_daHj-C2UjM+e!=&2%RB}MGW2-`KDXEG-R<$3c5na!PLQg%`p^`6#a7!;+n*@_$ zN95-CCfto4IcrZMXRVq0B(`4&8A7g5G$d>cT^70_bYJL+(4o+=(1)R~LK?wnF!CFX zml#eF5 z#B{0BUs#;&fo~djhF(U84j;~fW8_2lsO3Lk`(XSiH4U5E;R%+5PkAQe4YDvsDSq)( zCltmds8CHw|7n?U5WS`Zol_w)LT=#diW$j@N0w~qiuz_Qwa_+DIWt=fsa2iC3ioI# zGUK{vW}H7P(9AdinQ_-6GfoI=6<=-9rkoq!Whrct}t0fmL zppTbaNR#B&PEL};e3K$YF&jCH>D*8GM{##=#UJGRk*S-`>7Epj+^*8ogcg?9Ov5{; zWdRx1^yOw-M`e2~Y%Xl5Y`<`EsJ_9KbIE#7Rin#5?LDFRgNi0L8#>U$l1xHDN}*0= zvt^^IA@T_5#L?r_;PFpW|ML?Cf5w-^%g%Ut=67%Z!Aexz>d6l@tHf21qYL2oY3Jr} zOSn<)-Pn)SjZ#PN(&43}OSdfDwN$xu#wwK5b?KzLhRD!>l(pHl({-2YG1v31-@4v+ zsa#28LDb?(mSX+A{lopE{agBX_3!Q9*MG48)qZV%wquRzxI&LaxaWo^K>*oDK`xdS6by=o9vE@C! zCm3pMXv)c&^X*;MP?;+b2=LzqgAMFa`oMzgZ(BJ!bN=qT*Q`_gdDY?@MiG9X_w~=S2 z#;blmJ^os5DIc18u6}Czc>}57!+6g6BC6>;$Q`CR#N1vsPY3!XZdB7;c^8x4-{i8$ zAE(Bv#-_(#JNY5Y#h1qirpGsMZBn*W zIWYaaWBPdm|19|pp0k{OW(~w}x=!*_@~i3RRL_u~zsbFN+ViIA=MCgx@+;68S}XN& zAq!TBm9bvNzkkTR)tpFZan60>LGe}br1&M^wJ3`P#{V!ZUac23$uKEM`-}&nBxD0o z82dfM>Oj#tNHUk5mThE4E5kZZ?mE3TDtZ0iR754*9^qQ#dGA5w=>N0^{Oz;`{9or( zb~`J-EoL>~1FH})eh+HEPd2&Bq_VGzPy@bviM@o?fakU%l6(~EXbESEY3xRIZW3Qw zgeKZhYmUOPli)hAj4)e}jI%Pvv-CZtu`z^(OXI7Cm1noq$0Td8uhDHQR2Iw{ID2We z)a)oPG3nBksadV%^&Xe-R@jo?<-9IC*O8JoSXEPG>UQOs^K=EyfTOUh1vmGyut~^O zuEfn5pB8yNn!B2`bVbLRz(behWa>R#4ZfSH^^}SzZZ?;^=6%6i?ee_oxWnPN*AXqN z6fPEo0$at|q9Vrbwc#Y#lhV8^B;y-~z&s2IDpy9ODY2H{+OKzSdy zLCO4rj%hg!qD9O?Msf}fw+16U z{>D`C5&7KZ=34OcFd>7{aeidFfP^mHc5y>(`Hu6qTpw?6cspl0iOG~>Fr<{`SCv%H zA3pD#9oXT+fWKboK04U)a$?CQMM1KnG|eg6oY|g<*T=C*I4rQs9|{JAa-1vUA?$MC zD$Tonq}n~d#e{jx>#eKbf7PBMNWHPzUDK(C|68eqYSHdld55)Pn+nktI&zn;DQhm0T z_Z&TXm;rkh>uJP{Sf|@2GnpxX!uvDvx2nn<`31GLeMNRRMB4SWTcjdSlXBZQH2s?D z`K}Ukt}nROH=G@HIPi_a-cXl)F+MOL;y;sYywyFxmKF)u?I<;?}wBG*_{=kV`kGArPy8Lq9^MGiK>7I?QS& z(n?y;OsIF5`tM<#qme0i2|c9nbf*UObZ4Al|CtJKU}dGKL4^L{$y?-#tc+;)z{YPr zxc=+R3}s24DKev`=}Hw9T@{0ls_wqk11gpFXNoaZU!dPXn|a1akBT>?^;On6Jqtf4 zXxcU-^uO+R_f_^3mxo_mJrk#qI{6X*uJQ})VL_~3o03E8Gw(@xIORafD=F`!e3J5A zih5@XQJRfrew+D5^Zn*0&4!QJy7KK9ebdMI-xP~rT-x^-8_@L*K zqWdtp#FUFN>R0-UKLz3#G^Lc7VyKB=s0()Iv;#5!1(G((#pJJ1hp|&0IG_( z*+(h=JUO|B)e2!9cGR2kyqfXVliY2*gn3x?F*be>&qeO!A0bzhX#8eAD(-_#A`^0T zGAHUq^y^crb!g5(yH#*Cv?WOEV#+Nk0BAR6eMiu>HY?YBoDvrbYf|9Ehq~pBq%BCCdsgHC@LR(s; z?(fSk{+k>qZ?*l*6Y8o;cQFUAhp zeo+iuFL%g9l#pGdg=z4L;PA}45pgg z5=ky+om4L7ibk$X>Mht(z!zi}7W3(RqF-zIv<#Wp5+#I3PZYC`n5! zH6^P+i!QT1dx1_UfT#!iBg7kz4!oa!pEcnxv;`?{Cs;l`5EysR4ToMn>eaW#SC+>r za=Vm1XQ8LA)aCSg>McvjB1>mXF}J>~POl}TD?Q=~L z#SZi#Ifk4qtjMU(v-5epFU?h8&q6B43&#(!6(RE`Arlu(V;B{+&hV7V#Qv06+8P+M zZL`I^HA9};M=DYq=fvDC=dawb_Ng`N$C^~uO9~({D0XR(A=hx>fOB5VuXXPZm#t~7 zzHRaCvszksy|the9eGGpQKPt9{5gE$SYeK&g=@tpSoB$rWEY~5j>DKl4{bVJPB#6} z=2cVD1I2*TSIR(%ffHYjrj7Mp)9lQvqSet@Aa!C7Y0n#R^)UEGE6z0UT?jn*`Qfm z&}p&$Qiw13P1)0B-i8J*eyw?6yzqsl_!|`)aoM%yHAC(@*ZttKtxoG!cG&|BWw8tm zN>QDH$3RYRT*Ir<8{JkZ{+vmSdE7BkR1@W>uloD>8Z=gI**fSNZU`iK_f&hyy_wWM`P?ZUwb z@T@@4dg*E7m=S9EGEFIiLzNx&8;5A{C9=%^yQoJU#b=zhjn>owi7KYQ7@k0gJq>T^ zW14u38d1K?;{PM+{!;h+YriRbNtvw&$9kLPnWwb zTd{xQ#rb23dH*H4$Dh+C$p@UO9Q8*hn#8&G=At3T%8XiHoxl0qrAsPmJjO2Lz^(kc z{@;+Ndg%GaaJ~;Q>}%mx!?M>CbM(w=pS5z`$gp3_)%tTrq|MS!Ng?^y46K{gzHVhx zSkPOtN*%5y&#_~NfS%Naf}@sC8dXl9zv)gKf8!7ipAr>j5d)~2{(C4(ehA`-Nc+D! z_WuUXlMA!szMliQX#orTIzq&IH7nQ!NK+Tk80uNx*N+Qm%@+1gyudEtzeOtIZ<$0y z#>T`HHE)`OYiORnh8lmp@6He>UpscJ1SvvdB31%&x;wpeTojr%fk?i zV75Qia*TlO4|BcCotK!a#EZEqtLG9Cy$)R=_TRdi!`fo2~Kq zBvKvl+(-TD>IOV7V)I@@_9y1GS7P2!$W@S-mvxg9FTqHJNMHrmaIaw|x*K&VMwXTe zQ@fGpG*8cY5_U>?-*z8HM%rB3)8>T!oR|}u%hZg;80V>xXM}u)4slAI7(pHJW>gI^ z=BlI!t*Kv%0_UwYlBuOmO4aY5JQ%ZN7+dwK7B?qXyioWZN*ZVuLoR~D9F?+FNGw3% zkk`itk-OqNG)^Fu>P{S;IDAw$F;0u!Q(|X7tw)?p`*gHF;i*z0RB-W6sqiWv0E`sD zHEKy`^#<^UQr8nTm~3+ExXW*sJICELTTtqq50_N+-dg!gTDl<6_HraWE!q>$=lS~G z@wXB^<&;`iIIf&E)l60Gd)kX1#xpYjn?)rDM$J!XaGkhhnCG+A{X7?NXJ;p1o>s7xaUH2M30wyj z@ku^5E-5K7ZhrhhQK@_xxPcjA1$dvAcLINzvP3Z8IX+LHlOt@0JE<=+ZC5jKER2O^Q!0^P@`#$UgZ9h%{&xeBfO8y zmnpx-`=oF35cceeZxLvW=Tz<2_qnSl-@j(mlk z5N$?3rK{|7qKNnLIl5C4m>j0>>q_WOIecEx!FI+zPquR(vy&hx+3fuveqM!{KvVH~ zY5Mcd(>|{v_sQ?47})!)8Zuiq3e?eclTX;XSzjeaOJ^kZ^8`C-c|5&CdHhN4%hSfw zbHaGQ%t?HT@`vVrs~<;+oyhf-ColrO8=S-mvJ1Cwh@~iab!ESTLZCn)tAdS2bgr;f zq&GB^&36JHlE+rivB5HS^77aPlgEXx*d8j`%-3*NC*aBu#4Sadbne7$&Z0eN*sl5$ zySj<(N}hr4N}d6$pPHcpGekRnFazBuodNs2o#M6^cCtlm1>k7(mf7AY=gFx8Jk_-2 zXC_v_y2>!wf^s=j5?)F_ubud@5}kuFD=n8xp+NYShfOR)S4X^cvAW*6eRTp#JvWWa$3qCbR{uHOfr!r$YZ&eJf!1h()BULe!B&8o=pU_VJU3mw?K=wVj zrDl1bq%4GW#(K;`Vx8y^BYcYvF>G!QE8=g6AHzyz&)HslCk%qv>3fWGnqsM_PNW5W zAY7m(l^!>)hTb~sk0PGH_yLR;x%Uon@G{WRnTgRx@2Sypt!)Y;^6V$L_hcC1iN2Li z-cdI-xjZ*2CsP=a=RTojFv62ed2A?y(i0g*WXmL#B4C+hH?%Ub^NJXD-q7s{Cw4B| zDyb9!m4}YR9%U(_h{+ob_9G62g83Td)ocAA!kM;GBa1BwYz2w6#wM9?2K@)a`r_< zI>npX_|M~WCjJoV>51^g3-);4(?-N{gGg9fgJZ97#}B>ZN2X7gp18#IlbMf@4p-jAT+&qu}8BAH)L%Z)Fu1 zX{{)E8>a%*i&^ZVyt8QsT&78s4t;=*h;O}m;`J}cYX0Z(4~OP`^!{Cm6oKQ0l@9kiq2s{{hexq0{s<~Yz3}i;#7g>L{;8VS{MyX!w_f??ft5?&I=s9*FH5b? zHkXgVdO&yUgP;0-SlKk39(3$Cv1Q$@MQzV_6Q9cIl?rks6>aS*#nOAzhtm}v)I3O& zRNi*do{`)u)mL%V5(m?=%7aKwsfS<4kMIf$Qtz`Rm1^d!QKTsQXh-;LnhVXNwvE^8 zMN`$nLMj*L>GN6(XSGVd?Izv5n*j+`wDD3#uLR#FJ;@0c?>VS@eQaD8bt2|!V(<+b z0Xj%%KHi3%NIW_^aTI;M$DCC8V--s>D=XmG5>-YRYKp0)Pp3?{ zLLdp@udGHxj)0PK%Kj7-{Rs=1PcCMQw?y*w_stEnvxru$<;l0>&z-wD9wU3MsAy=Y z2%QYo$G>gxH#Yj4w-S>5;KnO2U-E%M_%rWs9vgV;B~o!#iRAW8@QQ;USG!8dxm)k% z$yxXAFzkQjm&?~YAKzuUS<&PxZ&FH4<-R6;({Rt=Pu^VK?(le2P5#wM=n%dtWXZGS zvG^R;?;93GXddmc(iHUT<|VT(b8jY}={BLHm$bKt6qRu{OA=Brh@>hLQqn}J6f))b zq1TU6i)ccsM3Th`BwQRq3@y%!3XBv8jXKn2#DU1hZ`z)jDZ%svAX3X_Q~uL@y*>Ae zUmv{iV7PmO-OZcwl%+*8D$ADbUlh-O^6{_oFC^;mb7RXh-n=sYSA{Lso6$a~3J=FW znVmL&Mp{M7(z(3iua7)b3|)fOe*a!M37iXX^|7Kk`D8#(nsp@Ka;Js20LJ`=5Zd%g zc|om|r3$7xVeX}S@n9=VVK{^WWru)ypb!+-^t8*cT&*S;NE9+nLVR`MdL zM}1Sd<6ooV@%xo$Z@TNb&+dEtw(H+KeA|8Qr@G3zLsqkzLJHp=oMT9*^l#(j5yewN z9<BS6DgB9%soeqm;l6@`7A zwHZBBZO~=3W|*X89L2;TC#~WG+5?v$RTog^ec}+kTaX`iC^YkoUazbZB<>TJ&C~+= zOSU?*gDCp>$dy}%FC5vmb=}TxU*S!S=l!ka)klLrEB1BYu@&(Tk3PP7XyH|Jd)?I| z<C#)@28$)3A6sVGffo z590hGs_6aT*67v9_GsWPyC903a-RJeR~7xPP?u-dWTdYR)va<|c-1G<4I4dYUJ}1Q zM~%ShC3U_qzxqO?)63aC^j=thIKc{kxhIxmM41f{bj>CRg`3qo)x26Ir8@*iE)H5| zNT5JRzy3(~HMQn}g3w-UGUWh?neJ-@B`mQ4MR)22)*9n()GHMAOO|ZtsJ35i|Cy~l zRP>U?2N`_0gkHBv~;1 z`0LOkkxorXCU$Uo%w9r~oH}=kLzyVLktmo9>mvgfB*TI0nt7e^tUxzOkil|5&}|B<;#zcE_j9gT zR=J;d`vsl9prSCTl((Shn9qVSKJ>T4pQDGUcyI#OfE~yNO6pDk;bp$WDa{_Jda4Te zRQe%R<`wCyQ?i5{b5^+CqE?}ze2YpawEM&5xl2l)ZH;ENE3C_3x;3>SRg-RLT5?r$ zT2)$k3@I~JX%$3Yp{v!E*DSR8md<*n^h8N{EnqA6NFvyket3#;%f}jRQtdQ~t3&(qhUh_+A)*m#q%*$3xH)?F2>eHC4P+iN*nj~Y>Ank}b)i4wAZJ)ec4OMx4k!&F05z{?EveE26KVAv_IDpLzslOnxBV4ogTbxJN5=;jWnTev#~LB2FVQ z=5#nLy$(m8Hm#zm%Hf&S=8(D^dC96-H4azMk%`JgNE~`^91SG!lOoxBhaei@*Z3hH zyPK@Hwy91~tjWr0*$rEQ{7vdzUU<=rL8vXss%R@t# z8Mnp%a#Q^G?Ymm)eU+r_$tQn7F8;W=-11#)U_Ona?VW!;jiUAc{vNWe83hz|=Earm zS*4P@r^p=Nvtu5reEEROYbW;#D(Ks4_|5xb0V}O8bQkIiN$EZhxP?)&lz2-bQ?Nh@)ST*~JdTz17QEP7g!uZ9ZAX$I+qM19+JEF~*@10R-b%&Z}-t^Y| zTCpJ~XtO9{U7ugnRAL>PxFRV-@zWg}c7FE4BcoaOSKsE)$2?uZx}R_Tv))nYUkZRE z4+$43vc(+O4s}n8X*8Y@p@3Lwf+fqwPbT9bx#A*6mCu?VtV}Oz_0JR@^I6TssUv4) zhil5Js9k|t3P)9?&{ib|>u*DKdXdvSkyc$$%_l4gtjm>hCB`&jjL5y652*cFS~W?$ zPc7`Ql30zdtp{T)h2wCZ1sDa>*e)qP1Vg9 z*)_MeA~7ek`mx=~R=>C98F@9eQ~`pkbd@L;BG2i^oWa^tbHXdMLA1+rf=(W1a6tV|IpQ67%2q^n ztUK+~m5tM%9-Vwt`5$bL&L8YCM(?&~uvDE``&pAODn&N311q7BNl%04T$7KAUm!}k z9bUiPF?&HQMb|oCYOa+GXiCM2L$jr@R9==P6%KmmkIv`kO9ra9XKDrA%q7qPkgap#2s$Pm8t16?PB}iPE@bNjA)#q)^cj7MN3wjBK~;GC6R6Il zZIn=g90;BbQcd|g{iOtpx7!No$1;r=6%2@9JVvw{Q*S8bbgNauT_3)1kWWg&%U-+6 zFvC#ZJim05WaQ7DU4Td?jWpwqySu~7gR_z|^q$6esPXRWXXeH~=2OVQgCFh{giq(? zFMR!%Yun-{5F#WM1?zwP;Br-|U8=w5x>=!)j?gl)d)Y0dUkrP@O-Tz&YGbZJg;qn} z?hK@t2$B6nqfyKl&fjE7k?bX67}q&@&*Y23kXX-kaAQ9!lq~dcb5hN%78e{yIbD$X zTMd#5nTa)|rqdpvZ^I7N8c=om3~tFJdKzmRdm0su4v)T8-=kOP9oz`4F-i`xEI59g zdhPgoN2tGzieI!X6;&3;$B#K7l4elRiF((jl>Q<+U&$CBm4v1rQVPpLUvMETOpLxp zFbr+!2|ZILz!xfKg}0||`tt17^6IlM@oBGn?!oqOim1vgQ1*wHSh6$pVsPC&Pp{q4 z7n-9dv}oftm~8W&(5X5GT#`MsZ%yt?V6Bs4ZEVhz zhjy}l@&knzxPTsZ44dAHAC$3{=yNdAUXx}_V3X|irMyC(^XV9?>9e*6VW42Z0(d(2U_s{r0g#bOkS=GF&a^ppeFEgF#6`Emfh-(RFUo< zn%T>c3z72y3vLwk7tEy&;_^7`rI}Iz0{#sWS5sM9DTF(8Tv$Hdn!h-VN(M$P5l1(%WnG1ZD}rN zD2C(!hqEH3(Oy#LcKi5bWA1A`mH#SV@=AfgnDOT5X%~^`AeNk_qz~*`$ zHr8C_YIoy5<#XV~*2F!+3(9}s9Njn>>bw7p`FSckG-ezLMhwN>0wfrWKqx95@%^W4 zM5H&3dV(NRT`>8kut2y9QE+F+w8f&j@KxtYwECfFYfsX*Iz4LioX|=Zy;mR8AJo69 zKZ#-n?qboFkKkZa3dTLD&uUFkar6^9{F76(hRuUPx6-PQ<6^m}v&hTryqt|41RabZMv_Fr# zGTa|OxN_yqb4%I>Ha(YGmA`#+xa0mV66_{VP%>BgU`cUB3F&dpsO*c6Uv}9q>jE7( zpXzvnaMqN^Z<^1|jxXYG6`OEs@bdu@j{_3(F?v?KL97(h@Lcw{9jBfHJa3#pUt6IO z&taygv;5|Eob0TLKhe=#9XAlG5IkfweM>rDkxpu*a;aKOk%CfnL!M-kYz{aY(j{9x zO0PGhc+wTlEJb~ocY-V7=n%w$%wGU0oa=}>picH9_)RVMh_2^pX#g28sp*g-JY`C{ zX@d`lAl}Ab3dkIRLxP?*RZmd`8DmA!shAk7vRN#)s$U$;H)qB-$MZzht~OV3idxKC zQQtm~yi5*2=T6e@z8CG=UYRH;w)_0{;_WwO7|DEoef;~Xp7@JB@wdwyVaGj=s?Vxw z&>lU)P<_HNlDUZ&Mp||>0@(JYHLo^5*!U~2`YlpP7m>++}!0f1x zHt2f~+yh7D9Hi`e0vtp3%S^EX0F2 zQhKYZdXn=Hd9XQk_dO?~Ij+I8j{c%KnB>&%4)I%41F5riUa-D*IBzU3(%v4yueoID z-28L$!>tcq|JGpqwbuB@EpJ?O^^QPG(z`3kZGalt2TQ57?1O!qB)nj}x)9P>No7(- zg091AsrW0S*0TTg?E?vURl+z&#kAjBo{`dOdB%6h7MW7=YCA?27bH!|%G3@TLQd3_ zNB5o25;NK`t|)(c#s$ESuSDv{roLD}HpF`EQ*aM=CR=3+lY>a1M}>ThkiEFa|--;^ehh5Us(nVdVDVcVON7vndr843TW@=LA@_UIN) zCH0{5K(|Fo$&eiA4FXS>HxLVK2?(S3u`h5i@MS<*0CEwi4rfT3%?{#_0)bGTqPtG2 zf>}s~K)ojFycws6^dTijP$G%vC>q=hj*a8j#L;nDdY&q2vQ#H`yOd#qT6w9+2JoQx zBjZ(Z5%SVx{Hr29|0x%Z%rgL05cf>VJ7z??@4u^0&|h2ka))WGcB3}cQqmbL^=MN> zi{Su}so3s+J|#UVt>XPlN2Jn5`-MxYtN&WvNxYrW8OmU|Cn<@Xdpv1Pw_d5ed4p}c zts~lHFRn@rr@0S!x`#-P*;j7P+3=Aiccs6iT*;>;3C3=mAhR69Z`=qOdf+}k+3hEM zl@yT5BvQ*sB{qq8b7Q%Ca}}?`UTc+5i(e}lC8dRo0&sQ_fsm%=>ITkPRA#H#rY077Pv+uV6r*vgjV205YO-?HGPc(7>s2 zZXqjID^nthdW6}5lJg0iTBrHhp^q3?@CCyRkb`xDCYu zW`$w7s$J%4nqj%HB#>+h`}5pQEBs@yZw31l3Nm~4+CrNrgD?K8R%Koq=}gY;s4EJ$ zeV5d%$;clV&eE#mf9ExtKv`>Es!G>XVg0x{U~6wFY}0CTI^4NAz**TRPNlXGgX*`Y zp;}KRthxc_5vSUlk9F|XW8?tCoVWHd3?rHHIOb@l>qNP42_mE8_#gGXh;ZKF^*HvFEJ3xTN^-m?wO}leXZ%1u zB@?wjxT6`&QUM!HitrF$i;5B%oG)g%LPOd$t2CQ5iXQaQqs^8ConS#NIX#zTP{H=> zp>pDhqlimq9;<{jBGZBdkdo&~zE~zT7Mk;&^MiAgH>NK#=#q?Wa@)-IygY-kq9@e)!0?)_IE>T2Uy5by zP1~2or@>X=#kZ&P1};sU`l{$)x*z)_;Do0zkU6?U@-AkdjqfrV@Lj#aLv-%McbWY7 zF8V$C$zfzx)FQJoKbESO)RHlmmyBkbSHgLiC5*{1^c#?+iXA>$IgzeE>HPOBq)T z8`lPIAvn)9M9qg`G21m`FIqLgAp*!{7BdyqKwvSWW4RUaujp9rAEcj4ei~6tzKGfY z=%Z3J>&(XD#&$92yGGb2TbB6lh2WQq*CzEQ;FXVI;*b+Myhl8>Ty%S&R{y4<^Q3CQ%I0nAF)2^l@`!`+eCmrM`n2~c`~6X1TDSS_OnWffBtVRE^0x3W;2 z2ftqWlU#;IuK=(D>yg(=B?7qeikPy8&LE7d7vBGUulF%;L3ETTOB6Rbq*{@TDC-Lr z6NMkVw>8m|dKI@W7BRJwKqE2b5@jywX*XoASvG%;R1>LpskJL4U&xirX(iX{IrYmT zD?)0wTh}$KnK$Xo_GAl|a15C~wa4L)@PKn;eCoPmK5$h(vNsMvcct_} zuHg;#NyQaecRj^NsRwe}C?)5|P3aGm3(KkjVwZt{rx{bIi-DFXlTBOf6|-R}9%=UK z+cF~Ms_c%PSM}cEOw*+=inM0ViC^Cz|IMuGhx7cMv}v_^=FFuKaauO!yl~>Q5nR7VzLpGVMvMF7ieYW*OzSk2LRlc%?bI``Rp{BN>H4?2y zAL~|MiNB+ucdfHRB^qY<%sIkPomw=utyKJN*NyG-?(#R&hSmc!u1y>BgjGnW2`x#6 zMX`GFGoe^$;EbS3wK3b$+>N>X%v>^;C#n(VM>lc#c_h_rf}j4$r;uuYY&dEqCua z{M}U}PoMYV&oAY(NNA;r>rtH?bTz}NdJIF={ z>31wc)oQd7$fd2^$QR~GGe6(F+I)doVJ`4{dwb7XRWOUpno%&caEKprm>p(+=wvOa z_3z61GK}@nB$;dp}8zoxM=!!wa0_1 zw#N_45m3j*!Kuc^POx97B6b1_8S?1h)CU8lnky2+2ML4Jf0ffhomir1;+5_H~8Hl&qo%$;y)>Uykr2{?^Hr zKE$$0n~auG4UH;I=~=+{cj-YlYb9MLJVn=|5YmG#83Z6AjM6?%;VFP<2>$zSV3D8IbtQN z&hhuIM;F(j0S^KgTe#jVe{X0w#D^#>L;)+IIdG8pYkXravcyIDT*OuCcaK}i#a1$6 zCG)MsYWMqk@n_TdE@Z7oDl3cY{3lVj6caq2s&A#g;dV)G&GY(;#l`;7jhp*P|4jeJ zlV~4E-_xe)TRXb_4SGLF2cQJ8VDC*F8iN@Ne?3kR1{$w44J3dP5ReG6kn88drH#f zzp~O#86fQ~F8(`Oa%9!~ZKuJ&hl?07Njq1jCf7VWJHuY!aLuT>b7fm!z)`Ens83$( zdES%c(4Mu_wLWb(FNEiiz#BgxE#Kb-T5=|Jd9OvLEb(WXB$=`Z)thp19J$#uN5-rn zhvx>bSe6z^=6Q8(N2Zpq>dN_a&vVmo^4K(-EJsZ3#>-qcxcFtRvt5V)##Qxsmyu=j zT2Rp@%Rd_065=Viyo&fyAyi{^ktbb;U3{PGJ{M2n1OPVQ`eW-eRt1HUnp%JuV5w%s z%09nmc;WEK@Xldjn1ak*b&r8f`M2cl$~&2-0L<)vTGvKP9r6r*lBeLOLxz&yFwhtT zY^yk*4U^Y8lIq3yz zuCRbcC%|BHOb)?2fp}%P(9kLTK;AA6<}_aijzO8w4jFI$s=TB;V4v$Ai1!tE3Ik;k zcS(j+=k1(0bgR!@c6Y=p+=tfOZCPoJg=d{r6!Au+v^m}8%81kU{Q4qG-bP13HuM@6 z>wvfkIo3fWO_y_A(vw^T*;PRZga)d)EuXwYd=N2j#jpVUFDlWKruZ))(QBUYw)M76 z>32IOA64ConTk0ljfrEUPGD5hQ@x#|oqIbK2|ciH@;%YU#<>XdT4A;y%d-Xd2B&7L zL;rz8Y?P1No0#nuHk-Gww{UOa)NE;!2gHZixajn^E|48}~LQMos3zpSB2h$NYZC`nWTGkXcsQDIwEKqJ(vFs92&$01r=Nlv?3?c|IwsQOVImgrEplCpolAG(sLK=GB+z=byL@%!}DC@Qy2 z10+$bDlXzb^xd(e#_Ms_1p9MbYe#->Usy7KRatvOqxORK{_NR-+OoN`o14oNUz{C( zCI0pOm(*7E2JFtZ&;Lk%k6x`C;~zhAv*h{R^>!Rzwecs*Gbt zUbZ8aCk4Na$ow|6OWO0wJ~4?y=q5Z6{jo}KDKW($8kxNCM3+`ubkvX>gEK2Y<5UCD z>y&hvG+7ot;(3;)mjYQPgyA z?YWaI`1IV$p|)_=qU=W}o_UlGeT?rwleUhkst)#JVp~TQOq|-b>I;$-V#>rKeZgS3 zH@UbIPYZEI%vS)Lo=ANKP$~f9tixw3vXrdpk_zt9LZLlJ3Pua_C4XB`%7LqjhY3Ap zXDKO#8gPi3(#L7S<7YH0_A?v>)su_iWPu+A1cKc%Yne$a{uZMf4kZ;Tamv1%psNPrj|C`6hz&>Zn>G7bE@a2@+#Uxvm(CmPV~?Wcc6#nZRCbV zB3`3X7x%~O1J#;f5GT5qomAxUdHm=rLHn7rws`aai&!sM`E+P(NCrb2*+RxbNfNbu5kq34 zsUWm>DgCRwus7QM*Y1_^YgQO(qu9kQEh`VG{(ODJJ~Ptx5Z@-ZiG9D#xpa+fH6h;k zMZf(C#z%XXhP#ptDKi4WWo_-KbENuWcL(~zI`ZWHunNVRzoR*9JP(~=aaIWr4PYop z@l3YLDF2Mtu*%^5q{&B=H?h}nA26H9$I5NMyAZc5mYfkJ)-qx&BbAbeo|8K{z134D z<)ukkv6S@ItUN>n=H-PWm1RUMBV`hoCnY7>lO z_#vk@p`j%^M0k{gQgKl_3(Eyyvbfp6RE-__8b^mXddlT#T_IjETTKh$D&rrWw|Hk{ zrs(qCg3@>!s%GkW{BwkhWD=#hv+2NzBF_DVglRr;evQ+_v= z@4?1V4;{w+Mz#zh|Cey(5w$L1LFpy#uT7ehb=>X3p#>M!GMG2cU0=g8bPt=GMl+&-u`P= zZLr-v&=Y?*{@FR-{HT3&Mke3xUb>;RzTD(7`STYSmn)^ z|2Y0_d|Xj-sp|pvmXqi)JzA>n&(Bym=R%SOOfVrwI!8dC2ySkyvNY>T*jzU2pV#yH z)b05M_5brn?fY;VTux4^l9NVL_onixsf9&cYL3FBE<_hsxZP@XM-Ut!r%ljsb*g+r z6oxuYejwUYBwb&q$7$6rUVKkkX=qmQ=%v?J*-T~4 zp*hiSQq$}7l|8*Rz1OVz!-wSjykJpL&mZEuNX=afEDaq&FXbEYMTi(p0mjdYSqy5D zZ6yVTq>x`2CgJ3aY$>_MDM|~WNLHgW6UFmXNc%>u-&|dY@zR-*fZL_damJ z&#HRY4-T623P=3pvRkiP@E@ydcT_G%D_p5VT1hTm8OYC;N|eeQ7mmb#_x3G;l9J|U zZ*B{Ag%@Tgr-;cpkPAG`tBCs3|GeSz^mOa0s3lKrcUWDKQkp8xF&sfWLj+lwh7kCq zRw|F?A+7`6ifp@Vyp8VMs7-CP?aJPZl5c9RDlJ(mEfXE|BK_k&-4W!H(!d2d#DlU@ z8@(`Sqbzy>e3JsP%vP~i`~@WAC$153gYuS99E*h{D(>8rTB{OV3-x8Id? zunp>>NY8fsZ7UsQN-RU#cb*0x1%R zk0XT~G367B$!i)lDRT70B4tUb$euMxqK*Ef-4jQ%6j_qRLM#@2zO;+q%R_6m=_M@% z3z`Z@g)5|2QrMs-NBEAxC#n7~|5qqlEs7#^Wey}7?}A_ApaRMwD00YU%|K7$J@Mbf z_un{n)1#!67-Fj(Z+-j0OYuL( zI~3f=wzapWEB3{!h$6m(JgNXkOVk(!hl93&dzYi9oUqvrKA|yXsc1Y@EJc&rn&Qa< zc%QTp-2DEZnc5ft7_5n0v&Awo1RULbS3qRCYx^THoFta`()qyEIMyr{XWl*{I^z87teB zyf>NO1wDx8&Do-uEosv%>9O?D^nK|E)0OGz7Hf98s4yg}Ikm;WAtHc=Fv(QvsBc`R zQnDTWROnX%v0>Y#fNVxr8_0^HVo8^~s(xNZxv#p`*%KTfZF}bA>t|hj_kg~4<-Wf- zuiO2j4c(nVNfG|-^EJiujywV~dqYu>N+zbsw-kR7EV!q+?4CfS6#K;xIL)S5*D@2y zb&<^(cOg%4VbKWK&BC0`Id|nKaw>R@R1q$ajBaUR+6dgEp^OZVR4et+Do+-N*Aa6l z91gQjNx$41pE0&_Xez42~frUNEXX+1h|5dK^tJin4|V?+!Lr3%TbsjU8mAG zU|a$}qI`+LFylkAs7yY(YTbhQYGWw==Fshp4Xd8!S4Mk#qw&XEtXF%MpI_cOyS-H= za`8p$hfT@Je7?r5DX(5eR2N;krGM_7jwlGjUq{Ml<^V| z=r>Jp1$u(lA`f?pOzUL{OWuTnBBm%aR-PYOlAM*hHr&ViuD0~ovy_GTw=M0N*Eh{m#)bw>>CX6vYi_=J@9S%?y3ba~|9a@o8&=$0S>k9s za8qlbGc<&zQK}?UvZ|yLqW1rK^KX&ndF92W*aelCQiK4s(DGOw0s)ItBo*356)iIm zgTzpbQy1llG{%PYC8x1%vUr1orV0CuJup6=5L?iooUsHz5ffzjtoS?U4VY*_oy<)4 zZ6_2EYkL)gTWfxIE6K0^b2J1bkN&y(=M9&`qIYg8eOY|FBR>8s_@v0>-{V&cD}-`r z%`;>El6<93NVOF5IuGq7uJHJCM@?Hyyh)SlOH$^dIc2^My_$6;N+Fv|^4Y{}w(R!~ z(Oy3I}rwWdmfm{_8;373JpMgdluqLnQ{p#${(Qy9hYtO+BkZ`#@x>e8(-SG2d_(!E z;NrsEidaKHvN*lYQRf!tE~nCI=Xtx7qm^`O$z!NBY&PsP2nH{D$`7NfypWR_r%jI^q-aX)gF73dcUcuzV~y3#tw?rhtFT#9K}pp!#43GoxP-9 zAa-k5aZj8S>(p*!##9LaSL)g_9 z>%PB>lr}#9zngmx@FuRMVR+AKRV+8jw%p6gURky!tJ-RAa<|;%jxp6X!WOvULJiFc zJpn@~X@E&1^`?=Y3)~x$+z?1YdO}F=2`QupEPr!$CD|l5|NH#^^ZeiQV(eY5cF)-} zXJ*dKoGHs?MmV85*m+!Sl)L?EbI&KZ>3cV^*Y8#TwTq ztR_W@Xwb|UE{hKK31i!2H7-t*Dt(L7xWs9oajCP}7V&-T{IK`E4DEp>l+9#~$bs)NS&3Z>L3hCX!TK`+8#5D_`(wvRpmT0BRw|LR4hSr=vbG&=zLca=NO2sB z-Cx0;6d0eenS*t=qzQ0L7EoIawVS{4oSbp5BqTY#(mEqBL>5hTdgeCfn%*#ZT_dec zsx(`v=gW#BQgq{5$S0DuZNKNsB7J@N3S>Yz_R|H)o0IGE9JN+(l+-?@-F6;@xe&EG zw>E((h9`Iqd9!jM3PWCHqSCNV3~*y3;`l#; z)?<4dN=P5KCqcf0P{t07djOob$Ur7CQV3FRx+o7kSF^d`PY5jjnU(P7yguhVn*#)F zpc=>!jzv}l;5!QnTrrD{IPej?km9@yaK+asKUGk5Rz?;b5m|BVmetD5NGu7>sp%{8 zWbw)!-SfK?OP#4X4Mxu|p0_`|arc?e(BfvRCbvCNlA@&28JRXiyn1j`xQbVAS`a5K zijP}VTaT-^HJYuNU*3A)4YUd+qMTs$^4ty9bS*%J_2z{vfdcH!3!ndNGv*>smH=jh z4H;7hwr9Y7Z0rVWWz1wHiytP>3qR)nOca7wZ>3#T#*|<#TFL00VIn5Jwuo5^rk+fq zj4{iYvCwglz(lnKu-a5kPsGVVI6(`+KJzKSzIVX}32TV}2T@^<7tj^G>j^*#GYQa= zy!$tiMjS8;8I@_s56&fzPEBEjXSh!RPeaaV8sE+Pta8IxK{Oo{ICI`PsCSxM9~T}N zDXqy>>`5ilY|S|_sOGx6Puw)2tDnorB6o*|qwAC{yco9ul{b`9A0j>VgrVN&WlW8!N;%i!bPb+bFfp*Pzmu^{)kWHiSbdW zR4=&gR9;ZZ0k00_}vKC8a4+o<1rpi#LH6?hd3_XYV6mQm^>vub`k*#je zO?w7cqT5!&S~l$2K|&?61hfi&9jXBwvw@tn!Xybne zG2%1qp>08ng2+;dEU%bRLUKc_rpY5>D-zU7F;i6=!qDZYygZBaYUed@7n9|~IZU&# z2Z^!mG#GAy(}BkewlFFHdoXfgJo6!-mz{anbNCWip6@O!-cMtD_%g@z@E3x-un}u| zCK(-XUG?OWV6Tff%lNWB82yV|_%+z2oG04(5DFWbO;L^|$&4*1XwSnp7jIl~q%(O_ za%El(lbRc14beWK-Siy_??{So%u3f$oOif&7<|h69;mr)#jlruPFGBRPkn;@7SXpH z=fj!gSUPwi@^?GD{aaJ`x@?CypbdTpn z^6Yh4YQU&J?@DsH5d%m8URwbM2G4{1KLkR6KpkPRCrX&OQYNX8kvkcE5M$CeR57w7 z@HY#ohbkxB@K4PFWmEDV_!j}!f8+c)JpSnhPS{sV@ypaEKn6xauTJDIj7PU4k79@XDv}gP ztF10i|AM=~^c~;HjPVT!kvw7D^Oro|JPzqQXFhh1TZz}#%l2?V6Z>WId%=4Gl9&aO zcn&#J0!}s}3HWUlGqyw~EkglOOtHH8jI4KXV(jrZiVU0QPL$vY~$e*I&$#Q}_rh@E_c+QR^9o~*yb6ojNSkg(c?!%qy_}}balHrm4z`*Ap_-s*=1vn*CK=s+pGf%UN|_*mroA% zEgwL!?6Lt+!>cZUl~ay6K(mStc=Y1B7i9Q@W7o%0jX867t$Mtst+Lb|YzVfbsf)5B zHLks*#(neUawQmbv+vn`_UcJi}hY|5<^}9OjEn zg$cuOwPY{#0v>{R2mb+3fMbA*W)n5M=)}H<3=0j##Z6R7ATV%tG7`5!$vs z`Roc?{;zpup3lo>d3Mjnn|E{2lG(+*n}Ir6sIY4wY^{NwfHO^SYhWbKZ%|nj&id{H z{MdCB=+;cs+SN&n7Ip?Q7|1@5Z8ZoPnt?FcNQ=QhLr%gtVoWj)Wl=;HO)43O!Di&( zrv21!Q-p1T_Y6Rt*nR-0q9j$=P4Y781X1m8X^#NNQ7s*eX6)gm6<*4Vz_hh_mc!9` z$WL2a#vxQHsO!p?5oPG_o<>=l$kG4cX&tiAKUJV%a2+Y1+H}1NZ@)9ejzuVI%!H3h{~V$?O*R z<+43S2~0JA7Va^Fr{3BMoYat5>iMQLCMhV;Iq&nFI)iMUCL$Sx_}UyS#4oosOCn!t zMV+nl?s>dEz$>l4)4c`+&A7l&QB1~SR$#v_krUWYT>9q32beGa*|X%&zBHG4RlxmT zuL@Z89%A(-To1?ZT>#&E^+?dGz+DSIU$&zT_`^zD{2#!N#cEGXm1YEFXbp)m0s2%% zDvb{`;$nuRK%`eg=@O36yduK0&l)7p8n9<>8U zc4#hhTA>!a_g-0oV5kAS%-2m7q4d`nr%hdsmiX@Ds@6p(Wcb$^j2Flbq+i$ zG@koCd#bIqiBfS$p={4{n-^aHsGUhR*8#`eowLkU(y|{}iZ{2`ShDdby_r1$D&S)Q zpa1M9(CB#!Z;TOTAUVc|F+!t-p^5n*G*qaWTWU(|cLJ4mk$i*PR(-ozCJTrPNBkh+qVNoD&3v?e{%q7cE62Ik z^T)(N&ud{MDT%1hPuob=ZeH51O3Tjid{^N)3$tA~`4P2MAc8z?;Df_J+>}0B%0SYx zkgQ}zL^EP>#u#s$NAg5j8Dum&cs5Z9*kS+xP%jGeRsevPKf<=C&qmBnz1OrD$?3&j zoenDM;PFzUEZc0&^*nIX1Ce5|lwBLS`-kcVeh4-gBT*MNAs#suHL?Na86Gi8OC(lB z$|uH0jZX}lR#_X7v=Q^r+V$(4*G@bDBgp}I<$IXH2G}v8vzURDb$D-In#WW%B``WE zN|I_pGHEnHnt2`%i@Jdz>hc;($P6+H53GRAtBQw(Ytz1ml>*K@$c3+Pn9S0@cPc@n z&yM7?OaZQ7MCRrZa|9u{6#exZU*^zxXD{u3C!#uhyAXs^JiRNVv0IT0B)W(wMNf_* zC00i2kX;X2z3)OOg1TrDfjcZg5s;ca53Qa*3oV*ub6)Yp#92?1L=X_=v@5rh)*bEY z3U!*X*z&WZpvE>=#!({}4=>gUb zmZ?qwb2=zNkD3O`zlEg#3yI*pcC`-H-K$BYEU%W2cru3_o^ur#rX0bn35vY}rC^A1 z#3Cb$QEUkY=wFE^189dNh5WxG9$`Q<6k@rIcDg;~i?u2;x~}l@>p)ZFq-XL1|7HGp z@P#yijWf{*VxbmnPOuis)3`%F@@@Or?=CHs@7h#q#n82o#F6|tMUSPMN zryEQ-$xS)sxrb>i>Th%|-jKe2UNWn5iGxVb_j0Uo)gVL7RT5(g%G-PN(fyupS&b_n zl{J-e8du`B#}B&>zhI}Zx+S<{+ZW{AWt_fsmWqt-^}K}jEo=)OntWHZfd3T%CLh)U zr>3G=J&V&dzXC5C4Pmy+R7`?S0ST;i;H(X`_oAYtV5bLcdIXOeXp&&jXv&!eXz$Mh z2KwTt>+c3SO}UJ@x-4BG`F~a@m!KP$98xKB#x9X_y}IOCzRW*1pbPEfkJLr}yO8s` z#GV?V0tq~n(VNm^sBAb3%_M}7N*HfQ6QXPhBo|I*jnqGbwEfeZpHE;a_!Jlkgdef& z5u|Tmi{7;l^Fo|f7>l63i>yN9H6miif^gQtMfQ1KdePo!Nmp)ucjBxMS9=17@ ziYNCd-cz{-ZaGw+o@s5e>_-G@K6&Km$>7oSLQ`|}jFG;L0%?Fc%{0?4I5f8_C$Y(t zn?B^3_`>tp&+mK=FP%2|wCG(Bs`VgcJMG$hCZkxyNNBKnMi!YEhOjYXnsE)O5wSb( zL82l9lSampG`<7;2(+KR@}af>cA-C+^V6J9k@gwvPJ>N;c;-;55n|^->t%P@AW0QS zOyObK>`D*Ws02KdIno%0M=A9t0mqg+p8*Ik?r09i+ zyc9ZFX@AMn9UMv``sw#3)_U&7slgB3!#m~82mb8ESL$nlelJX(rH+D~KmqhyYu8A_ z1;7DQnFPx=(T$*F1gn{(a1=f!9v72hkrxZhsZ5MiYJ`nyR(OuqV&H&(4M+$eJYzHf zF$tqJpg}4mh=j>!S4agTl_&rH4_O(|QE z*|Q1V-Eno`w{1qHOi=%6O6i_W+gl7ve+i*cfH1{rHNBNR>^YOsVAiD{xNjTaN8Vd{ z2&fZ6#h}d-pKYx2yisL!@?rG}?d%$eY>CZ7hEum=xrp`TgW4SeqJ*VooV7y-p4f7T z4}(gQu~aIpVZ@U5Pgp@M|BCeHKQ9$mGY-L5}BNv!HzJ&xj|^BU%LJJw-g=*9>^eH3}#^4}ole(cd>ltXJ>_Jm3I8B_J|Ha?%kL z=urw15Q8b;2b0D?2~bc(Zp*>DuerDPQP1no$E2sm@~8}1ap8e?mKS@jqWFsP?UEXmArq!*E{y&R zl>*tFX}dIDK{7#O!f`N4i9kIJ!v%41xx{I z``z;g^(gpN7$8=l+8$;U#xiSjkt7%8W`#0q!3hqB9Y%^B!YoEbF`24@Tw{^|s!4;h z2n7MNCm?pK0IPE6z({uvM}6YN_iR;T0KOUa1ic13V81?XgjHDmqX6C$4pRdE1xU_H za@hhUNvY>0MNktHqV=RRcZ^C?*k;P3-iXd7x_U3lKSoLnoGQciuU=YtxFK&;P&oU@g-JRVEMMhMt zOl7tiHSPJ*5?M%uO0dCH!!JmRj#0@?^_fPSS(RjrPl$|xyH!fVEP3?&MH+;7o3j<^ z0q9?0H*L>rNst>Gt{-bs*3F_*a#U$_d{g9BRdASKY1O_$L(y$QtwG-`H^8#9SnRr*VXz~oNh|&V~Ew-mdW~64AGI(wh zY2p}lFr&*_3yhu`VAg?6!Kl&5q|!73@bS1k8UojZVjn9oLaofO3Od1vT`M8p5Wo+A zu@vx(&yaEgL<8Uo=K<>APl!z^tT=#a2@^d2h&cq7?%2Hs?t+(9vZ(pY#-5$^ncCa* zsg=&E%DNnRt34{|`lLQxcDnk?zLx7(Ue~_xWo??tomO8`%2?uL5%E?>yi_aE!IzB6Cs0uDu<@T{k}sBQKwPmb!!Hi`pl^9N!mzIgqv1H`hUaFTNQzJZWY?HU{E3p58=oo0a7ljQ|W0C|)=O(rI$W!vrsOA2_hfo1<~>NzS6JPAte zDn4V=M~5)a20TNwOTFtJlq^{zXrlQtT zOJpVRhZabAW)AJWOR+0;AD;)hT%EGgl9-hfS-o71Xo~-|=ghjJ$(gPCig<(^DA|!y zhGQjS*VcRfSvOb}U0|Xul`#L*E>$V#@R)hfdk)0FIu#H;qjop+nz%7Gsk<48$2JLd?m`57~9o4 zW90dUd+i04+Tx0!)i^s~%H#`FI@Jht;IN0JL3zUL+*GiL4nW#kjP$XP?=CtAuE1A( zEpct=E!Y<#M=MD3fdZ>FZ{X=?k)2g-SbA^C!8rN{5SXCqjQ=w% zxU7_WAh(VR4|($>)Q`cYpl|`gmLHP$>Q^ExPKZQKMWtoNhbra58A~cFt;r+FmJcmC zLqj=On6S^^5R=A_G#=ICPllt0g`SlQVY)%PNdO^ zo8Gwa{O6w33(tPV8=1Um?$ULu4y|qh2;VdL8ubDd3D&e4yCsMTjn~GLN%8l^AB%q} zelngPZ-;=RcoC!1)M@5x)@jBx$2H$;gqmz(EOH#&8bw(m1}`BjnE{xg1^~`c;H5Au znt=I)TXW$hIjIbw3SR)A;Xmivsz6d{ zWNoNy=50y|pUYUu#aA_iCUo{#NShv($cOa=)Q+&^v4C+%`6QBu@#0~8klF+!Ow2t` z|BUmf10As*v49nRPRRqD;ucA{0mjNpi(4EQ8s;q;5>~!YTUC`yI-joLMe#{b!QA}ZYZxfqL=-W>qOvro zzN2PBVV5pOU}2(cj0^-@Z2?%rAiFRWc!0VtuVLRc)?~^Gs7qKo87vsNFmzTL;CW}0 z<)17w0q((3k1x^!qb3lUUtdtB@>4O{c{OK}+SELc#BmqAStI9Gy9Y);s_9THv{r50 z^p(4M)y4z8$;JAhw$_CfLrB8Jro`QC+1hkn)8JfQPK2l1T2o_ZsS02-JDW{vy;jI-w#vu0AFz02mIeM z$)`S~azT=J*mX1$OE9#|E~}Fb$kxHydR!)y6<8n{Ag#0O#&kSgelC+B8w2x6zEKds zGMU%roMuhycrk^|8NA`H;4mEXQ&=zXcmYkY4&^5SoCX`jRxG(jm?6fFy;A~y2cTB+ zoI-IzdaGrIP!cFu8I1W1FMHn1LdfW4X$+6RpA#&_rq1S9^IFPKOxfbTQ0V{ALPlo4P9@J!G`RXa2hbjU|%4CNM0(=mp z!kIuVoJARh!eFnysAUAf>=>sR&@lt@k+%}Yfc>l4VR~oPD-i-hz?j$(!`KD9Az+;A zHht}O?aFluGE)Zh`;uT&U)W^bNeP@;m6qAJny+|gF@|&~)v8sY zwW@=v`&7qNl*$fYsC0$_18Fc+Raby@)4Ru3Wfi1ybIH1o`Uo0KlMPRfPZd zAj2vKtL6IIVu8tjBhbU2XQHd(Kn*d`w#9i>nt`n!}c*KwY>(+E@@liSl47F29~+EWkE_FTq>sYpM{e zGvKRZH)S*FHZ7nacKJRS!HdA)jG%*bL3S{uj|K6AtVW+IX3aFdoPtt9m;`|3dEmbw zv104MoKs$zg=*(yfeYD*U+L=izCA>thnda^=A@NQK&xk{fe{@0T10So42BuM%|PovCUW;EJ~0! z&K^T~&F>v;D?^`>mG`2d*>MuQGPO>=Dkz2MOarW~^B^yFyfbPZl&=#8Gj?sAmeeMv zx3@5r%s|09a3a7crU4if%%9EZ>g;uObpv(l>iBgkW1x{D+KgkyaR?v~&2KSQmI#!_ zP$OP+&%<)WLIbC?K^QWe&hqZ5Q*$QZ7Xt=^g(W|n%Es&U24{dNtbBo)E-X1XI1&Ja zX%NJ}DOh5(@@hB#6@L63H=mM*0`p9pPX$CoLjq%K<-;)xV>9kl*{W--`Y16)Cp?mG zyf_8t@GZ8q%)i2xO6AoW%aWvlSE;0EI}(*> znT(?bVdFy0_%KXO8zCcw77V)*H)Tnr0pBX~(5OsU_{8fu9k)&#KS$6$iRMhh3lijk*P7JySMZ2g0s_Kowb z`i`BG@va5zV6yt`Gq4bYYbExD$KznRE4yuh`Gk)hz^a4KVO{2ih~4Bln{}kuiVNW< zMV{}(>0rlY(j^H{EH4dC6={M1BoLkH4UaC_cJK@tzVj~6muL6iNzUK2u=9px8|KVh zgtn&d+G0yi0!+R88PqM5IV@`Kqc*QjR^OeBjxFB`I>&QgtyoW9wPD@Cjuls}zGW1G z4avzrCeQMo0DE=UnEKP(h3jq_I9vTW8G6I>H5Tzx8Xv%6A?A&sO3lKmc zHJXu?LhzWC0zNm33i#lS5MYH4ths{9ZcgQ;C!q#oX$g*cp=fq%fm@md44XH<()?%T2v( z^ZCF=>(=1mbkJIC&eUl8YHj)o!Oo*cD+~g0y$h1mtH6CB>V^5}%K5WMQ&;wmM9)2C z4OJFNjhftX#Z^H)qoTq@OV!7GX^GVq1*PlwJ7nOkwN8*H~gGZR!9M5J`04|}Ne3AD8R6)-q>g|E5IITDoWYiQ5AF~DpWDwzp zhK3V%Nn{0q7gho%1?I|R@p+6=5ETx!EVL6R3V%KF-t*`@JORwc7x{?NC#-Zy%+XVKL+*OO1q zdo--VWU2@+S7k(s)0KwC^u#N-eSkza-Kh z&wm#^g)4TDkMZAv`yd1lXy=#7cZ4zuiuV!@$R}Wo&A_s*1ZgE}B|9X?B$UL?WHCVy z3{jPDG?{cnq8v6!eTzY52&3aj3c^GtSOYt@kKh=QcR|#}cz4+n3F3y5mA9r?CyR}# z;N-;N9HbKX)1ndSTQvCc<}HD{zR3e5;Xo>vz9yK_&5X`wz%SEZL)saYqF zcA1?ayJv4fc`ffBn^lfJM9%%at+64P^XezR5(uCcDAb|_dQ@jJDM3k02ooBOUIN3B znK=flV;*zN_!5X5B{@Wxs5mG^TbQX7;QF8ikV_3{@Tb>KbLNaWELgBEd^upu0wr7D z1YiI{1dC4G67yGy0{P`J$X^teyiqQa3U`Bd!^$sM^AUv&9jG#W%Y5cNw;5Ck`lbGDr%>an^j)A1`UimGE z1q7Nr3|1vvgQy(#gtgf@OgzODhJpt@6SH8Ki# zFL%iE`J|X*MQM$ej7;q8+z`IBGQHc&j^Y=^9f?`}T zl_A*+v$lJ7S2QrG7D-iP9J%3|;h?_y1PLE_QRRnxX{mV`e@)+x<&6(}ZhjY69s)XK zt?Miw0(4>d(72Zm#d4L^qkVB4TwY`d5%T6qf9H0NUqxbmm8tM$MJC!kcS1^ZY(*%t zD?x=)Xb7ebHey)Yfd-5QT6qCPz$T0-$6-+y`HcrZ&3WcD7WUb^4Q!T2z_QDAO|SU? z)_CAoSYYul^{^HIg#Thb;Pf2Ud>{_qrGAJPkua|ThQE~E-N zj>962wKzb@DWXT|u(GhFqM2(QcI6zZRp`t{ube|iuss1QMm!!5xbybO->B1qAHWv_ zBC<&)#F)U?m37MbN}e*3$&`x>x=1M1A|%02<}_5Ml6(SNv*1+#G8u4R1D`_+ENF5Z z7?4QF<}!ef-gONWK0jTdu_kn{xZajiA05?bTX^Q#K`1jX^F=%sHRcxc&xX|3KmxFw zd25q1Y`6}@pyzGRrM)Selbv~v8fz$o_dKQDOE&J!1qRCPCcnwg2VKnw)i9Z0*gBI( zG0L&TaR|*8Wri~XSZ5xFqKX1o;0sQJI?L`ZgSQBqy^94pCtk5{%uPtjf7y42LPw7W zs+AV2QXLi`ZBq}x?y~jrt>?aBDy>tOub^o~zTrlFTvVkjP#`dNc^2M+fxaJIr)Y7i zAK>!=Z{tY0;5G7Vcq#Ccg{|c7$p->@pmt6u=mA~C2vpE91RBu18H{=n6G06!LCMQZ zO!?AKQ<8}!W=Lj`rWww>ZbsAxX`<3}d7`E5q!T;E;Zm;W@CtxkVZq-V&=E4UvDI90 z9#P23z{!@Ze1Yc(2ZmtG!#|kmP3;)KcV1Z(A_Q48$>n8s@U*hc;Jp-xf$&$_!TZ^y zx86G#!LafweEg*$*YL7q_Ye2Y8<_aGEJK-;lGnMiVcRXXB4u*2vMA?%E5N}DI`t4hs>vr&xspyDn$8?bbGHGo_N?lsAQkj7)R}S6z$g)-I zSKfPYWSi%Dfl6sJfZ!kkn-rO$Fqsq?kctVR1YO_yU#@*>2TFLyR_A#d*Y8QU;QBpZ z=N5Rb_$Cj^_Y8gUe*cjz4jDT5OI(#bZMWx}(LWY>W|2_`XCx;mRAsq3BSd-jz;rF+ z1%cKqB%m5HRCh*v*!V#rLXs;v_wH$=J$LT3UYCxfa-LK!rIua#nHQKck;4m`h$5ez zumRShQQ`{TUdSoJBZ40yK-t21*R}AF0(1!8-idF>h%2Bz0g09ni+FdCH?w`o9`$tv zeh2<;*e9SH-W?Oqljamp=pxcG@in^O!R!z%Cssf|`-ni?k05~O>j(MF_aHg(_8uG< zIEa7IX6|?pdR|C$LC<%>lTn21(I6sB5E>wZ=eeHWg?F9ah7iYYV73MlEANgwmoL8) z|EBD5yZ7Ku{dVgy6^my{)7&Qe4E>)uP&R4PBnD zJq_LjkahdS3F!F^oKX7&mih$3LMFkmTZeELz^6zE6?i6%I?zSSX=ZNs;pRvBr);f8CG2? zO{Y84+w@WPbd;vFHcVWVyP%~^El)7=e$-acjx<%9_WtT@r(Uhfj1~%$5-t7u8dGMD zN@bF#R4H{c)9x=YRnu}>*(er=h27bhRdn2%SXh_5-<#C_b^<$uY1_zbb4fKwFY z$Q1w6^O z2@^qgg1n?eIz;xVfCp!S689`gl2D!})Rx~T@`sKimZyw~DC?M?M_g4h- zUV@|WL87Su*|!p^D^`O{TnluWxk=#8;Bc; zn~43y0mxuF4izkJCT<~aC2k{bCk_*L5O+e=*Sm>(h;uLY3c#(LCc$qju zyh^-Aybd{+-Xz{4-iCOavrw_)9Pu9UKJfwZA@LFMG4ToUDe)QcIq?PYCGi#UHF2K! zmiUhNfw(~YNc=?nO#DK812L^U;#cA~;&-TfdXcz9Ob{Mo68!NHu@6zi9SEX^Ad7+s zTph#+awwo+6oNvL1Y8!wz=zQn2hlh> zglm(8K5v^eB1^Jq{J+oMXVJUp9C{DEk3Ikm=_B+p_;P)UK0}|QFVL6hEA%z`2AxOWqVLf6=m&HG{fK@- zKcipJujn`QJNg4%M3>M6)FYV$)(cA`M95Gi9|8b`q=*b4q23)CLirI2qj zoP?+lh-Zs}$cq?ozm0>Cn*=hEOd@GgP9~EnBtt4d|5rj-N;-rws7N*V9{-@3R%b$jQ?uuIUx9jdvDJ?w$1h90RN+-)uQbsu-A^eylL8yXLAE${4U@5N_*Ln8yOL3jV4V88`3TRZ8fB;AVw``QQk zhlU6HVcuYJ`Y;fOT%G-W3j*2~y4@zdAxQ1<_0{%4Y=9c{)o5zX0H7aZotjn z0greGJY%ZGz-80UXHGj`F?G%#DbwkU?B6W*Z#ExrvTI0Oh;f}oXK}m#R9INbUJ7)w zM9rP|Pn`#}_w^6EdR*>y!HllKc3=_9xWf$gR>3m%5HMqb+coGKat{S8^PLH1ayPDE z4*`SiFbnN~kSy}*EY>W2fNN+N=6u+-AON_H%iYyI+#NLB4U@*54+SoCFZG=V4FP}Z z^L`QR>x4yraUrHb_B5!JBSH3qsC1aS8sO;no&`C3-I!9io13TIEOz#~y13h=Zn*uj z9{6kzR1r|A(AxvmhB*NAK;g#uRqX=3=$T~N#p}U{o z$nu4z_7S1CXI^o)n^!mF4#I8tdJOe`>H92ZSq%5aUJkUFf<1c1k7+4X0;l2@axm(!Jy)AFByI;VvFul;*GOrWf6FTAd zV;}`hhfnCAIuG);!o9EeOZJ19eV9FEaX_!r8H~QOY`y=?;6I!CHp_o4+ka;ApPBt< z9BYJ@v#q{sCY}Gx--pT9hd#^Sp5EVz-rtJe--^NCioxHC!Pkn;;D0}ZzdeKh{S5w= z4gQu5{+5mYmW}?FjsBL6ei#`2eHi_H82x=1{e2kyeHi_HWcm95s>90&Kq$-KN0z^j zEPo$UaLMxbk>&5hy9D7@{C$}GZ)Ng7Ve&s=^1qeI|Ag89R%ZXZnEmf!_P>kS-?G`? zvf1CV+269+-?GKuvc*4Mi@y(xzYmMQ4~xGKi@y(xzYmMQ4~xGKtG^GczYnXw539cq ztG^GczYnXw539cq^HeLoJ^;Sn+0yHL-|BU~KJ+?YA9|gy553OUhhFFFL$CAoq1XAw zq1XBQ(EIzCdgpB4HJz1v0!Y>StVwUoHV7&V2A$a`sL)%$a?c*J_3XiD6!#Cf`Z`8> zdR)W8b{DriV1~hQrP7hXepXKgUIAc2VchUD`J-F$&qC4l;Tqfk$S8gJ0m>D1G%#NV8_E*^AY{Nn^Y zb_g`q9?)cm;Wr=u=;+Jaqa^M1GhKuCzS>wg>-WR;M?L4pM?(vAqvUb;O(!G5w;VaM z^^3zN{+a#Ujn`~GnRK$TWv4FK|E`FFS6Y8SpQK9=@R})ccw`HRcfj-e=%&Gup<%if z40HX1i}g`D8NMMfJj8c{ns)ScYV>Md2KPmZ?+d!g-Rq(ohueDxVDY9KU4u*Aoi4he zzkgVtr897Mt7@HewWF}eQSE4&Nf#Cum)13vmZ<5p&UCAp_BF-zp-YSkwwiU>dYC^Q z{A+`cR=ok@6}XT8`vQ>3nqUA3vkxe|? z`b+xVt#kKM6PX>-*7flxm+XE$xmEl6sR;g6rYCmab)=^9%Wrd%?`^q$jr^vbjmIm? z_bobdyXo~y0hzBJvEGO+jA;7n0ZQ=Ty=>B(Ht_Rb`EuRGRj=Rq(>*IL@h|PkTat38 zD((HN!(CfE>P=`z+YKEjrH9x3^ytxuN6)lezgW~!`s~fOy_3C`pZwlnCbf}&_=?q3Hvpd;vUGkQ# ze=HC&Kfm$^;O}YpHIXvnpVAxNDLya1Sk`*gmXl?h#}wa2%>UCH|L@0v{}GAr(JLWK zJxgSXJ_7jfwB#e#z`rHe|4(%0BXaRyh+L`*#V;ld7diTdU4wnDVcq)u(`SH1>1}}0 zn=ne>-G2Vaz1NJDkG*?DI@kTKcx}g+K!5th$;~^<-gMY@fBBlAVE?^0FK_$i_e-6n z&c_1#bl=@#BCAGO@_^h=t9wx8DC(R%xv$*xbYzI*viPrY4U)IBS6^~A#@;!S@!FGBauzj*z; zTip-6x@thxk&;+K*WZ^Sdv2Kg-Elz~JNurEOR`0(Uv|9r!NYsM*mk(;C~J|h2g~;KRRYF|LU#Y@}-|1*WD7j z?!~ol<*XV1eNTp7CHvz)5$Dg{|7COGKv|}GjczpHcK8j2oE2bVk*rv_x9`gPUw#CI z_3b}?#I_3~Bx(O}HBW?S2Iqfi&>|L>R3m+4BlH_uzPY?)>$EI%N} z_h~x&d$ofuFe|u+`v+HOi|ZQkdec8RprJcf&<(DI8Z}-&G}TQdc+D{B^L4pgJJ}`f zF845u+EGFmgVkq}FQ zV0!wrV=5X&!310vk)vRUJu>!6>KzL{`&#z&Wbdj%r}+2&j3qB>q8o2Fm_B%|`@`%B zN7!3?FS%Z7jG&KF&#(OX`GMZu-<*2rz6{+BhSn<{xpT3i>-ys#E&Gc9>31LR{q^3! znA`u6d)2^4zxB^{uI>+QDBUW1)Aeo+&Hp&>P|rSFNT4G8y!-`vyLDy9mHg*ZVlOr9 zzh{5--Zyh=Tk}R&eH)P7@^JU@qSBjl^tW7mYtO~z=hS!H@^rfM#h@3m-hxl>A0u*A>5QTCwGxh2p#F z|Ckt*U)nh5*`F#yzG-bwsd@PU+ky|m56u0~hTiJP`|^Z9$hVC0&*?__Z?m(L5KfUg zLKg@?Pk_vrJd!`ITfZ59Le%>98c$!R z>>eH-7_w=#{{vwh8s$B+1A%LfrVD#|=mvbp5HO-4kZ)ZJ zG<0!kLsOxnRy?Dyp`oz0$x+%!mpB@Ws|y`9r6qJ>ZOJrwx7tzT0C86%#&_2`YRheO zQ$;D=+*nFG%iz?}$TsIFa}*agmD2FBv8lmP+*Cc2Zfq{9EG=%Lo1FL&aZ71~qtQ`b zJMDglvzD%FC@gMr6qmwt&_GRTZIgy(yKpo%HbZ}OVRKW3vjJppvF|0hE@1?;qo%If z;eF@Q*1Cq$#zuN-Q~-q9;_BuS+{)BdF}!z8X+v=Z4BaQyI~(XSM^i0+ybR6@>AJ!O zc&X;u7Sc zc%Sitn|1;e8t9V3n!@tZMh)FqS}Mk%#Onp_w4@X!rMeLyT?`g9z|$eRf8n2TvCBOK zQjKc?-PhlT(Q2XFwV;tBgu-EN^tHR4-L>$3h1`=_seK5Xv+ z1FNRXy->IQKFmpIYW-o|I^8-!;QWmhXyb3Cuw#edLYhDXS|*qKoeuj)#OC=3N(piUK$c@H>`LtCDRhs!y+cFy3anN#<`vEF4A0)C`1kGf_dSn2w5n{?frBfbSR$y9g}F}6N&l@r zXUmcYeu}Uxe`m)(0@s#TM0wV)71f%-3(vl~W}>7&dB>Su z2S46@{_{!V`G0>q82|Q7yuL^N)w#;Byd>wqhOHN`+GtMGe15ydod3k7A4gO4qf{>N zU<(XgH}ZdB{rE4!;AKXG@%7K@V*EOL08c-CVWB_1XTO#&zp7umj%@JLYcKNvC1Ay&d+>hv2LR&S}`6 z$5x32a8?FqeZ=sg)O8HTGVfZ&+GMe;#Y%C*D+c<(o<7jM;?KekH3~U3&m9@M?$NgT zw{s7FvXhdAFZpFz(SglJ{+&28bKQ%-o&A03o5`I$QFrWrFLx&s%s*k-aoq=fvPb?g zZ{5E?{^-Xgqc8k^f8U4cefAelMy1qPYY(3MeP`X6eBtqpugmLhDUv*lLf&in=H&C^ zN0&#<_%vu_{27(LwDgDB+fEmC?af|8xHCSF%2PfG;?k z)b`}MQ!{TFsC`8K(L;)&rmsrQ{=Dq&qPLyz7`OdO9bNl&LC=HxpDB)LI`+8o)h~Yg z>U8P*%br*zxzYCZW3I5=635;7?&numUflJ?@(*r(?~i(0@>N8}XwvbE$ro(&m8l`; zpS$6wMZ_P+S~eaUMK6QAcWP>u1o~0*Pq_3rM!)rs{jb+-|4u=_9EE4Jh7Pha@% z_YmQwLd!42rP2Ez*T3}T#I2LJs^fRdKK}Ul!k_Q^@Y<|m%Q!ip*J&M8#~ag oU;Fgq%_x^tW>d$1@r;juf=_^cg5NbFD|g0kH7NF z1B`$5UyK

    FZzI_4vne^BGIRy()7>*MLW8R<@9EUWdV+ZI|%zh+)75*WMl@?U;O z*P-6eei-@Nv3Yv8ZVqmBqC91wp4L9n4j$`9{x`9VHsX(tr_MM0eiMd+D)s)WTL|j9f;He@` zTv~a)hyz1BnO8;QoEfFgXk21usV^E=umovSG_FLM-O;#;d8C`8aW&G1qj3#eEj<&B zYgxXmd8G~`=~47X)Ajrd#nx!tz?P^6qH!bZRlOCBn+&h0%c5~Jn{PLYxSr&)%k3CQ z7W-O}ZWQU;MBFUmG|pUUMciz^LBt)1+wFTq+$qW&6mb{gR{QfJ9w*Y@5%GA$&GwH( z+$+j_DdI^~#vzHgPsGh49;EV)1QE{?@pOu71go1(cdhO6FYX`MxO&;r-nIVp>T&+O;^Mq4kcs||-X4ET|H}Tg8wYy))%~jn z`d4?YUDm%c+h5t&=NC2B_*eI==~=zLr#suv^2mrq9&E{?*RB(EcjT4e81pwElPEP>mH$x)$BB+_p>FSBz+I+5LYWvp8E8&D)iTd zQp9OGYd~rrYA-|HQj{UtrlMXqxI4bb=_tRHtrK-upOE8+4r2PqKOtup>a0ea%c4E! zqs;*Wq|qhF??E1Es0W@f zFcI?5=+xkzBwdO+GLDv@&T8bWjiTaTkH#2YsO~zn)QuK4iuNnf5@CVv{i4M#+{=8f z1lOzK``PJ&?=`rm@%AH7jb#E2OOU!4_oU^O0vXi)iM*~8HRKY0A<5}TA=D9$X)H-E zG06y5guFh{BFRsPq*h}sP_E21%`oC-1p@WHCMwkc;(bCUl7e!(MIWR!84Y86_o74$ zA7i>8G_QuHm2zGS@K- zu13Fd%0e+d6yI=MKdr0{7ORofAymT-QM?V7)el++I#s0CB4q~lMP#Y!u~VvrZ$W59 zc@xu%Kz2_as~CdE#w?aDTgCx_QW;BBHfE{*y*W8HJ~W;*UNO941;E`#=zSfoa-XDG z86`5t<@rP?9-EV7A88$-wq%=0cAxMpBZCl2y^>|186QJ0&G@;|-UyY{54Eree02$J z%YBZa_#ZVx_IL@(pN<;Tx*tKtsmvqUWJ)J{FV7INKZLBGT47?ghOAf*YLLE3(&MrJ zxN&+GEk&lJ_%XdmYH%xaQ(M7v2v)lQn}*fKNxtIFu;DPOk`QMPi3kj9pUkXp41G?EF}c?Z!HRPFiCZAx}=HQY0IV*uTGa$1Hb_m@Q-L!q|#U z>!4pqHx>QUIbtO!>6c~)%`94bNCwioybk%Xf|AAE6wO;BkhvK1fV4n3pqjL1Q=J*O zleu3fW(~DLQWKhK7S6_Xkw_u=spS8C2}#O!jGU}l(mjn0S%5UbtGp{Ddl8$llq(}X zHfLq)N!FHTHr1sSjd+f=L^@d}G)?0kYl+rI8n;-zAKQkpp5)UIt(jy!=xjwj5n5=C zUMJe7v`wSDtwCxZ%FAi8og=*-kDC82ZPLn5GhN;}&{)gkNn<~zPgoG*e(*C#fCu@twGln#pahnjx&Mq5Gl~F;vciL%?-6788bBer% zk!_)T${|Gml>CH8>WT0vuZTa^18E^t{hkLM{(Ls(5`GHc&bE?t1+VT%KOjj{FIb^c;YHWpQJkJ=^LJdCLpL|k7;qm z6Ka$>(V?6|sZwjSI=#VYGFz-RyTj>?wyopK4K7UGTAQ%d#rH>n*k(rg9lbe@c zFrjc_(WK(ZC8bl!$}1|Xs%vWN>KhuHny0q3wzW^2KBHsitl4wso-%L#sS6f%V#B<+ zyJyML-et>A>szt1e_++>HEY+cKYhc-O=q0B`K&El&pzkeZQIW~|AGs5?7ZmWOD^4Y z+2vR4zVfQ8uetWR>u%dNNFe#f16-F?rVz4!k77xxYB8`^*W0}nnl{P2NC z4nF$W<4-*K)YH#A`^)E^f8oVnz4Y=cufF!{*WdWfn{U1S&ToJB`$O-(_x|Azm{Mhi z&lDQf0@6=zr}yM|1ST%DXJ7lN?b~6N;oAuWkJf7DR-wzsp?cqsy)?}nvm*C z9haJs+K}3n+7plh)<8;#g`|)%WDPk(o={>a7|IMy2$hEVLR&-ILKlQC3SAMpC3J6S zD0ConF!W65SD{x!zYYB!V^1;y$e*VFZ4=y-t`yk_k zkE(orLh z%Da=_EqZstyLs=9e>d=M;=8VQr9+<|`t;DphyHZv!$WT$diBtYhn_z4)S*WhJ2Z4? z&!L+RH6Lm?RDWpvq4Yy(hk|%N^thN;2dD=L@0Te2w3C)d%cTuJo%hdDrB<}qD&ZXv zIcchVJy|MweyWCq*$;OwyNzvQ+wqp;D)wLOJa!4&$!^5^nA`C#X$P#rx$FwOU;2t& z%&uk^a0Pph{gvIs_OP$nQT7eHmHnK(z@B5jz|L(k+XY+oD_FGW*^BH|_7Z!Uy@K_8 z344RR#(s_WI!oCX>@xNi`we>&EA=Pr2)hu^yO-h2N6(B_vYTP&R$)g>&#`C^wI1ux zU+}zV6YS|3Y%@EP4YOO=7Iqe9>)Gs6_8B|C)m+21T*vj?z>cvIZsaCz<`x#g%P%Xp zv5z_DcJAO#?&5LW%{@GxCvY!M|4AK@^L>;;i){pgFM8;JdLOGaeO?_;F&xN zZ<^lb**u5m@;si;3-|S5#GmF@Rhuu{fYgV53qOG2kiIk5PO#$X1`_cvmv%$ z3Q1x1AbW^CBc-wX*#qoZb`E=rozJdipR=dg9qe+cf?X~(3EbeVLybOl$k z>w$+UQGXh{9o&2>U8zV@G%LUpqWKQ<5lgA%7Ry)G zYppNYBwMHLTl*CbgQL!|%5k;hNvGSH=bYwz+~sktay=X8i|dX1ojcB5?LN!>w)+du zIi9EEb@83?55)f^VMW5d37>jbC3Ymfm(-DTQ_}az?&NjJdy}6|{=ILB?@Zt2zCFID zeDC-^^DF&{{(OIv|0Dl*DOT9#vXmJqy(ybhcBkw~c_QVlluuKYu+F)ub*b}H*QV}G z{bOKZ;8<{H@aMt5hGvJ3hEES4O>?JBN&9)aKmD^ zl2x7cNY+U9ojJX^QtqPMOLHH{bLQ>H`!at@{*L^23iR;)f{6uF3m%!!G-2_CGbcP> z7*|+U*jqR>F>hky#IA|Eifl!biaLv)nq-;OH|g9-KcDn%@dw3!n{1jKm|QY>+T^8^ zH&4ED^4`f$PJSEyNQt5(z9grlwPb6_%O!s-HI@cT7na^#`q7lYl$lfRD`RDGWtnAF zWwXo9F8ipwzkGZ7_2pkzG*)z19IA9yc2&MzwWius{b5aUO zwl?!-cXL*Ab@SZj{^sq?*EIj4`I+Y5O$|?7J9Wp@pG|#W>WfnkPyM_u514r?sEmes%lL z+n;X#efw9_bkmZj}Y1^hW5=Z(w|5-qc(vn?9pBCL&n%lcf9C3$7tFkA=KV9@ zm}Q%lI;(hA^Q=>6_0Kwc))lkvnDyA~4YS{z{pFm-Ip@rIe9o718|QY-9X!Q#%KB6O zIL|w8@x1fr-8-MnFPOjg)Cs4)vLJWCtqTq;czwZtEf`toTsUrF^};(ljh+3SFL#x6 z-P-l1Ma7FwU3749;o|%F0O zsQ3Ba!^^Ul)hxSVdDZfH%hxQwW%R+XCB)x3z8S*>=XZE4J<3_T;v=w|%kQy}fe#{OuQPKeYYJ^Rmucdw$>o z(*=)T7`*WN9nCww+xh2pQL=xbf_pSKWH{t=HcAb)sIy|l( zL4%-wXEV&0v|JnJf!5i{*f3gMNc|hk2m6EFUzF z6@ccm36ZbyRF~)kRtQ?iCW206MW98XNAX;E5@<0i0iDcBK}$rul$Axk!tSUX6bme9 zxrkS=s>qi(pA)TO)u7d^2DFCNg4VLS$Y1d;l4w1v2W?;tpp9%QXcKFWe1YfAEud3b zD`<;|w~BZhYma=6=athyr?Kgv)7cEr8LT7n8QxtIoylf`&SJAcXR|q=bJ*O-5xm)( z2YL#d4?2&X3W`Mw^i;Mm@+n&&=t9g={D24t5dfPIfWqMeLHuA8^hgdI`G} z^ip;i=q`3S=w+ZEu*=yMpjWWnpt}XVl3j`TRqX1>VVsbz0lh}hYuUAkU&n3$y`J3| zc^}`q-2{3g`x)p>>}JrPv0EbV;nYL)7IrJ>t?V|?+XTIx-4S^gyY)Lk?__s@-X-YW z>>kALVS6Hna1Q%9=w3nZWxqiD=j=YvU$DW*?{VTHiqi+^J~jl3(?R5SY(Kjn^nUgr z=mYE_P@EP(A7aCi-{Oq*FzCbV0O$dB5cCoDDCj}|AF+m?^PaysTdn)oa zzRr6Z^eOfX=+o?3&}Y~$L7xSEi~W*42l^a)9`t$k0_Y2ZzQ|sRyood8%b+i@S3qB8 zuY$h9UITrVy&m}u&W=QX&E5cgoxKVA274>=22PPg-(+utzQx`FeVhFj^c~RGaTfX= z=28GeGB?`_8sWA?1#v&aQZw3`aK%~{eeY5j|n=$S>#2W zaV1dMrtANSO($#qADjLko4%MWK1rM22iyH0n|`8Azy3cq{XaJS|GQ29&p!P>`*eAq zezG?GKl}9m?9>0VPyhe2Pk>Rl03xyf61L={7ci@C1T_$358N^Rc)1Tf@>++W2c&*9-+#Y!V9NyGLFqc_8az|+Nk1Ff?L@OT4edtjyl1GV0CyJ- z_0XMTsE6`e_xGgx+AH%Xm>IgaPEf)ZI4N_@M>xndlf+; z&8o1TH_`VXg8#gV^R}M%#CghLX?leX3Fqye=wo$tc+zFJX)A`M#QQxuk8amv{B``9 z*)G0NP*p{oX4l7>UH52qou%2eP_t{EX4f3eu2~ugSRqZoBMzTbE={5OOA~N6@Cdi#ONl$Bi915=J-$=rk~7e*Xh7N~<%@Q2ma>pNb6Cn7 zO7>k-X^SS8O4)ec;7WIPL7i2F+s zeui)#!s7@kW&!mfNZ`~dddrb=hnz0z4KX}3EECsKDND-U?<~{xSK1-W7KHl{K1WcZ zk!&=Q&DszK!Tc8xL{(uSv3RkyG66|`gm#2o2ufCtg0UtJi9+Af3k%dpH+dp6Hn?Ed#8`Ant ze?&^h^G}~tJG33xm1_2HPxl=@AXP&-)%%gO{h(ZcACi&)oTbCKDjYPD*uQY&fEk$)0z9(-akYhL6Z{ANaAnCqvVGN=kv@j-htYwoD> z3_29eQuBP}e?h&OXjBnTymx>4IU-I_3=XcuLyt9kf@^d6;pY zx&2~q^g4HLM$%w+^Ncxz8(p(mo@sG~KGgt6(I zsHp87maasVik+Q<{y@#3h7zudCZq;xDk^HKt12tX%chi0Dw4Hot2p}eq4H5 zI1~(|rucoyNr~Qsc#k{I<#gC>R*TtWH0X6&jasEtNStNX2I@NfgW=9WWjN5#kVW@_ zE+ljvmw?WZRCi*TK|j^&Le>c-D^PODk4jd^B`Zcta;v|Tm1br7YXknlmumw4VSdWA zIf!3e6PW8CJR;&PBCZUJ8xw9)Qc%NR>*=lW5Asfb?O@&d-W|1_HCdT_pFv+8sP55c zWwL#G1EL1R2I~R?`*>X$7ZIthcJe-nX-$xEuqjYeJJ=XNRWzdr)pm6cwojW=TjNbh znVXe4$g39z77a2Q=?qbXRf}#0)zyO<(T#uEAjDxi{rfVX*m2RYl`ZPbFm?yJyXMas zRCJ+@+Cf{!U_HjHe$z*utjuA4XUCjDUA35>53{Do)_sjzYij0FZvff(#~1f1cGP;7 z`Kk7f9q0Q8Z=N>ixW>FG)a2Z`Xf!LcdHS3ba2=?<$WLNSpCcqdqui4N#wm@&lm+ey z)KW_4a{r(%P!;IivAh$5m9S%wP2ZR@l+aZ1FrMNx)%tgI%n76nmU{zpyJ`~mIoXcs z8}~O>_#02m$;#YkwaJ>^XSPHmM$_?;9*lyVCt{*F#lUq;)topAG!9k(V~hRZWKLjE z3QZ!?Gl}h3JP9KLHr`9oET^Zcr7n2K+m|W&lFq$fqZ!bVXCtA?w$SG6^oD zkQ>AYL{az+W@HSGA5TcpRAXqtS(&&m%*tFp*c=$J`Ujh#GS)r^mF7;)fyz@-Xq0yj zSFlC68QeN;j(m?lx$q9LiX0dSsgrV^h~>CuQqI;`&S>?{0N{MT_)5+-s11+)vsmLC zwY`%EdE9@K-6Q8?`qcXODOI5z?Q_CiJ9c`*ojWd?3sl!(R`1wR7x35Z=-kmY9ND@k z;I{^L>}zh`F;I)yD2p^4Ik3|^Sa;FfL2G9(hh7H@WQ7bms^=)Y5`hyj$*UklVMuBz zba%oYEhlI#2Yi&c_;>8=K_pOf5e;Sy%~M|68>n5@^{-0p*iqXZsO|3Ru97>b9<1m< zAJv1b;}lG!5N2mZR}FM3lEkHga+D&cvj#Rn^aey#6K{d8=oIFoDV@<2B%m7pHAXLB z9&2TaADzvlzVL52^28(xbG_hW4&`9dN+Nl#H+p+QL2tCuTsWB(>bHkb3zbn^j$%8m zo*_aiuBoaVybWe}qs8#157$U_WKe?QLmKaKSfo4LXCgo@a;v~Pt_SqlPmID z7^Cn{T#%LHz3oiA7o&HZpWuyZDc(~yL>|Q&7~;G69ZbV_W5;5|8{HT19pAT{DV~Zv zfj79-cvE^E-s~LZcEzocz3dW{GqTt5mEawCgJ{IN?h5uRd6V@6Nt} zR0jGg6I>*s?IwKx*a^S3z_4MP7jBwD@)+iN126uNyF)>G*bmG>NzVkgW}G`SDgC@8apNRp{?B$e&Gb zqk*;?@lEa>@V}t9yLeaoC?t9YntlcEIuAk1c;|>Wi(lcrBHkcE;}Tc!Bz)Z}f7=?u z*Q@l+Y9)LfMxX`QSGb%W|7)e+SX>TT+WG*-=g&Gnj3v>x<-2WHWU?i2P2uR)OW8X^zj3y|M3 zedHS{4_`m*Wx04aOLwgz{ac(yjFF>!7awLnK=KKgPv_$s5PJXp1G|d9j#1vs8`*BY znVl}3%RYw=dihKEYWP8X!Mh3gJjj~@1y&@rv3nJFvZK-_b|+`-Z&D`vqtp@kv#MDdz_-_5@*R8!KF6VN zt?va+=VP4j#W)V)o0@X8{3)NzUO{gaY#R{R!KN#7_+Kyr$@m_nOe&S!l8OJF|3L~V z&roCPlH<$dfTL-H^fe2rFejB=Y@%u>t~anC>`V|(Z8{KwQaMXj*5EKX2l08x+r)y3 z@yw`fVhsu-u1YphS;k5g5yYEWm2xK1QxUJ10<3Bs=6LnMY+J{)wlb2!coI_qZVV%ZvO{%8Oiu@c1Zi$CVM~ z!58s18fYw^11|xzhwq6L@8kY?#4+~DrK~|+%Yq_QgZI7cYH4reTN*pn1K@dKKyRqLwy!Gszs2VLRkdDCIxCwag=3~-ias9M*gNO zkNlZmiF^d*nHbxR2y=1&6mW?;R9_p#BE}*>{oy*5#zo+-HFAs88hH`n*8+FoLp>dQ z5e8|zqCt$s-pFgv)qM!hL2r{0-at4PVHJW0;RfWrrm*4nq8gc5;1<{s7=1PJDq%#q z0qM|@&?)2)I47(@HiRbrHO2(+G;e@i;yc#1z!>41uolC) zz`ryFf3-p5`&Xf3!W?08>{>KhCsr48RMi09X0QywBVm_#ja{dU`x4yeiE)nd6XR?2 zin&em3v=9zEB;0$axU<@2G{Fw-3k8HxQ+<@qnt`Y`4yOhcSgRze7sE91I$Ut*g$rH zbU%7s2R!xTz8BYClp%XTbM{A9)fA>jn{pnFCE@bNSJ)Ps-^vrNkq<|8OLm9G54MNq zKV1>T6_3!>0vj~%2qXXMil?w-w}kB=yG0l#+Xed(yFwogu`!~#DCQI9Bk?ZnVb4l? zBHtnZRKm7$YUB&m^2is823&p7Fa`SSj|_`8V0RUI$S>o)gZdzwt6Ts*6MkTGmH7TK zW^*A|iqH?0f$deKMLrhtf>(7X^O3z(H(+jUW>YYZFA#n)wk66GRsj8*p^pY-76PRe z;)?mJbjtY(JM0O{K#r-ga*7WlBg!I-BkZZd9L3Wq&?$|1Jj#z_CDIqTN1L!MQxxAZ zr|Q$lh`I*+_eXv!`l2zVe54UZRZUE{|2vCU-;OKwHHDR^&&9PBt2xa_(pwVbdK%Xsn3u*|^&Q4b5B+UK8U;7PW~Nr1 zjw|G)GRi7kVLNEvD^>xQ)PEW)p|y$TlhTKNFh|r^ApRKSufvu4VyswA^V1FNQacSy zEBeOY_lUI)d6=J%(b}lKhN)4ngvt;PLT?%91F|bh&~_Blqt|m!#5mb;<#O2SIoKDS z!P*sG)~-ASeea9B1x$yqACS;?jlK@L-^oJCeO#kH3f;WSPEpN-?fZy@R39Ul@cVtR z_jq5>2L7*&UayJWBaPx`sGelIpr1TYpeth6h z$YtqD;rKji=Va24ulw)DrMIxwvRF{Q$u6fLy@mA#LCbiD<`bTa;E!FAKNJmHaUG9x z11NV61dEY(aPvx(gwFW^Db$Sjp?{Vw^(oBbKn>*XWG+*+fZF zs8wo}q);e8B&ABBBBxZTB#9y#afe&vqoi=S(HiJCp;yE5((-tT#|B#F?raD z5j8*t6@qJ7D9R_^34o+oI8q%{Ch`SVHDYY2Ez;fbjsSDqJ;i|)yv9PZ&=6&6v_jun z(K5kBsU}<^Sub!2{s@UCb|LmH5zJIuO?gqpemC_tphB9OTCJ`N{`mi9+f;9M}X3kBQzqWg8*<4 z8(pcG!7Sra1HK8DAQEOA6(&lWEs$Bz!BW7IOi1-L{G5)4YrX)3~H2B9+pN(haj ztYDYsM9e|)gi92l9+3lOi)O{Zk%k15)Gc)+rxG1=#4$OIng9+W8$-E(nCT))sv~rW z@g*IMIWg4e35nFXkOp%QW{)&2v@2AG8UUY83F(P}Xd7UV`XyC~E`VDdW$6USuyE;g zghMzakOHYKa?}*5Rs*dF#lQw0mrr^|sj+++LQLuDEWjarW(1Q3B3QhR-DfCb2QAZ;ji=!o>Y>h_7rO+T{>hxrA zNkiyD;8Fuz;^#%wcnU>~sc=tAjs{Z+%S#lOXomzm4wr-v%pkBWm4!%~i(qMSt`Nm&R=Kn#ZaOAAcLkBYM{~>CXHUN z(bIrYgR;ScBI%BBi$chUo@waND8$qwN=)hTF$OVi1QNg@Or}MPmb6%RC8L_W+DP@q z;L)o5Z#%-JksJ*cVg@t`2eHwWhM8>m`Dd7DEySQ569^cfX$%RWD(vqdmAE6mutbPa zC%H8Sa1KQSSK<~F%2vvSX_KQP$&{ikxj||M^{5=#tWk$t=oHG+BN@0v1~jBIP&sH! zZXdH&Lm&iPO@vD-BFPK_mnLvaixRafIG||MVedhVP@~i(;S!3aW=W$+LpjQTqgygT zQ7cbqSY30hoE@s3{DUK?}nq+a>}QIgt+;C|_^T zB9YP|9b`2i3Mo_u9eK6dByfoZQe)F;4fy3Dy;d@5$ZJeGm^4!8$vIj+OymfSh#9ez z!x0aJOS2t6s}5Z1FfGW$0GBk4!5~Uw3nOr8AS+GF5AAEn;NqWJOJYL(N*EXtlQf9> zQCtcokKz(*vuvhCL7~T}zA1q^f;zP@>d-qTs9Z{KM1LwW^yq@%qS6AFTD?JIrj0Kt zj&O;V6_UzKY9x&Ua|R?))lrAOXicITaM&d2NU_8sEfeTp3^#E?Ud(?2C``(zr`dK9DR01Mv+F(Xw(_O0xgv=ER+vLQuFA`0Hb6u zMsZ8rLrf!zl0s!%YOs3a{0c;f)Fmv;*6R&j~Fr2s5TNvfm)rQ;KYaxlFlR3q5h_$gxYQa=lx4!~r-KPrLaK|}u!b;ba6*k(tW8KXne-;GKwCI$bSWQl z5_g1K7$uWQhXoa?ChjpfxF;p3Q4L8XIj~i$wHkGp=0NJn zIXZ}2$q^b6vtWw}r!@-DF6DpJO6H5~HF*ATmU=J$}GN3@C8U3lDAq*JU5x7JS zroK(aB`iJ|#F7GB+GtRY$E7&p5Du^?0v|9{^eBS5#O57F0G-5OgC}r;N$M6J10C~J zTz14UIc&D58qG(6OOY#9AQ2O|q*erq!1tIl!4i;BMJ+A9(~{#MM9%CNbgym(aV~Y$lvht^tsS)5`-zP3iT>HS2WvhrSGC z@Bk%|5A+dk&1T?MOlW`3IwArj^5>98*<0+ty+1>cha`4d5pa(92B7jqY87HOyw=0T7S?^3V8SKXC3y)wuvS09B?=%5r$JO1b2P$Zcc_o^A1Tj_T{ulpYF}rvpg-sv z&BDF|E*d?azv=;3JK>UwNHT-KrF|5aXop1oDO}RPK_;9b@q?kTd?WS87A)377G?~^apE6Lj(gR)QH8JM$cj~ zSU_nE#&Aj8VFm%WInDU*OAxRO?m^Y zB^_Z-#$j8dwv!_?B4#t23DpoAUFn&_BjeJjHyJQsz$JEL1S66#ic7tPb`KZ?9KiM1 z=L$!fhEy<+Is-6;;-G{}$d9VD`Nl+q34_$w>d2KqQIN`Ek2mJ1JIoAhHh@dBz!el| zvJ$wUAq*H)jt2?`!X@D9pa%t{W5Ol&C3ptpkij6@6&##^ODI{R!XE<2odcKn9b16| z+B87j00|9}UTpJC;@Jp#j4=(h3yz6vY_@23D%J_YrEvHggQ&xlhNtl+q|@$k)LF;` z(F&u(1SD$#T$*T4O%EObAM^oy5EIZIbZdbjMdfH4P!U!XVH`vk7C?!zELs!QRH>~N z%rp`PtFag&*f|0WHDxeZtwt=E^3WKeU?@%Cme6M*)mvrU(xB5Ew4$gEOj%6ibvlP$ zp(I>t^&XSKW-tLnl0#2k??7w+BV1}U4swJ`#G<&=W1mU5bS7Bv5rPT^+iawryn%2D z7*SW)pUclat+)X$Y3FXx(gqd(bOyZ@Qeh8{1F}%Qz@>f+m$WPpE-`4-)acluFpaRN zBM6->G0mYo>=L0)^Z<40%~k`}N()vE9Llk+L>`_R8O#>FlW<8eQ^*VgmoCB)whfQ~ z^BGPov$WLGdHXnAB1f$;8DSu3pdkvHgc*~$pn2$i7T);G1 z4vQ$H8O7yjI$E$saS1h1=P-~;ywre+fdYwlXxD&I0f?|T=&X7xj@sY~#YuCR0ThFU zM>fD?0hExSw+dWhuY!dTb!pU0IEug-NsWX{8a=DcXd}g-hDI#J$Pu`O5`kO&C~k>+ z!X=7A3a!;dUZ-;!6o3UzNQMNn(PlJREGC6hPhRgd<78wsinH}e5PERwBu7>fF*}-s z(}Q=6EpvITz@=JiGFpt-$>UXuz$Hm^JTA$?Vr~;Ih0v4_T+(9=H7uDZ4nzQLDv^&< z3TG}$zTw;#0dNdml#VNacMHiIc6vpmX9_sMr`7NU5Eoux7a5Lvq=;RkNQzu z8VQ$%QCw1kn9||`f+-D;rU*sQ!Ew$CdnV2jdIPKz?MhTwJ544t6sQH@1U~>QIs^!9 zdMl3Fs2*)YhAoOkI{|L3lx4+=j+$x>7D75B&`PKi6B7eUyz6x~B--pIn-PW%4kic- zF>(mEG`X#4z-BX|64iql!Qj{sg#rXFZD8DmR~a%cy%wXLel*>ra2d!OTo&v>O;G5` zITIdzy2ue45p!6rgldD;h_3LNe4VNf_=g$76sQAc)7zDGJv+%y&@BR0V}9b&~n z5^RIjPPnw8bF9073*iz?S!{+lIy2JZsUR7!LsM$qq(*GoXpOc}o8nQWFqfDcU{p)E z#6Y7op1DD>GA_}xz@^L>Btr-PfJde3;s)+drdr3XPRv=JKJSreBa7h-Jc8@V< zu+h?pJsZ#j>jhjIROkvrAs!wI?PAFwWMMVd+YOkN&@nv^B27Vyn7uF#=mpy%=-z6h zLz4|!mT_sv1{384E~!%!sS&tDQznz$ZnhhZcF_{Xp4yagi@t1Vzz*D^G4ufLA*vl5 zlC8B_Y!*8hkAtFdT+`@`i58Q?WC4g2aR%~+IIGcw{U#l)PsY&$^*C~bOT?TutmMEY z29I#*P8PV-nPIMFT;lNs!H6WJ=ZPeu9sOd`0M|Ii3pS8%GTOm8;gWVqD2`DeTta?A zS`?QkfLoIuEl|2BD37vyD=5{+iiS-vu!n_%iedB|COj~KhJZ^nfb)+DAT$B4?kFw| z3NQ%PfJ+Ys1wep9J0vPS>WVr%L%`Hm)1R7BcWBgNw%SZ!m}WXQ@i1e84+LvdqxmSdp+&Gu#sS&r2Dr6TmK~daNTSg?9Ka>|GwCdPF)=ZqXbM{l zyWV7SILr={(LwBL#X^i6QZvm}I~uS%WZWW~P_A}h6rlp09jJ7GaW`JEVf?i^W3tuc zG+S&oi^6RrZ*ozwENlXo=o$P2B*H;5j8_bmm`t)qb1__60AfHnhD+)RwgN#e ziMh&!+ug1HSYu>Z6=p9 zF)`6-bR;+vkY=;l6Oz%NG0|(svCnCBz~DRa#LF3pC zI-Q9~qN*`x*5kBi(mU}7`e4n0ZKFFbKEa7*Z4d>5qM*%Ao^G8U*odfiI%1wUCg*k< zQ4MEMv)&4Y%Gn-VL|q5gICvY_$Ck}zh}EWRlG|oAV+i$-%`lpr#rjFnurFHl3f_LM08}d(-XyH+*utK zOOl(s%^Gy7HD;&FXm(`ByL@pTuh*>#+R594363~NTwKCQI$FSkBO{Pxn)5HBV|ucNJ+$^VoJc{E=Pjh6Yoh#a3mz?_2@1>1U|e@M}pUEO|YjXBp@$7 zF2NIyb3;dFx7Ui|@$u&Pc$3L(3dO_O+!pZfii2ga$9p_pCz_#d;V7Fd2wi2DV2e+1 z+Y%GP;jq=3fd8ohg)v^K=?U1ign}rZkl>0>w%fg0k0&7|P1uDxVUhf*PEW6oSqP$mH_SBlH-FI z&vml#S4J0HbBqgPuq)UQT%O#fthgfDXi2t|9?+JRn7+cmbePnvf^S{m{~DQTgSKxz_1kGDd{Zbn zl$=cGyR@`obe86nkw!Gp8A?rxcczC@{XukSce}H*@+YK&;nehCdN7pkaeE*DJl&?} zqNS)$4+$Sm54)VQ&r0_=(^5kaiy-Ao3zN@D52uBMPe_9grG`@RzgMNC#L3w*Ey+ps zC&eelyF$T&iD@B^CuB{_OU};Di3_EBL(p!TD=jo3EhQ~In3$4U94JnArG`VmXE+Sy zCWb?C;XpV!5&a~F62e8n!bx$+o|K%M3`ty`(#g4LesG(foReG_h62V`~&d4Y@Ntcn4kkC*MmjRd1&`>pT zVh&tzVtTsKn8vo=-pSnVKu&wz+$K+Ydax!g>?x?ttEj1{tniGMt4ivsd&{O21Pg*?^%<4b<<*s;s_H;sN?>tyWmQ#nXEeX2!+UlowC2*2Kp*G}I-=Wu9AESXo#|$givGse=oU zyt2y+R+ScH1sW=+6jxN$)cD4YpV2<|)cPtU*O%9qSJ!8Z%Mi>|(rx`rv=sIARl--- zR|f;KZ?7L8tesMo7sv|~!PQoi@2Ib?t0Z5WO}?tMs zRbF*vT6J0Vq`bO~a`yVI&GtGf$l7DAHX_`cqmwZ-)qsKObA3u|g?Yn$iS zqpA9m;w5E`jm!Glm)Fc+mWwuv#RyH(LHq5T6tf?w5Dqb|HzG~^Rsom8Tiz_Q@ zGb>6lILo_hD~qd(CiKoCKc#qUeVix1t~sNi_ICWoIW036ESzTDT0y>I>-?IQnwFM% zC+S*Rva+^rfop-w+PZaJXJ-doMQ1}pTwER7^>81Hk54N+rLB90H!CZ>#WUVp+)~sq zwV|bTQcG)65^7ByXl!q9FD-6sAD`P&w6wLYp{=#4s;zllZB6mG;&FBDxsA>B%}wK* zo72*3)B2m6nwuxoWHy&~mQ@xMrWH@Y3)rll?}};ErINuQ%~t$*48|} zsiwWYy}r3UH#=8mj&9o*mNvzFTQm7~`0;77Kczi4y`{FPD6J^1tZd4Z)@Jex+MC;& z$hS@)-&E67QP|?r%74RVK1m zl`br4ZyG;7cjLN+EtTz!ZS5rsN>7{G+S<~wv>i>gS5>a5oj(2ajdM4&Og9sv}sM#7PU0BG}o6^_LsFctyw>FRdYjsQ&UTRLrq#*`su4$nkt*iCa>!xUsJiO z&EuWa+L2q_@^E*@=2@M~m(R2BY9QaRtG8uV%k0@pPSVYuT~M&=Qn=Z01-o`_>+4$x z*U&d@n#a?IKRu)0G{CPz;Lq*xt7q-|RLWr<9%5?EBRq_sn&Xo30sQ|Zc;7M1Ll5Hb zYMOK!lnC9=S)=x6594PNJQ=Olqoplhm$q8JDQ&TSUCPQ!t;b5gE=4piH^r7>3xRO_ zsLKz2#S=eNsPKdOe&rMB8NVrlKTgCi(ooOY6(;E!<;7|}{)0@3DOB_Wl^P9xL2tp3 zVz$=$&5`1qBQ|?+F)J@W_E}yoSEML7+Ln}6BhOdy>qpL0&-i|d^6BsXI&u)dSs~%C z)tjVWqiy`D2%GW{$6GYK&SJxSX@y5CF~f4bdbw7$T*;Pm{YBb4lo#=tM(a1nMvhoN zl0Bq2R%&+_=jA#Sg()sYfuM5>d4Bf2AUVn=Zu|S+M?RM+NrS)TQ@*dd9sl2okNr^5 zZ*iNg8hn0WQzv^&Hg%H6FpSOC?M(B^LpSA=laDU@cY?J=r+~#_imoY!|d-Mo~ z(Mta4k)y}tC=Dg~Z=eebIpX$wRd&W^>oezPd+0*v>Ej&~mf|Q-P$+N(6e+G0MZiHJ zP*~s?hjDWR`Gk%~JNV-1k51q7N;x-;ygL1{86(%WK0a;Fuggci;4hc+?lNVFZy7n8 z!eb+^KRU9FpGo0So;~sg{$D_j|2L*fIbQu9D`2}S^a)D!qq6Lr97h%wT!(X5>Uz-Sii=D2@&g=yf6cFWAa$wr z%0lS!(1QuLYL|{%H9=MkX$Rng_{U_0fC7l+<)kwFJ7PUTxuOWLnNm0*97t8WocN#f zk|h_;jIKaoHn#ys&bWg7iO5dNmI^0KEGjH;C3BZk@%>0&Vm5ZQp$D!TXnF0m1Gj$3 zcgN?BOAq%yyuIt?mk&I0KzT;>X;sC=3&Y`+r!Icr{CB=dy5>gfZ@IZ`@ojBI6E9d- zyLQDdH$U)-=j^jRzuF&9Q#u&=K($o88nerVU%V;AZ}^;3VaDv@TP1~4k`%?8@`t5G z6^3yV|8>QtaR&b;9o^gQ_+Tb}lU*Staa90+*Iu19j9;Ifa!2)}_(56xFcbb$9TgG+ zcO+4|X=aT)Z)oz^i|xfwf*rH;2r25=k@6!@&#@x}ne#V4lb5UG0UgIdp9fO2d7*7W z8866B<|Wg{<-{AI<8X)S#{Jg{L+L)$=BMY6waq_-~7Uoz4(@^RnF zX{~+TJb3z=#&+cS{N*FPwTZq`vX8;Yd&(PB-S}0lRQ%sZH&!_D_l8{ZxZMg*Aiz|C zpi&tO4s-W|ZiN$x@%WLiip)Sz@^I!h#p}i;Z?@ylUG(E#&=`>BiVvo^l>wE~<>lun zdNW-w0eE{VbScA@<>6ud%nZWbv2TvVTfh0p21^9vCk&vc{789e`4OADc+&ai>-lBT|r$UuV=fIKfY#(~$;<0*}hAt1lVZnRoE+ z!N&#$ZvN=``(Hil(vcN4>A{rLJI`&-$^LCrC?+CM27z6v zX6~{%lR3=JD7d6kXXLrpz-i&f@M$wyfSbfBOd~XhdEqXKa3|^RDMo`Y?f#8;V_e_{@=irvPxeia>4E2nP ztuOuX?8|3WzF{xwS4=s*zzoTfm5Zem^krs!6;}LNfkJD)k-(R63avqX4p$6w#eSwe$M6VO;Qy6j(&GJiw19`pSR6|~f=){XQgBaz zp(RYLVPYBMt|GU_tx3~hOI749JTD&$y*vec86A?c19!EM8x5 z3+beSHz<`VJ=V{h|HImQz(-Z3f8+O@d#Cr7%uL!$CcRBa4+L`Qy(jcQA_Sxpq)6|A zbfj9apx7v45+G96hPtj53t~YmSa#P~*2pfBx%q$3y^|2o{e9m5`~C=%nMqFWob%l0 zJmve8a|SgUIJ}qB(Fr25Ft`P31J$Wd^4cASle*xQP{|d@!yps{)16EK*m7+U{I-D2 zFOn%uWU92cNxGLmKyH`zHA(l8$uiAbI^aZC^buiqSWSv*Ri8rLkFC?`Rd}wb*G|)w z8^HUG><%}{cNpZ>;DqadjpP=rD=X3VAf0#2y=Ss*UVJew#JGn%5YLH zy+is*Col-(jV)jDv9fH<5#3ao3aCtGf1F*8Gnx9edy?Xx68WqbI?s1}^6;j;;F{4f*Oh9XTuN3<5=T z18pss;v{6_vnFj2^J0t$z1Y-Pq!0~z0^1{@ke-xg*oSUTA&L9c!>=9TC!HCPe75u) z`-}nz*7vb)FIOd|aUQFOs(CB*PC?RUoS6VF)Xj9FfX+LUdLxaMreh{*GEp_!!|fDx z>M4=Cqp7(jirrku6!!5I_{IfcEtZCCc!zmttc@g+O$gNT=W}*N{KYUW-G$0R5jX9b zW;9{jotc%DDeZ}#b!^Em|K21WCQj*x@9145cSN_YeWu^nX~X_~gMK=>N&1_l!^}%s zzTkgT-+^9!Q^h=v^O`>LB!A?c2?Q^GW;$=1sR4v)GICi?lQoG{CT&l8IO$l@3rQ*f zSFuyFoKvzIXqOZG?i^!sO$T`aR~oJIoNJgNp^&msUPb6z>$e`P4Qq&PQ;wa9U(uJH z3CNtxgb-da$u2LgAlC=PYkki<<8^-iZdA;ImNsZ!ySMT^Q!W^#girrDH~#3vHaS2RUW(d|x2@VUqrE{IQ1 z+%+ZffW0Oef+h4#MNJ#uFf9V=7X{fZP-u-wF{O#HfxO2+Ud4XvLJDn+&`>vi2Y*U3 zjNkRdA^(gQH$CvUW19xx4Soi(ieZ-oG{} z<0;a0Y`6I2-h6g=@7uviiLho%p5yf7NimjulseO7%2v&c=d))C@@ma_59)2XDoFQgfxEli)m1ik3M7?IDy2 zlTd~36By@!rO0P>*y>QS{%5tSp!Hi&AFC>=;FJw43lhjnzm2y_k~E9NNj0G9L)Xo! zY{KL`;|Brq!-MlF^SRz)GG{g?%uG+uiGke6!6q~ZZCrlj6z_rjDg5q2+Z6wSAOvXv zQ|1t*_-12!O*SIfXBT^dj4f~MGiE-)RE7N{Z>ZKSrqIt3-f+r0zW?aT0iQir|K8Zl zh5h?~{~a;B*CZ(nXlGD;-`8^5Sq+idSS~&O2r#mlpP1wKa{Q1w{ zUNesbhUFIzTGF?ua75_siq4%Tyf?L^^K_X%z7XtK;~)7$1>WGnBc=@fl-S+*;F6>% zoQ=6Hj5n}6**an@E%S%N&&(s)Tv04=NDP@RsLf?nn4Bm}kr`a=>O*#^8GEQ=?;H*G zh??{2ngj37wOg0GxAD-&6UeUoXoWq>G=-VtJ@lcaAbLsrF1Z*~Y@ z$;{=ky;F2T_o)dNG{crSj{K5odYoEOal&kdN*`%~nviWJ+;8xiY*nypV~e+17VKku ziggkGsJNSLjIN{ynkeLevsc!m#7K?HFBJ_ug_>fe{(>6sPjJMET>vIGp|d1Urqrr@ z>gVM*9BvXJMd17*(dvT(fwEU16LYkbjMT__Kz1>0#hfSTZEOsA-HnJwv8VM}=~`y& z3vj&I3uZ~=6Pt+$d~+B6rO;7249!$`yg}}f{`1q1;G3@GXHfJunaU~Hh1>$l{|D8^ z3ouDCN2lQ!shJ#6Y&YiNGvm!Ae|6a-56b zlAw=WsN&=88(fJlfJ`F7`5f_9>l>4~YEqsA1_>K7@L(0^BJ?Bn5B`I3n21$243n%7 zwaKt@{jw+x?-&n675QG8L3@0CY{g&ZKI;nH5jo6?&7B~y9y$4r7 z2$w~=)LV{4mv@J3kXOoJpDQ6|Ix%PsW@V5eLF`vyD+EjC;U~&cBaaLCIGdI8=M)s? zs)g1!g5721Knq3?c$#)7&B#JUkSNv`6`oolB$jNMD!p}0x-4xVvq|*k=9>3bODkTJ z4oUgsFj@9B@x3TLeRx%LkBL2Z*I%#iGcVmLr48xcbz<3ou8Y^IqMN_>>XPsHYHtha zB-KcD((}^#@fD9hP2M7l$O0-nBfa(=oco97b<6$!rQgZAK7HnfCXZh|nRMPhX14Sc z_=0tN7NVh(H0X7fD^BgIAE}?i@J5R|g0qr1b(|&&^>Ue-G+lyWxn`5*0nH(eh5efS zQiMY^SUp%%$<5Zx<(6p{XcrkzX`j;_H=HoOK;BWmqxqS%sIMB`sA(~<>#({*x$@4~ z(DJirLhT*8W$BFqOFm{liJ?}#$f{h8n?&pb4WI?dXz{5o&!!<1B1F!S7G%giODOJk$5@}i?V1Y^j--oMs9_wyk4!uRh!^{)Z^4&q(Xx!;nI zbwQs#>)t56{@#OkHU3CGe&(42727}hIxO=7ptA{`yZxfwve2Y8gRu4$nni9)wW$K= z1>4rLox>>T128E&kDwhW$KZ=H(us8VXijwM}6{`W~S3XLX5T^ue9wv+#)quJk!rc0EO3rG_9amtV(G-8!V=ML4=6hYn1=$i!=_ z4HXPvhfI}aX?m;OS_7F1yrAu?jQ&OXj%cK7BtMh{OYaQ!^qbNH(wXol#^4imOw+SZ zG|8W+lRr_5kU(XaLkea2jtsfB@)q2mpxaY~- z*wdVi=r{*CBt{Y9QY{SdF5^OvE+Qh;I+Y-!)vhBe9LbCYQgth0D^mWz0*!9wPFSya zpgK5!cEM7{#aCq=5{BSfnIVvm^~>V(h9^&4f>#>r&Pah!06!X*MjAobksB1+P=TENxN{d%9i0jD)_ypKOkyKz21T3tl=vp#N> zQ41PW0BZt!ep_U1@_HJJ;DfkvyJX}BJ}Z-yIYUN?M))xZ;~3j2Eq4I(?KV6+#;*)0}H(KZ&?(hGlLnv{T2x|z!LEv zd|Lu_0swKn8Tz9Hx}bt%dV^qo2*I&6M?^*u)f8#_PU-sn(st^1M|G@ZH(Ka<{j`vA z{R8#zdtQ|$Q7B(|1po3Wl;pDiEsDmeOnuy-u4n^fay4puzoP z8oGqe)6h+Ht%lxDcWEeob030<8oE!6AFLyDgcUlvQrM=W?+TZ7K;2q&^b6r99pwaz zjv}HlsE%7?05JyDs+drK5Dd+&kpE%L%8LrEALyV(gjv9O>sOi zW`&;VwRU2-)jMz10o0YKVDqi+c|_!*x9?v4&T@C_vozL|><>hyrMu}vO>aCoru^x@ z{!U!2uUcwKbC-pTTe=O{#^%E$^ktb}++2UrZ(oQ~3k#HjS!+S^-wM|@SBpz^*+o{k z9&%lF@h+T0ShoT)yn*&R;k6j6%@u$!nHsKXtf-kAmZY-0&WS~I2nr0F68eMLzYKdS zBTpWFuEH-K+E~Nb-)`!dnWr9JFnPzmE%$F75Sj-~JBbvJSvNdKp%%KagIY0MI@ec> z1|$GG+?%5IgKRM=3purxn7yB;ui&OeoQ6oq1V&s{p9mUefQDBXFwBH|Nh4w*vL(c% z76Q&LKLh_2Im+~^tmX(zh1^@9k4WjIJI4FBz1=N&@eA{}T$<@mTR4$V?koM!O5t;X zUSox=pMFAqJ9y;YL6y56+8_GY#rwv(3!;U(c7#^^4aU_@E}HB9tTuvKH}NPLae>wj zv({|!JmaC4J>(}3@tiWL7R5%`tDO}w3T;b5plt~UTTQ|GWc$V!wr?GS~Zl!S= zNqc|Y_>Id(xTHm?BN?H47Z<9BXPtfL>}pfo?IX`g<v?w-^lpNu@jUcUM==b+M^;18x-k+A1nw+wK z|K#oyKG^fvcm0K_ca~*!DIJ=c+VP3$(|N^sV1nNS6x>9q*D7-vss^9HQA$6!wP^& z4gIlnG>ic^Za56FAoI3~jD7}e{A0gMW1$zMGr#|$vLJ(jaDyOCfFDAd#EUwY$+l3f zb5;Y??0Y=Y3~LI(F9u*RAVa=R80cgEXBff}Z0-dwuG#VVEGIb_8Ayp_y0T&S{-Krk z9m2smf4SamTBojy1b9Y7_KZsKSvu}6#9|P(L_<#<)8y1jn6F|-e?T7YBWi3=C8mNM z0g=|NPIo~KOtqV66fU5MFk(_S6lCZXw**lSIrJgx4LL5^nYh^oK>MTC+Ip;f<tJfCx>La>)B+I>}^rgK4t0n7f0! zCUVww;^pD#X)X5i_q$*AZlm?CF;{H z|A5pqw_Fn4rhs6up}gIMZcrN3iV%wScUsPXQyA~%YKtjnNL1_BeVphdLwk1JVBr7Ep-Up zOZ!tuUYTNi6DVfmz7r!>kU4rZU_*06bX{Qw_Zh7!(aH$px9SPH=hzHr>#U9AtVU`z z#My8fk5x1Fwh+SB(%MR^UA|uL1H}r)XvYP#l1RO zqf?~G`}UE&2EW%f1_aA%Ui2?A_TIzNfB5zE&F&8@oJbIWW;=xc5H!;Dd& zp#21$l>8V>*~N@Un2dAE5}~J4~`z=ILTg?%l(!veL8E(!S7 zc+(8+@(iuv8S=D2t!dN&KKqjy=H?^X1z#^=>{#;pHKFR-wIedE`8=NGs;Rj(VMLjf z-Ha&XJTl1CCv~^D>zwU3v8t%r36^OY(OKk@A+N7EV~$G8w*} z_gR+Skq6ODZdY-S2-a_q)4`GeI%I2Lg&Bo4*O%QVNBTL{CF)fFfWJv(xg4h2l|1y= zu3EYl@?i*z{|HPg0EXlMd3VUR`5gf=>DU|UAEaNHrC8ANJ^zZTH|Imv%~&xNm1N0A zj~fYqL~Yc^j8kip$5{~EuL6Yg?Y zL!&EL1{dJYQhab^F55v6E-WN0CnQ0O=F4a%%-VuNIGu`F?m);-QLf}!Xr6f3st*sB%_D|e<7WeN_Yg5#%#}?-xINrlOPS7~?apTN}C@y}9zA6FW zZ;XOWo=)o`g@g46SQk*j~ zw6%Bdep4QN=%FXd=fD3FS@hK5^>@7q8nYQQKghxPxh}Q5)y_^P*fIQ+XvRUm4Ketf)aTp>dJN9rn!(U!ax5$U;^y8LBnM#q)C#&1kc-dxpxS*`~a zQttRhb-;!~1 zC;nLjOV8`puh|6-QRY&3$I=%5yW*#$VX<^rg|#^oaO0CtWFhIVP{?#Aj|>vUX4Zeyi@^ zMb;dBefp{oUrec*Qj$BTipef!2lba}J4`fd(VC^6GiRGunt3yFGz8J*08#?PTStPL zQUKfgT)JIm05K0AH{RyFZJz>}HkB~Yv_j6GgiANDQPFN#g^Oh~AfF4G3+bZ_D5d?E zWjXn{f^8nBK5@oi1{G784-QuWYZC zz}XBnOKh*T+iEgtlal=ikH7&AX#?=9at- zn+7cF5EJ7{2*gC797+{zrtd6T-+RpqqY6e$3TBVmww8Q#_Hk@N>EW?C#br{r(fMKx zqdGFD`5$Ge5oE^6&te1<7iNeHJE|6U>8c_)JEVk5;f@e9sF;YjAs&#s)`mz!K75w9 zsOPlZerZNzN}^Yq0V%L6JA1~K)6Fya$LDqHQQbTcAI78=KKy&UWO3VUF^)cnbM=I5 zp;A~WY!{%0V7;J=P8Ct@qUuT(Tnv>k1hA$;$pI70G znwH;NdJ$%m@~|R{#DqV)vaudLYPMVKFu8Y8OC>NuT>gr+neEZ`pMaaflJWp*lP2~_ zmVv8QJA7-IvWr&2e1Z0C!&*UM#Z^+)sQMoJA;2AfmM|kzOoFcya72$29OKZ& zP!mx5BO@((5Ci^NiklG#}DdOx_3neL*8bDrz*VG zX0Mz%X3HI|kP9?ZtlDBZZ%e}zT4dOtZ_l=Df3ciTu+&GI;OgNADsop2nzBAgx)T7I zN4nFI9+f0WcdCNR`}g0|zyG8ik2VkGtDYV@5&< zcb5-cy)kuie*WapQ{#*CM##Ior91x*%!TR8Zjhid1Q2J9H4#T7vq;pj<4guSa#{UL zbkLVJ0#O5v33Umz$&7z&$o68gjW9A;la$PE*iEvLe61;1J#hTp@#*Wv_g|Th=(*XR zniAA%Q)`prjN|?&#y^v0beh#YZ8G!Wu-APhLWKMeMG1_Twel0>CEYH4B@4-X^TRTR7h#r+oHCCU6xv#O{xj>SCuZO7W;}KD zv_Z-&nf_v^iE$I*(qQpCj8E#o-6>k$bzRP+PzweGZxaMq-jCL+#${-{4fH^L>^P^v z-#|yyS`T$-pe1#=?#bHIbOf>oIx(D%;jB%Kiv4_+^J4$|WjjvGHha_wN;_y#ILFbl<1L z$mFP$^!SL#4{8UMy}oYka}!1h;#^ zq(|pGw0BtdS>q>x3J9LlIjS$PtGkFk-u58n?Ai8}cHXY7N2>|#Aqx%SjHP`MP*)BM zY?4~rZP1u3GZEGZd=Wrv6|z4=T+9Z6<sFLATdHUpdGNcBL5bf{4pRk6 z*vTDYN+p@Cr7OucEftAE6#-qI0DGB%YqCQlsLhIAL^1+q0yLcViwT#S@$kShHx+7U}+xI9U~g8mvv-1fVMM~ilc-~_z~J4w(v+ld1{oQ_r+yOBcXLHq_ldky#s;0z--zPC{v zWXFFN+1e3vaHONut!_XU$H{2^f+HI(+9+CPc z1g$ZdQr|;loKU7NBZG%I`m!7ME7@|iR{BB}%nNnyL!Sxha6C8;>Qhk5jkt>z?oH9~ z4*!DY1;aZQL1VyeIZiD|8b|suV@^?L0&J<_&=VFYHu}1vZR{z~iO|utCLisp2adv0 zmYuL+*=qwX?i6Dzn(h2{n3vmCR+G({(=BKtr8W|0BPNs0DigD&q9Pqt7FVvgWv2ip zN*kOabFM-}z-^2s6^iL3nvp9Ao=1}>bni4-K&E#1?zzz*5uiz$tky7O64+cJfBPdZ zOA9;3rUa#QB^XfB1+Vr;DX&g=9EG>43)c;`e|iHts1@WO7vI zS{t=$IJ8|tIZ3^!F@vEP=O*$7o0V!GM>{=pB_))@(l`zsvn-qNm z4|w|l(SdXqvyTg!v$;~UV0Kn_=gh%idIgIQdw=+$qQ+ia!Q{U6ip&6|UdS%Ceq?uR zP>6(O-N0#2>I)3yno|nu3ZGO+ZsKgQXKKa}D0?#Efd##AAD_(hg zM(zg=zjcW)qIng+g57^0lJu-B&#FWRlB_h?F+0_;(9{~7r=`(0kn%blK80;qE;>|t z%1!|y{2ct{K7;Bu{cXR9Xd_E87C40|6e&N$FwUhp>_J>}9l)eWPck3nVQx z7^$Z}s)EudAtGHR5xfNeFs_^+ou}`@e~9OXh;BRb8Y1Gze3*-#%U;7}z18d4fL=l< z+7Wd~+KMyJ5`?%0qN(M|fsH72g8)pGG((iPA{^E#{*e@u&tRu6v=eiJHD-zkW~3vw zwYUlCIteppc`Em9%HL5;)sCLyM-SClbUha5J$!Uf^bqR(nXLHysYhpZ_^D*%&)e6O z6ztg|T}n&;x$oo8y*YORX8x4)Z?anUx8hC!!NX!eI9kt|Wy@e3^d5{`7Fu!uvwZ5~ zkJZEf^Vm%*9wbKE;yD{{ipPre?#mvl{<6;P*`QMvY;w(tHO=DrSb4#t;U%;!nAPFH zP`G)$@SYh`A#+Bd9Xa+{lx7iVS~=GXi>L3-oaJT<-c(A}p8i8e^l%%kotNcf!Eu98 z9zs@r_B0m!bH~wy+p#=YG-CxBos;krR{X)Nv4ANES4?N~zvF~wJC`O#+7BCa=PlfM z!vggymId^%mYd_$j&v}?h6|zumX)ZnVkWps@yRe`G%Up|l7+ep`QIO0KH}-B%$ZN` z+*-bKVNTZVi+IPHVZj5$wX#=n{tT|AMaebPY^3orVyxk|;>`J{xCqh6Q_h4oskuD0 z__)&ie3G7@-#T7vZySFJFCf}*g*|+;z^FnNXT6g z$YasPju|W56~znyWBxU663n4S>u*Y&_KKX+RvctmqS*c&vQ;itR>)|S%V-0e4|niJ z^c@L$ZQhWKoOWhK6lOxl7mQgt;(_#C=7iXo)HLs*=L^HBZtZj6iZ1yby*m$>{a{*b ztlvM$djIA3+H&6RyE!B7?{6GxX;E_0G`m5?6x?tPw}l%Hs@p|9fjZy-Y(u7%GLkD} zkw$V7V{wKy#(vCw*gDpQyvtl-x-nMH?2zv!3!t&P`ElFbOiDGlaCeg0?hdXk$8P2E zMd9(EDB}U!d%OmcONqPvcp2eV@5Nktgy(&<Rg%;-!|`C$9Cs#8Jl(M z*aL0Xy?A46dOFen$#plkjom7bRX8>)h`~JVz^)wTSOt|=Ki4+?WA2&OITy&+zI7g& z%(k(Y+Fcu>?B;8OyGx`kGU8vrJ#?aP1Zl_MC&1tF@i93K40z5Q=S&(Gqu~rrgXVwY zZv;=cv<@9|{5e%cX-nMW3&+3ME?HC2)Tg)r+?%w4451F(fq&54bjs&l}gC`SZ*A>6jf2P0#8b!p}PS@tDo&V(`T z)9vBzUHcy!2ZOH*&~1w+K!kL`Zz*z{Y+G9FT{dyzZd zdfk+ih}b{5F5@9(>{fZK!b52p7|biPXyqY{qBZiIKf;{V+?H2mu7~S}RJL5AZkt8R ztN8u*?M8OLF_Obx)!Z1l2iH8HX7g39d9iJzj>pJ$*L)r$7pd87m62O95_82K#gR%J z_NY9z-CX$}WPTqi)AwWUC4~-z^SPYbT;gt_kuNC z%cV)Tj%908uG{Wj1On{33Ac`At5e3dzZZ$g7<|jUU_9}Oygp_8$2WK)D}aRg_VbW^ zTX}sfZIRw%cZ5efOIt2`yHPZbPXgzH1X%57?9M$3ts^lCDkHM6kI4-A1b7w?21z?b_2Xuk0~;Olj$u@wg4(x>bCmdH|QoEfe){ zIgRmfWmPC-*VcL>-3_EyZG;DXT(q_E34sPWloZIc~U>AEE`D z%Y83+{s&Yer>91FQ*si?8dCSlskMLWkb7qPsoNeI=jQKQKd*D%?9k4corkTxC)4$l zlz#A_{gG#0A!&a*_ejj$ciSg!xSQEQsQ+`LHm;Q0AjX-jx`HCRt^?Mtw&cBG&d*O$ zFYCnn{GUdo-JcZEK;lJ<{k-?}j3fiMfi`qm9dBtM2Skf+L+o4e8~mfYS{pj#t?qy- zniIN)qScurMFxMNupYJ$dZMs=D}d}Jp(cd7VYSP_OV~(k>CAAKt9F&;!*UHb0D<*P zH3fxXsQEQA5Gq@h`CX8!mW;#&6wV|7Z$vYY@1#AN)VP$qj383sUi*q`q=6P+MkR-9%_m*>Yr#C?};QC#o-t?~4zLl{$@6F_L&mAOk3iTJ=aHOS+S@K=QoX1LbSP?$6n0FXWV7cS^pX@@p z4GxG5LBjA>e6ZHGJIwB2CDW>aEkUjsVf_{GMIZT9S}^9`EqiErP2=`U{O=iL%KW-X zk<#^RAF9*YTA*cx1l;Eou3WTmP6wB4ag1|14c>7H28e?bvG4-Wb+>^Y6m78xfF80e z5vtN+Vt4uCDpO@I09Z6`u7o*({ZS%zi|eM;;V|Egxd1k~9G%@Wwg(_BWrP<=ar|9< zMx-r&?9PE%g>Dj^6Oodd8jP1_6IW2XO&PgvxVk4RKy!5SffJ~D@WZDVoE6Gb%ZCgEaR!%2z z!W%t0SM*Q6tGc|be6OlmDnk2#b5a-bBI$gY%zt{fwD~tl+JnD*h9vL2F7cV`s>aWC zI=aqybj|#7sgAszUsAxDEVQGXo6F)R)+QWIY(Oqf@-;-{szn1RrSTm0Ue3H0-9R`- zD81(|)%t3)th~9e@ZY{riHxV9ucF!^1M-Oh@8XC*zhTf!k z&2P~yp*z?EQeZE#unx&tSjo?!BpF#)6onwWKogD*IZoFi$}J;5a&I0v4-3tj9Q2TM z@{MCG6N^|du;m)AQm6hB{G{RHMZ1PyfYa=E3`XStb{*M4AJGCSur^h&mM6?!a)gZ~ zNxDu?N!Qh1O3ke9ipY3OS8gCe2r9%G_llj7<_Nf*QyGzUt2Xjl9QVQFa3mv-1Aa`v zko7}?8U+C{j{&Dc~fveJ? z0Jr!uafdYX`XN!c~q)EskBr<9&OslXoU!jYCCw%0>o*L7-#WWMVysm!toVW z906f6oiAl@#C%QARTwMMrr}&~=5P-x!4uNR)@m;0@*^tLb0HsDF8> zQJcC@tMe@sBY0z1J>8CKMlZhmxG1^}9A~22>a8&uD?qBgCxU^b71j!*=&)!V9zP(B zz=O3StN}0@0ca24yS8cq6cHep1n|A>C+sF;TSa)3A{^w&B^M?kmx~o+BI+9nJ4Df6 zD0GpLEt^1{tPJO#ce+d;w^M$(<6XQAedb9{jbbG^s*(YaMgL^gIF%DN_j;iZ5tZ7U z36-0BhCaVoQ`&u|wD|0^tUiYz)s;tm_chgWp$l|bBA3Gr5TnfABu+>TCUIu3;LEUm z7`#6w^25~o1BMULZEXQOmJb8ICe56@j3(#ET$cQcl1`{5W|`tY7KgS^>>E}lhgBJ- z3R5(xwKf}OXaqx%WiqWM=v5E1By?SMS$&Z8~9ro;T}GYPcQ5 z$e&b`_I?+0zhG%I@rflN4-DC}a&IZXh<d=bB4s9GTdpbeT$Ql0W?b zKK%nkg7w_S|Jtnq$`5fMj_4O?xnKz6JLS1m8nzu*mP)_@KUoC>`oT|PYNv>Q0q zxPY5u)Ner724w#r4XH_XjG7?ck;Li=H8wVS#p6J2$LHKAaAC$I!;Ce~lfj&m>x-JqLe1k@t% z8}w`y$`bH|9F8D@TcL2~u)LH%TSvGL18efw){B9#Rj58t8Zzj9{IU5BtU`%Kv;28C z_q}Kw=^P!g-nk({h{$v{w7g#nE1$*g63}VX?H0^79H)bmu5jcAgg-KmTsEr>Ee0%V z!(ZXe(%VI!g;@VeEf#Gg(hIeEj)w=Y#vu&6$>7rJBCU=yXjTWYV8B#p!@7dX+#a7!0>i-bU(mjjSFvYU8}rt(YW=;tC4flZtPj6k&7j5DIp--KxE zaUjfOgq%mC%-5nFtev2JMk~Z=gLt`3`;fK;CBIcR0^?=0=m8QAei*_%49FBORwB;u zGwKa0tq6>vArf08GjieSBB;lp4`!O!AW~4LjYLP5jNs4533L8Fq{pBt(p7r9^D5~K zqITW4e9zzZ`}rkXskEGNZkLw7^QTnzp(-wg8-(hZn7AY-5*@MqiK))JOo%&8(xDoY zNcu^mA)-k;It{;rSE{9@t%efIux&^}G%}Nz73|2RD6J>Em znBYd=O$aqRxh*a4=;BFhO8;`@!TTQ}i{5*(hqi3N?7lVR)6%^o?yv0F<*wg_j0rzei-TPnNFRt} z!O0u(9VeR@pw}`*)XK2lnlN2Vwlic4SZ*f#ylwSFqy1VqO}0T2smO!%FgF<$Y7rO2 z(I_}fPtcwvJ77}T@SP(Wb$0c=xSJWG-oD3)IHyXu&jHqBcj9Uj^cvIYko3&PlADr# zi<|bX(#3-*dO4$C3ysH`L&9V9=c7{$lIm#y8lE-ph*b6d{W9GjnkYz7DN&z?qG?WO z6Q48sWKzoT1iqBdPJ%nZg@!i&d(e|wtUa^khudrT;=<%(e8pTK%*PEeaYCf4U~AdjCU zu@5FD!n!;~=c3o$v!cmmGzcx0L$(%*<6s-e?mGQs!kr~SE*V9RHJp#mskOJnoF<1^ zRwP?d6Vt_4OITMa#d|CPRp0GHf}M);GKKin!Ni0)RkQdf-jOb?9X#Y|>B+|rZX@2%^`APY z=1&}d{5pWM_yYNRbi zm*`$SqC?NTq?A~kKjY9P@hiw#GODg;QbtLFvo!5?saopM{OR$oMVSTuxVYG~L9BBl z!%Ks7o_ZFtwo|$JqRyBU=`#>wK_|KSkWEQ|Pc3Br$>@11-mt;rL+4r1srTs!S|I60 zrw<8K2Id6b4G4fWSBeJv5U!G&!@Uc*0PpJwv6lnHgiVYjm>Na6v2<=guCkfTtbSRf zwAPHm)sl^-n~OgpZxnxcuV!qVv-U1ui)TRYxQgz(r{eI9C}UYsloh9hsD@3PGOTRn z+tPxb85t8NcCGB5pA_(RjgRX3d}?afe4iKgg|gn|Sg)03``1Rz11>wi-Z{_2Dq~jE z#vXLDCtZ0Qq@dIa4~LDpEY|1`ci`5(xpaBP<^{`^^Ap`1!U-;X&Gpi;Kgts_1U}zzIuqRFojV2%iPKoT83R6B!9?^@Wo$v9UxOdoNNP(&{6o zx-R<95C@X3Qn@Iy<79Mn%${_l-Lqe6r|K@IoW(DV_$4a!$qszy6^2Ih1!(*6cCf3FuIO}iWC+scOdKBiZKRF4oD(7c-47EVyVQ0Z?bQIXE zU}fA$E1eo2+MOVDsw90h*FS=?9)z#CA6?gwK3(&Z_=M2z_>&hl&OA7XOo5HLsHfO7 zpZE@aNBT?0zdIy-k>ArG-=eNs0Id0(K zffEL98~D&bRouYfz}W*Y4-|p}$-senPp~8DxP;?^V0~07)ak1RqYcTh+O)~N*pp{G zYAF;bwgMDn{V;)9&Ak$0Rptm`mbNA@v0uoQPr*MHjI_B7tn(dc$3SYPR1wW*IVsFT z3hUptS`t;;_9#^SE%b{wEz?Jq4}N#==5xh`d&bY&mYKS8|L~3xZokhVt&5v|XkEXJ zrCEyy?E7?#G$TIBA0y2em>-uK6HQQd(lohK$@sH(t*Ku(0RP5p+`oCs(8B1X;_;(< zbzHDw;;iK>2C$%sVTB1taeKd(qgX1I3i&g}4WD91Hg#8qz(BJ1EA+n4>ad z6O$9nQCXR>rs$;P1XDC;j5c{KQPIpB%@uv-C^+I#UM@4*Xh}9lZ;Mi!x0&>5<8%i9 zI5AQa)j)UDMIRDOcorQ#^C5d|CLq%6gybdm@xk#`tfetCoA6-GL)_LTPn#d=x#ET^ z+U9oNa71rl4d7drHZG@h%YJCP>Y_h$MEUK>frJGOi{?I=A2&EN-j5vbsZVxE9VD%8 zP4X7@=P%o;!Z#^q(nzkE*$(O@0;~2! zEp#~CI2q9G)^2OX`^FwF=Py;{|n99wN}ZI_0`C9Irf^#nr6j)AK&j}N=IbB6 zau2$u9eZ`dqf6%=k-Aq5eNg(>sLn&S$@A|_zEH9GYq$&`L2S~3TBVUoW@`y+X)(T5 zxak~$V33_7!0;&u4M$J1SgP(uin=Ku_WLiw%h%1nyL>fkZR;}tV&)icrg!ERJnwPkj zfiUR!ml3;s^SDn~tzs*@;`QJdgA#b348CSoh#Z((uT|P8$PCEJs_}zX0}+|DxjLdr zP9%c2pY&JB`f5DMB)c^O|5MF}#)^BJUxx?xE_h@!B5l#!MzI(bT`rudZBS`ZOYM%( zI$b)4+wE}dG^hZes_^P<<(0#YV~?ZF@)Ku8Zw#UpojRAxOzNYp^=6$m!lebW7;8mv zBR3})%(dk*Hey*85cx8o!2~^P0wGU2{LIiBE(;8%0fvD9ZmuQ(_&A*u!nkz=3UeJ0 zQvBw$VlQgWdhE*Hxh`qjTgTHoJ4~B4Wo|DC44t-KJ@*4$iY6dE^=oLt^UFW9b)zSK zB}FGEcVODNm>fl>*gt?wrf|c=p!0mR?|f3+;mDN3@kt9JUx{82{~qPeYYgXYj>Dz} znpbQ{Ak)Vg94T|s4DeiJegHeLlN97MGONUV8RaDd#?=gxVVj^WtE|wb`I8^=zu&(k zziLipuz2qD?e~=5vmp1jBj%m+=uL)lco57?LTggu$dI|4kBzu(zdR@PWX zUT!QeZ!8xsguV>DLOano<@t{@6`Nn#tuv!>kZ_2A34PIq zoXI)^mnphgi>oaZ1th3f+pIpQ-K;;z+LyBe64rcJww`1vDDoKM7vTelJ#;h|5~X+g zwl+3r9aY(*H5*aRqr;~mzoR?15BY0yJ{pqMkvC>-%Z&?XI-eIDMr3 zSfxXfhK^Q2jorBSAhp#$xnqP);&a>?w)y$p`i2&s88G4@hWx@xQGEp~C6y}#22(8t z#d`g3ge1a1%p2z_8JCzjE-q0MCmV>R+p+O>6&C8fK|uCPS}i|O$LXuObwH(cSFjmW z5L)Ue_Fm`~QxC%QN4dtjEg_>lEUc^=s`-Xd7lytS;5&?j<2aD7LjUn3q{oxxWuNRG zyrE;^%6=QpO^q(Rd}zSkC3$NGZMiz2c~V4je54)c)KP6>gx?Kg?xSHjWfLA-v%Y>U zJNa(JnvIW<_zTZJf};Ub)?a*T{HiV;D?)!+mRmfPe6_VaKC>UNmX;!--l9b4yeaco*R zC;@XCTgMK0!Hh&5PD(gv#QcDbRvdRK^8-f!l$PYv6PWIS9K7WWg#hCLA^Zhtg;l?Xw!GLBYSEgB@{*P2bUb|cgt55_I_r~%Q{M_(48}S7C6q~Jnsc&OT-SVnk8Ns zO><(5Bcq{}S<`XWFI%zSU_41|v$V^_Qi0c0?cS4J!;6ZC4J+<6L^>>k_GM*7#lwen z>@-xkv(u1a_+8nfKYUa=WN0V6V)rx)6MI#)6*o-By(H#yYMt%@!Z{I2KoziD`}2TS z=Y&pC!SH)PP&oySR#4%5CxPc5&}#4-1WRB5iX0To!V>~;YmEkYA|NPKvSf)?5tU`! z%c_^v^kx2Ktq)k$fs-QnPObgU2ORN0tx&E9M*z|rtO!Vp zDivlPu2CM&96@EUa7L4D2cJ_4KgeG#!Q$I-$2-tqCDO5JWbRh=*OR z?Q*mO?zsSah{+@#a8(pHRZK$f0I!~l%8sgxS{b!HO67|pQEJEoOTE6e0Mv{Y%tWY* zA)Ww zR4|J|$dxMlwC__vmn!WJZthkQZhipyz}AqBHJ}{{H&C=ipjuaJs8`?AN&{zEqXCa* zTEs3_m4~&|*ky(R`f#oBHsp|^g$DQs79X1_R8e@UpxYm3$n2e)+i1{5YtQJYMtI;wcr$YEr64VIut6}PLl}G-VV>$2-q1uEYfAZB0!w0MO2C7Y;?2f zE6!kWIT@d`a4!3j2N z?gxy@EQ|sFMUz9Iv>kbLvnH>FCdYi+w76nq+^PltyB2SMHd3pFfyuyYNND*|Ymwz8 z>r~24hAZbLa!=lLI$ZcPI15gKLrs{SofbEGan7&?dYc$gxwx;mxNj<<@1+_DPdOTh zxp7Jy!>tn!4rEUi2PfjGuIK1#?C#bRHn8!%<)g&ID2l3awZ+lp7Vm(|1W3Hkx~D{ zxpZyb+QV%g*hPeP!(J6T|1p=^+q^a0Z;lUY*w_?Vw_dzaA!W94y7pC1Vb6|LQz@R^ z7Ot-Kx{4QQxpCbAxNerLvz6;^m9MMlY+RUCJju0JVIBX6O0DkrNw`wWgj9xH((c;K zgjyN9k-5U_e2?c@y6H$ z*(*-Fb?lAncE904Cnw)>U8M?*jYY@_cGQ;Eu_!|Gpa@N=K~t*Xl(B3M%GirH#=4{a zbnK1mw#}jSx}NZSnH0t+e~-Kco{JZ)RF8DO-o2|h*0H7%u(|9-4eD9lqg|hH^sZ3~ z_!;JiY{Spg{|4e&!rUF;uPkj5#f~ND23%6F`i6ePpMqs4(4qB+Wwmy^L-Gx>_Bl7Q z7@@%-?loxShh~1`7f9cupO*I*=@)h78se3{#b-Q&&$x~ui>hPvX1>qS(G=(`&5Nd`G;iq9e)&}rX5HgPVNQpi%zLioTd-sVu#53EWW>R3*C zXJRJEG7>b&h}p%Fh}@h)dOho|+}^|b^$zsQesI>tKIL5oMGucs-(Nk%9}_ca>Px=J zm@$~yYna*B>W!eCOVsgyMSBJn{ZWt)2?IvTbh|&Fe%*XUz43_LN3bKt*JuowqYv1C z_7(kW0(lJqx1sgg*EC36XQ{dj5SHyrIl?IyZIaiXR_|Q1c8B_DWA$W>VZ-B3tY?)K z@2f76i)xnX={(LaK(ac0jtoS~h@5d2R-qSLQ#xV8tih+JXaLc{hDm)61nN|44B1bU zPPltK-nc?Y%j{IE`xxemGLfrH6Nf|0ERjAEaEk&tiRFPFz>Ll=&H;5M03c7Hr z5G#D;Zz+3)FFz416&b;-5}4iL3Rl#%Rw#w7iGL_;#VyPyi*G93)7gwmQKC2J!BkeD zN|-?5+^S1_K;r=2G>E0>HT)AR(cS!#3VvA0@psgh)l|(`Rz*ICV*&?-{ghrtxdC%k z2wXyWMil^yn?me63~IDV0;PZuvLsaU;4ixu(A_`pUZ8PEeiz76y`N{ zs__3~r-qcBT8NGw1Uq#$vHXIR_!i<;&s)Q?q_9FWbc_mCvWZ(F0sz#R1kNN7y;euj zUO`WcXwm_*v(E_~b?S5!Eom3S-KKQ0hz81EuS7kRunwoKP&A`s88s%ssQW;pde>IR1r_yT)PF!K}b0nkfJfWdZ4Nhh_ zL+?Rr`?;9)J)({fJV9avgRx@5T9khh6k6>PF?x;IhVKY^347o~2UHeoe0lj_i z{r~6xp6`Co2PCP4lU@7lv-jF-zw2G^>d)n~;Av&>b}5iX?Z#5=+AT(0%l!eq`}FR^ z!a2a(ZN;^Ua4^+s^2%hZSY7?P1$v=^S1Z4)2PG}Aj4mSu3`*mJih&;5y!<(G6$9;j zK@k8a4%J-Efb{m}4)Y7lC4db`X^!)}zU0ab(OYK{|4_(#V@T0}V8NW=`pKT)TBML%$O zcm7fZ7SgY6!%X^F9hRz*!=+*n0{e@xNX3c2C5y4Bw{NAp&~kbw3t^y5H^e+jhMXyd zbXlpdvMvi9kH+kovL`cB4(7)FKg8s$ObWY#z~T03glnyU zUMdvKmi&}}MfRYAe`Dr}pD9Hskr4-#(sc-5XiD?4_-C#3g;x_P$ev2IxReU-6FS2<+ zbpHY8L*p4>q_B*D$|A&mqDlHK)u$WFW=h9o8!YW(u>v#ddci7~U}K?Cr85{I^&lP5 z>y9W!9Xnzaj+h|ysDOZe6*x=+Os@cCNB*5rhs{H$-*0?M{59b+;!WGbgmwLT2MQD( z!8NP4qoFVKal{GskEAleVF_ z>j+F`dLt`fW4E$WR`RI&4lCNKzNfysl@;k`ZN;}GTh+JK_a9|N>ib(69kGzfWM_L2 zA2SOvlqx}3!1xl3)vWEPz=P9v%pR)*Ibb4mzi6YUin*WfUT$1yV1}#U3AUnltwAD| zX*CdYr~nl5_iF1P_GhX-J7f0@W%h|j*lV-0-4{pZ(EH^|c5x0+gMct*mm~(PR#)I@ zHViw}EWG=$9+wora4hdhyN2lfE4E7_g-3VTY~tBLdTac zK-=Ziq8thrXp}=c6DKC#K6Xw`X7J1W+F@MOIz+*&Ze#}X^PZL$(y=h;??J$ zanB|VpA=Q`3iPZDd#p+Do6SB)Zf*z(&%=6rzCs7}Qb8|6Y}oEXNhpC@Uk2e3B{#UA zLP`6WAc@y*H$R_EKg-KQ5T$Fo`D`SX5I`G5!H!zp`=YvMHA@tT-Dh0+pvxy^*kPJ7S01DLt(Z@OHb3 zl&5f`cJS)zV|MFH;J5<3VWK%R)8(gO$j1K`v0=!9Hc7DfLS7aiy`ntuo37cOl?8R_ z726%xpnl2np1gBQ@HqK2l4J5jxlMjveiMpHm_|LzEmwi6$0ra*iAvEPMpA~B^vmHJ zZJdZTPd02|{t-uSn2Z2)-+cQIr-1ZLVkLlh^@8Mtl>SIlqBbKrCC=$SU4vC@{qyu# z9iJnmO_AEObEjTBvFrRX4?Ki9qN8!seVH7$Aovh3$I^otnVHK2K~EqM959F(!GH^! z;;qG%~r4``}M5G*Om_6ws44QX{zE6C3_quhri6w~-*#z|oj2Uo3c_Cj{RRTO3 z;qS5R@}{B9&C45`JdKS_Rpk{G%PXrqm6cV3-$yIXY?brfgck zdC;n)1oTsutK-K*aNZq!2je4)^_v<-ZBV%#O4=e?(I*csBYM$)Yk4DI5=9p10U%eC zKY)L=;Ke+OGhNBf#4}Of{cvK}f5if@xdbGh_~Mjj#Vcze`bX7b;^0d39@#FDEBwW7 z8O6<@kA~x}RxZzGb9lO;5NCkLd@~Rk^E!rZ!l$W|K}AsrK3Qr1iG!cZI>MGbXAw4tuCCY+s> zmr@^c0#b+oQt98BOvgFwGh|y++FSe?@SP{AzST!6?Q^)v z*&tWEsuEcrCjl5WgRr|(@G!!6DH2ow?<2{0=d@lxRQNBS4jUEpxoT?8>zr~=@mgD6 z1t8@BAbt!8IFc`F!2nBz%!tWBK{%SPNXQOv8TZGsKdJCaBW0#6Mmw1J;_d*#@3Wd2BrbFOKM6N%oiY zDe#l|m#xyuI{aqN@#83PJHM~CL(bM?H@01os_iiU?yZ$4*LDD-Nx4(kp~s<7tD7Ru z|E0Pq8m9?$Q}n_d2r>>43#3`nIC%J8__aHgsI(IWRk<_~Joi(;Q*mG8)G0%nrc9B> zwG16HWy+8tXA>%bQ-XLEP6;NUW-T!X($AM0O*rA0%uHtlp&fg%UT@((4bd&&vj!Je)hGUTO*}lVqVbISMSU@_s94KmRX#*7`dEl|n;!ebfOwLopjU%y zM_|6wwNIz^l(JG%#VhOEQ<5>T9ewQ{;5v>xj^p9&I{W9l*6yypb`J=@O|@H5p+Lp2 zqHn(U9#vn|WhyO*A*8dhu^GdH=L8o8CDbGFhTI{KH_hSo2g*DJfvY{MJa>B@@mRJ0 za(E}WCwO9MG4Dc8TiPoto9=~rD1TZ`DA7xgW8|bBi{63| z^`zY~o6T!ab0A&!$gZ@spclDaPl~ezuQ)qq54+yAznc-vL|y72xx(}ae^!^8ei%F) zje^{bGhkD*FNz;vHPS+?h$gBb4*Rc4RHu3EL66%N>?;tbm8f=vQN!&s{BE*Dbp(Jl z0xU_qx-JJQ83_EKq>+ePPYb7vsvcILWyKKto zlP7R-gO-186-Tgns5HJ5Yp70rQF=?J4E;vo>R37-vq6qQ;b2~#yQJDQIPNxw<0YV> z4;-=hg{z&)12WQTw{;nM3k?(}`sT%T!&hZAE*9I$o5h?n|Fml!%6@ZfI!nx_W;cT_L z?E00rtk^oc+<>wws$lcP#QnCf~mGt;8Ib z$Ifb=a^2Ku|9*2n=05EUKH+`g-PC?lP|R(8|2on3n+I_%?F)46ovHmMC+8RUn_u;{ z`;pKW`z_%6Si!07{<^Q-kA(YE?dF}jkHJ^e&D3Zn#sjKo`Y9$1`S@R9{-l%8x30WxGqW~c7iW)(~W5$+^9OE!lhqIB(^lx-+3 z^1?n9_t~6eY@BS4*6smeUaDO;Z?~U)oottEj@Ir0VN!(c&)aEm1aTfx!{#njGP)A^>2x}b2hN={k{(d1D?TLwi$ z;7R?>IcZIZjcNcj#Q(w+^%#pzpE9~iTk=W^P9LvB!sKrC>Ane0J7gnz{{bS@q$YLI zPQJJc5%Z0CDs})e3WbD0@qj)jZWBzjz}c3RNks0ptrK$jP&0HP_<=(nYl+wWUBX2~UGi7wjf?d9)&7XbI zuB)E@cx2+oaHuGcEeo{Ytai8yLRn|kq^z0Yj2mvflwCW2LswJBhua=k56&nbGX9NO z7hiw#FzM)nZPQ2OQv?X}VhCRg+I%}G%uLM-CvH2+em37|?P~Mlpm1Mmz7-apGT%n` zeuQ%#t+8T36};Dzdp2fX&!6se$;<{ zEavCOpS4T#SZntq;jO-Q`T22RyNQE3RDb8~q7UL)c0=z^f_WDc3X8HlQ8>$F>3C1| z>-t*U#V%&Uv>b-=dg|!_-CMFU6a%XzTfy(@qtwXSobXBp#K34grEmGQXC$wEHFd2o z=ms;#m$XQjvlOvv!-^xm;2ANTjHFjhPLGGBb=zc{MPd#Es%d*I?Z$bEd1*jQv$wnE zF~{48yjLH>-jneQTUcT_H8OtE!Zt2r8&5k;owiJ! zHj*7$CU<^-KU>GXS7y!04+x=}Bz-pq2L(wRf4fzI#8|tYp-(jk|&btIiB^hk!Q}7 zPan7OlAFWod{0SkhPq(1;u|vL(Q8Mab@yXbyK3Ip;j>SSljl7ObA2rq`#$8J)N*vd zCw$QRc4~a>Izk5q#3L`kwa-BdwU#TxdW8>upVXyIUfDMnd+)@RyZ9bJm;>y3?^~%> zQ9=r>Dt-G%?w(@srdl=gRt^2Fs<^fW z2uZ5d1F2RGBx1`9$yPNxEjsXYT&Ra)H5-4j*ieO36wMX{n78yeEl$w%CgHh3NoJ|8 zoxKgoiNsd}t#ETxGhI>2A3E9W9=V%s?0|KOk$-iO0tc$!$bto=zQ|6%#-9An3cWM7 zgp=MG;ceFDMiTgc^_>r_W%pgt=iCr=sQ;a{+T4%fo(V6nL(Q%Zvl)eku{;dq6Wa}n z*(}NJ%2KD)F1!r|6artc9^jPH>Oim)JR1aS;YdM|LP5QAUv({31Jvp_uKnz-`r2x` zRd%;-&vDNuzhdd)VBn^sdq?6dOYcb;TC_sT^@?yW2>%CA4%`I&vPxr{ak+7|QHF$p zQE|J?vUQzen;9TD&d`Qs3dfj#LRSP7H=`<3SQV+|fE7yp0sVmYsRjh`(d@o^+5IPS z_?LTLxVt`GFJHSKe~vAqA-P+(_W0bFfBlZB94p}nX3Pn0X{dlQ+1hYwcDd5*m@}?E zOVhiiccgf)@)KsHOPCCLih@K`Ys|b{%C;ZCnZTe3RE1Pz5AIODM7f(M*%m>^w#3X~ zFj;Ir8rK=_7r6@=6*Td2`u)eq{TK{6ftG7M<)(atQJ>|PhK_m)T^*MV1IQ5 zn4>0P0@zEK98Sdn<`TjuNRfof5NbS*_hqn32EN2Sc%~R;)I`1<3Gpml9w#vB%s}qbQ<@b zaXn_+N9>}+-vr|mq+akS^qEt?t6f9yJK!4FhtxH+mkRuD;jiEtXilf@)?y~TeoLQC z+np;!-W*s*93W zrFm&{*2YikBklKE9}f!8r21&LP#U)$KI-EDU2IeDG2M?C+d5$q z!)qM7Z~Y24Mzcj1!p}2NFF9RY#+c3EG{!yq?cfSp<#zwlki*(;dmEu9?viqAa`bRR zbJPL!D3U`ZMx05U3*K~^rs=>H@x-mOGd*c#!5noO+n9D)?d{#8y|eFrhgD6G;&aAT zc#j=aT3Rv&UAJ4kPd)VM+xMSIE2vk8F>1s)pe~k$-q_I>x8APUOz4fnVU^bfW@b2% zVbPWj`%XSGI>h?~^VUEmBIO)jx3RxVdfN6;%hn;@efQ9yqol%(WpkHd%H|1k$2w2E z<5(;Wy=M628>ot2=gQm*uU~oMNp&-yQN0IrUcN6^3kl4Y4^!10L?J(qGEMXQp9Gyp zKjix|DWB7|J5oMkUM>lVpM-x>yR$SE&6*i!4?fU#;bXwASJ%DeGLiGV$ zUz1!B8(5jJ`#Jje9dPAT{|>s7 z-kAkbS~#ur_phq=fbKHP{)uFf~@KHwmvowM=2%5)?ZP3A55}PgoX0tqDTMGuU(NQ}!L)UbYZh zIMf5yJEaQ8SAe^!Cr-WUTr77#C7OUH^V&`KHFom&*(#vR?&r+r;ign5a^>9E4x@4v$Ip zTw}Sx4jnwvaC=BG+t5`-0O0hgQ`x%t^XJVo6`r}F>*_YwROyz-_P_Pk{>Qee>ssrr?|9DX-pWR8C0jJU z_gkHlpFHXX2WHj>DVxEBh?lAwg!^aV@ZNt&U-Fa3RDj}i?Gve4n7p=s7HaKAF%z_Q zKTPEffQRn|-aL@suT^27vjh8@ufO*T~P_ou>c%z5qlKqkN5|FiZLvY}evKNapq-%q~2uYJt9@xbg|SOq!4*q9?D z_)})cp@`-VuVBc?1n*%>Pj+TD1WvZ>gsK*z=~PT9Pv5Sz=5kp{0)P6DU4TJN+F42_ z;D^-ixO6&Rpw!n%fEN4qnq4g(wlNDTb?l+Sh3n>>l{#jLris6PV4be^T3Yd><3(diEbnq=2=jg zGMA1+N3lQ#bR1$b%>&@*oPiZ8lXr0P!BC34r<7fM>6!5{R$p0tWTf=Bfk!v28~jnO<2GzCpR@0?z8I#*qtiv1w{IS5H6Hn%FfDoQ zyS#$a!oFfz=5gQie;n;n`i8z1lclh@v+%??SJG$8qjSas$!DI7I7mWurCW+hyw7wvV8ToCNYMi8AqhE@9fR};qLt3wjYn}^ zs_GsHO32U&!a1i@k7LZW><_@LzXze`7_w`&8^$Fuh2gw~m~lCvbKT`;Jv9{bXf5f@ zYbKbO=|ZcrM*o0?g{-1`t2gjh2|gpH*#$?{6SZUk*Gs_;~0$_>*xhON*;%m zx2Rnsd-*jb|LPj?AN-oqQ?CJWm!B+qkMw@3`-5^h-m6+bO^yNYCFb>AgPBys+i4xJFRgggVd=UO4$0bX~h<4<5iG{lAN~>|tEtWmi1=2+d*05D0EBgCLct zG03$It433Z$H-DO0u)$^%^hYs$FvB{WoB2r@DxHyNS_X!tulSFG1q*xewF@i{UdrP z9M~25&lsdGCMXm1ZNftR5@DJCa>G)~lZL&^wivhaAY0VFU{L>XEnlgspzOwnPAnPlY1tcp<{w@i65C{Yh4wcdev)sbCLKZ4`M zDDtcD$glja_^#E2;+Df9NpJn-$S)zfoQFZ-5Mo8+YyE!`?!`7_(j!0SlyI*UMy28b z;a*6$@dz(Ncvml#{9T>IVbb;I@ z={pUw-(Y}V!)Y;BMusaBSstzqL6p1v{%{v)hGTZ+xiXR7fz6PPtoQ&#t%Y(91K}YK z7OhrZrBXqy56H!X4xE}*P}Kl?DBV6ZJELsa zxmBgg$VF^G3p!}`U&$?7Sdr= zyO}5$#5eVFyUMoRZ z23c+=^*PK?gHG3uR6j`)WI%j>h!u#EA#A8Li2RcQLM6ytl4NG66dy;jnpkOg98R@C zs)zK@uQyBGC{NvOHW(2$1Q7<4bE#D_w3}Nkjs!g$ zEo?|nhe8@8?*uu}zP~Mq3VzM>>OWacB7dM%6W$TaT=L)@jl!6iaS4)*MerYhiqDQg zkJ7_%kkNM=MMdnE4I*-jm~Oop@?Q$^Q*era3L40|i3Xfz`jXTksR!jlP>b+M@~AJf z!6$yg8Rp;UjZf65PybDq%SLGT$}NCdh(fx%8?y2`gc%{%tryLrNo;3Jtw!L}Z&UUr zpMH4A%|r^Q=NX{ow^M5ysOpo*h5#-yw?bqiD$&qaBDypj_Q1{US8$|>9^ z#gKC9e37mfyRUk3S)nD=^}CfTe|L36ot9RXo9QdeiHNtW$KJkaNbTh}ytWC_g3>!T z4z9oPeN_#y%sJzlE>}N4q&`0M^!f`~R2vg^jL%kY%uHClyp+&+WPgw-d9wz{1B9n} zlUx^s0%LAp7_%bT!yo{zWU?uYY>i<(f)qxbli@-bZ0(^jJn68o0;E{@Di1(7pz#AOIiw)aQ5o5dd&J=} z(;|7fyjs3r*2zx+T$iwd@xv~53%iePL&hf6EHfD;lXv!TNirEVt9!K7e;A53_?)US zJw&UVPFB}nPna|`>`_+!jK>`lr|yPvMe%Xm2JVJ#2x<;s$Y6o$hNvTkmlO_GN4z6; ziM3)~;QMA!uGm0|of(Qk?aj5Zt zkkYsw#pWckkYJlNVb^FCNYb2P%1aug?)9ZJ`2uzITJ`u{>S{6KPaoVyD?oSp@uzg9 z$KO^a-}TkH+fmlUBomNzi1{8{~ZhZKf6$>Ek{XI^HPiFQnirtvqx6XWu>eF}R3b@NVQSn9k~ zT;-a5SNl_6)$;-cksK>M^aJ3cc!G+#Fq&uuv_P)RUzhPA`OGPS&jx zv8-_RUTPHErMIDqs`Ugc67+-sCj1pU5X_cdQ>V#}V@EVw!sCUA6}5mZ3Gj<(CR*Md zB7aab%LhDFUCWLE6W@GK&lTyv>siztJuB2urnD4x-n@R*Kdxh2u01QNw%1|Ze?yN1 zEg6MNW5%z9uQ1mTINHPBj6wC(13=G+Emt-QNELh&r7uuP06y0d!~>0zp<5P(Zn*Y% zjY>f0qO_50kR-@8W4oy)$ehxsnh(=zX^mpfIYpt1He1?!AodT@YxXP~e&So^QNNa) zD$Fk)pfp=N0z8eNW4`wRb;QWUV!2G|*6R#n`$C!7<&Zo>eop>W{!UiH@LAKtg zpy>N4Xda$17}K;WIdj zK456Jv{{UEjW-xYgRwwgXect)8^;)5#lp0q+c9I}oLcR-P9Ee- zKW=M$_1xO5v~f#Ar92k53QLgMfu#{~`H&d=4tPXYs_$!6JCw=C|2?rw9IG?-)$7n< zpB0qhc=~yWk~Ii}h4W(G(#j6K$&_v^sp`lK294>W(U9Msw@2L6W2kL+;w#G9XOtS+ z(<`?bVL%qrRA_1>^WD0b^D{IU35Fa$0$+pvhm!)C2i!v?!pA;b0AX3Un{_BT8L6fS zu{Rn<2}N(3jQNZBH6}39uSm)pkP}my?P(+CsRzcY(}t-Z&Kr?t$M#p7D5K@)?iMo-}Rh4qdjCtvucPiJ-@aq4$&R&RQFNYsH79_Y;`w0mUt#P>BE~8KwtP6@k(FL2{P9n6McRJHE+k;3z+Z=Pc zn6q7Y&h?#3T>Fp&$-e2Xd*#aliorat}^aD)o|k z=M&Fj8;6V@!Mf|;d2*#XZRL~i*0Jspqv6$@_*NV$Y$5J~J{FTfY)bebAzgv> z0__T9!9i_YQ+OgaETV`gLR-s=il9hkYV#3u)ZozaMN=1e7Qb}Qnm3mE7EEnzI9*LI z%FHbc|M=rk^We|dv#vkibl<4c*WdcSx?=t3gUv^OEZiij9gX!@Cd5rZ_Ut|dkOLJCfs-}De;==`2eR-0 zwa+?)KcT_^XQ3AtF>5~?6W2z2k4iuBYacrKS|(JKTR>w=vCwg?4a$s%__do(y*53V zhG0^9A1=l*!!~}chHiAc%6ovQAQD=j*EHZt^xzQ3L4bs#w^s2Yyttw_EAFhg*X%I4od%Qc+{oO>(#Q>w+asGJdr*x+b)> zY@Tl`Wy_itsuwo7D()M9!O9%A&YfS877h<#Q^b`^E}7|HF|_Vie^86m9eYMKoi=Xl zP15*8&8VTHW{N8&lya|Vq(mo|G%yp#$BIRpHS%gW>;al11mYf3VO$ZdrrdDYn_=qA z&CTd?&Mfr`onl*m{Q#b4gbB^}_XeI;i*OXqJb5tXJO=`Xn{Wo2%{kdpGHyUA#~RFl zEG~9HUGVo0KKaL*xt;6pxZ#1;N^eGHpt&g{H@jh;`jLFouGb%a;K3PdExzT`)lYB# z9rIhO3!B)K#xqQhOXm#P-Bh>`kB!t2pf}P8dwq3ml*0*efcaX9F`L6NU#EC<4yR6W z=!WCqf)mX$qs?g6OOX0f42oYV6bh6&MRqvYI=G;)|85&LZx@zq6bkP|lBqa61REO} z-DV^OXuH`LQK*jUG@*BLYDi0*a$IriQaNNVIR_B#zRme(7YNE%ZGweCV+gK92W&}dd&rL9sC-I z>`TE;@g%ycK)4O7@osVBz?U}grwxv(aU2#oZ z-Fs1G#e6kuNg><^rmbW=ff8Z*UWmn(?+BH=WDKE%Ppo)Rn1#cR{J3Ne#2xxN&nS-= z4(Ft$6?c}DcxILvm5iKD*o61^4D9Y=DT0c)BKu&u^`spv~5jA?tWpmdYIrznQ>YXJe)ur)qaj#7;#bv=^bD1*3>4MkmLZ!O&xXYCXxDqR#P8WO+pwHSS z(15SBZ~(;M0N>D8Gyp~bw}zx>+y@?8G7S$dJufabD8GW?SW@$w57j%w=X#bqL-ifg zfA#1~_YTV|sd=+`Y*=c!?&$9Quix?4JC2nOO0$K2d)F15jKzDFb-&yZ z$XmX5+c}q98gq#zS5c9>$)CdxiYqUFWc8>~tA4#Kabs#;i`8tx%+p8BP@ninUAC+` z%pSvNQS=EKZ#bg{V^(FE9x5HsJ_7BNK(6X!?1>JeFm4oZ2f1-=^sHg~cC@fgX~&7W zkrVb8+@rOltC4HKg1#))>~y>5>kS?VZ|Mzgw-b2ETEXps;Su!+0Lo5#+-9&@p!xx$ zrWkCv4$7qPO4IPpx;77iUfeoSvJJPtFiU-w$r+_nR=*4~Ifzx2MNC2`BTg4#Vm=71 zq6}e;I({=T`>q&#-hwk5M%FfZt`%L0Z{-Tr!sJV5g$(=4OVlsOzN&aupL5G}Z>$yN z{LFrzZ>`OYLNsP5vjo;^#+I2CpUp4WTyeK4%^VO+VSlAR=9m0R+^>h9$5=qH`OK2v z?qV@lmrHa#?|;)Tx?+A7^Dp;{eq05c3ygMgbTLrcCGc>uI56*`hbtD7_2s6Qe#Y+* z$-}%t2!TjAEclUsm*WPG%@+$+j+^v|>(a3G6quR#v2AkgkAK|W9Gs{GT=x9Smb~bw z>(;$EKH9v0+Wr#>!>~;8J=>R(`ve{Y@x!KoA65a6z4i$UAd&W%ALY;?JA+cnf?_cn z)){BI>};LT=A?H_QnsX+3= zacKz0Xy?vVcu%A7ek?qZwXsEPInzN-8_e`J-9n={Q8&W~HA1`sWQ8C|4rUHuW)y1| zQ6f_|8j}wKieb97l893}#LaL{NuvUqCa8C#gfTM$rj|a#E$$Jg_I!t&MtqHh!jS9o zv=6T^H=Dc6Qpij%X5eM78Sid3@xw^#;*#LuR?7EoAmimvokAPxlTdO}>OsTueDyf{ z`|1}jS&}@X(Ak6m2t#QrcWs@t>Y2pfUuSa{TSG3dCZc$vejdB`>krViDp*_*^Q}~P zaC^Y#Ba3@ZQNE|BD1TJ`l>BK$7YG;RU!H$Mkv_jDEChTZ!MVfbGKS+Jn^_+RPN%;E zsHNE$@TGeSigJrXp<Rji;xV3!=^D=`04~B^FOFgN1`1j$H=;ITlsQLUT`@ z8)+;s+JwOQqkWa`oJ@CXN-GCX8VR36#iY%qy(bMD(JvTo$_xGJsmdAWXR3$AS8m(6 zWYTtLxK6X*Lkr8Q-rLYBwVeIH;F*&KyZ667?B22CC%h8ADyP()G~*?8)m6sgtYeE2 zTHv`CxF2qwA&oTj2Mu-p=&|ZewjLd zid^yK@m;#H^zkM6MWcI%gRb2ORyQI7F)u>7-ni408Ha>sr)_4$LtZKLpD5;_A$Z&e zMKM!Nbetci;C=#KpnZYgIJupv{bA+y8A~GRfoxY%vCHtXPP{C+GpH9GIUv21aEV1B zadW(R819sN0_aJuFl)OkL6*WEt4MQs($ZWvq%lbjnbTYumbf`f3B@z?Knw&|8iYpt zj<{Z*H8Wr6^ta{l=TglD6JW=ZUH~Ae7J#dUByK%IF)k6=Z&wcuckKMrEJO-53e3|{GfPeYxA)45^I)FRY+pZeS_Yi zc2dkjJFjS6X2<3W{=m)KMUpm35m6WVH;;$E2dLzwB?f+1%Wr6&FGf4h6Ex?tQrpN`T6 zz}Ctt$SaXHzx0Q9&K{ANGfiCBzXmQjujND)%E8m9D^`!p58``TOHQp z%XI>6$UM%`B@=PR#wOo zvS;YBY|gZ}H|V!zX4#k&N4;RhYE!akgY(r6NtZ>{0HcI4 zM~7gL{9jV?0=8dxK?&FuydY0OOa15dAb3f2Dh$#0A_YXFWHtg#ZXDSlnM$V#oY^9h zJ4^DBv-^440X`txIOlbT=$w7rZv1*c`~LynM;o=ck>~rEdB}`h3(N@eSMj zi_{lHTOy>sv?)8!A-!t9coFMPY>>j-gBmVVwpp&QEH>o!T;w{(Be}Wu99sZ2t?j~U zEHK%t^bSP=7)=wj!-VH^mao33gkUwCw!7EF=LJ+ zyVI7Flb=U(g%WXq5kvojA2#s0nog~lF@(Z`O#`SsZy;EPnS*F7H;NjdMzaS$VxR6i zP{$UZHn_yg*7%ACk6?@IWBcwJuP!|C$ze8Y@0m^8R9*GyI;cO4tYRm&HJ!Ovy?4=v zE7XzfNo`fhC*bQ2f)0PEv^2-#tEwuB`%rnpoRfot62ivWN?7rD%1U#dVq=iiEU_`$ zqn!wWKHO7QK)3jC%vjdBu#}aS!eY}hfT{_6tV51NL+D#S9Yy$Jz}XjT!ijB})E5R- zKo$=EEtw_4ndt$7;h;l-Bw&X0KWQK=rYb|jNT5Qr?!xY}>Wt4W-4Ll-GWE_`o72;_ z%~k&}E#tSBeVSQS);+YDtt(Eilb*cUqWeHM^xThC-P02;E6-`4Fn+f9-iRIS_$O1F z@jsTE6PL|8O}sbJmYzRbypfPL1iHkvs3nr**a$a&mSSw$oPeRAGR|3Ipj;8ZjN2l9 zHAkXQN#wachNs5|APVG%f!Aw%F5qk$s~$Mp(<91qh_u0BkTq39^F z`1%=#)DQUtzjiM+ci?yIJ*{0P)Yo}{$<_C_+k%7Kz%1>Xg-iReLBK1Jr_i!UIF^W+ zfqXrl81^*lfG1(36!qTwkW1qd<{jsBhh}ST}@FTIdp@@>8 z%I4%;0|dZCP3`7H{L_LtT2e@w?#FeX-c*wpE}X7TBW8B-miCD^G_nhk_2z4ivE1vM zA57%P4V0s$ZfG7pZq>CIf4Y|n;?l7<>At~1-W)?T63a zKO_a%ExX>j@yWJ9=cs=^A1R6jCJM^~s{{839uFvifJYXD zEV-jh%IfeKyP#E0(oh15P2U(ZIvm2%=%OGC($50m{@l2|Xl`IHbfb{aOL44LqQKDC z6k^3!`M*+$LS!qcP6YQF0SX;fInkGJ=Ek^am=9_^57dfElinolr~CqM8q}Z0jG6S8 zJ0JdTEXhL^7Znut3q@D6S5IjGSPSHVVKrcWP-sLv$24ixuiwgd zmJKo>+V}E5RxK)F=~8JduDb*t309!8lAq)w@JJkZbRJj8)*)LB`fdOuc%zuxWN3Ff z1>|ITLLqCgy#if=O4SoN)(UVoXs)7w3tx!Xaw(9(S0yb~J`YCQCQ=MN@hQPRIru4j#64yFESK=xwJS z?+RHA?Z#wA*-_qcURRGOe%c-I+ZfPuLP&^{c5<)BPJeE{8tA0#vQD;f*o&{s9?)q{ zUTR4^Esi*)$NkpMM;UK|H7-d`pR3y=8k`1WyJ2Y{?PH&#-Se?CW#nG6{aD??Q})$wm``arb_79DjRp8W zl5M&Y2d9-Wd-#7G+f>UxCvLGF*lFhhVRu}#>A*&%q+bE+C-H^6hT&QqTw#;uc!=UdM&{;cwd zTTw{&D`pp~avWlDSx!|bRFxyufYgQ~MQ%Z5WkIe~wnuyV1h?vPZ zPa!8lz*B8qO)kC^00qVw#D^)se;Van202apX@s)?AW<&nb>|t>4P`6tQNJi-aeLOa zY-4w>k;Ti@&+oaWOx@tf1iwMtBP~>?oIPsTayI|cD}$o_pX{8jX61}A>Vkzj@%{wR zVz#zrWOJAL@IUQh@XAZob<2n8$BkiI7D@>OHyDt_&!iueON2_)qZ=d$LF;>gg7<<8 z0s&|Cf)dHOKyM8MtQMi%V|C=Sw*1xk_vb&J|9rljpI?x5LAmDwC|C~NCHy>=*(J9gQ9t2>M9^JU*gQrbLtRIL`)<(mm zMlChRr%iqT;pY#))eV$XWEG!v`RWl_IeEn)b^hC5v&f&uO1}x+q@H-;orNo&`g*zg z&$$hwZ(r0pB^|XR#!i@ac5Opz_pko)+kboQhNX1RWM4GC+as~T_lc|ZB1B$5YBd;S zF(y&r5vfvYHi$>1;|6hu^pru|AU$FbFO@nCNPt;o5Z6g}8AKE~N6mAPekaAk`YxnX zh_{H#^{9`61>Y+k(Tm@SpXo)r2m&V5);PHm8Ug*}%EKDDl4@-y$(8Vik+Oz}^8jY0 z2xg_8Gb^!kO0=3md==FD52&|*S;^YOg9)V7C-TGtsU2USoNx9H?fBTm|D4*zon{#< z30oK$AX=7><{gj%&P=%cV%#2J69U@;`vOuR;MNP9(s!r7lKx)0F5R$4comsvUkg9N zt|3MxgQH|OxXdo7WNqHbg6-+88KAXSBSp0W>H72;2b*RJ6wo}-!Xd!?@h_tI++JB{ zW(wF11jZIf5zwQ>4xK?4W8Do%<52&NWr5}2pmvTJGgwri(~xM9R`OY;sW-@gMMuXIC6T!0kYs{|b+U-^bDlbcVvNcaQ zjfiJ*PZm*S&54Dj#PFWvyXvN@)B0T1lYCQc2K^tvFD4J`|4%mm|K{9VY@MhwZ(wj& zjXF3rCv$K4e875xlS)!j(rf+uG*%9;s9_WQP|S(AIxH5O9ho>b!+%;sV;9xX;3YID zUa|Nv63hwLg?Ypjq}&{c@M;Grq6XIPK>O!((ZTg&mGEhga?hqvosE=wMw=I1giX+AC!?%RguXa z8ugFudykCwcL0a@ew?(11v`g~?Myf>A3eJJ_2%P$zW4gW-?9(3ZF{hF^?RSAx0KKF zzlPJh9u~qWJWREBM9$yzKw`@76eOfEABZW2N~kS~cJdwyBr{|@lpjIcvb8}yM+iCb zOLm*X9~$KPFQQ1;(3l(J3!_?Ls}!1TI-95cG{II;QPN5~UGUJM*2Rb) zQnH5Q3+^J2Qa%?HZK&6yJPG!~e!k{zQ>{7Mnr+GE#7uB9>0qxBKVT-)nY8|r^r74T z_+wylf&XK6ad%8=h<$1K!Cc6vw=R1vrV`WpL;b=WTZ`^%&aqr0xbBApx#rR1@1n+hl~aXdLVk zMdc#m+USOs+iqkVBl*+WM)<}HYKLupTv8GRGe$iqevAYx?)h=9yBW68VgOoUFe#!4 zz+#WMwZ{M@Ied+|4DB=I`;bo{&CqfQG$CtvGCaJ3UI3_p1R;kqI9}w8D8rAr_}wjI zn>7@JBN-ekQPyzZWKzs0*!V!=okg)bWUsJ`cDuP9vCOSKCX6Dzxx>^xL(eMpGxYZ% zM5xySoT;})z9J1Tz5S^JOoObfQ9n8MCEK`^dh*ao<4l_uoK=v!bbEMji2voKGrp{J z7(_bf)4^Ug;F$lk*u+6w$j&48hT}Ih_I=4WDWs1MlqVhY_i%jg58|TXFTQdTvNuIN z1s&sOd}TU%Vg;fX5NczYt`4~00Y!9ocx6DHI0X9Iy-U*#ZtTn`%L9^4ACd&r5f*hI z;BZnu=**jh90;#V0S?jug77%h2%qvKd{KQKJ?Te4s82;PFYgg`i1%lyk9URYPEc29 zJpNTDexU=u_|~*z6Z7+sG9BFcnLWXmT*&4e7AtVY?e;9Q7EkcTZ$nI2x;?lhxF`5( z@crOVLB;9RyX-uNDQ3wD7=nhbMMynu%_i5Da+q-nNB?l7_*sYn3kP5TsZZkoN(J5s zVbqRW5fuNC4t@2V`UzWidbR7DZ#*Sq)%kBScK9D`&tE@$o3XB+W{q3REQgq9{E)UM zZ~T1oA77%8>ph_~Vhl6E0BwymDcutoB>_s5Dww^-f`pc$H9iCKoLqH!ai#0uU1EN_ z9!Y&S2tVPs1u3iDwX{rOFeIh@j~Yiv_(yP$P}PG2wypHYDb$0BH&nti7Xy9io`{0u zE>eDqxZo0c*q4X}%b!`X@`bA-;Z(w>ScF8+EI%cBLJt%Z;pw-YT2|9=!~1GNJ%r59 zUk~M(pXzr~&YW?L9VcFB9#Kcw3=)teq$y)&AbRzL1!4QsVi}?+_&U-=yumt=OJORZ5vW%iHh&#;TTp{=QT+uQo7y;9>RCG@VotsY;%9BF9 ziM>KD7x~V;-mQsz^JPyH9T9h)lS!v?4Vw<&CAY%F!>vQ`L3;r16a%-0J)w4wdiRkx z-Yix-@-CY+?}_P8zLF8jE%Gd%8A>nA_eo{v-nnV{nzz*5i8+^#8rAXIg5S&^J-&AG zh0Qe!)#paFO}n6}Vm6IE#YVqGyv-^^k@Z|yEyr!YFDWW2DK9L{DT(KcB05Ow*#bC-LBf@T^9`UeoB%AV*c*wXm zTCGb`2(=4q#j|8{NvTk88%G43}P;2@`GeRL(B7=!Q~n)cA|nZ=v(yE(t8En zr~HmQLM&znnyIAFO!GP?GJ|*7JAq|(VDGI2me~a?vm=RR{s>1Rp+aBeU*nj%Pu1^% zV}3v7%=4uSr>KFsS3ng6${^y94)y~(yXu5Pe95NXtUiU_P`vyA)<+ij218>$(+>rt zvB8)lCmz(xSQ{b8W23$)L2d1Nu4NQwI$}#hjVPUoUjziu-h|2 zlBE-wd?1k+3iX|N21D~uS{fRO1k9R>3Ju^qdbs}^T!4SrQtF%QInIgl8f4E1$sx0h zFqKCip(87D`uHNkOJruju92IB05)ZA;X5K{=#gfIm-4sjm1Qf`#S6;R&a!=j$K=dz z51n4dy36OWTe`~F_2nZ%?L)?9&)hd;2J^2>yd*ZRRR3~=XV~&@9vbepiIIx*##udG z!-mW_xKh+5POLnL|Lf|R)tFw9p;yv}KlIIVzQba5y@8P|7bZO?WVjxeD%p_@s+Gg zJ8$Uhs(<#_%%^5IENvNF`i!A!aK_o?Q|CAS`H3ytuYk4Cd}iYA8HEWk(8iPCrE;O+ z2FerHi%2X*-nv*0_g#-yvREc)8Qoa1)%`GIU;g$@x9< zL{!H9CB8y9Bl+xA3Y47L59kizj9;cStWc|zaKEh4f787l$5GOV;fanY;$ye8?EDkOzPIZF ziCMevDfocpEs~x;wmw^h0jbo@iE-3 zUdV@pvS3g;ASK<2!&!NcQQs-hefA-Rhl#~Zwv8V3Xlc88@hwDV*9DG$&HWZsvBjR_ zhG#!~yTifgv4tF2R_690?Z&NS#jR$DvmuqsI5Q{Ri5$K*`0oj%cN6U?<@u7)<>Jix z6e)m1aNty6QV;ZcYuM-d+H20#O4**Vyk=l6Te;%0Q6p2eY)781z9}D4uO3j$mLfra zkzPV?vxPJEqK4J{nBU8oSB{7D7D{b&I0fg-Tw`Z2NiJ`K$Jjn`>XU*fE)T?n|j~X@hf_v|~Z`0YAz4be`^x>^5um7XAE~N{#C$(E=66Fp(ipQcp zsI(5^B-ixlpdv+k8tB2C9E{E+iDJ@)U#kn?si=QF{}=q)AOd> zvH6GTwSkY>!s}w7CC9$lI6wNfJL2fnO*yeb>LOpWk@J#OAcbY96Le85+h8jxQH%|7 zvrcC=<>dvuRdG*xx<~JW%<5FT7^Y?ZaF4!*jNQXAr@>#O@AQ>FXJAyM*D!>RIFz*m z+AUIH$nwD0K!M)@by6^v`(EGy@R>^!R~aw~cq~*q!c(zT?HGsCX&&4Pex%ESZ&fRQ z6S<=E{%PvMnGemsI+RVX*&2GCr7jSIq3o>T8JUTr_{6_qYgTP)U#jk76-!&zt`aNh zJ2p~%n!Zb1E_Tc;&Z%lnoH?g(gxE8uuqkmP{Qz?cf23bw9@vFH#?1Sq=k?E<_t|xN zGnVd7(JnbetCms|Gg^`SuNMH|073$01=;l{#dDGFf9`f`SR7_z9*ndBpY;O0Mj{0B z#4_#r)zWJ7YWr&0VRd?{hgUdRvy%Z|CN6t`#&L0LYe~}=_~R#;8TuOxI1V4~%eNuv z6-xbQ98cC3At@K4;;pQ=n9Ww3)lMl!{!cTgw(utqt+wL>JZC5O3jk238sNKipY;%pw?o^hhQ}VMMRq+9Mb`WrF04 zLgzkGxJbf)r=WmLGyi}j@SX_Dt~*x1*5V8E>HNp`Yxjt|8{I1?9eiF*j9IJ}0}Y}{ zW(ro+h8=JuI-!oRwMUOJq_=eIJ1ccFbPIKhbo+F@P}`&3KzfQvbC^4dZ2jD-=v-lYTnDj3CC`TuChdfy6=-Ipeq?WNYyhj%k%}~0R zd=K6)*#3dNQlCe6XvaqPjwX9n8uMrfAi4zv5Mu%aQ0t8b0v`PjLBQ0o{6Zgo>D_52 zHuRp5UX;tAdDgbO(7)Nf(Jz^v!4ZWCS*#jX<<^*Qb;11wVnKmDC+;`NaXT_(vRFYU z^Z?6aMkKizv*s8(O|(Lwi+1=69L>p*&)tmY-ng zYzttJ-LyL^obOgIUi|W=cizcbxU>7ZM>;auvb>^DWVht{YH#iGPb*p}JX~Tx`L&|569VOgGm5(A%BnznEh**SmD2jyK7r6O`oVeAhQwlou7;u!L znpq}`of7qZ0R9)HNnQaLE6Hm@&y$`c$ILXHjAZ&zU$P6Kn&OmBB)0x$DY9LzzV78K z0?0yod|(Q2Fe3UANG?jKu2ded`pm9v*CD_C%Jo<77dIl^Yg(fF65^c>M+f&|M!1Cx zu+}~2SeQkOqog1(zqAgw;?a!L?ks!2A}N~por&T1H4r0$MxIYpB6R!=_p2>p{jlFY z_2Ti3>dnE{MQf&f$(8~2ySS)yP@`xXexACP)pg8m%CfHNdHK=A3v5Vqy0fhjr!bCb zP|g6&Tb#mf=5-k~Esx?dD%Hk#?XwjB-k|Q+nUpE;@TT^7JJLY+{j3MrAfzKF$8wE= zWQ;3Hwob@4dA$L>J`z|5hfg*|*6G;laCT+3m|f9|;zv}Ji6dz=v$S|j10iZ$=Fg3D zFR*1KL#F{fOHtp~1-2eQj zN%uUOnDYDG%=`Z|_Z{$27J2{AJlnF_luZvQWJ3xBQZ_vy2_%GU5>kK^dP~_9NFxOZ zMIdwmML`f0!Gd~12p|HA1w_on1}dN@o)z0Eo}L^EWHm-?h zw-#>fA-SPu*eWzunUVInaYK)YMM+$Cs9)<(p4M&lAX#@n`=2`29IRK4asqWo*~HhdWX)A5AHll^Htn+Vg$FoQSl-$4C%JiPpqC!V`|5V&P|f$4C`Q})_|VieRd*`ti%z>KS})9J16JB& zBP;AQ);a%v^}tu!lkJ+UUZRI=B^?7iWC)!DoS0a0cH^$gMbb&Zo?iV&1y#Q$1R5hdwUN!C0NqLbiNB(3l;hU0pdeg_y=$KbL1=JTjUCz9Nx2( z_UbZ*eWuDe7>~hlMeFb9&y@B6!kZ=9DE75^4%=&nlf8G}HGfF0G1lY12-UPmxfxPJ ztD-%HyUrf?mH!*tJ{zn=zS(DB{qf*MTToQuBHj$2F>v@Tz^inp5Uc*AbmYHiZty9Dss0bW|2KQ2AkXCVx$ zF1`yLoYuIxIbg?vor_ZNUE%@XS)NN&WdW|vOSGiy$&hW)CeSNfo4}fbE-zJq29La# zVTIIcMzBIG`#!@8>D}fAcJJMQclLy2OVdt3vLDP^$;QyT%nB?d%nqzXdeB$Mhqn^A zg&gWGpW*q7o4upk46NqxRogpZ)MqDb^DXmtcDLK+q`9ucL0F>tHvI>1CEYG*KQi}N zRUFN#-L3`2g_4q!bYK2H=sua9q}>J$s97&7M4fv!A(E-z-?pk!M2i5FKo5LAD)O zk*(eK_w96oRMPbYG1M?iCke>?SO1f@4U2z?V#| zW{M@~$wxlz2)8dp9tRrCnMl`T0vc^GHO0Igak0LnR*2h z%y+R;+fG6cZ~i^c-TM7C;P)cOhveZav;X872PZmXz`AA>_>lOGyvWlT171R=aJLn1 zHxJ@CE8JvJ5q<3(WHbu)PS-GDfhc1&3gKb7_6seJFoBAU*7H-u?Yw{fTIPO(c72#* zRGXmaaVO8j!pXUx(!3me(ZRSH&0pN5wCVK@KQwZb|PaqXf zEHGT5ym?bqFpg7AmLo31S_n5G`WZV{=6Kfi1Zz8rBXVR=P0Np}_X!NsR?CmLmXaf! zm>A3wLWx{W=4LL^zkts0*-~6;QY!Gxfu%iavt=FhT(N3#nKqn5QwA=2cab`yOK9xAr z6|+P9pwesCxaCut=BM?XeEmN_p%oUAI--6txnwOW5_`;lWpZ=xMiyxPm<1k?ual1a zy?lUhFt+bg_`q%vGK51%BhIEI1wJQk##nFfk@Pe_ifUM7y4#jPY!D1}mxsyR54hTk z?+9-zPcTiopH}OsNls21HA<5v_$8&J%hKWk2M?0@g+zW4@jSar7y+*}_Tq$NnyHy- zC;WU)u)B`vI{a|B<&n4(A#~?Cd5rctdXHDG!1#3i>a{E23V7ndPg>8m*8uRuEp$Q402Y1MK?DhW6 z!A_Mnd(6s>E2im!$9|W|R0js9J{3?fCH<8vU%WJ8+PAftk)t1M^m{5b=!r8B7_3$K z#U4A&V14j}hneZZhv{zqKEogK@*XlHsA>9&>4&DDnl7Jyf_-sRKciHWd4iRvyXDMC zQ@NoNCI&J1+!w{5AU|?#?dO3-FWYoyycdt{wO64@hynS60KTXgTc-Q{0!y8f z+s}!@EG7;7VbHOVh?0RsG|IvLS}%0-$&Viy34X_~F#DVinX(VdmyVc{+vS7=1y8)Z zLf`%I>SyP8n0NXQ3Dw19Kk;P7s~;|VW`5{z{1CHv97$ywX+4lieE99&vzuFnW#^?yAYUcI#i19Z6%()X#N1`;DfE14u@VZPiM zT?KK4bW8xYJf}U6laIs2av_st9FNlkcxgjLub1HU+!Z?>&k2EeYbTZ;VS+C$zH)Gd z<6YU{5U8qT9GSiRNcz6y=fvegG~4!cwwHG(Jqp?9PZ!5h189ihFZ3oZAPOfDc|C?b z{3`mg7?GGj9gCABD0TF5Bs=(kbp!tJ837?((UNC%TMYSut-%)b-dA-fn)5On4xA`;5j1L+@WZ?T!K$R^kv4=I!S1plrF( zAkQi9$PSrWlE;EO7ANH`t{OUGXPP-+s7GkRl-@U4NXwF}(w2GVzdgNZ*pw0v_Rz@C zH1pu0?jdN!mMngtT+-F2$xOp z`>qYbc`?3Pt*@4Nl^YJ=r{yYa1%#X^!WFOquEH7{s143t@RF1WCZkJ2q7T`oJhTd0 zTNE?|^Gr$pp%L!Bp&MrAPm{%I9esVr`lr3SXTl`&Gt*jvhLwne%^yxkoHIOP;+~cJ zha@Kk`1l0m2eUGEt+B}bNoVCRv&Wflk_JE*fIKa#F#;GSgfqVkdqD>da0Y*b;_4+X z62ipI=_%n`ggxYRQN`476R)xxFaKEnce!k|9D{*d@@s1Gr2ME_+%JDjEiRF_s>O}+ z)oSqp`8KsEr_Di1L5@}|BSvW5)7@vg%beXuyN`EY z?!MRkkozfjmHSCC5i1mIBVFRSRZX2W6f)-{Q`_-@h1H=ujH%RuVZqeDU`YiUa&a%4V{!T}KC34t9J+Juv}J`_R^m7~%*o%+ z(R`n{%Ct<@E?&NIK-#)=>zu@Pt#i%aaJKVgyHi3(nFIU-Lccx$mYUZ0k$kB<2a-BS z$V~UdG>3Z7D}tc*e8ri`UQuflN~HsgpdCkD+kFS2>Fzkq z61`~Ynh+l+#Ks72LtP+RDi@Zq=!ki9&VtVue{Ft`jrj5s(`&w3dg$O{(apTM{rZTf z=CZV3da*U>iutQ?EUdlV{2tatIY9U5p?jzY7K9nKMEDK&b8vKWTH);A?(B@1vxCf8 z<1<8mHavXr(6g{Rl^=~iJ6NMWfljIYS8I6ji$corSL0h$S9hGhqHiU}d4rO0WD4h=OH>v(A4cQYZ}bu6xHMj;M`IoHzVpZqdR*EL`E5{S?4Gq&>$KCyZ80!7Q2zw%|Ru~GBxr1~g#O24eQ^!X{B&6x7!<#?K zK=PG{SEHb33)ZJS3$kK6)D=$FFGz6y4N*yeaCcX(nF?n)<9Tj&(L2&g;S#`Apk%xFDlR7%gbOykffYB}RL+WgDy5W1W}^ ztc%G4_Fem-*4Bed@*_tlD+k~BEOAW4?sc2fBGWdmpHrRNl{Ie;;M-{~#=0Hy*A4ir zAVs+}5=b%wz#IVc?PW*tf`1QYKx!`Lu$ipD!)QUU0V)r`iKRb)awmX^NZYuftU8B) zkv+7ytF^UrX?|pS(#`3LeFR!0A`}_{lH-LuQAw9RN4OwgEsQxm~(=Ts0>K4!U1r~ zsyPZbt+$|1+Yhi}-_7Z_V=zEio1SP_FsMLK_~#3GE)MSbE^6-r7ngBNo9n1>$dN}m zHad!q*=oTh*WJ$}$6x0@$6a*KRvWy3kIMa=3FrC$nnka{KMAZ9nAE#Mm?q?MR*q7ZazYNgxt(6&_d@BUJn{VT0amLuXIaWec<$`x?Y|S~k6dZjVE2`F{Cumu& z+(D7!sKacPDDSUYlzSsp&D)?>kMmRHvq5$REKlpLF3@^7I-x&RJI4q1s$hC20_+P;E#QHj!LPwUKyC-f}A>Av3a|y{ip!To5&Cq!lx5 zZCp?=78LF`O$Yx`eS?JU>7#@4bUG~U{rA-#q6l*MFIAm-RsYrM(?r0(M*+39;^aR> zgXxBN&J_J`k#XZ(7s(@*tfc>n;C{%z4)?=Coe-)`)ZK ztB+4~7nd^UFF(3(`-N}J-=B@_ET<@X*SxO zRc(}=m8%u3!_iJIlwySzE!2yN5u(1wu#c8$x>3)=@|Phy*jr@%$sfOVC;mY5oiMb- z$yZ|htQM-%W9(FRYE_=(X4+1TBaZSIKY#EBrj_zUl^Q#bL`9x}Px3{)%eNB`=S}3z z$eU?7XrEmcEf#FI}iDP>g46 zf?Yl%^4!Cr@dq^3O@|A6a5vuW4TKX+CJ+wi_hC8fRpO)|={O5+pcqP|q5TUU;?ws$ zJwG!$He|4`Ym}FZlf7JJGO64yf0PkEEY8_J*TK#$a4uSQg~=p7&0)yN@Bvi{(G@Mg z*nv)dQV0_;8<~&0Ja7aGCJ^vN55A~Ii|dc)_cZZ;QFNl9fR%s*Q7ktKkxOZG76-#j z0&7V^yf{RHC^*2+HBy2|+4IX)2_mh1j>gVI2Z;K<5j_>B#k1fNUAkJ#V=P~$5apzR zv~OtNKua%r@|KiJLbIeeeRG)NebJLRUA)7zRTiPjLE3<0tU$=;jNS!&A(?3_l07RF zsB)U&G4jkq9HN9P!4h>9 z`88Q4^wEARUN+6^63=$sTBaaR2YufFmT+5+B2qC+jtWbTay*025?Eq>lOrnT5+p7& z)yXouP`8_J@!A11FQaw}VHmvoknEyrYrRdW9F^c7D`_C?L>}=z(>x*(;J&rYic{pF5=LdH>Z% zj(GkW>}zw^6sp8LJH`s+`3n0yxklwEI#@-CW;r1jx3P?tKLhbV5J|o`16gXqOOh%> zg;9mXzHitR#cA0p4sU#htEE1~*?FKnXpSAI*19OI*!nP4`ymni>U9gUaKfual({%x z=rUb|M2qYcr06>f*Cb@PAy+O%ctWx$NhZk=@f1lYaV`n`bs~0Z(`bI09!+t@y2#SH zOvsl@{6MJ(>}nwce9MrQ@*;{VIM-qUprs6)Zi%PVyHG+)a(VqQ6^He4#=S~&y$nq# z{{!R7#+v3yysP-3>&>p-6lhx1L~#cCKrM{T@aAO^Z`xU;14ds(%IbdmC;{7ELMcBJ1)yHVY# zWWpnkQN_HpBVt`mAX9(A61A|>#e=p4<03Y8$;IAIwyaBBgW`YaGOzAUk++gAmh_(u zx5Uv@I+Y{IDsi_|HsPDJff8@*5tmA}imR1F;%z!n+{X1Hn*!9{)LP5>mgAP_NPIwY zCFz|%!YtL1mo)&h7Q{j|NQgCu$wfjew8PD}IAX!?;K*++crDEEvwp#D0ZYt%O>V0vBr4T!Lh&y`6H=biq7aTmz<6WT2`tv@V;tzJ<(D zOQ7cZmg-CRmFOo?)~apc;ETVJquk%{tzcnX>iyB5MdOP1A^RVCQ-EILTQnSJcv)HC zTcQz4z&-YUA!mj^l5y-(!Ck-fsI8>|yJnI_bXP3mNV3R#oQgBIOkHnvvG=5=Ny0BX zWvQE$Z>eS^4^nAT?JU^kT0r6{=_{i8AM!0180uKN#EOlwqFa4pIJ;z8(xu9|`BE3J zue_D`mQCTUqa>%l$G2Q&P&VP4WQA~Ip2uz*-vn%h{{(rEJbhO@5htkfFFzU9~@ z&Lx~m*tNC`5^is&aDQ1A+}bb;#^Jb?eS6EyE&;ceW zz}B0}A{kLx^wL1?B`B%4U^jrW*o04($erok~cPjjJE(JwbXBL z7G`A(L7lBwpwfuTsSF1T7O1TQ{VkkER8oK{PPpPUZ+zu~m_?5yC)*%G#0rxek;H>H zOlT!Y)WGlJ8bHSzK}CkV75KUN5;QhYWYyUyPr{JBrGG^lgrtx7U1ovJDg#6{k^wmX z1g82mTdGwCApDk|1Xtj(QlE%aIC>LZ7C}JAi};f?D@rHrNgQ%Jg{=Bq4J=4lQE-R| zI-(OnVJV+9I&YexaV*$yBc&?o9rhA4hjHn!b^9z7vO&;KA!i$fs2t)`D$7cter_R( z5|)TML@634IAAPgqYy2-mAWLqs7G$?PY|yVrU+}K)g1e&^C9(=t?UXu z;aw-GWa`blWFD?~-#pyX>{>fCGNO&8?u6@U89H079XS?g-Mv(MHRK8$f?f?t6iF7* z#-2k!;~ix`U2f~%q>@}qy zVr@kvO)Hgdl^CK4Z>J$L(5|+!rG^@1bAe%(Yz+$f{-6o<{ZTTt4-!o@ylf@!4UjH# zvgwO~P!M-mp>T#C6Y-r*R&JxoRgxPkG+5dPg+|!GMmY#dm#i4=H@jp*2~k8si)9=K z*xZELj1bJvOJh>fQzXA6H(Cy*GfJ2E#;ViQfW{T?Nu#*&nt33VD7fPp*S7>=D&UeD zAz~X6?%UNIIES}Kd%8WC~8B?Ux!M^cJh@GatJA+=2gsbfYzt1QYT zS+vmIMeq{ZGe)317aNYLFK7>V32rZhI2Fr+V+HCX!H&Jlcw@)uuHZG0BM*iz2Lb2Y zd*uLZ-&O-F!Z~9=LSq^6MZ6@mjE_uY-}1g4HN#eoDu!c}BEvWzEW-OF5T9F{NRF%{ z7O|ewKqd@6&I&|KDKfdm=42Zr*Gpt}vD%&L<(IA06YGKX-=q}lp=M!r!jPIXh&3hJ zo)4@kfk{e91|9LYWlAY&k&74fv1G84Qi>OOO21<~B>@{XU_d`0o%o$Cop=d)RO*FD z>0k)`y>w`qT*OPZgo6daj6D>*JZhhvK`}3^P$C=qP+^1+1@A|R*l95utFE&_*YQFz zwr5X=YwQZx3g-!pLW{6ad?vlmP9bN4MybM#qKnqi0jIz_IeYv21?qeU2Mh@c4jUE` zK6Lnq$f%@vOs}RSB*w(1W~6709X%$~kUgOwKR2hiaQwKu8B?c}mdu_uebVGP#>(27 zimK|l^IGRO)z>X-ZfU@de}lcf%)!Ip>FKN+Wbp9`3J)=ahDPa=4Or|rHq9_e>to7Bo6L%YuSrQBktkSXp+qEH6(sd9rNYyhd50XGmz; zsF}0c7I*~@O&vXBcI!g>K|aYNCl-~JYrK7vQYIA7slYjH8DpkSo8Rm#}2?d45DwSVATw;FutnroAP7#q=hSEv(4bI_FW3x*p*ENcPL!x7H$JNf2>4NmJ zIe9hnJQf%h;_Q-gLq&z1OS7S+MXRVXR9DL#8w`z&4s5Pr-aNtGeUY8rBCU3jT)xP` zVUZxTFFI^!Z=xjuSO+`sKV~X0XYWlG<&WRs_ICNP{x}|6 zzaH?#fTw?u$AB+XIm_tZ(%*#q!M}MfV1EWQ#1sEB4S~6;<-#gqov=~3Ti7b>5FQZr z2#*R+2>an*|7qd4a8h_lI3simufyB^yVxUlS@>A^T=+`(R`|OtAp;A&u(dLn)=i>? z_ZAET^b<}!z$&dIz?m+L#alhz_G>I`CBX`=e9U;12vhKO2Hy5-F$MHkrBEZ(2~9Xf zN+Ha_TbowHeTA?|SSqX#RtxKKw+L_Vw$(#{I_(u66z&(cVOC8cJchTAqE-)}c3W}( zgm6GOBpek^;EXJV@Fd>$*HnRepBLT`{w%zLNh5`D0dL<$&0hxw&fxw%^zCRQs71?3 zqag#H>_?7E0MTsJh(-vP(I2$xYX#bw4~0*JE5g^pcS!L*QrPf^`^!SM>NV7T5#V?q zc@qX_3hmg@^B3F=0?y_D{tJjxSw<4wF^6do4dMw~`*OHuPr5ZB>Nfv`+CEPRT)Kv1a$7<&V8JG@E8X;-_2H*u#1 zeO3ThR}c@zn~B0o;Thoz+=YOybr}y`RH51RyA z9?18m zsgn(Y91d0$BMT=j*znL3ub%r}9dDRe+~VOGP+d%IqI?@M)rA$R)xj{6RrzVMAYa!mQ$^wh=oKmFY0&(vXttl9N< z>^Sto`(LPsj|!~vziZGjkB`(LhK!2ZCHEYC_QOxrp#i>LZt|ee;gK;3Bb7h>gLnS8 zabU~<*vA&Hito?c4e_8~{eCaM|MWY>6N@bWZcc>|OaB(NL!kNpMT>5Y z>%ZedZji%Z8!ZQKj4c2(PhYaK+^ut2RkaR~Z?7?vQ6m4A*MZm$%HAP|L0kUK-U_>r0 zj=&JN$Q&)(Y}R9&6(H)*K_#T64^rf%%kobt^F*;gm6wj(lrVQveuwi2I4RGoKIQ@0 z!XXxJNiG6i91&3dY?ZkOOA~o1dCc4cTrt|^bAWXKR;Qzw6%;Yz6r%VBUDS}3D5l(e zl69Exz?XV_`MhEyp!0`SLV#H!pP_8=RYH$qQ&ZFxY*2!Uc zDqmM@;OX#rJ{AEG9{SUn1SE~dW+A3i?7vy6*kB4bg%fOgqg|%xj3vzcXC5iSrsREHImo9XFd7 zTxgtmu>8`F9T&?F%5FAaXvQ-p9&dTKIe*rnSvxLW+JOu4a6cq|u*U!dd4WB#Ar);c z7#oppFZQ;AZqJ^$Y6aw?M0NqRb{2-FJ26zsK3|aKJ7R^Bir7d;q-5LpvIXoMCnGf3 zIT_#DC~bROA-iDqELpIyxMaZs*@fP4@#un*;)QfebIQX}LZ_V8V7Oq!6QAzM@?25M zpnMHxBl0}+oeBgj681Zsx1nhOF3nf3e-DC~zQ@H{BH@pA9mNBGDvn!h^1xEAQEa$; zmFdOCcNZ}6*l{K}5a6ygQyx;o^i3k9c?`K})M>9T@T>U?JlOze77l*z~BLom^W&`bwxaR3s$24I8D ztJ%7>re^ECwYgQ*IXTtHoo?xuU!9X%Rh64ljRlOXqi=)q4*6=}JpeYUMA)Y8NKZ@} zm7FFIO)+HTdB=q2ga_!Nbfa}LUB1>JVEL<^-MCR{QSr%1K{;W$?(sQMxqb$Dwu8a_ zuwf?1lr8VYO7ust68$pn#`OWAd0P<6XZZl$1lrLS0CI{651GWHrt5qu@O6_5KbAg5 z?&{$#%7cakW2doeu-6bdwivp?k$13be4H3Ou)^F|wx#kckv3ZJZDFBuVK0k0@F(;6 zeUF>p{?mRI^Y8}qt*u*_eDh`|-?A0{t~!Q9MGXnm>qUDh5@og2Uqi~;4NE%XIECj z@j*XUePR2Hg(o2Wu*ldbxo5OtM4sIc&m2E(zK{(>Mn;7M#10$e7LXGV!a{Q8gL1TP z%qHe}laeAc`u=x`#yZi0PG>d&|qV#*8l9xpVw)k!7CzTigIIvw3Y=qQb&q_SA=B{kV%fC~0tjo2%SskVB}!IVi|S$k7|bsO%)epd2qB zH&=X*W9nV-eX5tgE-YN`6E`?u_y~DWu;^uof+^D}$060=oE@AKX9x{CY@miHTfPHf z4x4~=t5>g>aFi)bY%ud%x5itq*qwo0L-^$PUqjwvU9bcjf7svUg((3g4sF0;CMuZJ zu~Zv>2r*}X<=gl}DCt|mF71MiWU{sSRePqeA#vujMbPAu?gxiS>`Kx7Hr%-BWUII4ePG0S#xduo!6D6<}TIfY~~kl{%rQR zIa9MvKV<%E4D-oJb})CbiO!?a%zukzgG(Npn>BY&2@6Oze`!dw%U%65C0~zBeqIea zTr=k?G>XqLA|EQif0&QKEj!R4Xy6xER2yV=vK)n74&3}1@L+JT!7JO@F!-<`f#cGP zXFA>+c%=Pu+$jj1T2I^QfGIvTh&51{LBT1{)?){tJY~EMvg%NoAA8*#pJI+< zZ&d&Do{hh3SbyVA^QTuAe0m3Sd-)7=yW>;#rnw=-oXd`_Yozi_e&^GPg5}Kf}p@qR?o*si5D)6+xYHb`f1$R1>H z6Adz%9B(}QnE~%$1P@XeJUsk^40hRCgMWWDEfwVFdtp^NnT;_S#CvO~IfM>p<-yYj za1e|CsI!-wN(Nc7I^5#>Q@zw|sM~E-mY)iKH2E&`u5I_RMm$<2cl@bQFIW8eAQlGOl>=xUiMSe1Vi6yQE6wl6!s?a{+ULN^l#4G! zJj+JgmVcc<+w{@Z!v{UI zug0zJf`hZOnJ7a|-TbfcPZmXL9^4@c6Y5~PXKrv7L4tiHZ(;ZNxQ?{Ml;AF6aF~h)KBPhhy zra{oI*f0S&u7RPbY&uAQpENKOP>6e`bZnn7?#cB>X%NNmOqrhUG1$-3-rmn8SMba6q-iZz!=P-astPKUokp0$ z-UE+cq2^MEVO)A4%iIqKz@Y7#ScC6R9vlD)&SIC`b4!c!*_WXQ633@T#8o6GoZ9ncl0>zo~w z08pC?Uy-?jLyl4jC`GhRI1vP38eD%DP}5ZbQ?^mK@WX-0s}QLh{0G1x0|E5(a#0Mt z_Yys2exrBHuJ72jcvxDNsnZ6r{O4b89awrt(Xxuldz}2m3(xjG-@b0bk_rM^2HUJ4 zkL7;yXwI@WJrthueC!2Zz3&{~6~0@16*^z$tHdfM=cD$5tKM~mtIXBOUU7oSpY{?I zniDK4-BI+}#s-!7qh^lV;CpB95pB62`7i|6ai4nE$y3wlDC+HTPk-FMxJMu?4^}^n zSXu)&GdNI(28Z%k^PHSz5l_uA*A*ALX0KQ$E|pvXzUh@P{GD58`-brJJ!1FxOHyB)Y2oqz|9-{foH%c=yn`XMLDmle8* zUp!;?G2rEntW4b|gPm@R<>xkQfxqwB{d1sxy@(CFU2C+kz4)CwNpOv* zf^9h+Lr$-#Z_f%|Iw&u6QEtyG$C?%J6)fB%A0>Z^_x$G^by1(y+Mj@zqM&7tCs^Mz z{)5tO)9$jxi6?gV2;JWApD_3E`$+VI9N z;M@UsKw+X6yb!=Axk}QTLsdf)spS}&=tW*BJaKlCG>(J28d>D(O{;QqS8ZCIvSMt; zveb^dSC1RFdefRw%hJ=An-lidH9{Y@?39PBxob`PiggP+Hm?l9zm=Oi7OuNv2_E9c zJZ0enyBivJKZ+&+b>;v1VudOxc6%t^hkNoOMRGtZ2;m(TErmVCV-6T`JD~;9LbJJo zv)nOf;R*ioM!(4ilH!M!W-u_Q!>q;-v{J!nSwhjH8isaiI7U?AnCFN@UssR0pcu4I zahTspKpU5YIh&DK4Umdim{I5nr^8}A2BWXBup48Pg%&FptyCUnfC{i?WISedCc=9{ zG3IGXg-PVr9aiOOSUoTUw&huv$(jQTb2;X;Dq&}?!pvI@tj%+=s-O-w=LW1TXoBUr z87mB0VSipAEX4d(yRaCuU`t_(z5_FHD`1iCz`WvW*rnHEc5ywd(|2NyaT9FRcVVt> z3oO<5Vm59Y?A6;Db`Zj9y^F~(2en&xh+)V83-%+JwR;S9?8h;`_9U#?PhqC*0BqU^ zF<*BGmhB^$pF9ft_A$&-o|KC8{1WEy-iKBE1I)&K2;2Ban4$Xw7V^(9&v^xQ@-H#l`8BNN zf5V*Tcd(g%FZ>-dOFs(#5PlM_3I7zXGX>5qyCK{ZZVA1DNiYk2Sfs5)N8XO9nLX1m z2j+-Qy))A?7v{>`m^+SR@~%^$!rRn%BHdDYzCXjX0h2g+NF$@vkF$pjI4@Pvl>>* z=CXOLj@7dU*2tRR3$~fHuvXT_7O;hE5o>3Q*%G!C9*Xb45pOHlO4h+vvDIu1Tg%q5 z^=t#XlWk<1*k*PY4uIPNciZ>E_4+n;AKT7$u=}x(Zx?%jJ;-(od)Py458KNgW{=X7W`wR}OuCOoIm+UL{HT#DBjeX0$V^`Vt?C1gh>oHYP5{@6E~2aGCc29r zqNnI3dW(ZZAJJFz6a7W>gyHxnP#hu#iNRus7%C1Ghlye0aB+kfE=J%8pP$7jI0lLq zW5if7PK*~5#6&SkOcqCqDPpRaCXNzEi|Jy9I7ZAA$BJ2^LCh9 VQlm?y$QD;A35 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 literal 0 HcmV?d00001 diff --git a/upload/includes/classes/captcha/img/fonts/monofont.ttf b/upload/includes/classes/captcha/img/fonts/monofont.ttf new file mode 100644 index 0000000000000000000000000000000000000000..ec6c51b2640bafbf046060a8e2b594905dd5e7dc GIT binary patch literal 41036 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 SyQDLSP-N_L`0;nd!2ds0@g5HV literal 0 HcmV?d00001 diff --git a/upload/includes/classes/captcha/img/fonts/verdana.ttf b/upload/includes/classes/captcha/img/fonts/verdana.ttf new file mode 100644 index 0000000000000000000000000000000000000000..8f25a642311b8dde62b6154184aea935999b7c15 GIT binary patch literal 171792 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 z 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 literal 0 HcmV?d00001 diff --git a/upload/includes/classes/captcha/index.php b/upload/includes/classes/captcha/index.php new file mode 100644 index 00000000..403f2e18 --- /dev/null +++ b/upload/includes/classes/captcha/index.php @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/upload/includes/classes/captcha_simple.img.php b/upload/includes/classes/captcha_simple.img.php new file mode 100644 index 00000000..7538bf34 --- /dev/null +++ b/upload/includes/classes/captcha_simple.img.php @@ -0,0 +1,86 @@ +generateCode($characters); + /* font size will be 75% of the image height */ + $font_size = $height * 0.75; + $image = @imagecreate($width, $height) or die('Cannot initialize new GD image stream'); + /* set the colours */ + $background_color = imagecolorallocate($image, 255, 255, 255); + $text_color = imagecolorallocate($image, 0, 0, 0); + $noise_color = imagecolorallocate($image, 226, 82, 207); + $noise_color1 = imagecolorallocate($image, 64, 179, 255); + $noise_color2 = imagecolorallocate($image, 255 ,204, 190); + + /* generate random dots in background */ + for( $i=0; $i<($width*$height)/250; $i++ ) { + imageellipse($image, mt_rand(0,$width), mt_rand(0,$height), mt_rand(0,$width), mt_rand(0,$height), $noise_color2); + } + /* generate random dots in background */ + for( $i=0; $i<($width*$height)/150; $i++ ) { + imagedashedline($image, mt_rand(0,$width), mt_rand(0,$height), mt_rand(0,$width), mt_rand(0,$height), $noise_color1); + } + /* generate random lines in background */ + for( $i=0; $i<($width*$height)/150; $i++ ) { + + imagedashedline($image, mt_rand(0,$width), mt_rand(0,$height), mt_rand(0,$width), mt_rand(0,$height), $noise_color); + } + /* create textbox and add text */ + $textbox = imagettfbbox($font_size, 0, $this->font, $code) or die('Error in imagettfbbox function'); + $x = ($width - $textbox[4])/2; + $y = ($height - $textbox[5])/2; + imagettftext($image, $font_size, 0, $x, $y, $text_color, $this->font , $code) or die('Error in imagettftext function'); + + /* output captcha image to browser */ + imagejpeg($image); + imagedestroy($image); + $_SESSION['security_code'] = $code; + } + +} + +$width = isset($_GET['width']) ? $_GET['width'] : '120'; +$height = isset($_GET['height']) ? $_GET['height'] : '40'; +$characters = isset($_GET['characters']) && $_GET['characters'] > 1 ? $_GET['characters'] : '6'; + +$captcha = new CaptchaSecurityImages($width,$height,$characters); +?> \ No newline at end of file diff --git a/upload/includes/classes/conversion/ffmpeg.class.php b/upload/includes/classes/conversion/ffmpeg.class.php new file mode 100644 index 00000000..4f3d4e41 --- /dev/null +++ b/upload/includes/classes/conversion/ffmpeg.class.php @@ -0,0 +1,646 @@ + 1) { + $time = date("H:i:s", $duration - rand(0,$duration)); + } else { + $time = "00:"; + $time .= date("i:s", $duration - rand(0,$duration)); + } + return $time; + } elseif($rand == "") { + if($duration / 3600 > 1 ) { + $time = date("H:i:s",$duration); + } else { + $time = "00:"; + $time .= date("i:s",$duration); + } + return $time; + } + } + + //THIS FUNCTION IS USED TO GENERATE THUMBS + function AssignGeneratedThumbs($flv,$duration,$rand = "") { + global $row; + $filename_minus_ext = substr($flv, 0, strrpos($flv, '.')); + $thumbnail_temp_dir = BASEDIR.'/files/temp'; + $thumbnail_output_dir = BASEDIR.'/files/thumbs'; + $ffmpeg = FFMPEG_BINARY; + $flv_file = BASEDIR.'/files/temp/'.$flv; + if(!file_exists($flv_file)) { + $flv_file = BASEDIR.'/files/videos/'.$flv; + } + $t_height = $row['thumb_height']; + $t_width = $row['thumb_width']; + $t_dim = $t_width.'x'.$t_height; + + $thumb_log = BASEDIR.'/logs/thumblog.txt'; + if($duration > 14 ) { + $duration = $duration - 5; + //Setting oF Thumbs Duration + $division = $duration / 3; + $count=1; + for($id=3;$id<=$duration;$id++) { + $id = $id + $division - 1; + if($rand != "") { + $time = $this->ChangeTime($id,1); + } elseif($rand == "") { + $time = $this->ChangeTime($id); + } + $command = "$ffmpeg -i $flv_file -an -ss $time -an -r 1 -s $t_dim -y -f image2 -vframes 1 $thumbnail_temp_dir/$filename_minus_ext-$count.jpg &> $thumb_log"; + $this->exec("$command",$output); + $count = $count+1; + } + } else { + $command = "$ffmpeg -i $flv_file -an -s $t_dim -y -f image2 -vframes 3 $thumbnail_temp_dir/$filename_minus_ext-%d.jpg &> $thumb_log"; + if(!isset($output)) + $output = ""; + $this->exec($command,$output); + } + $command2 = "$ffmpeg -i $flv_file -an -s 320x240 -y -f image2 -vframes 1 $thumbnail_temp_dir/$filename_minus_ext-big.jpg"; + $this->exec($command2); + + //Checkin IF Thumnails Have Been Generated Or Not + for($id=1;$id<=3;$id++) { + if(file_exists($thumbnail_temp_dir.'/'.$filename_minus_ext.'-'.$id.'.jpg')) { + @unlink($thumbnail_output_dir/$filename_minus_ext.'-'.$id.'.jpg'); + copy($thumbnail_temp_dir.'/'.$filename_minus_ext.'-'.$id.'.jpg',$thumbnail_output_dir.'/'.$filename_minus_ext.'-'.$id.'.jpg'); + @unlink($thumbnail_temp_dir.'/'.$filename_minus_ext.'-'.$id.'.jpg'); + } + } + if(file_exists($thumbnail_temp_dir.'/'.$filename_minus_ext.'-big.jpg')) { + @unlink($thumbnail_output_dir.'/'.$filename_minus_ext.'-big.jpg'); + copy($thumbnail_temp_dir.'/'.$filename_minus_ext.'-big.jpg',$thumbnail_output_dir.'/'.$filename_minus_ext.'-big.jpg'); + @unlink($thumbnail_temp_dir.'/'.$filename_minus_ext.'-big.jpg'); + } + } + + //THIS FUNCTION IS USED TO GENERATE DEFAULT THUMBS + function AssignDefaultThumb($flv){ +/* global $LANG,$row; + $site_template = BASEDIR.'/styles/'.$row['template_dir']; + //Minus Extension + $filename_minus_ext = substr($flv, 0, strrpos($flv, '.')); + $proccesing_thumb = $site_template.'/images/'.LANG.'/processing.png'; + $proccesing_thumb_big = $site_template.'/images/'.LANG.'/processing-big.png'; + copy($proccesing_thumb,BASEDIR.'/files/thumbs/'.$filename_minus_ext.'-1.jpg'); + copy($proccesing_thumb,BASEDIR.'/files/thumbs/'.$filename_minus_ext.'-2.jpg'); + copy($proccesing_thumb,BASEDIR.'/files/thumbs/'.$filename_minus_ext.'-3.jpg'); + copy($proccesing_thumb_big,BASEDIR.'/files/thumbs/'.$filename_minus_ext.'-big.jpg'); +*/ + } + + //THIS FUNCTION IS USED TO VALIDATE FILETYPE + function ValidateFile($file) { + global $row; + $ph = substr($file, strrpos($file,'.') + 1); + $ph = strtolower($ph); // Added line to fix case + $types = strtolower($row['allowed_types']); + $types_array = preg_replace('/,/',' ',$types); + $types_array = explode(' ',$types_array); + foreach($types_array as $type) { + $return = false; + if($type == $ph) { + $return = true; + break; + } + } + return $return; + } + + //THE REAL ENCODING GOES HERE + function ConvertFile($file,$flv) { + global $stats,$db,$row; + if($this->ValidateFile($file)) { + $flvtool2 = FFMPEG_FLVTOOLS_BINARY; + $vbrate = VBRATE; + $srate = SRATE; + $sbrate = $row['sbrate']; + $r_height = R_HEIGHT; + $ffmpeg = FFMPEG_BINARY; + $r_width = R_WIDTH; + $resize = RESIZE; + $keep_original = KEEP_ORIGINAL; + $max_size = MAX_UPLOAD_SIZE; + $max_encode = 3; + $vcodec = VCODEC; + $acodec = ACODEC; + $video_file = BASEDIR.'/files/temp/'.$file; + $flv_file = BASEDIR.'/files/videos/'.$flv; + $extension = substr($video_file, strrpos($video_file,'.') + 1); + //Check VIdeo File Size + $size = filesize($video_file); + if($size > $max_size*1024*1024) { + $status = "Failed"; + $flv_file = "failed.flv"; + } else { + + $resize = $resize == 'yes' ? 'WxH' : 'no'; + $CONFIG['ffmpeg']['resize'] = $resize; + $CONFIG['ffmpeg']['format'] = 'flv'; + $CONFIG['ffmpeg']['audio_codec' ] = $row['audio_codec']; + $CONFIG['ffmpeg']['audio_rate'] = $srate; + $CONFIG['ffmpeg']['audio_bitrate'] = $sbrate; + $CONFIG['ffmpeg']['video_codec'] = 'flv'; + $CONFIG['ffmpeg']['video_width'] = $r_width; + $CONFIG['ffmpeg']['video_height'] = $r_height; + $CONFIG['ffmpeg']['video_max_rate'] = 25; + $CONFIG['ffmpeg']['video_bitrate'] = $vbrate; + $CONFIG['ffmpeg']['video_rate'] = '800'; + $CONFIG['ffmpeg']['flvtool2'] = $flvtool2; + $info = $this->get_file_info( $video_file ); + //print_r($info); + + $record['src_ext'] = substr( $file, strrpos( $file, '.' ) + 1 ); + $record['src_format'] = $info['format']; + $record['src_duration'] = $info['duration']; + $record['src_size'] = $info['size']; + $record['src_bitrate'] = $info['bitrate']; + $record['src_video_width'] = $info['video_width']; + $record['src_video_height'] = $info['video_height']; + $record['src_video_wh_ratio'] = $info['video_wh_ratio']; + $record['src_video_codec'] = $info['video_codec']; + $record['src_video_rate'] = $info['video_rate']; + $record['src_video_bitrate'] = $info['video_bitrate']; + $record['src_video_color'] = $info['video_color']; + $record['src_audio_codec'] = $info['audio_codec']; + $record['src_audio_bitrate'] = $info['audio_bitrate']; + $record['src_audio_rate'] = $info['audio_rate']; + $record['src_audio_channels'] = $info['audio_channels']; + + $parameters = $CONFIG['ffmpeg']; + $parameters['path_source'] = $video_file; + $parameters['path_log'] = BASEDIR."/logs/logs.txt"; + $parameters['path_target'] = $flv_file; + //$lock = tempnam(BASEDIR . "/files/temp", "LOCK"); + if(!isset($extension)) + $extension = ""; + if($extension != 'flv') { + if(isset($info['Unknown'])) { + if($info['Unknown'] == "Unknwon") { + exit; + } + } + //for(;;) { + //if($max_encode >= count(glob(BASEDIR."/files/temp/LOCK*"))) { + $this->start_encoding( $parameters, $info, $lock ); + //break; + //} + //} + } else { + copy($video_file,$flv_file); + } + + $sec = $info['duration']; + if(!isset($sec)) + $sec = "1"; + + + ///////////////////////////////////////////////////////////// + // STEP 2 // + // FLVTOOL2 INJECTION // + ///////////////////////////////////////////////////////////// + /*if($flvtool2 != '') { + while(1) { + if(!is_file($lock)) + break; + } + $flv_cmd = "$flvtool2 -U $flv_file"; + if(!isset($output)) + $output = ""; + $this->exec("$flv_cmd >> ".BASEDIR."/logs/logs.txt 2>&1", $output); + }*/ + + $status = "Successful"; + + $this->AssignGeneratedThumbs($file,$sec); + $db->Execute("INSERT INTO `video_detail` (`flv`,`status`,`duration`,`original`) VALUES ('".$flv."','".$status."','".$sec."','".$file."')"); + $db->Execute("UPDATE LOW_PRIORITY `video` SET `duration` = '".$sec."' , status='".$status."' WHERE `flv` = '".$flv."'"); + + if($status == "Successful") { $stats->UpdateVideoRecord(8); } + + if($keep_original == 1) { + $original_file = BASEDIR.'/files/original/'.$file; + copy($video_file,$original_file); + } + + if(is_file($video_file)) + unlink($video_file); + }//If MAX SIZE CONDITION ENDs + } + if(!file_exists($flv_file)) { + $status = "Failed"; + $stats->UpdateVideoRecord(10); + $this->AssignDefaultThumb($flv); + $db->Execute("UPDATE LOW_PRIORITY `video_detail` SET `status` = '".$status."' WHERE `flv` = '".$flv."'"); + $db->Execute("UPDATE LOW_PRIORITY `video` SET `active` = 'no' AND `status` = '".$status."' WHERE `flv` = '".$flv."'"); + } + } + + ############################################################### + # start encoding + # NOTE: see file av_encoder.class.php for interface details + # Author : Arslan Hassan, Made For ClipBucket + ############################################################## + function start_encoding( $parameters, $source_info, $lockfile ) { + $ffmpeg = FFMPEG_BINARY; + + $p = & $parameters; + $i = & $source_info; + + $opt_av = " -y "; + $p['video_codec']; + # Prepare the ffmpeg command to execute + if(isset($p['extra_options'])) + $opt_av .= " -y {$p['extra_options']} "; + + # file format + if(isset($p['format'])) + $opt_av .= " -f {$p['format']} "; + # video codec, frame rate and bitrate + $video_rate = min( $p['video_max_rate'], $i['video_rate'] ); + $opt_av .= " -vcodec {$p['video_codec']} -b {$p['video_bitrate']} -r $video_rate "; + + # video size, aspect and padding + $this->calculate_size_padding( $p, $i, $width, $height, $ratio, $pad_top, $pad_bottom, $pad_left, $pad_right ); + $opt_av .= " -s {$width}x{$height} -aspect $ratio -padcolor 000000 -padtop $pad_top -padbottom $pad_bottom -padleft $pad_left -padright $pad_right "; + + # audio codec, rate and bitrate + if(!empty($p['audio_codec']) && $p['audio_codec'] != 'None'){ + $opt_av .= " -acodec {$p['audio_codec']}"; + } + # audio codec, rate and bitrate + $opt_av .= " -ar {$p['audio_rate']} -ab {$p['audio_bitrate']} "; + + + + if(!isset($output)) + $output = ""; + //$lockfile = BASEDIR . "/files/temp/lock.tmp"; + # execute ffmpeg, send output to the log file, run in background, with low priority (niced) + //$this->exec("echo $ffmpeg -i {$p['path_source']} $opt_av {$p['path_target']} >> {$p['path_log']} "); + $this->exec( "$ffmpeg -i '{$p['path_source']}' $opt_av '{$p['path_target']}' &> '{$p['path_log']}'" ); + + # Adding FLVtool2 for addin video meta deta + if(!empty($p['flvtool2'])){ + $this->exec( "{$p['flvtool2']} -U {$p['path_target']} >> '{$p['path_log']}'" ); + $opt_av .= " {$p['flvtool2']} -U {$p['path_target']} >> '{$p['path_log']}'"; + } + + $this->exec( "echo $ffmpeg -i {$p['path_source']} $opt_av {$p['path_target']} >> '{$p['path_log']}'" ); + } + + ############################################################### + # get encoding progress + # NOTE: see file av_encoder.class.php for interface details + # Author : Pedro,Arslan Hassan, Made For ClipBucket + ############################################################### + function get_file_info( $path_source ) { + $ffmpeg = FFMPEG_BINARY; + # init the info to N/A + $info['format'] = 'N/A'; + $info['duration'] = 'N/A'; + $info['size'] = 'N/A'; + $info['bitrate'] = 'N/A'; + $info['video_width'] = 'N/A'; + $info['video_height'] = 'N/A'; + $info['video_wh_ratio'] = 'N/A'; + $info['video_codec'] = 'N/A'; + $info['video_rate'] = 'N/A'; + $info['video_bitrate'] = 'N/A'; + $info['video_color'] = 'N/A'; + $info['audio_codec'] = 'N/A'; + $info['audio_bitrate'] = 'N/A'; + $info['audio_rate'] = 'N/A'; + $info['audio_channels'] = 'N/A'; + # get the file size + $stats = stat( $path_source ); + if( $stats === false ) + trigger_error( "Failed to stat file $path_source!", E_USER_ERROR ); + $info['size'] = (integer)$stats['size']; + $output = $this->exec( "$ffmpeg -i '$path_source' -acodec copy -vcodec copy -f null /dev/null 2>&1" ); + # parse output + if( $this->parse_format_info( $output, $info ) === false ) + return false; + + return $info; + + } + + ############################################################### + # Author : Pedro,ArslanHassan , Made For ClipBucket + # parse format info + # + # output (string) + # - the ffmpeg output to be parsed to extract format info + # + # info (array) + # - see function get_encoding_progress + # + # returns: + # - (bool) false on error + # - (bool) true on success + ############################################################### + function parse_format_info( $output, & $info ) { + + # search the output for specific patterns and extract info + # check final encoding message + if( ereg( 'Unknown format', $output, $args) ) { + $Unkown = "Unkown"; + } else { + $Unkown = ""; + } + if( ereg( 'video:([0-9]+)kB audio:([0-9]+)kB global headers:[0-9]+kB muxing overhead', $output, $args ) ) { + $video_size = (float)$args[1]; + $audio_size = (float)$args[2]; + } else { + return false; + } + + # check for last enconding update message + if( ereg( '(frame=([^=]*) fps=[^=]* q=[^=]* L)?size=[^=]*kB time=([^=]*) bitrate=[^=]*kbits/s[^=]*$', $output, $args ) ) { + $frame_count = $args[2] ? (float)$args[2] : 0; + $duration = (float)$args[3]; + } else { + return false; + } + + $info['duration'] = $duration; + $info['bitrate' ] = (integer)($info['size'] * 8 / 1024 / $duration); + if( $frame_count > 0 ) + $info['video_rate'] = (float)$frame_count / (float)$duration; + if( $video_size > 0 ) + $info['video_bitrate'] = (integer)($video_size * 8 / $duration); + if( $audio_size > 0 ) + $info['audio_bitrate'] = (integer)($audio_size * 8 / $duration); + # get format information + if( ereg( "Input #0, ([^ ]+), from", $output, $args ) ) { + $info['format'] = $args[1]; + } + + # get video information + if( ereg( 'Video: ([^ ]+), ([^ ]+), ([0-9]+)x([0-9]+)( \[PAR ([0-9]+):([0-9]+) DAR ([0-9]+):([0-9]+)\])?', $output, $args ) ) { + $info['video_codec' ] = $args[1]; + $info['video_color' ] = $args[2]; + $info['video_width' ] = $args[3]; + $info['video_height' ] = $args[4]; + if( $args[5] ) { + $par1 = $args[6]; + $par2 = $args[7]; + $dar1 = $args[8]; + $dar2 = $args[9]; + if( (int)$dar1 > 0 && (int)$dar2 > 0 && (int)$par1 > 0 && (int)$par2 > 0 ) + $info['video_wh_ratio'] = ( (float)$dar1 / (float)$dar2 ) / ( (float)$par1 / (float)$par2 ); + } + # laking aspect ratio information, assume pixel are square + if( $info['video_wh_ratio'] === 'N/A' ) + $info['video_wh_ratio'] = (float)$info['video_width'] / (float)$info['video_height']; + } + + # get audio information + if( ereg( "Audio: ([^ ]+), ([0-9]+) Hz, ([^\n,]*)", $output, $args ) ) { + $info['audio_codec' ] = $args[1]; + $info['audio_rate' ] = $args[2]; + $info['audio_channels'] = $args[3]; + } + + # check if file contains a video stream + return $video_size > 0; + + #TODO allow files with no video (only audio)? + #return true; + } + + function calculate_size_padding( $parameters, $source_info, & $width, & $height, & $ratio, & $pad_top, & $pad_bottom, & $pad_left, & $pad_right ) { + $p = $parameters; + $i = $source_info; + + switch( $p['resize'] ) { + # dont resize, use same size as source, and aspect ratio + # WARNING: some codec will NOT preserve the aspect ratio + case 'no': + $width = $i['video_width' ]; + $height = $i['video_height' ]; + $ratio = $i['video_wh_ratio']; + $pad_top = 0; + $pad_bottom = 0; + $pad_left = 0; + $pad_right = 0; + break; + # resize to parameters width X height, use same aspect ratio + # WARNING: some codec will NOT preserve the aspect ratio + case 'WxH': + $width = $p['video_width' ]; + $height = $p['video_height' ]; + $ratio = $i['video_wh_ratio']; + $pad_top = 0; + $pad_bottom = 0; + $pad_left = 0; + $pad_right = 0; + break; + # make pixel square + # reduce video size if bigger than p[width] X p[height] + # and preserve aspect ratio + case 'max': + $width = (float)$i['video_width' ]; + $height = (float)$i['video_height' ]; + $ratio = (float)$i['video_wh_ratio']; + $max_width = (float)$p['video_width' ]; + $max_height = (float)$p['video_height' ]; + + # make pixels square + if( $ratio > 1.0 ) + $width = $height * $ratio; + else + $height = $width / $ratio; + + # reduce width + if( $width > $max_width ) { + $r = $max_width / $width; + $width *= $r; + $height *= $r; + } + + # reduce height + if( $height > $max_height ) { + $r = $max_height / $height; + $width *= $r; + $height *= $r; + } + + # make size even (required by many codecs) + $width = (integer)( ($width + 1 ) / 2 ) * 2; + $height = (integer)( ($height + 1 ) / 2 ) * 2; + # no padding + $pad_top = 0; + $pad_bottom = 0; + $pad_left = 0; + $pad_right = 0; + break; + # make pixel square + # resize video to fit inside p[width] X p[height] + # add padding and preserve aspect ratio + case 'fit': + # values need to be multiples of 2 in the end so + # divide width and height by 2 to do the calculation + # then multiply by 2 in the end + $ratio = (float)$i['video_wh_ratio']; + $width = (float)$i['video_width' ] / 2; + $height = (float)$i['video_height' ] / 2; + $trt_width = (float)$p['video_width' ] / 2; + $trt_height = (float)$p['video_height' ] / 2; + + # make pixels square + if( $ratio > 1.0 ) + $width = $height * $ratio; + else + $height = $width / $ratio; + + # calculate size to fit + $ratio_w = $trt_width / $width; + $ratio_h = $trt_height / $height; + + if( $ratio_h > $ratio_w ) { + $width = (integer)$trt_width; + $height = (integer)($width / $ratio); + } else { + $height = (integer)$trt_height; + $width = (integer)($height * $ratio); + } + + # calculate padding + $pad_top = (integer)(($trt_height - $height + 1) / 2); + $pad_left = (integer)(($trt_width - $width + 1) / 2); + $pad_bottom = (integer)($trt_height - $height - $pad_top ); + $pad_right = (integer)($trt_width - $width - $pad_left); + + # multiply by 2 to undo division and get multiples of 2 + $width *= 2; + $height *= 2; + $pad_top *= 2; + $pad_left *= 2; + $pad_bottom *= 2; + $pad_right *= 2; + break; + } + } + + ############################################################### + # exec + # + # exec shell scripts using bash + # + ############################################################### + function exec( $cmd ) { + # use bash to execute the command + # add common locations for bash to the PATH + # this should work in virtually any *nix/BSD/Linux server on the planet + # assuming we have execute permission + //$cmd = "PATH=\$PATH:/bin:/usr/bin:/usr/local/bin bash -c \"$cmd\" "; + return shell_exec( $cmd ); + } + + ############################################################### + # list_formats + # + # List Available File Formats (Do not use) + # + ############################################################### + function list_formats($format) { + + if($format == 'encoder') { + $formats = "E"; + } elseif($format == 'decoder') { + $formats = "D"; + } else { + $formats = "DE"; + } + + $ffmpeg = FFMPEG_BINARY; + exec("$ffmpeg -formats 2>&1", $output); + + $formatstart = array_search('File formats:', $output); + $formatend = array_search('Codecs:', $output); + + $formatstart = $formatstart + 1; + $formatend = $formatend - 2; + + $i = 0; + foreach (range($formatstart,$formatend) as $number) { + $output[$number] = preg_replace('/^\s+/', '', $output[$number]); + list($enc[$number],$name[$number],$desc[$number]) = preg_split('/\s+/', $output[$number], 3); + + if(ereg($formats, $enc[$number])) { + $listing[$i] = array('encode/decode' => $enc[$number], 'name' => $name[$number], 'description' => $desc[$number]); + $i++; + } + } + return $listing; + } + + ############################################################### + # list_codecs + # + # List Available Codecs + # + ############################################################### + function list_codecs($format, $type) { + + if($format == "encode") { + $formats = "E"; + } elseif ($format = "decode") { + $formats = "D"; + } else { + return false; + } + if($type == "video") { + $types = "V"; + } elseif ($type == "audio") { + $types = "A"; + } + + $ffmpeg = FFMPEG_BINARY; + exec("$ffmpeg -formats 2>&1", $output); + + $codecstart = array_search('Codecs:', $output); + $codecend = array_search('Bitstream filters:', $output); + $codecstart = $codecstart + 1; + $codecend = $codecend - 2; + + $i = 0; + + foreach (range($codecstart, $codecend) as $number) { + $output[$number] = preg_replace('/^\s+/', '', $output[$number]); + $enc[$number] = preg_replace('/^([D E V A S T]+) (.+?)$/', '$1', $output[$number]); + $tmp[$number] = preg_replace('/^([D E V A S T]+) (.+?)$/', '$2', $output[$number]); + list($name[$number],$desc[$number]) = preg_split('/\s+/', $tmp[$number], 2); + + if(ereg($formats, $enc[$number])) { + if(ereg($types, $enc[$number])) { + $listing[$i] = array('encode/decode' => $enc[$number], 'name' => $name[$number], 'description' => $desc[$number]); + $i++; + } + } + } + return $listing; + } + + + +} +?> \ No newline at end of file diff --git a/upload/includes/classes/conversion/ffmpeg.win32.php b/upload/includes/classes/conversion/ffmpeg.win32.php new file mode 100644 index 00000000..2ed2e8aa --- /dev/null +++ b/upload/includes/classes/conversion/ffmpeg.win32.php @@ -0,0 +1,663 @@ +ffmpeg = FFMPEG_BINARY; + $this->input_file = $file; + + } + + + /** + * Prepare file to be converted + * this will first get info of the file + * and enter its info into database + */ + function prepare($file=NULL) + { + global $db; + + if($file) + $this->input_file = $file; + + if(file_exists($this->input_file)) + $this->input_file = $this->input_file; + else + $this->input_file = TEMP_DIR.'/'.$this->input_file; + + //Checking File Exists + if(!file_exists($this->input_file)) + { + $this->log('File Exists','No'); + }else{ + $this->log('File Exists','Yes'); + } + + //Get File info + $this->input_details = $this->get_file_info(); + + //Loging File Details + $this->log .= "\nPreparing file...\n"; + $this->log_file_info(); + + //Insert Info into database + $this->insert_data(); + + } + + + /** + * Function used to convert video + */ + function convert($file=NULL) + { + if($file) + $this->input_file = $file; + + $this->log .= "\r\nConverting Video\r\n"; + + + $p = $this->configs; + $i = $this->input_details; + + + # Prepare the ffmpeg command to execute + if(isset($p['extra_options'])) + $opt_av .= " -y {$p['extra_options']} "; + + # file format + if(isset($p['format'])) + $opt_av .= " -f {$p['format']} "; + + # video codec + if(isset($p['video_codec'])) + $opt_av .= " -vcodec ".$p['video_codec']; + elseif(isset($i['video_codec'])) + $opt_av .= " -vcodec ".$i['video_codec']; + + # video rate + if($p['use_video_rate']) + { + if(isset($p['video_rate'])) + $vrate = $p['video_rate']; + elseif(isset($i['video_rate'])) + $vrate = $i['video_rate']; + if(isset($p['video_max_rate']) && !empty($vrate)) + $vrate = min($p['video_max_rate'],$vrate); + if(!empty($vrate)) + $opt_av .= " -r $vrate "; + } + + # video bitrate + if($p['use_video_bit_rate']) + { + if(isset($p['video_bitrate'])) + $vbrate = $p['video_bitrate']; + elseif(isset($i['video_bitrate'])) + $vbrate = $i['video_bitrate']; + if(!empty($vbrate)) + $opt_av .= " -b $vbrate "; + } + + + # video size, aspect and padding + $this->calculate_size_padding( $p, $i, $width, $height, $ratio, $pad_top, $pad_bottom, $pad_left, $pad_right ); + $opt_av .= " -s {$width}x{$height} -aspect $ratio -padcolor 000000 -padtop $pad_top -padbottom $pad_bottom -padleft $pad_left -padright $pad_right "; + + # audio codec, rate and bitrate + if($p['use_audio_codec']) + { + if(!empty($p['audio_codec']) && $p['audio_codec'] != 'None'){ + $opt_av .= " -acodec {$p['audio_codec']}"; + } + } + + # audio bitrate + if($p['use_audio_bit_rate']) + { + if(isset($p['audio_bitrate'])) + $abrate = $p['audio_bitrate']; + elseif(isset($i['audio_bitrate'])) + $abrate = $i['audio_bitrate']; + if(!empty($abrate)) + $opt_av .= " -ab $abrate "; + } + + # audio bitrate + if($p['use_audio_rate']) + { + if(isset($p['audio_rate'])) + $arate = $p['audio_rate']; + elseif(isset($i['audio_rate'])) + $arate = $i['audio_rate']; + if(!empty($arate)) + $opt_av .= " -ar $arate "; + } + + $opt_av .= " -map_meta_data ".$this->output_file.":".$this->input_file; + + $command = $this->ffmpeg." -i ".$this->input_file." $opt_av ".$this->output_file." 2> ".TEMP_DIR."/output.tmp "; + $output = $this->exec($command); + $output = $output ? $output : join("", file(TEMP_DIR.'/output.tmp')); + if(file_exists(TEMP_DIR.'/output.tmp')) + unlink(TEMP_DIR.'/output.tmp'); + $this->log('Conversion Command',$command); + $this->log .="\r\n\r\nConversion Details\r\n\r\n"; + $this->log .=$output; + $this->output_details = $this->get_file_info($this->output_file); + } + + /** + * Function used to get file information using FFMPEG + * @param FILE_PATH + */ + function get_file_info( $path_source =NULL) { + + if(!$path_source) + $path_source = $this->input_file; + + # init the info to N/A + $info['format'] = 'N/A'; + $info['duration'] = 'N/A'; + $info['size'] = 'N/A'; + $info['bitrate'] = 'N/A'; + $info['video_width'] = 'N/A'; + $info['video_height'] = 'N/A'; + $info['video_wh_ratio'] = 'N/A'; + $info['video_codec'] = 'N/A'; + $info['video_rate'] = 'N/A'; + $info['video_bitrate'] = 'N/A'; + $info['video_color'] = 'N/A'; + $info['audio_codec'] = 'N/A'; + $info['audio_bitrate'] = 'N/A'; + $info['audio_rate'] = 'N/A'; + $info['audio_channels'] = 'N/A'; + $info['path'] = $path_source; + + # get the file size + $stats = stat( $path_source ); + if( $stats === false ) + $this->log .= "Failed to stat file $path_source!\n"; + $info['size'] = (integer)$stats['size']; + $output = $this->exec( $this->ffmpeg." -i $path_source -acodec copy -vcodec copy -f null /dev/null 2>&1" ); + # parse output + if( $this->parse_format_info( $output, $info ) === false ) + return false; + + return $info; + } + + + + + + /** + * Function used to excute SHELL Scripts + */ + function exec( $cmd ) { + # use bash to execute the command + # add common locations for bash to the PATH + # this should work in virtually any *nix/BSD/Linux server on the planet + # assuming we have execute permission + //$cmd = "PATH=\$PATH:/bin:/usr/bin:/usr/local/bin bash -c \"$cmd\" "; + return shell_exec( $cmd); + } + + + + /** + * Author : Arslan Hassan + * parse format info + * + * output (string) + * - the ffmpeg output to be parsed to extract format info + * + * info (array) + * - see function get_encoding_progress + * + * returns: + * - (bool) false on error + * - (bool) true on success + */ + + function parse_format_info( $output, & $info ) { + + # search the output for specific patterns and extract info + # check final encoding message + if( ereg( 'Unknown format', $output, $args) ) { + $Unkown = "Unkown"; + } else { + $Unkown = ""; + } + if( ereg( 'video:([0-9]+)kB audio:([0-9]+)kB global headers:[0-9]+kB muxing overhead', $output, $args ) ) { + $video_size = (float)$args[1]; + $audio_size = (float)$args[2]; + } else { + return false; + } + + # check for last enconding update message + if( ereg( '(frame=([^=]*) fps=[^=]* q=[^=]* L)?size=[^=]*kB time=([^=]*) bitrate=[^=]*kbits/s[^=]*$', $output, $args ) ) { + $frame_count = $args[2] ? (float)$args[2] : 0; + $duration = (float)$args[3]; + } else { + return false; + } + + $info['duration'] = $duration; + $info['bitrate' ] = (integer)($info['size'] * 8 / 1024 / $duration); + if( $frame_count > 0 ) + $info['video_rate'] = (float)$frame_count / (float)$duration; + if( $video_size > 0 ) + $info['video_bitrate'] = (integer)($video_size * 8 / $duration); + if( $audio_size > 0 ) + $info['audio_bitrate'] = (integer)($audio_size * 8 / $duration); + # get format information + if( ereg( "Input #0, ([^ ]+), from", $output, $args ) ) { + $info['format'] = $args[1]; + } + + # get video information + if( ereg( 'Video: ([^ ]+), ([^ ]+), ([0-9]+)x([0-9]+)( \[PAR ([0-9]+):([0-9]+) DAR ([0-9]+):([0-9]+)\])?', $output, $args ) ) { + $info['video_codec' ] = $args[1]; + $info['video_color' ] = $args[2]; + $info['video_width' ] = $args[3]; + $info['video_height' ] = $args[4]; + if( $args[5] ) { + $par1 = $args[6]; + $par2 = $args[7]; + $dar1 = $args[8]; + $dar2 = $args[9]; + if( (int)$dar1 > 0 && (int)$dar2 > 0 && (int)$par1 > 0 && (int)$par2 > 0 ) + $info['video_wh_ratio'] = ( (float)$dar1 / (float)$dar2 ) / ( (float)$par1 / (float)$par2 ); + } + # laking aspect ratio information, assume pixel are square + if( $info['video_wh_ratio'] === 'N/A' ) + $info['video_wh_ratio'] = (float)$info['video_width'] / (float)$info['video_height']; + } + + # get audio information + if( ereg( "Audio: ([^ ]+), ([0-9]+) Hz, ([^\n,]*)", $output, $args ) ) { + $info['audio_codec' ] = $args[1]; + $info['audio_rate' ] = $args[2]; + $info['audio_channels'] = $args[3]; + } + + # check if file contains a video stream + return $video_size > 0; + + #TODO allow files with no video (only audio)? + #return true; + } + + /** + * Function used to insert data into database + * @param ARRAY + */ + + function insert_data() + { + global $db; + //Insert Info into database + if(is_array($this->input_details)) + { + foreach($this->input_details as $field=>$value) + { + $fields[] = 'src_'.$field; + $values[] = $value; + } + $fields[] = 'src_ext'; + $values[] = getExt($this->input_details['path']); + $fields[] = 'src_name'; + $values[] = getName($this->input_details['path']); + + $db->insert($this->tbl,$fields,$values); + $this->row_id = $db->insert_id(); + } + } + + /** + * Function used to update data of + */ + function update_data() + { + global $db; + //Insert Info into database + if(is_array($this->output_details)) + { + foreach($this->output_details as $field=>$value) + { + $fields[] = 'output_'.$field; + $values[] = $value; + } + $fields[] = 'file_conversion_log'; + $values[] = $this->log; + $db->update($this->tbl,$fields,$values," id = '".$this->row_id."'"); + } + } + + + /** + * Function used to add log in log var + */ + function log($name,$value) + { + $this->log .= $name.' : '.$value."\r\n"; + } + + /** + * Function used to start log + */ + function start_log() + { + $this->log = "Started on ".NOW()." - ".date("Y M d")."\r\n\n"; + $this->log .= "Checking File ....\r\n"; + $this->log('File',$this->input_file); + } + + /** + * Function used to log video info + */ + function log_file_info() + { + $details = $this->input_details; + if(is_array($details)) + { + foreach($details as $name => $value) + { + $this->log($name,$value); + } + }else{ + $this->log .=" Unknown file details - Unable to get video details using FFMPEG \n"; + } + } + + + + /** + * Function used to time check + */ + function time_check() + { + $time = microtime(); + $time = explode(' ',$time); + $time = $time[1]+$time[0]; + return $time; + } + + /** + * Function used to start timing + */ + function start_time_check() + { + $this->start_time = $this->time_check(); + } + + /** + * Function used to end timing + */ + function end_time_check() + { + $this->end_time = $this->time_check(); + } + + /** + * Function used to check total time + */ + function total_time() + { + $this->total_time = round(($this->end_time-$this->start_time),4); + } + + + /** + * Function used to calculate video padding + */ + function calculate_size_padding( $parameters, $source_info, & $width, & $height, & $ratio, & $pad_top, & $pad_bottom, & $pad_left, & $pad_right ) { + $p = $parameters; + $i = $source_info; + + switch( $p['resize'] ) { + # dont resize, use same size as source, and aspect ratio + # WARNING: some codec will NOT preserve the aspect ratio + case 'no': + $width = $i['video_width' ]; + $height = $i['video_height' ]; + $ratio = $i['video_wh_ratio']; + $pad_top = 0; + $pad_bottom = 0; + $pad_left = 0; + $pad_right = 0; + break; + # resize to parameters width X height, use same aspect ratio + # WARNING: some codec will NOT preserve the aspect ratio + case 'WxH': + $width = $p['video_width' ]; + $height = $p['video_height' ]; + $ratio = $i['video_wh_ratio']; + $pad_top = 0; + $pad_bottom = 0; + $pad_left = 0; + $pad_right = 0; + break; + # make pixel square + # reduce video size if bigger than p[width] X p[height] + # and preserve aspect ratio + case 'max': + $width = (float)$i['video_width' ]; + $height = (float)$i['video_height' ]; + $ratio = (float)$i['video_wh_ratio']; + $max_width = (float)$p['video_width' ]; + $max_height = (float)$p['video_height' ]; + + # make pixels square + if( $ratio > 1.0 ) + $width = $height * $ratio; + else + $height = $width / $ratio; + + # reduce width + if( $width > $max_width ) { + $r = $max_width / $width; + $width *= $r; + $height *= $r; + } + + # reduce height + if( $height > $max_height ) { + $r = $max_height / $height; + $width *= $r; + $height *= $r; + } + + # make size even (required by many codecs) + $width = (integer)( ($width + 1 ) / 2 ) * 2; + $height = (integer)( ($height + 1 ) / 2 ) * 2; + # no padding + $pad_top = 0; + $pad_bottom = 0; + $pad_left = 0; + $pad_right = 0; + break; + # make pixel square + # resize video to fit inside p[width] X p[height] + # add padding and preserve aspect ratio + case 'fit': + # values need to be multiples of 2 in the end so + # divide width and height by 2 to do the calculation + # then multiply by 2 in the end + $ratio = (float)$i['video_wh_ratio']; + $width = (float)$i['video_width' ] / 2; + $height = (float)$i['video_height' ] / 2; + $trt_width = (float)$p['video_width' ] / 2; + $trt_height = (float)$p['video_height' ] / 2; + + # make pixels square + if( $ratio > 1.0 ) + $width = $height * $ratio; + else + $height = $width / $ratio; + + # calculate size to fit + $ratio_w = $trt_width / $width; + $ratio_h = $trt_height / $height; + + if( $ratio_h > $ratio_w ) { + $width = (integer)$trt_width; + $height = (integer)($width / $ratio); + } else { + $height = (integer)$trt_height; + $width = (integer)($height * $ratio); + } + + # calculate padding + $pad_top = (integer)(($trt_height - $height + 1) / 2); + $pad_left = (integer)(($trt_width - $width + 1) / 2); + $pad_bottom = (integer)($trt_height - $height - $pad_top ); + $pad_right = (integer)($trt_width - $width - $pad_left); + + # multiply by 2 to undo division and get multiples of 2 + $width *= 2; + $height *= 2; + $pad_top *= 2; + $pad_left *= 2; + $pad_bottom *= 2; + $pad_right *= 2; + break; + } + } + + + + /** + * Function used to perform all actions when converting a video + */ + function ClipBucket() + { + $this->start_time_check(); + $this->start_log(); + $this->prepare(); + $this->convert(); + $this->end_time_check(); + $this->total_time(); + $this->output_details = $this->get_file_info($this->output_file); + $this->log .= "\n\Time Took : "; + $this->log .= $this->total_time.' seconds'; + $this->update_data(); + //Generating Thumb + if($this->gen_thumbs) + $this->generate_thumbs($this->input_file,$this->input_details['duration']); + if($this->gen_big_thumb) + $this->generate_thumbs($this->input_file,$this->input_details['duration'],'300x240','big'); + //Remove Input + if($this->remove_input) + unlink($this->input_file); + } + + + + /** + * Function used to generate video thumbnails + */ + function generate_thumbs($input_file,$duration,$dim='120x90',$num=3,$rand=NULL) + { + $output_dir = THUMBS_DIR; + + if($num=='big') + { + $file_name = getName($input_file)."-big.jpg"; + $file_path = THUMBS_DIR.'/'.$file_name; + $command = $this->ffmpeg." -i $input_file -an -s $dim -y -f image2 -vframes 1 $file_path "; + $this->exec($command); + }else{ + + if($num > 1 && $duration > 14) + { + $duration = $duration - 5; + $division = $duration / 3; + $count=1; + for($id=3;$id<=$duration;$id++) + { + $file_name = getName($input_file)."-$count.jpg"; + $file_path = THUMBS_DIR.'/'.$file_name; + + $id = $id + $division - 1; + if($rand != "") { + $time = $this->ChangeTime($id,1); + } elseif($rand == "") { + $time = $this->ChangeTime($id); + } + $command = $this->ffmpeg." -i $input_file -an -ss $time -an -r 1 -s $dim -y -f image2 -vframes 1 $file_path "; + $this->exec($command); + $count = $count+1; + } + }else{ + $file_name = getName($input_file)."-%d.jpg"; + $file_path = THUMBS_DIR.'/'.$file_name; + $command = $this->ffmpeg." -i $input_file -an -s $dim -y -f image2 -vframes $num $file_path "; + $this->exec($command); + } + } + } + + + + /** + * Function used to convert seconds into proper time format + * @param : INT duration + * @parma : rand + */ + + function ChangeTime($duration, $rand = "") { + if($rand != "") { + if($duration / 3600 > 1) { + $time = date("H:i:s", $duration - rand(0,$duration)); + } else { + $time = "00:"; + $time .= date("i:s", $duration - rand(0,$duration)); + } + return $time; + } elseif($rand == "") { + if($duration / 3600 > 1 ) { + $time = date("H:i:s",$duration); + } else { + $time = "00:"; + $time .= date("i:s",$duration); + } + return $time; + } + } +} +?> \ No newline at end of file diff --git a/upload/includes/classes/conversion/multi.class.php b/upload/includes/classes/conversion/multi.class.php new file mode 100644 index 00000000..169fb3a3 --- /dev/null +++ b/upload/includes/classes/conversion/multi.class.php @@ -0,0 +1,542 @@ + 1 ){ + $time = date("H:i:s",$duration - rand(0,$duration)); + }else{ + $time = "00:"; + $time .= date("i:s",$duration - rand(0,$duration)); + } + return $time; + } + + if($rand == null) + { + if($duration / 3600 > 1 ){ + $time = date("H:i:s",$duration); + }else{ + $time = "00:"; + $time .= date("i:s",$duration); + } + return $time; + } + } + + + //THIS FUNCTION IS USED TO GENERATE THUMBS + + function AssignGeneratedThumbs($flv,$duration,$rand = null) + { + + $filename_minus_ext = substr($flv, 0, strrpos($flv, '.')); + $thumbnail_output_dir = BASEDIR.'/files/thumbs'; + $ffmpeg = FFMPEG_BINARY; + $flv_file = BASEDIR.'/files/videos/'.$flv; + + if($duration > 14 ){ + $duration = $duration - 5; + //Setting oF Thumbs Duration + $division = $duration / 3; + $count=1; + for($id=3;$id<=$duration;$id++){ + $id = $id +$division-1; + if($rand != null) + { + $time = $this->ChangeTime($id,1); + } + if($rand == null) + { + $time = $this->ChangeTime($id); + } + $command = "$ffmpeg -i $flv_file -an -ss $time -an -r 1 -s 120x90 -y -f image2 -vframes 1 $thumbnail_output_dir/$filename_minus_ext-$count.jpg"; + exec("$command",$output); + $count = $count+1; + } + }else{ + $command = "$ffmpeg -i $flv_file -an -s 120x90 -y -f image2 -vframes 3 $thumbnail_output_dir/$filename_minus_ext-%d.jpg"; + exec($command,$output); + } + $command2 = "$ffmpeg -i $flv_file -an -s 320x240 -y -f image2 -vframes 1 $thumbnail_output_dir/$filename_minus_ext-big.jpg"; + exec($command2,$output2); + + //debugging + $debug_1 = $command . "\n";//file line of debug + $debug_1 .= $command2 . "\n";//file line of debug + foreach ($output as $outputline) { + $debug_1 = $debug_1 . $outputline . "\n"; + if ($debugmodex == 1) {//no debug mode + echo ("$outputline
    "); + } + } + if (ENCODING_LOGGING == "yes") { + //check if file exists + $file_contents = 'ClipBucket debug' . "\n" . $command . "\n" . $command2 . "\n". + 'Commands were executed.See rest of log for output details' . "\n" . + '=================================================================' . "\n"; + $log_file = BASEDIR."/logs/logs.txt"; + if (@file_exists($log_file)) {//append to log file + $fo = @fopen($log_file, 'a'); + @fwrite($fo, $file_contents); + @fclose($fo); + } + else { + $fo = @fopen($log_file, 'w');//else create new log + @fwrite($fo, $file_contents); + @fclose($fo); + } + } + } + + //THIS FUNCTION IS USED TO GENERATE DEFAULT THUMBS + function AssignDefaultThumb($flv){ + + //Minus Extension + $filename_minus_ext = substr($flv, 0, strrpos($flv, '.')); + $proccesing_thumb = TEMPLATEDIR.'/images/'.LANG.'/processing.png'; + $proccesing_thumb_big = TEMPLATEDIR.'/images/'.LANG.'/processing-big.png'; + copy($proccesing_thumb,BASEDIR.'/files/thumbs/'.$filename_minus_ext.'-1.jpg'); + copy($proccesing_thumb,BASEDIR.'/files/thumbs/'.$filename_minus_ext.'-2.jpg'); + copy($proccesing_thumb,BASEDIR.'/files/thumbs/'.$filename_minus_ext.'-3.jpg'); + copy($proccesing_thumb_big,BASEDIR.'/files/thumbs/'.$filename_minus_ext.'-big.jpg'); + + } + + //THIS FUNCTION IS USED TO VALIDATE FILETYPE + //THIS FUNCTION IS USED TO VALIDATE FILETYPE + function ValidateFile($file) { + global $row; + $ph = substr($file, strrpos($file,'.') + 1); + $ph = strtolower($ph); // Added line to fix case + $types = strtolower($row['allowed_types']); + $types_array = preg_replace('/,/',' ',$types); + $types_array = explode(' ',$types_array); + foreach($types_array as $type) { + $return = false; + if($type == $ph) { + $return = true; + break; + } + } + return $return; + } + + //THE REAL ENCODING GOES HERE + function ConvertFile($file,$flv){ + + $video_file = BASEDIR.'/files/temp/'.$file; + $flv_file = BASEDIR.'/files/videos/'.$flv; + + if($this->ValidateFile($file)){ + + $mencoder = FFMPEG_MENCODER_BINARY; + $mplayer = FFMPEG_MPLAYER_BINARY; + $flvtool2 = FFMPEG_FLVTOOLS_BINARY; + $vbrate = VBRATE; + $srate = SRATE; + $r_height = R_HEIGHT; + $ffmpeg = FFMPEG_BINARY; + $r_width = R_WIDTH; + $resize = RESIZE; + $keep_original = KEEP_ORIGINAL; + $max_size = MAX_UPLOAD_SIZE; + + + //Check VIdeo File Size + $size = @filesize($flv_file); + if($size > $max_size*1024*1024){ + $status = "Failed"; + $flv_file = "failed.flv"; + }else{ + + $scale = ""; + $f_scale = ""; + if($resize == 'yes'){ + $scale = "scale=".$r_width.":".$r_height; + $f_scale = "-s ".$r_width."x".$r_height; + } + $extension = substr($file, strrpos($file,'.') + 1); + + + + //LOG THAT THIS PAGE WAS LOADED (debugging for CLI) + if (ENCODING_LOGGING == "yes") { + //check if file exists + $file_contents = "\n\n\n\n" . 'ClipBucket Conversion debug' . "\n" . + 'CLI for convertor OK' . "\n" . date("l, F d, Y / h:i:s A T (O)") . "\n" . + '================================================================================' . + "\n"; + $log_file = BASEDIR."/logs/logs.txt"; + if (@file_exists($log_file)) {//append to log file + $fo = @fopen($log_file, 'a'); + @fwrite($fo, $file_contents); + @fclose($fo); + } + else { + $fo = @fopen($log_file, 'w');//else create new log + @fwrite($fo, $file_contents); + @fclose($fo); + } + } + + ///////////////////////////////////////////////////////////// + // STEP 1 // + // encode video to flv // + ///////////////////////////////////////////////////////////// + + //This Will Check The Extension of the uploaded video and checks its encoding command against each case + $extension = strtolower($extension); + switch($extension){ + + //For WMV FILES + case 'wmv'; + //For High Quality Video + //$command = "$ffmpeg -i $video_file -ab 64 -ar 44100 -b 300k -r 30 -s 720x480 -sameq $flv_file"; + $command = "$ffmpeg -i $video_file -ab 32 -ar $srate $f_scale $flv_file"; + @exec("$command",$output); + + if(!file_exists($flv_file)){ + $command = "$ffmpeg -i $video_file -ar $srate -ab 32 -f flv $f_scale $flv_file"; + @exec("$command",$output); + } + //debugging + $debug_1 = $command . "\n";//file line of debug + foreach ($output as $outputline) { + $debug_1 = $debug_1 . $outputline . "\n"; + if ($debugmodex == 1) {//no debug mode + echo ("$outputline
    "); + } + } + + if (ENCODING_LOGGING == "yes") { + //check if file exists + $file_contents = 'ClipBucket debug' . "\n" . $command . "\n" . + 'Command was executed.See rest of log for output details' . "\n" . + '=================================================================' . "\n"; + $log_file = BASEDIR."/logs/logs.txt"; + if (@file_exists($log_file)) {//append to log file + $fo = @fopen($log_file, 'a'); + @fwrite($fo, $file_contents); + + + @fclose($fo); + } + else { + $fo = @fopen($log_file, 'w');//else create new log + @fwrite($fo, $file_contents); + @fclose($fo); + } + } + + break; + + //For Avi Files + case 'avi'; + if($resize == 'yes') + { + $command = "$ffmpeg -i $video_file -ab 32 -ar $srate $f_scale $flv_file"; + } + else + { + $command = "$ffmpeg -i $video_file -ab 32 -ar $srate $flv_file"; + } + @exec("$command",$output); + + if(!file_exists($flv_file)){ + if($resize == 'yes') + { + $command = "$ffmpeg -i $video_file -ar $srate -ab 32 -f flv $f_scale $flv_file"; + } + else + { + $command = "$ffmpeg -i $video_file -ar $srate -ab 32 -f flv $flv_file"; + } + @exec("$command",$output); + } + + //debugging + $debug_1 = $command . "\n";//file line of debug + foreach ($output as $outputline) { + $debug_1 = $debug_1 . $outputline . "\n"; + if ($debugmodex == 1) {//no debug mode + echo ("$outputline
    "); + } + } + + if (ENCODING_LOGGING == "yes") { + //check if file exists + $file_contents = 'ClipBucket debug' . "\n" . $command . "\n" . + 'Command was executed.See rest of log for output details' . "\n" . + '=================================================================' . "\n"; + $log_file = BASEDIR."/logs/logs.txt"; + if (@file_exists($log_file)) {//append to log file + $fo = @fopen($log_file, 'a'); + @fwrite($fo, $file_contents); + @fclose($fo); + } + else { + $fo = @fopen($log_file, 'w');//else create new log + @fwrite($fo, $file_contents); + @fclose($fo); + } + } + + break; + + //For FLV Files + case 'flv'; + copy($video_file,$flv_file); + break; + + + default: + //the following can be changed (vbitrate, vop scale, SRATE) + + if($resize == 'yes') + { + $command = "$mencoder $video_file -o $flv_file -of lavf -oac mp3lame -lameopts abr:br=56 -ovc lavc -lavcopts vcodec=flv:vbitrate=$vbrate:mbd=2:mv0:trell:v4mv:keyint=10:cbp:last_pred=3 -lavfopts i_certify_that_my_video_stream_does_not_use_b_frames -vf $scale -srate $srate"; + } + else + { + $command = "$mencoder $video_file -o $flv_file -of lavf -oac mp3lame -lameopts abr:br=56 -ovc lavc -lavcopts vcodec=flv:vbitrate=$vbrate:mbd=2:mv0:trell:v4mv:keyint=10:cbp:last_pred=3 -lavfopts i_certify_that_my_video_stream_does_not_use_b_frames -srate $srate"; + } + @exec("$command",$output); + + + //If no flv was created. Attempt to convert with -vop swicth and not -vf + if(!file_exists($flv_file)){ + if($resize == 'yes') + { + $command = "$mencoder $video_file -o $flv_file -of lavf -oac mp3lame -lameopts abr:br=56 -ovc lavc -lavcopts vcodec=flv:vbitrate=$vbrate:mbd=2:mv0:trell:v4mv:keyint=10:cbp:last_pred=3 -lavfopts i_certify_that_my_video_stream_does_not_use_b_frames -vop $scale -srate $srate"; + } + else + { + $command = "$mencoder $video_file -o $flv_file -of lavf -oac mp3lame -lameopts abr:br=56 -ovc lavc -lavcopts vcodec=flv:vbitrate=$vbrate:mbd=2:mv0:trell:v4mv:keyint=10:cbp:last_pred=3 -lavfopts i_certify_that_my_video_stream_does_not_use_b_frames -srate $srate"; + } + @exec("$command",$output); + } + + //If no flv was created. Attempt to convert with no -lavcopts i_certify_etc_etc + if(!file_exists($flv_file)){ + if($resize == 'yes') + { + $command = "$mencoder $video_file -o $flv_file -of lavf -oac mp3lame -lameopts abr:br=56 -ovc lavc -lavcopts vcodec=flv:vbitrate=$vbrate:mbd=2:mv0:trell:v4mv:keyint=10:cbp:last_pred=3 -vf $scale -srate $srate"; + } + else + { + $command = "$mencoder $video_file -o $flv_file -of lavf -oac mp3lame -lameopts abr:br=56 -ovc lavc -lavcopts vcodec=flv:vbitrate=$vbrate:mbd=2:mv0:trell:v4mv:keyint=10:cbp:last_pred=3 -srate $srate"; + } + @exec("$command",$output); + } + } + +/* //debugging + $debug_1 = @$command . "\n";//file line of debug + foreach ($output as $outputline) { + $debug_1 = $debug_1 . $outputline . "\n"; + if ($debugmodex == 1) {//no debug mode + echo ("$outputline
    "); + } + }*/ + + if (ENCODING_LOGGING == "yes") { + //check if file exists + $file_contents = 'ClipBucket debug' . "\n" . @$command . "\n" . + 'Command was executed.See rest of log for output details' . "\n" . + '=================================================================' . "\n"; + $log_file = BASEDIR."/logs/logs.txt"; + if (@file_exists($log_file)) {//append to log file + $fo = @fopen($log_file, 'a'); + @fwrite($fo, $file_contents); + @fclose($fo); + } + else { + $fo = @fopen($log_file, 'w');//else create new log + @fwrite($fo, $file_contents); + @fclose($fo); + } + } + + ///////////////////////////////////////////////////////////// + // STEP 2 // + // FLVTOOL2 INJECTION // + /////////////////////////////////////////////////////////////; + $flv_cmd = "$flvtool2 -U $flv_file"; + @exec("$flv_cmd 2>&1", $output); + + //debugging + $debug_2 = $flv_cmd . "\n";//file line of debug + foreach ($output as $outputline) { + $debug_2 = $debug_2 . $outputline . "\n"; + + if ($debugmodex == 1) {//no debug mode + echo ("$outputline
    "); + } + } + + if (ENCODING_LOGGING== "yes") { + //check if file exists + $file_contents = 'ClipBucket debug' . "\n" . $flv_cmd . "\n" . + 'Command was executed.See rest of log for output details' . "\n" . + '================================================================================' . + "\n"; + $log_file = BASEDIR."/logs/logs.txt"; + if (@file_exists($log_file)) {//append to log file + $fo = @fopen($log_file, 'a'); + @fwrite($fo, $file_contents); + @fclose($fo); + } + else { + $fo = @fopen($log_file, 'w');//else create new log + @fwrite($fo, $file_contents); + @fclose($fo); + } + } + + ///////////////////////////////////////////////////////////// + // STEP 3 // + // get video duration // + ///////////////////////////////////////////////////////////// + //Try and read the time from the output files +/* $shell_output = $debug_1 . $debug_2;//get as much sheel out put as possible to run search for duration + if (@preg_match('/Video stream:.*bytes..(.*?).sec/', $shell_output, $regs)) { + $sec = $regs[1]; + $duration = $sec;//covert to 00:00:00 i.e. hrs:min:sec + $sec = date("s", strtotime($duration));//change back to seconds for use in getting middle of video + } + else { + $sec = ""; + $duration = $sec; + } + + //check if duration has been picked up...if not try second method (ffmpeg -i video.flv) + if ($sec == "" || !is_numeric($sec)) { + $check_duration = $ffmpeg . ' -i ' . $flv_file; + $durationfile = ""; + @exec("$check_duration 2>&1", $durationoutput); + + foreach ($durationoutput as $outputline) { + $durationfile = $durationfile . $outputline . "\n"; + + } + + if (preg_match('/uration:.(.*?)\./', $durationfile, $regs)) { + $duration = $regs[1];//duration already in 00:00:00 format + $sec = date("s", strtotime($duration));//change back to seconds for use in getting middle of video + $duration = $sec ; + } + + }*/ + + //The Final Step, If Duration Still has not been picked up + if (@$sec == "" || !is_numeric(@$sec) || @$sec == "00") { + exec("$mplayer -vo null -ao null -frames 0 -identify $flv_file", $p); + while(list($k,$v)=each($p)) + { + if($length=strstr($v,'ID_LENGTH=')) + break; + } + $lx = explode("=",$length); + $duration = round($lx[1]); + $sec = $duration ; + } + + //LOG THAT STEP 3 was ok + if (ENCODING_LOGGING == "yes") { + $main_duration = $duration; + //check if file exists + $file_contents = 'ClipBucket debug' . "\n" . + 'MPLAYER - check - Video Duration = ' . $sec. "\n" . + '================================================================================' . + "\n"; + $log_file = BASEDIR."/logs/logs.txt"; + if (@file_exists($log_file)) {//append to log file + $fo = @fopen($log_file, 'a'); + @fwrite($fo, $file_contents); + @fclose($fo); + } + else { + $fo = @fopen($log_file, 'w');//else create new log + @fwrite($fo, $file_contents); + @fclose($fo); + } + } + + + if($keep_original == 1){ + $original_file = BASEDIR.'/files/original/'.$file; + copy($video_file,$original_file); + } + + $status = "Successful"; + + + //If MAX SIZE CONDITION ENDs + mysql_query("INSERT INTO video_detail(flv,status,duration,original) VALUES ('".$flv."','".$status."','".$sec."','".$file."')"); + mysql_query("UPDATE video SET duration='".$sec."' , status='".$status."' WHERE flv = '".$flv."'"); + + + //$this->AssignDefaultThumb($flv); + $this->AssignGeneratedThumbs($flv,$sec); + } + } + unlink($video_file); + if(!file_exists($flv_file)){ + $status = "Failed"; + $this->AssignDefaultThumb($flv); + mysql_query("UPDATE video_detail SET status='".$status."' WHERE flv = '".$flv."'"); + mysql_query("UPDATE video SET active='no' AND status='".$status."' WHERE flv = '".$flv."'"); + } + + //LOG FINAL + if (ENCODING_LOGGING == "yes") { + $main_duration = $duration; + //check if file exists + $file_contents = 'ClipBucket debug' . "\n" . + 'Video PROCESS Status = ' . $status. "\n" . + '================================================================================' . + "\n"; + $log_file = BASEDIR."/logs/logs.txt"; + if (@file_exists($log_file)) {//append to log file + $fo = @fopen($log_file, 'a'); + @fwrite($fo, $file_contents); + @fclose($fo); + } + else { + $fo = @fopen($log_file, 'w');//else create new log + @fwrite($fo, $file_contents); + @fclose($fo); + } + } + } + +} + +/* +$ffmpeg = new ffmpeg(); +$file = "920657135.WMV"; +$flv = "920657135.flv"; +$ffmpeg->ConvertFile($file,$flv); +*/ + +?> \ No newline at end of file diff --git a/upload/includes/classes/curl/class.curl.php b/upload/includes/classes/curl/class.curl.php new file mode 100644 index 00000000..4eff0b34 --- /dev/null +++ b/upload/includes/classes/curl/class.curl.php @@ -0,0 +1,547 @@ +m_header['Set-Cookie'][0] and ...[1] + * + * @access private + * @var mixed + */ + + var $m_header ; + + /** + * Current setting of the curl options. + * + * @access private + * @var mixed + */ + + var $m_options ; + + /** + * Status information for the last executed http request. Includes the errno and error + * in addition to the information returned by curl_getinfo. + * + * The keys defined are those returned by curl_getinfo with two additional + * ones specified, 'error' which is the value of curl_error and 'errno' which + * is the value of curl_errno. + * + * @link http://www.php.net/curl_getinfo + * @link http://www.php.net/curl_errno + * @link http://www.php.net/curl_error + * @access private + * @var mixed + */ + + var $m_status ; + + /** + * Collection of headers when curl follows redirections as per CURLOPTION_FOLLOWLOCATION. + * The collection includes the headers of the final page too. + * + * @access private + * @var array + */ + + var $m_followed ; + + /** + * curl class constructor + * + * Initializes the curl class for it's default behavior: + * o no HTTP headers. + * o return the transfer as a string. + * o URL to access. + * By default, the curl class will simply read the URL provided + * in the constructor. + * + * @link http://www.php.net/curl_init + * @param string $theURL [optional] the URL to be accessed by this instance of the class. + */ + + var $file_size; + + function curl($theURL=null) + { + if (!function_exists('curl_init')) + { + trigger_error('PHP was not built with --with-curl, rebuild PHP to use the curl class.', + E_USER_ERROR) ; + } + + $this->m_handle = curl_init() ; + + $this->m_caseless = null ; + $this->m_header = null ; + $this->m_options = null ; + $this->m_status = null ; + $this->m_followed = null ; + + if (!empty($theURL)) + { + $this->setopt(CURLOPT_URL, $theURL) ; + } + $this->setopt(CURLOPT_HEADER, false) ; + $this->setopt(CURLOPT_RETURNTRANSFER, true) ; + $this->file_size = $this->remote_filesize($theURL); + } + + /** + * Free the resources associated with the curl session. + * + * @link http://www.php.net/curl_close + */ + + function close() + { + curl_close($this->m_handle) ; + $this->m_handle = null ; + } + + /** + * Execute the curl request and return the result. + * + * @link http://www.php.net/curl_exec + * @link http://www.php.net/curl_getinfo + * @link http://www.php.net/curl_errno + * @link http://www.php.net/curl_error + * @return string The contents of the page (or other interaction as defined by the + * settings of the various curl options). + */ + + function exec() + { + $theReturnValue = curl_exec($this->m_handle) ; + + $this->m_status = curl_getinfo($this->m_handle) ; + $this->m_status['errno'] = curl_errno($this->m_handle) ; + $this->m_status['error'] = curl_error($this->m_handle) ; + + // + // Collect headers espesically if CURLOPT_FOLLOWLOCATION set. + // Parse out the http header (from last one if any). + // + + $this->m_header = null ; + + // + // If there has been a curl error, just return a null string. + // + + if ($this->m_status['errno']) + { + return '' ; + } + + if ($this->getOption(CURLOPT_HEADER)) + { + + $this->m_followed = array() ; + $rv = $theReturnValue ; + + while (count($this->m_followed) <= $this->m_status['redirect_count']) + { + $theArray = preg_split("/(\r\n){2,2}/", $rv, 2) ; + + $this->m_followed[] = $theArray[0] ; + + $rv = $theArray[1] ; + } + + $this->parseHeader($theArray[0]) ; + + return $theArray[1] ; + } + else + { + return $theReturnValue ; + } + } + + /** + * Returns the parsed http header. + * + * @param string $theHeader [optional] the name of the header to be returned. + * The name of the header is case insensitive. If + * the header name is omitted the parsed header is + * returned. If the requested header doesn't exist + * false is returned. + * @returns mixed + */ + + function getHeader($theHeader=null) + { + // + // There can't be any headers to check if there weren't any headers + // returned (happens in the event of errors). + // + + if (empty($this->m_header)) + { + return false ; + } + + if (empty($theHeader)) + { + return $this->m_header ; + } + else + { + $theHeader = strtoupper($theHeader) ; + if (isset($this->m_caseless[$theHeader])) + { + return $this->m_header[$this->m_caseless[$theHeader]] ; + } + else + { + return false ; + } + } + } + + /** + * Returns the current setting of the request option. If no + * option has been set, it return null. + * + * @param integer the requested CURLOPT. + * @returns mixed + */ + + function getOption($theOption) + { + if (isset($this->m_options[$theOption])) + { + return $this->m_options[$theOption] ; + } + + return null ; + } + + /** + * Did the last curl exec operation have an error? + * + * @return mixed The error message associated with the error if an error + * occurred, false otherwise. + */ + + function hasError() + { + if (isset($this->m_status['error'])) + { + return (empty($this->m_status['error']) ? false : $this->m_status['error']) ; + } + else + { + return false ; + } + } + + /** + * Parse an HTTP header. + * + * As a side effect it stores the parsed header in the + * m_header instance variable. The header is stored as + * an associative array and the case of the headers + * as provided by the server is preserved and all + * repeated headers (pragma, set-cookie, etc) are grouped + * with the first spelling for that header + * that is seen. + * + * All headers are stored as if they COULD be repeated, so + * the headers are really stored as an array of arrays. + * + * @param string $theHeader The HTTP data header. + */ + + function parseHeader($theHeader) + { + $this->m_caseless = array() ; + + $theArray = preg_split("/(\r\n)+/", $theHeader) ; + + // + // Ditch the HTTP status line. + // + + if (preg_match('/^HTTP/', $theArray[0])) + { + $theArray = array_slice($theArray, 1) ; + } + + foreach ($theArray as $theHeaderString) + { + $theHeaderStringArray = preg_split("/\s*:\s*/", $theHeaderString, 2) ; + + $theCaselessTag = strtoupper($theHeaderStringArray[0]) ; + + if (!isset($this->m_caseless[$theCaselessTag])) + { + $this->m_caseless[$theCaselessTag] = $theHeaderStringArray[0] ; + } + + $this->m_header[$this->m_caseless[$theCaselessTag]][] = $theHeaderStringArray[1] ; + } + } + + /** + * Return the status information of the last curl request. + * + * @param string $theField [optional] the particular portion + * of the status information desired. + * If omitted the array of status + * information is returned. If a non-existant + * status field is requested, false is returned. + * @returns mixed + */ + + function getStatus($theField=null) + { + if (empty($theField)) + { + return $this->m_status ; + } + else + { + if (isset($this->m_status[$theField])) + { + return $this->m_status[$theField] ; + } + else + { + return false ; + } + } + } + + /** + * Set a curl option. + * + * @link http://www.php.net/curl_setopt + * @param mixed $theOption One of the valid CURLOPT defines. + * @param mixed $theValue the value of the curl option. + */ + + function setopt($theOption, $theValue) + { + curl_setopt($this->m_handle, $theOption, $theValue) ; + $this->m_options[$theOption] = $theValue ; + } + + /** + * @desc Post string as an array + * @param string by reference data to be written. + * @return array hash containing the post string as individual elements, urldecoded. + * @access public + */ + + function &fromPostString(&$thePostString) + { + $return = array() ; + $fields = explode('&', $thePostString) ; + foreach($fields as $aField) + { + $xxx = explode('=', $aField) ; + $return[$xxx[0]] = urldecode($xxx[1]) ; + } + + return $return ; + } + + /** + * Arrays are walked through using the key as a the name. Arrays + * of Arrays are emitted as repeated fields consistent with such things + * as checkboxes. + * + * @desc Return data as a post string. + * @param mixed by reference data to be written. + * @param string [optional] name of the datum. + * @access public + */ + + function &asPostString(&$theData, $theName = NULL) + { + $thePostString = '' ; + $thePrefix = $theName ; + + if (is_array($theData)) + { + foreach ($theData as $theKey => $theValue) + { + if ($thePrefix === NULL) + { + $thePostString .= '&' . curl::asPostString($theValue, $theKey) ; + } + else + { + $thePostString .= '&' . curl::asPostString($theValue, $thePrefix . '[' . $theKey . ']') ; + } + } + } + else + { + $thePostString .= '&' . urlencode((string)$thePrefix) . '=' . urlencode($theData) ; + } + + $xxx =& substr($thePostString, 1) ; + + return $xxx ; + } + + /** + * Returns the followed headers lines, including the header of the retrieved page. + * Assumed preconditions: CURLOPT_HEADER and expected CURLOPT_FOLLOWLOCATION set. + * The content is returned as an array of headers of arrays of header lines. + * + * @param none. + * @returns mixed an empty array implies no headers. + * @access public + */ + + function getFollowedHeaders() + { + $theHeaders = array() ; + if ($this->m_followed) + { + foreach ( $this->m_followed as $aHeader ) + { + $theHeaders[] = explode( "\r\n", $aHeader ) ; + } ; + return $theHeaders ; + } + + return $theHeaders ; + } + + + + function remote_filesize($url, $user = "", $pw = "") + { + ob_start(); + $ch = curl_init($url); + curl_setopt($ch, CURLOPT_HEADER, 1); + curl_setopt($ch, CURLOPT_NOBODY, 1); + + if(!empty($user) && !empty($pw)) + { + $headers = array('Authorization: Basic ' . base64_encode("$user:$pw")); + curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); + } + + $ok = curl_exec($ch); + curl_close($ch); + $head = ob_get_contents(); + ob_end_clean(); + + $regex = '/Content-Length:\s([0-9].+?)\s/'; + $count = preg_match($regex, $head, $matches); + + return isset($matches[1]) ? $matches[1] : "unknown"; + } +} +?> diff --git a/upload/includes/classes/errorhandler.class.php b/upload/includes/classes/errorhandler.class.php new file mode 100644 index 00000000..399d7f1a --- /dev/null +++ b/upload/includes/classes/errorhandler.class.php @@ -0,0 +1,141 @@ +error_list[] = $message; + } + + + /** + * Function usd to add new warning + */ + function add_warning($message=NULL,$id=NULL) + { + $this->warning_list[] = $message; + } + + /** + * Function used to get error list + */ + + function error_list() + { + return $this->error_list; + } + + /** + * Function used to flush errors + */ + function flush_error() + { + $this->error_list = ''; + } + + /** + * Functio nused to add message_list + */ + function add_message($message=NULL,$id=NULL) + { + //if id is set, error will be generated from error message list + $this->message_list[] = $message; + } + + /** + * Function used to get message list + */ + function message_list() + { + return $this->message_list; + } + + /** + * Function used to flush message + */ + function flush_msg() + { + $this->message_list = ''; + } + + /** + * Function used to flush warning + */ + function flush_warning() + { + $this->warning_list = ''; + } + + /** + * Function used to flush , both message and error + */ + function flush() + { + $this->flush_msg(); + $this->flush_error(); + $this->flush_warning(); + } + + /** + * Function used to add error or either message using simple + * and small object + * @param : message, @param :type,@param:id + */ + function e($message=NULL,$type=e,$id=NULL) + { + switch($type) + { + case 'm': + case 1: + case 'msg': + case 'message': + $this->add_message($message,$id); + break; + + case 'e': + case 0: + case 'err': + case 'error': + $this->add_error($message,$id); + break; + + case 'w': + case 2: + case 'war': + case 'warning': + $this->add_warning($message,$id); + break; + + default: + $this->error_list($message,$id); + break; + } + + return $message; + } + +} + + +?> \ No newline at end of file diff --git a/upload/includes/classes/form.class.php b/upload/includes/classes/form.class.php new file mode 100644 index 00000000..9f4845a6 --- /dev/null +++ b/upload/includes/classes/form.class.php @@ -0,0 +1,262 @@ + +* @LINK : http://arslan.labguru.com/ - http://clip-bucket.com/ +* @LICENSE : CBLA +* @DATE : Feb 21 2009 +* @Version : 1.0 +* @CB Version : 1.7.2 +* @Class : formObj +*/ + +class formObj +{ + + /** + * FUNCTION USED TO CREATE TEXT FIELD + */ + function createField($field) + { + $field['sep'] = $field['sep'] ? $field['sep'] : '
    '; + + switch($field['type']) + { + case 'textfield': + case 'password': + case 'textarea': + $fields=$this->createTextfield($field); + break; + case 'checkbox': + $fields=$this->createCheckBox($field); + break; + case 'radiobutton': + $fields=$this->createRadioButton($field); + break; + case 'dropdown': + $fields=$this->createDropDown($field); + break; + + } + return $fields; + } + + + /** + * FUNCTION USED TO CREATE TEXT FIELD + * @param name + * @param id + * @param value + * @param class + * @param extra_tags + * @param label + */ + function createTextfield($field) + { + //Starting Text Field + if($field['type']=='textfield') + $textField = ''; + else + $formTextField = $textField; + + return $formTextField; + + } + + + /** + * FUNCTION USED TO CREATE CHECK BOXES + * @param name + * @param id + * @param value = array('value'=>'name') + * @param class + * @param extra_tags + * @param label + */ + + function createCheckBox($field) + { + //First Checking if value is CATEGORY + if($field['value'][0]=='category') + { + $values_array = $field['value'][1][0]; + $field['value'] = ''; + //Generate Category list + $catArray = getCategoryList(); + foreach ($catArray as $cat) + { + $field['value'][$cat['categoryid']] = $cat['category_name']; + } + } + $arrayName = $this->rmBrackets($field['name']); + //Creating Fields + + foreach($field['value'] as $key => $value) + { + if(is_array($values_array)) + { + foreach($values_array as $cat_val) + { + if ($cat_val == $key || $field['checked']=='checked') + { + $checked = ' checked '; + break; + }else{ + $checked = ' '; + } + } + } + echo ''.$value ; + echo $field['sep']; + } + } + + + /** + * FUNCTION USED TO CREATE RADIO Button + * @param name + * @param id + * @param value = array('value'=>'name') + * @param class + * @param extra_tags + * @param label + */ + function createRadioButton($field) + { + //Creating Fields + $count = 0; + $sep = $field['sep']; + $arrayName = $this->rmBrackets($field['name']); + foreach($field['value'] as $key => $value) + { + if(!empty($_POST[$arrayName]) || !empty($field['checked'])) + { + if ($_POST[$arrayName] == $key || $field['checked'] == $key) + { + $checked = ' checked '; + }else{ + $checked = ' '; + } + }else{ + if($count==0) + $checked = ' checked '; + else + $checked = ''; + $count++; + } + echo ''.$value ; + echo $sep; + } + } + + /** + * FUNCTION USED TO REMOVE BRACKET FROM FROM FIELD NAME IF IT IS AN ARRAY + * @param name with brackets + * return name without brackets + */ + function rmBrackets($string) + { + $string = preg_replace('/\[\]/','',$string); + return $string; + } + + + /** + * FUNCTION USED TO CREATEA DROPDOWN MENU + * @param name + * @param id + * @param value = array('value'=>'name') + * @param class + * @param extra_tags + * @param label + */ + + function createDropDown($field) + { + global $LANG; + $ddFieldStart = ''; + echo $ddFieldStart.$fieldOpts.$ddFieldEnd; + } + + + + /** + * Form Validator + * This function used to valid form fields + */ + function validate_form($field,$method,$syntax=NULL) + { + switch($method) + { + case 'username': + $syntax = get_re('username'); + } + + } +} + + + + +?> \ No newline at end of file diff --git a/upload/includes/classes/groups.class.php b/upload/includes/classes/groups.class.php new file mode 100644 index 00000000..c9759a58 --- /dev/null +++ b/upload/includes/classes/groups.class.php @@ -0,0 +1,629 @@ +0){ + return true; + }else{ + return false; + } + } + + //Function Used TO CHeck Weather Entered Name already Exists or not + function ExistsName($name){ + $query = mysql_query("SELECT * FROM groups WHERE group_name = '".$name."'"); + if(mysql_num_rows($query)>0){ + return true; + }else{ + return false; + } + } + + //Function Used To Get Groups Details + function GetDetails($url){ + $query = mysql_query("SELECT * FROM groups WHERE group_url='".$url."'"); + $data = mysql_fetch_array($query); + return $data; + } + + //Function Used To Get Groups Details + function GetDetailsId($id){ + $query = mysql_query("SELECT * FROM groups WHERE group_id='".$id."'"); + $data = mysql_fetch_array($query); + return $data; + } + + + //Check Group Owner + function GetGroupOwner($group,$type=1){ + if($type == 1){ + $data = $this->GetDetailsId($group); + }else{ + $data = $this->GetDetails($group); + } + return $data['username']; + } + + //Function Used TO Join Group + + function JoinGroup($username,$group,$active='yes'){ + global $LANG; + if($this->is_joined($username,$group)){ + $msg = e($LANG['grp_join_error']); + }else{ + if(!mysql_query("INSERT INTO group_members(group_id,username,active)VALUES('".$group."','".$username."','".$active."')")) die(mysql_error()); + $total_users = $this->CountMembers($group); + mysql_query("UPDATE groups SET total_members='".$total_users."' WHERE group_id='".$group."'"); + } + return @$msg; + } + + //Function Used to Validate Group Form + function CreateGroup(){ + global $LANG; + $name = mysql_clean($_POST['name']); + $description = mysql_clean($_POST['description']); + $tags = mysql_clean($_POST['tags']); + $url = mysql_clean($_POST['url']); + @$category = mysql_clean($_POST['category']); + $group_type = mysql_clean($_POST['group_type']); + $video_type = mysql_clean($_POST['video_type']); + $post_type = mysql_clean($_POST['post_type']); + if(@GROUP_ACTIVATION == 'yes'){ + $active = 'no'; + }else{ + $active = 'yes'; + } + $username = $_SESSION['username']; + + //Validation Starts Here + + // If Users Session Ends + if(empty($_SESSION['username'])){ + redirect_to(BASEURL.signup_link); + } + + //If Group Title isnt set + if(empty($name)){ + $msg[] = e($LANG['grp_name_error']); + }elseif($this->ExistsName($name)){ + $msg[] = e($LANG['grp_name_error1']); + } + //if description is not entered + if(empty($description)){ + $msg[] = e($LANG['grp_des_error']); + } + //if tags is not entered + if(empty($tags)){ + $msg[] = e($LANG['grp_tags_error']); + } + //if url is not entered or url already exists + if(empty($url)){ + $msg[] = e($LANG['grp_url_error']); + }elseif(!isValidText($url)){ + $msg[] = e($LANG['grp_url_error1']); + }elseif($this->ExistsURL($url)){ + $msg[] = e($LANG['grp_url_error2']); + } + + //Check If category is not selected + if(empty($category)){ + $msg[] = e($LANG['grp_cat_error']); + } + + //Data Entering + + if(empty($msg)){ + if(!mysql_query("INSERT INTO groups(group_name,group_description,group_tags,group_url,group_category,group_type,video_type,post_type,active,username,group_thumb)VALUES + ('".$name."','".$description."','".$tags."','".$url."','".$category."','".$group_type."','".$video_type."','".$post_type."','".$active."','".$username."','no_thumb.png')")) die(mysql_error()); + $ID = mysql_insert_id(); + //Updating Users Number Of Videos Added By User + $groups_query = mysql_query("SELECT * FROM groups WHERE username='".$username."'"); + $groupscount = mysql_num_rows($groups_query); + $updatequery = mysql_query("UPDATE users SET total_groups='".$groupscount."' WHERE username = '".$username."'"); + //Auto Joining Group Owner + $this->JoinGroup($username,$ID); + + redirect_to(BASEURL.view_group_link.$url); + } + return $msg; + + } + + + //Function Used To add Topics ion the groups + + function AddTopic($topic,$group,$video=0,$approved='yes'){ + global $LANG; + if(empty($topic)){ + if(empty($_SESSION['username'])){ + redirect_to(BASEURL.signup_link); + } + $msg = e($LANG['grp_tpc_error2']); + }else{ + if(!mysql_query("INSERT into group_topics(topic_title,group_id,username,videokey,approved,last_reply) + VALUES('".$topic."','".$group."','".$_SESSION['username']."','".$video."','".$approved."',now())")) die(mysql_error()); + $total_topics = $this->CountTopics($group); + mysql_query("UPDATE groups SET total_topics='".$total_topics."' WHERE group_id='".$group."'"); + $msg[] = e($LANG['grp_tpc_msg'],m); + if($approved=='no'){ + $msg[] = e($LANG['grp_tpc_error3']); + } + } + return $msg; + } + + //Function Used To Get Topic List + + function GetTopics($group){ + $sql = "Select * FROM group_topics WHERE group_id = ''".$group."' AND approved='yes'"; + $data = $db->Execute($sql); + $details = $data->getrows; + return $details; + } + + //Function used to check Topic exists or not + + function is_topic($topic){ + $query = mysql_query("SELECT * FROM group_topics WHERE topic_id ='".$topic."'"); + if(mysql_num_rows($query) >0){ + return true; + }else{ + return false; + } + } + + //Function Used to get Topic + + function GetTopic($topic){ + $query = mysql_query("SELECT * FROM group_topics WHERE topic_id ='".$topic."'"); + return mysql_fetch_array($query); + } + + //Function Used To Add Comments + + function AddComment($comment,$topic,$reply_to=NULL){ + global $LANG; + if(empty($comment)){ + $msg = e($LANG['grp_comment_error']); + }else{ + if(!mysql_query("INSERT INTO group_posts(post,topic_id,username,reply_to)VALUES('".$comment."','".$topic."','".$_SESSION['username']."','".$reply_to."')")) die(mysql_error()); + if(!mysql_query("UPDATE group_topics SET last_reply=now() WHERE topic_id='".$topic."'")) die(mysql_error()); + $msg = e($LANG['grp_comment_msg'],m); + } + return $msg; + } + + //Function Used To Check User is invited or not to join this group + + function is_userinvite($user,$owner,$group){ + $query = mysql_query("SELECT * FROM group_invitations WHERE invited_user='".$user."' AND invited_by ='".$owner."' AND group_id='".$group."'"); + if(mysql_num_rows($query) > 0){ + $query = mysql_query("SELECT * FROM groups WHERE username = '".$owner."' AND group_id ='".$group."'"); + if(mysql_num_rows($query) > 0){ + return true; + }else{ + return false; + } + }else{ + return false; + } + } + + //Function Used To CHeck User Is Joined or not + + function is_joined($username,$group){ + $query = mysql_query("SELECT * FROM group_members WHERE username = '".$username."' AND group_id ='".$group."'"); + if(mysql_num_rows($query)>0){ + return true; + }else{ + return false; + } + } + + //Function Used To CHeck User Is Active or not + + function is_active($username,$group){ + $query = mysql_query("SELECT * FROM group_members WHERE username = '".$username."' AND group_id ='".$group."' AND active='yes'"); + if(mysql_num_rows($query)>0){ + return true; + }else{ + return false; + } + } + + //Function Used To update group + + function UpdateGroup($redirect=1){ + global $LANG; + $name_exist = $_POST['name_exist']; + $url_exist = $_POST['url_exist']; + $name = mysql_clean($_POST['name']); + $description = mysql_clean($_POST['description']); + $tags = mysql_clean($_POST['tags']); + $url = mysql_clean($_POST['url']); + $category = mysql_clean($_POST['category']); + $group_type = mysql_clean($_POST['group_type']); + $video_type = mysql_clean($_POST['video_type']); + $post_type = mysql_clean($_POST['post_type']); + //If Group Title isnt set + if(empty($name)){ + $msg[] = e($LANG['grp_name_error']); + }elseif($this->ExistsName($name) && $name_exist !== $name ){ + $msg[] = e($LANG['grp_name_error1']); + } + //if description is not entered + if(empty($description)){ + $msg[] = e($LANG['grp_des_error']); + } + //if tags is not entered + if(empty($tags)){ + $msg[] = e($LANG['grp_tags_error']); + } + //if url is not entered or url already exists + if(empty($url)){ + $msg[] = e($LANG['grp_url_error']); + }elseif(!isValidText($url)){ + $msg[] = e($LANG['grp_url_error1']); + }elseif($this->ExistsURL($url) && $url_exist !== $url){ + $msg[] = e($LANG['grp_url_error2']); + } + + //Getting Thumb + $file = $_FILES['thumb_upload']['name']; + $thumb = $_POST['thumb_exist']; + $ext = substr($file, strrpos($file, '.') + 1); + + if(empty($msg)){ + + if(!empty($file)){ + $image = new ResizeImage(); + if($image->ValidateImage($_FILES['thumb_upload']['tmp_name'],$ext)){ + if($thumb != 'no_thumb.png'){ + unlink(BASEDIR.'/images/groups_thumbs/'.$thumb); + } + $newname = RandomString(10); + $newthumb = $newname.'.'.$ext; + $new_thumb = BASEDIR.'/images/groups_thumbs/'.$newthumb; + copy($_FILES['thumb_upload']['tmp_name'],$new_thumb); + $image->CreateThumb($new_thumb,$new_thumb,120,$ext); + $thumb = $newthumb; + } + } + + if(!mysql_query("UPDATE groups SET + group_name = '".$name."', + group_tags = '".$tags."', + group_description = '".$description."', + group_url = '".$url."', + group_category = '".$category."', + group_type = '".$group_type."', + video_type = '".$video_type."', + post_type = '".$post_type."', + group_thumb = '".$thumb."' + WHERE group_id = '".$_POST['group_id']."'")) die(mysql_error()); + $msg = e($LANG['grp_update_msg'],m); + if($redirect == 1){ + redirect_to(BASEURL.edit_group_link.$url.'&update=true'); + } + } + return $msg; + } + + //Function Used To Count Number Of Member in a group + function CountMembers($group){ + $query = mysql_query("SELECT * FROM group_members WHERE group_id='".$group."' AND active='yes'"); + return mysql_num_rows($query); + } + + //Function Used to Count Number of Video In A Group + function CountVideos($group){ + $query = mysql_query("SELECT * FROM group_videos WHERE group_id='".$group."' AND approved='yes'"); + return mysql_num_rows($query); + } + + //Function Used To Count Nmber of topics + function CountTopics($group){ + $query = mysql_query("SELECT * FROM group_topics WHERE group_id='".$group."' AND approved='yes'"); + return mysql_num_rows($query); + } + + //Function Used TO check Number of posts in a group + function CountGroupPosts($group){ + $query = mysql_query("SELECT * FROM group_topics WHERE group_id='".$group."' AND approved='yes'"); + $topics = 0; + while($data = mysql_fetch_array($query)){ + $topic_query = mysql_query("SELECT * FROM group_posts WHERE topic_id ='".$data['topic_id']."'"); + $topics = $topics + mysql_num_rows($topic_query); + } + return $topics; + } + + //Function Used To Get Number Of Replies in a post + + function CountReplies($topic){ + $query = mysql_query("SELECT * FROM group_posts WHERE topic_id ='".$topic."'"); + return mysql_num_rows($query); + } + + //Function Used TO check Video exist in the group or not + + function is_video($group,$video){ + $query = mysql_query("SELECT * FROM group_videos WHERE videokey = '".$video."' AND group_id = '".$group."'"); + if(mysql_num_rows($query)>0){ + return true; + }else{ + return false; + } + } + + //Function Used To Add Videos To Groups + + function AddVideos($group,$approved='yes'){ + global $LANG; + if(!empty($_SESSION['username'])){ + $msg = e($LANG['grp_vdo_msg1'],m); + $query = mysql_query("SELECT * FROM video WHERE username = '".$_SESSION['username']."' "); + while($data = mysql_fetch_array($query)){ + if($_POST[$data['videokey']] == 'yes'){ + if(!$this->is_video($group,$data['videokey'])){ + if(!mysql_query("INSERT INTO group_videos(videokey,group_id,username,approved)VALUES('".$data['videokey']."','".$group."','".$_SESSION['username']."','".$approved."') ")) die(mysql_error()); + $total_videos = $this->CountVideos($group); + mysql_query("UPDATE groups SET total_videos='".$total_videos."' WHERE group_id='".$group."'"); + } + } + } + } + return $msg; + } + + + //Function Used To Delete Videos + + function RemoveVideos($group){ + global $LANG; + $query = mysql_query("SELECT * FROM group_videos WHERE group_id = '".$group."'"); + while($data = mysql_fetch_array($query)){ + if($_POST[$data['videokey']] == 'yes'){ + mysql_query("DELETE FROM group_videos WHERE videokey = '".$data['videokey']."'"); + $total_videos = $this->CountVideos($group); + mysql_query("UPDATE groups SET total_videos='".$total_videos."' WHERE group_id='".$group."'"); + } + } + $msg = e($LANG['grp_vdo_msg'],m); + return $msg; + } + + //Function Used To Approve Movies + + function ApproveVideos($group){ + global $LANG; + $query = mysql_query("SELECT * FROM group_videos WHERE group_id = '".$group."'"); + while($data = mysql_fetch_array($query)){ + if($_POST[$data['videokey']] == 'yes'){ + mysql_query("UPDATE group_videos SET approved='yes' WHERE videokey = '".$data['videokey']."'"); + $total_videos = $this->CountVideos($group); + mysql_query("UPDATE groups SET total_videos='".$total_videos."' WHERE group_id='".$group."'"); + } + } + $msg = e($LANG['grp_vdo_msg2'],m); + return $msg; + } + + //Function Used To Delete Members + + function RemoveMembers($group){ + global $LANG; + $query = mysql_query("SELECT * FROM group_members WHERE group_id = '".$group."'"); + while($data = mysql_fetch_array($query)){ + if($_POST[$data['username']] == 'yes'){ + mysql_query("DELETE FROM group_members WHERE username = '".$data['username']."'"); + $total_users = $this->CountMembers($group); + mysql_query("UPDATE groups SET total_members='".$total_users."' WHERE group_id='".$group."'"); + } + } + $msg = e($LANG['grp_mem_msg'],m); + return $msg; + } + + //Function Used To Approve Members + + function ApproveMembers($group){ + global $LANG; + $query = mysql_query("SELECT * FROM group_members WHERE group_id = '".$group."'"); + while($data = mysql_fetch_array($query)){ + if($_POST[$data['username']] == 'yes'){ + mysql_query("UPDATE group_members SET active='yes' WHERE username = '".$data['username']."'"); + $total_users = $this->CountMembers($group); + mysql_query("UPDATE + groups SET total_members='".$total_users."' WHERE group_id='".$group."'"); + } + } + $msg = e($LANG['grp_mem_msg1'],m); + return $msg; + } + + //Function Used To Send Invitations + + function SendInvitation($user,$group,$subj,$url){ + global $LANG; + $video = ""; + //Sending Message to Website Users + $query = mysql_query("SELECT * FROM contacts WHERE username='".$user."'"); + while($data=mysql_fetch_array($query)){ + if($_POST[$data['friend_username']] == 'yes'){ + //Send Message To $data['friend_username'] + $myquery = new myquery(); + $to = $data['friend_username']; + $from = $_SESSION['username']; + $message = nl2br(mysql_clean($_POST['msg']))."
    Groupurl:
    ".$url.""; + $redirect = 0; + $myquery->SendMessage($to,$from,$subj,$message,$video,$redirect); + mysql_query("INSERT INTO group_invitations(group_id,invited_user,invited_by)VALUES('".$group."','".$to ."','".$from."')"); + } + } + + //Sending Message Getting User From Boxes + $users = $_POST['users']; + $new_users = explode(',',$users); + foreach($new_users as $user){ + $query = mysql_query("SELECT * FROM users WHERE username='".$user."' OR email='".$user."'"); + if(mysql_num_rows($query) > 0){ + $data = mysql_fetch_array($query); + $myquery = new myquery(); + $to = $data['username']; + $from = $_SESSION['username']; + $message = nl2br(mysql_clean($_POST['msg']))."
    Groupurl: ".$url.""; + $redirect = 0; + $myquery->SendMessage($to,$from,$subj,$message,$video,$redirect); + mysql_query("INSERT INTO group_invitations(group_id,invited_user,invited_by)VALUES('".$group."','".$to ."','".$from."')"); + }elseif(isValidEmail($user)){ + $to = $data['friend_username']; + $from = $_SESSION['username']; + $message = nl2br(mysql_clean($_POST['msg']))."
    Groupurl: ".$url."";; + $redirect = 0; + send_email($from,$to,$subj,$message); + } + } + $msg = e($LANG['grp_inv_msg'],m); + return $msg; + } + + + //Function Used TO Delete Post + function DeletePost($post){ + global $LANG; + mysql_query("DELETE FROM group_posts WHERE post_id='".$post."'"); + $msg = e($LANG['grp_post_msg'],m); + return $msg; + } + + //Function Used To Leave Group + function LeaveGroup($user,$group){ + global $LANG; + //CHecking if user is Group Owner or not + $owner = $this->GetGroupOwner($group); + if($owner == $user){ + return false; + }else{ + mysql_query("DELETE FROM group_members WHERE group_id='".$group."' AND username='".$user."' "); + $total_users = $this->CountMembers($group); + mysql_query("UPDATE groups SET total_members='".$total_users."' WHERE group_id='".$group."'"); + return true; + } + } + + //Function Used To Delete Topic + function DeleteTopic($topic){ + global $LANG; + mysql_query("DELETE FROM group_topics WHERE topic_id='".$topic."'"); + mysql_query("DELETE FROM group_posts WHERE topic_id='".$topic."'"); + $total_topics = $this->CountTopics($group); + mysql_query("UPDATE groups SET total_topics='".$total_topics."' WHERE group_id='".$group."'"); + $msg = e($LANG['grp_tpc_msg'],m); + return $msg; + } + + + //Function Used To Delete Group + function DeleteGroup($group){ + global $LANG; + $__groupsquery = mysql_query("SELECT * FROM groups WHERE group_id='".$group."'"); + $__Data = mysql_fetch_array($__groupsquery); + mysql_query("DELETE FROM group_members WHERE group_id='".$group."'"); + mysql_query("DELETE FROM group_videos WHERE group_id='".$group."'"); + mysql_query("DELETE FROM group_invitations WHERE group_id='".$group."'"); + $query = mysql_query("SELECT * FROM group_topics WHERE group_id='".$group."'"); + while($data=mysql_fetch_array($query)){ + $this->DeleteTopic($data['topic_id']); + } + mysql_query("DELETE FROM groups WHERE group_id='".$group."'"); + //Updating Users Number Of Videos Added By User + $groups_query = mysql_query("SELECT * FROM groups WHERE username='".$__Data['username']."'"); + $groupscount = mysql_num_rows($groups_query); + $updatequery = mysql_query("UPDATE users SET total_groups='".$groupscount."' WHERE username = '".@$username."'"); + $msg = e($LANG['grp_del_msg']); + return $msg; + } + + //Function Used To Approve Topics + function ApproveTopic($topic){ + mysql_query("UPDATE group_topics SET approved='yes' WHERE topic_id='".$topic."'"); + $msg = e($LANG['grp_tpc_msg2'],m); + return $msg; + } + + //Functoin USed To Check weather group exist or not + + function GroupExists($group){ + $query = mysql_query("SELECT * FROM groups WHERE group_id = '".$group."'"); + if(mysql_num_rows($query)>0){ + return true; + }else{ + return false; + } + } + + //Function Used To Feature Group + + function MakeFeatured($group){ + global $LANG; + mysql_query("UPDATE groups SET featured='yes' WHERE group_id='".$group."'"); + return e($LANG['grp_fr_msg'],m); + } + + //Function Used To UngFeatured Group + + function MakeUnFeatured($group){ + global $LANG; + mysql_query("UPDATE groups SET featured='no' WHERE group_id='".$group."'"); + return e($LANG['grp_fr_msg2'],m); + } + + //Function Used To Activate Group + + function Activate($group){ + global $LANG; + mysql_query("UPDATE groups SET active='yes' WHERE group_id='".$group."'"); + return e($LANG['grp_av_msg'],m); + } + + //Function Used To DeActivate Group + + function DeActivate($group){ + global $LANG; + mysql_query("UPDATE groups SET active='no' WHERE group_id='".$group."'"); + return e($LANG['grp_inv_msg1'],m); + } + + /** + * FUNCTION USED TO GET GROUP THUMB + * @param : group thumb + */ + function getThumb($groupThumb) + { + //Path to thumbs directory + $dir = BASEDIR.'/images/groups_thumbs/'; + $url = BASEURL.'/images/groups_thumbs/'; + $thumb = $dir.$groupThumb; + $thumb_url = $url.$groupThumb; + $default = $url.'no_thumb.png'; + //Checking if thumb exists or not + if(file_exists($thumb)) + { + return $thumb_url; + }else{ + return $default; + } + } +} +?> \ No newline at end of file diff --git a/upload/includes/classes/image.class.php b/upload/includes/classes/image.class.php new file mode 100644 index 00000000..e2d9f661 --- /dev/null +++ b/upload/includes/classes/image.class.php @@ -0,0 +1,61 @@ + $height_orig) + $ratio= $width_orig/$dim; + else $ratio=$height_orig/$dim; + + $width=$width_orig/$ratio; + $height=$height_orig/$ratio; + + if($aspect_ratio == false && $dim_h !=''){ + $width = $dim; + $height = $dim_h; + } + + $image_p = imagecreatetruecolor($width, $height); + + if($ext=='jpg' || $ext=='JPG' || $ext=='JPEG'){ + $image = imagecreatefromjpeg($file); + imagecopyresampled($image_p, $image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig); + imagejpeg($image_p,$des, 90); + } + if($ext=='png' || $ext=='PNG'){ + $image = imagecreatefrompng($file); + imagecopyresampled($image_p, $image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig); + imagepng($image_p,$des); + } + + if($ext=='gif' || $ext=='GIF'){ + $image = imagecreatefromgif($file); + imagecopyresampled($image_p, $image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig); + imagegif($image_p,$des, 90); + } + + } + + //Validating an Image + + function ValidateImage($file,$ext=NULL){ + $array = getimagesize($file); + if($ext == 'jpg' || $ext == 'JPG' ||$ext == 'JPEG' || $ext == 'gif' || $ext == 'GIF' || $ext == 'PNG' || $ext == 'png'){ + if(empty($array[0]) || empty($array[1])){ + $validate = false; + }else{ + $validate = true; + } + }else{ + $validate = false; + } + return $validate; + } +} +?> \ No newline at end of file diff --git a/upload/includes/classes/index.php b/upload/includes/classes/index.php new file mode 100644 index 00000000..403f2e18 --- /dev/null +++ b/upload/includes/classes/index.php @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/upload/includes/classes/lang.class.php b/upload/includes/classes/lang.class.php new file mode 100644 index 00000000..72d44d4d --- /dev/null +++ b/upload/includes/classes/lang.class.php @@ -0,0 +1,191 @@ +lang = $this->lang_iso = 'en'; + } + + + /** + * Function used add new phrase + */ + function add_phrase($name,$text,$lang_code='en') + { + global $db; + //First checking if phrase already exists or not + if(empty($name)) + e("Phrase code was empty"); + elseif(empty($text)) + e("Phrase text was empty"); + elseif(!$this->lang_exists($lang_code)) + e("Language does not exist"); + elseif(!$this->get_phrase($name,$lang_code)) + { + e("'$name' has been added",m); + $db->insert("phrases",array('lang_iso','varname','text'),array($lang_code,$name,$text)); + }else{ + e("'$name' alread exists",m); + } + } + + /** + * Function used to get language phrase + * @param STRING name + * @param STRING lang_code + */ + function get_phrase($name,$lang_code=NULL) + { + global $db; + + if($lang_code!='') + { + $lang_query = "AND lang_iso = '".mysql_clean($lang_code)."'"; + } + + $results = $db->select("phrases",'*'," id = '".mysql_clean($name)."' OR varname = '".mysql_clean($name)."' $lang_query "); + if($db->num_rows > 0 ) + return $results[0]; + else + return false; + } + + + /** + * Function used to modify phrase + */ + function update_phrase($id,$text,$lang_code='en') + { + global $db; + //First checking if phrase already exists or not + if($this->get_phrase($id,$lang_code)) + $db->update("phrases",array('text'),array($text)," id = '".mysql_clean($id)."' "); + } + + /** + * Function used to get all phrases of particular language + */ + function get_phrases($lang=NULL,$fields="varname,text",$limit=NULL,$extra_param=NULL) + { + global $db; + $lang_details = $this->lang_exists($lang); + $lang_code = $lang_details['lang_code']; + if(empty($lang_code)) + $lang_code = $this->lang; + return $db->select("phrases",$fields," lang_iso = '".$lang_code."' $extra_param",$limit," id "); + + } + + + /** + * Function used to count phrases + */ + function count_phrases($lang=NULL,$extra_param=NULL) + { + global $db; + $lang_details = $this->lang_exists($lang); + $lang_code = $lang_details['lang_code']; + if(empty($lang_code)) + $lang_code = $this->lang; + + $results = $db->select("phrases","COUNT(id)"," lang_iso = '".$lang_code."' $extra_param"); + if($db->num_rows>0) + return $results[0][0]; + else + return 0; + + } + + /** + * Function used to assign phrases as an array + */ + function lang_phrases() + { + $phrases = $this->get_phrases(); + foreach($phrases as $phrase) + { + $lang[$phrase['varname']] = $phrase['text']; + } + return $lang; + } + + + /** + * Function used to get list of languages installed + */ + function get_langs() + { + global $db; + $results = $db->select("languages","*"); + return $results; + } + + + + /** + * Function used to check + * weather language existsor not + * using iso_code or its lang_id + */ + function lang_exists($id) + { + global $db; + $results = $db->select("languages","*"," language_code ='$id' OR language_id = '$id'"); + if($db->num_rows>0) + return $results[0]; + else + return false; + } + + + /** + * Make Language Default + */ + function make_default($lid) + { + global $db; + if($this->lang_exists($lid)) + { + $db->update("languages",array("language_default"),array("no")," language_default='yes'"); + $db->update("languages",array("language_default"),array("yes")," language_id='$lid'"); + } + } + + /** + * Funcion used to get language detilas + */ + function get_lang($id) + { + return $this->lang_exists($id); + } +} + +?> \ No newline at end of file diff --git a/upload/includes/classes/log.class.php b/upload/includes/classes/log.class.php new file mode 100644 index 00000000..ae223602 --- /dev/null +++ b/upload/includes/classes/log.class.php @@ -0,0 +1,65 @@ +insert('action_log', + array + ( + 'action_type', + 'action_username', + 'action_userid', + 'action_useremail', + 'action_ip', + 'date_added', + 'action_success', + 'action_details', + 'action_userlevel', + ), + array + ( + $type, + $username, + $userid , + $useremail, + $ip, + NOW(), + $success, + $details, + $userlevel + ) + ); + + } + +} + +?> \ No newline at end of file diff --git a/upload/includes/classes/mass_upload.class.php b/upload/includes/classes/mass_upload.class.php new file mode 100644 index 00000000..b33775c6 --- /dev/null +++ b/upload/includes/classes/mass_upload.class.php @@ -0,0 +1,106 @@ +UpdateVideoRecord(1); + } +} diff --git a/upload/includes/classes/my_queries.class.php b/upload/includes/classes/my_queries.class.php new file mode 100644 index 00000000..0b46762a --- /dev/null +++ b/upload/includes/classes/my_queries.class.php @@ -0,0 +1,1526 @@ +update("config",array('value'),array($value)," name = '".$name."'"); + } + + //Updating Plugin Details + function Set_Plugin_Details($name,$value){ + mysql_query("UPDATE plugin_config SET plugin_config_value = '".$value."' WHERE plugin_config_name ='".$name."'"); + } + + function Set_Email_Settings($name,$value){ + mysql_query("UPDATE email_settings config SET email_settings_value = '".$value."' WHERE email_settings_name ='".$name."'"); + } + function Set_Email_Settings_Headers($name,$header){ + mysql_query("UPDATE email_settings config SET email_settings_headers = '".$header."' WHERE email_settings_name ='".$name."'"); + } + + function Get_Website_Details(){ + $query = mysql_query("SELECT * FROM config"); + while($row = mysql_fetch_array($query)){ + $name = $row['name']; + $data[$name] = $row['value']; + } + return $data; + } + + function Get_Plugin_Details(){ + $query = mysql_query("SELECT * FROM plugin_config"); + if(mysql_num_rows($query) > 0) + { + while($row = mysql_fetch_array($query)){ + $name = $row['plugin_config_name']; + $data[$name] = $row['plugin_config_value']; + } + return $data; + } + } + + function Get_Email_Settings(){ + $query = mysql_query("SELECT * FROM email_settings"); + while($row = mysql_fetch_array($query)){ + $name = $row['email_settings_name']; + $data[$name] = $row['email_settings_value']; + } + return $data; + } + + function Get_Email_Settings_Headers(){ + $query = mysql_query("SELECT * FROM email_settings"); + while($row = mysql_fetch_array($query)){ + $name = $row['email_settings_name']; + $data[$name] = $row['email_settings_headers']; + } + return $data; + } + + function Get_Advertisments(){ + $query = mysql_query("SELECT * FROM ads_data + WHERE ad_id >= FLOOR( RAND( ) * ( SELECT MAX( ad_id ) FROM ads_data ) ) AND ad_status='1' + ORDER BY ad_id ASC + "); + while($row = mysql_fetch_array($query)){ + $id = $row['ad_id']; + $imp = $row['ad_impressions']+1; + $name = $row['ad_placement']; + $data[$name] = stripslashes($row['ad_code']); + //Update IMpressions + mysql_query("UPDATE ads_data SET ad_impressions ='".$imp."' WHERE ad_id='".$id."' "); + + } + return $data; + } + + function check_user($username){ + $query = mysql_query("SELECT * FROM users WHERE username ='".$username."'"); + if(mysql_num_rows($query) > 0){ + return true; + }else{ + return false; + } + } + + function check_email($email){ + $query = mysql_query("SELECT * FROM users WHERE email ='".$email."'"); + if(mysql_num_rows($query) > 0){ + return true; + }else{ + return false; + } + + } + + function fetch($query){ + $fetch = mysql_fetch_array($query); + return $fetch; + } + + //This Function is used to Add Categories + + function AddCategory(){ + global $LANG; + $title = mysql_clean($_POST['title']); + $description = mysql_clean($_POST['description']); + $file = $_FILES['category_thumb']['name']; + $ext = substr($file, strrpos($file, '.') + 1); + $thumb = 'no_thumb.jpg'; + if(!empty($file)){ + $image = new ResizeImage(); + if($image->ValidateImage($_FILES['category_thumb']['tmp_name'],$ext)){ + $newfilename = RandomString(10).'.'.$ext; + $category_thumb = '../images/category_thumbs/'.$newfilename; + copy($_FILES['category_thumb']['tmp_name'],$category_thumb); + $image->CreateThumb($category_thumb,$category_thumb,120,$ext); + $thumb = $newfilename; + }else{ + $msg[] = e($LANG['class_error_occured']); + $add = false; + } + } + if(empty($msg)){ + mysql_query("INSERT INTO category(category_name,category_description,category_thumb,date_added) + VALUES('".$title."','".$description."','".$thumb."',now())"); + $add = true; + } + return $add; + } + + //This Function Is Used to Check Category Exits or Not + + function CategoryExists($category){ + $query = mysql_query("SELECT categoryid FROM category WHERE categoryid ='".$category."'"); + if(mysql_num_rows($query)>0){ + return true; + }else{ + return false; + } + } + + //This Function Is Used to Update Category + + function UpdateCategory($category){ + global $LANG; + $title = mysql_clean($_POST['title']); + $description = mysql_clean($_POST['description']); + $file = $_FILES['category_thumb']['name']; + $ext = substr($file, strrpos($file, '.') + 1); + $thumb = $_POST['thumb']; + if(!empty($file)){ + $image = new ResizeImage(); + if($image->ValidateImage($_FILES['category_thumb']['tmp_name'],$ext)){ + if($thumb != 'no_thumb.jpg'){ + unlink('../images/category_thumbs/'.$thumb); + } + $newfilename = RandomString(10).'.'.$ext; + $category_thumb = '../images/category_thumbs/'.$newfilename; + copy($_FILES['category_thumb']['tmp_name'],$category_thumb); + $image->CreateThumb($category_thumb,$category_thumb,120,$ext); + $thumb = $newfilename; + } + } + if(empty($msg)){ + mysql_query("UPDATE category SET + category_name ='".$title."', + category_description ='".$description."', + category_thumb ='".$thumb."' + WHERE categoryid = '".$category."'"); + $update = true; + } + return $update; + } + + //Function Delete Category + function DeleteCategory($category){ + global $LANG; + mysql_query("DELETE FROM category WHERE categoryid='".$category."'"); + $msg=e($LANG['class_cat_del_msg'],m); + return $msg; + } + + //Function Used to Delete Flv File + + function DeleteFlv($flv){ + $file = BASEDIR.'/files/videos/'.$flv; + if(file_exists($file) && !empty($flv)){ + unlink($file); + } + } + + //Function Used To Delete the Original Video + + function DeleteOriginal($file){ + $file_path = BASEDIR.'/files/original/'.$file; + if(file_exists($file_path) && !empty($file)){ + unlink($file_path); + } + } + + //Function Used to Delete Video Thumbs + + function DeleteThumbs($flv){ + $thumb = substr($flv, 0, strrpos($flv, '.')); + $thumb1 = BASEDIR."/files/thumbs/".$thumb."-1.jpg"; + $thumb2 = BASEDIR."/files/thumbs/".$thumb."-2.jpg"; + $thumb3 = BASEDIR."/files/thumbs/".$thumb."-3.jpg"; + $thumb4 = BASEDIR."/files/thumbs/".$thumb."-big.jpg"; + + if(file_exists($thumb1)){ + unlink($thumb1); + } + if(file_exists($thumb2)){ + unlink($thumb2); + } + if(file_exists($thumb3)){ + unlink($thumb3); + } + if(file_exists($thumb4)){ + unlink($thumb4); + } + + } + + //Function Used to Check Weather Video Exists or not + function video_exists($videoid) + { + return $this->VideoExists($videoid); + } + function VideoExists($videoid){ + $query = mysql_query("SELECT videoid FROM video WHERE videoid ='".$videoid."'"); + if(mysql_num_rows($query)>0){ + return true; + }else{ + return false; + } + } + + //Function Used to Delete Video Files + + function DeleteVideoFiles($videoid){ + $query = mysql_query("SELECT * FROM video WHERE videoid ='".$videoid."'"); + $data = mysql_fetch_array($query); + $flv = $data['flv']; + $query = mysql_query("SELECT * FROM video_detail WHERE flv ='".$data['flv']."'"); + $data = mysql_fetch_array($query); + + //Updating Users Number Of Videos Added By User + $videos_query = mysql_query("SELECT * FROM video WHERE username='".@$data['username']."'"); + + $this->DeleteOriginal($data['original']); + $this->DeleteFlv($data['flv']); + $this->DeleteThumbs($data['flv']); + mysql_query("DELETE FROM video_detail WHERE flv='".$data['flv']."'"); + + $videoscount = mysql_num_rows($videos_query); + $updatequery = mysql_query("UPDATE users SET total_videos='".$videoscount."' WHERE username = '".@$username."'"); + } + + //Function Delete Video + + function DeleteVideo($videoid){ + global $LANG,$stats; + $this->DeleteVideoFiles($videoid); + $this->DeleteFlag($videoid); + $this->RemoveFavourite($videoid,NULL,2); + mysql_query("DELETE FROM video WHERE videoid='".$videoid ."'"); + $msg = e($LANG['class_vdo_del_msg'],m); + $stats->UpdateVideoRecord(2); + return $msg; + } + + //Function Used to Make Video Featured + + function MakeFeaturedVideo($videoid){ + global $LANG; + mysql_query("UPDATE video SET featured = 'yes' WHERE videoid='".$videoid."'"); + $msg = e($LANG['class_vdo_fr_msg'],m); + return $msg; + } + + //Function Used to Make Video UnFeatured + + function MakeUnFeaturedVideo($videoid){ + global $LANG; + mysql_query("UPDATE video SET featured = 'no' WHERE videoid='".$videoid."'"); + $msg = e($LANG['class_fr_msg1'],m); + return $msg; + } + + //Function Used to Activate Vide + + function ActivateVideo($videoid){ + global $LANG,$stats; + mysql_query("UPDATE video SET active = 'yes' WHERE videoid='".$videoid."'"); + $msg = e($LANG['class_vdo_act_msg'],m); + $stats->UpdateVideoRecord(11); + return $msg; + } + + //Function Used to Deactivate Video + + function DeActivateVideo($videoid){ + global $LANG,$stats; + mysql_query("UPDATE video SET active = 'no' WHERE videoid='".$videoid."'"); + $msg = e($LANG['class_vdo_act_msg1'],m); + $stats->UpdateVideoRecord(12); + return $msg; + } + + + /** + * Function used to get video details + * from video table + * @param INPUT vid or videokey + */ + function get_video_details($vid) + { + global $db; + $results = $db->select("video","*"," videoid='$vid' OR videokey='$vid'"); + return $results[0]; + } + function GetVideoDetails($video){ + return $this->get_video_details; + } + + + //Function Used To Update Video Details + + function UpdateVideo($video){ + global $LANG,$Upload; + + $title = mysql_clean($_POST['title']); + $description = mysql_clean($_POST['description']); + $tags = mysql_clean($_POST['tags']); + $broadcast = $_POST['broadcast']; + $comments = $_POST['comments']; + $comment_voting = $_POST['comment_voting']; + $rating = $_POST['rating']; + $embedding = $_POST['embedding']; + $country = mysql_clean($_POST['country']); + $location = mysql_clean($_POST['location']); + + if(!empty($_POST['year']) && !empty($_POST['day']) && !empty($_POST['month'])){ + $date = $_POST['year'].'-'.$_POST['month'].'-'.$_POST['day']; + } + + $sql = mysql_query("SELECT * from category"); + $total_categories = mysql_num_rows($sql); + + for($id=0;$id<=$total_categories;$id++){ + @$category = $_POST['category'][$id]; + if(!empty($category)){ + $selected[] = $category ; + } + } + $category01 = $selected[0]; + @$category02 = $selected[1]; + @$category03 = $selected[2]; + + //If Video Is Updated via Admin Panel + if($_POST['admin']=='true'){ + if(!empty($_POST['duration'])){ + $add_query = ",duration='".$_POST['duration']."'"; + } + if(!empty($_POST['embed_code'])){ + $embedCode = $Upload->CleanEmbedCode($_POST['embed_code']); + $add_query .= ",embed_code='".$embedCode."'"; + } + if(!empty($_POST['flv_file_url'])){ + $file_url = mysql_clean($_POST['flv_file_url']); + $add_query .= ",flv_file_url='".$file_url."'"; + } + if(!empty($_POST['embeded'])){ + $add_query .= ",embeded='".$_POST['embeded']."'"; + } + $add_query .= ",status='".$_POST['status']."'"; + + //Stats Update + //Views + $views = $_POST['views']; + if(is_numeric($views) && $views > 0) + $add_query .= ",views='".$views."'"; + //Rating + $Totalrating = $_POST['Totalrating']; + if(is_numeric($Totalrating)){ + $Totalrating = $Totalrating <=10 ? $Totalrating : '10'; + $Totalrating = $Totalrating >=0 ? $Totalrating : '0'; + $add_query .= ",rating='".$Totalrating."'"; + } + //RatedBy + $rated_by = $_POST['rated_by']; + if(is_numeric($rated_by) && $rated_by> 0) + $add_query .= ",rated_by='".$rated_by."'"; + } + + mysql_query("UPDATE video SET + title = '".$title."', + description = '".$description."', + tags = '".$tags."', + broadcast = '".$broadcast."', + allow_comments = '".$comments."', + comment_voting = '".$comment_voting."', + allow_rating = '".$rating."', + allow_embedding = '".$embedding."', + country = '".$country."', + location = '".$location."', + category01 = '".$category01."', + category02 = '".$category02."', + category03 = '".$category03."', + datecreated = '".@$date."' + $add_query + WHERE videoid = '".$video."'") or die(mysql_error()); + + $msg = e($LANG['class_vdo_update_msg'],m); + return $msg; + } + + //Function Used To Check Video Exists or No + + function CheckVideoExists($videokey){ + global $LANG; + $query = mysql_query("SELECT * FROM video WHERE videokey ='".$videokey."'"); + if(mysql_num_rows($query)>0){ + return true; + }else{ + return false; + } + } + + //Function Used To Get Video Details VIA video Key + + function GetVideDetails($vkey){ + global $LANG,$Cbucket; + $query = mysql_query("SELECT * FROM video WHERE videokey = '".$vkey."' "); + $data = mysql_fetch_array($query); + return $data; + } + + //Function Used To Update Videos Views + + function UpdateVideoViews($vkey){ + global $LANG,$stats; + $data=$this->GetVideDetails($vkey); + if(!isset($_COOKIE['video_'.$vkey])){ + $views = $data['views'] + 1; + mysql_query("UPDATE video SET views = '".$views."',last_viewed=now() WHERE videokey = '".$vkey."'"); + $stats->UpdateVideoRecord(5); + setcookie('video_'.$vkey,'watched',time()+3600); + } + } + + //Function Used To Get Category Details + + function GetCategory($category,$attr=NULL){ + global $LANG; + $query = mysql_query("SELECT * FROM category WHERE categoryid='".$category."'"); + $data = mysql_fetch_array($query); + if(empty($attr)){ + return $data; + }else{ + return $data[$attr]; + } + } + + //Function Used To Get Duration + + function GetVideoDetail($flv){ + global $LANG; + $query = mysql_query("SELECT * FROM video_detail WHERE flv='".$flv."'"); + $data = mysql_fetch_array($query); + return $data; + } + + //Function Used To Rate Video + + function RateVideo($videoid,$userid,$rating){ + global $LANG; + + $query = mysql_query("select rated_by,rating,voter_ids from video where videoid='".$videoid."'"); + $data = mysql_fetch_array($query); + $voter_id = $data['voter_ids']; + + $niddle = "|"; + $niddle .= $userid; + $niddle .= "|"; + $flag = strstr($voter_id, $niddle); + + if(empty($flag)){ + if ($voter_id == "") + { + $voter_id .= "|"; + } + $voter_id .= $userid; + $voter_id .= "|"; + $t = $data['rated_by'] * $data['rating']; + $newrby = ($data['rated_by'] + 1); + $newrate = ($t + $rating) / $newrby; + mysql_query("UPDATE video set + rated_by='".$newrby."', + rating='".$newrate."', + voter_ids='".$voter_id."' + WHERE videoid='".$videoid."'"); + $details=$this->GetVideoDetails($videoid); + + $msg = round(($details['rating']/2)*20,2); + }else{ + $msg = "already_voted"; + } + return $msg; + } + + //Function Used To Add Comment + + function AddComment($videoid,$comment,$replyto=0){ + global $row,$LANG,$stats; + if($row['user_comment_opt1'] == 'yes') + { + if(empty($_SESSION['username'])){ + $msg[] = e($LANG['class_comment_err']); + }else{ + if(empty($comment)){ + $msg[] = e($LANG['class_comment_err1']); + } + } + if(empty($msg)){ + mysql_query("INSERT into video_comments(comment,username,videoid,date_added,reply_to,scorer_ids)VALUES('".$comment."','".$_SESSION['username']."','".$videoid."',now(),'".$replyto."','|".$_SESSION['userid']."|')"); + mysql_query("UPDATE video SET comments_count=comments_count+1 WHERE videoid = '".$videoid."'") or die(mysql_error()); + $msg[] = e($LANG['class_comment_msg'],m); + $stats->UpdateVideoRecord(3); + } + } + else + { + $msg[] = "Comments Disabled"; + } + return $msg; + } + + + + /** + * Function used to delete comments + * @param CID + */ + function delete_comment($cid,$type='v',$is_reply=FALSE) + { + global $db,$userquery,$LANG; + //first get comment details + + $cdetails = $this->get_comment($cid); + + switch($type) + { + case 'v': + $own_id = $this->get_vid_owner($cdetails['type_id']); + break; + + case 'c'; + $own_id = $this->get_vid_owner($cdetails['type_id']); + break; + } + + + $uid = user_id(); + if( $uid == $cdetails['userid'] + || $uid==$own_id + || $userquery->permission['mod_access'] == 'yes' + || $is_reply==TRUE) + { + $replies = $this->get_comments($cdetails['type_id'],$type,FALSE,$cid,TRUE); + if(count($replies)>0 && is_array($replies)) + { + foreach($replies as $reply) + { + $this->delete_comment($reply['comment_id'],$type,TRUE); + } + } + $db->Execute("DELETE FROM comments WHERE comment_id='$cid'"); + e($LANG['usr_cmt_del_msg'],m); + }else{ + e($LANG['no_comment_del_perm']); + } + } + + + //function used to delete comment + function DeleteComment($id,$videoid){ + global $LANG,$stats; + mysql_query("DELETE FROM video_comments WHERE comment_id = '".$id."' OR reply_to='".$id."'"); + mysql_query("UPDATE video SET comments_count=comments_count-1 WHERE videoid = '".$videoid."'") or die(mysql_error()); + $stats->UpdateVideoRecord(4); + } + //Function Used To Rate Comments + function RateComment($rate,$commentid){ + global $LANG; + if(!empty($_SESSION['username']) ){ + $query = mysql_query("select score,scorer_ids from video_comments where comment_id='".$commentid."'"); + $data = mysql_fetch_array($query); + $voter_id = $data['scorer_ids']; + $userid = $_SESSION['userid']; + $niddle = "|"; + $niddle .= $userid; + $niddle .= "|"; + $flag = strstr($voter_id, $niddle); + if(empty($flag)){ + if ($voter_id == "") + { + $voter_id .= "|"; + } + $voter_id .= $userid; + $voter_id .= "|"; + $newscore = $rate+$data['score']; + mysql_query("UPDATE video_comments SET score='".$newscore."' , scorer_ids='".$voter_id."' WHERE comment_id ='".$commentid."'"); + }else{ + $msg = e($LANG['class_comment_err7']); + } + }else{ + $msg = e($LANG['class_comment_err6']); + } + return $msg; + } + + //Function Used To Add Video To Favourites + function AddToFavourite($userid,$videoid){ + global $LANG,$stats; + $query = mysql_query("SELECT * FROM video_favourites WHERE userid='".$userid."' AND videoid='".$videoid."'"); + if(mysql_num_rows($query)>0){ + $msg = e($LANG['class_vdo_fav_err']); + }else{ + if($userid !=0){ + mysql_query("INSERT INTO video_favourites(videoid,userid)VALUES('".$videoid."','".$userid."')"); + $msg = e($LANG['class_vdo_fav_msg'],m); + $stats->UpdateVideoRecord(6); + } + } + return $msg; + } + + //Function Used To Flagg Video + function FlagAsInappropriate($username,$videoid){ + global $LANG; + $query = mysql_query("SELECT * FROM flagged_videos WHERE username='".$username."' AND videoid='".$videoid."'"); + if(mysql_num_rows($query)>0){ + $msg = e($LANG['class_vdo_flag_err']); + }else{ + mysql_query("INSERT INTO flagged_videos(videoid,username)VALUES('".$videoid."','".$username."')"); + $msg = e($LANG['class_vdo_flag_msg'],m); + } + return $msg; + } + + //Function Delete Flag + function DeleteFlag($videoid){ + global $LANG; + mysql_query("DELETE FROM flagged_videos where videoid='".$videoid."'"); + return e($LANG['class_vdo_flag_rm'],m); + } + + //Function Used To Share Videos + function ShareVideo($username,$videoid,$message,$emails){ + global $LANG; + $userquery = new userquery(); + $user_data = $userquery->GetUserData_username($username); + $video_data = $this->GetVideoDetails($videoid); + $t__o = $emails; + $from = $user_data['email']; + $title = TITLE; + $baseurl = BASEURL; + $videotitle = $video_data['title']; + $videodes = $video_data['description']; + $videokey = $video_data['videokey']; + $videothumb = ''; + $user_data = ""; + $video_data = ""; + require_once(BASEDIR.'/includes/email_templates/share_video.template.php'); + require_once(BASEDIR.'/includes/email_templates/share_video.header.php'); + send_email($from,$t__o,$subj,$body); + + } + + //Function Used To Send Message + function SendMessage($to,$from,$subj,$message,$video,$reply_to=0,$redirect=NULL){ + global $LANG; + if(empty($to)){ + $msg = e($LANG['class_send_msg_err']); + }else{ + $userquery = new userquery(); + $user_data = $userquery->GetUserData_username($to); + if(empty($user_data['userid'])){ + $msg = e($LANG['class_invalid_user'],m); + } + } + if(empty($subj)){ + $msg = e($LANG['class_subj_err']); + } + if(empty($message)){ + $msg = e($LANG['class_msg_err']); + } + if(empty($msg)){ + if(!mysql_query("INSERT INTO messages (inbox_user,outbox_user,message,attachment,subject,reply_to,reciever,sender)VALUES('".$to."','".$from."','".$message."','".$video."','".$subj."','".$reply_to."','".$to."','".$from."')"))die(mysql_error()); + + //Sending Email + $users = new userquery(); + $users = $users->GetUserData_username($to); + if($users['msg_notify'] == 'yes'){ + $email = $users['email']; + $from_email = TITLE."<".SUPPORT_EMAIL.">"; + $subject = $from." ".$LANG['class_sent_you_msg']; + $messg = $from." ".$LANG['class_sent_prvt_msg']." ".TITLE."
    +".$LANG['class_click_inbox']."
    +".$LANG['class_click_login']."
    +====================================
    +".TITLE." ".$LANG['class_email_notify']; + send_email($from_email,$email,$subject,$messg); + } + if($redirect==1){ + redirect_to(BASEURL.compose_msg_link.'?msg='.$LANG['class_msg_has_sent_to'].$to); + } + } + + return $msg; + } + + //Functon Used To Fetch Message From MESSEGES Table + + function GetMsg($msgid,$user){ + global $LANG; + $query = mysql_query("SELECT * FROM messages WHERE message_id='".$msgid."' AND inbox_user='".$user."'"); + $data = mysql_fetch_array($query); + return $data; + } + + //Functon Used To Fetch Message From MESSEGES Table + + function GetMsgSent($msgid,$user){ + global $LANG; + $query = mysql_query("SELECT * FROM messages WHERE message_id='".$msgid."' AND outbox_user='".$user."'"); + $data = mysql_fetch_array($query); + return $data; + } + + //Function Used To Delete Message + + function DeleteMessage($msgid,$user,$box){ + global $LANG; + $user_data = $this->GetMsg($msgid,$user); + if(empty($user_data['subject'])|| $box=='outbox'){ + $user_data = $this->GetMsgSent($msgid,$user); + } + if(!empty($user_data['subject'])){ + if($box == 'inbox'){ + if(empty($user_data['outbox_user'])){ + mysql_query("DELETE FROM messages WHERE message_id='".$msgid."'"); + }else{ + mysql_query("UPDATE messages SET inbox_user='' WHERE message_id='".$msgid."'"); + } + $msg = e($LANG['class_inbox_del_msg'],m); + }else{ + if(empty($user_data['inbox_user'])){ + mysql_query("DELETE FROM messages WHERE message_id='".$msgid."'"); + }else{ + mysql_query("UPDATE messages SET outbox_user='' WHERE message_id='".$msgid."'"); + } + $msg = e($LANG['class_sent_del_msg'],m); + } + + }else{ + $msg = e($LANG['class_msg_exist_err']); + } + return $msg; + } + + //Function Used to Get Subscriber List + + function GetSubscribers($user){ + global $LANG; + $query = mysql_query("SELECT * FROM subscriptions WHERE subscribed_to ='".$user."'"); + $data = mysql_num_rows($query); + return $data; + } + + function GetSubscriptions($user){ + global $LANG; + $query = mysql_query("SELECT * FROM subscriptions WHERE subscribed_user ='".$user."'"); + $data = mysql_num_rows($query); + return $data; + } + + //Function Used To Get Number Of Favourite Videos of user + + function GetTotalFavourites($username){ + global $LANG; + $query = mysql_query("SELECT * FROM video_favourites WHERE userid = '".$username."'"); + return mysql_num_rows($query); + } + + //Function Used To Get Numbe Of Comments on a Channel + + function GetTotalChannelComments($username){ + global $LANG; + $query = mysql_query("SELECT * FROM channel_comments WHERE channel_user = '".$username."'"); + return mysql_num_rows($query); + } + + //Function Used To Get Total number of videos watched by user uploaded by user + function GetUploadedWatched($username){ + global $LANG; + $query = mysql_query("SELECT * FROM video WHERE username='".$username."'"); + $total_views = 0; + while($data=mysql_fetch_array($query)){ + $total_views = $total_views + $data['views']; + } + return $total_views; + } + + //Function Used To Get Total number of Groups Create By + function GetUserCreateGroups($username){ + global $LANG; + $query = mysql_query("SELECT * FROM groups WHERE username='".$username."'"); + return mysql_num_rows($query);; + } + + //Function Used To Get Total number + function GetUserJoinGroups($username){ + global $LANG; + $query = mysql_query("SELECT * FROM group_members WHERE username='".$username."'"); + return mysql_num_rows($query); + } + + //Delete Video 2 + function DeleteUserVideo($videoid,$user){ + global $LANG; + $query = mysql_query("SELECT * FROM video WHERE videoid='".$videoid."' AND username='".$user."'"); + if(mysql_num_rows($query)>0){ + $this->DeleteVideo($videoid); + $this->DeleteVideoFiles($videoid); + mysql_query("DELETE FROM video WHERE videoid='".$videoid ."'"); + $msg = e($LANG['class_vdo_del_msg'],m); + }else{ + $msg = e($LANG['class_vdo_del_err']); + } + //Updating Users Number Of Videos Added By User + $videos_query = mysql_query("SELECT * FROM video WHERE username='".$user."'"); + $videoscount = mysql_num_rows($videos_query); + $updatequery = "UPDATE users SET total_videos='".$videoscount."' WHERE username = '".$user."'"; + return $msg; + } + + //Function Used To Get Total Videos + function GetTotalVideos($user){ + global $LANG; + $query=mysql_query("SELECT * FROM video WHERE username='".$user."'"); + return mysql_num_rows($query); + } + + //Function Used To Unsubscribe To User + function UnSubscribe($subid,$user){ + global $LANG; + $query=mysql_query("SELECT * FROM subscriptions WHERE subscription_id='".$subid."' AND subscribed_user='".$user."' "); + if(mysql_num_rows($query)>0){ + global $LANG; + mysql_query("DELETE FROM subscriptions WHERE subscription_id='".$subid."'"); + $msg = e($LANG['class_unsub_msg'],m); + }else{ + $msg = e($LANG['class_sub_exist_err']); + } + return $msg; + } + + //Function Used To Remove From Favourites + function RemoveFavourite($favid,$userid=NULL,$method=1){ + global $LANG,$stats;; + if($method == 1){ + $query = mysql_query("SELECT * FROM video_favourites WHERE fav_id='".$favid."' AND userid='".$userid."'"); + if(mysql_num_rows($query)>0){ + mysql_query("DELETE FROM video_favourites WHERE fav_id='".$favid."'"); + $msg = e($LANG['class_vdo_rm_fav_msg'],m); + $stats->UpdateVideoRecord(7); + }else{ + $msg = e($LANG['class_vdo_fav_err1']); + } + }else{ + mysql_query("DELETE FROM video_favourites WHERE videoid='".$favid."'"); + $stats->UpdateVideoRecord(7); + } + return @$msg; + } + + //Function Used To Remove Contact + function RemoveUser($contactid,$user){ + global $LANG; + $query=mysql_query("SELECT * FROM contacts WHERE contactid='".$contactid."' AND username ='".$user."'"); + if(mysql_num_rows($query)>0){ + mysql_query("DELETE from contacts WHERE contactid='".$contactid."'"); + $msg = e($LANG['class_cont_del_msg'],m); + + }else{ + $msg = e($LANG['class_cot_err']); + } + return $msg; + + } + + //Function Used To Varify Syntax + function isValidSyntax($syntax){ + global $LANG; + $pattern = "^^[_a-z0-9-]+$"; + if (eregi($pattern, $syntax)){ + return true; + }else { + return false; + } + } + + # THIS WAS AN OLD AD SYSTEM + + /*//Function Used Ti add Advertisement + + function AddAd(){ + $type = mysql_clean($_POST['type']); + $name = mysql_clean($_POST['name']); + $code = $_POST['code']; + $syntax = mysql_clean($_POST['syntax']); + + if(empty($name)){ + $msg = e($LANG['class_vdo_ep_add_msg']); + } + if(empty($code)){ + $msg = e($lANG['class_vdo_ep_err']); + } + $query = mysql_query("SELECT * FROM advertisement WHERE ad_syntax = '".$syntax."'"); + if(mysql_num_rows($query)>0){ + $msg = "This Syntax Already Exists, Please Enter Different Syntax "; + } + if(empty($syntax)){ + $msg = "Please Enter Syntax For Advertisement"; + }else{ + if(!$this->isValidSyntax($syntax)){ + $msg = "Syntax Can Only Contain Underscores, Letters and Numbers"; + } + } + + $query = mysql_query("SELECT * FROM advertisement WHERE ad_name ='".$name."'"); + if(mysql_num_rows($query)>0){ + $msg = "Error : Advertisement With This Name Already Exists"; + } + if(empty($msg)){ + mysql_query("INSERT INTO advertisement (ad_type,ad_name,ad_syntax,ad_code)VALUES('".$type."','".$name."','".$syntax."','".$code."')"); + $msg = "Advertisment Has Been Added"; + } + return $msg; + } + + //Function Used To Change Ad Status + + function ChangeAdStatus($status,$id){ + if($status !==0 && $status !==1){ + $status = 0; + } + $status; + mysql_query("UPDATE advertisement SET ad_status = '".$status."' WHERE ad_id ='".$id."' "); + if($status == '0'){ + $show_status = "Deactivated"; + }else{ + $show_status = "Activated"; + } + $msg = "Ad Has Been ".$show_status; + return $msg; + } + + //Function Used To Edit Advertisment + + function EditAd($id){ + $type = mysql_clean($_POST['type']); + $name = mysql_clean($_POST['name']); + $code = $_POST['code']; + $syntax = mysql_clean($_POST['syntax']); + if(empty($name)){ + $msg = "Please Enter Name For The Advertisment"; + } + if(empty($code)){ + $msg = "Please Enter Code For Advertisement"; + + } + $query = mysql_query("SELECT * FROM advertisement WHERE ad_id <> '".$id."' AND ad_syntax = '".$syntax."'"); + if(mysql_num_rows($query)>0){ + $msg = "This Syntax Already Exists, Please Enter Different Syntax "; + } + if(empty($syntax)){ + $msg = "Please Enter Syntax For Advertisement"; + }else{ + if(!$this->isValidSyntax($syntax)){ + $msg = "Syntax Can Only Contain Underscores, Letters and Numbers"; + } + } + if(empty($msg)){ + mysql_query("UPDATE advertisement SET + ad_type = '".$type."', + ad_name = '".$name."', + ad_syntax = '".$syntax."', + ad_code = '".$code."' + Where ad_id = '".$id."'"); + $msg = "Advertisment Has Been Updated"; + } + return $msg; + } + + //Function Used To delete AD + + function DeleteAd($id){ + $query = mysql_query("SELECT * FROM advertisement WHERE ad_id ='".$id."'"); + if(mysql_num_rows($query)!=1){ + $msg = "Error : Advertisement Doesnt Exist "; + }else{ + mysql_query("DELETE FROM advertisement WHERE ad_id='".$id."'"); + $msg = "Advertisement Has Been Deleted"; + } + return $msg; + }*/ + + //Function Used To Add IN Editor Pick + function AddToEditorPick($video){ + global $LANG; + $data = $this->GetVideoDetails($video); + $videokey = $data['videokey']; + $query1 = mysql_query("SELECT * FROM editors_picks ORDER BY sort ASC"); + if(mysql_num_rows($query1)<10){ + $query = mysql_query("SELECT * FROM editors_picks WHERE videokey = '".$videokey."'"); + if(mysql_num_rows($query)==0){ + $data = mysql_fetch_assoc($query1); + $sort = $data['sort']; + $sort = $sort + 1; + mysql_query("INSERT INTO editors_picks (videokey,sort)VALUES('".$videokey."','".$sort."')"); + $msg = e($LANG['class_vdo_ep_add_msg'],m); + }else{ + $msg = e($LANG['class_vdo_ep_err']); + } + }else{ + $msg = e($LANG['class_vdo_ep_err1']); + } + return $msg; + } + + //Function Used To Delete Video From Editors Pick + + function DeleteEditorPick($id){ + global $LANG; + $query = mysql_query("SELECT * FROM editors_picks WHERE pick_id='".$id."'"); + if(mysql_num_rows($query)!=0){ + $query = mysql_query("DELETE FROM editors_picks WHERE pick_id='".$id."'"); + $msg =e($LANG['class_vdo_ep_msg'],m); + }else{ + $msg = e($LANG['class_vdo_exist_err']); + } + return $msg; + } + + //Function Used To Change Website Logo Via Admin Panel + function ChangeLogo($logo_name,$dir,$allowed_ext){ + global $LANG; + $file = $_FILES['image_file']['name']; + $ext = substr($file, strrpos($file, '.') + 1); + switch($allowed_ext){ + case 1; + $ext1 = 'gif'; + $ext2 = 'GIF'; + $msg = e($LANG['class_img_gif_err']); + break; + + case 2; + $ext1 = 'png'; + $ext2 = 'PNG'; + $msg = e($LANG['class_img_png_err']); + break; + + case 3; + $ext1 = 'jpg'; + $ext2 = 'JPG'; + $msg = e($LANG['class_img_jpg_err']); + break; + + default: + $ext1 = 'gif'; + $ext2 = 'GIF'; + $msg = e($LANG['class_img_gif_err']); + + } + + if($ext !=$ext1 && $ext !=$ext2){ + global $LANG; + + }else{ + if(!empty($file)){ + $image = new ResizeImage(); + if($image->ValidateImage($_FILES['image_file']['tmp_name'],$ext)){ + $newfilename = $logo_name; + $uploaded_thumb = $dir.'/'.$newfilename; + copy($_FILES['image_file']['tmp_name'],$uploaded_thumb); + if($ext1 !='png'){ + list($width, $height) = getimagesize($uploaded_thumb); + $image->CreateThumb($uploaded_thumb,$uploaded_thumb,$width,$ext); + } + $msg = e($LANG['class_logo_msg'],m); + }else{ + $msg = e($LANG['class_error_occured']); + } + } + + } + return $msg; + } + + //FUNCTION USED TO MOVE VIDE UP IN EDITORS PICK + function MovePickUp($id){ + global $LANG; + $query = mysql_query("SELECT * FROM editors_picks WHERE pick_id ='".$id."'"); + $data = mysql_fetch_assoc($query); + $sort = $data['sort'] - 2; + if(!mysql_query("UPDATE editors_picks SET sort='".$sort."' WHERE pick_id ='".$data['pick_id']."'"))die(mysql_error()); + return e($LANG['editor_pic_up'],m); + + } + //FUNCTION USED TO MOVE VIDE UP IN EDITORS PICK + function MovePickDown($id){ + global $LANG; + $query = mysql_query("SELECT * FROM editors_picks WHERE pick_id ='".$id."'"); + $data = mysql_fetch_assoc($query); + $sort = $data['sort'] + 2; + if(!mysql_query("UPDATE editors_picks SET sort='".$sort."' WHERE pick_id ='".$data['pick_id']."'"))die(mysql_error()); + return e($LANG['editor_pic_up'],m); + + } + + //FUNCTION USED TO CHECK , SELECTED TEMPLATE IS CORRECT OR NOT + function IsTemplate($tempdir) + { + $query = mysql_query("SELECT * FROM template WHERE template_dir = '".$tempdir."'"); + if(mysql_num_rows($query)>0) + return true; + else + return false; + } + + //DEACTIVATING FONT + function PluginActive($plugin_id_code,$active='yes'){ + mysql_query("UPDATE plugins SET plugin_active='".$active."' WHERE plugin_id_code='".$plugin_id_code."'"); + } + + //UPDATING PLUGIN LICENSE + function UpdatePluginLicense($plugin_id_code){ + $code = mysql_clean($_POST['license_code']); + $key = mysql_clean($_POST['license_key']); + mysql_query("UPDATE plugins SET plugin_license_key='".$key."', + plugin_license_code='".$code."' + WHERE plugin_id_code='".$plugin_id_code."'"); + + } + + /** + * FUNCTION USED TO GET VIDEOS FROM DATABASE + * @param: array of query parameters array() + * featured => '' (yes,no) + * username => '' (TEXT) + * title => '' (TEXT) + * tags => '' (TEXT) + * category => '' (INT) + * limit => '' (OFFSET,LIMIT) + * order=>'' (BY SORT) -- (date_added DESC) + * extra_param=>'' ANYTHING FOR MYSQL QUERY + * @param: boolean + * @param: results type (results,query) + */ + + function getVideoList($param=array(),$global_cond=true,$result='results') + { + global $db; + + $sql = "SELECT * FROM video"; + + //Global Condition For Videos + if($global_cond==true) + $cond = "broadcast='public' AND active='yes' AND status='Successful'"; + //Checking Condition + if(!empty($param['featured'])) + { + $param['featured'] = 'yes' ? 'yes' : 'no'; + $cond .=" AND featured= '".$param['featured']."' "; + } + if(!empty($param['username'])) + { + $username = mysql_clean($param['username']); + $cond .=" AND featured= '".$username."' "; + } + if(!empty($param['category'])) + { + $category = intval($param['category']); + $cond .=" AND (category01= '".$category."' OR category02= '".$category."' OR category03= '".$category."') "; + } + if(!empty($param['tags'])) + { + $tags = mysql_clean($param['tags']); + $cond .=" AND tags LIKE '%".$tags."%' "; + } + if(!empty($param['title'])) + { + $tags = mysql_clean($param['tags']); + $cond .=" AND title LIKE '%".$param['title']."%' "; + } + + //Adding Condition in Query + if(!empty($cond)) + $sql .= " WHERE $cond "; + + //SORTING VIDEOS + if(!empty($param['order'])) + $sort = 'ORDER BY '.$param['order']; + + //Adding Sorting In Query + $sql .= $sort; + + //LIMITING VIDEO LIST + if(empty($param['limit'])) + $limit = " LIMIT ". VLISTPP; + elseif($param['limit']=='nolimit') + $limit = ''; + else + $limit = " LIMIT ".$param['limit']; + + $sql .= $limit; + //Final Executing of Query and Returning Results + if($result=='results') + return $db->Execute($sql); + else + return $sql; + } + + + + + /** + * Function used to send subsribtion message + */ + function send_subscription($subscriber,$from,$video) + { + global $LANG; + //First checking weather $subscriber exists or not + $array = array('%subscriber%','%user%','%website_title%'); + $replace = array($subscriber,$from,TITLE); + + $to = $subscriber; + $subj = str_replace($array,$replace,$LANG['user_subscribe_subject']); + + //Get Subscription Message Template + $msg = get_subscription_template(); + $msg = str_replace($array,$replace,$msg); + $this->SendMessage($to,$from,$subj,$msg,$video,0,0); + } + + + /** + * Function used to add comment + * This is more advance function , + * in this function functions can be applied on comments + */ + function add_comment($comment,$obj_id,$reply_to=NULL,$type='v') + { + global $userquery,$eh,$db; + //Checking maximum comments characters allowed + if(defined("MAX_COMMENT_CHR")) + { + if(strlen($comment) > MAX_COMMENT_CHR) + e(sprintf("'%d' characters allowed for comment",MAX_COMMENT_CHR)); + } + if(empty($comment)) + e("Please enter something for comment"); + + if($type=='video' || $type=='v') + { + if(!$this->video_exists($obj_id)) + e("Video does not exist"); + + //Checking owner of video + if(!USER_COMMENT_OWN) + { + if(userid()==$this->get_vid_owner($obj_id)); + e("You cannot comment on your video"); + } + } + + if(!userid()) + e("You are not logged in"); + + if(empty($eh->error_list)) + { + $db->insert("comments",array + ('type,comment,type_id,userid,date_added,parent_id'), + array + ($type,$comment,$obj_id,userid(),NOW(),$reply_to)); + e("Comment has been added",m); + return $db->insert_id(); + } + } + + + + /** + * Function used to get file details from database + */ + function file_details($file_name) + { + global $db; + $results = $db->select("video_files","*"," src_name='$file_name'"); + if($db->num_rows==0) + return false; + else + { + return $results[0]; + } + } + + + + /** + * Function used to update video and set a thumb as default + * @param VID + * @param THUMB NUM + */ + function set_default_thumb($vid,$thumb) + { + global $db,$LANG; + $num = get_thumb_num($thumb); + $file = THUMBS_DIR.'/'.$thumb; + if(file_exists($file)) + { + $db->update("video",array("default_thumb"),array($num)," videoid='$vid'"); + e($LANG['vid_thumb_changed'],m); + }else{ + e($LANG['vid_thumb_change_err']); + } + } + + + + + /** + * Function used to update video + */ + function update_video() + { + global $eh,$Cbucket,$db,$Upload; + + $Upload->validate_video_upload_form(NULL,TRUE); + + if(empty($eh->error_list)) + { + $required_fields = $Upload->loadRequiredFields($array); + $location_fields = $Upload->loadLocationFields($array); + $option_fields = $Upload->loadOptionFields($array); + + $upload_fields = array_merge($required_fields,$location_fields,$option_fields); + + //Adding Custom Upload Fields + if(count($Upload->custom_upload_fields)>0) + $upload_fields = array_merge($upload_fields,$Upload->custom_upload_fields); + //Adding Custom Form Fields + if(count($Upload->custom_form_fields)>0) + $upload_fields = array_merge($upload_fields,$Upload->custom_form_fields); + + $array = $_POST; + $vid = $array['videoid']; + + if(is_array($_FILES)) + $array = array_merge($array,$_FILES); + + foreach($upload_fields as $field) + { + $name = formObj::rmBrackets($field['name']); + $val = $array[$name]; + + if($field['use_func_val']) + $val = $field['validate_function']($val); + + + if(!empty($field['db_field'])) + $query_field[] = $field['db_field']; + + if(is_array($val)) + { + $new_val = ''; + foreach($val as $v) + { + $new_val .= "#".$v."# "; + } + $val = $new_val; + } + if(!$field['clean_func'] || (!function_exists($field['clean_func']) && !is_array($field['clean_func']))) + $val = mysql_clean($val); + else + $val = apply_func($field['clean_func'],$val); + + if(!empty($field['db_field'])) + $query_val[] = $val; + + } + + #$query = "INSERT INTO video ("; + $total_fields = count($query_field); + + //Adding Fields to query + $i = 0; + + /*for($key=0;$key<$total_fields;$key++) + { + $query .= query_field[$key]." = '".$query_val[$key]."'" ; + if($key<$total_fields-1) + $query .= ','; + }*/ + + + if(!userid()) + { + e("You are not logged in"); + }elseif(!$this->video_exists($vid)){ + e("Video deos not exist"); + }else{ + $db->update('video',$query_field,$query_val," videoid='$vid'"); + e("Video details have been updated",m); + } + + } + } + + + + /** + * Function used to get categorie details + */ + function get_category($id) + { + global $db; + $results = $db->select("category","*"," categoryid='$id'"); + return $results[0]; + } + + + /** + * Function used to get comment from its ID + * @param ID + */ + function get_comment($id) + { + global $db; + $result = $db->select("comments","*"," comment_id='$id'"); + if($db->num_rows>0) + { + return $result[0]; + }else{ + return false; + } + } + + /** + * Function used to get from database + * @param TYPE_ID + * @param TYPE + * @param COUNT_ONLY Boolean + * @param PARENT_ID + * @param GET_REPLYIES_ONLY Boolean + */ + function get_comments($type_id,$type='v',$count_only=FALSE,$parent_id=NULL,$get_reply_only=FALSE) + { + global $db; + $cond = ''; + + #Checking if user wants to get replies of comment + if($parent_id!=NULL && $get_reply_only) + { + $cond .= " AND parent_id='$parent_id'"; + } + + $result = $db->select("comments","*"," type='$type' AND type_id='$type_id' $cond"); + + if($db->num_rows > 0) + { + if($count_only) + return $db->num_rows; + else + return $result; + }else{ + return ''; + } + + } + + + /** + * Function used to get video owner + */ + function get_vid_owner($vid) + { + global $db; + $results = $db->select("video","userid"," videoid='$vid'"); + return $results[0]; + } + +} +?> \ No newline at end of file diff --git a/upload/includes/classes/pages.class.php b/upload/includes/classes/pages.class.php new file mode 100644 index 00000000..e9ac25bc --- /dev/null +++ b/upload/includes/classes/pages.class.php @@ -0,0 +1,314 @@ +GetServerUrl(); + $scriptPath = NULL; + if ( isset($_SERVER['SCRIPT_NAME']) ) { + $scriptPath = $_SERVER['SCRIPT_NAME']; + $scriptPath = ( $scriptPath == '/' ) ? '' : dirname($scriptPath); + } + + $baseURL = $serverURL . $scriptPath; + $baseURL = preg_replace('/:\/\/www\./','',$baseURL); + return $baseURL; + } + + function GetCurrentUrl() + { + $serverURL = $this->GetServerUrl(); + $requestURL = $_SERVER['REQUEST_URI']; + + return $serverURL . $requestURL; + } + + //This Function Set The PageDirect + function page_redir(){ + setcookie("pageredir",clean($this->GetCurrentUrl()),time()+7200,'/'); + Assign('pageredir',@$_COOKIE['pageredir']); + } + + //This Funtion is use to Show Admin Panels Pages + + function show_admin_page($page){ + $pages = array( + 'main' => 'main.php', + 'server_check' => 'verifier.php', + 'members_showall' => 'members.php?view=showall', + 'members_inactive' => 'members.php?view=inactive', + 'members_active' => 'members.php?view=active', + 'members_addmember' => 'members.php?view=addmember', + 'members_search' => 'members.php?view=search' + ); + return @$pages[$page]; + } + + + //Redirects page to without www. + function redirectOrig() + { + $curpage = $this->GetCurrentUrl(); + $newPage = preg_replace('/:\/\/www\./','',$curpage); + if($curpage !=$newPage) + redirect_to($newPage); + } + + function createUrl($url,$params_array,$remove_param=false,$urlencode=false) + { + //Cleaning Url and Create Existing Params as Array + $list1 = explode('&',$url); + $semi_clean_url = preg_replace('/&(.*)/','',$url); + $list2= explode('?',$semi_clean_url); + $clean_url = preg_replace('/\?(.*)/','',$semi_clean_url); + $lists=array_merge($list1,$list2); + foreach($lists as $list) + { + preg_match('/http:\/\//',$list,$matches); + if(empty($matches[0])) + { + if($remove_param!=true) + { + list($param,$value) = explode('=',$list); + if(empty($params_array[$param])) + $params_array[$param] = $value; + else + $params_array[$param] = $params_array[$param]; + } + } + } + $count = 0; + $total = count($params_array); + if($total>0 && !empty($params_array)) + { + foreach($params_array as $param => $value) + { + $count++; + if($count==1) + $url_param .= '?'; + $url_param .=$param.'='.$value; + if($count != $total) + $url_param .='&'; + } + } + + $finalUrl = $clean_url.$url_param ; + if($urlencode ==true) + $finalUrl = urlencode($finalUrl); + return $finalUrl; + } + + //This Fucntion is used to Redirect to respective URL + + function redirect($url){ + echo ''; + } + + /** + * Function used to create link + */ + function create_link($page,$link,$extra_params=NULL,$tag,$return_param=false) + { + $page_pattern = '#page#'; + $param_pattern = '#params#'; + $page_url_param = $this->url_page_var; + $page_link_pattern = $page_url_param.'='.$page_pattern; + + preg_match('/\?/',$link,$matches); + + if(!empty($matches[0])) + { + $page_link = '&'.$page_link_pattern; + }else{ + $page_link = '?'.$page_link_pattern; + } + + $link = $link.$page_link; + $params = 'href="'.$link.'"'; + $params .= ' '.$extra_params; + + $final_link = preg_replace(array("/$page_pattern/i","/$param_pattern/i"),array($page,$params),$tag); + $final_link = preg_replace(array("/$page_pattern/i","/$param_pattern/i"),array($page,$params),$final_link); + + if($return_param) + { + return preg_replace("/$page_pattern/i",$page,$params); + } + + return $final_link; + } + + /** + * Function used to create pagination + * @param : total number of pags + * @param : current page + * @param : extra paraments in the tag ie #page#') + { + + $total_pages = $total; + $pagination_start = 10; + $display_page = 7; + $this->selected = $selected = $page; + $hellip = '…'; + $first_hellip = ''; + $second_hellip = ''; + + $start = ''; + $mid = ''; + $end = ''; + + $start_last = ''; + $end_first = ''; + + $mid_first = ''; + $mid_last = ''; + + $differ = round(($display_page/2)+.49,0)-1; + + if($pagination_start < $total_pages) + { + //Starting First + for($i=1;$i<=$display_page;$i++) + { + if($selected == $i) + { + $start .= ''.$i.''; + }else + $start .= $this->create_link($i,$link,$extra_params,$tag); + $start_last = $i; + } + + + //Starring Last + for($i=$total_pages-$display_page;$i<=$total_pages;$i++) + { + if($end_first=='') + $end_first = $i; + + if($selected == $i) + { + $end .= ''.$i.''; + }else + $end .= $this->create_link($i,$link,$extra_params,$tag); + } + + //Starting mid + for($i=$selected-$differ;$i<=$selected+$differ;$i++) + { + if($mid_first=='') + $mid_first = $i; + + if($i>$start_last && $i<$end_first) + { + if($selected == $i) + { + $mid .= ''.$i.''; + }else + $mid .= $this->create_link($i,$link,$extra_params,$tag); + } + + $mid_last = $i; + } + + + if($start_last < $mid_first) + $first_hellip = $hellip; + if($end_first > $mid_last) + $second_hellip = $hellip; + + //Previous Page + if($selected-1 > 1) + $this->pre_link = $this->create_link($selected-1,$link,$extra_params,$tag,true); + //Next Page + if($selected+1 < $total) + $this->next_link = $this->create_link($selected+1,$link,$extra_params,$tag,true); + //First Page + if($selected!=1) + $this->first_link = $this->create_link(1,$link,$extra_params,$tag,true); + //First Page + if($selected!=$total) + $this->last_link = $this->create_link($total,$link,$extra_params,$tag,true); + + return $start.$first_hellip.$mid.$second_hellip.$end; + }else{ + $pagination_smart = ''; + for($i=1;$i<=$total_pages;$i++) + { + if($i == $selected) + $pagination_smart .= ''.$i.''; + else + $pagination_smart .=$this->create_link($i,$link,$extra_params,$tag); + } + + return $pagination_smart; + } + } + + + /** + * Function used to create pagination and assign values that can bee used in template + */ + function paginate($total,$page,$link,$extra_params=NULL,$tag='#page#') + { + $this->pagination = $this->pagination($total,$page,$link,$extra_params,$tag); + //Assigning Varaiable that can be used in templates + assign('pagination',$this->pagination); + + assign('next_link',$this->next_link); + assign('pre_link',$this->pre_link); + + assign('first_link',$this->first_link); + assign('last_link',$this->last_link); + } + +} +?> \ No newline at end of file diff --git a/upload/includes/classes/plugin.class.php b/upload/includes/classes/plugin.class.php new file mode 100644 index 00000000..b2e7ad0e --- /dev/null +++ b/upload/includes/classes/plugin.class.php @@ -0,0 +1,307 @@ +getPluginDetails($plugin_file); + if(!empty($plugin_details['name'])) + $plugins_array[]= $plugin_details; + } + + return $plugins_array; + } + + function getPluginList() + { + return $this->getPlugins(); + } + + + /** + * Function used to get new plugins, that are not installed yet + */ + function getNewPlugins() + { + //first get list of all plugins + $plugin_list = $this->getPluginList(); + + //Now Checking if plugin is installed or not + if(is_array($plugin_list)) + { + foreach($plugin_list as $plugin) + { + if(!$this->is_installed($plugin['file'])) + $plug_array[] = $plugin; + } + return $plug_array; + } + } + + + /** + * Function used to get new plugins, that are not installed yet + */ + function getInstalledPlugins() + { + //first get list of all plugins + $plugin_list = $this->getPluginList(); + //Now Checking if plugin is installed or not + foreach($plugin_list as $plugin) + { + if($this->is_installed($plugin['file'])) + { + $plugin = array_merge($plugin,$this->getPlugin($plugin['file'])); + $plug_array[] = $plugin; + } + } + return $plug_array; + } + + /** + * Function used to check weather plugin is instlled or not + * @param : $plugin_code STRING + */ + function is_installed($file,$v=NULL) + { + global $db; + + if($v) + $version_check = "AND plugin_version='$v'"; + $query = "SELECT plugin_file FROM plugins WHERE $version_check plugin_file='".$file."'"; + $details = $db->Execute($query); + if($details->recordcount()>0) + return true; + else + return false; + } + + + /** + * get plugin details + * @param : $file STRING + */ + function get_plugin_details($plug_file) + { + $file = PLUG_DIR.'/'.$plug_file; + if(file_exists($file) && is_file($file)) + { + // We don't need to write to the file, so just open for reading. + $fp = fopen($file, 'r'); + // Pull only the first 8kiB of the file in. + $plugin_data = fread( $fp, 8192 ); + // PHP will close file handle, but we are good citizens. + fclose($fp); + preg_match( '/Plugin Name:(.*)$/mi', $plugin_data, $name ); + preg_match( '/Website:(.*)$/mi', $plugin_data, $website ); + preg_match( '/Version:(.*)/mi', $plugin_data, $version ); + preg_match( '/Description:(.*)$/mi', $plugin_data, $description ); + preg_match( '/Author:(.*)$/mi', $plugin_data, $author ); + preg_match( '/Author Website:(.*)$/mi', $plugin_data, $author_page ); + preg_match( '/ClpBucket Version:(.*)$/mi', $plugin_data, $cbversion ); + preg_match( '/Plugint Type:(.*)$/mi', $plugin_data, $type ); + + $details_array = array + ( + 'name', + 'website', + 'version', + 'description', + 'author', + 'cbversion', + 'code', + 'type', + + ); + foreach ($details_array as $detail) + { + $plugin_array[$detail]=${$detail}[1]; + } + $plugin_array['file'] = $plug_file; + $plugin_array['code'] = preg_replace('/\s/', '', $code[1]); + + return $plugin_array; + }else{ + return false; + } + } + function getPluginDetails($file) + { + return $this->get_plugin_details($file); + } + + + + /** + * Function used to get plugin details from database + * @param : plugin_id_code STRING + */ + function getPlugin($file) + { + $query = mysql_query("SELECT * FROM plugins WHERE plugin_file ='".$file."'"); + return mysql_fetch_assoc($query); + } + + + /** + * ClipBucket Internal Plugin Installer + * @param:plugin + */ + function installPlugin($pluginFile) + { + global $db,$LANG,$Cbucket; + $plug_details = $this->get_plugin_details($pluginFile); + if(!$plug_details) + $msg = e($LANG['plugin_no_file_err']); + if(empty($plug_details['name'])) + $msg = e($LANG['plugin_file_detail_err']); + if($this->is_installed($pluginFile)) + $msg = e($LANG['plugin_installed_err']); + + if(empty($msg)) + { + + $plug_details = $this->getPluginDetails(PLUG_DIR.'/'.$pluginFile); + + if(file_exists(PLUG_DIR.'/install_'.$pluginFile)) + require_once(PLUG_DIR.'/install_'.$pluginFile); + + dbInsert + ( + 'plugins', + array( + 'plugin_file', + 'plugin_license_type', + 'plugin_license_key', + 'plugin_license_code', + 'plugin_active', + ), + array( + $pluginFile, + $plugin_details_array['plugin_license_type'], + $plugin_details_array['plugin_license_key'], + $plugin_details_array['plugin_license_code'], + 'yes', + ) + ); + + //Checking For the installation SQL + $msg = e($LANG['plugin_install_msg'],m); + define('NEW_INSTALL',false); + } + return $msg; + } + + /** + * Function used to activate plugin + */ + function pluginActive($plugin_file,$active='yes'){ + global $LANG; + if($this->is_installed($plugin_file)) + { + mysql_query("UPDATE plugins SET plugin_active='".$active."' WHERE plugin_file='".$plugin_file."'"); + $active_msg = $active=='yes' ? 'activated' : 'deactiveted'; + $msg = e("Plugin has been $active_msg",m); + }else{ + $msg = e($LANG['plugin_no_install_err']); + } + return $msg; + } + + /** + * Function used to activate plugin + */ + function uninstallPlugin($file){ + global $LANG; + if($this->is_installed($file)) + { + mysql_query("DELETE FROM plugins WHERE plugin_file='".$file."' "); + if(file_exists(PLUG_DIR.'/uninstall_'.$file)) + require_once(PLUG_DIR.'/uninstall_'.$file); + $msg = e("Plugin has been Uninstalled",m); + }else{ + $msg = e($LANG['plugin_no_install_err']); + } + return $msg; + } + + /** + * Function used to add ClipBucket Plugin Menu + */ + function add_admin_menu($headers,$links) + { + //This Function used to createa admin menu + + } + + +} + +?> \ No newline at end of file diff --git a/upload/includes/classes/session.class.php b/upload/includes/classes/session.class.php new file mode 100644 index 00000000..7f529757 --- /dev/null +++ b/upload/includes/classes/session.class.php @@ -0,0 +1,131 @@ + + * http://clip-bucket.com/ + */ + + +class Session +{ + var $tbl = 'sessions'; + var $id= ''; + var $overwrite = false; + /** + * offcourse, its a constructor + */ + function session() + { + $this->id = session_id() ; + } + + /** + * Function used to add session + + + function add_session($user,$name,$value=false) + { + global $db; + if(!$value) + $value = $this->session; + $this->get_user_session($user,$name); + if($db->num_rows>0) + $db->delete($this->tbl,'session_string',$name); + $db->insert($this->tbl,'session_user,session_string,session_value',"$user,$name,$value"); + //Finally Registering session + $this->session_register($name); + $this->session_val($name,$value); + } + */ + + + /** + * Function is used to get session + + function get_user_session($user,$session_name=false) + { + global $db; + if($session_name) + $session_cond = " session_string='".mysql_val($session_name)."'"; + $results = $db->select($this->tbl,'*',$session_cond); + return $results; + } + */ + + + /** + * Function used to get current user session, if any + + function get_current_session($session_string) + { + global $db; + $results = $db->select($this->tbl,'*'," session_string='logged_in' AND session_value='".$this->session."'"); + return $results[0]; + } + */ + + + /** + Functin used to register session + */ + function session_register($name) + { + if($this->overwrite) + $this->session_unregister($name); + session_register($name); + } + + /** + * FUnction used to unregiser session + */ + function session_unregister($name) + { + session_unregister($name); + } + + /** + * Ftunction used to set session value + */ + function session_val($name,$value) + { + $_SESSION[$name] = $value; + } + + /** + * Function used to remove session + */ + function remove_session($user,$name) + { + global $db; + $db->delete('sessions'," session_user,session_string","$user,$name"); + $_SESSION[$name] = ''; + $this->session_unregister($name); + } + + /** + * Function used to set register session and set its value + */ + function set_session($name,$val) + { + $this->session_register($name); + $_SESSION[$name] = $val; + } + function set($name,$val) + { + $this->set_session($name,$val); + } + + /** + * Function used to get session value + * param VARCHAR name + */ + function get_session($name) + { + if(isset($_SESSION[$name])) + return $_SESSION[$name]; + } + //replica + function get($name){ return $this->get_session($name); } +} + +?> \ No newline at end of file diff --git a/upload/includes/classes/signup.class.php b/upload/includes/classes/signup.class.php new file mode 100644 index 00000000..177e6e07 --- /dev/null +++ b/upload/includes/classes/signup.class.php @@ -0,0 +1,430 @@ + array( + 'title'=> $LANG['username'], + 'type'=> "textfield", + 'name'=> "username", + 'id'=> "username", + 'value'=> $username, + 'hint_2'=> $LANG['user_allowed_format'], + ), + 'email' => array( + 'title'=> $LANG['email'], + 'type'=> "textfield", + 'name'=> "email", + 'id'=> "email", + 'value'=> $email, + ), + 'password' => array( + 'title'=> $LANG['password'], + 'type'=> "password", + 'name'=> "password", + 'id'=> "password", + ), + 'cpassword' => array( + 'title'=> $LANG['user_confirm_pass'], + 'type'=> "password", + 'name'=> "cpassword", + 'id'=> "cpassword", + ), + 'country' => array( + 'title'=> $LANG['country'], + 'type' => 'dropdown', + 'value' => $Cbucket->get_countries(iso2), + 'id' => 'country', + 'name' => 'country', + 'checked'=> $dcountry + ), + 'gender' => array( + 'title' => $LANG['gender'], + 'type' => 'radiobutton', + 'name' => 'gender', + 'id' => 'gender', + 'value' => array('Male'=>$LANG['male'],'Female'=>$LANG['female']), + 'sep'=> ' ', + 'checked'=>'female', + ), + 'dob' => array( + 'title' => $LANG['user_date_of_birth'], + 'type' => 'textfield', + 'name' => 'dob', + 'id' => 'dob', + 'class'=>'date_field', + 'anchor_after' => 'date_picker', + 'value'=> $dob, + ) + ); + + return $user_signup_fields; + } + + + //Creating DOB field + + + //Duplicate User Check + function duplicate_user($name){ + $myquery = new myquery(); + if($myquery->check_user($name)){ + return true; + }else{ + return false; + } + } + + function duplicate_email($name){ + $myquery = new myquery(); + if($myquery->check_email($name)){ + return true; + }else{ + return false; + } + } + + //Validate Email + + function isValidEmail($email){ + $pattern = "^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$"; + if (eregi($pattern, $email)){ + return true; + } + else { + return false; + } + } + + //Validate Username + function isValidUsername($uname){ + return $this->is_username($uname); + } + + /** + * Function used to make username valid + * this function will also check if username is banned or not + * it will also filter the username and also filter its patterns + * as given in administratio panel + */ + function is_username($username) + { + global $Cbucket; + //Our basic pattern for username is + //$pattern = "^^[_a-z0-9-]+$"; + $pattern = "^^[_a-z0-9-]+$"; + //Now we will check if admin wants to change the pattern + if (eregi($pattern, $username)){ + return true; + }else { + return false; + } + + } + + //Validate Admin Member + function Admin_Add_User(){ + global $LANG,$stats; + $uname = mysql_clean($_POST['username']); + $email = mysql_clean($_POST['email']); + $pass = pass_code(mysql_clean($_POST['password'])); + $fname = mysql_clean($_POST['fname']); + $lname = mysql_clean($_POST['lname']); + $gender = mysql_clean($_POST['gender']); + $level = mysql_clean($_POST['level']); + $dob = mysql_clean($_POST['dob']); + $ht = mysql_clean($_POST['hometown']); + $city = mysql_clean($_POST['city']); + $country = $_POST['country']; + $zip = mysql_clean($_POST['zip']); + $active = $_POST['active']; + + if(empty($uname)){ + $msg[] = e($LANG['usr_uname_err']); + } + if($this->duplicate_user($uname)){ + $msg[] = e($LANG['usr_uname_err2']); + } + if(!$this->isValidUsername($uname)){ + $msg[] = e($LANG['usr_uname_err3']); + } + if(empty($_POST['password'])){ + $msg[] = e($LANG['usr_pass_err2']); + } + if(empty($email)){ + $msg[] = e($LANG['usr_email_err1']); + }elseif(!$this->isValidEmail($email)){ + $msg[] = e($LANG['usr_email_err2']); + } + if($this->duplicate_email($email)){ + $msg[] = e($LANG['usr_email_err3']); + } + if(!empty($zip) && !is_numeric($zip)){ + $msg[] = e($LANG['usr_pcode_err']); + } + + if(!$this->is_username($uname)) + $msg[] = 'Username is not valid'; + + $dob = strtotime($dob) ; + if(date("Y",$dob) < 1960 || date("Y",$dob) > date("Y")) + $msg[] = "Please enter valid date of birth"; + + $dob = date('Y-m-d',strtotime($dob)); + + if(empty($msg)){ + if(!mysql_query("INSERT INTO users (username,password,email,first_name,last_name,sex,level,dob,hometown,city,country,zip,usr_status) + VALUES('".$uname."','".$pass."','".$email."','".$fname."','".$lname."','".$gender."','".$level."','".$dob."','".$ht."','".$city."','".$country."','".$zip."','".$active."')")) die(mysql_error()); + $stats->UpdateUserRecord(1); + redirect_to($_SERVER['PHP_SELF'].'?msg='.urlencode($LANG['usr_add_succ_msg'])); + } + + return $msg; + + } + + + //UPDATE USER + function Admin_Edit_User(){ + global $LANG; + $email = mysql_clean($_POST['email']); + $fname = mysql_clean($_POST['fname']); + $lname = mysql_clean($_POST['lname']); + $gender = mysql_clean(@$_POST['gender']); + $level = mysql_clean($_POST['level']); + $ht = mysql_clean($_POST['hometown']); + $city = mysql_clean($_POST['city']); + $country = $_POST['country']; + $zip = mysql_clean($_POST['zip']); + $email_inuse = $_POST['email_inuse']; + + if($_GET['userid'] == 1){ + if($_SESSION['superadmin'] == ''){ + $msg[] = "You Are Not Allowed To Change 'Super Admin' Details"; + } + } + if(empty($email)){ + $msg[] = e($LANG['usr_email_err1']); + }elseif(!$this->isValidEmail($email)){ + $msg[] = e($LANG['usr_email_err2']); + } + if($email !== $email_inuse){ + if($this->duplicate_email($email)){ + $msg[] = e($LANG['usr_email_err3']); + } + } + + if(!empty($zip) && !is_numeric($zip)){ + $msg[] = e($LANG['usr_pcode_err']); + } + + if(!empty($_POST['pwrd'])){ + $pass = pass_code($_POST['pwrd']); + $cpass = pass_code($_POST['cpwrd']); + if($pass != $cpass){ + $msg[] = e($LANG['usr_cpass_err1']); + }else{ + $pass_Query = "password = '".$pass."',"; + } + } + if(empty($msg)){ + if(!mysql_query("UPDATE users Set + email = '".$email."', + $pass_Query + first_name = '".$fname."', + last_name = '".$lname."', + sex = '".$gender."', + level = '".$level."', + hometown = '".$ht."', + city = '".$city."', + country = '".$country."', + zip = '".$zip."' + Where userid = '".$_GET['userid']."'"))die(mysql_error()); + redirect_to($_SERVER['PHP_SELF'].'?msg='.urlencode($LANG['usr_upd_succ_msg']).'&userid='.$_GET['userid']); + } + + return $msg; + + } + + //This Function Is Used To Check Regiseration is allowed or not + function Registration(){ + if(ALLOW_REGISTERATION == 1 ){ + return true; + }else{ + return false; + } + } + + //Validate Form Fields And Add Member + + function SignUpUser(){ + global $row,$LANG,$stats; + if($this->Registration()){ + $uname = mysql_clean($_POST['username']); + $email = mysql_clean($_POST['email']); + $pass = pass_code(mysql_clean($_POST['password'])); + $cpass = pass_code(mysql_clean($_POST['cpassword'])); + $gender = mysql_clean($_POST['gender']); + $level = mysql_clean($_POST['level']); + $dob = mysql_clean($_POST['dob']); + $country = mysql_clean($_POST['country']); + $verify = clean($_POST['verification']); + $agree = mysql_clean($_POST['agree']); + $signuo_ip = $_SERVER['REMOTE_ADDR']; + $avcode = RandomString(10); + + //Check User + if(empty($uname)){ + $msg[] = e($LANG['usr_uname_err']); + }elseif(!$this->isValidUsername($uname)){ + $msg[] = e($LANG['usr_uname_err3']); + } + if($this->duplicate_user($uname)){ + $msg[] = e($LANG['usr_uname_err2']); + } + + //Check Password + if(empty($_POST['password']) || empty($_POST['cpassword'])){ + $msg[] = e($LANG['usr_pass_err2']); + } + if($pass != $cpass){ + $msg[] = e($LANG['usr_pass_err3']); + } + + //Check Email + if(empty($email)){ + $msg[] = e($LANG['usr_email_err1']); + }elseif(!$this->isValidEmail($email)){ + $msg[] = e($LANG['usr_email_err2']); + } + if($this->duplicate_email($email)){ + $msg[] = e($LANG['usr_email_err3']); + } + + //Checking Date Of Birth + $dob = strtotime($dob) ; + if(date("Y",$dob) < 1960 || date("Y",$dob) > date("Y")-5) + $msg[] = "Please enter valid date of birth"; + + $dob = date('Y-m-d',$dob); + + //Check AgreeMent + if(empty($agree)){ + $msg[] = e($LANG['usr_ament_err']); + } + + //Check Confirmation Code + if($row['captcha_type'] == '2'){ + require "captcha/class.img_validator.php"; + $img = new img_validator(); + if(!$img->checks_word($verify)){ + $msg[] = e($LANG['usr_ccode_err']); + } + } + if($row['captcha_type'] == 1){ + if($verify != $_SESSION['security_code']){ + $msg[] = e($LANG['usr_ccode_err']); + } + } + if(empty($msg)){ + if(EMAIL_VERIFICATION == '1'){ + $usr_status = 'ToActivate'; + }else{ + $usr_status = 'Ok'; + } + if(!mysql_query("INSERT INTO users (username,password,email,first_name,last_name,sex,level,dob,hometown,city,country,zip,avcode,signup_ip,usr_status) + VALUES('".$uname."','".$pass."','".$email."','".$fname."','".$lname."','".$gender."','".$level."','".$dob."','".$ht."','".$city."','".$country."','".$zip."','".$avcode."','".$_SERVER['REMOTE_ADDR']."','".$usr_status."')")) die(mysql_error()); + + + $stats->UpdateUserRecord(1); + $username = $uname; + $password = mysql_clean($_POST['password']); + $cur_date = date("m-d-Y"); + $baseurl = BASEURL; + $title = TITLE; + $to = $email; + + //Send EMail For Email Verification + + if(EMAIL_VERIFICATION == '1'){ + $from = SUPPORT_EMAIL; + + require_once(BASEDIR.'/includes/email_templates/email_verify.template.php'); + require_once(BASEDIR.'/includes/email_templates/email_verify.header.php'); + send_email($from,$to,$subj,nl2br($body)); + + }else{ + //Send Welcome Email + $subj = $LANG['welcome'].' '.$username.' to '.$title; + $from = WELCOME_EMAIL; + require_once(BASEDIR.'/includes/email_templates/welcome_message.template.php'); + require_once(BASEDIR.'/includes/email_templates/welcome_message.header.php'); + send_email($from,$to,$subj,nl2br($body)); + + } + //$userquery = new userquery(); + //$userquery->userlogin($uname,$pass); + $msg = 'success'; + } + + }else{ + $msg = e($LANG['usr_reg_err']); + } + return $msg; + + } + + +} +?> \ No newline at end of file diff --git a/upload/includes/classes/stats.class.php b/upload/includes/classes/stats.class.php new file mode 100644 index 00000000..06873243 --- /dev/null +++ b/upload/includes/classes/stats.class.php @@ -0,0 +1,459 @@ +stats = $details; + if($refresh=true){ + $this->Refresh(); + } + } + + //FUNCTION USED TO REFRESH STATS DATA + function Refresh(){ + $today = date("Y-m-d"); + $query = mysql_query("SELECT * FROM users WHERE doj like '%$today%'"); + $array['today_signups'] = mysql_num_rows($query); + $query = mysql_query("SELECT * FROM users WHERE last_logged like '%$today%'"); + $array['todays_logins'] = mysql_num_rows($query); + $query = mysql_query("SELECT * FROM video WHERE date_added like '%$today%'"); + $array['videos_added_today'] = mysql_num_rows($query); + + $month = date("Y-m"); + //if(date("Y-m",strtotime($this->stats['last_update'])) != $month ){ + $query = mysql_query("SELECT * FROM users WHERE last_logged like '%$month%'"); + $array['months_logins'] = mysql_num_rows($query); + $query = mysql_query("SELECT * FROM video WHERE date_added like '%$month%'"); + $array['videos_added_this_month'] = mysql_num_rows($query); + //} + + $query = mysql_query("SELECT videoid, count(*) AS flags FROM flagged_videos GROUP BY videoid ORDER BY flags DESC "); + $array['total_flagged_videos'] = mysql_num_rows($query); + + mysql_query("UPDATE stats SET value='".$array['today_signups']."' WHERE name='today_signups'"); + mysql_query("UPDATE stats SET value='".$array['todays_logins']."' WHERE name='todays_logins'"); + mysql_query("UPDATE stats SET value='".$array['videos_added_today']."' WHERE name='videos_added_today'"); + mysql_query("UPDATE stats SET value='".$array['months_logins']."' WHERE name='months_logins'"); + mysql_query("UPDATE stats SET value='".$array['videos_added_this_month']."' WHERE name='videos_added_this_month'"); + mysql_query("UPDATE stats SET value='".$array['total_flagged_videos']."' WHERE name='total_flagged_videos'"); + mysql_query("UPDATE stats SET value=now() WHERE name='last_update'"); + $this->UpdateGroupRecord(); + $query = mysql_query("SELECT * FROM stats"); + while($data = mysql_fetch_array($query)){ + $details[$data['name']] = $data['value']; + } + + if($query) + mysql_free_result($query); + $this->stats = $details; + } + + //FUNCTION USED TO UPDATE USER RECORD + function UpdateUserRecord($type=1){ + $today = date("Y-m-d"); + $month = date("Y-m"); + switch($type){ + //TYPE 1 , INCREASE TOTAL USERS + case 1; + $update = $this->stats['total_users'] + 1; + break; + //TYPE 2 , Decrease TOTAL USERS + case 2; + $update = $this->stats['total_users'] - 1; + break; + //Type 3, Update Users Signup Today + case 3; + $query = mysql_query("SELECT * FROM users WHERE doj like '%$today%'"); + $array['today_logins'] = mysql_num_rows($query); + mysql_query("UPDATE stats SET value='".$array['today_logins']."' WHERE name='today_signups'"); + break; + //Type 4, Update Users Login Today + case 4; + $query = mysql_query("SELECT * FROM users WHERE last_logged like '%$today%'"); + $array['today_logins'] = mysql_num_rows($query); + mysql_query("UPDATE stats SET value='".$array['today_logins']."' WHERE name='todays_logins'"); + break; + //Type 5, Update Users Login This Month + case 5; + $query = mysql_query("SELECT * FROM users WHERE last_logged like '%$month%'"); + $array['months_logins'] = mysql_num_rows($query); + mysql_query("UPDATE stats SET value='".$array['months_logins']."' WHERE name='months_logins'"); + break; + //Type 6, Update Number of total user comments + case 6; + $update = $this->stats['total_user_comments'] + 1; + if(!mysql_query("UPDATE stats SET value = '".$update."' WHERE name='total_user_comments'"))die(mysql_error()); + break; + } + + if($type<=2){ + mysql_query("UPDATE stats SET value = '".$update."' WHERE name='total_users'"); + } + + if(@$query) + mysql_free_result($query); + } + + + //FUNCTION USED TO UPDATE VIDEO RECORD + function UpdateVideoRecord($type=1){ + switch($type){ + //Case1: Increase 1 Video + case 1; + $update = $this->stats['total_videos'] + 1; + break; + case 2; + $update = $this->stats['total_videos'] - 1; + break; + case 3; + $update = $this->stats['total_video_comments'] + 1; + break; + case 4; + $update = $this->stats['total_video_comments'] - 1; + break; + case 5; + $update = $this->stats['total_watched_videos'] + 1; + mysql_query("UPDATE stats SET value = '".$update."' WHERE name='total_watched_videos'"); + break; + case 6; + $update = $this->stats['total_added_favorites'] + 1; + break; + case 7; + $update = $this->stats['total_added_favorites'] - 1; + break; + case 8; + $update = $this->stats['total_success_videos'] + 1; + $update2 = $this->stats['total_videos_processing'] - 1; + mysql_query("UPDATE stats SET value = '".$update."' WHERE name='total_success_videos'"); + mysql_query("UPDATE stats SET value = '".$update2."' WHERE name='total_videos_processing'"); + break; + case 9; + $update = $this->stats['total_videos_processing'] + 1; + mysql_query("UPDATE stats SET value = '".$update."' WHERE name='total_videos_processing'"); + break; + case 10; + $update = $this->stats['total_failed_videos'] + 1; + $update2 = $this->stats['total_videos_processing'] - 1; + mysql_query("UPDATE stats SET value = '".$update."' WHERE name='total_failed_videos'"); + mysql_query("UPDATE stats SET value = '".$update2."' WHERE name='total_videos_processing'"); + break; + case 11; + $update = $this->stats['total_active_videos'] + 1; + mysql_query("UPDATE stats SET value = '".$update."' WHERE name='total_active_videos'"); + break; + case 12; + $update = $this->stats['total_active_videos'] - 1; + mysql_query("UPDATE stats SET value = '".$update."' WHERE name='total_active_videos'"); + break; + } + + if($type<=2){ + mysql_query("UPDATE stats SET value = '".$update."' WHERE name='total_videos'"); + } + if($type==4 || $type==3){ + mysql_query("UPDATE stats SET value = '".$update."' WHERE name='total_video_comments'"); + } + if($type==6 || $type==7){ + mysql_query("UPDATE stats SET value = '".$update."' WHERE name='total_added_favorites'"); + } + + if(@$query) + mysql_free_result($query); + + } + + //Update Group Record + function UpdateGroupRecord(){ + $details = $this->GetGroupStats(); + mysql_query("UPDATE stats SET value='".$details['total' ]."' WHERE name='total_groups'"); + mysql_query("UPDATE stats SET value='".$details['total_topics' ]."' WHERE name='total_topics'"); + mysql_query("UPDATE stats SET value='".$details['total_posts' ]."' WHERE name='total_posts'"); + mysql_query("UPDATE stats SET value='".$details['group_invitations' ]."' WHERE name='group_invitations'"); + mysql_query("UPDATE stats SET value='".$details['groups_added_today']."' WHERE name='groups_added_today'"); + mysql_query("UPDATE stats SET value='".$details['groups_added_month']."' WHERE name='groups_added_month'"); + mysql_query("UPDATE stats SET value='".$details['group_members' ]."' WHERE name='group_members'"); + } + + //FUNCTIONS USED TO GET USER STATSS + function GetUsersStats(){ + //Query of total users + $query = mysql_query("SELECT * FROM users"); + $array['total'] = mysql_num_rows($query); + if($query) + mysql_free_result($query); + //Query For Active Users Only + $query = mysql_query("SELECT * FROM users WHERE usr_status='Ok'"); + $array['active'] = mysql_num_rows($query); + if($query) + mysql_free_result($query); + //Query For Todays Signups + $today = date("Y-m-d"); + $query = mysql_query("SELECT * FROM users WHERE doj like '%$today%'"); + $array['today_singups'] = mysql_num_rows($query); + if($query) + mysql_free_result($query); + //Query for todays Logins + $query = mysql_query("SELECT * FROM users WHERE last_logged like '%$today%'"); + $array['today_logins'] = mysql_num_rows($query); + //Query for Active Users in This Month + $month = date("Y-m"); + $query = mysql_query("SELECT * FROM users WHERE last_logged like '%$month%'"); + $array['months_logins'] = mysql_num_rows($query); + if($query) + mysql_free_result($query); + //Query For counting comments on user profiles + $query = mysql_query("SELECT * FROM channel_comments"); + $array['total_comments'] = mysql_num_rows($query); + if($query) + mysql_free_result($query); + + + return $array; + } + + //FUNCTION USED TO GET VIDEO DETAILS + function GetVideoStats(){ + $today = date("Y-m-d"); + $month = date("Y-m"); + //Query User To Get Total Videos + $query = mysql_query("SELECT * FROM video"); + $array['total'] = mysql_num_rows($query); + if($query) + mysql_free_result($query); + //Query User To Get Total Active Videos + $query = mysql_query("SELECT * FROM video WHERE active='yes'"); + $array['total_active'] = mysql_num_rows($query); + if($query) + mysql_free_result($query); + //Query User To Get FlaggedVideos + + $query = mysql_query("SELECT videoid, count(*) AS flags FROM flagged_videos GROUP BY videoid ORDER BY flags DESC "); + $array['total_flags'] = mysql_num_rows($query); + if($query) + mysql_free_result($query); + //Videos Added Today + $query = mysql_query("SELECT * FROM video WHERE date_added like '%$today%'"); + $array['added_today'] = mysql_num_rows($query); + if($query) + mysql_free_result($query); + + $query = mysql_query("SELECT * FROM video WHERE date_added like '%$month%'"); + $array['added_this_month'] = mysql_num_rows($query); + if($query) + mysql_free_result($query); + + //Total Videos Watched + $query = mysql_query("SELECT views FROM video "); + $views = 0; + while($data = mysql_fetch_array($query)){ + @$views = $views + $data['views']; + } + $array['total_watched'] = $views; + //Used To Count Comment Of Videos + $query = mysql_query("SELECT * FROM video_comments"); + $array['total_comments'] = mysql_num_rows($query); + if($query) + mysql_free_result($query); + //Used To Count Number Videos in Favourites + $query = mysql_query("SELECT * FROM video_favourites"); + $array['total_favorites'] = mysql_num_rows($query); + if($query) + mysql_free_result($query); + //Get Total Processed Videos + $query = mysql_query("SELECT * FROM video WHERE status='Processing'"); + $array['total_videos_processing'] = mysql_num_rows($query); + if($query) + mysql_free_result($query); + //Get Total Successfull Videos + $query = mysql_query("SELECT * FROM video WHERE status='Successful'"); + $array['total_success_videos'] = mysql_num_rows($query); + if($query) + mysql_free_result($query); + //Get Total Failed Videos + $query = mysql_query("SELECT * FROM video WHERE status='Failed'"); + $array['total_failed_videos'] = mysql_num_rows($query); + if($query) + mysql_free_result($query); + return $array; + } + + + //Function Used Get Group Details + function GetGroupStats($type=false){ + $today = date("Y-m-d"); + $month = date("Y-m"); + if($type==FALSE){ + //Used To Get Total Number Of Groups + $query = mysql_query("SELECT * FROM groups"); + $array['total'] = mysql_num_rows($query); + if($query) + mysql_free_result($query); + //Used To Get Total Number Of Topics + $query = mysql_query("SELECT * FROM group_topics"); + $array['total_topics'] = mysql_num_rows($query); + if($query) + mysql_free_result($query); + //Used To Get Total Number Of Posts + $query = mysql_query("SELECT * FROM group_posts"); + $array['total_posts'] = mysql_num_rows($query); + if($query) + mysql_free_result($query); + //Used To Get Total Number Of Invitations + $query = mysql_query("SELECT * FROM group_invitations"); + $array['group_invitations'] = mysql_num_rows($query); + if($query) + mysql_free_result($query); + //Groups Added Today + $query = mysql_query("SELECT * FROM groups WHERE date_added like '%$today%'"); + $array['groups_added_today'] = mysql_num_rows($query); + if($query) + mysql_free_result($query); + //Groups Added This Month + $query = mysql_query("SELECT * FROM groups WHERE date_added like '%$month%'"); + $array['groups_added_month'] = mysql_num_rows($query); + if($query) + mysql_free_result($query); + //Total Members + $query = mysql_query("SELECT * FROM group_members"); + $array['group_members'] = mysql_num_rows($query); + if($query) + mysql_free_result($query); + }else{ + switch($type){ + case 1; + //Used To Get Total Number Of Groups + $query = mysql_query("SELECT * FROM groups"); + $array['total'] = mysql_num_rows($query); + if($query) + mysql_free_result($query); + break; + + case 2; + //Used To Get Total Number Of Topics + $query = mysql_query("SELECT * FROM group_topics"); + $array['total_topics'] = mysql_num_rows($query); + if($query) + mysql_free_result($query); + break; + + case 3; + //Used To Get Total Number Of Posts + $query = mysql_query("SELECT * FROM group_posts"); + $array['total_posts'] = mysql_num_rows($query); + if($query) + mysql_free_result($query); + break; + + case 4; + //Used To Get Total Number Of Invitations + $query = mysql_query("SELECT * FROM group_invitations"); + $array['group_invitations'] = mysql_num_rows($query); + if($query) + mysql_free_result($query); + break; + + case 5; + //Groups Added Today + $query = mysql_query("SELECT * FROM groups WHERE date_added like '%$today%'"); + $array['groups_added_today'] = mysql_num_rows($query); + if($query) + mysql_free_result($query); + break; + + case 6; + //Groups Added This Month + $query = mysql_query("SELECT * FROM groups WHERE date_added like '%$month%'"); + $array['groups_added_today'] = mysql_num_rows($query); + if($query) + mysql_free_result($query); + break; + + case 7; + //Total Members + $query = mysql_query("SELECT * FROM group_members"); + $array['group_members'] = mysql_num_rows($query); + if($query) + mysql_free_result($query); + break; + + } + } + + + return $array; + } + + + //Use To Get Database Stats + function ServerDetails(){ + global $db; + $status['mysql_ver'] = mysql_get_server_info(); + $result = mysql_query( "SHOW TABLE STATUS" ); + $dbsize = 0; + while( $row = mysql_fetch_array( $result ) ) { + $dbsize += $row[ "Data_length" ] + $row[ "Index_length" ]; + } + $status['db_size'] = formatfilesize($dbsize); + $status['disk_space'] = formatfilesize(disk_total_space(BASEDIR)); + $status['space_free'] = formatfilesize(disk_free_space(BASEDIR)); + $status['space_used'] = formatfilesize(disk_total_space(BASEDIR)-disk_free_space(BASEDIR)); + $status['php_ver'] = PHP_VERSION; + return $status ; + } + + //Function Force Update + //FUNCTION USED TO COUNT THE DETAIL FROMT THE TABLES + //1 by 1 + function __FORCEUPDATE__(){ + //Update User Stats + $user_details = $this->GetUsersStats(); + mysql_query("UPDATE stats SET value='".$user_details['total' ]."' WHERE name='total_users'"); + mysql_query("UPDATE stats SET value='".$user_details['active' ]."' WHERE name='total_active_users'"); + mysql_query("UPDATE stats SET value='".$user_details['today_singups' ]."' WHERE name='today_signups'"); + mysql_query("UPDATE stats SET value='".$user_details['today_logins' ]."' WHERE name='todays_logins'"); + mysql_query("UPDATE stats SET value='".$user_details['months_logins' ]."' WHERE name='months_logins'"); + mysql_query("UPDATE stats SET value='".$user_details['total_comments' ]."' WHERE name='total_user_comments'"); + + //Update Video Stats + $video_details = $this->GetVideoStats(); + mysql_query("UPDATE stats SET value='".$video_details['total' ]."' WHERE name='total_videos'"); + mysql_query("UPDATE stats SET value='".$video_details['total_active' ]."' WHERE name='total_active_videos'"); + mysql_query("UPDATE stats SET value='".$video_details['total_flags' ]."' WHERE name='total_flagged_videos'"); + mysql_query("UPDATE stats SET value='".$video_details['added_today' ]."' WHERE name='videos_added_today'"); + mysql_query("UPDATE stats SET value='".$video_details['added_this_month']."' WHERE name='videos_added_this_month'"); + mysql_query("UPDATE stats SET value='".$video_details['total_watched' ]."' WHERE name='total_watched_videos'"); + mysql_query("UPDATE stats SET value='".$video_details['total_comments' ]."' WHERE name='total_video_comments'"); + mysql_query("UPDATE stats SET value='".$video_details['total_favorites' ]."' WHERE name='total_added_favorites'"); + mysql_query("UPDATE stats SET value='".$video_details['total_videos_processing']."' WHERE name='total_videos_processing'"); + mysql_query("UPDATE stats SET value='".$video_details['total_success_videos']."' WHERE name='total_success_videos'"); + mysql_query("UPDATE stats SET value='".$video_details['total_failed_videos']."' WHERE name='total_failed_videos'"); + + } + + function UpdateDate(){ + mysql_query("UPDATE stats SET value=now() WHERE name='date_updated'"); + } + +} + +?> \ No newline at end of file diff --git a/upload/includes/classes/swfObj.class.php b/upload/includes/classes/swfObj.class.php new file mode 100644 index 00000000..e703b14f --- /dev/null +++ b/upload/includes/classes/swfObj.class.php @@ -0,0 +1,97 @@ +SelectPlayer(); + $this->WritePlayer(); + $this->code = $this->ClearTabs($this->code); + } + + + //Function Used To Construct Player OBJ + function FlashObj(){ + $this->code = "var ".$this->playerVar." = new ".$this->objName."(\""; + //$this->code .= BASEURL; + $this->code .= $this->playerFile.'"'; + $this->code .= ',"base","'.$this->width.'","'.$this->height.'","'.$this->PlayerVer.'","'.$this->bgcolor.'");'; + } + + //Function Used To Check Which Player Has Been Selected + function SelectPlayer() + { + global $row; + + //Player + if(empty($this->playerFile)) + $this->playerFile = $row['player_file']; + } + + + + //Function Used To Add Param + function addParam($name,$value,$remove_quotes = false){ + if($remove_quotes == false){ + $this->code .= " + ".$this->playerVar.".addParam('$name', '$value');"; + }else{ + $this->code .= " + ".$this->playerVar.".addParam('$name', $value);"; + } + } + + //Function Used To Add Variables + function addVar($name,$value,$remove_quotes = false){ + if($remove_quotes == false){ + $this->code .= " + ".$this->playerVar.".addVariable('$name', '$value');"; + }else{ + $this->code .= " + ".$this->playerVar.".addVariable('$name', $value);"; + } + } + + //Function Write Player + function WritePlayer() + { + $this->code .= " + ".$this->playerVar.'.write("'.$this->DivId.'");'; + } + + //function used to remove tabs + function ClearTabs($text,$str=false){ + if($str==false){ + return preg_replace('/\t/','',$text); + }else{ + return str_replace('/\t/','',$text); + } + } + + //function for Embed Code + function EmbedCode($code){ + $this->code = 'var EmbedCode="'.addslashes($code).'";'."\r\n"; + $this->code .= "innerHtmlDiv('".$this->DivId."',EmbedCode)"; + } + +} +?> \ No newline at end of file diff --git a/upload/includes/classes/sysinfo.class.php b/upload/includes/classes/sysinfo.class.php new file mode 100644 index 00000000..81df9cdb --- /dev/null +++ b/upload/includes/classes/sysinfo.class.php @@ -0,0 +1,272 @@ + + $login_count = `last | grep / | cut -d' ' -f1 | sort | uniq -c`; + + // compact whitespace, remove leading/trailing whitespace + $login_count = trim(ereg_replace("[[:space:]]+", ' ', $login_count)); + + // convert to array, format: + // odds = login name, evens = login count (2, pedram, 5, shawn, ...) + $login_count = explode(" ", $login_count); + + // loop through our raw data and store the pertinant stats + for ($i = 0, $x = 0; $i < sizeof($login_count); $i += 2, $x++) { + $days = $hours = $mins = 0; + + // strip out the login duration (not including those currently logged in) + // XXX - add support for users still logged in. + $login_time = `last | grep -e ^{$login_count[$i+1]} | grep -v still | cut -d'(' -f2`; + $login_time = ereg_replace("[[:space:]]+", "", str_replace("\n", "", $login_time)); + $login_time = explode(")", $login_time); + + // determine the login durations + for ($j = 0; $j < sizeof($login_time); $j++) { + $entry = explode(":", $login_time[$j]); + $days += substr($entry[0], 0, strpos($entry[0], "+")); + $hours += substr($entry[0], strpos($entry[0], "+")); + $mins += $entry[1]; + } + + // formatting + $hours += floor($mins / 60); + $days += floor($hours / 24); + + $hours = $hours % 24; + $mins = $mins % 60; + + $login_stats[$x]["user"] = $login_count[$i+1]; + $login_stats[$x]["count"] = $login_count[$i]; + $login_stats[$x]["days"] = $days; + $login_stats[$x]["hours"] = $hours; + $login_stats[$x]["mins"] = $mins; + $login_stats[$x]["start"] = $wtmp_start; + } + + return $login_stats; +} + + + +/******************************************************************************* + * helper functions * + *******************************************************************************/ + + +/////////////////////////////////////////////////////////////////////////////// +// convert_bytes +// + +function convert_bytes ($bytes) { + $kbytes = $bytes / 1024; + + if ($kbytes > 1048576) + $converted = sprintf("%.2f GB", $kbytes / 1048576); + else if ($kbytes > 1024) + $converted = sprintf("%.2f MB", $kbytes / 1024); + else + $converted = sprintf("%.2f KB", $kbytes); + + return $converted; +} + +?> \ No newline at end of file diff --git a/upload/includes/classes/template.class.php b/upload/includes/classes/template.class.php new file mode 100644 index 00000000..a4b84549 --- /dev/null +++ b/upload/includes/classes/template.class.php @@ -0,0 +1,111 @@ +compile_check = true; + $Smarty->debugging = false; + $Smarty->template_dir = BASEDIR."/styles"; + $Smarty->compile_dir = BASEDIR."/cache"; + + return true; + } + + function setCompileDir($dir_name) { + global $Smarty; + if (!isset($Smarty)) { + DoTemplate::create(); + } + $Smarty->compile_dir = $dir_name; + } + + function setType($type) { + global $Smarty; + if (!isset($Smarty)) { + DoTemplate::create(); + } + $Smarty->type = $type; + } + + function assign($var, $value) { + global $Smarty; + if (!isset($Smarty)) { + DoTemplate::create(); + } + $Smarty->assign($var, $value); + } + + function setTplDir($dir_name = null) { + global $Smarty; + if (!isset($Smarty)) { + DoTemplate::create(); + } + if (!$dir_name) { + $Smarty->template_dir = BASEDIR."/styles/clipbucketblue"; + } else { + $Smarty->template_dir = $dir_name; + } + } + + function setModule($module) { + global $Smarty; + if (!isset($Smarty)) { + DoTemplate::create(); + } + $Smarty->theme = $module; + $Smarty->type = "module"; + } + + function setTheme($theme) { + global $Smarty; + if (!isset($Smarty)) { + DoTemplate::create(); + } + $Smarty->template_dir = BASEDIR."/styles/" . $theme; + $Smarty->compile_dir = BASEDIR."/styles/" . $theme; + $Smarty->theme = $theme; + $Smarty->type = "theme"; + } + + function getTplDir() { + global $Smarty; + if (!isset($Smarty)) { + DoTemplate::create(); + } + return $Smarty->template_dir; + } + + function display($filename) { + global $Smarty; + if (!isset($Smarty)) { + DoTemplate::create(); + } + $Smarty->display($filename); + } + + function fetch($filename) { + global $Smarty; + if (!isset($Smarty)) { + DoTemplate::create(); + } + return $Smarty->fetch($filename); + } + + function getVars() { + global $Smarty; + if (!isset($Smarty)) { + DoTemplate::create(); + } + return $Smarty->get_template_vars(); + } +} +?> \ No newline at end of file diff --git a/upload/includes/classes/upload.class.php b/upload/includes/classes/upload.class.php new file mode 100644 index 00000000..d2ab524d --- /dev/null +++ b/upload/includes/classes/upload.class.php @@ -0,0 +1,862 @@ +loadRequiredFields($array); + $location_fields = $this->loadLocationFields($array); + $date_fields = $this->loadDateForm('','/',TRUE); + $option_fields = $this->loadOptionFields($array); + + if($array==NULL) + $array = $_POST; + + if(is_array($_FILES)) + $array = array_merge($array,$_FILES); + + //Mergin Array + $upload_fields = array_merge($required_fields,$location_fields,$option_fields); + + //Adding Custom Upload Fields + if(count($this->custom_upload_fields)>0 && $is_upload) + $upload_fields = array_merge($upload_fields,$this->custom_upload_fields); + //Adding Custom Form Fields + if(count($this->custom_form_fields)>0) + $upload_fields = array_merge($upload_fields,$this->custom_form_fields); + + //Now Validating Each Field 1 by 1 + foreach($upload_fields as $field) + { + $field['name'] = formObj::rmBrackets($field['name']); + + //pr($field); + $title = $field['title']; + $val = $array[$field['name']]; + $req = $field['required']; + $invalid_err = $field['invalid_err']; + $length = strlen($val); + $min_len = $field['min_length']; + $min_len = $min_len ? $min_len : 0; + $max_len = $field['max_length'] ; + + if(empty($invalid_err)) + $invalid_err = sprintf("Invalid '%s'",$title); + if(is_array($array[$field['name']])) + $invalid_err = ''; + + //Checking if its required or not + if($req == 'yes') + { + if(empty($val) && !is_array($array[$field['name']])) + { + e($invalid_err); + $block = true; + } + } + + $funct_err = is_valid_value($field['validate_function'],$val); + if($block!=true) + { + + //Checking Syntax + if(!$funct_err) + { + if(!empty($invalid_err)) + e($invalid_err); + }elseif(!is_valid_syntax($field['syntax_type'],$val)) + { + if(!empty($invalid_err)) + e($invalid_err); + } + elseif(isset($max_len)) + { + if($length > $max_len || $length < $min_len) + e(sprintf(" please enter '%s' value between '%s' and '%s'", + $title,$field['min_length'],$field['max_length'])); + } + } + } + + } + function ValidateUploadForm() + { + return validate_video_upload_form(); + } + + function UploadProcess() + { + return $this->submit_upload(); + } + + function submit_upload() + { + global $eh,$Cbucket,$db; + + $this->validate_video_upload_form(NULL,TRUE); + + if(empty($eh->error_list)) + { + $required_fields = $this->loadRequiredFields($array); + $location_fields = $this->loadLocationFields($array); + $option_fields = $this->loadOptionFields($array); + + $upload_fields = array_merge($required_fields,$location_fields,$option_fields); + //Adding Custom Upload Fields + if(count($this->custom_upload_fields)>0) + $upload_fields = array_merge($upload_fields,$this->custom_upload_fields); + //Adding Custom Form Fields + if(count($this->custom_form_fields)>0) + $upload_fields = array_merge($upload_fields,$this->custom_form_fields); + + $array = $_POST; + if(is_array($_FILES)) + $array = array_merge($array,$_FILES); + + foreach($upload_fields as $field) + { + $name = formObj::rmBrackets($field['name']); + $val = $array[$name]; + + if($field['use_func_val']) + $val = $field['validate_function']($val); + + + if(!empty($field['db_field'])) + $query_field[] = $field['db_field']; + + if(is_array($val)) + { + $new_val = ''; + foreach($val as $v) + { + $new_val .= "#".$v."# "; + } + $val = $new_val; + } + if(!$field['clean_func'] || (!function_exists($field['clean_func']) && !is_array($field['clean_func']))) + $val = mysql_clean($val); + else + $val = apply_func($field['clean_func'],$val); + + if(!empty($field['db_field'])) + $query_val[] = $val; + + } + + //Adding Video Code + $query_field[] = "file_name"; + $file_name = mysql_clean($array['file_name']); + $query_val[] = $file_name; + + //ADding Video Key + $query_field[] = "videokey"; + $query_val[] = $this->video_keygen(); + //Userid + $query_field[] = "userid"; + $query_val[] = userid(); + //Setting Activation Option + if($activation == 0){ + $active = 'yes'; + }else{ + $active = 'no'; + } + $query_field[] = "active"; + $query_val[] = $active; + + $query = "INSERT INTO video ("; + $total_fields = count($query_field); + + //Adding Fields to query + $i = 0; + foreach($query_field as $qfield) + { + $i++; + $query .= $qfield; + if($i<$total_fields) + $query .= ','; + } + + $query .= ") VALUES ("; + + $i = 0; + //Adding Fields Values to query + foreach($query_val as $qval) + { + $i++; + $query .= "'$qval'"; + if($i<$total_fields) + $query .= ','; + } + + //Finalzing Query + $query .= ")"; + + if(!userid()) + { + e("You are not logged in"); + }else{ + $insert_id = file_name_exists($file_name); + if(!$insert_id) + { + $db->Execute($query); + $insert_id = $db->insert_id(); + } + } + + } + + return $insert_id; + + } + + //FUNCTION USED TO CLEAN EMBED CODE + function CleanEmbedCode($code){ + $code = trim($code); + $embed_code = str_replace('/','',$embed_code); + + if ( !stristr($embed_code, 'CleanEmbedCode($_POST['embed_code']); + + if(empty($embed_code)) + $msg[] = e($LANG['vdo_embed_code_wrong']); + $seconds = mysql_clean($_POST['seconds']); + $minutes = mysql_clean($_POST['minutes']); + + if(strlen($seconds)<2) $seconds = '0'.$seconds; + if(empty($seconds) || !is_numeric($seconds)) + $msg[] = e($LANG['vdo_seconds_err']); + + if(strlen($minutes)<2) $minutes = '0'.$minutes; + if(empty($minutes) || !is_numeric($minutes)) + $msg[] = e($LANG['vdo_mins_err']); + + //Getting Thumb + if(empty($msg)){ + $file = $_FILES['thumb_upload']['name']; + $ext = GetExt($file); + $image = new ResizeImage(); + if($image->ValidateImage($_FILES['thumb_upload']['tmp_name'],$ext)){ + $file_1 = BASEDIR.'/files/thumbs/'.GetThumb($_POST['flvname'],1,FALSE); + $file_2 = BASEDIR.'/files/thumbs/'.GetThumb($_POST['flvname'],2,FALSE); + $file_3 = BASEDIR.'/files/thumbs/'.GetThumb($_POST['flvname'],3,FALSE); + move_uploaded_file($_FILES['thumb_upload']['tmp_name'],$file_1); + $image->CreateThumb($file_1,$file_1,THUMB_WIDTH,$ext,THUMB_HEIGHT,false); + copy($file_1,$file_2); + copy($file_1,$file_3); + }else{ + $msg[] = e($LANG['vdo_thumb_up_err']); + } + } + + if(empty($msg)){ + return 'OK'; + }else{ + return $msg; + } + } + + + + /** + * Function used to get available name for video thumb + * @param FILE_Name + */ + function get_available_file_num($file_name) + { + //Starting from 1 + $code = 1; + while(1) + { + $path = THUMBS_DIR.'/'.$file_name.'-'.$code.'.'; + if(!file_exists($path.'jpg') && !file_exists($path.'png') && !file_exists($path.'gif')) + break; + else + $code = $code + 1; + } + + return $code; + } + + + function upload_thumb($file_name,$file_array,$key=0) + { + global $imgObj,$LANG; + $file = $file_array; + if(!empty($file['name'][$key])) + { + $file_num = $this->get_available_file_num($file_name); + $ext = getExt($file['name'][$key]); + if($imgObj->ValidateImage($file['tmp_name'][$key],$ext)) + { + $file_path = THUMBS_DIR.'/'.$file_name.'-'.$file_num.'.'.$ext; + move_uploaded_file($file['tmp_name'][$key],$file_path); + $imgObj->CreateThumb($file_path,$file_path,THUMB_WIDTH,$ext,THUMB_HEIGHT,false); + e($LANG['upload_vid_thumb_msg'],m); + } + } + } + + + /** + * Function used to upload video thumbs + * @param FILE_NAME + * @param $_FILES array name + */ + + function upload_thumbs($file_name,$file_array) + { + global $LANG; + if(count($file_array[name])>1) + { + for($i=0;$iupload_thumb($file_name,$file_array,$i); + } + e($LANG['upload_vid_thumbs_msg'],m); + }else{ + $file = $file_array; + $this->upload_thumb($file_name,$file); + } + } + + function UploadThumb($flv,$thumbid){ + $file = $_FILES["upload_thumb_$thumbid"]['tmp_name']; + $ext = GetExt($_FILES["upload_thumb_$thumbid"]['name']); + if(!empty($file) && $ext =='jpg'){ + $image = new ResizeImage(); + if($image->ValidateImage($file,$ext)){ + $thumb = BASEDIR.'/files/thumbs/'.GetThumb($flv,$thumbid); + move_uploaded_file($file,$thumb); + $image->CreateThumb($thumb,$thumb,THUMB_WIDTH,$ext,THUMB_HEIGHT,false); + return true; + }else{ + return false; + } + }else{ + return false; + } + + } + + + + /** + * FUNCTION USED TO LOAD UPLOAD FORM REQUIRED FIELDS + * title [Text Field] + * description [Text Area] + * tags [Text Field] + * categories [Check Box] + */ + + function loadRequiredFields($default=NULL) + { + global $LANG; + if($default == NULL) + $default = $_POST; + + $title = $default['title']; + $desc = $default['description']; + + if(is_array($default['category'])) + $cat_array = array($default['category']); + else + { + preg_match_all('/#([0-9]+)#/',$default['category'],$m); + $cat_array = array($m[1]); + } + + $tags = $default['tags']; + + $uploadFormRequiredFieldsArray = array + ( + /** + * this function will create initial array for fields + * this will tell + * array( + * title [text that will represents the field] + * type [type of field, either radio button, textfield or text area] + * name [name of the fields, input NAME attribute] + * id [id of the fields, input ID attribute] + * value [value of the fields, input VALUE attribute] + * id [name of the fields, input NAME attribute] + * size + * class + * label + * extra_params + * hint_1 [hint before field] + * hint_2 [hint after field] + * anchor_before [before after field] + * anchor_after [anchor after field] + * ) + */ + + 'title' => array('title'=> $LANG['vdo_title'], + 'type'=> 'textfield', + 'name'=> 'title', + 'id'=> 'title', + 'value'=> cleanForm($title), + 'size'=>'45', + 'db_field'=>'title', + 'required'=>'yes', + + ), + 'desc' => array('title'=> $LANG['vdo_desc'], + 'type'=> 'textarea', + 'name'=> 'description', + 'id'=> 'desc', + 'value'=> cleanForm($desc), + 'size'=>'35', + 'extra_params'=>' rows="4"', + 'db_field'=>'description', + 'required'=>'yes' + + ), + 'cat' => array('title'=> $LANG['vdo_cat'], + 'type'=> 'checkbox', + 'name'=> 'category[]', + 'id'=> 'category', + 'value'=> array('category',$cat_array), + 'hint_1'=> $LANG['vdo_cat_msg'].'
    ', + 'db_field'=>'category', + 'required'=>'yes', + 'validate_function'=>'validate_category', + 'invalid_err'=>$LANG['vdo_cat_err3'], + 'display_function' => 'convert_to_categories' + + + ), + 'tags' => array('title'=> $LANG['tag_title'], + 'type'=> 'textfield', + 'name'=> 'tags', + 'id'=> 'tags', + 'value'=> cleanForm(genTags($tags)), + 'hint_1'=> '', + 'hint_2'=> $LANG['vdo_tags_msg'], + 'db_field'=>'tags', + 'required'=>'yes', + 'validate_function'=>'genTags' + ), + ); + //Setting Anchors + $uploadFormRequiredFieldsArray['desc']['anchor_before'] = 'before_desc_compose_box'; + + //Setting Sizes + return $uploadFormRequiredFieldsArray; + } + + /** + * FUNCTION USED TO LOAD FORM OPTION FIELDS + * broadacast [Radio Button] + * embedding [Radio Button] + * rating [Radio Button] + * comments [Radio Button] + * comments rating [Radio Button] + */ + function loadOptionFields($default=NULL) + { + global $LANG,$uploadFormOptionFieldsArray; + + + if($default == NULL) + $default = $_POST; + + $broadcast = $default['broadcast'] ? $default['broadcast'] : 'public'; + $comments = $default['allow_comments'] ? $default['allow_comments'] : 'yes'; + $comment_voting = $default['comment_voting'] ? $default['comment_voting'] : 'yes'; + $rating = $default['allow_rating'] ? $default['allow_rating'] : 'yes'; + $embedding = $default['allow_embedding'] ? $default['allow_embedding'] : 'yes'; + + $uploadFormOptionFieldsArray = array + ( + 'broadcast'=> array('title'=>$LANG['vdo_br_opt'], + 'type'=>'radiobutton', + 'name'=>'broadcast', + 'id'=>'broadcast', + 'value'=>array('public'=>$LANG['vdo_br_opt1'],'private'=>$LANG['vdo_br_opt2']), + 'checked'=>$broadcast, + 'db_field'=>'broadcast', + 'required'=>'no', + 'validate_function'=>'yes_or_no', + 'display_function'=>'display_sharing_opt', + ), + 'comments'=> array('title'=>$LANG['comments'], + 'type'=> 'radiobutton', + 'name'=>'allow_comments', + 'id'=>'comments', + 'value'=> array('yes'=>$LANG['vdo_allow_comm'],'no'=>$LANG['vdo_dallow_comm']), + 'checked'=> $comments, + 'db_field'=>'allow_comments', + 'required'=>'no', + 'validate_function'=>'yes_or_no', + 'display_function'=>'display_sharing_opt', + ), + 'commentsvote'=> array('title'=>$LANG['vdo_comm_vote'], + 'type'=>'radiobutton', + 'name'=>'comment_voting', + 'id'=>'comment_voting', + 'value'=>array('yes'=>$LANG['vdo_allow_comm'].' Voting','no'=>$LANG['vdo_dallow_comm'].' Voting'), + 'checked'=>$comment_voting, + 'db_field'=>'comment_voting', + 'required'=>'no', + 'validate_function'=>'yes_or_no', + 'display_function'=>'display_sharing_opt', + ), + 'rating'=> array('title'=>$LANG['ratings'], + 'type'=>'radiobutton', + 'name'=>'allow_rating', + 'id'=>'rating', + 'value'=> array('yes'=>$LANG['vdo_allow_rating'],'no'=>$LANG['vdo_dallow_ratig']), + 'checked'=>$rating, + 'db_field'=>'allow_rating', + 'required'=>'no', + 'validate_function'=>'yes_or_no', + 'display_function'=>'display_sharing_opt', + ), + 'embedding'=> array('title'=>$LANG['vdo_embedding'], + 'type'=> 'radiobutton', + 'name'=> 'allow_embedding', + 'id'=> 'embedding', + 'value'=> array('yes'=>$LANG['vdo_embed_opt1'],'no'=>$LANG['vdo_embed_opt2']), + 'checked'=> $embedding, + 'db_field'=>'allow_embedding', + 'required'=>'no', + 'validate_function'=>'yes_or_no', + 'display_function'=>'display_sharing_opt', + ), + ); + return $uploadFormOptionFieldsArray; + } + + /** + * FUNCTION USED TO LOAD DATE AND LOCATION OPTION OF UPLOAD FORM + * - day - month - year + * - country + * - city + */ + function loadLocationFields($default=NULL) + { + global $LANG,$LocationFieldsArray,$CBucket; + + if($default == NULL) + $default = $_POST; + + $dcountry = $default['country']; + $location = $default['location']; + $date_recorded = $default['date_recorded']; + $date_recorded = $date_recorded ? date("d-m-Y",strtotime($date_recorded)) : date("d-m-Y",time()); + + $LocationFieldsArray = array + ( + 'country'=> array('title'=>$LANG['country'], + 'type'=> 'dropdown', + 'name'=> 'country', + 'id'=> 'country', + 'value'=> ClipBucket::get_countries(), + 'checked'=> $dcountry, + 'db_field'=>'country', + 'required'=>'no' + + + ), + 'location'=> array('title'=>$LANG['location'], + 'type'=>'textfield', + 'name'=> 'location', + 'id'=> 'location', + 'value'=> $location, + 'hint_2'=> $LANG['vdo_add_eg'], + 'db_field'=>'location', + 'required'=>'no' + ), + 'date_recorded' => array( + 'title' => 'Date Recorded', + 'type' => 'textfield', + 'name' => 'date_recorded', + 'id' => 'date_recorded', + 'class'=>'date_field', + 'anchor_after' => 'date_picker', + 'value'=> $date_recorded, + 'db_field'=>'datecreated', + 'required'=>'no' + ) + ); + return $LocationFieldsArray; + } + + /** + * FUNCTION USED TO DISPLAY DATE FORM + */ + function loadDateForm($date=NULL,$sep='/',$bg_process=FALSE) + { + global $LANG,$formObj; + $month_array = array(''=>'--'); + $day_array = array(''=>'--'); + $year_array = array(''=>'----'); + for($i=1;$i<13;$i++) $month_array[$i] = $i; + for($i=1;$i<32;$i++) $day_array[$i] = $i; + for($i=date("Y",time());$i>1900;$i--) $year_array[$i] = $i; + + if($date['value']==NULL) + { + $d_month = $_POST['month']; + $d_day = $_POST['day']; + $d_year = $_POST['year']; + }else{ + $d_month = date("m",strtotime($date)); + $d_day = date("d",strtotime($date)); + $d_year = date("Y",strtotime($date)); + } + if(!$bg_process) + { + echo $formObj->createField('dropdown','month','',$month_array,NULL,NULL,NULL,NULL,$d_month); + echo $sep; + echo $formObj->createField('dropdown','day','',$day_array,NULL,NULL,NULL,NULL,$d_day); + echo $sep; + echo $formObj->createField('dropdown','year','',$year_array,NULL,NULL,NULL,NULL,$d_year); + echo $LANG['vdo_for_date']; + } + + } + + + + /** + * Function used to load upload form fields + * it will load all the values that are submited in the upload form + * after validation + */ + function load_post_fields() + { + + $required_fields = $this->loadRequiredFields($array); + $location_fields = $this->loadLocationFields($array); + $option_fields = $this->loadOptionFields($array); + $upload_fields = array_merge($required_fields,$location_fields,$option_fields); + if(count($this->custom_form_fields)>0) + $upload_fields = array_merge($upload_fields,$this->custom_form_fields); + + foreach($upload_fields as $field) + { + $name = formObj::rmBrackets($field['name']); + $val = $_POST[$name]; + if(!is_array($val)) + { + $val = cleanForm($_POST[$name]); + echo ''; + }else{ + $loop = count($val); + for($i=0;$i<$loop;$i++) + { + $val = $_POST[$name][$i]; + $val = cleanForm($_POST[$name][$i]); + echo ''; + } + } + } + } + + + /** + * Function used to add files in conversion queue + */ + function add_conversion_queue($file) + { + global $Cbucket,$db; + $tmp_ext = $Cbucket->temp_exts; + + $count = 1; + while(1) + { + $exists = 'no'; + foreach($tmp_ext as $exts) + { + + if(file_exists(TEMP_DIR.'/' .getName($file).'.'.$exts)) + { + $exists = 'yes'; + break; + } + } + + if($exists !='yes') + break; + + $new_file = getName($file).'-'.$count.'.'.strtolower(getExt($file)); + rename(TEMP_DIR.'/'.$file,TEMP_DIR.'/'.$new_file); + $file = $new_file; + + $count++; + if($count>50) + break; + } + + //Checking file existsi or not + if(file_exists(TEMP_DIR.'/'.$file)) + { + $ext = mysql_clean(strtolower(getExt($file))); + $name = mysql_clean(getName($file)); + //Get Temp Ext + $tmp_ext = mysql_clean($tmp_ext[rand(0,count($tmp_ext)-1)]); + //Creating New File Name + $new_file = $name.'.'.$tmp_ext; + //Renaming File for security purpose + rename(TEMP_DIR.'/'.$file,TEMP_DIR.'/'.$new_file); + //Adding Details to database + $db->Execute("INSERT INTO conversion_queue (cqueue_name,cqueue_ext,cqueue_tmp_ext,date_added) + VALUES ('".$name."','".$ext."','".$tmp_ext."','".NOW()."') "); + return $db->insert_id; + }else{ + return false; + } + } + + + /** + * Video Key Gen + * * it is use to generate video key + */ + function video_keygen() + { + global $db; + + $char_list = "ABDGHKMNORSUXWY"; + $char_list .= "123456789"; + while(1) + { + $vkey = ''; + srand((double)microtime()*1000000); + for($i = 0; $i < 12; $i++) + { + $vkey .= substr($char_list,(rand()%(strlen($char_list))), 1); + } + + if(!vkey_exists($vkey)) + break; + } + + return $vkey; + } + + + + + /** + * Function used to load upload form + */ + function load_upload_options() + { + global $Cbucket,$Smarty; + $opt_list = $Cbucket->upload_opt_list; + + foreach($opt_list as $opt) + { + $Smarty->register_function($opt['load_func'],$opt['load_func']); + } + + return $opt_list; + } + + + + /** + * Function used to perform some actions , after video is upload + * @param Videoid + */ + function do_after_video_upload($vid) + { + foreach($this->actions_after_video_upload as $funcs) + { + if(function_exists($funcs)) + $funcs($vid); + } + } + + + /** + * Function used to load custom upload fields + */ + function load_custom_upload_fields($data,$ck_display_admin=FALSE,$ck_display_user=FALSE) + { + $array = $this->custom_upload_fields; + foreach($array as $key => $fields) + { + $ok = 'yes'; + if($ck_display_admin) + { + if($fields['display_admin'] == 'no_display') + $ok = 'no'; + } + + if($ok=='yes') + { + if(!$fields['value']) + $fields['value'] = $data[$fields['db_field']]; + $new_array[$key] = $fields; + } + } + + return $new_array; + } + + + /** + * Function used to load custom form fields + */ + function load_custom_form_fields($data) + { + $array = $this->custom_form_fields; + foreach($array as $key => $fields) + { + if(!$fields['value']) + $fields['value'] = $data[$fields['db_field']]; + $new_array[$key] = $fields; + } + + return $new_array; + } + +} +?> \ No newline at end of file diff --git a/upload/includes/classes/user.class.php b/upload/includes/classes/user.class.php new file mode 100644 index 00000000..17fffa7c --- /dev/null +++ b/upload/includes/classes/user.class.php @@ -0,0 +1,1434 @@ +userid = $sess->get('userid'); + $this->username = $sess->get('username'); + $this->level = $sess->get('level'); + + + //Setting Access + $this->add_access_type('admin_access','Admin Access'); + $this->add_access_type('upload_access','Upload Access'); + $this->add_access_type('channel_access','Channel Access'); + $this->add_access_type('mod_access','Moderator Access'); + + } + + /** + * Function used to create user session key + */ + function create_session_key($session,$pass) + { + $newkey = $session.$pass; + $newkey = md5($newkey); + + } + + /** + * Function used to create user session code + * just for session authentication incase user wants to login again + */ + function create_session_code() + { + $code = rand(10000,99999); + return $code; + } + + /** + * Neat and clean function to login user + * this function was made for v2.x with User Level System + * param VARCHAR $username + * param TEXT $password + */ + function login_user($username,$password) + { + global $LANG,$sess,$cblog,$db; + //Now checking if user exists or not + $pass = pass_code($password); + $udetails = $this->get_user_with_pass($username,$pass); + + //Inerting Access Log + $log_array = array('username'=>$username); + + //First we will check weather user is already logged in or not + if($this->login_check) + $msg[] = e($LANG['you_already_logged']); + elseif(!$this->user_exists($username)) + $msg[] = e($LANG['user_doesnt_exist']); + elseif(!$udetails) + $msg[] = e($LANG['usr_login_err']); + elseif(strtolower($udetails['usr_status']) != 'ok') + $msg[] = e($LANG['user_inactive_msg']); + elseif($udetails['ban_status'] == 'yes') + $msg[] = e($LANG['usr_ban_err']); + else + { + + $log_array['userid'] = $userid = $udetails['userid']; + $log_array['useremail'] = $udetails['email']; + $log_array['success'] = 1; + + $log_array['level'] = $level = $udetails['level']; + + $sess->set('username',$username); + $sess->set('level',$level); + $sess->set('userid',$userid); + + //Starting special sessions for security + $sess->set('user_session_key',$udetails['user_session_key']); + $sess->set('user_session_code',$udetails['user_session_code']); + + //Setting Vars + $this->userid = $sess->get('userid'); + $this->username = $sess->get('username'); + $this->level = $sess->get('level'); + + //Updating User last login and num of visist + $db->update('users', + array( + 'num_visits','last_logged' + ), + array( + '|f|num_visits+1',NOW() + ), + "userid='".$userid."'" + ); + //Logging Actiong + $cblog->insert('login',$log_array); + + return true; + } + + //Error Loging + if(!empty($msg)) + { + //Loggin Action + $log_array['success'] = no; + $log_array['details'] = $msg[0]; + $cblog->insert('login',$log_array); + } + } + + /** + * Function used to check weather user is login or not + * it will also check weather user has access or not + * @param VARCHAR acess type it can be admin_access, upload_acess etc + * you can either set it as level id + */ + function login_check($access=NULL,$check_only=FALSE) + { + global $LANG,$Cbucket,$sess; + //First check weather userid is here or not + if(!userid()) + { + if(!$check_only) + e($LANG['you_not_logged_in']); + return false; + } + elseif(!$this->session_auth(userid())) + { + if(!$check_only) + e($LANG['usr_invalid_session_err']); + return false; + } + //Now Check if logged in user exists or not + elseif(!$this->user_exists(userid())) + { + if(!$check_only) + e($LANG['invalid_user']); + return false; + } + //Now Check logged in user is banned or not + elseif($this->is_banned(userid())=='yes') + { + if(!$check_only) + e($LANG['usr_ban_err']); + return false; + } + + //Now user have passed all the stages, now checking if user has level access or not + elseif($access) + { + $access_details = $this->get_user_level(userid()); + if(is_numeric($access)) + { + $access_details = $this->get_user_level(userid()); + if($access_details['level_id'] == $access) + { + return true; + }else{ + if(!$check_only) + e($LANG['insufficient_privileges']); + $Cbucket->show_page(false); + return false; + } + }else + { + if($access_details[$access] == 'yes') + { + return true; + } + else + { + if(!$check_only) + e($LANG['insufficient_privileges']); + $Cbucket->show_page(false); + return false; + } + } + } + else + { + return true; + } + } + + /** + * This function was used to check + * user is logged in or not -- for v1.7.x and old + * it has been replaced by login_check in v2 + * this function is sitll in use so + * we are just replace the lil code of it + */ + function logincheck($redirect=TRUE) + { + + if(!$this->login_check()) + { + if($redirect==TRUE) + redirect_to(BASEURL.signup_link); + return false; + } + else + { + return true; + } + } + + /** + * Function used to authenticate user session + */ + function session_auth($uid) + { + global $sess; + $ufields = $this->get_user_fields($uid,'user_session_key,user_session_code'); + if($sess->get('user_session_key') == $ufields['user_session_key'] + && $sess->get('user_session_code') == $ufields['user_session_code']) + return true; + else + return false; + } + + /** + * Function used to get user details using username and password + */ + function get_user_with_pass($username,$pass) + { + global $db; + $results = $db->select("users", + "userid,email,level,usr_status,user_session_key,user_session_code", + "username='$username' AND password='$pass'"); + if($db->num_rows > 0) + { + return $results[0]; + }else{ + return false; + } + } + + + /** + * Function used to check weather user is banned or not + */ + function is_banned($uid) + { + global $db; + $details = $this->get_user_field($uid,'ban_status'); + return $details['ban_status']; + } + + /* + + -- USED WITH PRIRIOR VERSIONS OF CB + + //This Function Is Used to Login Admin + function adminlogin($username,$password){ + $query = mysql_query("Select * FROM users WHERE level = 'Admin' and username = '".$username."' and password = '".$password."'"); + $updatequery = "UPDATE users SET session='".$_COOKIE['PHPSESSID']."' WHERE username = '".$username."'"; + + if(mysql_num_rows($query) >0 ){ + $data = mysql_fetch_array($query); + if($data['ban_status'] != 'yes'){ + setcookie('username',$username,time()+7200,'/'); + setcookie('userid',$data['userid'],time()+7200,'/'); + setcookie('session',$_COOKIE['PHPSESSID'],time()+7200,'/'); + session_register('username'); + session_register('superadmin'); + session_register('admin'); + session_register('userid'); + $_SESSION['userid'] = $data['userid']; + $_SESSION['username'] = $data['username']; + if($data['userid']==1){ + $_SESSION['superadmin'] = $data['username']; + } + $_SESSION['admin'] = $data['username']; + mysql_query($updatequery); + $login = 'loggedin'; + }else{ + $login = 'banned'; + } + }else{ + $login = 'failed'; + } + return $login; + } + */ + function admin_check(){ + $admin = 'Admin'; + if(isset($_SESSION['userid']) && isset($_SESSION['username']) && isset($_SESSION['session'])) + { + $userid = @$_SESSION['userid']; + $username = @$_SESSION['username']; + $session = @$_SESSION['session']; + + $query = mysql_query("SELECT * FROM users WHERE level='".$admin."' AND username ='".$username."' AND userid = '".$userid."' AND session='".$session."'"); + if(mysql_num_rows($query)>0){ + $answer = 1; + return $answer; + }else{ + $answer = 0; + return $answer; + } + } + } + + /** + * Function used to check user is admin or not + * @param BOOLEAN if true, after checcking user will be redirected to login page if needed + */ + function admin_login_check($is_login_page=false) + { + if(!$this->login_check('admin_access')) + { + if($is_login_page==FALSE) + redirect_to('login.php'); + return false; + }else{ + return true; + } + } + + /*//This Fucntion Is Used To Check Weather User as Admin has Been Lggen in or Not FOR LOGIN PAGE + function admin_login_check_2(){ + $admin = 'Admin'; + $userid = @$_SESSION['userid']; + $username = @$_SESSION['username']; + $session = @$_COOKIE['PHPSESSID']; + $query = mysql_query("SELECT * FROM users WHERE level='".$admin."' AND username ='".$username."' AND userid = '".$userid."' AND session='".$session."'"); + if(mysql_num_rows($query)>0){ + $login = true; + }else{ + + } + + return @$login; + + }*/ + + /*//Function Used To Check if SuperAdmin is loggged in or no + function SuperAdminCheck(){ + $username = $_SESSION['username']; + $session = $_COOKIE['PHPSESSID']; + $query = mysql_query("SELECT * FROM admin WHERE username = '".$username."' AND session = '".$session."'"); + if(mysql_num_rows($query)>0){ + $login = true; + }else{ + redirect_to('main.php?msg=Please%20Loggin%20As%20SuperAdmin'); + } + }*/ + + //This Function Is Used to Logout + function logout($page='login.php'){ + setcookie('username','',time()-3600,'/'); + setcookie('userid','',time()-3600,'/'); + setcookie('session','',time()-3600,'/'); + session_unregister('username'); + session_unregister('superadmin'); + session_unregister('userid'); + session_destroy(); + redirect_to($page); + } + + //List All Users + + function Get_All_Users($orderby,$order){ + $myquery = new myquery(); + $query = mysql_query("SELECT * FROM users ORDER BY '".$orderby."' '".$order."'"); + while($data=$myquery->fetch($query)){ + } + return $data; + } + + //Updating Super Admin + function UpdateSuperAdmin(){ + global $LANG; + $query = mysql_query("SELECT * FROM admin WHERE admin_id = '1' "); + $data = mysql_fetch_array($query); + + $pass = $data['password']; + + $uname = clean($_POST['uname']); + if(empty($uname)){ + $msg = e($LANG['usr_sadmin_err']); + } + $op = pass_code($_POST['opass']); + $np = pass_code($_POST['npass']); + $cp = pass_code($_POST['cnpass']); + + if(!empty($_POST['npass'])){ + if($np != $cp){ + $msg = e($LANG['usr_cpass_err']); + }elseif($op != $pass){ + $msg = e($LANG['usr_pass_err']); + }else{ + $pass_query = " , password = '".$np."'"; + } + } + if(empty($msg)){ + mysql_query("UPDATE admin SET username = '".$uname."' $pass_query WHERE username = '".$data['username']."'"); + $msg = e($LANG['usr_sadmin_msg'],m); + } + return $msg; + } + //--------ADMIN ACTIONS START ---------// + + //Delete User + + function DeleteUser($id){ + global $stats; + if($id !=1){ + $query = 'DELETE FROM users WHERE userid="'.$id.'"'; + $result = mysql_query($query); + $stats->UpdateUserRecord(2); + if (mysql_errno()){ + $result = false; + }else{ + $result = true; + } + return $result; + }else{ + return false; + } + } + + //Check User Exists or Not + function Check_User_Exists($id){ + $query = mysql_query("SELECT * FROM users WHERE userid='".$id."' OR username='".$id."'"); + if(mysql_num_rows($query)>0){ + return true; + }else{ + return false; + } + } + + function user_exists($username) + { + return $this->Check_User_Exists($username); + } + + /** + * Function used to get user details using userid + */ + function get_user_details($id=NULL) + { + global $db; + if(!$id) + $id = userid(); + + $results = $db->select('users','*'," userid='$id' "); + return $results[0]; + }function GetUserData($id=NULL){ return $this->get_user_details($id); } + + + //Get User Data from Database + function GetUserData_username($username){ + $query = mysql_query("SELECT * FROM users WHERE username='".$username."'"); + $data = mysql_fetch_array($query); + return $data; + } + + //Get User Data from Database + function CheckVideoOwner($videoid,$username){ + $query = mysql_query("SELECT * FROM video WHERE videoid='".$videoid."'"); + $videodata = mysql_fetch_array($query); + if($videodata['username'] == $username) + { + $response = 1; + } + else + { + $response = 0; + } + return $response; + } + + //Activate User + function Activate($user){ + $avcode = RandomString(10); + mysql_query("UPDATE users SET usr_status ='Ok',avcode='".$avcode."' WHERE userid='".$user."'"); + return true; + } + + //DeActivate User + function DeActivate($user){ + $avcode = RandomString(10); + mysql_query("UPDATE users SET usr_status ='ToActivate',avcode='".$avcode."' WHERE userid='".$user."'"); + return true; + } + + //Featured User + function MakeFeatured($user){ + mysql_query("UPDATE users SET featured ='Yes' WHERE userid='".$user."'"); + return true; + } + + //UnFeatured User + function MakeUnFeatured($user){ + mysql_query("UPDATE users SET featured ='No' WHERE userid='".$user."'"); + return true; + } + + //Ban User + function ban($user){ + mysql_query("UPDATE users SET ban_status ='yes' WHERE userid='".$user."'"); + return true; + } + + //UnBan User + function unban($user){ + mysql_query("UPDATE users SET ban_status ='no' WHERE userid='".$user."'"); + return true; + } + + + //--------ADMIN ACTIONS END ---------// + + //User Login + + function userlogin($username,$password){ + //FUNCTION PENDING DUE TO FAILED IMPLEMENTATION -- ARSLAN +/* if(LOGIN_BRIDGE==1){ + require('login_bridge.php'); + $bridgeid = LOGIN_BRIDGE_ID; + $param = $this->GetBridgeParams($bridgeid); + $param['username'] = $username; + $param['password'] = $password; + $brige_results = BridgePHPBB($param); + }else{*/ + + $query = mysql_query("Select * FROM users WHERE username = '".$username."' and password = '".$password."'"); + $user_query = mysql_query("Select num_visits FROM users WHERE username = '".$username."'"); + $user_data = mysql_fetch_array($user_query); + $videos_query = mysql_query("SELECT * FROM video WHERE username='".$username."'"); + $videoscount = mysql_num_rows($videos_query); + $comments_query = mysql_query("SELECT * FROM channel_comments WHERE channel_user='".$username."'"); + $commentscount = mysql_num_rows($comments_query); + $num_visits = $user_data['num_visits']+1; + $updatequery = "UPDATE users SET session='".$_COOKIE['PHPSESSID']."' , last_logged =now(), num_visits='".$num_visits."',total_videos='".$videoscount."',total_comments='".$commentscount."',ip='".$_SERVER['REMOTE_ADDR']."' WHERE username = '".$username."'"; + //} + //if(mysql_num_rows($query) >0 || $brige_results==true){ -- In case we turn LoginBrigge on + if(mysql_num_rows($query) >0){ + $data = mysql_fetch_array($query); + if($data['ban_status'] != 'yes'){ + setcookie('username',$data['username'],time()+7200,'/'); + setcookie('userid',$data['userid'],time()+7200,'/'); + setcookie('session',$_COOKIE['PHPSESSID'],time()+7200,'/'); + session_register('username'); + session_register('userid'); + session_register('session'); + session_register('admin'); + $_SESSION['username'] = $data['username']; + $_SESSION['userid'] = $data['userid']; + $_SESSION['session'] = $_COOKIE['PHPSESSID']; + if(!empty($admin) || $data['level'] == 'Admin'){ + $_SESSION['admin'] = $data['username']; + } + if($data['userid'==1]){ + $_SESSION['superadmin'] = $data['username']; + } + mysql_query($updatequery); + $login = 'loggedin'; + }else{ + $login = 'banned'; + } + }else{ + $login = 'failed'; + } + return $login; + } + + + + + function logincheck2(){ + @$userid = $_SESSION['userid']; + @$username = $_SESSION['username']; + @$session = $_COOKIE['PHPSESSID']; + $query = mysql_query("SELECT * FROM users WHERE username ='".$username."' AND userid = '".$userid."' AND session='".$session."'"); + if(mysql_num_rows($query)>0){ + $login = true; + }else{ + $login = false; + } + return $login; + } + + + //Function Used to Count Number of Videos Uploaded By User + + function TotalVideos($username){ + $query = mysql_query("SELECT * FROM video WHERE username = '".$username."'"); + $total = mysql_num_rows($query); + return $total; + } + + //Function Used to Count Number of Friends of User + + function TotalFriends($username){ + $query = mysql_query("SELECT * FROM contacts WHERE username = '".$username."' AND type='1'"); + $total = mysql_num_rows($query); + return $total; + } + + //Function Used to Count Number of Groups of User + + function TotalGroups($username){ + $query = mysql_query("SELECT * FROM groups WHERE username = '".$username."'"); + $total = mysql_num_rows($query); + return $total; + } + + + + //Function Used To Activate User + function ActivateUser($user,$avcode){ + $data = $this->GetUserData_username($user); + if($data['usr_status'] == 'Ok' || $data['avcode'] !=$avcode || empty($user)){ + return false; + }else{ + $this->Activate($data['userid']); + return true; + } + } + + //Function Used To Send Activation Code To User + function SendActivation($email){ + $query = mysql_query("SELECT * FROM users WHERE email='".$email."'"); + $data = mysql_fetch_array($query); + if(!empty($data['username']) && $data['usr_status'] != 'Ok'){ + $username = $data['username']; + $avcode = $data['avcode']; + $cur_date = date('m-d-Y'); + $title = TITLE; + $baseurl = BASEURL; + $from = SUPPORT_EMAIL; + $to = $email; + require_once(BASEDIR.'/includes/email_templates/activation_request.template.php'); + require_once(BASEDIR.'/includes/email_templates/activation_request.header.php'); + send_email($from,$to,$subj,nl2br($body)); + return true; + }else{ + return false; + } + } + + //Function Made to Update User Profile And Channel + function UpdateUserProfile($userid){ + //Getting Personal Information + $fname = mysql_clean(@$_POST['fname']); + $lname = mysql_clean(@$_POST['lname']); + $sex = @$_POST['gender']; + $relation = @$_POST['relationship']; + $show_dob = $_POST['show_dob']; + $about_me = mysql_clean($_POST['about_me']); + $web_url = mysql_clean($_POST['web_url']); + + //Getting Professional Information + $education = $_POST['education']; + $schools = mysql_clean($_POST['schools']); + $occupation = mysql_clean($_POST['occupation']); + $companies = mysql_clean($_POST['campanies']); + + //Getting Interest & Hobbies + $hobbies = mysql_clean($_POST['hobbies']); + $fav_movies = mysql_clean($_POST['fav_movies']); + $fav_music = mysql_clean($_POST['fav_music']); + $fav_books = mysql_clean($_POST['fav_books']); + + //Getting Avatar + $file = $_FILES['avatar']['name']; + $ext = substr($file, strrpos($file, '.') + 1); + $thumb = $_POST['thumb']; + $thumb_ext = substr($thumb, strrpos($thumb, '.') + 1); + $small_t = substr($thumb, 0, strrpos($thumb, '.')).'-small.'.$thumb_ext; + + //Getting Channel Details + $title = mysql_clean($_POST['title']); + $des = mysql_clean($_POST['des']); + $rating = $_POST['rating']; + $comment = $_POST['comment']; + $f_video = $_POST['f_video']; + + if(!empty($file)){ + $image = new ResizeImage(); + if($image->ValidateImage($_FILES['avatar']['tmp_name'],$ext)){ + $thumb_file = BASEDIR.'/images/avatars/'.$thumb; + $small_thumb_file=BASEDIR.'/images/avatars/'.$small_t; + if($thumb != 'no_avatar.jpg' && file_exists($thumb_file) && file_exists($small_thumb_file)){ + unlink($thumb_file); + unlink($small_thumb_file); + } + $newname = $userid; + $newthumb = $newname.'.'.$ext; + $newthumb_small = $newname.'-small.'.$ext; + $new_thumb = BASEDIR.'/images/avatars/'.$newthumb; + $new_thumb_small = BASEDIR.'/images/avatars/'.$newthumb_small; + copy($_FILES['avatar']['tmp_name'],$new_thumb); + $image->CreateThumb($new_thumb,$new_thumb,90,$ext); + $image->CreateThumb($new_thumb,$new_thumb_small,30,$ext); + $thumb = $newthumb; + } + } + + $bgfile = $_FILES['background']['name']; + $bg = $_POST['bg']; + $ext = substr($bgfile, strrpos($bgfile, '.') + 1); + + //Delete background + if($_POST['remove_bg'] == 'yes'){ + if(is_file(BASEDIR.'/images/backgrounds/'.$bg) && file_exists(BASEDIR.'/images/backgrounds/'.$bg)){ + unlink(BASEDIR.'/images/backgrounds/'.$bg); + } + $bg = ""; + } + if(!empty($bgfile)){ + $image = new ResizeImage(); + if($image->ValidateImage($_FILES['background']['tmp_name'],$ext)){ + if(file_exists(BASEDIR.'/images/backgrounds/'.$bg)){ + unlink(BASEDIR.'/images/backgrounds/'.$bg); + } + $newname = RandomString(10); + $newthumb = $newname.'.'.$ext; + $new_thumb = BASEDIR.'/images/backgrounds/'.$newthumb; + copy($_FILES['background']['tmp_name'],$new_thumb); + $bg = $newthumb; + } + } + + mysql_query("UPDATE users SET + first_name = '".$fname."', + last_name = '".$lname."', + sex = '".$sex."', + relation_status = '".$relation."', + about_me = '".$about_me."', + web_url = '".$web_url."', + show_dob = '".$show_dob."', + + education = '".$education."', + schools = '".$schools."', + occupation = '".$occupation."', + companies = '".$companies."', + + hobbies = '".$hobbies."', + fav_movies = '".$fav_movies."', + fav_music = '".$fav_music."', + fav_books = '".$fav_books."', + + avatar = '".$thumb."', + background = '".$bg."', + + channel_title = '".$title."', + channel_des = '".$des."', + featured_video = '".$f_video."', + allow_comment = '".$comment."', + allow_rating = '".$rating."' + + WHERE userid='".$userid."'"); + redirect_to($_COOKIE['page']."?updated=successfull"); + } + + //Function Used To Update Email Settings For User + + function UpdateUserEmailSettings($usreid){ + $email = mysql_clean($_POST['email']); + $msg_notify = $_POST['msg_notify']; + $signup = new signup(); + if($signup->isValidEmail($email)){ + mysql_query("UPDATE users SET email='".$email."',msg_notify='".$msg_notify."' WHERE userid='".$usreid."'"); + $msg = e($LANG['usr_email_msg'],m); + }else{ + $msg = e($LANG['usr_email_err']); + } + return $msg; + } + + //Function Used To Change Password + + function ChangeUserPassword($userid){ + global $LANG; + $old_pass = pass_code($_POST['old_pass']); + $new_pass = pass_code($_POST['new_pass']); + $c_new_pass = pass_code($_POST['c_new_pass']); + $query = mysql_query("SELECT * FROM users WHERE userid = '".$userid."' AND password = '".$old_pass."'"); + if(mysql_num_rows($query)>0){ + if($new_pass == $c_new_pass){ + mysql_query("UPDATE users Set password='".$new_pass."' WHERE userid='".$userid."'"); + $msg = e($LANG['usr_pass_msg'],m); + }else{ + $msg = e($LANG['usr_cpass_err1']); + } + }else{ + $msg = e($LANG['usr_pass_err1']); + } + return $msg; + } + + //Function Used to update number of channel / profile views of user + + function UpdateChannelViews($user){ + $query = mysql_query("SELECT profile_hits FROM users WHERE username='".$user."'"); + $data = mysql_fetch_array($query); + $views = $data['profile_hits']+1; + if(!isset($_COOKIE['view_'.$user])){ + mysql_query("UPDATE users SET profile_hits = '".$views."' WHERE username = '".$user."'"); + setcookie('view_'.$user,'true',time()+3600,'/'); + } + } + + + //Function Used To Add Channel Comment + + function AddChannelComment($username,$comment){ + global $LANG,$stats; + if(empty($_SESSION['username']) ||empty($_COOKIE['session'])){ + $msg[] = e($LANG['usr_cmt_err']); + }else{ + if(empty($comment)){ + $msg[] = e($LANG['usr_cmt_err1']); + } + $userdetails = $this->GetUserData_username($username); + if($_SESSION['username'] == $userdetails['username']){ + $msg[] = e($LANG['usr_cmt_err2']); + } + $query = mysql_query("SELECT * FROM channel_comments WHERE channel_user ='".$username."' AND username = '".$_SESSION['username']."'"); + if(mysql_num_rows($query)>0){ + $msg[] = e($LANG['usr_cmt_err3']); + } + } + if(empty($msg)){ + $stats->UpdateUserRecord(6); + mysql_query("INSERT into channel_comments(comment,username,channel_user,date_added)VALUES('".$comment."','".$_SESSION['username']."','".$username."',now())"); + $msg[] = e($LANG['usr_cmt_err4']); + } + return $msg; + } + + + //Add Contact to Contact list + + function AddContact($friend,$username,$type=1){ + global $LANG; + if($friend == $username){ + $msg = e($LANG['usr_cnt_err']); + } + $query = mysql_query("SELECT * FROM contacts WHERE friend_username = '".$friend."' AND username='".$username."'"); + if(mysql_num_rows($query)>0){ + $msg = e($LANG['usr_cnt_err1']); + } + if(empty($msg)){ + mysql_query("INSERT INTO contacts (friend_username,username,type)VALUES('".$friend."','".$username."','".$type."')"); + $msg = e($LANG['usr_cnt_msg']); + } + return $msg; + } + + //Function Used to Update Videos Watch By A User + function UpdateWatched($userid){ + global $LANG; + $data = $this->GetUserData($userid); + $watched = $data['total_watched']+1; + mysql_query("UPDATE users SET total_watched ='".$watched."' WHERE userid='".$userid."'"); + } + + /** + * Old Function : GetNewMsgs + * This function is used to get user messages + * @param : user + * @param : sent/inbox + * @param : count (TRUE : FALSE) + */ + + function get_pm_msgs($user,$box='inbox',$count=FALSE){ + global $db,$eh,$LANG; + if(!$user) + $user = user_id(); + if(!user_id()) + { + $eh->e($LANG['you_not_logged_in']); + }else{ + switch($box) + { + case 'inbox': + default: + $boxtype = 'inbox'; + break; + + case 'sent': + case 'outbox': + $boxtype = 'outbox'; + break; + } + + if($count) + $status_query = " AND status = '0' "; + + $results = $db->select("messages", + " message_id ", + "(".$boxtype."_user = '$user' OR ".$boxtype."_user_id = '$user') $status_query"); + + + if($db->num_rows > 0) + { + if($count) + return $db->num_rows; + else + return $results; + } + else + { + return false; + } + } + } + function GetNewMsgs($user) + { + $msgs = $this->get_pm_msgs($user,'inbox',TRUE); + if($msgs) + return $msgs; + else + return 0; + } + + //Function Used To Unpdat Numner Of Subscrtibers of user + function UpdateSubscribers($user){ + global $LANG; + $query = mysql_query("SELECT * FROM subscriptions WHERE subscribed_to ='".$user."' "); + $subs = mysql_num_rows($query); + mysql_query("UPDATE users SET subscribers = '".$subs."' WHERE username='".$user."'"); + } + + //Function Used To Subscribe to User + function SubscribeUser($sub_user,$sub_to){ + global $LANG; + if(!empty($sub_user) || !empty($sub_to)){ + $query=mysql_query("SELECT * FROM subscriptions WHERE subscribed_user='".$sub_user."' AND subscribed_to='".$sub_to."'"); + if(mysql_num_rows($query)==0){ + mysql_query("INSERT INTO subscriptions(subscribed_user,subscribed_to)VALUES('".$sub_user."','".$sub_to."')"); + $this->UpdateSubscribers($sub_to); + $msg = e($LANG['usr_sub_msg'].$sub_to,m); + }else{ + $msg = e($LANG['usr_sub_err'].$sub_to); + } + } + return $msg; + } + + //Function Used To Reset Passoword + function ResetPassword($step){ + global $LANG,$row; + if($step == 1){ + $user = mysql_clean($_POST['username']); + $verify = $_POST['vcode']; + $query = mysql_query("SELECT * FROM users WHERE username = '".$user."'"); + $data = mysql_fetch_array($query); + if(!mysql_num_rows($query)>0){ + $msg[] = e($LANG['usr_exist_err']); + } + //Check Confirmation Code + if($row['captcha_type'] == '2'){ + require "captcha/class.img_validator.php"; + $img = new img_validator(); + if(!$img->checks_word($verify)){ + $msg[] = e($LANG['usr_ccode_err']); + } + } + if($row['captcha_type'] == 1){ + if($verify != $_SESSION['security_code']){ + $msg[] = e($LANG['usr_ccode_err']); + } + } + if(empty($msg)){ + $myquery = new myquery(); + $to = $data['email']; + $from = SUPPORT_EMAIL; + $subj = $LANG['usr_pass_reset_conf']; + $message = $LANG['usr_dear_user'].", + ".$LANG['usr_pass_reset_msg']." + ".BASEURL."/forgot.php?action=reset_pass&code=".md5($to)."___AAAWWWx54s5d744_sad1sad&avcode=".$data['avcode']."&user=".$user; + send_email($from,$to,$subj,nl2br($message)); + $msg = $LANG['usr_rpass_email_msg']; + } + } + if($step==2){ + $user = mysql_clean($_GET['user']); + $avcode = mysql_clean($_GET['avcode']); + $query = mysql_query("SELECT * FROM users WHERE username='".$user."' AND avcode ='".$avcode."'"); + $data = mysql_fetch_array($query); + if(mysql_num_rows($query)>0&& !empty($avcode)){ + $newpass = RandomString(6); + $pass = pass_code($newpass); + mysql_query("UPDATE users SET password = '".$pass."' WHERE username = '".$user."'"); + $msg = e($LANG['usr_pass_email_msg'],m); + + $myquery = new myquery(); + $to = $data['email']; + $from = SUPPORT_EMAIL; + $subj = $LANG['usr_rpass_msg']; + $message = $LANG['usr_dear_user'].", + ".$LANG['usr_rpass_req_msg'].$newpass; + send_email($from,$to,$subj,nl2br($message)); + }else{ + $msg = e($LANG['usr_exist_err']); + } + } + + return $msg; + } + + //Function Used to recover USername + function RecoverUsername(){ + global $LANG; + $email = mysql_clean($_POST['email']); + $verify = $_POST['vcode']; + $query = mysql_query("SELECT * FROM users WHERE email='".$email."'"); + $data = mysql_fetch_array($query); + if(!mysql_num_rows($query)>0){ + $msg[] = e($LANG['usr_exist_err1']); + } + + //Check Confirmation Code + require "captcha/class.img_validator.php"; + $img = new img_validator(); + if(!$img->checks_word($verify)){ + $msg[] = e($LANG['usr_ccode_err']); + } + + if(empty($msg)){ + $to = $email; + $from = SUPPORT_EMAIL; + $subj = $ANG['usr_uname_recovery']; + $message= $LANG['usr_dear_user'].", + ".$LANG['usr_uname_req_msg'].$data['username']; + send_email($from,$to,$subj,nl2br($message)); + $msg = e($LANG['usr_uname_email_msg'],m); + } + return $msg; + + + } + //Gettin Bridge Paramaters + function GetBridgeParams($bridgeid){ + $query = mysql_query("SELECT * FROM login_bridges WHERE bridge_id='".$bridgeid."'"); + return mysql_fetch_array($query); + } + + //Updateing User if login + function UpdateBrigeUser($username,$session,$bridge){ + $query = mysql_query("SELECT * FROM bridge_users where username='".$username."'"); + $date = time(); + if(mysql_num_rows($query)>0){ + mysql_query("UPDATE bridge_users SET session = '".$session."', date_updated = '".$date."'WHERE username='".$username."'"); + }else{ + mysql_query("INSERT INTO bridge_users(username,session,bridge,date_update)VALUES('".$username."','".$session."','".$bridge."','".$date."'"); + } + } + + //FUNCTION USED TO UPDATE LAST ACTIVE FOR OF USER + // @ Param : username + function UpdateLastActive($username) + { + global $db; + $sql = "UPDATE users SET last_active = now() WHERE username='".$username."'"; + $db->Execute($sql); + } + + //FUNCTION USED TO DELETE COMMMENT + // @ Param : username + // @ Param : commentid + function deleteUserComment($username,$commentid) + { + global $is_admin,$db,$LANG; + if($_SESSION['username']==$username || $is_admin ==1) + { + $sql = "DELETE FROM channel_comments WHERE comment_id='".$commentid."' + AND channel_user = '".$username."'"; + $db->Execute($sql); + $msg = e($LANG['usr_cmt_del_msg'],m); + }else{ + $msg = e($LANG['usr_cmt_del_err']); + } + return $msg; + } + + /** + * FUNCTION USED TO GE USER THUMBNAIL + * @param : thumb file + * @param : size (NULL,small) + */ + function getUserThumb($udetails,$size='',$uid=NULL) + { + if(empty($udetails['userid'])) + $udetails = $this->get_user_details($uid); + $thumbnail = $udetails['avatar'] ? $udetails['avatar'] : 'noavatar.png'; + $thumb_file = BASEDIR.'/images/avatars/'.$thumbnail; + if(file_exists($thumb_file)) + $thumb_file = BASEURL.'/images/avatars/'.$thumbnail; + else + $thumb_file = BASEURL.'/images/avatars/no_avatar.jpg'; + $ext = GetExt($thumb_file); + $file = getName($thumb_file); + if(!empty($size)) + $thumb = $file.'-'.$size.'.'.$ext; + else + $thumb = $file.'.'.$ext; + return $thumb; + } + function avatar($udetails,$size='',$uid=NULL) + { + return $this->getUserThumb($udetails,$size,$uid); + } + + + + + /** + * Function used to get user subscriber's list + * @param VARCHAR//INT username or userid , both works fine + */ + function get_user_subscriber($username) + { + global $db; + $results = $db->Execute("SELECT * FROM subscriptions WHERE subsctibe_to='$username'"); + if($results->recordcount() > 0) + return $results->getrows(); + else + return false; + } + + + + /** + * Function used to get user field + * @ param INT userid + * @ param FIELD name + */ + function get_user_field($uid,$field) + { + global $db; + $results = $db->select('users',$field,"userid='$uid'"); + + if($db->num_rows>0) + { + return $results[0]; + }else{ + return false; + } + }function get_user_fields($uid,$field){return $this->get_user_field($uid,$field);} + + + /** + * Function used to get user level and its details + * @param INT userid + */ + function get_user_level($uid) + { + global $db; + if(!$uid) + $uid = userid(); + $level = $this->get_user_field($uid,'level'); + $results = $db->select('user_levels','*'," user_level_id='".$level['level']."'"); + if($db->num_rows == 0) + //incase user level is not valid, it will consider it as registered user + $u_level['user_level_id'] = 3; + else + $u_level = $results[0]; + + //Now Getting Access Details + $access_results = $db->select("user_levels_permissions","*", + "user_level_id = '".$u_level['user_level_id']."'"); + $a_results = $access_results[0]; + + //Now Merging the two arrays + $user_level = array_merge($u_level,$a_results); + + return $user_level; + } + + + /** + * Function used to get all levels + * @param : filter + */ + function get_levels($filter=NULL) + { + global $db; + $results = $db->select("user_levels","*"); + if($db->num_rows > 0) + { + return $results; + }else{ + return false; + } + } + + + /** + * Function used to get level details + * @param : level_id INT + */ + function get_level_details($lid) + { + global $db; + $results = $db->select("user_levels","*"," user_level_id='$lid' "); + if($db->num_rows > 0 ) + { + return $results[0]; + }else{ + e("Cannot find level"); + return false; + } + } + + /** + * Function used to get users of particular level + * @param : level_id + * @param : count BOOLEAN (if TRUE it will return NUMBERS) + */ + function get_level_users($id,$count=FALSE) + { + global $db; + $results = $db->select("users","level"," level='$id'"); + if($db->num_rows>0) + { + if($count) + return $db->num_rows; + else + return $results; + }else{ + return 0; + } + } + + + /** + * Function used to add user level + */ + function add_user_level($array) + { + global $db; + if(!is_array($array)) + $array = $_POST; + $level_name = mysql_clean($array['level_name']); + if(empty($level_name)) + e("Please enter level nane"); + else + { + $db->insert("user_levels",array('user_level_name'),array($level_name)); + $iid = $db->insert_id(); + + $fields_array[] = 'user_level_id'; + $value_array[] = $iid; + foreach($this->get_access_type_list() as $access => $name) + { + $fields_array[] = $access; + $value_array[] = $array[$access] ? $array[$access] : 'no'; + } + $db->insert("user_levels_permissions",$fields_array,$value_array); + } + } + + /** + * Function usewd to get level permissions + */ + function get_level_permissions($id) + { + global $db; + $results = $db->select("user_levels_permissions","*"," user_level_id = '$id'"); + if($db->num_rows>0) + return $results[0]; + else + return false; + } + + /** + * Function used to get custom permissions + */ + function get_access_type_list() + { + return $this->access_type_list; + } + + /** + * Function used to add new custom permission + */ + function add_access_type($access,$name) + { + if(!empty($access) && !empty($name)) + $this->access_type_list[$access] = $name; + } + + /** + * Function get access + */ + function get_access($access) + { + return $this->access_type_list[$access]; + } + + /** + * Function used to update user level + * @param INT level_id + * @param ARRAY perm_level + */ + function update_user_level($id,$array) + { + global $db; + if(!is_array($array)) + $array = $_POST; + + //First Checking Level + $level = $this->get_level_details($id); + if($level) + { + foreach($this->get_access_type_list() as $access => $name) + { + $fields_array[] = $access; + $value_array[] = $array[$access]; + } + + //Checking level Name + if(!empty($array['level_name'])) + { + $level_name = mysql_clean($array['level_name']); + //Upadting Now + $db->update("user_levels",array("user_level_name"),array($level_name)," user_level_id = '$id'"); + } + + //Updating Permissions + $db->update("user_levels_permissions",$fields_array,$value_array," user_level_id = '$id'"); + + e("Level has been updated",m); + return true; + }else{ + return false; + } + } + + + /** + * Function used to delete user levels + * @param INT level_id + */ + function delete_user_level($id) + { + global $db; + $level_details = $this->get_level_details($id); + $de_level = $this->get_level_details(3); + if($level_details) + { + //CHeck if leve is deleteable or not + if($level_details['user_level_is_default']=='no') + { + $db->delete("user_levels",array("user_level_id"),$id); + $db->delete("user_levels_permissions",array("user_level_id"),$id); + e("User level has been deleted, + all users of this level has been transfered to '".$de_level['user_level_name']."' "); + + $db->update("users",array("level"),array(3)," level='$id'"); + return true; + + }else{ + e("This level is not deletable"); + return false; + } + } + } + + /** + * Function used to add comment on users profile + */ + function add_comment($comment,$obj_id,$reply_to=NULL,$type='c') + { + global $myquery; + if(!$this->user_exists($obj_id)) + e("User does not exists"); + return $myquery->add_comment($comment,$obj_id,$reply_to,$type); + } + + + /** + * Function used to get number of videos uploaded by user + * @param INT userid + * @param Conditions + */ + function get_user_vids($uid,$cond=NULL,$count_only=false) + { + global $db; + if($cond!=NULL) + $cond = " AND $cond "; + + $results = $db->select("video","*"," userid = '$uid' $cond"); + if($db->num_rows > 0) + { + if($count_only) + return $db->num_rows; + else + return $results[0]; + }else{ + return false; + } + } + + + /** + * Function used to get logged in username + */ + function get_logged_username() + { + return $this->get_user_fields(user_id(),'username'); + } +} +?> \ No newline at end of file diff --git a/upload/includes/common.php b/upload/includes/common.php new file mode 100644 index 00000000..f74b64bb --- /dev/null +++ b/upload/includes/common.php @@ -0,0 +1,407 @@ +Get_Website_Details(); + $email_data = $myquery->Get_Email_Settings(); + $cbplugin = new CBPlugin(); + $eh = new EH(); + $lang_obj = new language; + $sess = new Session(); + $cblog = new CBLogs(); + $swfobj = new SWFObject(); + $imgObj = new ResizeImage(); + + +//Initializng Userquery class +$userquery->init(); + + +//Holds Advertisment IDS that are being Viewed + $ads_array = array(); +// Report all errors + +define('DEBUG_LEVEL', $row['debug_level']); +if(DEBUG_LEVEL == 1) +{ + error_reporting(E_ALL); + ini_set('display_errors', '1'); +} +elseif(DEBUG_LEVEL == 2) +{ + error_reporting(E_ALL ^ E_NOTICE); + ini_set('display_errors', '1'); +} +else +{ + error_reporting(0); + ini_set('display_errors', '0'); +} + +error_reporting(E_ALL ^ E_NOTICE); + ini_set('display_errors', '1'); + +//Website Details + + define('CB_VERSION', $row['version']); + define('TITLE',$row['site_title']); + define('SLOGAN',$row['site_slogan']); + $sitelang = @$_COOKIE['sitelang']; + + function ValidLang($sitelang){ + global $languages; + if(empty($languages[$sitelang])) { + return false; + }else { + return true; + } + } + + if (!isset($sitelang) || !ValidLang($sitelang)) + { + define('LANG',$row['default_site_lang']); + setcookie('sitelang', $row['default_site_lang'], time()+315360000, '/'); + } + else + { + define('LANG',$sitelang); + } + + + //Seo URLS + + define('SEO',$row['seo']); //Set yes / no + + //Registration & Email Settings + + define('EMAIL_VERIFICATION',$row['email_verification']); + define('ALLOW_REGISTERATION',$row['allow_registeration']); + define('WEBSITE_EMAIL',$email_data['website_email']); + define('SUPPORT_EMAIL',$email_data['support_email']); + define('WELCOME_EMAIL',$email_data['welcome_email']); + @define('VIDEO_REQUIRE_LOGIN',$row['video_require_login']); + define('ACTIVATION',$row['activation']); + + //Listing Of Videos , Channels + + define('VLISTPP',$row['videos_list_per_page']); //Video List Per page + define('VLISTPT',$row['videos_list_per_tab']); //Video List Per tab + define('CLISTPP',$row['channels_list_per_page']); //Channels List Per page + define('CLISTPT',$row['channels_list_per_tab']); //Chaneels List Per tab + define('GLISTPP',$row['groups_list_per_page']); //Groups List Per page + define('SLISTPP',$row['search_list_per_page']); //Search Results List Per page + define('RVLIST',$row['recently_viewed_limit']); //Search Results List Per page + + //Video Options + + define('VIDEO_COMMENT',$row['video_comments']); + define('VIDEO_RATING',$row['video_rating']); + define('COMMENT_RATING',$row['comment_rating']); + define('VIDEO_DOWNLOAD',$row['video_download']); + define('VIDEO_EMBED',$row['video_embed']); + + + define('BASEDIR',$Cbucket->BASEDIR); + if(!file_exists(BASEDIR.'/index.php')) + die('Basedir is incorrect, please set the correct basedir value in \'config\' table'); + + define('BASEURL',$row['baseurl']); //Direct Path To Script ie http://yourwebsite.com/subdi + + + define('TEMPLATEFOLDER','styles'); //Template Folder Name, usually STYLES + + if($row['allow_template_change'] == 1){ + $sitestyle = @$_COOKIE['sitestyle']; + if (!$sitestyle || !$myquery->IsTemplate($sitestyle)) + { + define('TEMPLATE',$row['template_dir']); + setcookie('sitestyle', $row['template_dir'], time()+315360000, '/'); + } + else + { + define('TEMPLATE',$sitestyle); + } + }else{ + define('TEMPLATE',$row['template_dir']); + } + +// Define Lang Select & Style Select + + define('ALLOW_LANG_SELECT',$row['allow_language_change']); + define('ALLOW_STYLE_SELECT',$row['allow_template_change']); + + define('FLVPLAYER',$row['player_file']); + define('SUBTITLE',$row['code_dev']); + define('JSDIR','js'); //Javascript Directory Name + define('ADMINDIR','admin_area'); //Admin Accissble Folder + define('MODULEDIR',BASEDIR.'/modules'); //Modules Directory + +//DIRECT PATHS OF VIDEO FILES + define('FILES_DIR',BASEDIR.'/files'); + define('VIDEOS_DIR',FILES_DIR.'/videos'); + define('THUMBS_DIR',FILES_DIR.'/thumbs'); + define('ORIGINAL_DIR',FILES_DIR.'/original'); + define('TEMP_DIR',FILES_DIR.'/temp'); + define('CON_DIR',FILES_DIR.'/conversion_queue'); + +//DIRECT URL OF VIDEO FILES + define('FILES_URL',BASEURL.'/files'); + define('VIDEOS_URL',FILES_URL.'/videos'); + define('THUMBS_URL',FILES_URL.'/thumbs'); + define('ORIGINAL_URL',FILES_URL.'/original'); + define('TEMP_URL',FILES_URL.'/temp'); + + //Required Settings For Video Converion + + define('VBRATE', $row['vbrate']); + define('SRATE', $row['srate']); + define('SBRATE', $row['sbrate']); + define('R_HEIGHT', $row['r_height']); + define('R_WIDTH', $row['r_width']); + define('RESIZE', $row['resize']); + define('KEEP_ORIGINAL', $row['keep_original']); + define('MAX_UPLOAD_SIZE', $row['max_upload_size']); + define('THUMB_HEIGHT', $row['thumb_height']); + define('THUMB_WIDTH', $row['thumb_width']); + define('FFMPEG_TYPE', $row['ffmpeg_type']); + if(FFMPEG_TYPE == 's'){ + define('FFMPEG_BINARY', MODULEDIR.'/encoders/ffmpeg'); + }else{ + define('FFMPEG_BINARY', $row['ffmpegpath']); + } + define('FFMPEG_FLVTOOLS_BINARY', $row['flvpath']); + define('PHP_PATH', $row['php_path']); + define('FFMPEG_MENCODER_BINARY', $row['mencoderpath']); + define('FFMPEG_MPLAYER_BINARY', $row['mplayerpath']); + + //Defining Plugin Directory + define('PLUG_DIR',BASEDIR.'/plugins'); + define('PLUG_URL',BASEURL.'/plugins'); + + + define('ALLOWED_CATEGORIES',3); + + define('MAX_COMMENT_CHR',$Cbucket->configs['max_comment_chr']); + define('USER_COMMENT_OWN',$Cbucket->configs['user_comment_own']); + + //Assigning Smarty Tags & Values + include 'functions.php'; + include 'plugins_functions.php'; + require BASEDIR.'/includes/templatelib/Template.class.php'; + require BASEDIR.'/includes/classes/template.class.php'; + require BASEDIR.'/includes/active.php'; + require BASEDIR.'/includes/defined_links.php'; + require_once('email_templates/template_writer.php'); + include(BASEDIR.'/lang/'.LANG.'/lang.php'); + + $is_admin = $userquery->admin_check(); + if ($is_admin == 1) + { + Assign('is_admin',$is_admin); + } + + $thisurl = curPageURL(); + Assign('THIS_URL', $thisurl); + + Assign('CB_VERSION',CB_VERSION); + Assign('FFMPEG_FLVTOOLS_BINARY',FFMPEG_FLVTOOLS_BINARY); + Assign('FFMPEG_MPLAYER_BINARY',FFMPEG_MPLAYER_BINARY); + Assign('PHP_PATH',PHP_PATH); + Assign('FFMPEG_BINARY',FFMPEG_BINARY); + Assign('FFMPEG_MENCODER_BINARY',FFMPEG_MENCODER_BINARY); + Assign('js',BASEURL.'/'.JSDIR); + Assign('title',TITLE); + Assign('slogan',SLOGAN); + Assign('flvplayer',FLVPLAYER); + Assign('avatardir',BASEURL.'/images/avatars'); + Assign('whatis',$row['whatis']); + Assign('category_thumbs',BASEURL.'/images/category_thumbs'); + Assign('video_thumbs',THUMBS_URL); + //Assign('ads',$ads); + Assign('meta_keywords',$row['keywords']); + Assign('meta_description',$row['description']); + Assign('email_verification',EMAIL_VERIFICATION); + Assign('group_thumb',BASEURL.'/images/groups_thumbs'); + Assign('bg_dir',BASEURL.'/images/backgrounds'); + Assign('captcha_type',$row['captcha_type']); + Assign('languages',$languages); + + Assign('module_dir',MODULEDIR); + + Assign('VIDEOS_URL',VIDEOS_URL); + Assign('THUMBS_URL',THUMBS_URL); + Assign('PLUG_URL',BASEURL.'/plugins'); + +//Remote and Embed + Assign('remoteUpload',$row['remoteUpload']); + Assign('embedUpload',$row['embedUpload']); + +//Video Options + Assign('video_comment',$row['video_comments']); + Assign('video_rating',$row['video_rating']); + Assign('comment_rating',$row['comment_rating']); + Assign('video_download',$row['video_download']); + Assign('video_embed',$row['video_embed']); + + +//Assign Lang + $LANG = $lang_obj->lang_phrases(); + Assign('LANG',$LANG); + Assign('langf',LANG); + Assign('lang_count',count($languages)); + +//Assign Footer + + Assign('lang_changer', $row['allow_language_change']); + Assign('template_changer', $row['allow_template_change']); + Assign('current_template', TEMPLATE); + +//Getting Template List (admin area) + $sql = "SELECT * from template"; + $rs = $db->Execute($sql); + $templates = $rs->getrows(); + + // sort user template list (fwhite / February 05, 2009) + foreach ($templates as $key => $temp_row) { + $temp_name[$key] = $temp_row[1]; + } + + // Sort the data with name ascending + // Add data as the last parameter, to sort by the common key + array_multisort($temp_name, SORT_ASC, $templates); + Assign('templates', $templates); + +//Assign Player Div Id + Assign('player_div_id',$row['player_div_id']); + +//Asigning Page + Assign('page',PAGE); + +//Add Modules +require('modules.php'); + + +//Checking what permissions do logged in user have +if(user_id()) +{ + $userquery->permission = $userquery->get_user_level(userid()); +} + +/* +REGISTER OBJECTS FOR SMARTY +*/ + +$Smarty->assign_by_ref('pages', $pages); +$Smarty->assign_by_ref('myquery', $myquery); +$Smarty->assign_by_ref('userquery', $userquery); +$Smarty->assign_by_ref('signup', $signup); +$Smarty->assign_by_ref('Upload', $Upload); +$Smarty->assign_by_ref('groupsObj', new groups()); +$Smarty->assign_by_ref('Stats', $stats); +$Smarty->assign_by_ref('db', $db); +$Smarty->assign_by_ref('adsObj', $adsObj); +$Smarty->assign_by_ref('formObj', $formObj); +$Smarty->assign_by_ref('Cbucket', $Cbucket);$Smarty->assign_by_ref('ClipBucket', $Cbucket); +$Smarty->assign_by_ref('eh', $eh); +$Smarty->assign_by_ref('lang_obj', $lang_obj); + + +/* +REGISERTING FUNCTION FOR SMARTY TEMPLATES +*/ + + +$Smarty->register_function('AD','getAd'); +$Smarty->register_function('get_thumb','getSmartyThumb'); +$Smarty->register_function('getThumb','getSmartyThumb'); +$Smarty->register_function('videoLink','videoSmartyLink'); +$Smarty->register_function('pullRating','pullSmartyRating'); +$Smarty->register_function('ANCHOR','ANCHOR'); +$Smarty->register_function('FUNC','FUNC'); +$Smarty->register_modifier('SetTime','SetTime'); +$Smarty->register_modifier('getname','getname'); +$Smarty->register_modifier('getext','getext'); +$Smarty->register_modifier('form_val','form_val'); +$Smarty->register_function('avatar','avatar'); +$Smarty->register_function('load_form','load_form'); +$Smarty->register_function('get_all_video_files',get_all_video_files_smarty); +$Smarty->register_function('input_value','input_value'); + +$Smarty->register_function('userid','userid'); +$Smarty->register_function('FlashPlayer','flashPlayer'); + + +$Smarty->register_modifier('get_thumb_num','get_thumb_num'); +?> \ No newline at end of file diff --git a/upload/includes/config.inc.php b/upload/includes/config.inc.php new file mode 100644 index 00000000..947783ba --- /dev/null +++ b/upload/includes/config.inc.php @@ -0,0 +1,51 @@ +logincheck2()){ +Assign('logged_user',$_SESSION['username']); +Assign('new_msgs',$userquery->GetNewMsgs($_SESSION['username'])); +} + +//Checking Website is closed or not +if($row['closed'] == 1){ + + $msg = $row['closed_msg']; + + if($_SESSION['admin'] !='') + $msg = 'Attention: Site in Offline Mode'; + + Assign('msg',$msg); + Assign('subtitle','Site Closed'); + if($_SESSION['admin'] ==''){ + Template('header.html'); + Template('message.html'); + Template('footer.html'); + exit(); + } +} +$AdminArea = false; +include('plugins.php'); + +//Assigning JS Files +Assign('jsArray',$Cbucket->JSArray); +//Assigning Module Files +Assign('module_list',$Cbucket->moduleList); + +?> \ No newline at end of file diff --git a/upload/includes/configs/index.php b/upload/includes/configs/index.php new file mode 100644 index 00000000..403f2e18 --- /dev/null +++ b/upload/includes/configs/index.php @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/upload/includes/conversion.conf.php b/upload/includes/conversion.conf.php new file mode 100644 index 00000000..d4b89057 --- /dev/null +++ b/upload/includes/conversion.conf.php @@ -0,0 +1,171 @@ +Get_Website_Details(); + $email_data = $myquery->Get_Email_Settings(); + $ads = $myquery->Get_Advertisments(); + +//Website Details + + define('TITLE',$row['site_title']); + define('SLOGAN',$row['site_slogan']); + + //Seo URLS + + define('SEO',$row['seo']); //Set yes / no + + //Required Modules and Their Paths (Editable In Admin Panel) + + define('FFMPEG_BINARY', $row['ffmpegpath']); + define('FFMPEG_FLVTOOLS_BINARY', $row['flvpath']); + define('FFMPEG_MENCODER_BINARY', $row['mencoderpath']); + define('FFMPEG_MPLAYER_BINARY', $row['mplayerpath']); + define('PHP_PATH', $row['php_path']); + + //Registration & Email Settings + + define('EMAIL_VERIFICATION',$row['email_verification']); + define('ALLOW_REGISTERATION',$row['allow_registeration']); + define('WEBSITE_EMAIL',$email_data['website_email']); + define('SUPPORT_EMAIL',$email_data['support_email']); + define('WELCOME_EMAIL',$email_data['welcome_email']); + define('VIDEO_REQUIRE_LOGIN',@$row['video_require_login']); + define('ACTIVATION',$row['activation']); + + //Listing Of Videos , Channels + + define('VLISTPP',$row['videos_list_per_page']); //Video List Per page + define('VLISTPT',$row['videos_list_per_tab']); //Video List Per tab + define('CLISTPP',$row['channels_list_per_page']); //Channels List Per page + define('CLISTPT',$row['channels_list_per_tab']); //Chaneels List Per tab + define('GLISTPP',$row['groups_list_per_page']); //Groups List Per page + + //Video Options + + define('VIDEO_COMMENT',$row['video_comments']); + define('VIDEO_RATING',$row['video_rating']); + define('COMMENT_RATING',$row['comment_rating']); + define('VIDEO_DOWNLOAD',$row['video_download']); + define('VIDEO_EMBED',$row['video_embed']); + + //Required Settings For Video Converion + + define('VBRATE', $row['vbrate']); + define('SRATE', $row['srate']); + define('SBRATE', $row['sbrate']); + define('R_HEIGHT', $row['r_height']); + define('R_WIDTH', $row['r_width']); + define('RESIZE', $row['resize']); + define('KEEP_ORIGINAL', $row['keep_original']); + define('MAX_UPLOAD_SIZE', $row['max_upload_size']); + define('THUMB_HEIGHT', $row['thumb_height']); + define('THUMB_WIDTH', $row['thumb_width']); + define('FFMPEG_TYPE', $row['ffmpeg_type']); + if(FFMPEG_TYPE == 's'){ + define('FFMPEG_BINARY', MODULEDIR.'/encoders/ffmpeg'); + }else{ + define('FFMPEG_BINARY', $row['ffmpegpath']); + } + define('FFMPEG_FLVTOOLS_BINARY', $row['flvpath']); + define('PHP_PATH', $row['php_path']); + define('FFMPEG_MENCODER_BINARY', $row['mencoderpath']); + define('FFMPEG_MPLAYER_BINARY', $row['mplayerpath']); + + //Required Paths Relative and Direct (Editable In Admin Panel) + + if(is_dir($row['basedir'])){ + define('BASEDIR',$row['basedir']); + }else{ + define('BASEDIR',dirname(__FILE__).'/..'); + } + define('BASEURL',$row['baseurl']); //Direct Path To Script ie http://yourwebsite.com/subdir + + define('TEMPLATEFOLDER','styles'); //Template Folder Name, usually STYLES + define('TEMPLATE',$row['template_dir']); //Select Any Template Name, usually 'clipbucketblue' + define('FLVPLAYER',$row['player_file']); //Select FLV Player For Your Script + define('JSDIR','js'); //Javascript Directory Name + define('ADMINDIR','admin_area'); //Admin Accissble Folder + define('MODULEDIR',BASEDIR.'/modules'); //Modules Directory + + //DIRECT PATHS OF VIDEO FILES + define('FILES_DIR',BASEDIR.'/files'); + define('VIDEOS_DIR',FILES_DIR.'/videos'); + define('THUMBS_DIR',FILES_DIR.'/thumbs'); + define('ORIGINAL_DIR',FILES_DIR.'/original'); + define('TEMP_DIR',FILES_DIR.'/temp'); + + //DIRECT URL OF VIDEO FILES + define('FILES_URL',BASEURL.'/files'); + define('VIDEOS_URL',FILES_URL.'/videos'); + define('THUMBS_URL',FILES_URL.'/thumbs'); + define('ORIGINAL_URL',FILES_URL.'/original'); + define('TEMP_URL',FILES_URL.'/temp'); + + //Do No Edit Below This Line + + define('TEMPLATEDIR',BASEDIR.'/'.TEMPLATEFOLDER.'/'.TEMPLATE); + define('TEMPLATEURL',BASEURL.'/'.TEMPLATEFOLDER.'/'.TEMPLATE); + define('LAYOUT',TEMPLATEDIR.'/layout'); + define('ADMINLAYOUT',BASEDIR.'/'.ADMINDIR.'/'.TEMPLATEFOLDER.'/'.TEMPLATE.'/layout'); + + //Assigning Smarty Tags & Values + + require BASEDIR.'/includes/templatelib/Template.class.php'; + require BASEDIR.'/includes/classes/template.class.php'; + require BASEDIR.'/includes/classes/TConfig.php'; + require BASEDIR.'/includes/classes/TError.php'; + require BASEDIR.'/includes/active.php'; + require BASEDIR.'/includes/defined_links.php'; + + $SYSTEM_OS = $row['sys_os'] ? $row['sys_os'] : 'linux'; + + //Including FFMPEG CLASS + if($SYSTEM_OS=='linux') + { + if($row['con_modules_type'] == 0){ + require_once(BASEDIR.'/includes/classes/conversion/ffmpeg.class.php'); + }else{ + require_once(BASEDIR.'/includes/classes/conversion/multi.class.php'); + } + }else{ + require_once(BASEDIR.'/includes/classes/conversion/ffmpeg.win32.php'); + } + +?> \ No newline at end of file diff --git a/upload/includes/dbconnect.php b/upload/includes/dbconnect.php new file mode 100644 index 00000000..3f4bca82 --- /dev/null +++ b/upload/includes/dbconnect.php @@ -0,0 +1,42 @@ +debug = false; + $db->charpage = 'cp_utf8'; + $db->charset = 'utf8'; + $db->Execute("set names 'utf8'"); + $db->Execute("set COLLATION_CONNECTION = 'utf8_general_ci'"); + if(!$db->Connect($DBHOST, $DBUSER, $DBPASS, $DBNAME)) + { + exit($db->ErrorMsg()); + } + $db->Connect($DBHOST, $DBUSER, $DBPASS, $DBNAME); + +?> \ No newline at end of file diff --git a/upload/includes/define_php_links.php b/upload/includes/define_php_links.php new file mode 100644 index 00000000..4440e498 --- /dev/null +++ b/upload/includes/define_php_links.php @@ -0,0 +1,59 @@ +','?','[',']','\\',';',"'",',','.','/','*','+','~','`','='); + $entities_replace = array('-','-','','','','','','','','','','','','','','','','','','','','','','','',''); + $clean_text = str_replace($entities_match, $entities_replace, $text); + if ( $clean_text != '' ) + $slash = ( $slash ) ? '/' : NULL; + return $slash . $clean_text; +} + + if($seo_urls == 'yes'){ + + + + @define(compose_msg_link,'/message/compose'); + @define(login_success,'/login/success'); + @define(logout_success,'/logout/success'); + @define(signup_success,'/signup/success'); + @define(signup_link,'/signup.php'); + @define(myaccount_link,'/myaccount'); + @define(videos_link,'/videos'); + @define(view_group_link,'/group/view/'); + @define(user_account_link,'/manage/account'); + @define(search_result,'/search/result'); + //@define(edit_group_link,'/manage/group/edit/'); + @define(edit_group_link,'/edit_group.php?url='); + @define(admin_link,'/admin_area/'); + + + + }else{ + + @define(compose_msg_link,'/compose.php'); + @define(login_success,'/login_success.php'); + @define(logout_success,'/logout_success.php'); + @define(signup_success,'/signup_success.php'); + @define(signup_link,'/signup.php'); + @define(myaccount_link,'/myaccount.php'); + @define(videos_link,'/videos.php'); + @define(view_group_link,'/view_group.php?url='); + @define(user_account_link,'/user_account.php'); + @define(search_result,'/search_result.php'); + @define(edit_group_link,'/edit_group.php?url='); + @define(admin_link,'/admin_area/'); + + } +?> \ No newline at end of file diff --git a/upload/includes/defined_links.php b/upload/includes/defined_links.php new file mode 100644 index 00000000..d8848247 --- /dev/null +++ b/upload/includes/defined_links.php @@ -0,0 +1,117 @@ + \ No newline at end of file diff --git a/upload/includes/email_templates/activation_request.header.php b/upload/includes/email_templates/activation_request.header.php new file mode 100644 index 00000000..df512419 --- /dev/null +++ b/upload/includes/email_templates/activation_request.header.php @@ -0,0 +1,5 @@ + + + \ No newline at end of file diff --git a/upload/includes/email_templates/activation_request.template.php b/upload/includes/email_templates/activation_request.template.php new file mode 100644 index 00000000..43f0c97c --- /dev/null +++ b/upload/includes/email_templates/activation_request.template.php @@ -0,0 +1,14 @@ + + Click Here To Goto Activation Page + +Direct Activation +========================================== +Click Here or Copy & Paste the following link in your browser +$baseurl/activation.php?username=$username&avcode=$avcode +" + ?> + \ No newline at end of file diff --git a/upload/includes/email_templates/email_verify.header.php b/upload/includes/email_templates/email_verify.header.php new file mode 100644 index 00000000..84c553f2 --- /dev/null +++ b/upload/includes/email_templates/email_verify.header.php @@ -0,0 +1,5 @@ + + + \ No newline at end of file diff --git a/upload/includes/email_templates/email_verify.template.php b/upload/includes/email_templates/email_verify.template.php new file mode 100644 index 00000000..f5107e99 --- /dev/null +++ b/upload/includes/email_templates/email_verify.template.php @@ -0,0 +1,21 @@ + + Click Here + +$baseurl/activation.php?username=$username&avcode=$avcode + +==================== +Regards +$title" + ?> + \ No newline at end of file diff --git a/upload/includes/email_templates/index.php b/upload/includes/email_templates/index.php new file mode 100644 index 00000000..403f2e18 --- /dev/null +++ b/upload/includes/email_templates/index.php @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/upload/includes/email_templates/share_video.header.php b/upload/includes/email_templates/share_video.header.php new file mode 100644 index 00000000..63174f80 --- /dev/null +++ b/upload/includes/email_templates/share_video.header.php @@ -0,0 +1,5 @@ + + + \ No newline at end of file diff --git a/upload/includes/email_templates/share_video.template.php b/upload/includes/email_templates/share_video.template.php new file mode 100644 index 00000000..95342da5 --- /dev/null +++ b/upload/includes/email_templates/share_video.template.php @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + +
    $titleshare video
    $username wants to share Video With You
    Video Description
    + $videodes
    Personal Message
    + $message +
    +
    +Thanks,
    +$username
    copyrights 2007 $title
    + +" + ?> + \ No newline at end of file diff --git a/upload/includes/email_templates/template_writer.php b/upload/includes/email_templates/template_writer.php new file mode 100644 index 00000000..119723aa --- /dev/null +++ b/upload/includes/email_templates/template_writer.php @@ -0,0 +1,105 @@ +Get_Email_Settings(); + $email_verify = $email_data['email_verification_template']; + $fp = fopen(BASEDIR."/includes/email_templates/email_verify.template.php", "w"); + fwrite($fp, ' + + '); + $email_header = $myquery->Get_Email_Settings_headers(); + $email_verify_header = $email_header['email_verification_template']; + $fp = fopen(BASEDIR."/includes/email_templates/email_verify.header.php", "w"); + fwrite($fp, ' + + '); + } + + //This Function Is Used To Write Welcome Message Template + function WriteWelcomeMessage(){ + $myquery = new myquery(); + $email_data = $myquery->Get_Email_Settings(); + $email_verify = $email_data['welcome_message_template']; + $fp = fopen(BASEDIR."/includes/email_templates/welcome_message.template.php", "w"); + fwrite($fp, ' + + '); + + $email_header = $myquery->Get_Email_Settings_headers(); + $email_verify_header = $email_header['welcome_message_template']; + $fp = fopen(BASEDIR."/includes/email_templates/welcome_message.header.php", "w"); + fwrite($fp, ' + + '); + } + + //This Function Is Used To Write Welcome Message Template + function WriteActvationRequest(){ + $myquery = new myquery(); + $email_data = $myquery->Get_Email_Settings(); + $email_verify = $email_data['activate_request_template']; + $fp = fopen(BASEDIR."/includes/email_templates/activation_request.template.php", "w"); + fwrite($fp, ' + + '); + + $email_header = $myquery->Get_Email_Settings_headers(); + $email_verify_header = $email_header['activate_request_template']; + $fp = fopen(BASEDIR."/includes/email_templates/activation_request.header.php", "w"); + fwrite($fp, ' + + '); + } + + //This Function Is Used To Write Share Video Template + function WriteShareVideo(){ + $myquery = new myquery(); + $email_data = $myquery->Get_Email_Settings(); + $email_verify = $email_data['share_video_template']; + $fp = fopen(BASEDIR."/includes/email_templates/share_video.template.php", "w"); + fwrite($fp, ' + + '); + + $email_header = $myquery->Get_Email_Settings_headers(); + $email_verify_header = $email_header['share_video_template']; + $fp = fopen(BASEDIR."/includes/email_templates/share_video.header.php", "w"); + fwrite($fp, ' + + '); + } + +?> \ No newline at end of file diff --git a/upload/includes/email_templates/welcome_message.header.php b/upload/includes/email_templates/welcome_message.header.php new file mode 100644 index 00000000..79af96f1 --- /dev/null +++ b/upload/includes/email_templates/welcome_message.header.php @@ -0,0 +1,5 @@ + + + \ No newline at end of file diff --git a/upload/includes/email_templates/welcome_message.template.php b/upload/includes/email_templates/welcome_message.template.php new file mode 100644 index 00000000..9923bd53 --- /dev/null +++ b/upload/includes/email_templates/welcome_message.template.php @@ -0,0 +1,17 @@ + + Upload Videos +-> Share Videos +-> Make Friends and Send Messages +-> Now You Have Your Own Channel + +To Access Your Account Please Click Here and login + +Thank You For Joining Us, +Regards +$title Team" + ?> + \ No newline at end of file diff --git a/upload/includes/email_templates/welcome_messege.header.php b/upload/includes/email_templates/welcome_messege.header.php new file mode 100644 index 00000000..79af96f1 --- /dev/null +++ b/upload/includes/email_templates/welcome_messege.header.php @@ -0,0 +1,5 @@ + + + \ No newline at end of file diff --git a/upload/includes/email_templates/welcome_messege.template.php b/upload/includes/email_templates/welcome_messege.template.php new file mode 100644 index 00000000..bef68e43 --- /dev/null +++ b/upload/includes/email_templates/welcome_messege.template.php @@ -0,0 +1,17 @@ + + Upload Videos +-> Share Videos +-> Make Friends and Send Messeges +-> Now You Have Your Own Channel + +To Access Your Account Please Click Here and login + +Thank You For Joining Us, +Regards +$title Team" + ?> + \ No newline at end of file diff --git a/upload/includes/flv_player.php b/upload/includes/flv_player.php new file mode 100644 index 00000000..c5bcb02e --- /dev/null +++ b/upload/includes/flv_player.php @@ -0,0 +1,59 @@ +GetPlayerConfig()); + } +} + +?> \ No newline at end of file diff --git a/upload/includes/functions.php b/upload/includes/functions.php new file mode 100644 index 00000000..3addee33 --- /dev/null +++ b/upload/includes/functions.php @@ -0,0 +1,1910 @@ + + window.location = "'.$url.'" + '; + } + + //Simple Template Displaying Function + + function Template($template,$layout=true){ + global $admin_area; + if($layout) + DoTemplate::display(LAYOUT.'/'.$template); + else + DoTemplate::display($template); + + if($template == 'footer.html' && $admin_area !=TRUE){ + DoTemplate::display(BASEDIR.'/includes/templatelib/'.$template); + } + if($template == 'header.html'){ + DoTemplate::display(BASEDIR.'/includes/templatelib/'.$template); + } + } + + function Assign($name,$value){ + DoTemplate::assign($name,$value); + } + + //Funtion of Random String + function RandomString($length) + { + // Generate random 32 charecter string + $string = md5(time()); + + // Position Limiting + $highest_startpoint = 32-$length; + + // Take a random starting point in the randomly + // Generated String, not going any higher then $highest_startpoint + $randomString = substr($string,rand(0,$highest_startpoint),$length); + + return $randomString; + +} + + + //This Function Is Used To Display Tags Cloud + function TagClouds($cloudquery) + { + $tags = array(); + $cloud = array(); + $query = mysql_query($cloudquery); + while ($t = mysql_fetch_array($query)) + { + $db = explode(' ', $t[0]); + while (list($key, $value) = each($db)) + { + @$keyword[$value] += 1; + } + } + if (is_array(@$keyword)) + { + $minFont = 11; + $maxFont = 22; + $min = min(array_values($keyword)); + $max = max(array_values($keyword)); + $fix = ($max - $min == 0) ? 1 : $max - $min; + // Display the tags + foreach ($keyword as $tag => $count) + { + $size = $minFont + ($count - $min) * ($maxFont - $minFont) / $fix; + $cloud[] = '' . mysql_clean($tag) . ''; + } + $shown = join("\n", $cloud) . "\n"; + return $shown; + } + } + + // -------------RATING FUNCTION---------------- // + +function getRating($id){ + + $total = 0; + $rows = 0; + + $sel = mysql_query("SELECT * FROM video WHERE videoid = '$id'"); + if(mysql_num_rows($sel) > 0){ + $data = mysql_fetch_assoc($sel); + + //$newPerc = round($perc/5)*5; + //return $newPerc.'%'; + + $newPerc = round($data['rating']*10,2); + return $newPerc.'%'; + + } else { + + return '0%'; + + } +} + +function outOfFive($id){ + + $total = 0; + $rows = 0; + + $sel = mysql_query("SELECT * FROM video WHERE videoid = '$id'"); + if(mysql_num_rows($sel) > 0){ + $data = mysql_fetch_assoc($sel); + + return round($data['rating']/2,2); + //return round(($perc*2), 0)/2; // 3.5 + + } else { + + return '0'; + + } + + +} + +function getVotes($id){ + + $sel = mysql_query("SELECT * FROM video WHERE videoid = '$id'"); + $data = mysql_fetch_assoc($sel); + return $data['rated_by']; + +} + +function pullRating($id,$show5 = false, $showPerc = false, $showVotes = false, $static = NULL){ + global $row; + // Check if they have already voted... + $text = ''; + + $sel = mysql_query("SELECT * FROM video WHERE videoid = '$id'"); + $data = mysql_fetch_array($sel); + $voter_id = $data['voter_ids']; + @$userid = $_SESSION['userid']; + $niddle = "|"; + $niddle .= $userid; + $niddle .= "|"; + $flag = strstr($voter_id, $niddle); + if($row['user_rate_opt1'] !='yes'){ + if($data['username'] == $_SESSION['username']){ + $static = 'novote'; + } + } + if(!empty($flag) || $static == 'novote' || !isset($_SESSION['userid']) || isset($_COOKIE['has_voted_'.$id]) ){ + + + + if($show5 || $showPerc || $showVotes){ + + $text .= '

    '; + + } + + if($show5){ + $text .= 'Rated '.outOfFive($id).'/5'; + } + if($showPerc){ + $text .= ' ('.getRating($id).')'; + } + if($showVotes){ + $text .= ' ('.getVotes($id).')'; + } + + if($show5 || $showPerc || $showVotes){ + + $text .= '
    '; + + } + + + return $text.' + +
    '; + + + } else { + + if($show5 || $showPerc || $showVotes){ + + $text .= '
    '; + + } + if($show5){ + $show5bool = 'true'; + $text .= 'Rated '.outOfFive($id).'/5'; + } else { + $show5bool = 'false'; + } + if($showPerc){ + $showPercbool = 'true'; + $text .= ' ('.getRating($id).')'; + } else { + $showPercbool = 'false'; + } + if($showVotes){ + $showVotesbool = 'true'; + $text .= ' ('.getVotes($id).')'; + } else { + $showVotesbool = 'false'; + } + + if($show5 || $showPerc || $showVotes){ + + $text .= '
    '; + + } + + return $text.' + +
    '; + + } +} + + + //Function Send Email + function send_email($from,$to,$subj,$msg){ + $header = "From: ".$from." \r\n"; + $header .= "Content-Type: text/html; charset=utf-8 \r\n"; + $retval = mail ($to,$subj,$msg,$header); + if( $retval == true ){ + return true; + }else{ + return false; + } + } + + /** + * Function used to get file name + */ + function GetName($file){ + $path = explode('/',$file); + if(is_array($path)) + $file = $path[count($path)-1]; + $new_name = substr($file, 0, strrpos($file, '.')); + return $new_name; + } + + function get_elapsed_time($ts,$datetime=1) + { + if($datetime == 1) + { + $ts = date('U',strtotime($ts)); + } + $mins = floor((time() - $ts) / 60); + $hours = floor($mins / 60); + $mins -= $hours * 60; + $days = floor($hours / 24); + $hours -= $days * 24; + $weeks = floor($days / 7); + $days -= $weeks * 7; + $t = ""; + if ($weeks > 0) + return "$weeks week" . ($weeks > 1 ? "s" : ""); + if ($days > 0) + return "$days day" . ($days > 1 ? "s" : ""); + if ($hours > 0) + return "$hours hour" . ($hours > 1 ? "s" : ""); + if ($mins > 0) + return "$mins min" . ($mins > 1 ? "s" : ""); + return "< 1 min"; + } + + //Function Used TO Get Extensio Of File + function GetExt($file){ + return substr($file, strrpos($file,'.') + 1); + } + +function SetTime($sec, $padHours = true) { + + $hms = ""; + + // there are 3600 seconds in an hour, so if we + // divide total seconds by 3600 and throw away + // the remainder, we've got the number of hours + $hours = intval(intval($sec) / 3600); + + // add to $hms, with a leading 0 if asked for + $hms .= ($padHours) + ? str_pad($hours, 2, "0", STR_PAD_LEFT). ':' + : $hours. ':'; + + // dividing the total seconds by 60 will give us + // the number of minutes, but we're interested in + // minutes past the hour: to get that, we need to + // divide by 60 again and keep the remainder + $minutes = intval(($sec / 60) % 60); + + // then add to $hms (with a leading 0 if needed) + $hms .= str_pad($minutes, 2, "0", STR_PAD_LEFT). ':'; + + // seconds are simple - just divide the total + // seconds by 60 and keep the remainder + $seconds = intval($sec % 60); + + // add to $hms, again with a leading 0 if needed + $hms .= str_pad($seconds, 2, "0", STR_PAD_LEFT); + + return $hms; +} + + //Simple Validation + function isValidText($text){ + $pattern = "^^[_a-z0-9-]+$"; + if (eregi($pattern, $text)){ + return true; + }else { + return false; + } + } + + //Function Used To Validate Email + + function isValidEmail($email){ + $pattern = "^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$"; + if (eregi($pattern, $email)){ + return true; + } + else { + return false; + } + } + + + // THIS FUNCTION SETS HTMLSPECIALCHARS_DECODE IF FUNCTION DOESN'T EXIST + // INPUT: $text REPRESENTING THE TEXT TO DECODE + // $ent_quotes (OPTIONAL) REPRESENTING WHETHER TO REPLACE DOUBLE QUOTES, ETC + // OUTPUT: A STRING WITH HTML CHARACTERS DECODED + if(!function_exists('htmlspecialchars_decode')) { + function htmlspecialchars_decode($text, $ent_quotes = "") { + $text = str_replace(""", "\"", $text); + $text = str_replace("'", "'", $text); + $text = str_replace("<", "<", $text); + $text = str_replace(">", ">", $text); + $text = str_replace("&", "&", $text); + return $text; + } + } // END htmlspecialchars() FUNCTION + + //THIS FUNCTION IS USED TO LIST FILE TYPES IN FLASH UPLOAD + //INPUT FILE TYPES + //OUTPUT FILE TYPE IN PROPER FORMAT + function ListFileTypes($types){ + $types_array = preg_replace('/,/',' ',$types); + $types_array = explode(' ',$types_array); + $list = 'Video,'; + for($i=0;$i<=count($types_array);$i++){ + if($types_array[$i]!=''){ + $list .= '*.'.$types_array[$i]; + if($i!=count($types_array))$list .= ';'; + } + } + return $list; + } + + + //FUNCTION USED TO FORMAT FILE SIZE + //INPUT BYTES + //OUTPT MB , Kib + function formatfilesize( $data ) { + // bytes + if( $data < 1024 ) { + return $data . " bytes"; + } + // kilobytes + else if( $data < 1024000 ) { + return round( ( $data / 1024 ), 1 ) . "KB"; + } + // megabytes + else if($data < 1024000000){ + return round( ( $data / 1024000 ), 1 ) . " MB"; + }else{ + return round( ( $data / 1024000000 ), 1 ) . " GB"; + } + + } + + /** + * FUNCTION USED TO GET THUMBNAIL + * @param ARRAY video_details, or videoid will also work + */ + + function get_thumb($vdetails,$num='default',$multi=false,$count=false){ + global $db,$Cbucket,$myquery; + $num = $num ? $num : 'default'; + #checking what kind of input we have + if(is_array($vdetails)) + { + if(empty($vdetails['title'])) + { + #check for videoid + if(empty($vdetails['videoid']) && empty($vdetails['vid']) && empty($vdetails['videokey'])) + { + if($multi) + return $dthumb[0] = default_thumb(); + return default_thumb(); + }else{ + if(!empty($vdetails['videoid'])) + $vid = $vdetails['videoid']; + elseif(!empty($vdetails['vid'])) + $vid = $vdetails['vid']; + elseif(!empty($vdetails['videokey'])) + $vid = $vdetails['videokey']; + else + { + if($multi) + return $dthumb[0] = default_thumb(); + return default_thumb(); + } + } + } + }else{ + if(is_numeric($vdetails)) + $vid = $vdetails; + else + { + if($multi) + return $dthumb[0] = default_thumb(); + return default_thumb(); + } + } + + + #checking if we have vid , so fetch the details + if(!empty($vid)) + $vdetails = $myquery->get_video_details($vid); + + if(empty($vdetails['title'])) + { + if($multi) + return default_thumb(); + return default_thumb(); + } + + #Checking if there is any custom function for + if(count($Cbucket->custom_get_thumb_funcs)>0) + foreach($Cbucket->custom_get_thumb_funcs as $funcs) + { + if(function_exists($funcs)) + return $funcs($vdetails); + } + + #get all possible thumbs of video + $vid_thumbs = glob(THUMBS_DIR."/".$vdetails['file_name']."*"); + #replace Dir with URL + foreach($vid_thumbs as $thumb) + { + $thumb_parts = explode('/',$thumb); + $thumb_file = $thumb_parts[count($thumb_parts)-1]; + $thumbs[] = THUMBS_URL.'/'.$thumb_file; + } + + if(count($thumbs)==0) + { + if($count) + return count($thumbs); + if($multi) + return $dthumb[0] = default_thumb(); + return default_thumb(); + } + else + { + if($multi) + return $thumbs; + if($count) + return count($thumbs); + + //Now checking for thumb + if($num=='default') + { + $num = $vdetails['default_thumb']; + } + $vdetails['file_name'].'-'.$num; + $default_thumb = array_find($vdetails['file_name'].'-'.$num,$thumbs); + + if(!empty($default_thumb)) + return $default_thumb; + return $thumbs[0]; + } + + } + function GetThumb($vdetails,$num='default',$multi=false,$count=false) + { + + return get_thumb($vdetails,$num,$multi,$count); + } + + /** + * function used to get detaulf thumb of ClipBucket + */ + function default_thumb() + { + return BASEURL.'/files/thumbs/processing.jpg'; + } + + + //TEST EXCEC FUNCTION + function test_exec( $cmd ) + { + echo '
    '; + echo '

    ' . htmlentities( $cmd ) . '

    '; + + if (stristr(PHP_OS, 'WIN')) { + $cmd = $cmd; + }else{ + $cmd = "PATH=\$PATH:/bin:/usr/bin:/usr/local/bin bash -c \"$cmd\""; + } + $data = shell_exec( $cmd ); + if( $data === false ) + echo "

    FAILED: $cmd

    "; + echo '

    ' . htmlentities( $data ) . '

    '; + } + + + /** + * Function used to get video link + * @param ARRAY video details + */ + function video_link($vdetails) + { + global $myquery; + #checking what kind of input we have + if(is_array($vdetails)) + { + if(empty($vdetails['title'])) + { + #check for videoid + if(empty($vdetails['videoid']) && empty($vdetails['vid']) && empty($vdetails['videokey'])) + { + return BASEURL; + }else{ + if(!empty($vdetails['videoid'])) + $vid = $vdetails['videoid']; + elseif(!empty($vdetails['vid'])) + $vid = $vdetails['vid']; + elseif(!empty($vdetails['videokey'])) + $vid = $vdetails['videokey']; + else + return BASEURL; + } + } + }else{ + if(is_numeric($vdetails)) + $vid = $vdetails; + else + return BASEURL; + } + #checking if we have vid , so fetch the details + if(!empty($vid)) + $vdetails = $myquery->get_video_details($vid); + + if(SEO == 'yes'){ + $link = BASEURL.'/video/'.$vdetails['videokey'].'/'.SEO(clean(str_replace(' ','-',$vdetails['title']))); + }else{ + $link = BASEURL.'/watch_video.php?v='.$vdetails['videokey']; + } + return $link; + } + + + //Function That will use in creating SEO urls + function VideoLink($vdetails){ + return video_link($vdetails); + } + + /** + * FUNCTION USED TO GET ADVERTISMENT + * @param : array(Ad Code, LIMIT); + */ + function getAd($params,&$Smarty) + { + global $adsObj; + $data = $adsObj->getAd($params['place']); + return $data; + } + + /** + * FUNCTION USED TO GET THUMBNAIL, MADE FOR SMARTY + * @ param : array("FLV"); + */ + function getSmartyThumb($params,&$Smarty) + { + return get_thumb($params['vdetails'],$params['num'],$params['multi'],$params['count_only']); + } + + /** + * Function Used to format video duration + * @param : array(videoKey or ID,videok TITLE) + */ + + function videoSmartyLink($params,&$Smarty) + { + return VideoLink($params['vdetails']); + } + + /** + * FUNCTION USED TO GET VIDEO RATING IN SMARTY + * @param : array(pullRating($videos[$id]['videoid'],false,false,false,'novote'); + */ + function pullSmartyRating($param,&$Smarty) + { + return pullRating($param['id'],$param['show5'],$param['showPerc'],$aram['showVotes'],$param['static']); + } + + /** + * FUNCTION USED TO CLEAN VALUES THAT CAN BE USED IN FORMS + */ + function cleanForm($string) + { + $string = htmlspecialchars($string); + return $string; + } + function form_val($string){return cleanForm($string); } + + /** + * FUNCTION USED TO MAKE TAGS MORE PERFECT + * @Author : Arslan Hassan + * @param tags text unformatted + * returns tags formatted + */ + function genTags($tags,$sep=',') + { + //Remove fazool spaces + $tags = preg_replace(array('/ ,/','/, /'),',',$tags); + $tags = preg_replace( "`[,]+`" , ",", $tags); + $tag_array = explode($sep,$tags); + foreach($tag_array as $tag) + { + if(isValidtag($tag)) + { + $newTags[] = $tag; + } + + } + //Creating new tag string + $tagString = implode(',',$newTags); + return $tagString; + } + + /** + * FUNCTION USED TO VALIDATE TAG + * @Author : Arslan Hassan + * @param tag + * return true or false + */ + function isValidtag($tag) + { + $disallow_array = array + ('of','is','no','on','off','a','the','why','how','what','in'); + if(!in_array($tag,$disallow_array)) + return true; + else + return false; + } + + + /** + * FUNCTION USED TO GET CATEGORY LIST + */ + function getCategoryList() + { + global $db; + $sql = "SELECT * FROM category"; + return $db->GetArray($sql); + } + + + /** + * FUNCTION USED TO REGISTER ACTIONS THAT ARE TO APPLIED + * ON COMMENTS , TITLE, DESCRIPTIONS etc + */ + function register_action($name,$type=NULL) + { + global $Cbucket; + if(is_array($name)) + { + foreach($name as $key => $naam) + if(is_array($naam)) + { + foreach($naam as $name) + { + $Cbucket->actionList[$name][] = $key; + } + }else{ + + $Cbucket->actionList[$naam][] = $key; + } + }elseif($type!=NULL){ + $Cbucket->actionList[$type][] = $name; + } + } + //Function used to register function as multiple modifiers + + + + /** + * Function used to insert data in database + * @param : table name + * @param : fields array + * @param : values array + * @param : extra params + */ + function dbInsert($tbl,$flds,$vls,$ep=NULL) + { + global $db ; + $total_fields = count($flds); + $count = 0; + foreach($flds as $field) + { + $count++; + $fields_query .= $field; + if($total_fields!=$count) + $fields_query .= ','; + } + $total_values = count($vls); + $count = 0; + foreach($vls as $value) + { + $count++; + $val = mysql_clean($value); + $needle = substr($val,0,3); + + if($needle != '|f|') + $values_query .= "'".$val."'"; + else + { + $val = substr($val,3,strlen($val)); + $values_query .= "'".$val."'"; + } + + + if($total_values!=$count) + $values_query .= ','; + } + //Complete Query + $query = "INSERT INTO $tbl ($fields_query) VALUES ($values_query) $ep"; + //if(!mysql_query($query)) die(mysql_error()); + $db->Execute($query); + if(mysql_error()) die ($db->db_query.'
    '.mysql_error()); + } + + /** + * Function used to Update data in database + * @param : table name + * @param : fields array + * @param : values array + * @param : Condition params + * @params : Extra params + */ + function dbUpdate($tbl,$flds,$vls,$cond,$ep=NULL) + { + global $db ; + + $total_fields = count($flds); + $count = 0; + for($i=0;$i<$total_fields;$i++) + { + $count++; + $val = mysql_clean($vls[$i]); + $needle = substr($val,0,3); + if($needle != '|f|') + $fields_query .= $flds[$i]."='".$val."'"; + else + { + $val = substr($val,3,strlen($val)); + $fields_query .= $flds[$i]."=".$val.""; + } + if($total_fields!=$count) + $fields_query .= ','; + } + //Complete Query + $query = "UPDATE $tbl SET $fields_query WHERE $cond $ep"; + //if(!mysql_query($query)) die(mysql_error()); + $db->Execute($query); + if(mysql_error()) die ($db->db_query.'
    '.mysql_error()); + return $query; + } + + + + /** + * Function used to Delete data in database + * @param : table name + * @param : fields array + * @param : values array + * @params : Extra params + */ + function dbDelete($tbl,$flds,$vls,$ep=NULL) + { + global $db ; + $total_fields = count($flds); + $count = 0; + for($i=0;$i<$total_fields;$i++) + { + $count++; + $fields_query .= $flds[$i].'='.mysql_clean($vls[$i]); + if($total_fields!=$count) + $fields_query .= ' AND '; + } + //Complete Query + $query = "DELETE FROM $tbl WHERE $fields_query $ep"; + //if(!mysql_query($query)) die(mysql_error()); + $db->Execute($query); + if(mysql_error()) die ($db->db_query.'
    '.mysql_error()); + } + + + /** + * FUNCTION USED TO CREATE ANCHOR PLACEMENT + * these are the placement where we can add plugin's or widget's code, + * e.g if we want to display a new WYSIWYG box before comment text area + * we will create anchor before text area as {ANCHOR place='before_compose_box'} + * code will be written in plugin file and its place will point 'before_compose_box' + * then our function will get all the code for this placement and will display it + * @param : array(Ad Code, LIMIT); + */ + function ANCHOR($params,&$Smarty) + { + global $Cbucket; + //Getting List of codes to display at this anchor + $codes = $Cbucket->get_anchor_codes($params['place']); + if(!empty($codes)) + { + if(is_array($codes)) + { + foreach($codes as $code) + { + echo $code; + } + }else{ + echo $codes; + } + } + + //Getting list of function that will be performed while calling achor + $funcs = $Cbucket->get_anchor_function_list($params['place']); + + if(!empty($funcs)) + { + if(is_array($funcs)) + { + foreach($funcs as $func) + { + if(function_exists($func)) + $func(); + } + }else{ + $funcs(); + } + } + } + + /** + * FUNCTION USED TO REGISTER ANCHORS + * before_comments etc.. see complete list on http://docs.clip-bucket.com + */ + function register_anchor($name,$type=NULL) + { + global $Cbucket; + if(is_array($name)) + { + foreach($name as $key => $naam) + if(is_array($naam)) + { + foreach($naam as $name) + { + $Cbucket->anchorList[$name][] = $key; + } + }else{ + + $Cbucket->anchorList[$naam][] = $key; + } + }elseif($type!=NULL){ + $Cbucket->anchorList[$type][] = $name; + } + } + + + + /** + * FUNCTION USED TO REGISTER FUNCTION + * If you want to perform some function on + * some place, you can simple register function that will be execute where anchor points are + * placed + */ + function register_anchor_function($name,$type=NULL) + { + global $Cbucket; + if(is_array($name)) + { + foreach($name as $key => $naam) + if(is_array($naam)) + { + foreach($naam as $name) + { + $Cbucket->anchor_function_list[$name][] = $key; + } + }else{ + + $Cbucket->anchor_function_list[$naam][] = $key; + } + }elseif($type!=NULL){ + $Cbucket->anchor_function_list[$type][] = $name; + } + } + + /** + * Insert Id + */ + function get_id($code) + { + global $Cbucket; + $id = $Cbucket->ids[$code]; + if(empty($id)) $id = $code; + return $id; + } + + /** + * Set Id + */ + function set_id($code,$id) + { + global $Cbucket; + return $Cbucket->ids[$code]=$id; + } + + + /** + * Function used to add items in admin menu + * This function will insert new item in admin menu + * under given header, if the header is not available + * it will create one, ( Header means titles ie 'Plugins' 'Videos' etc) + * @param STRING $header - Could be Plugin , Videos, Users , please check + * http://docs.clip-bucket.com. for reference + * @param STRING name + * @param STRING link + * That will add new item in admin menu + */ + function add_admin_menu($header='Tool Box',$name,$link) + { + global $Cbucket; + //Gett Menu + $menu = $Cbucket->AdminMenu; + //Add New Meny + $menu[$header][$name] = $link; + $Cbucket->AdminMenu = $menu; + } + + + /** + * Function used to select data from database + */ + function dbselect($tbl,$fields='*',$cond=false,$limit=false,$order=false) + { + global $db; + $query_params = ''; + //Making Condition possible + if($cond) + $where = " WHERE "; + else + $where = false; + + $query_params .= $where; + if($where) + { + $query_params .= $cond; + } + + + + if($order) + $query_params .= " ORDER BY $order "; + if($limit) + $query_params .= " LIMIT $limit "; + + $query = " SELECT $fields FROM $tbl $query_params "; + + //Finally Executing + $data = $db->Execute($query); + $db->num_rows = $data->_numOfRows; + + //Now Get Rows and return that data + if($db->num_rows > 0) + return $data->getrows(); + else + return false; + } + + + + /** + * An easy function for erorrs and messages (e is basically short form of exception) + * I dont want to use the whole Trigger and Exception code, so e pretty works for me :D + * @param TEXT $msg + * @param TYPE $type (e for Error, m for Message + * @param INT $id Any Predefined Message ID + */ + + function e($msg=NULL,$type='e',$id=NULL) + { + global $eh; + return $eh->e($msg,$type,$id); + } + + + /** + * Function used to get subscription template + */ + function get_subscription_template() + { + global $LANG; + return $LANG['user_subscribe_message']; + } + + + /** + * Short form of print_r as pr + */ + function pr($text) + { + print_r($text); + } + + + /** + * This function is used to call function in smarty template + * This wont let you pass parameters to the function, but it will only call it + */ + function FUNC($params,&$Smarty) + { + global $Cbucket; + //Function used to call functions by + //{func namefunction_name} + // in smarty + $func=$params['name']; + if(function_exists($func)) + $func(); + } + + /** + * Function used to get userid anywhere + * if there is no user_id it will return false + */ + function user_id() + { + global $userquery; + if($userquery->userid !='') return $userquery->userid; else false; + } + //replica + function userid(){return user_id();} + + /** + * Function used to get username anywhere + * if there is no usern_name it will return false + */ + function user_name() + { + global $userquery; + return $userquery->user_name; + } + function username(){return user_name();} + + /** + * Function used to return mysql time + * @author : Fwhite + */ + function NOW() + { + return date('Y-m-d H:i:s', time()); + } + + + /** + * Function used to get Regular Expression from database + * @param : code + */ + function get_re($code) + { + global $db; + $results = $db->select("validation_re","*"," re_code='$code'"); + if($db->num_rows>0) + { + return $results[0]['re_syntax']; + }else{ + return false; + } + } + function get_regular_expression($code) + { + return get_re($code); + } + + /** + * Function used to check weather input is valid or not + * based on preg_match + */ + function check_re($syntax,$text) + { + preg_match('/'.$syntax.'/',$text,$matches); + if(!empty($matches[0])) + { + return true; + }else{ + return false; + } + } + function check_regular_expression($code,$text) + { + return check_re($code,$text); + } + + /** + * Function used to check field directly + */ + function validate_field($code,$text) + { + $syntax = get_re($code); + if(empty($syntax)) + return true; + return check_regular_expression($syntax,$text); + } + + function is_valid_syntax($code,$text) + { + return validate_field($code,$text); + } + + /** + * Function used to apply function on a value + */ + function is_valid_value($func,$val) + { + if(!function_exists($func)) + return true; + elseif(!$func($val)) + return false; + else + return true; + } + + function apply_func($func,$val) + { + if(is_array($func)) + { + foreach($func as $f) + if(function_exists($f)) + $val = $f($val); + }else{ + $val = $func($val); + } + return $val; + } + + /** + * Function used to validate YES or NO input + */ + function yes_or_no($input,$return=yes) + { + $input = strtolower($input); + if($input!=yes && $input !=no) + return $return; + else + return $input; + } + + /** + * Function used to validate category + * INPUT $cat array + */ + function validate_category($array=NULL) + { + global $myquery,$LANG; + if($array==NULL) + $array = $_POST['category']; + if(count($array)==0) + return false; + else + { + + foreach($array as $arr) + { + if($myquery->CategoryExists($arr)) + $new_array[] = $arr; + } + } + if(count($new_array)==0) + { + e($LANG['vdo_cat_err3']); + return false; + }elseif(count($new_array)>ALLOWED_CATEGORIES) + { + e(sprintf($LANG['vdo_cat_err2'],ALLOWED_CATEGORIES)); + return false; + } + + return true; + } + + + /** + * Function used to check videokey exists or not + * key_exists + */ + function vkey_exists($key) + { + global $db; + $db->select("video","videokey"," videokey='$key'"); + if($db->num_rows>0) + return true; + else + return false; + } + + /** + * Function used to check file_name exists or not + * as its a unique name so it will not let repost the data + */ + function file_name_exists($name) + { + global $db; + $results = $db->select("video","videoid,file_name"," file_name='$name'"); + + if($db->num_rows >0) + return $results[0]['videoid']; + else + return false; + } + + + + /** + * Function used to get video from downloading queue + */ + function get_queued_video() + { + global $db; + $results = $db->select("conversion_queue","*","cqueue_conversion='no'"); + $result = $results[0]; + $db->update("conversion_queue",array("cqueue_conversion"),array("p")," cqueue_id = '".$result['cqueue_id']."'"); + return $result; + } + + + + function get_video_details($vid=NULL) + { + global $myquery; + if(!$vid) + global $vid; + + return $myquery->get_video_details($vid); + } + + + + /** + * Function used to get all video files + * @param Vdetails + * @param $count_only + * @param $with_path + */ + function get_all_video_files($vdetails,$count_only=false,$with_path=false) + { + $details = get_video_file($vdetails,true,$with_path,true,$count_only); + if($count_only) + return count($details); + return $details; + } + function get_all_video_files_smarty($params,&$Smarty) + { + $vdetails = $params['vdetails']; + $count_only = $params['count_only']; + $with_path = $params['with_path']; + return get_all_video_files($vdetails,$count_only,$with_path); + } + + /** + * Function use to get video files + */ + function get_video_file($vdetails,$return_default=true,$with_path=true,$multi=false,$count_only=false) + { + # checking if there is any other functions + # available + if(is_array($Cbucket->custom_video_file_funcs)) + foreach($Cbucket->custom_video_file_funcs as $funcs) + if(function_exists($func)) + return $func($vdetails); + + #Now there is no function so lets continue as + $vid_files = glob(VIDEOS_DIR."/".$vdetails['file_name']."*"); + + #replace Dir with URL + foreach($vid_files as $file) + { + $files_part = explode('/',$file); + $video_file = $files_part[count($files_part)-1]; + + if($with_path) + $files[] = VIDEOS_URL.'/'.$video_file; + else + $files[] = $video_file; + } + + if(count($files)==0 && !$multi && !$count_only) + { + if($return_default) + { + if($with_path) + return VIDEOS_URL.'/no_video.flv'; + else + return 'no_video.flv'; + } + }else{ + if($multi) + return $files; + if($count_only) + return count($files); + return $files[0]; + } + } + + + /** + * Function used to display flash player for ClipBucket video + */ + function flashPlayer($param,&$Smarty) + { + global $Cbucket,$swfobj; + + $key = $param['key']; + $flv = $param['flv'].'.flv'; + $code = $param['code']; + $flv_url = $file; + $embed = $param['embed']; + $code = $param['code']; + $height = $param['height'] = $param['height'] ? $param['height'] : 360; + $width = $param['width'] = $param['width'] ? $param['width'] : 450; + + if(count($Cbucket->actions_play_video)>0) + { + foreach($Cbucket->actions_play_video as $funcs) + { + if(function_exists($funcs)) + { + $func_data = $funcs($param['vdetails']); + } + if($func_data) + return $func_data; + } + } + + #checking video file + $file = get_video_file($param['vdetails']); + + + + //Getting Player + $player = get_player(); + $swfobj->playerFile = BASEURL.'/player/'.FLVPLAYER; + $swfobj->FlashObj(); + //Writing Param + $swfobj->addParam('allowfullscreen','true'); + $swfobj->addParam('allowscriptaccess','always'); + $swfobj->addParam('quality','high'); + $swfobj->addVar('baseurl',BASEURL); + $swfobj->addVar('video',get_video_file($param['vdetails'],false,true)); + + if(!empty($flv_url) && GetExt($flv_url)=='flv'){ + $swfobj->addVar('file_url',urldecode($flv_url)); + }else{ + $swfobj->addVar('file_url',$file ); + } + $swfobj->CreatePlayer(); + return $swfobj->code; + } + + /** + * Function used to get player from website settings + */ + function get_player() + { + global $Cbucket; + return $Cbucket->configs['player_file']; + } + + + /** + * Function used to get user avatar + * @param ARRAY $userdetail + * @param SIZE $int + */ + function avatar($param,&$Smarty) + { + global $userquery; + $udetails = $param['details']; + $size = $param['size']; + $uid = $param['uid']; + return $userquery->avatar($udetails,$size,$uid); + } + + + /** + * This funcion used to call function dynamically in smarty + */ + function load_form($param,&$Smarty) + { + $func = $param['name']; + if(function_exists($func)) + return $func($param); + } + + + + /** + * Function used to add custom upload fields + * In this you will provide an array that has a complete + * details of the field such as 'name',validate_func etc + * please check docs.clip-bucket.com for "how to add custom upload field" + */ + function register_custom_upload_field($array) + { + global $Upload; + $name = key($array); + if(is_array($array) && !empty($array[$name]['name'])) + { + foreach($array as $key => $arr) + $Upload->custom_upload_fields[$key] = $arr; + } + } + + /** + * Function used to add custom form fields + * In this you will provide an array that has a complete + * details of the field such as 'name',validate_func etc + * please check docs.clip-bucket.com for "how to add custom form field" + */ + function register_custom_form_field($array) + { + global $Upload; + $name = key($array); + if(is_array($array) && !empty($array[$name]['name'])) + { + foreach($array as $key => $arr) + $Upload->custom_form_fields[$key] = $arr; + } + } + + + /** + * Function used to get PHP Path + */ + function php_path() + { + return PHP_PATH; + } + + + + /** + * Function used to add actions that will be performed + * when video is uploaded + * @param Function name + */ + function register_after_video_upload_action($func) + { + global $Upload; + $Upload->actions_after_video_upload[] = $func; + } + + /** + * Function used to add actions that will be performed + * when video is going to play, it will check which player to use + * what type to use and what to do + * @param Function name + */ + function register_actions_play_video($func) + { + global $Cbucket; + $Cbucket->actions_play_video[] = $func; + } + + + + /** + * Function in case htmlspecialchars_decode does not exist + */ + function unhtmlentities ($string) { + $trans_tbl =get_html_translation_table (HTML_ENTITIES ); + $trans_tbl =array_flip ($trans_tbl ); + return strtr ($string ,$trans_tbl ); + } + + + + /** + * Function used to update processed video + * @param Files details + */ + function update_processed_video($file_array) + { + global $db; + $file = $file_array['cqueue_name']; + $array = explode('-',$file); + + if(!empty($array[0])) + $file_name = $array[0]; + $file_name = $file; + + $file_path = VIDEOS_DIR.'/'.$file_array['cqueue_name'].'.flv'; + + if(file_exists($file_path)) + { + $file_size = filesize($file_path); + //Now we will update video where file_name = $file_name + if($file_size>0) + { + //Get Duration + $stats = get_file_details($file_name); + $db->update("video",array("status","duration"),array("Successful",$stats['src_duration'])," file_name='".$file_name."'"); + } + } + } + + + /** + * This function will activate the video if file exists + */ + function activate_video_with_file($vid) + { + global $db; + $vdetails = get_video_details($vid); + $file_name = $vdetails['file_name']; + $results = $db->select("conversion_queue","*"," cqueue_name='$file_name' AND cqueue_conversion='yes'"); + $result = $results[0]; + update_processed_video($result); + } + + + /** + * Function Used to get video file stats from database + * @param FILE_NAME + */ + function get_file_details($file_name) + { + global $db; + $result = $db->select("video_files","*"," id ='$file_name' OR src_name = '$file_name' "); + return $result[0]; + } + + + /** + * Function used to execute command in background + */ + function bgexec($cmd) { + if (substr(php_uname(), 0, 7) == "Windows"){ + //exec($cmd." >> /dev/null &"); + exec($cmd); + //pclose(popen("start \"bla\" \"" . $exe . "\" " . escapeshellarg($args), "r")); + }else{ + exec($cmd . " > /dev/null &"); + } + } + + + /** + * Function used to get thumbnail number from its name + */ + function get_thumb_num($name) + { + $list = explode('-',$name); + $list = explode('.',$list[1]); + return $list[0]; + } + + + /** + * Function used to remove thumb + */ + function delete_video_thumb($file) + { + global $LANG; + $path = THUMBS_DIR.'/'.$file; + if(file_exists($path)) + { + unlink($path); + e($LANG['video_thumb_delete_msg'],m); + }else{ + e($LANG['video_thumb_delete_err']); + } + } + + + /** + * Function used to get array value + * if you know partial value of array and wants to know complete + * value of an array, this function is being used then + */ + function array_find($needle, $haystack) + { + foreach ($haystack as $item) + { + if (strpos($item, $needle) !== FALSE) + { + return $item; + break; + } + } + } + + + + /** + * Function used to give output in proper form + */ + function input_value($params,&$Smarty) + { + $input = $params['input']; + + if(function_exists($input['display_function'])) + return $input['display_function']($input['value']); + else + return $input['value']; + } + + /** + * Function used to convert input to categories + * @param input can be an array or #12# like + */ + function convert_to_categories($input) + { + if(is_array($input)) + { + foreach($input as $in) + { + if(is_array($in)) + { + foreach($in as $i) + { + if(is_array($i)) + { + foreach($i as $info) + { + $cat_details = get_category($info); + $cat_array[] = array($cat_details['categoryid'],$cat_details['category_name']); + } + }elseif(is_numeric($i)){ + $cat_details = get_category($i); + $cat_array[] = array($cat_details['categoryid'],$cat_details['category_name']); + } + } + }elseif(is_numeric($in)){ + $cat_details = get_category($in); + $cat_array[] = array($cat_details['categoryid'],$cat_details['category_name']); + } + } + }else{ + preg_match_all('/#([0-9]+)#/',$default['category'],$m); + $cat_array = array($m[1]); + foreach($cat_array as $i) + { + $cat_details = get_category($i); + $cat_array[] = array($cat_details['categoryid'],$cat_details['category_name']); + } + } + + $count = 1; + if(is_array($cat_array)) + { + foreach($cat_array as $cat) + { + echo ''.$cat[1].''; + if($count!=count($cat_array)) + echo ', '; + $count++; + } + } + } + + + + /** + * Function used to get categorie details + */ + function get_category($id) + { + global $myquery; + return $myquery->get_category($id); + } + + + /** + * Sharing OPT displaying + */ + function display_sharing_opt($input) + { + foreach($input as $key => $i) + { + return $key; + break; + } + } + + /** + * Function used to get number of videos uploaded by user + * @param INT userid + * @param Conditions + */ + function get_user_vids($uid,$cond=NULL,$count_only=false) + { + global $userquery; + return $userquery->get_user_vids($uid,$cond,$count_only); + } + + + + /** + * Function used to get error_list + */ + function error_list() + { + global $eh; + return $eh->error_list; + } + + + /** + * Function used to add tempalte in display template list + */ + function template_files($file) + { + global $ClipBucket; + $ClipBucket->template_files[] = $file; + } + + /** + * Function used to call display + */ + function display_it() + { + global $ClipBucket; + $dir = LAYOUT; + foreach($ClipBucket->template_files as $file) + { + if(file_exists(LAYOUT.'/'.$file)) + { + $new_list[] = $file; + } + } + + assign('template_files',$new_list); + Template('body.html'); + } + + + /** + * Function used to display hint + */ + function hint($hint) + { + + } + + + + function showpagination($total,$page,$link,$extra_params=NULL,$tag='#page#') + { + global $pages; + return $pages->pagination($total,$page,$link,$extra_params,$tag); + } + + + /** + * Function used to check username is disallowed or not + * @param USERNAME + */ + function check_disallowed_user($username) + { + global $Cbucket; + $disallowed_user = $Cbucket->configs['disallowed_usernames']; + $censor_users = explode(',',$disallowed_user); + if(in_array($username,$censor_users)) + return false; + else + return true; + } + + +?> \ No newline at end of file diff --git a/upload/includes/index.php b/upload/includes/index.php new file mode 100644 index 00000000..403f2e18 --- /dev/null +++ b/upload/includes/index.php @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/upload/includes/languages.php b/upload/includes/languages.php new file mode 100644 index 00000000..66eb47cf --- /dev/null +++ b/upload/includes/languages.php @@ -0,0 +1,49 @@ + '中文 (简体)', +'de' => 'Deutsch', +'en' => 'English (US)', +'es' => 'Español', +'fr' => 'Français', +'it' => 'Italiano', +'ja' => '日本語', +'lt' => 'Lietuvių', +'lv' => 'Latviešu', +'pt_BR' => 'Português (Brasil)', +'pt_PT' => 'Português (Portugal)', +'ru' => 'Pyccĸий', +'nl' => 'Dutch', +'sk' => 'Slovenčina', +'tr' => 'Türkçe', +); + +$total = count($langs); +foreach($langs as $lang){ +if(!empty($langArray[$lang])) $languages[$lang] =$langArray[$lang] ; +} +asort($langArray); + +?> \ No newline at end of file diff --git a/upload/includes/modules.php b/upload/includes/modules.php new file mode 100644 index 00000000..1932d745 --- /dev/null +++ b/upload/includes/modules.php @@ -0,0 +1,115 @@ +GetModuleDetails($module); + if(!empty($data['module_name'])){ + mysql_query("UPDATE modules SET active = '".yes."' WHERE module_name = '".$module."'"); + $msg = "Module Has Been Activated"; + }else{ + $msg = "Module Doesnt Exist"; + } + return $msg ; + } + + //Function Used To DeActivate Moodule + + function DeActivateModule($module){ + $data = $this->GetModuleDetails($module); + if(!empty($data['module_name'])){ + mysql_query("UPDATE modules SET active = '".no."' WHERE module_name = '".$module."'"); + $msg = "Module Has Been DeActivated"; + }else{ + $msg = "Module Doesnt Exist"; + } + return $msg; + } + + //Function Used To Delete Module + function DeleteModule($module){ + $data = $this->GetModuleDetails($module); + if(!empty($data['module_name'])){ + mysql_query("DELETE FROM modules WHERE module_name = '".$module."'"); + $msg = "Module Has Been Deleted"; + }else{ + $msg = "Sorry File Doesnt Exist"; + } + } + + //Function Used To Add Module + function AddModule(){ + $name = substr($_POST['module_file'], 0, strrpos($_POST['module_file'], '.instructions')); + $file = mysql_clean($_POST['module_file']); + $active = mysql_clean($_POST['active']); + + if(empty($name)){ + $msg[] = "Module Name Is Empty"; + }elseif(!$this->isValidModule($name)){ + $msg[] = "Module Name Is Not Valid"; + } + $data = $this->GetModuleDetails($name); + if(!empty($data['module_name'])){ + $msg[] = "Module Already Exists"; + } + if(empty($file)){ + $msg[] = "No File Selected"; + } + if(!file_exists(MODULEDIR.'/'.$file)){ + $msg[] = "Specified File Does not Exists"; + } + if(empty($msg)){ + mysql_query("INSERT INTO modules(module_name,module_file,active)VALUES('".$name."','".$file."','".$active."')"); + $msg="Module Has Been Added"; + } + return $msg; + } + +} + +$Modules = new Modules(); + + //Ading and Displaying Module + + $moduleQuery = @mysql_query("SELECT * FROM modules WHERE active ='yes'"); + while($moduleData = @mysql_fetch_array($moduleQuery)){ + $module = $Modules->GetModuleDetails($moduleData['module_name']); + if($module['active'] == 'yes'){ + include(MODULEDIR.'/'.$moduleData['module_file']); + $module_list[] = $module; + } + } + + $Cbucket->moduleList = $module_list; + +?> \ No newline at end of file diff --git a/upload/includes/plugins.php b/upload/includes/plugins.php new file mode 100644 index 00000000..8909dff5 --- /dev/null +++ b/upload/includes/plugins.php @@ -0,0 +1,42 @@ +Get_Plugin_Details(); + +if(!$AdminArea){ +$pluginQueryNA = mysql_query("SELECT * FROM plugins WHERE plugin_active ='yes'"); +$total_plugins = mysql_num_rows($pluginQueryNA); +while($pluginDataNa = mysql_fetch_array($pluginQueryNA)){ + + if(file_exists(BASEDIR.'/plugins/'.$pluginDataNa['plugin_file']) + && !empty($pluginDataNa['plugin_file'])) + { + include(BASEDIR.'/plugins/'.$pluginDataNa['plugin_file']); + $plugin_list[] = $pluginDataNa; + } + } +}else{ +$pluginQueryA = mysql_query("SELECT * FROM plugins"); +$total_plugins = mysql_num_rows($pluginQueryA); +if($total_plugins > 0) +{ +while($pluginDataA = mysql_fetch_array($pluginQueryA)){ + if(file_exists(BASEDIR.'/plugins/'.$pluginDataA['plugin_file']) + && !empty($pluginDataA['plugin_file'])) + include(BASEDIR.'/plugins/'.$pluginDataA['plugin_file']); + //$plugin_list[] = $pluginDataA; + $plugin_list[] = $pluginDataA; + } + Assign('plugin_list',$plugin_list); +} +} + +$cbplugin = new CBPlugin(); +$cbplugin->getPlugins(); + +Assign('total_plugins',$total_plugins); +?> \ No newline at end of file diff --git a/upload/includes/plugins_functions.php b/upload/includes/plugins_functions.php new file mode 100644 index 00000000..6ff6b83f --- /dev/null +++ b/upload/includes/plugins_functions.php @@ -0,0 +1,77 @@ +getFunctionList('comment'); + //Applying Function + if(count($func_list)>0) + { + foreach($func_list as $func) + { + $comment = $func($comment); + } + } + return $comment; + } + + + /** + * Function used to modify description, if there is any plugin installed + * @param : description + */ + function description($description) + { + global $Cbucket; + //Getting List of comment functions + $func_list = $Cbucket->getFunctionList('description'); + //Applying Function + if(count($func_list)>0) + { + foreach($func_list as $func) + { + $description = $func($description); + } + } + return $description; + } + + + /** + * Function used to modify title of video , channel or any object except website, + * if there is any plugin installed + * @param : title + */ + function title($title) + { + global $Cbucket; + //Getting List of comment functions + $func_list = $Cbucket->getFunctionList('title'); + //Applying Function + foreach($func_list as $func) + { + $title = $func($title); + } + return $title; + } + + + +?> \ No newline at end of file diff --git a/upload/includes/templatelib/Config_File.class.php b/upload/includes/templatelib/Config_File.class.php new file mode 100644 index 00000000..d1f812e3 --- /dev/null +++ b/upload/includes/templatelib/Config_File.class.php @@ -0,0 +1,389 @@ + + * @access public + * @package Smarty + */ + +/* $Id$ */ + +/** + * Config file reading class + * @package Smarty + */ +class Config_File { + /**#@+ + * Options + * @var boolean + */ + /** + * Controls whether variables with the same name overwrite each other. + */ + var $overwrite = true; + + /** + * Controls whether config values of on/true/yes and off/false/no get + * converted to boolean values automatically. + */ + var $booleanize = true; + + /** + * Controls whether hidden config sections/vars are read from the file. + */ + var $read_hidden = true; + + /** + * Controls whether or not to fix mac or dos formatted newlines. + * If set to true, \r or \r\n will be changed to \n. + */ + var $fix_newlines = true; + /**#@-*/ + + /** @access private */ + var $_config_path = ""; + var $_config_data = array(); + /**#@-*/ + + /** + * Constructs a new config file class. + * + * @param string $config_path (optional) path to the config files + */ + function Config_File($config_path = NULL) + { + if (isset($config_path)) + $this->set_path($config_path); + } + + + /** + * Set the path where configuration files can be found. + * + * @param string $config_path path to the config files + */ + function set_path($config_path) + { + if (!empty($config_path)) { + if (!is_string($config_path) || !file_exists($config_path) || !is_dir($config_path)) { + $this->_trigger_error_msg("Bad config file path '$config_path'"); + return; + } + if(substr($config_path, -1) != DIRECTORY_SEPARATOR) { + $config_path .= DIRECTORY_SEPARATOR; + } + + $this->_config_path = $config_path; + } + } + + + /** + * Retrieves config info based on the file, section, and variable name. + * + * @param string $file_name config file to get info for + * @param string $section_name (optional) section to get info for + * @param string $var_name (optional) variable to get info for + * @return string|array a value or array of values + */ + function get($file_name, $section_name = NULL, $var_name = NULL) + { + if (empty($file_name)) { + $this->_trigger_error_msg('Empty config file name'); + return; + } else { + $file_name = $this->_config_path . $file_name; + if (!isset($this->_config_data[$file_name])) + $this->load_file($file_name, false); + } + + if (!empty($var_name)) { + if (empty($section_name)) { + return $this->_config_data[$file_name]["vars"][$var_name]; + } else { + if(isset($this->_config_data[$file_name]["sections"][$section_name]["vars"][$var_name])) + return $this->_config_data[$file_name]["sections"][$section_name]["vars"][$var_name]; + else + return array(); + } + } else { + if (empty($section_name)) { + return (array)$this->_config_data[$file_name]["vars"]; + } else { + if(isset($this->_config_data[$file_name]["sections"][$section_name]["vars"])) + return (array)$this->_config_data[$file_name]["sections"][$section_name]["vars"]; + else + return array(); + } + } + } + + + /** + * Retrieves config info based on the key. + * + * @param $file_name string config key (filename/section/var) + * @return string|array same as get() + * @uses get() retrieves information from config file and returns it + */ + function &get_key($config_key) + { + list($file_name, $section_name, $var_name) = explode('/', $config_key, 3); + $result = &$this->get($file_name, $section_name, $var_name); + return $result; + } + + /** + * Get all loaded config file names. + * + * @return array an array of loaded config file names + */ + function get_file_names() + { + return array_keys($this->_config_data); + } + + + /** + * Get all section names from a loaded file. + * + * @param string $file_name config file to get section names from + * @return array an array of section names from the specified file + */ + function get_section_names($file_name) + { + $file_name = $this->_config_path . $file_name; + if (!isset($this->_config_data[$file_name])) { + $this->_trigger_error_msg("Unknown config file '$file_name'"); + return; + } + + return array_keys($this->_config_data[$file_name]["sections"]); + } + + + /** + * Get all global or section variable names. + * + * @param string $file_name config file to get info for + * @param string $section_name (optional) section to get info for + * @return array an array of variables names from the specified file/section + */ + function get_var_names($file_name, $section = NULL) + { + if (empty($file_name)) { + $this->_trigger_error_msg('Empty config file name'); + return; + } else if (!isset($this->_config_data[$file_name])) { + $this->_trigger_error_msg("Unknown config file '$file_name'"); + return; + } + + if (empty($section)) + return array_keys($this->_config_data[$file_name]["vars"]); + else + return array_keys($this->_config_data[$file_name]["sections"][$section]["vars"]); + } + + + /** + * Clear loaded config data for a certain file or all files. + * + * @param string $file_name file to clear config data for + */ + function clear($file_name = NULL) + { + if ($file_name === NULL) + $this->_config_data = array(); + else if (isset($this->_config_data[$file_name])) + $this->_config_data[$file_name] = array(); + } + + + /** + * Load a configuration file manually. + * + * @param string $file_name file name to load + * @param boolean $prepend_path whether current config path should be + * prepended to the filename + */ + function load_file($file_name, $prepend_path = true) + { + if ($prepend_path && $this->_config_path != "") + $config_file = $this->_config_path . $file_name; + else + $config_file = $file_name; + + ini_set('track_errors', true); + $fp = @fopen($config_file, "r"); + if (!is_resource($fp)) { + $this->_trigger_error_msg("Could not open config file '$config_file'"); + return false; + } + + $contents = ($size = filesize($config_file)) ? fread($fp, $size) : ''; + fclose($fp); + + $this->_config_data[$config_file] = $this->parse_contents($contents); + return true; + } + + /** + * Store the contents of a file manually. + * + * @param string $config_file file name of the related contents + * @param string $contents the file-contents to parse + */ + function set_file_contents($config_file, $contents) + { + $this->_config_data[$config_file] = $this->parse_contents($contents); + return true; + } + + /** + * parse the source of a configuration file manually. + * + * @param string $contents the file-contents to parse + */ + function parse_contents($contents) + { + if($this->fix_newlines) { + // fix mac/dos formatted newlines + $contents = preg_replace('!\r\n?!', "\n", $contents); + } + + $config_data = array(); + $config_data['sections'] = array(); + $config_data['vars'] = array(); + + /* reference to fill with data */ + $vars =& $config_data['vars']; + + /* parse file line by line */ + preg_match_all('!^.*\r?\n?!m', $contents, $match); + $lines = $match[0]; + for ($i=0, $count=count($lines); $i<$count; $i++) { + $line = $lines[$i]; + if (empty($line)) continue; + + if ( substr($line, 0, 1) == '[' && preg_match('!^\[(.*?)\]!', $line, $match) ) { + /* section found */ + if (substr($match[1], 0, 1) == '.') { + /* hidden section */ + if ($this->read_hidden) { + $section_name = substr($match[1], 1); + } else { + /* break reference to $vars to ignore hidden section */ + unset($vars); + $vars = array(); + continue; + } + } else { + $section_name = $match[1]; + } + if (!isset($config_data['sections'][$section_name])) + $config_data['sections'][$section_name] = array('vars' => array()); + $vars =& $config_data['sections'][$section_name]['vars']; + continue; + } + + if (preg_match('/^\s*(\.?\w+)\s*=\s*(.*)/s', $line, $match)) { + /* variable found */ + $var_name = rtrim($match[1]); + if (strpos($match[2], '"""') === 0) { + /* handle multiline-value */ + $lines[$i] = substr($match[2], 3); + $var_value = ''; + while ($i<$count) { + if (($pos = strpos($lines[$i], '"""')) === false) { + $var_value .= $lines[$i++]; + } else { + /* end of multiline-value */ + $var_value .= substr($lines[$i], 0, $pos); + break; + } + } + $booleanize = false; + + } else { + /* handle simple value */ + $var_value = preg_replace('/^([\'"])(.*)\1$/', '\2', rtrim($match[2])); + $booleanize = $this->booleanize; + + } + $this->_set_config_var($vars, $var_name, $var_value, $booleanize); + } + /* else unparsable line / means it is a comment / means ignore it */ + } + return $config_data; + } + + /**#@+ @access private */ + /** + * @param array &$container + * @param string $var_name + * @param mixed $var_value + * @param boolean $booleanize determines whether $var_value is converted to + * to true/false + */ + function _set_config_var(&$container, $var_name, $var_value, $booleanize) + { + if (substr($var_name, 0, 1) == '.') { + if (!$this->read_hidden) + return; + else + $var_name = substr($var_name, 1); + } + + if (!preg_match("/^[a-zA-Z_]\w*$/", $var_name)) { + $this->_trigger_error_msg("Bad variable name '$var_name'"); + return; + } + + if ($booleanize) { + if (preg_match("/^(on|true|yes)$/i", $var_value)) + $var_value = true; + else if (preg_match("/^(off|false|no)$/i", $var_value)) + $var_value = false; + } + + if (!isset($container[$var_name]) || $this->overwrite) + $container[$var_name] = $var_value; + else { + settype($container[$var_name], 'array'); + $container[$var_name][] = $var_value; + } + } + + /** + * @uses trigger_error() creates a PHP warning/error + * @param string $error_msg + * @param integer $error_type one of + */ + function _trigger_error_msg($error_msg, $error_type = E_USER_WARNING) + { + trigger_error("Config_File error: $error_msg", $error_type); + } + /**#@-*/ +} + +?> diff --git a/upload/includes/templatelib/Template.class.php b/upload/includes/templatelib/Template.class.php new file mode 100644 index 00000000..286e4d6f --- /dev/null +++ b/upload/includes/templatelib/Template.class.php @@ -0,0 +1,1944 @@ + + * @author Andrei Zmievski + * @package Smarty + * @version 2.6.18 + */ + +/* $Id$ */ + +/** + * DIR_SEP isn't used anymore, but third party apps might + */ +if(!defined('DIR_SEP')) { + define('DIR_SEP', DIRECTORY_SEPARATOR); +} + +/** + * set SMARTY_DIR to absolute path to Smarty library files. + * if not defined, include_path will be used. Sets SMARTY_DIR only if user + * application has not already defined it. + */ + +if (!defined('SMARTY_DIR')) { + define('SMARTY_DIR', dirname(__FILE__) . DIRECTORY_SEPARATOR); +} + +if (!defined('SMARTY_CORE_DIR')) { + define('SMARTY_CORE_DIR', SMARTY_DIR . 'internals' . DIRECTORY_SEPARATOR); +} + +define('SMARTY_PHP_PASSTHRU', 0); +define('SMARTY_PHP_QUOTE', 1); +define('SMARTY_PHP_REMOVE', 2); +define('SMARTY_PHP_ALLOW', 3); + +/** + * @package Smarty + */ +class Smarty +{ + /**#@+ + * Smarty Configuration Section + */ + + /** + * The name of the directory where templates are located. + * + * @var string + */ + var $template_dir = 'styles'; + + /** + * The directory where compiled templates are located. + * + * @var string + */ + var $compile_dir = 'cache'; + + /** + * The directory where config files are located. + * + * @var string + */ + var $config_dir = 'includes/configs'; + + /** + * An array of directories searched for plugins. + * + * @var array + */ + var $plugins_dir = array('plugins'); + + /** + * If debugging is enabled, a debug console window will display + * when the page loads (make sure your browser allows unrequested + * popup windows) + * + * @var boolean + */ + var $debugging = false; + + /** + * When set, smarty does uses this value as error_reporting-level. + * + * @var boolean + */ + var $error_reporting = null; + + /** + * This is the path to the debug console template. If not set, + * the default one will be used. + * + * @var string + */ + var $debug_tpl = ''; + + /** + * This determines if debugging is enable-able from the browser. + *
      + *
    • NONE => no debugging control allowed
    • + *
    • URL => enable debugging when SMARTY_DEBUG is found in the URL.
    • + *
    + * @link http://www.foo.dom/index.php?SMARTY_DEBUG + * @var string + */ + var $debugging_ctrl = 'NONE'; + + /** + * This tells Smarty whether to check for recompiling or not. Recompiling + * does not need to happen unless a template or config file is changed. + * Typically you enable this during development, and disable for + * production. + * + * @var boolean + */ + var $compile_check = true; + + /** + * This forces templates to compile every time. Useful for development + * or debugging. + * + * @var boolean + */ + var $force_compile = false; + + /** + * This enables template caching. + *
      + *
    • 0 = no caching
    • + *
    • 1 = use class cache_lifetime value
    • + *
    • 2 = use cache_lifetime in cache file
    • + *
    + * @var integer + */ + var $caching = 0; + + /** + * The name of the directory for cache files. + * + * @var string + */ + var $cache_dir = 'cache'; + + /** + * This is the number of seconds cached content will persist. + *
      + *
    • 0 = always regenerate cache
    • + *
    • -1 = never expires
    • + *
    + * + * @var integer + */ + var $cache_lifetime = 3600; + + /** + * Only used when $caching is enabled. If true, then If-Modified-Since headers + * are respected with cached content, and appropriate HTTP headers are sent. + * This way repeated hits to a cached page do not send the entire page to the + * client every time. + * + * @var boolean + */ + var $cache_modified_check = false; + + /** + * This determines how Smarty handles "" tags in templates. + * possible values: + *
      + *
    • SMARTY_PHP_PASSTHRU -> print tags as plain text
    • + *
    • SMARTY_PHP_QUOTE -> escape tags as entities
    • + *
    • SMARTY_PHP_REMOVE -> remove php tags
    • + *
    • SMARTY_PHP_ALLOW -> execute php tags
    • + *
    + * + * @var integer + */ + var $php_handling = SMARTY_PHP_PASSTHRU; + + /** + * This enables template security. When enabled, many things are restricted + * in the templates that normally would go unchecked. This is useful when + * untrusted parties are editing templates and you want a reasonable level + * of security. (no direct execution of PHP in templates for example) + * + * @var boolean + */ + var $security = false; + + /** + * This is the list of template directories that are considered secure. This + * is used only if {@link $security} is enabled. One directory per array + * element. {@link $template_dir} is in this list implicitly. + * + * @var array + */ + var $secure_dir = array(); + + /** + * These are the security settings for Smarty. They are used only when + * {@link $security} is enabled. + * + * @var array + */ + var $security_settings = array( + 'PHP_HANDLING' => false, + 'IF_FUNCS' => array('array', 'list', + 'isset', 'empty', + 'count', 'sizeof', + 'in_array', 'is_array', + 'true', 'false', 'null'), + 'INCLUDE_ANY' => false, + 'PHP_TAGS' => false, + 'MODIFIER_FUNCS' => array('count'), + 'ALLOW_CONSTANTS' => false + ); + + /** + * This is an array of directories where trusted php scripts reside. + * {@link $security} is disabled during their inclusion/execution. + * + * @var array + */ + var $trusted_dir = array(); + + /** + * The left delimiter used for the template tags. + * + * @var string + */ + var $left_delimiter = '{'; + + /** + * The right delimiter used for the template tags. + * + * @var string + */ + var $right_delimiter = '}'; + + /** + * The order in which request variables are registered, similar to + * variables_order in php.ini E = Environment, G = GET, P = POST, + * C = Cookies, S = Server + * + * @var string + */ + var $request_vars_order = 'EGPCS'; + + /** + * Indicates wether $HTTP_*_VARS[] (request_use_auto_globals=false) + * are uses as request-vars or $_*[]-vars. note: if + * request_use_auto_globals is true, then $request_vars_order has + * no effect, but the php-ini-value "gpc_order" + * + * @var boolean + */ + var $request_use_auto_globals = true; + + /** + * Set this if you want different sets of compiled files for the same + * templates. This is useful for things like different languages. + * Instead of creating separate sets of templates per language, you + * set different compile_ids like 'en' and 'de'. + * + * @var string + */ + var $compile_id = null; + + /** + * This tells Smarty whether or not to use sub dirs in the cache/ and + * templates_c/ directories. sub directories better organized, but + * may not work well with PHP safe mode enabled. + * + * @var boolean + * + */ + var $use_sub_dirs = false; + + /** + * This is a list of the modifiers to apply to all template variables. + * Put each modifier in a separate array element in the order you want + * them applied. example: array('escape:"htmlall"'); + * + * @var array + */ + var $default_modifiers = array(); + + /** + * This is the resource type to be used when not specified + * at the beginning of the resource path. examples: + * $smarty->display('file:index.tpl'); + * $smarty->display('db:index.tpl'); + * $smarty->display('index.tpl'); // will use default resource type + * {include file="file:index.tpl"} + * {include file="db:index.tpl"} + * {include file="index.tpl"} {* will use default resource type *} + * + * @var array + */ + var $default_resource_type = 'file'; + + /** + * The function used for cache file handling. If not set, built-in caching is used. + * + * @var null|string function name + */ + var $cache_handler_func = null; + + /** + * This indicates which filters are automatically loaded into Smarty. + * + * @var array array of filter names + */ + var $autoload_filters = array(); + + /**#@+ + * @var boolean + */ + /** + * This tells if config file vars of the same name overwrite each other or not. + * if disabled, same name variables are accumulated in an array. + */ + var $config_overwrite = true; + + /** + * This tells whether or not to automatically booleanize config file variables. + * If enabled, then the strings "on", "true", and "yes" are treated as boolean + * true, and "off", "false" and "no" are treated as boolean false. + */ + var $config_booleanize = true; + + /** + * This tells whether hidden sections [.foobar] are readable from the + * tempalates or not. Normally you would never allow this since that is + * the point behind hidden sections: the application can access them, but + * the templates cannot. + */ + var $config_read_hidden = false; + + /** + * This tells whether or not automatically fix newlines in config files. + * It basically converts \r (mac) or \r\n (dos) to \n + */ + var $config_fix_newlines = true; + /**#@-*/ + + /** + * If a template cannot be found, this PHP function will be executed. + * Useful for creating templates on-the-fly or other special action. + * + * @var string function name + */ + var $default_template_handler_func = ''; + + /** + * The file that contains the compiler class. This can a full + * pathname, or relative to the php_include path. + * + * @var string + */ + var $compiler_file = 'Template_Compiler.class.php'; + + /** + * The class used for compiling templates. + * + * @var string + */ + var $compiler_class = 'Smarty_Compiler'; + + /** + * The class used to load config vars. + * + * @var string + */ + var $config_class = 'Config_File'; + +/**#@+ + * END Smarty Configuration Section + * There should be no need to touch anything below this line. + * @access private + */ + /** + * where assigned template vars are kept + * + * @var array + */ + var $_tpl_vars = array(); + + /** + * stores run-time $smarty.* vars + * + * @var null|array + */ + var $_smarty_vars = null; + + /** + * keeps track of sections + * + * @var array + */ + var $_sections = array(); + + /** + * keeps track of foreach blocks + * + * @var array + */ + var $_foreach = array(); + + /** + * keeps track of tag hierarchy + * + * @var array + */ + var $_tag_stack = array(); + + /** + * configuration object + * + * @var Config_file + */ + var $_conf_obj = null; + + /** + * loaded configuration settings + * + * @var array + */ + var $_config = array(array('vars' => array(), 'files' => array())); + + /** + * md5 checksum of the string 'Smarty' + * + * @var string + */ + var $_smarty_md5 = 'f8d698aea36fcbead2b9d5359ffca76f'; + + /** + * Smarty version number + * + * @var string + */ + var $_version = '2.6.18'; + + /** + * current template inclusion depth + * + * @var integer + */ + var $_inclusion_depth = 0; + + /** + * for different compiled templates + * + * @var string + */ + var $_compile_id = null; + + /** + * text in URL to enable debug mode + * + * @var string + */ + var $_smarty_debug_id = 'SMARTY_DEBUG'; + + /** + * debugging information for debug console + * + * @var array + */ + var $_smarty_debug_info = array(); + + /** + * info that makes up a cache file + * + * @var array + */ + var $_cache_info = array(); + + /** + * default file permissions + * + * @var integer + */ + var $_file_perms = 0644; + + /** + * default dir permissions + * + * @var integer + */ + var $_dir_perms = 0771; + + /** + * registered objects + * + * @var array + */ + var $_reg_objects = array(); + + /** + * table keeping track of plugins + * + * @var array + */ + var $_plugins = array( + 'modifier' => array(), + 'function' => array(), + 'block' => array(), + 'compiler' => array(), + 'prefilter' => array(), + 'postfilter' => array(), + 'outputfilter' => array(), + 'resource' => array(), + 'insert' => array()); + + + /** + * cache serials + * + * @var array + */ + var $_cache_serials = array(); + + /** + * name of optional cache include file + * + * @var string + */ + var $_cache_include = null; + + /** + * indicate if the current code is used in a compiled + * include + * + * @var string + */ + var $_cache_including = false; + + /**#@-*/ + /** + * The class constructor. + */ + function Smarty() + { + $this->assign('SCRIPT_NAME', isset($_SERVER['SCRIPT_NAME']) ? $_SERVER['SCRIPT_NAME'] + : @$GLOBALS['HTTP_SERVER_VARS']['SCRIPT_NAME']); + } + + /** + * assigns values to template variables + * + * @param array|string $tpl_var the template variable name(s) + * @param mixed $value the value to assign + */ + function assign($tpl_var, $value = null) + { + if (is_array($tpl_var)){ + foreach ($tpl_var as $key => $val) { + if ($key != '') { + $this->_tpl_vars[$key] = $val; + } + } + } else { + if ($tpl_var != '') + $this->_tpl_vars[$tpl_var] = $value; + } + } + + /** + * assigns values to template variables by reference + * + * @param string $tpl_var the template variable name + * @param mixed $value the referenced value to assign + */ + function assign_by_ref($tpl_var, &$value) + { + if ($tpl_var != '') + $this->_tpl_vars[$tpl_var] = &$value; + } + + /** + * appends values to template variables + * + * @param array|string $tpl_var the template variable name(s) + * @param mixed $value the value to append + */ + function append($tpl_var, $value=null, $merge=false) + { + if (is_array($tpl_var)) { + // $tpl_var is an array, ignore $value + foreach ($tpl_var as $_key => $_val) { + if ($_key != '') { + if(!@is_array($this->_tpl_vars[$_key])) { + settype($this->_tpl_vars[$_key],'array'); + } + if($merge && is_array($_val)) { + foreach($_val as $_mkey => $_mval) { + $this->_tpl_vars[$_key][$_mkey] = $_mval; + } + } else { + $this->_tpl_vars[$_key][] = $_val; + } + } + } + } else { + if ($tpl_var != '' && isset($value)) { + if(!@is_array($this->_tpl_vars[$tpl_var])) { + settype($this->_tpl_vars[$tpl_var],'array'); + } + if($merge && is_array($value)) { + foreach($value as $_mkey => $_mval) { + $this->_tpl_vars[$tpl_var][$_mkey] = $_mval; + } + } else { + $this->_tpl_vars[$tpl_var][] = $value; + } + } + } + } + + /** + * appends values to template variables by reference + * + * @param string $tpl_var the template variable name + * @param mixed $value the referenced value to append + */ + function append_by_ref($tpl_var, &$value, $merge=false) + { + if ($tpl_var != '' && isset($value)) { + if(!@is_array($this->_tpl_vars[$tpl_var])) { + settype($this->_tpl_vars[$tpl_var],'array'); + } + if ($merge && is_array($value)) { + foreach($value as $_key => $_val) { + $this->_tpl_vars[$tpl_var][$_key] = &$value[$_key]; + } + } else { + $this->_tpl_vars[$tpl_var][] = &$value; + } + } + } + + + /** + * clear the given assigned template variable. + * + * @param string $tpl_var the template variable to clear + */ + function clear_assign($tpl_var) + { + if (is_array($tpl_var)) + foreach ($tpl_var as $curr_var) + unset($this->_tpl_vars[$curr_var]); + else + unset($this->_tpl_vars[$tpl_var]); + } + + + /** + * Registers custom function to be used in templates + * + * @param string $function the name of the template function + * @param string $function_impl the name of the PHP function to register + */ + function register_function($function, $function_impl, $cacheable=true, $cache_attrs=null) + { + $this->_plugins['function'][$function] = + array($function_impl, null, null, false, $cacheable, $cache_attrs); + + } + + /** + * Unregisters custom function + * + * @param string $function name of template function + */ + function unregister_function($function) + { + unset($this->_plugins['function'][$function]); + } + + /** + * Registers object to be used in templates + * + * @param string $object name of template object + * @param object &$object_impl the referenced PHP object to register + * @param null|array $allowed list of allowed methods (empty = all) + * @param boolean $smarty_args smarty argument format, else traditional + * @param null|array $block_functs list of methods that are block format + */ + function register_object($object, &$object_impl, $allowed = array(), $smarty_args = true, $block_methods = array()) + { + settype($allowed, 'array'); + settype($smarty_args, 'boolean'); + $this->_reg_objects[$object] = + array(&$object_impl, $allowed, $smarty_args, $block_methods); + } + + /** + * Unregisters object + * + * @param string $object name of template object + */ + function unregister_object($object) + { + unset($this->_reg_objects[$object]); + } + + + /** + * Registers block function to be used in templates + * + * @param string $block name of template block + * @param string $block_impl PHP function to register + */ + function register_block($block, $block_impl, $cacheable=true, $cache_attrs=null) + { + $this->_plugins['block'][$block] = + array($block_impl, null, null, false, $cacheable, $cache_attrs); + } + + /** + * Unregisters block function + * + * @param string $block name of template function + */ + function unregister_block($block) + { + unset($this->_plugins['block'][$block]); + } + + /** + * Registers compiler function + * + * @param string $function name of template function + * @param string $function_impl name of PHP function to register + */ + function register_compiler_function($function, $function_impl, $cacheable=true) + { + $this->_plugins['compiler'][$function] = + array($function_impl, null, null, false, $cacheable); + } + + /** + * Unregisters compiler function + * + * @param string $function name of template function + */ + function unregister_compiler_function($function) + { + unset($this->_plugins['compiler'][$function]); + } + + /** + * Registers modifier to be used in templates + * + * @param string $modifier name of template modifier + * @param string $modifier_impl name of PHP function to register + */ + function register_modifier($modifier, $modifier_impl) + { + $this->_plugins['modifier'][$modifier] = + array($modifier_impl, null, null, false); + } + + /** + * Unregisters modifier + * + * @param string $modifier name of template modifier + */ + function unregister_modifier($modifier) + { + unset($this->_plugins['modifier'][$modifier]); + } + + /** + * Registers a resource to fetch a template + * + * @param string $type name of resource + * @param array $functions array of functions to handle resource + */ + function register_resource($type, $functions) + { + if (count($functions)==4) { + $this->_plugins['resource'][$type] = + array($functions, false); + + } elseif (count($functions)==5) { + $this->_plugins['resource'][$type] = + array(array(array(&$functions[0], $functions[1]) + ,array(&$functions[0], $functions[2]) + ,array(&$functions[0], $functions[3]) + ,array(&$functions[0], $functions[4])) + ,false); + + } else { + $this->trigger_error("malformed function-list for '$type' in register_resource"); + + } + } + + /** + * Unregisters a resource + * + * @param string $type name of resource + */ + function unregister_resource($type) + { + unset($this->_plugins['resource'][$type]); + } + + /** + * Registers a prefilter function to apply + * to a template before compiling + * + * @param string $function name of PHP function to register + */ + function register_prefilter($function) + { + $_name = (is_array($function)) ? $function[1] : $function; + $this->_plugins['prefilter'][$_name] + = array($function, null, null, false); + } + + /** + * Unregisters a prefilter function + * + * @param string $function name of PHP function + */ + function unregister_prefilter($function) + { + unset($this->_plugins['prefilter'][$function]); + } + + /** + * Registers a postfilter function to apply + * to a compiled template after compilation + * + * @param string $function name of PHP function to register + */ + function register_postfilter($function) + { + $_name = (is_array($function)) ? $function[1] : $function; + $this->_plugins['postfilter'][$_name] + = array($function, null, null, false); + } + + /** + * Unregisters a postfilter function + * + * @param string $function name of PHP function + */ + function unregister_postfilter($function) + { + unset($this->_plugins['postfilter'][$function]); + } + + /** + * Registers an output filter function to apply + * to a template output + * + * @param string $function name of PHP function + */ + function register_outputfilter($function) + { + $_name = (is_array($function)) ? $function[1] : $function; + $this->_plugins['outputfilter'][$_name] + = array($function, null, null, false); + } + + /** + * Unregisters an outputfilter function + * + * @param string $function name of PHP function + */ + function unregister_outputfilter($function) + { + unset($this->_plugins['outputfilter'][$function]); + } + + /** + * load a filter of specified type and name + * + * @param string $type filter type + * @param string $name filter name + */ + function load_filter($type, $name) + { + switch ($type) { + case 'output': + $_params = array('plugins' => array(array($type . 'filter', $name, null, null, false))); + require_once(SMARTY_CORE_DIR . 'core.load_plugins.php'); + smarty_core_load_plugins($_params, $this); + break; + + case 'pre': + case 'post': + if (!isset($this->_plugins[$type . 'filter'][$name])) + $this->_plugins[$type . 'filter'][$name] = false; + break; + } + } + + /** + * clear cached content for the given template and cache id + * + * @param string $tpl_file name of template file + * @param string $cache_id name of cache_id + * @param string $compile_id name of compile_id + * @param string $exp_time expiration time + * @return boolean + */ + function clear_cache($tpl_file = null, $cache_id = null, $compile_id = null, $exp_time = null) + { + + if (!isset($compile_id)) + $compile_id = $this->compile_id; + + if (!isset($tpl_file)) + $compile_id = null; + + $_auto_id = $this->_get_auto_id($cache_id, $compile_id); + + if (!empty($this->cache_handler_func)) { + return call_user_func_array($this->cache_handler_func, + array('clear', &$this, &$dummy, $tpl_file, $cache_id, $compile_id, $exp_time)); + } else { + $_params = array('auto_base' => $this->cache_dir, + 'auto_source' => $tpl_file, + 'auto_id' => $_auto_id, + 'exp_time' => $exp_time); + require_once(SMARTY_CORE_DIR . 'core.rm_auto.php'); + return smarty_core_rm_auto($_params, $this); + } + + } + + + /** + * clear the entire contents of cache (all templates) + * + * @param string $exp_time expire time + * @return boolean results of {@link smarty_core_rm_auto()} + */ + function clear_all_cache($exp_time = null) + { + return $this->clear_cache(null, null, null, $exp_time); + } + + + /** + * test to see if valid cache exists for this template + * + * @param string $tpl_file name of template file + * @param string $cache_id + * @param string $compile_id + * @return string|false results of {@link _read_cache_file()} + */ + function is_cached($tpl_file, $cache_id = null, $compile_id = null) + { + if (!$this->caching) + return false; + + if (!isset($compile_id)) + $compile_id = $this->compile_id; + + $_params = array( + 'tpl_file' => $tpl_file, + 'cache_id' => $cache_id, + 'compile_id' => $compile_id + ); + require_once(SMARTY_CORE_DIR . 'core.read_cache_file.php'); + return smarty_core_read_cache_file($_params, $this); + } + + + /** + * clear all the assigned template variables. + * + */ + function clear_all_assign() + { + $this->_tpl_vars = array(); + } + + /** + * clears compiled version of specified template resource, + * or all compiled template files if one is not specified. + * This function is for advanced use only, not normally needed. + * + * @param string $tpl_file + * @param string $compile_id + * @param string $exp_time + * @return boolean results of {@link smarty_core_rm_auto()} + */ + function clear_compiled_tpl($tpl_file = null, $compile_id = null, $exp_time = null) + { + if (!isset($compile_id)) { + $compile_id = $this->compile_id; + } + $_params = array('auto_base' => $this->compile_dir, + 'auto_source' => $tpl_file, + 'auto_id' => $compile_id, + 'exp_time' => $exp_time, + 'extensions' => array('.inc', '.php')); + require_once(SMARTY_CORE_DIR . 'core.rm_auto.php'); + return smarty_core_rm_auto($_params, $this); + } + + /** + * Checks whether requested template exists. + * + * @param string $tpl_file + * @return boolean + */ + function template_exists($tpl_file) + { + $_params = array('resource_name' => $tpl_file, 'quiet'=>true, 'get_source'=>false); + return $this->_fetch_resource_info($_params); + } + + /** + * Returns an array containing template variables + * + * @param string $name + * @param string $type + * @return array + */ + function &get_template_vars($name=null) + { + if(!isset($name)) { + return $this->_tpl_vars; + } elseif(isset($this->_tpl_vars[$name])) { + return $this->_tpl_vars[$name]; + } else { + // var non-existant, return valid reference + $_tmp = null; + return $_tmp; + } + } + + /** + * Returns an array containing config variables + * + * @param string $name + * @param string $type + * @return array + */ + function &get_config_vars($name=null) + { + if(!isset($name) && is_array($this->_config[0])) { + return $this->_config[0]['vars']; + } else if(isset($this->_config[0]['vars'][$name])) { + return $this->_config[0]['vars'][$name]; + } else { + // var non-existant, return valid reference + $_tmp = null; + return $_tmp; + } + } + + /** + * trigger Smarty error + * + * @param string $error_msg + * @param integer $error_type + */ + function trigger_error($error_msg, $error_type = E_USER_WARNING) + { + trigger_error("Smarty error: $error_msg", $error_type); + } + + + /** + * executes & displays the template results + * + * @param string $resource_name + * @param string $cache_id + * @param string $compile_id + */ + function display($resource_name, $cache_id = null, $compile_id = null) + { + $this->fetch($resource_name, $cache_id, $compile_id, true); + } + + /** + * executes & returns or displays the template results + * + * @param string $resource_name + * @param string $cache_id + * @param string $compile_id + * @param boolean $display + */ + function fetch($resource_name, $cache_id = null, $compile_id = null, $display = false) + { + static $_cache_info = array(); + + $_smarty_old_error_level = $this->debugging ? error_reporting() : error_reporting(isset($this->error_reporting) + ? $this->error_reporting : error_reporting() & ~E_NOTICE); + + if (!$this->debugging && $this->debugging_ctrl == 'URL') { + $_query_string = $this->request_use_auto_globals ? $_SERVER['QUERY_STRING'] : $GLOBALS['HTTP_SERVER_VARS']['QUERY_STRING']; + if (@strstr($_query_string, $this->_smarty_debug_id)) { + if (@strstr($_query_string, $this->_smarty_debug_id . '=on')) { + // enable debugging for this browser session + @setcookie('SMARTY_DEBUG', true); + $this->debugging = true; + } elseif (@strstr($_query_string, $this->_smarty_debug_id . '=off')) { + // disable debugging for this browser session + @setcookie('SMARTY_DEBUG', false); + $this->debugging = false; + } else { + // enable debugging for this page + $this->debugging = true; + } + } else { + $this->debugging = (bool)($this->request_use_auto_globals ? @$_COOKIE['SMARTY_DEBUG'] : @$GLOBALS['HTTP_COOKIE_VARS']['SMARTY_DEBUG']); + } + } + + if ($this->debugging) { + // capture time for debugging info + $_params = array(); + require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); + $_debug_start_time = smarty_core_get_microtime($_params, $this); + $this->_smarty_debug_info[] = array('type' => 'template', + 'filename' => $resource_name, + 'depth' => 0); + $_included_tpls_idx = count($this->_smarty_debug_info) - 1; + } + + if (!isset($compile_id)) { + $compile_id = $this->compile_id; + } + + $this->_compile_id = $compile_id; + $this->_inclusion_depth = 0; + + if ($this->caching) { + // save old cache_info, initialize cache_info + array_push($_cache_info, $this->_cache_info); + $this->_cache_info = array(); + $_params = array( + 'tpl_file' => $resource_name, + 'cache_id' => $cache_id, + 'compile_id' => $compile_id, + 'results' => null + ); + require_once(SMARTY_CORE_DIR . 'core.read_cache_file.php'); + if (smarty_core_read_cache_file($_params, $this)) { + $_smarty_results = $_params['results']; + if (!empty($this->_cache_info['insert_tags'])) { + $_params = array('plugins' => $this->_cache_info['insert_tags']); + require_once(SMARTY_CORE_DIR . 'core.load_plugins.php'); + smarty_core_load_plugins($_params, $this); + $_params = array('results' => $_smarty_results); + require_once(SMARTY_CORE_DIR . 'core.process_cached_inserts.php'); + $_smarty_results = smarty_core_process_cached_inserts($_params, $this); + } + if (!empty($this->_cache_info['cache_serials'])) { + $_params = array('results' => $_smarty_results); + require_once(SMARTY_CORE_DIR . 'core.process_compiled_include.php'); + $_smarty_results = smarty_core_process_compiled_include($_params, $this); + } + + + if ($display) { + if ($this->debugging) + { + // capture time for debugging info + $_params = array(); + require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); + $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = smarty_core_get_microtime($_params, $this) - $_debug_start_time; + require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php'); + $_smarty_results .= smarty_core_display_debug_console($_params, $this); + } + if ($this->cache_modified_check) { + $_server_vars = ($this->request_use_auto_globals) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS']; + $_last_modified_date = @substr($_server_vars['HTTP_IF_MODIFIED_SINCE'], 0, strpos($_server_vars['HTTP_IF_MODIFIED_SINCE'], 'GMT') + 3); + $_gmt_mtime = gmdate('D, d M Y H:i:s', $this->_cache_info['timestamp']).' GMT'; + if (@count($this->_cache_info['insert_tags']) == 0 + && !$this->_cache_serials + && $_gmt_mtime == $_last_modified_date) { + if (php_sapi_name()=='cgi') + header('Status: 304 Not Modified'); + else + header('HTTP/1.1 304 Not Modified'); + + } else { + header('Last-Modified: '.$_gmt_mtime); + echo $_smarty_results; + } + } else { + echo $_smarty_results; + } + error_reporting($_smarty_old_error_level); + // restore initial cache_info + $this->_cache_info = array_pop($_cache_info); + return true; + } else { + error_reporting($_smarty_old_error_level); + // restore initial cache_info + $this->_cache_info = array_pop($_cache_info); + return $_smarty_results; + } + } else { + $this->_cache_info['template'][$resource_name] = true; + if ($this->cache_modified_check && $display) { + header('Last-Modified: '.gmdate('D, d M Y H:i:s', time()).' GMT'); + } + } + } + + // load filters that are marked as autoload + if (count($this->autoload_filters)) { + foreach ($this->autoload_filters as $_filter_type => $_filters) { + foreach ($_filters as $_filter) { + $this->load_filter($_filter_type, $_filter); + } + } + } + + $_smarty_compile_path = $this->_get_compile_path($resource_name); + + // if we just need to display the results, don't perform output + // buffering - for speed + $_cache_including = $this->_cache_including; + $this->_cache_including = false; + if ($display && !$this->caching && count($this->_plugins['outputfilter']) == 0) { + if ($this->_is_compiled($resource_name, $_smarty_compile_path) + || $this->_compile_resource($resource_name, $_smarty_compile_path)) + { + include($_smarty_compile_path); + } + } else { + ob_start(); + if ($this->_is_compiled($resource_name, $_smarty_compile_path) + || $this->_compile_resource($resource_name, $_smarty_compile_path)) + { + include($_smarty_compile_path); + } + $_smarty_results = ob_get_contents(); + ob_end_clean(); + + foreach ((array)$this->_plugins['outputfilter'] as $_output_filter) { + $_smarty_results = call_user_func_array($_output_filter[0], array($_smarty_results, &$this)); + } + } + + if ($this->caching) { + $_params = array('tpl_file' => $resource_name, + 'cache_id' => $cache_id, + 'compile_id' => $compile_id, + 'results' => $_smarty_results); + require_once(SMARTY_CORE_DIR . 'core.write_cache_file.php'); + smarty_core_write_cache_file($_params, $this); + require_once(SMARTY_CORE_DIR . 'core.process_cached_inserts.php'); + $_smarty_results = smarty_core_process_cached_inserts($_params, $this); + + if ($this->_cache_serials) { + // strip nocache-tags from output + $_smarty_results = preg_replace('!(\{/?nocache\:[0-9a-f]{32}#\d+\})!s' + ,'' + ,$_smarty_results); + } + // restore initial cache_info + $this->_cache_info = array_pop($_cache_info); + } + $this->_cache_including = $_cache_including; + + if ($display) { + if (isset($_smarty_results)) { echo $_smarty_results; } + if ($this->debugging) { + // capture time for debugging info + $_params = array(); + require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); + $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = (smarty_core_get_microtime($_params, $this) - $_debug_start_time); + require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php'); + echo smarty_core_display_debug_console($_params, $this); + } + error_reporting($_smarty_old_error_level); + return; + } else { + error_reporting($_smarty_old_error_level); + if (isset($_smarty_results)) { return $_smarty_results; } + } + } + + /** + * load configuration values + * + * @param string $file + * @param string $section + * @param string $scope + */ + function config_load($file, $section = null, $scope = 'global') + { + require_once($this->_get_plugin_filepath('function', 'config_load')); + smarty_function_config_load(array('file' => $file, 'section' => $section, 'scope' => $scope), $this); + } + + /** + * return a reference to a registered object + * + * @param string $name + * @return object + */ + function &get_registered_object($name) { + if (!isset($this->_reg_objects[$name])) + $this->_trigger_fatal_error("'$name' is not a registered object"); + + if (!is_object($this->_reg_objects[$name][0])) + $this->_trigger_fatal_error("registered '$name' is not an object"); + + return $this->_reg_objects[$name][0]; + } + + /** + * clear configuration values + * + * @param string $var + */ + function clear_config($var = null) + { + if(!isset($var)) { + // clear all values + $this->_config = array(array('vars' => array(), + 'files' => array())); + } else { + unset($this->_config[0]['vars'][$var]); + } + } + + /** + * get filepath of requested plugin + * + * @param string $type + * @param string $name + * @return string|false + */ + function _get_plugin_filepath($type, $name) + { + $_params = array('type' => $type, 'name' => $name); + require_once(SMARTY_CORE_DIR . 'core.assemble_plugin_filepath.php'); + return smarty_core_assemble_plugin_filepath($_params, $this); + } + + /** + * test if resource needs compiling + * + * @param string $resource_name + * @param string $compile_path + * @return boolean + */ + function _is_compiled($resource_name, $compile_path) + { + if (!$this->force_compile && file_exists($compile_path)) { + if (!$this->compile_check) { + // no need to check compiled file + return true; + } else { + // get file source and timestamp + $_params = array('resource_name' => $resource_name, 'get_source'=>false); + if (!$this->_fetch_resource_info($_params)) { + return false; + } + if ($_params['resource_timestamp'] <= filemtime($compile_path)) { + // template not expired, no recompile + return true; + } else { + // compile template + return false; + } + } + } else { + // compiled template does not exist, or forced compile + return false; + } + } + + /** + * compile the template + * + * @param string $resource_name + * @param string $compile_path + * @return boolean + */ + function _compile_resource($resource_name, $compile_path) + { + + $_params = array('resource_name' => $resource_name); + if (!$this->_fetch_resource_info($_params)) { + return false; + } + + $_source_content = $_params['source_content']; + $_cache_include = substr($compile_path, 0, -4).'.inc'; + + if ($this->_compile_source($resource_name, $_source_content, $_compiled_content, $_cache_include)) { + // if a _cache_serial was set, we also have to write an include-file: + if ($this->_cache_include_info) { + require_once(SMARTY_CORE_DIR . 'core.write_compiled_include.php'); + smarty_core_write_compiled_include(array_merge($this->_cache_include_info, array('compiled_content'=>$_compiled_content, 'resource_name'=>$resource_name)), $this); + } + + $_params = array('compile_path'=>$compile_path, 'compiled_content' => $_compiled_content); + require_once(SMARTY_CORE_DIR . 'core.write_compiled_resource.php'); + smarty_core_write_compiled_resource($_params, $this); + + return true; + } else { + return false; + } + + } + + /** + * compile the given source + * + * @param string $resource_name + * @param string $source_content + * @param string $compiled_content + * @return boolean + */ + function _compile_source($resource_name, &$source_content, &$compiled_content, $cache_include_path=null) + { + if (file_exists(SMARTY_DIR . $this->compiler_file)) { + require_once(SMARTY_DIR . $this->compiler_file); + } else { + // use include_path + require_once($this->compiler_file); + } + + + $smarty_compiler = new $this->compiler_class; + + $smarty_compiler->template_dir = $this->template_dir; + $smarty_compiler->compile_dir = $this->compile_dir; + $smarty_compiler->plugins_dir = $this->plugins_dir; + $smarty_compiler->config_dir = $this->config_dir; + $smarty_compiler->force_compile = $this->force_compile; + $smarty_compiler->caching = $this->caching; + $smarty_compiler->php_handling = $this->php_handling; + $smarty_compiler->left_delimiter = $this->left_delimiter; + $smarty_compiler->right_delimiter = $this->right_delimiter; + $smarty_compiler->_version = $this->_version; + $smarty_compiler->security = $this->security; + $smarty_compiler->secure_dir = $this->secure_dir; + $smarty_compiler->security_settings = $this->security_settings; + $smarty_compiler->trusted_dir = $this->trusted_dir; + $smarty_compiler->use_sub_dirs = $this->use_sub_dirs; + $smarty_compiler->_reg_objects = &$this->_reg_objects; + $smarty_compiler->_plugins = &$this->_plugins; + $smarty_compiler->_tpl_vars = &$this->_tpl_vars; + $smarty_compiler->default_modifiers = $this->default_modifiers; + $smarty_compiler->compile_id = $this->_compile_id; + $smarty_compiler->_config = $this->_config; + $smarty_compiler->request_use_auto_globals = $this->request_use_auto_globals; + + if (isset($cache_include_path) && isset($this->_cache_serials[$cache_include_path])) { + $smarty_compiler->_cache_serial = $this->_cache_serials[$cache_include_path]; + } + $smarty_compiler->_cache_include = $cache_include_path; + + + $_results = $smarty_compiler->_compile_file($resource_name, $source_content, $compiled_content); + + if ($smarty_compiler->_cache_serial) { + $this->_cache_include_info = array( + 'cache_serial'=>$smarty_compiler->_cache_serial + ,'plugins_code'=>$smarty_compiler->_plugins_code + ,'include_file_path' => $cache_include_path); + + } else { + $this->_cache_include_info = null; + + } + + return $_results; + } + + /** + * Get the compile path for this resource + * + * @param string $resource_name + * @return string results of {@link _get_auto_filename()} + */ + function _get_compile_path($resource_name) + { + return $this->_get_auto_filename($this->compile_dir, $resource_name, + $this->_compile_id) . '.php'; + } + + /** + * fetch the template info. Gets timestamp, and source + * if get_source is true + * + * sets $source_content to the source of the template, and + * $resource_timestamp to its time stamp + * @param string $resource_name + * @param string $source_content + * @param integer $resource_timestamp + * @param boolean $get_source + * @param boolean $quiet + * @return boolean + */ + + function _fetch_resource_info(&$params) + { + if(!isset($params['get_source'])) { $params['get_source'] = true; } + if(!isset($params['quiet'])) { $params['quiet'] = false; } + + $_return = false; + $_params = array('resource_name' => $params['resource_name']) ; + if (isset($params['resource_base_path'])) + $_params['resource_base_path'] = $params['resource_base_path']; + else + $_params['resource_base_path'] = $this->template_dir; + + if ($this->_parse_resource_name($_params)) { + $_resource_type = $_params['resource_type']; + $_resource_name = $_params['resource_name']; + switch ($_resource_type) { + case 'file': + if ($params['get_source']) { + $params['source_content'] = $this->_read_file($_resource_name); + } + $params['resource_timestamp'] = filemtime($_resource_name); + $_return = is_file($_resource_name); + break; + + default: + // call resource functions to fetch the template source and timestamp + if ($params['get_source']) { + $_source_return = isset($this->_plugins['resource'][$_resource_type]) && + call_user_func_array($this->_plugins['resource'][$_resource_type][0][0], + array($_resource_name, &$params['source_content'], &$this)); + } else { + $_source_return = true; + } + + $_timestamp_return = isset($this->_plugins['resource'][$_resource_type]) && + call_user_func_array($this->_plugins['resource'][$_resource_type][0][1], + array($_resource_name, &$params['resource_timestamp'], &$this)); + + $_return = $_source_return && $_timestamp_return; + break; + } + } + + if (!$_return) { + // see if we can get a template with the default template handler + if (!empty($this->default_template_handler_func)) { + if (!is_callable($this->default_template_handler_func)) { + $this->trigger_error("default template handler function \"$this->default_template_handler_func\" doesn't exist."); + } else { + $_return = call_user_func_array( + $this->default_template_handler_func, + array($_params['resource_type'], $_params['resource_name'], &$params['source_content'], &$params['resource_timestamp'], &$this)); + } + } + } + + if (!$_return) { + if (!$params['quiet']) { + $this->trigger_error('unable to read resource: "' . $params['resource_name'] . '"'); + } + } else if ($_return && $this->security) { + require_once(SMARTY_CORE_DIR . 'core.is_secure.php'); + if (!smarty_core_is_secure($_params, $this)) { + if (!$params['quiet']) + $this->trigger_error('(secure mode) accessing "' . $params['resource_name'] . '" is not allowed'); + $params['source_content'] = null; + $params['resource_timestamp'] = null; + return false; + } + } + return $_return; + } + + + /** + * parse out the type and name from the resource + * + * @param string $resource_base_path + * @param string $resource_name + * @param string $resource_type + * @param string $resource_name + * @return boolean + */ + + function _parse_resource_name(&$params) + { + + // split tpl_path by the first colon + $_resource_name_parts = explode(':', $params['resource_name'], 2); + + if (count($_resource_name_parts) == 1) { + // no resource type given + $params['resource_type'] = $this->default_resource_type; + $params['resource_name'] = $_resource_name_parts[0]; + } else { + if(strlen($_resource_name_parts[0]) == 1) { + // 1 char is not resource type, but part of filepath + $params['resource_type'] = $this->default_resource_type; + $params['resource_name'] = $params['resource_name']; + } else { + $params['resource_type'] = $_resource_name_parts[0]; + $params['resource_name'] = $_resource_name_parts[1]; + } + } + + if ($params['resource_type'] == 'file') { + if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $params['resource_name'])) { + // relative pathname to $params['resource_base_path'] + // use the first directory where the file is found + foreach ((array)$params['resource_base_path'] as $_curr_path) { + $_fullpath = $_curr_path . DIRECTORY_SEPARATOR . $params['resource_name']; + if (file_exists($_fullpath) && is_file($_fullpath)) { + $params['resource_name'] = $_fullpath; + return true; + } + // didn't find the file, try include_path + $_params = array('file_path' => $_fullpath); + require_once(SMARTY_CORE_DIR . 'core.get_include_path.php'); + if(smarty_core_get_include_path($_params, $this)) { + $params['resource_name'] = $_params['new_file_path']; + return true; + } + } + return false; + } else { + /* absolute path */ + return file_exists($params['resource_name']); + } + } elseif (empty($this->_plugins['resource'][$params['resource_type']])) { + $_params = array('type' => $params['resource_type']); + require_once(SMARTY_CORE_DIR . 'core.load_resource_plugin.php'); + smarty_core_load_resource_plugin($_params, $this); + } + + return true; + } + + + /** + * Handle modifiers + * + * @param string|null $modifier_name + * @param array|null $map_array + * @return string result of modifiers + */ + function _run_mod_handler() + { + $_args = func_get_args(); + list($_modifier_name, $_map_array) = array_splice($_args, 0, 2); + list($_func_name, $_tpl_file, $_tpl_line) = + $this->_plugins['modifier'][$_modifier_name]; + + $_var = $_args[0]; + foreach ($_var as $_key => $_val) { + $_args[0] = $_val; + $_var[$_key] = call_user_func_array($_func_name, $_args); + } + return $_var; + } + + /** + * Remove starting and ending quotes from the string + * + * @param string $string + * @return string + */ + function _dequote($string) + { + if ((substr($string, 0, 1) == "'" || substr($string, 0, 1) == '"') && + substr($string, -1) == substr($string, 0, 1)) + return substr($string, 1, -1); + else + return $string; + } + + + /** + * read in a file + * + * @param string $filename + * @return string + */ + function _read_file($filename) + { + if ( file_exists($filename) && ($fd = @fopen($filename, 'rb')) ) { + $contents = ''; + while (!feof($fd)) { + $contents .= fread($fd, 8192); + } + fclose($fd); + return $contents; + } else { + return false; + } + } + + /** + * get a concrete filename for automagically created content + * + * @param string $auto_base + * @param string $auto_source + * @param string $auto_id + * @return string + * @staticvar string|null + * @staticvar string|null + */ + function _get_auto_filename($auto_base, $auto_source = null, $auto_id = null) + { + $_compile_dir_sep = $this->use_sub_dirs ? DIRECTORY_SEPARATOR : '^'; + $_return = $auto_base . DIRECTORY_SEPARATOR; + + if(isset($auto_id)) { + // make auto_id safe for directory names + $auto_id = str_replace('%7C',$_compile_dir_sep,(urlencode($auto_id))); + // split into separate directories + $_return .= $auto_id . $_compile_dir_sep; + } + + if(isset($auto_source)) { + // make source name safe for filename + $_filename = urlencode(basename($auto_source)); + $_crc32 = sprintf('%08X', crc32($auto_source)); + // prepend %% to avoid name conflicts with + // with $params['auto_id'] names + $_crc32 = substr($_crc32, 0, 2) . $_compile_dir_sep . + substr($_crc32, 0, 3) . $_compile_dir_sep . $_crc32; + $_return .= '%%' . $_crc32 . '%%' . $_filename; + } + + return $_return; + } + + /** + * unlink a file, possibly using expiration time + * + * @param string $resource + * @param integer $exp_time + */ + function _unlink($resource, $exp_time = null) + { + if(isset($exp_time)) { + if(time() - @filemtime($resource) >= $exp_time) { + return @unlink($resource); + } + } else { + return @unlink($resource); + } + } + + /** + * returns an auto_id for auto-file-functions + * + * @param string $cache_id + * @param string $compile_id + * @return string|null + */ + function _get_auto_id($cache_id=null, $compile_id=null) { + if (isset($cache_id)) + return (isset($compile_id)) ? $cache_id . '|' . $compile_id : $cache_id; + elseif(isset($compile_id)) + return $compile_id; + else + return null; + } + + /** + * trigger Smarty plugin error + * + * @param string $error_msg + * @param string $tpl_file + * @param integer $tpl_line + * @param string $file + * @param integer $line + * @param integer $error_type + */ + function _trigger_fatal_error($error_msg, $tpl_file = null, $tpl_line = null, + $file = null, $line = null, $error_type = E_USER_ERROR) + { + if(isset($file) && isset($line)) { + $info = ' ('.basename($file).", line $line)"; + } else { + $info = ''; + } + if (isset($tpl_line) && isset($tpl_file)) { + $this->trigger_error('[in ' . $tpl_file . ' line ' . $tpl_line . "]: $error_msg$info", $error_type); + } else { + $this->trigger_error($error_msg . $info, $error_type); + } + } + + + /** + * callback function for preg_replace, to call a non-cacheable block + * @return string + */ + function _process_compiled_include_callback($match) { + $_func = '_smarty_tplfunc_'.$match[2].'_'.$match[3]; + ob_start(); + $_func($this); + $_ret = ob_get_contents(); + ob_end_clean(); + return $_ret; + } + + + /** + * called for included templates + * + * @param string $_smarty_include_tpl_file + * @param string $_smarty_include_vars + */ + + // $_smarty_include_tpl_file, $_smarty_include_vars + + function _smarty_include($params) + { + if ($this->debugging) { + $_params = array(); + require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); + $debug_start_time = smarty_core_get_microtime($_params, $this); + $this->_smarty_debug_info[] = array('type' => 'template', + 'filename' => $params['smarty_include_tpl_file'], + 'depth' => ++$this->_inclusion_depth); + $included_tpls_idx = count($this->_smarty_debug_info) - 1; + } + + $this->_tpl_vars = array_merge($this->_tpl_vars, $params['smarty_include_vars']); + + // config vars are treated as local, so push a copy of the + // current ones onto the front of the stack + array_unshift($this->_config, $this->_config[0]); + + $_smarty_compile_path = $this->_get_compile_path($params['smarty_include_tpl_file']); + + + if ($this->_is_compiled($params['smarty_include_tpl_file'], $_smarty_compile_path) + || $this->_compile_resource($params['smarty_include_tpl_file'], $_smarty_compile_path)) + { + include($_smarty_compile_path); + } + + // pop the local vars off the front of the stack + array_shift($this->_config); + + $this->_inclusion_depth--; + + if ($this->debugging) { + // capture time for debugging info + $_params = array(); + require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); + $this->_smarty_debug_info[$included_tpls_idx]['exec_time'] = smarty_core_get_microtime($_params, $this) - $debug_start_time; + } + + if ($this->caching) { + $this->_cache_info['template'][$params['smarty_include_tpl_file']] = true; + } + } + + + /** + * get or set an array of cached attributes for function that is + * not cacheable + * @return array + */ + function &_smarty_cache_attrs($cache_serial, $count) { + $_cache_attrs =& $this->_cache_info['cache_attrs'][$cache_serial][$count]; + + if ($this->_cache_including) { + /* return next set of cache_attrs */ + $_return = current($_cache_attrs); + next($_cache_attrs); + return $_return; + + } else { + /* add a reference to a new set of cache_attrs */ + $_cache_attrs[] = array(); + return $_cache_attrs[count($_cache_attrs)-1]; + + } + + } + + + /** + * wrapper for include() retaining $this + * @return mixed + */ + function _include($filename, $once=false, $params=null) + { + if ($once) { + return include_once($filename); + } else { + return include($filename); + } + } + + + /** + * wrapper for eval() retaining $this + * @return mixed + */ + function _eval($code, $params=null) + { + return eval($code); + } + /**#@-*/ + +} + +/* vim: set expandtab: */ + +?> diff --git a/upload/includes/templatelib/Template_Compiler.class.php b/upload/includes/templatelib/Template_Compiler.class.php new file mode 100644 index 00000000..a3a527d3 --- /dev/null +++ b/upload/includes/templatelib/Template_Compiler.class.php @@ -0,0 +1,2327 @@ + + * @author Andrei Zmievski + * @version 2.6.18 + * @copyright 2001-2005 New Digital Group, Inc. + * @package Smarty + */ + +/* $Id$ */ + +/** + * Template compiling class + * @package Smarty + */ +//@require('Template.class.php'); +class Smarty_Compiler extends Smarty { + + // internal vars + /**#@+ + * @access private + */ + var $_folded_blocks = array(); // keeps folded template blocks + var $_current_file = null; // the current template being compiled + var $_current_line_no = 1; // line number for error messages + var $_capture_stack = array(); // keeps track of nested capture buffers + var $_plugin_info = array(); // keeps track of plugins to load + var $_init_smarty_vars = false; + var $_permitted_tokens = array('true','false','yes','no','on','off','null'); + var $_db_qstr_regexp = null; // regexps are setup in the constructor + var $_si_qstr_regexp = null; + var $_qstr_regexp = null; + var $_func_regexp = null; + var $_reg_obj_regexp = null; + var $_var_bracket_regexp = null; + var $_num_const_regexp = null; + var $_dvar_guts_regexp = null; + var $_dvar_regexp = null; + var $_cvar_regexp = null; + var $_svar_regexp = null; + var $_avar_regexp = null; + var $_mod_regexp = null; + var $_var_regexp = null; + var $_parenth_param_regexp = null; + var $_func_call_regexp = null; + var $_obj_ext_regexp = null; + var $_obj_start_regexp = null; + var $_obj_params_regexp = null; + var $_obj_call_regexp = null; + var $_cacheable_state = 0; + var $_cache_attrs_count = 0; + var $_nocache_count = 0; + var $_cache_serial = null; + var $_cache_include = null; + + var $_strip_depth = 0; + var $_additional_newline = "\n"; + + /**#@-*/ + /** + * The class constructor. + */ + function Smarty_Compiler() + { + // matches double quoted strings: + // "foobar" + // "foo\"bar" + $this->_db_qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"'; + + // matches single quoted strings: + // 'foobar' + // 'foo\'bar' + $this->_si_qstr_regexp = '\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\''; + + // matches single or double quoted strings + $this->_qstr_regexp = '(?:' . $this->_db_qstr_regexp . '|' . $this->_si_qstr_regexp . ')'; + + // matches bracket portion of vars + // [0] + // [foo] + // [$bar] + $this->_var_bracket_regexp = '\[\$?[\w\.]+\]'; + + // matches numerical constants + // 30 + // -12 + // 13.22 + $this->_num_const_regexp = '(?:\-?\d+(?:\.\d+)?)'; + + // matches $ vars (not objects): + // $foo + // $foo.bar + // $foo.bar.foobar + // $foo[0] + // $foo[$bar] + // $foo[5][blah] + // $foo[5].bar[$foobar][4] + $this->_dvar_math_regexp = '(?:[\+\*\/\%]|(?:-(?!>)))'; + $this->_dvar_math_var_regexp = '[\$\w\.\+\-\*\/\%\d\>\[\]]'; + $this->_dvar_guts_regexp = '\w+(?:' . $this->_var_bracket_regexp + . ')*(?:\.\$?\w+(?:' . $this->_var_bracket_regexp . ')*)*(?:' . $this->_dvar_math_regexp . '(?:' . $this->_num_const_regexp . '|' . $this->_dvar_math_var_regexp . ')*)?'; + $this->_dvar_regexp = '\$' . $this->_dvar_guts_regexp; + + // matches config vars: + // #foo# + // #foobar123_foo# + $this->_cvar_regexp = '\#\w+\#'; + + // matches section vars: + // %foo.bar% + $this->_svar_regexp = '\%\w+\.\w+\%'; + + // matches all valid variables (no quotes, no modifiers) + $this->_avar_regexp = '(?:' . $this->_dvar_regexp . '|' + . $this->_cvar_regexp . '|' . $this->_svar_regexp . ')'; + + // matches valid variable syntax: + // $foo + // $foo + // #foo# + // #foo# + // "text" + // "text" + $this->_var_regexp = '(?:' . $this->_avar_regexp . '|' . $this->_qstr_regexp . ')'; + + // matches valid object call (one level of object nesting allowed in parameters): + // $foo->bar + // $foo->bar() + // $foo->bar("text") + // $foo->bar($foo, $bar, "text") + // $foo->bar($foo, "foo") + // $foo->bar->foo() + // $foo->bar->foo->bar() + // $foo->bar($foo->bar) + // $foo->bar($foo->bar()) + // $foo->bar($foo->bar($blah,$foo,44,"foo",$foo[0].bar)) + $this->_obj_ext_regexp = '\->(?:\$?' . $this->_dvar_guts_regexp . ')'; + $this->_obj_restricted_param_regexp = '(?:' + . '(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . ')(?:' . $this->_obj_ext_regexp . '(?:\((?:(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . ')' + . '(?:\s*,\s*(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . '))*)?\))?)*)'; + $this->_obj_single_param_regexp = '(?:\w+|' . $this->_obj_restricted_param_regexp . '(?:\s*,\s*(?:(?:\w+|' + . $this->_var_regexp . $this->_obj_restricted_param_regexp . ')))*)'; + $this->_obj_params_regexp = '\((?:' . $this->_obj_single_param_regexp + . '(?:\s*,\s*' . $this->_obj_single_param_regexp . ')*)?\)'; + $this->_obj_start_regexp = '(?:' . $this->_dvar_regexp . '(?:' . $this->_obj_ext_regexp . ')+)'; + $this->_obj_call_regexp = '(?:' . $this->_obj_start_regexp . '(?:' . $this->_obj_params_regexp . ')?(?:' . $this->_dvar_math_regexp . '(?:' . $this->_num_const_regexp . '|' . $this->_dvar_math_var_regexp . ')*)?)'; + + // matches valid modifier syntax: + // |foo + // |@foo + // |foo:"bar" + // |foo:$bar + // |foo:"bar":$foobar + // |foo|bar + // |foo:$foo->bar + $this->_mod_regexp = '(?:\|@?\w+(?::(?:\w+|' . $this->_num_const_regexp . '|' + . $this->_obj_call_regexp . '|' . $this->_avar_regexp . '|' . $this->_qstr_regexp .'))*)'; + + // matches valid function name: + // foo123 + // _foo_bar + $this->_func_regexp = '[a-zA-Z_]\w*'; + + // matches valid registered object: + // foo->bar + $this->_reg_obj_regexp = '[a-zA-Z_]\w*->[a-zA-Z_]\w*'; + + // matches valid parameter values: + // true + // $foo + // $foo|bar + // #foo# + // #foo#|bar + // "text" + // "text"|bar + // $foo->bar + $this->_param_regexp = '(?:\s*(?:' . $this->_obj_call_regexp . '|' + . $this->_var_regexp . '|' . $this->_num_const_regexp . '|\w+)(?>' . $this->_mod_regexp . '*)\s*)'; + + // matches valid parenthesised function parameters: + // + // "text" + // $foo, $bar, "text" + // $foo|bar, "foo"|bar, $foo->bar($foo)|bar + $this->_parenth_param_regexp = '(?:\((?:\w+|' + . $this->_param_regexp . '(?:\s*,\s*(?:(?:\w+|' + . $this->_param_regexp . ')))*)?\))'; + + // matches valid function call: + // foo() + // foo_bar($foo) + // _foo_bar($foo,"bar") + // foo123($foo,$foo->bar(),"foo") + $this->_func_call_regexp = '(?:' . $this->_func_regexp . '\s*(?:' + . $this->_parenth_param_regexp . '))'; + } + + /** + * compile a resource + * + * sets $compiled_content to the compiled source + * @param string $resource_name + * @param string $source_content + * @param string $compiled_content + * @return true + */ + function _compile_file($resource_name, $source_content, &$compiled_content) + { + + if ($this->security) { + // do not allow php syntax to be executed unless specified + if ($this->php_handling == SMARTY_PHP_ALLOW && + !$this->security_settings['PHP_HANDLING']) { + $this->php_handling = SMARTY_PHP_PASSTHRU; + } + } + + $this->_load_filters(); + + $this->_current_file = $resource_name; + $this->_current_line_no = 1; + $ldq = preg_quote($this->left_delimiter, '~'); + $rdq = preg_quote($this->right_delimiter, '~'); + + // run template source through prefilter functions + if (count($this->_plugins['prefilter']) > 0) { + foreach ($this->_plugins['prefilter'] as $filter_name => $prefilter) { + if ($prefilter === false) continue; + if ($prefilter[3] || is_callable($prefilter[0])) { + $source_content = call_user_func_array($prefilter[0], + array($source_content, &$this)); + $this->_plugins['prefilter'][$filter_name][3] = true; + } else { + $this->_trigger_fatal_error("[plugin] prefilter '$filter_name' is not implemented"); + } + } + } + + /* fetch all special blocks */ + $search = "~{$ldq}\*(.*?)\*{$rdq}|{$ldq}\s*literal\s*{$rdq}(.*?){$ldq}\s*/literal\s*{$rdq}|{$ldq}\s*php\s*{$rdq}(.*?){$ldq}\s*/php\s*{$rdq}~s"; + + preg_match_all($search, $source_content, $match, PREG_SET_ORDER); + $this->_folded_blocks = $match; + reset($this->_folded_blocks); + + /* replace special blocks by "{php}" */ + $source_content = preg_replace($search.'e', "'" + . $this->_quote_replace($this->left_delimiter) . 'php' + . "' . str_repeat(\"\n\", substr_count('\\0', \"\n\")) .'" + . $this->_quote_replace($this->right_delimiter) + . "'" + , $source_content); + + /* Gather all template tags. */ + preg_match_all("~{$ldq}\s*(.*?)\s*{$rdq}~s", $source_content, $_match); + $template_tags = $_match[1]; + /* Split content by template tags to obtain non-template content. */ + $text_blocks = preg_split("~{$ldq}.*?{$rdq}~s", $source_content); + + /* loop through text blocks */ + for ($curr_tb = 0, $for_max = count($text_blocks); $curr_tb < $for_max; $curr_tb++) { + /* match anything resembling php tags */ + if (preg_match_all('~(<\?(?:\w+|=)?|\?>|language\s*=\s*[\"\']?\s*php\s*[\"\']?)~is', $text_blocks[$curr_tb], $sp_match)) { + /* replace tags with placeholders to prevent recursive replacements */ + $sp_match[1] = array_unique($sp_match[1]); + usort($sp_match[1], '_smarty_sort_length'); + for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++) { + $text_blocks[$curr_tb] = str_replace($sp_match[1][$curr_sp],'%%%SMARTYSP'.$curr_sp.'%%%',$text_blocks[$curr_tb]); + } + /* process each one */ + for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++) { + if ($this->php_handling == SMARTY_PHP_PASSTHRU) { + /* echo php contents */ + $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', ''."\n", $text_blocks[$curr_tb]); + } else if ($this->php_handling == SMARTY_PHP_QUOTE) { + /* quote php tags */ + $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', htmlspecialchars($sp_match[1][$curr_sp]), $text_blocks[$curr_tb]); + } else if ($this->php_handling == SMARTY_PHP_REMOVE) { + /* remove php tags */ + $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', '', $text_blocks[$curr_tb]); + } else { + /* SMARTY_PHP_ALLOW, but echo non php starting tags */ + $sp_match[1][$curr_sp] = preg_replace('~(<\?(?!php|=|$))~i', ''."\n", $sp_match[1][$curr_sp]); + $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', $sp_match[1][$curr_sp], $text_blocks[$curr_tb]); + } + } + } + } + + /* Compile the template tags into PHP code. */ + $compiled_tags = array(); + for ($i = 0, $for_max = count($template_tags); $i < $for_max; $i++) { + $this->_current_line_no += substr_count($text_blocks[$i], "\n"); + $compiled_tags[] = $this->_compile_tag($template_tags[$i]); + $this->_current_line_no += substr_count($template_tags[$i], "\n"); + } + if (count($this->_tag_stack)>0) { + list($_open_tag, $_line_no) = end($this->_tag_stack); + $this->_syntax_error("unclosed tag \{$_open_tag} (opened line $_line_no).", E_USER_ERROR, __FILE__, __LINE__); + return; + } + + /* Reformat $text_blocks between 'strip' and '/strip' tags, + removing spaces, tabs and newlines. */ + $strip = false; + for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) { + if ($compiled_tags[$i] == '{strip}') { + $compiled_tags[$i] = ''; + $strip = true; + /* remove leading whitespaces */ + $text_blocks[$i + 1] = ltrim($text_blocks[$i + 1]); + } + if ($strip) { + /* strip all $text_blocks before the next '/strip' */ + for ($j = $i + 1; $j < $for_max; $j++) { + /* remove leading and trailing whitespaces of each line */ + $text_blocks[$j] = preg_replace('![\t ]*[\r\n]+[\t ]*!', '', $text_blocks[$j]); + if ($compiled_tags[$j] == '{/strip}') { + /* remove trailing whitespaces from the last text_block */ + $text_blocks[$j] = rtrim($text_blocks[$j]); + } + $text_blocks[$j] = ""\'", "\\"=>"\\\\")) . "'; ?>"; + if ($compiled_tags[$j] == '{/strip}') { + $compiled_tags[$j] = "\n"; /* slurped by php, but necessary + if a newline is following the closing strip-tag */ + $strip = false; + $i = $j; + break; + } + } + } + } + $compiled_content = ''; + + $tag_guard = '%%%SMARTYOTG' . md5(uniqid(rand(), true)) . '%%%'; + + /* Interleave the compiled contents and text blocks to get the final result. */ + for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) { + if ($compiled_tags[$i] == '') { + // tag result empty, remove first newline from following text block + $text_blocks[$i+1] = preg_replace('~^(\r\n|\r|\n)~', '', $text_blocks[$i+1]); + } + // replace legit PHP tags with placeholder + $text_blocks[$i] = str_replace('\n", $compiled_content); + $compiled_content = preg_replace("~(?\n", $compiled_content); + + // recover legit tags + $compiled_content = str_replace($tag_guard, '_cache_serial)) { + $compiled_content = "_cache_serials['".$this->_cache_include."'] = '".$this->_cache_serial."'; ?>" . $compiled_content; + } + + // run compiled template through postfilter functions + if (count($this->_plugins['postfilter']) > 0) { + foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) { + if ($postfilter === false) continue; + if ($postfilter[3] || is_callable($postfilter[0])) { + $compiled_content = call_user_func_array($postfilter[0], + array($compiled_content, &$this)); + $this->_plugins['postfilter'][$filter_name][3] = true; + } else { + $this->_trigger_fatal_error("Smarty plugin error: postfilter '$filter_name' is not implemented"); + } + } + } + + // put header at the top of the compiled template + $template_header = "_version.", created on ".strftime("%Y-%m-%d %H:%M:%S")."\n"; + $template_header .= " compiled from ".strtr(urlencode($resource_name), array('%2F'=>'/', '%3A'=>':'))." */ ?>\n"; + + /* Emit code to load needed plugins. */ + $this->_plugins_code = ''; + if (count($this->_plugin_info)) { + $_plugins_params = "array('plugins' => array("; + foreach ($this->_plugin_info as $plugin_type => $plugins) { + foreach ($plugins as $plugin_name => $plugin_info) { + $_plugins_params .= "array('$plugin_type', '$plugin_name', '" . strtr($plugin_info[0], array("'" => "\\'", "\\" => "\\\\")) . "', $plugin_info[1], "; + $_plugins_params .= $plugin_info[2] ? 'true),' : 'false),'; + } + } + $_plugins_params .= '))'; + $plugins_code = "\n"; + $template_header .= $plugins_code; + $this->_plugin_info = array(); + $this->_plugins_code = $plugins_code; + } + + if ($this->_init_smarty_vars) { + $template_header .= "\n"; + $this->_init_smarty_vars = false; + } + + $compiled_content = $template_header . $compiled_content; + return true; + } + + /** + * Compile a template tag + * + * @param string $template_tag + * @return string + */ + function _compile_tag($template_tag) + { + /* Matched comment. */ + if (substr($template_tag, 0, 1) == '*' && substr($template_tag, -1) == '*') + return ''; + + /* Split tag into two three parts: command, command modifiers and the arguments. */ + if(! preg_match('~^(?:(' . $this->_num_const_regexp . '|' . $this->_obj_call_regexp . '|' . $this->_var_regexp + . '|\/?' . $this->_reg_obj_regexp . '|\/?' . $this->_func_regexp . ')(' . $this->_mod_regexp . '*)) + (?:\s+(.*))?$ + ~xs', $template_tag, $match)) { + $this->_syntax_error("unrecognized tag: $template_tag", E_USER_ERROR, __FILE__, __LINE__); + } + + $tag_command = $match[1]; + $tag_modifier = isset($match[2]) ? $match[2] : null; + $tag_args = isset($match[3]) ? $match[3] : null; + + if (preg_match('~^' . $this->_num_const_regexp . '|' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '$~', $tag_command)) { + /* tag name is a variable or object */ + $_return = $this->_parse_var_props($tag_command . $tag_modifier); + return "" . $this->_additional_newline; + } + + /* If the tag name is a registered object, we process it. */ + if (preg_match('~^\/?' . $this->_reg_obj_regexp . '$~', $tag_command)) { + return $this->_compile_registered_object_tag($tag_command, $this->_parse_attrs($tag_args), $tag_modifier); + } + + switch ($tag_command) { + case 'include': + return $this->_compile_include_tag($tag_args); + + case 'include_php': + return $this->_compile_include_php_tag($tag_args); + + case 'if': + $this->_push_tag('if'); + return $this->_compile_if_tag($tag_args); + + case 'else': + list($_open_tag) = end($this->_tag_stack); + if ($_open_tag != 'if' && $_open_tag != 'elseif') + $this->_syntax_error('unexpected {else}', E_USER_ERROR, __FILE__, __LINE__); + else + $this->_push_tag('else'); + return ''; + + case 'elseif': + list($_open_tag) = end($this->_tag_stack); + if ($_open_tag != 'if' && $_open_tag != 'elseif') + $this->_syntax_error('unexpected {elseif}', E_USER_ERROR, __FILE__, __LINE__); + if ($_open_tag == 'if') + $this->_push_tag('elseif'); + return $this->_compile_if_tag($tag_args, true); + + case '/if': + $this->_pop_tag('if'); + return ''; + + case 'capture': + return $this->_compile_capture_tag(true, $tag_args); + + case '/capture': + return $this->_compile_capture_tag(false); + + case 'ldelim': + return $this->left_delimiter; + + case 'rdelim': + return $this->right_delimiter; + + case 'section': + $this->_push_tag('section'); + return $this->_compile_section_start($tag_args); + + case 'sectionelse': + $this->_push_tag('sectionelse'); + return ""; + break; + + case '/section': + $_open_tag = $this->_pop_tag('section'); + if ($_open_tag == 'sectionelse') + return ""; + else + return ""; + + case 'foreach': + $this->_push_tag('foreach'); + return $this->_compile_foreach_start($tag_args); + break; + + case 'foreachelse': + $this->_push_tag('foreachelse'); + return ""; + + case '/foreach': + $_open_tag = $this->_pop_tag('foreach'); + if ($_open_tag == 'foreachelse') + return ""; + else + return ""; + break; + + case 'strip': + case '/strip': + if (substr($tag_command, 0, 1)=='/') { + $this->_pop_tag('strip'); + if (--$this->_strip_depth==0) { /* outermost closing {/strip} */ + $this->_additional_newline = "\n"; + return '{' . $tag_command . '}'; + } + } else { + $this->_push_tag('strip'); + if ($this->_strip_depth++==0) { /* outermost opening {strip} */ + $this->_additional_newline = ""; + return '{' . $tag_command . '}'; + } + } + return ''; + + case 'php': + /* handle folded tags replaced by {php} */ + list(, $block) = each($this->_folded_blocks); + $this->_current_line_no += substr_count($block[0], "\n"); + /* the number of matched elements in the regexp in _compile_file() + determins the type of folded tag that was found */ + switch (count($block)) { + case 2: /* comment */ + return ''; + + case 3: /* literal */ + return ""\'", "\\"=>"\\\\")) . "'; ?>" . $this->_additional_newline; + + case 4: /* php */ + if ($this->security && !$this->security_settings['PHP_TAGS']) { + $this->_syntax_error("(secure mode) php tags not permitted", E_USER_WARNING, __FILE__, __LINE__); + return; + } + return ''; + } + break; + + case 'insert': + return $this->_compile_insert_tag($tag_args); + + default: + if ($this->_compile_compiler_tag($tag_command, $tag_args, $output)) { + return $output; + } else if ($this->_compile_block_tag($tag_command, $tag_args, $tag_modifier, $output)) { + return $output; + } else if ($this->_compile_custom_tag($tag_command, $tag_args, $tag_modifier, $output)) { + return $output; + } else { + $this->_syntax_error("unrecognized tag '$tag_command'", E_USER_ERROR, __FILE__, __LINE__); + } + + } + } + + + /** + * compile the custom compiler tag + * + * sets $output to the compiled custom compiler tag + * @param string $tag_command + * @param string $tag_args + * @param string $output + * @return boolean + */ + function _compile_compiler_tag($tag_command, $tag_args, &$output) + { + $found = false; + $have_function = true; + + /* + * First we check if the compiler function has already been registered + * or loaded from a plugin file. + */ + if (isset($this->_plugins['compiler'][$tag_command])) { + $found = true; + $plugin_func = $this->_plugins['compiler'][$tag_command][0]; + if (!is_callable($plugin_func)) { + $message = "compiler function '$tag_command' is not implemented"; + $have_function = false; + } + } + /* + * Otherwise we need to load plugin file and look for the function + * inside it. + */ + else if ($plugin_file = $this->_get_plugin_filepath('compiler', $tag_command)) { + $found = true; + + include_once $plugin_file; + + $plugin_func = 'smarty_compiler_' . $tag_command; + if (!is_callable($plugin_func)) { + $message = "plugin function $plugin_func() not found in $plugin_file\n"; + $have_function = false; + } else { + $this->_plugins['compiler'][$tag_command] = array($plugin_func, null, null, null, true); + } + } + + /* + * True return value means that we either found a plugin or a + * dynamically registered function. False means that we didn't and the + * compiler should now emit code to load custom function plugin for this + * tag. + */ + if ($found) { + if ($have_function) { + $output = call_user_func_array($plugin_func, array($tag_args, &$this)); + if($output != '') { + $output = '_push_cacheable_state('compiler', $tag_command) + . $output + . $this->_pop_cacheable_state('compiler', $tag_command) . ' ?>'; + } + } else { + $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__); + } + return true; + } else { + return false; + } + } + + + /** + * compile block function tag + * + * sets $output to compiled block function tag + * @param string $tag_command + * @param string $tag_args + * @param string $tag_modifier + * @param string $output + * @return boolean + */ + function _compile_block_tag($tag_command, $tag_args, $tag_modifier, &$output) + { + if (substr($tag_command, 0, 1) == '/') { + $start_tag = false; + $tag_command = substr($tag_command, 1); + } else + $start_tag = true; + + $found = false; + $have_function = true; + + /* + * First we check if the block function has already been registered + * or loaded from a plugin file. + */ + if (isset($this->_plugins['block'][$tag_command])) { + $found = true; + $plugin_func = $this->_plugins['block'][$tag_command][0]; + if (!is_callable($plugin_func)) { + $message = "block function '$tag_command' is not implemented"; + $have_function = false; + } + } + /* + * Otherwise we need to load plugin file and look for the function + * inside it. + */ + else if ($plugin_file = $this->_get_plugin_filepath('block', $tag_command)) { + $found = true; + + include_once $plugin_file; + + $plugin_func = 'smarty_block_' . $tag_command; + if (!function_exists($plugin_func)) { + $message = "plugin function $plugin_func() not found in $plugin_file\n"; + $have_function = false; + } else { + $this->_plugins['block'][$tag_command] = array($plugin_func, null, null, null, true); + + } + } + + if (!$found) { + return false; + } else if (!$have_function) { + $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__); + return true; + } + + /* + * Even though we've located the plugin function, compilation + * happens only once, so the plugin will still need to be loaded + * at runtime for future requests. + */ + $this->_add_plugin('block', $tag_command); + + if ($start_tag) + $this->_push_tag($tag_command); + else + $this->_pop_tag($tag_command); + + if ($start_tag) { + $output = '_push_cacheable_state('block', $tag_command); + $attrs = $this->_parse_attrs($tag_args); + $_cache_attrs=''; + $arg_list = $this->_compile_arg_list('block', $tag_command, $attrs, $_cache_attrs); + $output .= "$_cache_attrs\$this->_tag_stack[] = array('$tag_command', array(".implode(',', $arg_list).')); '; + $output .= '$_block_repeat=true;' . $this->_compile_plugin_call('block', $tag_command).'($this->_tag_stack[count($this->_tag_stack)-1][1], null, $this, $_block_repeat);'; + $output .= 'while ($_block_repeat) { ob_start(); ?>'; + } else { + $output = '_compile_plugin_call('block', $tag_command).'($this->_tag_stack[count($this->_tag_stack)-1][1], $_block_content, $this, $_block_repeat)'; + if ($tag_modifier != '') { + $this->_parse_modifiers($_out_tag_text, $tag_modifier); + } + $output .= '$_block_repeat=false;echo ' . $_out_tag_text . '; } '; + $output .= " array_pop(\$this->_tag_stack); " . $this->_pop_cacheable_state('block', $tag_command) . '?>'; + } + + return true; + } + + + /** + * compile custom function tag + * + * @param string $tag_command + * @param string $tag_args + * @param string $tag_modifier + * @return string + */ + function _compile_custom_tag($tag_command, $tag_args, $tag_modifier, &$output) + { + $found = false; + $have_function = true; + + /* + * First we check if the custom function has already been registered + * or loaded from a plugin file. + */ + if (isset($this->_plugins['function'][$tag_command])) { + $found = true; + $plugin_func = $this->_plugins['function'][$tag_command][0]; + if (!is_callable($plugin_func)) { + $message = "custom function '$tag_command' is not implemented"; + $have_function = false; + } + } + /* + * Otherwise we need to load plugin file and look for the function + * inside it. + */ + else if ($plugin_file = $this->_get_plugin_filepath('function', $tag_command)) { + $found = true; + + include_once $plugin_file; + + $plugin_func = 'smarty_function_' . $tag_command; + if (!function_exists($plugin_func)) { + $message = "plugin function $plugin_func() not found in $plugin_file\n"; + $have_function = false; + } else { + $this->_plugins['function'][$tag_command] = array($plugin_func, null, null, null, true); + + } + } + + if (!$found) { + return false; + } else if (!$have_function) { + $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__); + return true; + } + + /* declare plugin to be loaded on display of the template that + we compile right now */ + $this->_add_plugin('function', $tag_command); + + $_cacheable_state = $this->_push_cacheable_state('function', $tag_command); + $attrs = $this->_parse_attrs($tag_args); + $_cache_attrs = ''; + $arg_list = $this->_compile_arg_list('function', $tag_command, $attrs, $_cache_attrs); + + $output = $this->_compile_plugin_call('function', $tag_command).'(array('.implode(',', $arg_list)."), \$this)"; + if($tag_modifier != '') { + $this->_parse_modifiers($output, $tag_modifier); + } + + if($output != '') { + $output = '_pop_cacheable_state('function', $tag_command) . "?>" . $this->_additional_newline; + } + + return true; + } + + /** + * compile a registered object tag + * + * @param string $tag_command + * @param array $attrs + * @param string $tag_modifier + * @return string + */ + function _compile_registered_object_tag($tag_command, $attrs, $tag_modifier) + { + if (substr($tag_command, 0, 1) == '/') { + $start_tag = false; + $tag_command = substr($tag_command, 1); + } else { + $start_tag = true; + } + + list($object, $obj_comp) = explode('->', $tag_command); + + $arg_list = array(); + if(count($attrs)) { + $_assign_var = false; + foreach ($attrs as $arg_name => $arg_value) { + if($arg_name == 'assign') { + $_assign_var = $arg_value; + unset($attrs['assign']); + continue; + } + if (is_bool($arg_value)) + $arg_value = $arg_value ? 'true' : 'false'; + $arg_list[] = "'$arg_name' => $arg_value"; + } + } + + if($this->_reg_objects[$object][2]) { + // smarty object argument format + $args = "array(".implode(',', (array)$arg_list)."), \$this"; + } else { + // traditional argument format + $args = implode(',', array_values($attrs)); + if (empty($args)) { + $args = 'null'; + } + } + + $prefix = ''; + $postfix = ''; + $newline = ''; + if(!is_object($this->_reg_objects[$object][0])) { + $this->_trigger_fatal_error("registered '$object' is not an object" , $this->_current_file, $this->_current_line_no, __FILE__, __LINE__); + } elseif(!empty($this->_reg_objects[$object][1]) && !in_array($obj_comp, $this->_reg_objects[$object][1])) { + $this->_trigger_fatal_error("'$obj_comp' is not a registered component of object '$object'", $this->_current_file, $this->_current_line_no, __FILE__, __LINE__); + } elseif(method_exists($this->_reg_objects[$object][0], $obj_comp)) { + // method + if(in_array($obj_comp, $this->_reg_objects[$object][3])) { + // block method + if ($start_tag) { + $prefix = "\$this->_tag_stack[] = array('$obj_comp', $args); "; + $prefix .= "\$_block_repeat=true; \$this->_reg_objects['$object'][0]->$obj_comp(\$this->_tag_stack[count(\$this->_tag_stack)-1][1], null, \$this, \$_block_repeat); "; + $prefix .= "while (\$_block_repeat) { ob_start();"; + $return = null; + $postfix = ''; + } else { + $prefix = "\$_obj_block_content = ob_get_contents(); ob_end_clean(); \$_block_repeat=false;"; + $return = "\$this->_reg_objects['$object'][0]->$obj_comp(\$this->_tag_stack[count(\$this->_tag_stack)-1][1], \$_obj_block_content, \$this, \$_block_repeat)"; + $postfix = "} array_pop(\$this->_tag_stack);"; + } + } else { + // non-block method + $return = "\$this->_reg_objects['$object'][0]->$obj_comp($args)"; + } + } else { + // property + $return = "\$this->_reg_objects['$object'][0]->$obj_comp"; + } + + if($return != null) { + if($tag_modifier != '') { + $this->_parse_modifiers($return, $tag_modifier); + } + + if(!empty($_assign_var)) { + $output = "\$this->assign('" . $this->_dequote($_assign_var) ."', $return);"; + } else { + $output = 'echo ' . $return . ';'; + $newline = $this->_additional_newline; + } + } else { + $output = ''; + } + + return '" . $newline; + } + + /** + * Compile {insert ...} tag + * + * @param string $tag_args + * @return string + */ + function _compile_insert_tag($tag_args) + { + $attrs = $this->_parse_attrs($tag_args); + $name = $this->_dequote($attrs['name']); + + if (empty($name)) { + return $this->_syntax_error("missing insert name", E_USER_ERROR, __FILE__, __LINE__); + } + + if (!preg_match('~^\w+$~', $name)) { + return $this->_syntax_error("'insert: 'name' must be an insert function name", E_USER_ERROR, __FILE__, __LINE__); + } + + if (!empty($attrs['script'])) { + $delayed_loading = true; + } else { + $delayed_loading = false; + } + + foreach ($attrs as $arg_name => $arg_value) { + if (is_bool($arg_value)) + $arg_value = $arg_value ? 'true' : 'false'; + $arg_list[] = "'$arg_name' => $arg_value"; + } + + $this->_add_plugin('insert', $name, $delayed_loading); + + $_params = "array('args' => array(".implode(', ', (array)$arg_list)."))"; + + return "" . $this->_additional_newline; + } + + /** + * Compile {include ...} tag + * + * @param string $tag_args + * @return string + */ + function _compile_include_tag($tag_args) + { + $attrs = $this->_parse_attrs($tag_args); + $arg_list = array(); + + if (empty($attrs['file'])) { + $this->_syntax_error("missing 'file' attribute in include tag", E_USER_ERROR, __FILE__, __LINE__); + } + + foreach ($attrs as $arg_name => $arg_value) { + if ($arg_name == 'file') { + $include_file = $arg_value; + continue; + } else if ($arg_name == 'assign') { + $assign_var = $arg_value; + continue; + } + if (is_bool($arg_value)) + $arg_value = $arg_value ? 'true' : 'false'; + $arg_list[] = "'$arg_name' => $arg_value"; + } + + $output = '_tpl_vars;\n"; + + + $_params = "array('smarty_include_tpl_file' => " . $include_file . ", 'smarty_include_vars' => array(".implode(',', (array)$arg_list)."))"; + $output .= "\$this->_smarty_include($_params);\n" . + "\$this->_tpl_vars = \$_smarty_tpl_vars;\n" . + "unset(\$_smarty_tpl_vars);\n"; + + if (isset($assign_var)) { + $output .= "\$this->assign(" . $assign_var . ", ob_get_contents()); ob_end_clean();\n"; + } + + $output .= ' ?>'; + + return $output; + + } + + /** + * Compile {include ...} tag + * + * @param string $tag_args + * @return string + */ + function _compile_include_php_tag($tag_args) + { + $attrs = $this->_parse_attrs($tag_args); + + if (empty($attrs['file'])) { + $this->_syntax_error("missing 'file' attribute in include_php tag", E_USER_ERROR, __FILE__, __LINE__); + } + + $assign_var = (empty($attrs['assign'])) ? '' : $this->_dequote($attrs['assign']); + $once_var = (empty($attrs['once']) || $attrs['once']=='false') ? 'false' : 'true'; + + $arg_list = array(); + foreach($attrs as $arg_name => $arg_value) { + if($arg_name != 'file' AND $arg_name != 'once' AND $arg_name != 'assign') { + if(is_bool($arg_value)) + $arg_value = $arg_value ? 'true' : 'false'; + $arg_list[] = "'$arg_name' => $arg_value"; + } + } + + $_params = "array('smarty_file' => " . $attrs['file'] . ", 'smarty_assign' => '$assign_var', 'smarty_once' => $once_var, 'smarty_include_vars' => array(".implode(',', $arg_list)."))"; + + return "" . $this->_additional_newline; + } + + + /** + * Compile {section ...} tag + * + * @param string $tag_args + * @return string + */ + function _compile_section_start($tag_args) + { + $attrs = $this->_parse_attrs($tag_args); + $arg_list = array(); + + $output = '_syntax_error("missing section name", E_USER_ERROR, __FILE__, __LINE__); + } + + $output .= "unset(\$this->_sections[$section_name]);\n"; + $section_props = "\$this->_sections[$section_name]"; + + foreach ($attrs as $attr_name => $attr_value) { + switch ($attr_name) { + case 'loop': + $output .= "{$section_props}['loop'] = is_array(\$_loop=$attr_value) ? count(\$_loop) : max(0, (int)\$_loop); unset(\$_loop);\n"; + break; + + case 'show': + if (is_bool($attr_value)) + $show_attr_value = $attr_value ? 'true' : 'false'; + else + $show_attr_value = "(bool)$attr_value"; + $output .= "{$section_props}['show'] = $show_attr_value;\n"; + break; + + case 'name': + $output .= "{$section_props}['$attr_name'] = $attr_value;\n"; + break; + + case 'max': + case 'start': + $output .= "{$section_props}['$attr_name'] = (int)$attr_value;\n"; + break; + + case 'step': + $output .= "{$section_props}['$attr_name'] = ((int)$attr_value) == 0 ? 1 : (int)$attr_value;\n"; + break; + + default: + $this->_syntax_error("unknown section attribute - '$attr_name'", E_USER_ERROR, __FILE__, __LINE__); + break; + } + } + + if (!isset($attrs['show'])) + $output .= "{$section_props}['show'] = true;\n"; + + if (!isset($attrs['loop'])) + $output .= "{$section_props}['loop'] = 1;\n"; + + if (!isset($attrs['max'])) + $output .= "{$section_props}['max'] = {$section_props}['loop'];\n"; + else + $output .= "if ({$section_props}['max'] < 0)\n" . + " {$section_props}['max'] = {$section_props}['loop'];\n"; + + if (!isset($attrs['step'])) + $output .= "{$section_props}['step'] = 1;\n"; + + if (!isset($attrs['start'])) + $output .= "{$section_props}['start'] = {$section_props}['step'] > 0 ? 0 : {$section_props}['loop']-1;\n"; + else { + $output .= "if ({$section_props}['start'] < 0)\n" . + " {$section_props}['start'] = max({$section_props}['step'] > 0 ? 0 : -1, {$section_props}['loop'] + {$section_props}['start']);\n" . + "else\n" . + " {$section_props}['start'] = min({$section_props}['start'], {$section_props}['step'] > 0 ? {$section_props}['loop'] : {$section_props}['loop']-1);\n"; + } + + $output .= "if ({$section_props}['show']) {\n"; + if (!isset($attrs['start']) && !isset($attrs['step']) && !isset($attrs['max'])) { + $output .= " {$section_props}['total'] = {$section_props}['loop'];\n"; + } else { + $output .= " {$section_props}['total'] = min(ceil(({$section_props}['step'] > 0 ? {$section_props}['loop'] - {$section_props}['start'] : {$section_props}['start']+1)/abs({$section_props}['step'])), {$section_props}['max']);\n"; + } + $output .= " if ({$section_props}['total'] == 0)\n" . + " {$section_props}['show'] = false;\n" . + "} else\n" . + " {$section_props}['total'] = 0;\n"; + + $output .= "if ({$section_props}['show']):\n"; + $output .= " + for ({$section_props}['index'] = {$section_props}['start'], {$section_props}['iteration'] = 1; + {$section_props}['iteration'] <= {$section_props}['total']; + {$section_props}['index'] += {$section_props}['step'], {$section_props}['iteration']++):\n"; + $output .= "{$section_props}['rownum'] = {$section_props}['iteration'];\n"; + $output .= "{$section_props}['index_prev'] = {$section_props}['index'] - {$section_props}['step'];\n"; + $output .= "{$section_props}['index_next'] = {$section_props}['index'] + {$section_props}['step'];\n"; + $output .= "{$section_props}['first'] = ({$section_props}['iteration'] == 1);\n"; + $output .= "{$section_props}['last'] = ({$section_props}['iteration'] == {$section_props}['total']);\n"; + + $output .= "?>"; + + return $output; + } + + + /** + * Compile {foreach ...} tag. + * + * @param string $tag_args + * @return string + */ + function _compile_foreach_start($tag_args) + { + $attrs = $this->_parse_attrs($tag_args); + $arg_list = array(); + + if (empty($attrs['from'])) { + return $this->_syntax_error("foreach: missing 'from' attribute", E_USER_ERROR, __FILE__, __LINE__); + } + $from = $attrs['from']; + + if (empty($attrs['item'])) { + return $this->_syntax_error("foreach: missing 'item' attribute", E_USER_ERROR, __FILE__, __LINE__); + } + $item = $this->_dequote($attrs['item']); + if (!preg_match('~^\w+$~', $item)) { + return $this->_syntax_error("'foreach: 'item' must be a variable name (literal string)", E_USER_ERROR, __FILE__, __LINE__); + } + + if (isset($attrs['key'])) { + $key = $this->_dequote($attrs['key']); + if (!preg_match('~^\w+$~', $key)) { + return $this->_syntax_error("foreach: 'key' must to be a variable name (literal string)", E_USER_ERROR, __FILE__, __LINE__); + } + $key_part = "\$this->_tpl_vars['$key'] => "; + } else { + $key = null; + $key_part = ''; + } + + if (isset($attrs['name'])) { + $name = $attrs['name']; + } else { + $name = null; + } + + $output = '_foreach[$name]"; + $output .= "{$foreach_props} = array('total' => count(\$_from), 'iteration' => 0);\n"; + $output .= "if ({$foreach_props}['total'] > 0):\n"; + $output .= " foreach (\$_from as $key_part\$this->_tpl_vars['$item']):\n"; + $output .= " {$foreach_props}['iteration']++;\n"; + } else { + $output .= "if (count(\$_from)):\n"; + $output .= " foreach (\$_from as $key_part\$this->_tpl_vars['$item']):\n"; + } + $output .= '?>'; + + return $output; + } + + + /** + * Compile {capture} .. {/capture} tags + * + * @param boolean $start true if this is the {capture} tag + * @param string $tag_args + * @return string + */ + + function _compile_capture_tag($start, $tag_args = '') + { + $attrs = $this->_parse_attrs($tag_args); + + if ($start) { + if (isset($attrs['name'])) + $buffer = $attrs['name']; + else + $buffer = "'default'"; + + if (isset($attrs['assign'])) + $assign = $attrs['assign']; + else + $assign = null; + $output = ""; + $this->_capture_stack[] = array($buffer, $assign); + } else { + list($buffer, $assign) = array_pop($this->_capture_stack); + $output = "_smarty_vars['capture'][$buffer] = ob_get_contents(); "; + if (isset($assign)) { + $output .= " \$this->assign($assign, ob_get_contents());"; + } + $output .= "ob_end_clean(); ?>"; + } + + return $output; + } + + /** + * Compile {if ...} tag + * + * @param string $tag_args + * @param boolean $elseif if true, uses elseif instead of if + * @return string + */ + function _compile_if_tag($tag_args, $elseif = false) + { + + /* Tokenize args for 'if' tag. */ + preg_match_all('~(?> + ' . $this->_obj_call_regexp . '(?:' . $this->_mod_regexp . '*)? | # valid object call + ' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)? | # var or quoted string + \-?0[xX][0-9a-fA-F]+|\-?\d+(?:\.\d+)?|\.\d+|!==|===|==|!=|<>|<<|>>|<=|>=|\&\&|\|\||\(|\)|,|\!|\^|=|\&|\~|<|>|\||\%|\+|\-|\/|\*|\@ | # valid non-word token + \b\w+\b | # valid word token + \S+ # anything else + )~x', $tag_args, $match); + + $tokens = $match[0]; + + if(empty($tokens)) { + $_error_msg = $elseif ? "'elseif'" : "'if'"; + $_error_msg .= ' statement requires arguments'; + $this->_syntax_error($_error_msg, E_USER_ERROR, __FILE__, __LINE__); + } + + + // make sure we have balanced parenthesis + $token_count = array_count_values($tokens); + if(isset($token_count['(']) && $token_count['('] != $token_count[')']) { + $this->_syntax_error("unbalanced parenthesis in if statement", E_USER_ERROR, __FILE__, __LINE__); + } + + $is_arg_stack = array(); + + for ($i = 0; $i < count($tokens); $i++) { + + $token = &$tokens[$i]; + + switch (strtolower($token)) { + case '!': + case '%': + case '!==': + case '==': + case '===': + case '>': + case '<': + case '!=': + case '<>': + case '<<': + case '>>': + case '<=': + case '>=': + case '&&': + case '||': + case '|': + case '^': + case '&': + case '~': + case ')': + case ',': + case '+': + case '-': + case '*': + case '/': + case '@': + break; + + case 'eq': + $token = '=='; + break; + + case 'ne': + case 'neq': + $token = '!='; + break; + + case 'lt': + $token = '<'; + break; + + case 'le': + case 'lte': + $token = '<='; + break; + + case 'gt': + $token = '>'; + break; + + case 'ge': + case 'gte': + $token = '>='; + break; + + case 'and': + $token = '&&'; + break; + + case 'or': + $token = '||'; + break; + + case 'not': + $token = '!'; + break; + + case 'mod': + $token = '%'; + break; + + case '(': + array_push($is_arg_stack, $i); + break; + + case 'is': + /* If last token was a ')', we operate on the parenthesized + expression. The start of the expression is on the stack. + Otherwise, we operate on the last encountered token. */ + if ($tokens[$i-1] == ')') + $is_arg_start = array_pop($is_arg_stack); + else + $is_arg_start = $i-1; + /* Construct the argument for 'is' expression, so it knows + what to operate on. */ + $is_arg = implode(' ', array_slice($tokens, $is_arg_start, $i - $is_arg_start)); + + /* Pass all tokens from next one until the end to the + 'is' expression parsing function. The function will + return modified tokens, where the first one is the result + of the 'is' expression and the rest are the tokens it + didn't touch. */ + $new_tokens = $this->_parse_is_expr($is_arg, array_slice($tokens, $i+1)); + + /* Replace the old tokens with the new ones. */ + array_splice($tokens, $is_arg_start, count($tokens), $new_tokens); + + /* Adjust argument start so that it won't change from the + current position for the next iteration. */ + $i = $is_arg_start; + break; + + default: + if(preg_match('~^' . $this->_func_regexp . '$~', $token) ) { + // function call + if($this->security && + !in_array($token, $this->security_settings['IF_FUNCS'])) { + $this->_syntax_error("(secure mode) '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__); + } + } elseif(preg_match('~^' . $this->_var_regexp . '$~', $token) && (strpos('+-*/^%&|', substr($token, -1)) === false) && isset($tokens[$i+1]) && $tokens[$i+1] == '(') { + // variable function call + $this->_syntax_error("variable function call '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__); + } elseif(preg_match('~^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)$~', $token)) { + // object or variable + $token = $this->_parse_var_props($token); + } elseif(is_numeric($token)) { + // number, skip it + } else { + $this->_syntax_error("unidentified token '$token'", E_USER_ERROR, __FILE__, __LINE__); + } + break; + } + } + + if ($elseif) + return ''; + else + return ''; + } + + + function _compile_arg_list($type, $name, $attrs, &$cache_code) { + $arg_list = array(); + + if (isset($type) && isset($name) + && isset($this->_plugins[$type]) + && isset($this->_plugins[$type][$name]) + && empty($this->_plugins[$type][$name][4]) + && is_array($this->_plugins[$type][$name][5]) + ) { + /* we have a list of parameters that should be cached */ + $_cache_attrs = $this->_plugins[$type][$name][5]; + $_count = $this->_cache_attrs_count++; + $cache_code = "\$_cache_attrs =& \$this->_smarty_cache_attrs('$this->_cache_serial','$_count');"; + + } else { + /* no parameters are cached */ + $_cache_attrs = null; + } + + foreach ($attrs as $arg_name => $arg_value) { + if (is_bool($arg_value)) + $arg_value = $arg_value ? 'true' : 'false'; + if (is_null($arg_value)) + $arg_value = 'null'; + if ($_cache_attrs && in_array($arg_name, $_cache_attrs)) { + $arg_list[] = "'$arg_name' => (\$this->_cache_including) ? \$_cache_attrs['$arg_name'] : (\$_cache_attrs['$arg_name']=$arg_value)"; + } else { + $arg_list[] = "'$arg_name' => $arg_value"; + } + } + return $arg_list; + } + + /** + * Parse is expression + * + * @param string $is_arg + * @param array $tokens + * @return array + */ + function _parse_is_expr($is_arg, $tokens) + { + $expr_end = 0; + $negate_expr = false; + + if (($first_token = array_shift($tokens)) == 'not') { + $negate_expr = true; + $expr_type = array_shift($tokens); + } else + $expr_type = $first_token; + + switch ($expr_type) { + case 'even': + if (isset($tokens[$expr_end]) && $tokens[$expr_end] == 'by') { + $expr_end++; + $expr_arg = $tokens[$expr_end++]; + $expr = "!(1 & ($is_arg / " . $this->_parse_var_props($expr_arg) . "))"; + } else + $expr = "!(1 & $is_arg)"; + break; + + case 'odd': + if (isset($tokens[$expr_end]) && $tokens[$expr_end] == 'by') { + $expr_end++; + $expr_arg = $tokens[$expr_end++]; + $expr = "(1 & ($is_arg / " . $this->_parse_var_props($expr_arg) . "))"; + } else + $expr = "(1 & $is_arg)"; + break; + + case 'div': + if (@$tokens[$expr_end] == 'by') { + $expr_end++; + $expr_arg = $tokens[$expr_end++]; + $expr = "!($is_arg % " . $this->_parse_var_props($expr_arg) . ")"; + } else { + $this->_syntax_error("expecting 'by' after 'div'", E_USER_ERROR, __FILE__, __LINE__); + } + break; + + default: + $this->_syntax_error("unknown 'is' expression - '$expr_type'", E_USER_ERROR, __FILE__, __LINE__); + break; + } + + if ($negate_expr) { + $expr = "!($expr)"; + } + + array_splice($tokens, 0, $expr_end, $expr); + + return $tokens; + } + + + /** + * Parse attribute string + * + * @param string $tag_args + * @return array + */ + function _parse_attrs($tag_args) + { + + /* Tokenize tag attributes. */ + preg_match_all('~(?:' . $this->_obj_call_regexp . '|' . $this->_qstr_regexp . ' | (?>[^"\'=\s]+) + )+ | + [=] + ~x', $tag_args, $match); + $tokens = $match[0]; + + $attrs = array(); + /* Parse state: + 0 - expecting attribute name + 1 - expecting '=' + 2 - expecting attribute value (not '=') */ + $state = 0; + + foreach ($tokens as $token) { + switch ($state) { + case 0: + /* If the token is a valid identifier, we set attribute name + and go to state 1. */ + if (preg_match('~^\w+$~', $token)) { + $attr_name = $token; + $state = 1; + } else + $this->_syntax_error("invalid attribute name: '$token'", E_USER_ERROR, __FILE__, __LINE__); + break; + + case 1: + /* If the token is '=', then we go to state 2. */ + if ($token == '=') { + $state = 2; + } else + $this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__); + break; + + case 2: + /* If token is not '=', we set the attribute value and go to + state 0. */ + if ($token != '=') { + /* We booleanize the token if it's a non-quoted possible + boolean value. */ + if (preg_match('~^(on|yes|true)$~', $token)) { + $token = 'true'; + } else if (preg_match('~^(off|no|false)$~', $token)) { + $token = 'false'; + } else if ($token == 'null') { + $token = 'null'; + } else if (preg_match('~^' . $this->_num_const_regexp . '|0[xX][0-9a-fA-F]+$~', $token)) { + /* treat integer literally */ + } else if (!preg_match('~^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . ')*$~', $token)) { + /* treat as a string, double-quote it escaping quotes */ + $token = '"'.addslashes($token).'"'; + } + + $attrs[$attr_name] = $token; + $state = 0; + } else + $this->_syntax_error("'=' cannot be an attribute value", E_USER_ERROR, __FILE__, __LINE__); + break; + } + $last_token = $token; + } + + if($state != 0) { + if($state == 1) { + $this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__); + } else { + $this->_syntax_error("missing attribute value", E_USER_ERROR, __FILE__, __LINE__); + } + } + + $this->_parse_vars_props($attrs); + + return $attrs; + } + + /** + * compile multiple variables and section properties tokens into + * PHP code + * + * @param array $tokens + */ + function _parse_vars_props(&$tokens) + { + foreach($tokens as $key => $val) { + $tokens[$key] = $this->_parse_var_props($val); + } + } + + /** + * compile single variable and section properties token into + * PHP code + * + * @param string $val + * @param string $tag_attrs + * @return string + */ + function _parse_var_props($val) + { + $val = trim($val); + + if(preg_match('~^(' . $this->_obj_call_regexp . '|' . $this->_dvar_regexp . ')(' . $this->_mod_regexp . '*)$~', $val, $match)) { + // $ variable or object + $return = $this->_parse_var($match[1]); + $modifiers = $match[2]; + if (!empty($this->default_modifiers) && !preg_match('~(^|\|)smarty:nodefaults($|\|)~',$modifiers)) { + $_default_mod_string = implode('|',(array)$this->default_modifiers); + $modifiers = empty($modifiers) ? $_default_mod_string : $_default_mod_string . '|' . $modifiers; + } + $this->_parse_modifiers($return, $modifiers); + return $return; + } elseif (preg_match('~^' . $this->_db_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) { + // double quoted text + preg_match('~^(' . $this->_db_qstr_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match); + $return = $this->_expand_quoted_text($match[1]); + if($match[2] != '') { + $this->_parse_modifiers($return, $match[2]); + } + return $return; + } + elseif(preg_match('~^' . $this->_num_const_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) { + // numerical constant + preg_match('~^(' . $this->_num_const_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match); + if($match[2] != '') { + $this->_parse_modifiers($match[1], $match[2]); + return $match[1]; + } + } + elseif(preg_match('~^' . $this->_si_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) { + // single quoted text + preg_match('~^(' . $this->_si_qstr_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match); + if($match[2] != '') { + $this->_parse_modifiers($match[1], $match[2]); + return $match[1]; + } + } + elseif(preg_match('~^' . $this->_cvar_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) { + // config var + return $this->_parse_conf_var($val); + } + elseif(preg_match('~^' . $this->_svar_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) { + // section var + return $this->_parse_section_prop($val); + } + elseif(!in_array($val, $this->_permitted_tokens) && !is_numeric($val)) { + // literal string + return $this->_expand_quoted_text('"' . strtr($val, array('\\' => '\\\\', '"' => '\\"')) .'"'); + } + return $val; + } + + /** + * expand quoted text with embedded variables + * + * @param string $var_expr + * @return string + */ + function _expand_quoted_text($var_expr) + { + // if contains unescaped $, expand it + if(preg_match_all('~(?:\`(?_dvar_guts_regexp . '(?:' . $this->_obj_ext_regexp . ')*\`)|(?:(?_parse_var(str_replace('`','',$_var)) . ')."'; + } + $var_expr = strtr($var_expr, $_replace); + $_return = preg_replace('~\.""|(?_dvar_math_regexp.'|'.$this->_qstr_regexp.')~', $var_expr, -1, PREG_SPLIT_DELIM_CAPTURE); + + if(count($_math_vars) > 1) { + $_first_var = ""; + $_complete_var = ""; + $_output = ""; + // simple check if there is any math, to stop recursion (due to modifiers with "xx % yy" as parameter) + foreach($_math_vars as $_k => $_math_var) { + $_math_var = $_math_vars[$_k]; + + if(!empty($_math_var) || is_numeric($_math_var)) { + // hit a math operator, so process the stuff which came before it + if(preg_match('~^' . $this->_dvar_math_regexp . '$~', $_math_var)) { + $_has_math = true; + if(!empty($_complete_var) || is_numeric($_complete_var)) { + $_output .= $this->_parse_var($_complete_var); + } + + // just output the math operator to php + $_output .= $_math_var; + + if(empty($_first_var)) + $_first_var = $_complete_var; + + $_complete_var = ""; + } else { + $_complete_var .= $_math_var; + } + } + } + if($_has_math) { + if(!empty($_complete_var) || is_numeric($_complete_var)) + $_output .= $this->_parse_var($_complete_var); + + // get the modifiers working (only the last var from math + modifier is left) + $var_expr = $_complete_var; + } + } + + // prevent cutting of first digit in the number (we _definitly_ got a number if the first char is a digit) + if(is_numeric(substr($var_expr, 0, 1))) + $_var_ref = $var_expr; + else + $_var_ref = substr($var_expr, 1); + + if(!$_has_math) { + + // get [foo] and .foo and ->foo and (...) pieces + preg_match_all('~(?:^\w+)|' . $this->_obj_params_regexp . '|(?:' . $this->_var_bracket_regexp . ')|->\$?\w+|\.\$?\w+|\S+~', $_var_ref, $match); + + $_indexes = $match[0]; + $_var_name = array_shift($_indexes); + + /* Handle $smarty.* variable references as a special case. */ + if ($_var_name == 'smarty') { + /* + * If the reference could be compiled, use the compiled output; + * otherwise, fall back on the $smarty variable generated at + * run-time. + */ + if (($smarty_ref = $this->_compile_smarty_ref($_indexes)) !== null) { + $_output = $smarty_ref; + } else { + $_var_name = substr(array_shift($_indexes), 1); + $_output = "\$this->_smarty_vars['$_var_name']"; + } + } elseif(is_numeric($_var_name) && is_numeric(substr($var_expr, 0, 1))) { + // because . is the operator for accessing arrays thru inidizes we need to put it together again for floating point numbers + if(count($_indexes) > 0) + { + $_var_name .= implode("", $_indexes); + $_indexes = array(); + } + $_output = $_var_name; + } else { + $_output = "\$this->_tpl_vars['$_var_name']"; + } + + foreach ($_indexes as $_index) { + if (substr($_index, 0, 1) == '[') { + $_index = substr($_index, 1, -1); + if (is_numeric($_index)) { + $_output .= "[$_index]"; + } elseif (substr($_index, 0, 1) == '$') { + if (strpos($_index, '.') !== false) { + $_output .= '[' . $this->_parse_var($_index) . ']'; + } else { + $_output .= "[\$this->_tpl_vars['" . substr($_index, 1) . "']]"; + } + } else { + $_var_parts = explode('.', $_index); + $_var_section = $_var_parts[0]; + $_var_section_prop = isset($_var_parts[1]) ? $_var_parts[1] : 'index'; + $_output .= "[\$this->_sections['$_var_section']['$_var_section_prop']]"; + } + } else if (substr($_index, 0, 1) == '.') { + if (substr($_index, 1, 1) == '$') + $_output .= "[\$this->_tpl_vars['" . substr($_index, 2) . "']]"; + else + $_output .= "['" . substr($_index, 1) . "']"; + } else if (substr($_index,0,2) == '->') { + if(substr($_index,2,2) == '__') { + $this->_syntax_error('call to internal object members is not allowed', E_USER_ERROR, __FILE__, __LINE__); + } elseif($this->security && substr($_index, 2, 1) == '_') { + $this->_syntax_error('(secure) call to private object member is not allowed', E_USER_ERROR, __FILE__, __LINE__); + } elseif (substr($_index, 2, 1) == '$') { + if ($this->security) { + $this->_syntax_error('(secure) call to dynamic object member is not allowed', E_USER_ERROR, __FILE__, __LINE__); + } else { + $_output .= '->{(($_var=$this->_tpl_vars[\''.substr($_index,3).'\']) && substr($_var,0,2)!=\'__\') ? $_var : $this->trigger_error("cannot access property \\"$_var\\"")}'; + } + } else { + $_output .= $_index; + } + } elseif (substr($_index, 0, 1) == '(') { + $_index = $this->_parse_parenth_args($_index); + $_output .= $_index; + } else { + $_output .= $_index; + } + } + } + + return $_output; + } + + /** + * parse arguments in function call parenthesis + * + * @param string $parenth_args + * @return string + */ + function _parse_parenth_args($parenth_args) + { + preg_match_all('~' . $this->_param_regexp . '~',$parenth_args, $match); + $orig_vals = $match = $match[0]; + $this->_parse_vars_props($match); + $replace = array(); + for ($i = 0, $count = count($match); $i < $count; $i++) { + $replace[$orig_vals[$i]] = $match[$i]; + } + return strtr($parenth_args, $replace); + } + + /** + * parse configuration variable expression into PHP code + * + * @param string $conf_var_expr + */ + function _parse_conf_var($conf_var_expr) + { + $parts = explode('|', $conf_var_expr, 2); + $var_ref = $parts[0]; + $modifiers = isset($parts[1]) ? $parts[1] : ''; + + $var_name = substr($var_ref, 1, -1); + + $output = "\$this->_config[0]['vars']['$var_name']"; + + $this->_parse_modifiers($output, $modifiers); + + return $output; + } + + /** + * parse section property expression into PHP code + * + * @param string $section_prop_expr + * @return string + */ + function _parse_section_prop($section_prop_expr) + { + $parts = explode('|', $section_prop_expr, 2); + $var_ref = $parts[0]; + $modifiers = isset($parts[1]) ? $parts[1] : ''; + + preg_match('!%(\w+)\.(\w+)%!', $var_ref, $match); + $section_name = $match[1]; + $prop_name = $match[2]; + + $output = "\$this->_sections['$section_name']['$prop_name']"; + + $this->_parse_modifiers($output, $modifiers); + + return $output; + } + + + /** + * parse modifier chain into PHP code + * + * sets $output to parsed modified chain + * @param string $output + * @param string $modifier_string + */ + function _parse_modifiers(&$output, $modifier_string) + { + preg_match_all('~\|(@?\w+)((?>:(?:'. $this->_qstr_regexp . '|[^|]+))*)~', '|' . $modifier_string, $_match); + list(, $_modifiers, $modifier_arg_strings) = $_match; + + for ($_i = 0, $_for_max = count($_modifiers); $_i < $_for_max; $_i++) { + $_modifier_name = $_modifiers[$_i]; + + if($_modifier_name == 'smarty') { + // skip smarty modifier + continue; + } + + preg_match_all('~:(' . $this->_qstr_regexp . '|[^:]+)~', $modifier_arg_strings[$_i], $_match); + $_modifier_args = $_match[1]; + + if (substr($_modifier_name, 0, 1) == '@') { + $_map_array = false; + $_modifier_name = substr($_modifier_name, 1); + } else { + $_map_array = true; + } + + if (empty($this->_plugins['modifier'][$_modifier_name]) + && !$this->_get_plugin_filepath('modifier', $_modifier_name) + && function_exists($_modifier_name)) { + if ($this->security && !in_array($_modifier_name, $this->security_settings['MODIFIER_FUNCS'])) { + $this->_trigger_fatal_error("[plugin] (secure mode) modifier '$_modifier_name' is not allowed" , $this->_current_file, $this->_current_line_no, __FILE__, __LINE__); + } else { + $this->_plugins['modifier'][$_modifier_name] = array($_modifier_name, null, null, false); + } + } + $this->_add_plugin('modifier', $_modifier_name); + + $this->_parse_vars_props($_modifier_args); + + if($_modifier_name == 'default') { + // supress notifications of default modifier vars and args + if(substr($output, 0, 1) == '$') { + $output = '@' . $output; + } + if(isset($_modifier_args[0]) && substr($_modifier_args[0], 0, 1) == '$') { + $_modifier_args[0] = '@' . $_modifier_args[0]; + } + } + if (count($_modifier_args) > 0) + $_modifier_args = ', '.implode(', ', $_modifier_args); + else + $_modifier_args = ''; + + if ($_map_array) { + $output = "((is_array(\$_tmp=$output)) ? \$this->_run_mod_handler('$_modifier_name', true, \$_tmp$_modifier_args) : " . $this->_compile_plugin_call('modifier', $_modifier_name) . "(\$_tmp$_modifier_args))"; + + } else { + + $output = $this->_compile_plugin_call('modifier', $_modifier_name)."($output$_modifier_args)"; + + } + } + } + + + /** + * add plugin + * + * @param string $type + * @param string $name + * @param boolean? $delayed_loading + */ + function _add_plugin($type, $name, $delayed_loading = null) + { + if (!isset($this->_plugin_info[$type])) { + $this->_plugin_info[$type] = array(); + } + if (!isset($this->_plugin_info[$type][$name])) { + $this->_plugin_info[$type][$name] = array($this->_current_file, + $this->_current_line_no, + $delayed_loading); + } + } + + + /** + * Compiles references of type $smarty.foo + * + * @param string $indexes + * @return string + */ + function _compile_smarty_ref(&$indexes) + { + /* Extract the reference name. */ + $_ref = substr($indexes[0], 1); + foreach($indexes as $_index_no=>$_index) { + if (substr($_index, 0, 1) != '.' && $_index_no<2 || !preg_match('~^(\.|\[|->)~', $_index)) { + $this->_syntax_error('$smarty' . implode('', array_slice($indexes, 0, 2)) . ' is an invalid reference', E_USER_ERROR, __FILE__, __LINE__); + } + } + + switch ($_ref) { + case 'now': + $compiled_ref = 'time()'; + $_max_index = 1; + break; + + case 'foreach': + array_shift($indexes); + $_var = $this->_parse_var_props(substr($indexes[0], 1)); + $_propname = substr($indexes[1], 1); + $_max_index = 1; + switch ($_propname) { + case 'index': + array_shift($indexes); + $compiled_ref = "(\$this->_foreach[$_var]['iteration']-1)"; + break; + + case 'first': + array_shift($indexes); + $compiled_ref = "(\$this->_foreach[$_var]['iteration'] <= 1)"; + break; + + case 'last': + array_shift($indexes); + $compiled_ref = "(\$this->_foreach[$_var]['iteration'] == \$this->_foreach[$_var]['total'])"; + break; + + case 'show': + array_shift($indexes); + $compiled_ref = "(\$this->_foreach[$_var]['total'] > 0)"; + break; + + default: + unset($_max_index); + $compiled_ref = "\$this->_foreach[$_var]"; + } + break; + + case 'section': + array_shift($indexes); + $_var = $this->_parse_var_props(substr($indexes[0], 1)); + $compiled_ref = "\$this->_sections[$_var]"; + break; + + case 'get': + $compiled_ref = ($this->request_use_auto_globals) ? '$_GET' : "\$GLOBALS['HTTP_GET_VARS']"; + break; + + case 'post': + $compiled_ref = ($this->request_use_auto_globals) ? '$_POST' : "\$GLOBALS['HTTP_POST_VARS']"; + break; + + case 'cookies': + $compiled_ref = ($this->request_use_auto_globals) ? '$_COOKIE' : "\$GLOBALS['HTTP_COOKIE_VARS']"; + break; + + case 'env': + $compiled_ref = ($this->request_use_auto_globals) ? '$_ENV' : "\$GLOBALS['HTTP_ENV_VARS']"; + break; + + case 'server': + $compiled_ref = ($this->request_use_auto_globals) ? '$_SERVER' : "\$GLOBALS['HTTP_SERVER_VARS']"; + break; + + case 'session': + $compiled_ref = ($this->request_use_auto_globals) ? '$_SESSION' : "\$GLOBALS['HTTP_SESSION_VARS']"; + break; + + /* + * These cases are handled either at run-time or elsewhere in the + * compiler. + */ + case 'request': + if ($this->request_use_auto_globals) { + $compiled_ref = '$_REQUEST'; + break; + } else { + $this->_init_smarty_vars = true; + } + return null; + + case 'capture': + return null; + + case 'template': + $compiled_ref = "'$this->_current_file'"; + $_max_index = 1; + break; + + case 'version': + $compiled_ref = "'$this->_version'"; + $_max_index = 1; + break; + + case 'const': + if ($this->security && !$this->security_settings['ALLOW_CONSTANTS']) { + $this->_syntax_error("(secure mode) constants not permitted", + E_USER_WARNING, __FILE__, __LINE__); + return; + } + array_shift($indexes); + if (preg_match('!^\.\w+$!', $indexes[0])) { + $compiled_ref = '@' . substr($indexes[0], 1); + } else { + $_val = $this->_parse_var_props(substr($indexes[0], 1)); + $compiled_ref = '@constant(' . $_val . ')'; + } + $_max_index = 1; + break; + + case 'config': + $compiled_ref = "\$this->_config[0]['vars']"; + $_max_index = 3; + break; + + case 'ldelim': + $compiled_ref = "'$this->left_delimiter'"; + break; + + case 'rdelim': + $compiled_ref = "'$this->right_delimiter'"; + break; + + default: + $this->_syntax_error('$smarty.' . $_ref . ' is an unknown reference', E_USER_ERROR, __FILE__, __LINE__); + break; + } + + if (isset($_max_index) && count($indexes) > $_max_index) { + $this->_syntax_error('$smarty' . implode('', $indexes) .' is an invalid reference', E_USER_ERROR, __FILE__, __LINE__); + } + + array_shift($indexes); + return $compiled_ref; + } + + /** + * compiles call to plugin of type $type with name $name + * returns a string containing the function-name or method call + * without the paramter-list that would have follow to make the + * call valid php-syntax + * + * @param string $type + * @param string $name + * @return string + */ + function _compile_plugin_call($type, $name) { + if (isset($this->_plugins[$type][$name])) { + /* plugin loaded */ + if (is_array($this->_plugins[$type][$name][0])) { + return ((is_object($this->_plugins[$type][$name][0][0])) ? + "\$this->_plugins['$type']['$name'][0][0]->" /* method callback */ + : (string)($this->_plugins[$type][$name][0][0]).'::' /* class callback */ + ). $this->_plugins[$type][$name][0][1]; + + } else { + /* function callback */ + return $this->_plugins[$type][$name][0]; + + } + } else { + /* plugin not loaded -> auto-loadable-plugin */ + return 'smarty_'.$type.'_'.$name; + + } + } + + /** + * load pre- and post-filters + */ + function _load_filters() + { + if (count($this->_plugins['prefilter']) > 0) { + foreach ($this->_plugins['prefilter'] as $filter_name => $prefilter) { + if ($prefilter === false) { + unset($this->_plugins['prefilter'][$filter_name]); + $_params = array('plugins' => array(array('prefilter', $filter_name, null, null, false))); + require_once(SMARTY_CORE_DIR . 'core.load_plugins.php'); + smarty_core_load_plugins($_params, $this); + } + } + } + if (count($this->_plugins['postfilter']) > 0) { + foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) { + if ($postfilter === false) { + unset($this->_plugins['postfilter'][$filter_name]); + $_params = array('plugins' => array(array('postfilter', $filter_name, null, null, false))); + require_once(SMARTY_CORE_DIR . 'core.load_plugins.php'); + smarty_core_load_plugins($_params, $this); + } + } + } + } + + + /** + * Quote subpattern references + * + * @param string $string + * @return string + */ + function _quote_replace($string) + { + return strtr($string, array('\\' => '\\\\', '$' => '\\$')); + } + + /** + * display Smarty syntax error + * + * @param string $error_msg + * @param integer $error_type + * @param string $file + * @param integer $line + */ + function _syntax_error($error_msg, $error_type = E_USER_ERROR, $file=null, $line=null) + { + $this->_trigger_fatal_error("syntax error: $error_msg", $this->_current_file, $this->_current_line_no, $file, $line, $error_type); + } + + + /** + * check if the compilation changes from cacheable to + * non-cacheable state with the beginning of the current + * plugin. return php-code to reflect the transition. + * @return string + */ + function _push_cacheable_state($type, $name) { + $_cacheable = !isset($this->_plugins[$type][$name]) || $this->_plugins[$type][$name][4]; + if ($_cacheable + || 0<$this->_cacheable_state++) return ''; + if (!isset($this->_cache_serial)) $this->_cache_serial = md5(uniqid('Smarty')); + $_ret = 'if ($this->caching && !$this->_cache_including): echo \'{nocache:' + . $this->_cache_serial . '#' . $this->_nocache_count + . '}\'; endif;'; + return $_ret; + } + + + /** + * check if the compilation changes from non-cacheable to + * cacheable state with the end of the current plugin return + * php-code to reflect the transition. + * @return string + */ + function _pop_cacheable_state($type, $name) { + $_cacheable = !isset($this->_plugins[$type][$name]) || $this->_plugins[$type][$name][4]; + if ($_cacheable + || --$this->_cacheable_state>0) return ''; + return 'if ($this->caching && !$this->_cache_including): echo \'{/nocache:' + . $this->_cache_serial . '#' . ($this->_nocache_count++) + . '}\'; endif;'; + } + + + /** + * push opening tag-name, file-name and line-number on the tag-stack + * @param string the opening tag's name + */ + function _push_tag($open_tag) + { + array_push($this->_tag_stack, array($open_tag, $this->_current_line_no)); + } + + /** + * pop closing tag-name + * raise an error if this stack-top doesn't match with the closing tag + * @param string the closing tag's name + * @return string the opening tag's name + */ + function _pop_tag($close_tag) + { + $message = ''; + if (count($this->_tag_stack)>0) { + list($_open_tag, $_line_no) = array_pop($this->_tag_stack); + if ($close_tag == $_open_tag) { + return $_open_tag; + } + if ($close_tag == 'if' && ($_open_tag == 'else' || $_open_tag == 'elseif' )) { + return $this->_pop_tag($close_tag); + } + if ($close_tag == 'section' && $_open_tag == 'sectionelse') { + $this->_pop_tag($close_tag); + return $_open_tag; + } + if ($close_tag == 'foreach' && $_open_tag == 'foreachelse') { + $this->_pop_tag($close_tag); + return $_open_tag; + } + if ($_open_tag == 'else' || $_open_tag == 'elseif') { + $_open_tag = 'if'; + } elseif ($_open_tag == 'sectionelse') { + $_open_tag = 'section'; + } elseif ($_open_tag == 'foreachelse') { + $_open_tag = 'foreach'; + } + $message = " expected {/$_open_tag} (opened line $_line_no)."; + } + $this->_syntax_error("mismatched tag {/$close_tag}.$message", + E_USER_ERROR, __FILE__, __LINE__); + } + +} + +/** + * compare to values by their string length + * + * @access private + * @param string $a + * @param string $b + * @return 0|-1|1 + */ +function _smarty_sort_length($a, $b) +{ + if($a == $b) + return 0; + + if(strlen($a) == strlen($b)) + return ($a > $b) ? -1 : 1; + + return (strlen($a) > strlen($b)) ? -1 : 1; +} + + +/* vim: set et: */ +?> diff --git a/upload/includes/templatelib/debug.tpl b/upload/includes/templatelib/debug.tpl new file mode 100644 index 00000000..c05ef5d0 --- /dev/null +++ b/upload/includes/templatelib/debug.tpl @@ -0,0 +1,157 @@ +{* Smarty *} +{* debug.tpl, last updated version 2.1.0 *} +{assign_debug_info} +{capture assign=debug_output} + + + + Smarty Debug Console +{literal} + +{/literal} + + + +

    Smarty Debug Console

    + +

    included templates & config files (load time in seconds)

    + +
    +{section name=templates loop=$_debug_tpls} + {section name=indent loop=$_debug_tpls[templates].depth}   {/section} + + {$_debug_tpls[templates].filename|escape:html} + {if isset($_debug_tpls[templates].exec_time)} + + ({$_debug_tpls[templates].exec_time|string_format:"%.5f"}) + {if %templates.index% eq 0}(total){/if} + + {/if} +
    +{sectionelse} +

    no templates included

    +{/section} +
    + +

    assigned template variables

    + + + {section name=vars loop=$_debug_keys} + + + + {sectionelse} + + {/section} +
    {ldelim}${$_debug_keys[vars]|escape:'html'}{rdelim}{$_debug_vals[vars]|@debug_print_var}

    no template variables assigned

    + +

    assigned config file variables (outer template scope)

    + + + {section name=config_vars loop=$_debug_config_keys} + + + + {sectionelse} + + {/section} +
    {ldelim}#{$_debug_config_keys[config_vars]|escape:'html'}#{rdelim}{$_debug_config_vals[config_vars]|@debug_print_var}

    no config vars assigned

    + + +{/capture} +{if isset($_smarty_debug_output) and $_smarty_debug_output eq "html"} + {$debug_output} +{else} + +{/if} \ No newline at end of file diff --git a/upload/includes/templatelib/footer.html b/upload/includes/templatelib/footer.html new file mode 100644 index 00000000..24e59c1b --- /dev/null +++ b/upload/includes/templatelib/footer.html @@ -0,0 +1,11 @@ +{if $view_channel_active == ''} + + + + + +{/if} + + diff --git a/upload/includes/templatelib/header.html b/upload/includes/templatelib/header.html new file mode 100644 index 00000000..9b700480 --- /dev/null +++ b/upload/includes/templatelib/header.html @@ -0,0 +1 @@ + diff --git a/upload/includes/templatelib/index.php b/upload/includes/templatelib/index.php new file mode 100644 index 00000000..403f2e18 --- /dev/null +++ b/upload/includes/templatelib/index.php @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/upload/includes/templatelib/internals/core.assemble_plugin_filepath.php b/upload/includes/templatelib/internals/core.assemble_plugin_filepath.php new file mode 100644 index 00000000..fc64b8c2 --- /dev/null +++ b/upload/includes/templatelib/internals/core.assemble_plugin_filepath.php @@ -0,0 +1,67 @@ +plugins_dir as $_plugin_dir) { + + $_plugin_filepath = $_plugin_dir . DIRECTORY_SEPARATOR . $_plugin_filename; + + // see if path is relative + if (!preg_match("/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/", $_plugin_dir)) { + $_relative_paths[] = $_plugin_dir; + // relative path, see if it is in the SMARTY_DIR + if (@is_readable(SMARTY_DIR . $_plugin_filepath)) { + $_return = SMARTY_DIR . $_plugin_filepath; + break; + } + } + // try relative to cwd (or absolute) + if (@is_readable($_plugin_filepath)) { + $_return = $_plugin_filepath; + break; + } + } + + if($_return === false) { + // still not found, try PHP include_path + if(isset($_relative_paths)) { + foreach ((array)$_relative_paths as $_plugin_dir) { + + $_plugin_filepath = $_plugin_dir . DIRECTORY_SEPARATOR . $_plugin_filename; + + $_params = array('file_path' => $_plugin_filepath); + require_once(SMARTY_CORE_DIR . 'core.get_include_path.php'); + if(smarty_core_get_include_path($_params, $smarty)) { + $_return = $_params['new_file_path']; + break; + } + } + } + } + $_filepaths_cache[$_plugin_filename] = $_return; + return $_return; +} + +/* vim: set expandtab: */ + +?> diff --git a/upload/includes/templatelib/internals/core.assign_smarty_interface.php b/upload/includes/templatelib/internals/core.assign_smarty_interface.php new file mode 100644 index 00000000..500ba9a9 --- /dev/null +++ b/upload/includes/templatelib/internals/core.assign_smarty_interface.php @@ -0,0 +1,43 @@ + + * Name: assign_smarty_interface
    + * Purpose: assign the $smarty interface variable + * @param array Format: null + * @param Smarty + */ +function smarty_core_assign_smarty_interface($params, &$smarty) +{ + if (isset($smarty->_smarty_vars) && isset($smarty->_smarty_vars['request'])) { + return; + } + + $_globals_map = array('g' => 'HTTP_GET_VARS', + 'p' => 'HTTP_POST_VARS', + 'c' => 'HTTP_COOKIE_VARS', + 's' => 'HTTP_SERVER_VARS', + 'e' => 'HTTP_ENV_VARS'); + + $_smarty_vars_request = array(); + + foreach (preg_split('!!', strtolower($smarty->request_vars_order)) as $_c) { + if (isset($_globals_map[$_c])) { + $_smarty_vars_request = array_merge($_smarty_vars_request, $GLOBALS[$_globals_map[$_c]]); + } + } + $_smarty_vars_request = @array_merge($_smarty_vars_request, $GLOBALS['HTTP_SESSION_VARS']); + + $smarty->_smarty_vars['request'] = $_smarty_vars_request; +} + +/* vim: set expandtab: */ + +?> diff --git a/upload/includes/templatelib/internals/core.create_dir_structure.php b/upload/includes/templatelib/internals/core.create_dir_structure.php new file mode 100644 index 00000000..abc2850c --- /dev/null +++ b/upload/includes/templatelib/internals/core.create_dir_structure.php @@ -0,0 +1,79 @@ +_dir_perms) && !is_dir($_new_dir)) { + $smarty->trigger_error("problem creating directory '" . $_new_dir . "'"); + return false; + } + $_new_dir .= '/'; + } + } +} + +/* vim: set expandtab: */ + +?> diff --git a/upload/includes/templatelib/internals/core.display_debug_console.php b/upload/includes/templatelib/internals/core.display_debug_console.php new file mode 100644 index 00000000..59686767 --- /dev/null +++ b/upload/includes/templatelib/internals/core.display_debug_console.php @@ -0,0 +1,61 @@ + + * Name: display_debug_console
    + * Purpose: display the javascript debug console window + * @param array Format: null + * @param Smarty + */ +function smarty_core_display_debug_console($params, &$smarty) +{ + // we must force compile the debug template in case the environment + // changed between separate applications. + + if(empty($smarty->debug_tpl)) { + // set path to debug template from SMARTY_DIR + $smarty->debug_tpl = SMARTY_DIR . 'debug.tpl'; + if($smarty->security && is_file($smarty->debug_tpl)) { + $smarty->secure_dir[] = realpath($smarty->debug_tpl); + } + $smarty->debug_tpl = 'file:' . SMARTY_DIR . 'debug.tpl'; + } + + $_ldelim_orig = $smarty->left_delimiter; + $_rdelim_orig = $smarty->right_delimiter; + + $smarty->left_delimiter = '{'; + $smarty->right_delimiter = '}'; + + $_compile_id_orig = $smarty->_compile_id; + $smarty->_compile_id = null; + + $_compile_path = $smarty->_get_compile_path($smarty->debug_tpl); + if ($smarty->_compile_resource($smarty->debug_tpl, $_compile_path)) + { + ob_start(); + $smarty->_include($_compile_path); + $_results = ob_get_contents(); + ob_end_clean(); + } else { + $_results = ''; + } + + $smarty->_compile_id = $_compile_id_orig; + + $smarty->left_delimiter = $_ldelim_orig; + $smarty->right_delimiter = $_rdelim_orig; + + return $_results; +} + +/* vim: set expandtab: */ + +?> diff --git a/upload/includes/templatelib/internals/core.get_include_path.php b/upload/includes/templatelib/internals/core.get_include_path.php new file mode 100644 index 00000000..0cfdbdcc --- /dev/null +++ b/upload/includes/templatelib/internals/core.get_include_path.php @@ -0,0 +1,44 @@ + diff --git a/upload/includes/templatelib/internals/core.get_microtime.php b/upload/includes/templatelib/internals/core.get_microtime.php new file mode 100644 index 00000000..3c998a71 --- /dev/null +++ b/upload/includes/templatelib/internals/core.get_microtime.php @@ -0,0 +1,23 @@ + diff --git a/upload/includes/templatelib/internals/core.get_php_resource.php b/upload/includes/templatelib/internals/core.get_php_resource.php new file mode 100644 index 00000000..8fa1da6b --- /dev/null +++ b/upload/includes/templatelib/internals/core.get_php_resource.php @@ -0,0 +1,80 @@ +trusted_dir; + $smarty->_parse_resource_name($params, $smarty); + + /* + * Find out if the resource exists. + */ + + if ($params['resource_type'] == 'file') { + $_readable = false; + if(file_exists($params['resource_name']) && is_readable($params['resource_name'])) { + $_readable = true; + } else { + // test for file in include_path + $_params = array('file_path' => $params['resource_name']); + require_once(SMARTY_CORE_DIR . 'core.get_include_path.php'); + if(smarty_core_get_include_path($_params, $smarty)) { + $_include_path = $_params['new_file_path']; + $_readable = true; + } + } + } else if ($params['resource_type'] != 'file') { + $_template_source = null; + $_readable = is_callable($smarty->_plugins['resource'][$params['resource_type']][0][0]) + && call_user_func_array($smarty->_plugins['resource'][$params['resource_type']][0][0], + array($params['resource_name'], &$_template_source, &$smarty)); + } + + /* + * Set the error function, depending on which class calls us. + */ + if (method_exists($smarty, '_syntax_error')) { + $_error_funcc = '_syntax_error'; + } else { + $_error_funcc = 'trigger_error'; + } + + if ($_readable) { + if ($smarty->security) { + require_once(SMARTY_CORE_DIR . 'core.is_trusted.php'); + if (!smarty_core_is_trusted($params, $smarty)) { + $smarty->$_error_funcc('(secure mode) ' . $params['resource_type'] . ':' . $params['resource_name'] . ' is not trusted'); + return false; + } + } + } else { + $smarty->$_error_funcc($params['resource_type'] . ':' . $params['resource_name'] . ' is not readable'); + return false; + } + + if ($params['resource_type'] == 'file') { + $params['php_resource'] = $params['resource_name']; + } else { + $params['php_resource'] = $_template_source; + } + return true; +} + +/* vim: set expandtab: */ + +?> diff --git a/upload/includes/templatelib/internals/core.is_secure.php b/upload/includes/templatelib/internals/core.is_secure.php new file mode 100644 index 00000000..15c729ea --- /dev/null +++ b/upload/includes/templatelib/internals/core.is_secure.php @@ -0,0 +1,59 @@ +security || $smarty->security_settings['INCLUDE_ANY']) { + return true; + } + + if ($params['resource_type'] == 'file') { + $_rp = realpath($params['resource_name']); + if (isset($params['resource_base_path'])) { + foreach ((array)$params['resource_base_path'] as $curr_dir) { + if ( ($_cd = realpath($curr_dir)) !== false && + strncmp($_rp, $_cd, strlen($_cd)) == 0 && + substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR ) { + return true; + } + } + } + if (!empty($smarty->secure_dir)) { + foreach ((array)$smarty->secure_dir as $curr_dir) { + if ( ($_cd = realpath($curr_dir)) !== false) { + if($_cd == $_rp) { + return true; + } elseif (strncmp($_rp, $_cd, strlen($_cd)) == 0 && + substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR) { + return true; + } + } + } + } + } else { + // resource is not on local file system + return call_user_func_array( + $smarty->_plugins['resource'][$params['resource_type']][0][2], + array($params['resource_name'], &$smarty)); + } + + return false; +} + +/* vim: set expandtab: */ + +?> diff --git a/upload/includes/templatelib/internals/core.is_trusted.php b/upload/includes/templatelib/internals/core.is_trusted.php new file mode 100644 index 00000000..ecf703c8 --- /dev/null +++ b/upload/includes/templatelib/internals/core.is_trusted.php @@ -0,0 +1,47 @@ +trusted_dir)) { + $_rp = realpath($params['resource_name']); + foreach ((array)$smarty->trusted_dir as $curr_dir) { + if (!empty($curr_dir) && is_readable ($curr_dir)) { + $_cd = realpath($curr_dir); + if (strncmp($_rp, $_cd, strlen($_cd)) == 0 + && substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR ) { + $_smarty_trusted = true; + break; + } + } + } + } + + } else { + // resource is not on local file system + $_smarty_trusted = call_user_func_array($smarty->_plugins['resource'][$params['resource_type']][0][3], + array($params['resource_name'], $smarty)); + } + + return $_smarty_trusted; +} + +/* vim: set expandtab: */ + +?> diff --git a/upload/includes/templatelib/internals/core.load_plugins.php b/upload/includes/templatelib/internals/core.load_plugins.php new file mode 100644 index 00000000..6f412ec9 --- /dev/null +++ b/upload/includes/templatelib/internals/core.load_plugins.php @@ -0,0 +1,125 @@ +_plugins[$_type][$_name]; + + /* + * We do not load plugin more than once for each instance of Smarty. + * The following code checks for that. The plugin can also be + * registered dynamically at runtime, in which case template file + * and line number will be unknown, so we fill them in. + * + * The final element of the info array is a flag that indicates + * whether the dynamically registered plugin function has been + * checked for existence yet or not. + */ + if (isset($_plugin)) { + if (empty($_plugin[3])) { + if (!is_callable($_plugin[0])) { + $smarty->_trigger_fatal_error("[plugin] $_type '$_name' is not implemented", $_tpl_file, $_tpl_line, __FILE__, __LINE__); + } else { + $_plugin[1] = $_tpl_file; + $_plugin[2] = $_tpl_line; + $_plugin[3] = true; + if (!isset($_plugin[4])) $_plugin[4] = true; /* cacheable */ + } + } + continue; + } else if ($_type == 'insert') { + /* + * For backwards compatibility, we check for insert functions in + * the symbol table before trying to load them as a plugin. + */ + $_plugin_func = 'insert_' . $_name; + if (function_exists($_plugin_func)) { + $_plugin = array($_plugin_func, $_tpl_file, $_tpl_line, true, false); + continue; + } + } + + $_plugin_file = $smarty->_get_plugin_filepath($_type, $_name); + + if (! $_found = ($_plugin_file != false)) { + $_message = "could not load plugin file '$_type.$_name.php'\n"; + } + + /* + * If plugin file is found, it -must- provide the properly named + * plugin function. In case it doesn't, simply output the error and + * do not fall back on any other method. + */ + if ($_found) { + include_once $_plugin_file; + + $_plugin_func = 'smarty_' . $_type . '_' . $_name; + if (!function_exists($_plugin_func)) { + $smarty->_trigger_fatal_error("[plugin] function $_plugin_func() not found in $_plugin_file", $_tpl_file, $_tpl_line, __FILE__, __LINE__); + continue; + } + } + /* + * In case of insert plugins, their code may be loaded later via + * 'script' attribute. + */ + else if ($_type == 'insert' && $_delayed_loading) { + $_plugin_func = 'smarty_' . $_type . '_' . $_name; + $_found = true; + } + + /* + * Plugin specific processing and error checking. + */ + if (!$_found) { + if ($_type == 'modifier') { + /* + * In case modifier falls back on using PHP functions + * directly, we only allow those specified in the security + * context. + */ + if ($smarty->security && !in_array($_name, $smarty->security_settings['MODIFIER_FUNCS'])) { + $_message = "(secure mode) modifier '$_name' is not allowed"; + } else { + if (!function_exists($_name)) { + $_message = "modifier '$_name' is not implemented"; + } else { + $_plugin_func = $_name; + $_found = true; + } + } + } else if ($_type == 'function') { + /* + * This is a catch-all situation. + */ + $_message = "unknown tag - '$_name'"; + } + } + + if ($_found) { + $smarty->_plugins[$_type][$_name] = array($_plugin_func, $_tpl_file, $_tpl_line, true, true); + } else { + // output error + $smarty->_trigger_fatal_error('[plugin] ' . $_message, $_tpl_file, $_tpl_line, __FILE__, __LINE__); + } + } +} + +/* vim: set expandtab: */ + +?> diff --git a/upload/includes/templatelib/internals/core.load_resource_plugin.php b/upload/includes/templatelib/internals/core.load_resource_plugin.php new file mode 100644 index 00000000..8a084f1b --- /dev/null +++ b/upload/includes/templatelib/internals/core.load_resource_plugin.php @@ -0,0 +1,74 @@ +_plugins['resource'][$params['type']]; + if (isset($_plugin)) { + if (!$_plugin[1] && count($_plugin[0])) { + $_plugin[1] = true; + foreach ($_plugin[0] as $_plugin_func) { + if (!is_callable($_plugin_func)) { + $_plugin[1] = false; + break; + } + } + } + + if (!$_plugin[1]) { + $smarty->_trigger_fatal_error("[plugin] resource '" . $params['type'] . "' is not implemented", null, null, __FILE__, __LINE__); + } + + return; + } + + $_plugin_file = $smarty->_get_plugin_filepath('resource', $params['type']); + $_found = ($_plugin_file != false); + + if ($_found) { /* + * If the plugin file is found, it -must- provide the properly named + * plugin functions. + */ + include_once($_plugin_file); + + /* + * Locate functions that we require the plugin to provide. + */ + $_resource_ops = array('source', 'timestamp', 'secure', 'trusted'); + $_resource_funcs = array(); + foreach ($_resource_ops as $_op) { + $_plugin_func = 'smarty_resource_' . $params['type'] . '_' . $_op; + if (!function_exists($_plugin_func)) { + $smarty->_trigger_fatal_error("[plugin] function $_plugin_func() not found in $_plugin_file", null, null, __FILE__, __LINE__); + return; + } else { + $_resource_funcs[] = $_plugin_func; + } + } + + $smarty->_plugins['resource'][$params['type']] = array($_resource_funcs, true); + } +} + +/* vim: set expandtab: */ + +?> diff --git a/upload/includes/templatelib/internals/core.process_cached_inserts.php b/upload/includes/templatelib/internals/core.process_cached_inserts.php new file mode 100644 index 00000000..046e2c4d --- /dev/null +++ b/upload/includes/templatelib/internals/core.process_cached_inserts.php @@ -0,0 +1,71 @@ +_smarty_md5.'{insert_cache (.*)}'.$smarty->_smarty_md5.'!Uis', + $params['results'], $match); + list($cached_inserts, $insert_args) = $match; + + for ($i = 0, $for_max = count($cached_inserts); $i < $for_max; $i++) { + if ($smarty->debugging) { + $_params = array(); + require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); + $debug_start_time = smarty_core_get_microtime($_params, $smarty); + } + + $args = unserialize($insert_args[$i]); + $name = $args['name']; + + if (isset($args['script'])) { + $_params = array('resource_name' => $smarty->_dequote($args['script'])); + require_once(SMARTY_CORE_DIR . 'core.get_php_resource.php'); + if(!smarty_core_get_php_resource($_params, $smarty)) { + return false; + } + $resource_type = $_params['resource_type']; + $php_resource = $_params['php_resource']; + + + if ($resource_type == 'file') { + $smarty->_include($php_resource, true); + } else { + $smarty->_eval($php_resource); + } + } + + $function_name = $smarty->_plugins['insert'][$name][0]; + if (empty($args['assign'])) { + $replace = $function_name($args, $smarty); + } else { + $smarty->assign($args['assign'], $function_name($args, $smarty)); + $replace = ''; + } + + $params['results'] = substr_replace($params['results'], $replace, strpos($params['results'], $cached_inserts[$i]), strlen($cached_inserts[$i])); + if ($smarty->debugging) { + $_params = array(); + require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); + $smarty->_smarty_debug_info[] = array('type' => 'insert', + 'filename' => 'insert_'.$name, + 'depth' => $smarty->_inclusion_depth, + 'exec_time' => smarty_core_get_microtime($_params, $smarty) - $debug_start_time); + } + } + + return $params['results']; +} + +/* vim: set expandtab: */ + +?> diff --git a/upload/includes/templatelib/internals/core.process_compiled_include.php b/upload/includes/templatelib/internals/core.process_compiled_include.php new file mode 100644 index 00000000..76492eb5 --- /dev/null +++ b/upload/includes/templatelib/internals/core.process_compiled_include.php @@ -0,0 +1,37 @@ +_cache_including; + $smarty->_cache_including = true; + + $_return = $params['results']; + + foreach ($smarty->_cache_info['cache_serials'] as $_include_file_path=>$_cache_serial) { + $smarty->_include($_include_file_path, true); + } + + foreach ($smarty->_cache_serials as $_include_file_path=>$_cache_serial) { + $_return = preg_replace_callback('!(\{nocache\:('.$_cache_serial.')#(\d+)\})!s', + array(&$smarty, '_process_compiled_include_callback'), + $_return); + } + $smarty->_cache_including = $_cache_including; + return $_return; +} + +?> diff --git a/upload/includes/templatelib/internals/core.read_cache_file.php b/upload/includes/templatelib/internals/core.read_cache_file.php new file mode 100644 index 00000000..2205b2ae --- /dev/null +++ b/upload/includes/templatelib/internals/core.read_cache_file.php @@ -0,0 +1,101 @@ +force_compile) { + // force compile enabled, always regenerate + return false; + } + + if (isset($content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']])) { + list($params['results'], $smarty->_cache_info) = $content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']]; + return true; + } + + if (!empty($smarty->cache_handler_func)) { + // use cache_handler function + call_user_func_array($smarty->cache_handler_func, + array('read', &$smarty, &$params['results'], $params['tpl_file'], $params['cache_id'], $params['compile_id'], null)); + } else { + // use local cache file + $_auto_id = $smarty->_get_auto_id($params['cache_id'], $params['compile_id']); + $_cache_file = $smarty->_get_auto_filename($smarty->cache_dir, $params['tpl_file'], $_auto_id); + $params['results'] = $smarty->_read_file($_cache_file); + } + + if (empty($params['results'])) { + // nothing to parse (error?), regenerate cache + return false; + } + + $_contents = $params['results']; + $_info_start = strpos($_contents, "\n") + 1; + $_info_len = (int)substr($_contents, 0, $_info_start - 1); + $_cache_info = unserialize(substr($_contents, $_info_start, $_info_len)); + $params['results'] = substr($_contents, $_info_start + $_info_len); + + if ($smarty->caching == 2 && isset ($_cache_info['expires'])){ + // caching by expiration time + if ($_cache_info['expires'] > -1 && (time() > $_cache_info['expires'])) { + // cache expired, regenerate + return false; + } + } else { + // caching by lifetime + if ($smarty->cache_lifetime > -1 && (time() - $_cache_info['timestamp'] > $smarty->cache_lifetime)) { + // cache expired, regenerate + return false; + } + } + + if ($smarty->compile_check) { + $_params = array('get_source' => false, 'quiet'=>true); + foreach (array_keys($_cache_info['template']) as $_template_dep) { + $_params['resource_name'] = $_template_dep; + if (!$smarty->_fetch_resource_info($_params) || $_cache_info['timestamp'] < $_params['resource_timestamp']) { + // template file has changed, regenerate cache + return false; + } + } + + if (isset($_cache_info['config'])) { + $_params = array('resource_base_path' => $smarty->config_dir, 'get_source' => false, 'quiet'=>true); + foreach (array_keys($_cache_info['config']) as $_config_dep) { + $_params['resource_name'] = $_config_dep; + if (!$smarty->_fetch_resource_info($_params) || $_cache_info['timestamp'] < $_params['resource_timestamp']) { + // config file has changed, regenerate cache + return false; + } + } + } + } + + $content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']] = array($params['results'], $_cache_info); + + $smarty->_cache_info = $_cache_info; + return true; +} + +/* vim: set expandtab: */ + +?> diff --git a/upload/includes/templatelib/internals/core.rm_auto.php b/upload/includes/templatelib/internals/core.rm_auto.php new file mode 100644 index 00000000..5174f024 --- /dev/null +++ b/upload/includes/templatelib/internals/core.rm_auto.php @@ -0,0 +1,71 @@ + $params['auto_base'], + 'level' => 0, + 'exp_time' => $params['exp_time'] + ); + require_once(SMARTY_CORE_DIR . 'core.rmdir.php'); + $_res = smarty_core_rmdir($_params, $smarty); + } else { + $_tname = $smarty->_get_auto_filename($params['auto_base'], $params['auto_source'], $params['auto_id']); + + if(isset($params['auto_source'])) { + if (isset($params['extensions'])) { + $_res = false; + foreach ((array)$params['extensions'] as $_extension) + $_res |= $smarty->_unlink($_tname.$_extension, $params['exp_time']); + } else { + $_res = $smarty->_unlink($_tname, $params['exp_time']); + } + } elseif ($smarty->use_sub_dirs) { + $_params = array( + 'dirname' => $_tname, + 'level' => 1, + 'exp_time' => $params['exp_time'] + ); + require_once(SMARTY_CORE_DIR . 'core.rmdir.php'); + $_res = smarty_core_rmdir($_params, $smarty); + } else { + // remove matching file names + $_handle = opendir($params['auto_base']); + $_res = true; + while (false !== ($_filename = readdir($_handle))) { + if($_filename == '.' || $_filename == '..') { + continue; + } elseif (substr($params['auto_base'] . DIRECTORY_SEPARATOR . $_filename, 0, strlen($_tname)) == $_tname) { + $_res &= (bool)$smarty->_unlink($params['auto_base'] . DIRECTORY_SEPARATOR . $_filename, $params['exp_time']); + } + } + } + } + + return $_res; +} + +/* vim: set expandtab: */ + +?> diff --git a/upload/includes/templatelib/internals/core.rmdir.php b/upload/includes/templatelib/internals/core.rmdir.php new file mode 100644 index 00000000..3280ff75 --- /dev/null +++ b/upload/includes/templatelib/internals/core.rmdir.php @@ -0,0 +1,54 @@ + keep root) + * WARNING: no tests, it will try to remove what you tell it! + * + * @param string $dirname + * @param integer $level + * @param integer $exp_time + * @return boolean + */ + +// $dirname, $level = 1, $exp_time = null + +function smarty_core_rmdir($params, &$smarty) +{ + if(!isset($params['level'])) { $params['level'] = 1; } + if(!isset($params['exp_time'])) { $params['exp_time'] = null; } + + if($_handle = @opendir($params['dirname'])) { + + while (false !== ($_entry = readdir($_handle))) { + if ($_entry != '.' && $_entry != '..') { + if (@is_dir($params['dirname'] . DIRECTORY_SEPARATOR . $_entry)) { + $_params = array( + 'dirname' => $params['dirname'] . DIRECTORY_SEPARATOR . $_entry, + 'level' => $params['level'] + 1, + 'exp_time' => $params['exp_time'] + ); + smarty_core_rmdir($_params, $smarty); + } + else { + $smarty->_unlink($params['dirname'] . DIRECTORY_SEPARATOR . $_entry, $params['exp_time']); + } + } + } + closedir($_handle); + } + + if ($params['level']) { + return @rmdir($params['dirname']); + } + return (bool)$_handle; + +} + +/* vim: set expandtab: */ + +?> diff --git a/upload/includes/templatelib/internals/core.run_insert_handler.php b/upload/includes/templatelib/internals/core.run_insert_handler.php new file mode 100644 index 00000000..40e539f7 --- /dev/null +++ b/upload/includes/templatelib/internals/core.run_insert_handler.php @@ -0,0 +1,71 @@ +debugging) { + $_params = array(); + $_debug_start_time = smarty_core_get_microtime($_params, $smarty); + } + + if ($smarty->caching) { + $_arg_string = serialize($params['args']); + $_name = $params['args']['name']; + if (!isset($smarty->_cache_info['insert_tags'][$_name])) { + $smarty->_cache_info['insert_tags'][$_name] = array('insert', + $_name, + $smarty->_plugins['insert'][$_name][1], + $smarty->_plugins['insert'][$_name][2], + !empty($params['args']['script']) ? true : false); + } + return $smarty->_smarty_md5."{insert_cache $_arg_string}".$smarty->_smarty_md5; + } else { + if (isset($params['args']['script'])) { + $_params = array('resource_name' => $smarty->_dequote($params['args']['script'])); + require_once(SMARTY_CORE_DIR . 'core.get_php_resource.php'); + if(!smarty_core_get_php_resource($_params, $smarty)) { + return false; + } + + if ($_params['resource_type'] == 'file') { + $smarty->_include($_params['php_resource'], true); + } else { + $smarty->_eval($_params['php_resource']); + } + unset($params['args']['script']); + } + + $_funcname = $smarty->_plugins['insert'][$params['args']['name']][0]; + $_content = $_funcname($params['args'], $smarty); + if ($smarty->debugging) { + $_params = array(); + require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); + $smarty->_smarty_debug_info[] = array('type' => 'insert', + 'filename' => 'insert_'.$params['args']['name'], + 'depth' => $smarty->_inclusion_depth, + 'exec_time' => smarty_core_get_microtime($_params, $smarty) - $_debug_start_time); + } + + if (!empty($params['args']["assign"])) { + $smarty->assign($params['args']["assign"], $_content); + } else { + return $_content; + } + } +} + +/* vim: set expandtab: */ + +?> diff --git a/upload/includes/templatelib/internals/core.smarty_include_php.php b/upload/includes/templatelib/internals/core.smarty_include_php.php new file mode 100644 index 00000000..de03f93d --- /dev/null +++ b/upload/includes/templatelib/internals/core.smarty_include_php.php @@ -0,0 +1,50 @@ + $params['smarty_file']); + require_once(SMARTY_CORE_DIR . 'core.get_php_resource.php'); + smarty_core_get_php_resource($_params, $smarty); + $_smarty_resource_type = $_params['resource_type']; + $_smarty_php_resource = $_params['php_resource']; + + if (!empty($params['smarty_assign'])) { + ob_start(); + if ($_smarty_resource_type == 'file') { + $smarty->_include($_smarty_php_resource, $params['smarty_once'], $params['smarty_include_vars']); + } else { + $smarty->_eval($_smarty_php_resource, $params['smarty_include_vars']); + } + $smarty->assign($params['smarty_assign'], ob_get_contents()); + ob_end_clean(); + } else { + if ($_smarty_resource_type == 'file') { + $smarty->_include($_smarty_php_resource, $params['smarty_once'], $params['smarty_include_vars']); + } else { + $smarty->_eval($_smarty_php_resource, $params['smarty_include_vars']); + } + } +} + + +/* vim: set expandtab: */ + +?> diff --git a/upload/includes/templatelib/internals/core.write_cache_file.php b/upload/includes/templatelib/internals/core.write_cache_file.php new file mode 100644 index 00000000..4cf3601d --- /dev/null +++ b/upload/includes/templatelib/internals/core.write_cache_file.php @@ -0,0 +1,96 @@ +_cache_info['timestamp'] = time(); + if ($smarty->cache_lifetime > -1){ + // expiration set + $smarty->_cache_info['expires'] = $smarty->_cache_info['timestamp'] + $smarty->cache_lifetime; + } else { + // cache will never expire + $smarty->_cache_info['expires'] = -1; + } + + // collapse nocache.../nocache-tags + if (preg_match_all('!\{(/?)nocache\:[0-9a-f]{32}#\d+\}!', $params['results'], $match, PREG_PATTERN_ORDER)) { + // remove everything between every pair of outermost noache.../nocache-tags + // and replace it by a single nocache-tag + // this new nocache-tag will be replaced by dynamic contents in + // smarty_core_process_compiled_includes() on a cache-read + + $match_count = count($match[0]); + $results = preg_split('!(\{/?nocache\:[0-9a-f]{32}#\d+\})!', $params['results'], -1, PREG_SPLIT_DELIM_CAPTURE); + + $level = 0; + $j = 0; + for ($i=0, $results_count = count($results); $i < $results_count && $j < $match_count; $i++) { + if ($results[$i] == $match[0][$j]) { + // nocache tag + if ($match[1][$j]) { // closing tag + $level--; + unset($results[$i]); + } else { // opening tag + if ($level++ > 0) unset($results[$i]); + } + $j++; + } elseif ($level > 0) { + unset($results[$i]); + } + } + $params['results'] = implode('', $results); + } + $smarty->_cache_info['cache_serials'] = $smarty->_cache_serials; + + // prepend the cache header info into cache file + $_cache_info = serialize($smarty->_cache_info); + $params['results'] = strlen($_cache_info) . "\n" . $_cache_info . $params['results']; + + if (!empty($smarty->cache_handler_func)) { + // use cache_handler function + call_user_func_array($smarty->cache_handler_func, + array('write', &$smarty, &$params['results'], $params['tpl_file'], $params['cache_id'], $params['compile_id'], null)); + } else { + // use local cache file + + if(!@is_writable($smarty->cache_dir)) { + // cache_dir not writable, see if it exists + if(!@is_dir($smarty->cache_dir)) { + $smarty->trigger_error('the $cache_dir \'' . $smarty->cache_dir . '\' does not exist, or is not a directory.', E_USER_ERROR); + return false; + } + $smarty->trigger_error('unable to write to $cache_dir \'' . realpath($smarty->cache_dir) . '\'. Be sure $cache_dir is writable by the web server user.', E_USER_ERROR); + return false; + } + + $_auto_id = $smarty->_get_auto_id($params['cache_id'], $params['compile_id']); + $_cache_file = $smarty->_get_auto_filename($smarty->cache_dir, $params['tpl_file'], $_auto_id); + $_params = array('filename' => $_cache_file, 'contents' => $params['results'], 'create_dirs' => true); + require_once(SMARTY_CORE_DIR . 'core.write_file.php'); + smarty_core_write_file($_params, $smarty); + return true; + } +} + +/* vim: set expandtab: */ + +?> diff --git a/upload/includes/templatelib/internals/core.write_compiled_include.php b/upload/includes/templatelib/internals/core.write_compiled_include.php new file mode 100644 index 00000000..15c44d63 --- /dev/null +++ b/upload/includes/templatelib/internals/core.write_compiled_include.php @@ -0,0 +1,91 @@ +caching && \!\$this->_cache_including\)\: echo \'\{nocache\:('.$params['cache_serial'].')#(\d+)\}\'; endif;'; + $_tag_end = 'if \(\$this->caching && \!\$this->_cache_including\)\: echo \'\{/nocache\:(\\2)#(\\3)\}\'; endif;'; + + preg_match_all('!('.$_tag_start.'(.*)'.$_tag_end.')!Us', + $params['compiled_content'], $_match_source, PREG_SET_ORDER); + + // no nocache-parts found: done + if (count($_match_source)==0) return; + + // convert the matched php-code to functions + $_include_compiled = "_version.", created on ".strftime("%Y-%m-%d %H:%M:%S")."\n"; + $_include_compiled .= " compiled from " . strtr(urlencode($params['resource_name']), array('%2F'=>'/', '%3A'=>':')) . " */\n\n"; + + $_compile_path = $params['include_file_path']; + + $smarty->_cache_serials[$_compile_path] = $params['cache_serial']; + $_include_compiled .= "\$this->_cache_serials['".$_compile_path."'] = '".$params['cache_serial']."';\n\n?>"; + + $_include_compiled .= $params['plugins_code']; + $_include_compiled .= "= 5.0) ? '_smarty' : 'this'; + for ($_i = 0, $_for_max = count($_match_source); $_i < $_for_max; $_i++) { + $_match =& $_match_source[$_i]; + $source = $_match[4]; + if ($this_varname == '_smarty') { + /* rename $this to $_smarty in the sourcecode */ + $tokens = token_get_all('\n"; + + $_params = array('filename' => $_compile_path, + 'contents' => $_include_compiled, 'create_dirs' => true); + + require_once(SMARTY_CORE_DIR . 'core.write_file.php'); + smarty_core_write_file($_params, $smarty); + return true; +} + + +?> diff --git a/upload/includes/templatelib/internals/core.write_compiled_resource.php b/upload/includes/templatelib/internals/core.write_compiled_resource.php new file mode 100644 index 00000000..d0e56480 --- /dev/null +++ b/upload/includes/templatelib/internals/core.write_compiled_resource.php @@ -0,0 +1,35 @@ +compile_dir)) { + // compile_dir not writable, see if it exists + if(!@is_dir($smarty->compile_dir)) { + $smarty->trigger_error('the $compile_dir \'' . $smarty->compile_dir . '\' does not exist, or is not a directory.', E_USER_ERROR); + return false; + } + $smarty->trigger_error('unable to write to $compile_dir \'' . realpath($smarty->compile_dir) . '\'. Be sure $compile_dir is writable by the web server user.', E_USER_ERROR); + return false; + } + + $_params = array('filename' => $params['compile_path'], 'contents' => $params['compiled_content'], 'create_dirs' => true); + require_once(SMARTY_CORE_DIR . 'core.write_file.php'); + smarty_core_write_file($_params, $smarty); + return true; +} + +/* vim: set expandtab: */ + +?> diff --git a/upload/includes/templatelib/internals/core.write_file.php b/upload/includes/templatelib/internals/core.write_file.php new file mode 100644 index 00000000..9f6ee5ca --- /dev/null +++ b/upload/includes/templatelib/internals/core.write_file.php @@ -0,0 +1,54 @@ + $_dirname); + require_once(SMARTY_CORE_DIR . 'core.create_dir_structure.php'); + smarty_core_create_dir_structure($_params, $smarty); + } + + // write to tmp file, then rename it to avoid file locking race condition + $_tmp_file = tempnam($_dirname, 'wrt'); + + if (!($fd = @fopen($_tmp_file, 'wb'))) { + $_tmp_file = $_dirname . DIRECTORY_SEPARATOR . uniqid('wrt'); + if (!($fd = @fopen($_tmp_file, 'wb'))) { + $smarty->trigger_error("problem writing temporary file '$_tmp_file'"); + return false; + } + } + + fwrite($fd, $params['contents']); + fclose($fd); + + if (DIRECTORY_SEPARATOR == '\\' || !@rename($_tmp_file, $params['filename'])) { + // On platforms and filesystems that cannot overwrite with rename() + // delete the file before renaming it -- because windows always suffers + // this, it is short-circuited to avoid the initial rename() attempt + @unlink($params['filename']); + @rename($_tmp_file, $params['filename']); + } + @chmod($params['filename'], $smarty->_file_perms); + + return true; +} + +/* vim: set expandtab: */ + +?> \ No newline at end of file diff --git a/upload/includes/templatelib/plugins/block.textformat.php b/upload/includes/templatelib/plugins/block.textformat.php new file mode 100644 index 00000000..2a374232 --- /dev/null +++ b/upload/includes/templatelib/plugins/block.textformat.php @@ -0,0 +1,103 @@ + + * Name: textformat
    + * Purpose: format text a certain way with preset styles + * or custom wrap/indent settings
    + * @link http://smarty.php.net/manual/en/language.function.textformat.php {textformat} + * (Smarty online manual) + * @param array + *
    + * Params:   style: string (email)
    + *           indent: integer (0)
    + *           wrap: integer (80)
    + *           wrap_char string ("\n")
    + *           indent_char: string (" ")
    + *           wrap_boundary: boolean (true)
    + * 
    + * @author Monte Ohrt + * @param string contents of the block + * @param Smarty clever simulation of a method + * @return string string $content re-formatted + */ +function smarty_block_textformat($params, $content, &$smarty) +{ + if (is_null($content)) { + return; + } + + $style = null; + $indent = 0; + $indent_first = 0; + $indent_char = ' '; + $wrap = 80; + $wrap_char = "\n"; + $wrap_cut = false; + $assign = null; + + foreach ($params as $_key => $_val) { + switch ($_key) { + case 'style': + case 'indent_char': + case 'wrap_char': + case 'assign': + $$_key = (string)$_val; + break; + + case 'indent': + case 'indent_first': + case 'wrap': + $$_key = (int)$_val; + break; + + case 'wrap_cut': + $$_key = (bool)$_val; + break; + + default: + $smarty->trigger_error("textformat: unknown attribute '$_key'"); + } + } + + if ($style == 'email') { + $wrap = 72; + } + + // split into paragraphs + $_paragraphs = preg_split('![\r\n][\r\n]!',$content); + $_output = ''; + + for($_x = 0, $_y = count($_paragraphs); $_x < $_y; $_x++) { + if ($_paragraphs[$_x] == '') { + continue; + } + // convert mult. spaces & special chars to single space + $_paragraphs[$_x] = preg_replace(array('!\s+!','!(^\s+)|(\s+$)!'), array(' ',''), $_paragraphs[$_x]); + // indent first line + if($indent_first > 0) { + $_paragraphs[$_x] = str_repeat($indent_char, $indent_first) . $_paragraphs[$_x]; + } + // wordwrap sentences + $_paragraphs[$_x] = wordwrap($_paragraphs[$_x], $wrap - $indent, $wrap_char, $wrap_cut); + // indent lines + if($indent > 0) { + $_paragraphs[$_x] = preg_replace('!^!m', str_repeat($indent_char, $indent), $_paragraphs[$_x]); + } + } + $_output = implode($wrap_char . $wrap_char, $_paragraphs); + + return $assign ? $smarty->assign($assign, $_output) : $_output; + +} + +/* vim: set expandtab: */ + +?> diff --git a/upload/includes/templatelib/plugins/compiler.assign.php b/upload/includes/templatelib/plugins/compiler.assign.php new file mode 100644 index 00000000..b8a35199 --- /dev/null +++ b/upload/includes/templatelib/plugins/compiler.assign.php @@ -0,0 +1,46 @@ + + * Name: assign
    + * Purpose: assign a value to a template variable + * @link http://smarty.php.net/manual/en/language.custom.functions.php#LANGUAGE.FUNCTION.ASSIGN {assign} + * (Smarty online manual) + * @author Monte Ohrt (initial author) + * @auther messju mohr (conversion to compiler function) + * @param string containing var-attribute and value-attribute + * @param Smarty_Compiler + */ +function smarty_compiler_assign($tag_attrs, &$compiler) +{ + $_params = $compiler->_parse_attrs($tag_attrs); + + if (!isset($_params['var'])) { + $compiler->_syntax_error("assign: missing 'var' parameter", E_USER_WARNING); + return; + } + + if (!isset($_params['value'])) { + $compiler->_syntax_error("assign: missing 'value' parameter", E_USER_WARNING); + return; + } + + $val = $_params['value']; + if(substr($val,1,6)=='func->') + $_params['value'] = substr($val,7,strlen($val)-8); + $_params['value'] = preg_replace(array("/\"\./","/\.\"/"),'',$_params['value']); + + + return "\$this->assign({$_params['var']}, {$_params['value']});"; +} + +/* vim: set expandtab: */ + +?> diff --git a/upload/includes/templatelib/plugins/function.assign_debug_info.php b/upload/includes/templatelib/plugins/function.assign_debug_info.php new file mode 100644 index 00000000..cc2c14b5 --- /dev/null +++ b/upload/includes/templatelib/plugins/function.assign_debug_info.php @@ -0,0 +1,40 @@ + + * Name: assign_debug_info
    + * Purpose: assign debug info to the template
    + * @author Monte Ohrt + * @param array unused in this plugin, this plugin uses {@link Smarty::$_config}, + * {@link Smarty::$_tpl_vars} and {@link Smarty::$_smarty_debug_info} + * @param Smarty + */ +function smarty_function_assign_debug_info($params, &$smarty) +{ + $assigned_vars = $smarty->_tpl_vars; + ksort($assigned_vars); + if (@is_array($smarty->_config[0])) { + $config_vars = $smarty->_config[0]; + ksort($config_vars); + $smarty->assign("_debug_config_keys", array_keys($config_vars)); + $smarty->assign("_debug_config_vals", array_values($config_vars)); + } + + $included_templates = $smarty->_smarty_debug_info; + + $smarty->assign("_debug_keys", array_keys($assigned_vars)); + $smarty->assign("_debug_vals", array_values($assigned_vars)); + + $smarty->assign("_debug_tpls", $included_templates); +} + +/* vim: set expandtab: */ + +?> diff --git a/upload/includes/templatelib/plugins/function.config_load.php b/upload/includes/templatelib/plugins/function.config_load.php new file mode 100644 index 00000000..062c3564 --- /dev/null +++ b/upload/includes/templatelib/plugins/function.config_load.php @@ -0,0 +1,142 @@ + + * Name: config_load
    + * Purpose: load config file vars + * @link http://smarty.php.net/manual/en/language.function.config.load.php {config_load} + * (Smarty online manual) + * @author Monte Ohrt + * @author messju mohr (added use of resources) + * @param array Format: + *
    + * array('file' => required config file name,
    + *       'section' => optional config file section to load
    + *       'scope' => local/parent/global
    + *       'global' => overrides scope, setting to parent if true)
    + * 
    + * @param Smarty + */ +function smarty_function_config_load($params, &$smarty) +{ + if ($smarty->debugging) { + $_params = array(); + require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); + $_debug_start_time = smarty_core_get_microtime($_params, $smarty); + } + + $_file = isset($params['file']) ? $smarty->_dequote($params['file']) : null; + $_section = isset($params['section']) ? $smarty->_dequote($params['section']) : null; + $_scope = isset($params['scope']) ? $smarty->_dequote($params['scope']) : 'global'; + $_global = isset($params['global']) ? $smarty->_dequote($params['global']) : false; + + if (!isset($_file) || strlen($_file) == 0) { + $smarty->trigger_error("missing 'file' attribute in config_load tag", E_USER_ERROR, __FILE__, __LINE__); + } + + if (isset($_scope)) { + if ($_scope != 'local' && + $_scope != 'parent' && + $_scope != 'global') { + $smarty->trigger_error("invalid 'scope' attribute value", E_USER_ERROR, __FILE__, __LINE__); + } + } else { + if ($_global) { + $_scope = 'parent'; + } else { + $_scope = 'local'; + } + } + + $_params = array('resource_name' => $_file, + 'resource_base_path' => $smarty->config_dir, + 'get_source' => false); + $smarty->_parse_resource_name($_params); + $_file_path = $_params['resource_type'] . ':' . $_params['resource_name']; + if (isset($_section)) + $_compile_file = $smarty->_get_compile_path($_file_path.'|'.$_section); + else + $_compile_file = $smarty->_get_compile_path($_file_path); + + if($smarty->force_compile || !file_exists($_compile_file)) { + $_compile = true; + } elseif ($smarty->compile_check) { + $_params = array('resource_name' => $_file, + 'resource_base_path' => $smarty->config_dir, + 'get_source' => false); + $_compile = $smarty->_fetch_resource_info($_params) && + $_params['resource_timestamp'] > filemtime($_compile_file); + } else { + $_compile = false; + } + + if($_compile) { + // compile config file + if(!is_object($smarty->_conf_obj)) { + require_once SMARTY_DIR . $smarty->config_class . '.class.php'; + $smarty->_conf_obj = new $smarty->config_class(); + $smarty->_conf_obj->overwrite = $smarty->config_overwrite; + $smarty->_conf_obj->booleanize = $smarty->config_booleanize; + $smarty->_conf_obj->read_hidden = $smarty->config_read_hidden; + $smarty->_conf_obj->fix_newlines = $smarty->config_fix_newlines; + } + + $_params = array('resource_name' => $_file, + 'resource_base_path' => $smarty->config_dir, + $_params['get_source'] = true); + if (!$smarty->_fetch_resource_info($_params)) { + return; + } + $smarty->_conf_obj->set_file_contents($_file, $_params['source_content']); + $_config_vars = array_merge($smarty->_conf_obj->get($_file), + $smarty->_conf_obj->get($_file, $_section)); + if(function_exists('var_export')) { + $_output = ''; + } else { + $_output = ''\\\'', '\\'=>'\\\\')) . '\'); ?>'; + } + $_params = (array('compile_path' => $_compile_file, 'compiled_content' => $_output, 'resource_timestamp' => $_params['resource_timestamp'])); + require_once(SMARTY_CORE_DIR . 'core.write_compiled_resource.php'); + smarty_core_write_compiled_resource($_params, $smarty); + } else { + include($_compile_file); + } + + if ($smarty->caching) { + $smarty->_cache_info['config'][$_file] = true; + } + + $smarty->_config[0]['vars'] = @array_merge($smarty->_config[0]['vars'], $_config_vars); + $smarty->_config[0]['files'][$_file] = true; + + if ($_scope == 'parent') { + $smarty->_config[1]['vars'] = @array_merge($smarty->_config[1]['vars'], $_config_vars); + $smarty->_config[1]['files'][$_file] = true; + } else if ($_scope == 'global') { + for ($i = 1, $for_max = count($smarty->_config); $i < $for_max; $i++) { + $smarty->_config[$i]['vars'] = @array_merge($smarty->_config[$i]['vars'], $_config_vars); + $smarty->_config[$i]['files'][$_file] = true; + } + } + + if ($smarty->debugging) { + $_params = array(); + require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); + $smarty->_smarty_debug_info[] = array('type' => 'config', + 'filename' => $_file.' ['.$_section.'] '.$_scope, + 'depth' => $smarty->_inclusion_depth, + 'exec_time' => smarty_core_get_microtime($_params, $smarty) - $_debug_start_time); + } + +} + +/* vim: set expandtab: */ + +?> diff --git a/upload/includes/templatelib/plugins/function.counter.php b/upload/includes/templatelib/plugins/function.counter.php new file mode 100644 index 00000000..e8937d11 --- /dev/null +++ b/upload/includes/templatelib/plugins/function.counter.php @@ -0,0 +1,80 @@ + + * Name: counter
    + * Purpose: print out a counter value + * @author Monte Ohrt + * @link http://smarty.php.net/manual/en/language.function.counter.php {counter} + * (Smarty online manual) + * @param array parameters + * @param Smarty + * @return string|null + */ +function smarty_function_counter($params, &$smarty) +{ + static $counters = array(); + + $name = (isset($params['name'])) ? $params['name'] : 'default'; + if (!isset($counters[$name])) { + $counters[$name] = array( + 'start'=>1, + 'skip'=>1, + 'direction'=>'up', + 'count'=>1 + ); + } + $counter =& $counters[$name]; + + if (isset($params['start'])) { + $counter['start'] = $counter['count'] = (int)$params['start']; + } + + if (!empty($params['assign'])) { + $counter['assign'] = $params['assign']; + } + + if (isset($counter['assign'])) { + $smarty->assign($counter['assign'], $counter['count']); + } + + if (isset($params['print'])) { + $print = (bool)$params['print']; + } else { + $print = empty($counter['assign']); + } + + if ($print) { + $retval = $counter['count']; + } else { + $retval = null; + } + + if (isset($params['skip'])) { + $counter['skip'] = $params['skip']; + } + + if (isset($params['direction'])) { + $counter['direction'] = $params['direction']; + } + + if ($counter['direction'] == "down") + $counter['count'] -= $counter['skip']; + else + $counter['count'] += $counter['skip']; + + return $retval; + +} + +/* vim: set expandtab: */ + +?> diff --git a/upload/includes/templatelib/plugins/function.cycle.php b/upload/includes/templatelib/plugins/function.cycle.php new file mode 100644 index 00000000..1a04af98 --- /dev/null +++ b/upload/includes/templatelib/plugins/function.cycle.php @@ -0,0 +1,102 @@ + + * Name: cycle
    + * Date: May 3, 2002
    + * Purpose: cycle through given values
    + * Input: + * - name = name of cycle (optional) + * - values = comma separated list of values to cycle, + * or an array of values to cycle + * (this can be left out for subsequent calls) + * - reset = boolean - resets given var to true + * - print = boolean - print var or not. default is true + * - advance = boolean - whether or not to advance the cycle + * - delimiter = the value delimiter, default is "," + * - assign = boolean, assigns to template var instead of + * printed. + * + * Examples:
    + *
    + * {cycle values="#eeeeee,#d0d0d0d"}
    + * {cycle name=row values="one,two,three" reset=true}
    + * {cycle name=row}
    + * 
    + * @link http://smarty.php.net/manual/en/language.function.cycle.php {cycle} + * (Smarty online manual) + * @author Monte Ohrt + * @author credit to Mark Priatel + * @author credit to Gerard + * @author credit to Jason Sweat + * @version 1.3 + * @param array + * @param Smarty + * @return string|null + */ +function smarty_function_cycle($params, &$smarty) +{ + static $cycle_vars; + + $name = (empty($params['name'])) ? 'default' : $params['name']; + $print = (isset($params['print'])) ? (bool)$params['print'] : true; + $advance = (isset($params['advance'])) ? (bool)$params['advance'] : true; + $reset = (isset($params['reset'])) ? (bool)$params['reset'] : false; + + if (!in_array('values', array_keys($params))) { + if(!isset($cycle_vars[$name]['values'])) { + $smarty->trigger_error("cycle: missing 'values' parameter"); + return; + } + } else { + if(isset($cycle_vars[$name]['values']) + && $cycle_vars[$name]['values'] != $params['values'] ) { + $cycle_vars[$name]['index'] = 0; + } + $cycle_vars[$name]['values'] = $params['values']; + } + + $cycle_vars[$name]['delimiter'] = (isset($params['delimiter'])) ? $params['delimiter'] : ','; + + if(is_array($cycle_vars[$name]['values'])) { + $cycle_array = $cycle_vars[$name]['values']; + } else { + $cycle_array = explode($cycle_vars[$name]['delimiter'],$cycle_vars[$name]['values']); + } + + if(!isset($cycle_vars[$name]['index']) || $reset ) { + $cycle_vars[$name]['index'] = 0; + } + + if (isset($params['assign'])) { + $print = false; + $smarty->assign($params['assign'], $cycle_array[$cycle_vars[$name]['index']]); + } + + if($print) { + $retval = $cycle_array[$cycle_vars[$name]['index']]; + } else { + $retval = null; + } + + if($advance) { + if ( $cycle_vars[$name]['index'] >= count($cycle_array) -1 ) { + $cycle_vars[$name]['index'] = 0; + } else { + $cycle_vars[$name]['index']++; + } + } + + return $retval; +} + +/* vim: set expandtab: */ + +?> diff --git a/upload/includes/templatelib/plugins/function.debug.php b/upload/includes/templatelib/plugins/function.debug.php new file mode 100644 index 00000000..de09b308 --- /dev/null +++ b/upload/includes/templatelib/plugins/function.debug.php @@ -0,0 +1,35 @@ + + * Name: debug
    + * Date: July 1, 2002
    + * Purpose: popup debug window + * @link http://smarty.php.net/manual/en/language.function.debug.php {debug} + * (Smarty online manual) + * @author Monte Ohrt + * @version 1.0 + * @param array + * @param Smarty + * @return string output from {@link Smarty::_generate_debug_output()} + */ +function smarty_function_debug($params, &$smarty) +{ + if (isset($params['output'])) { + $smarty->assign('_smarty_debug_output', $params['output']); + } + require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php'); + return smarty_core_display_debug_console(null, $smarty); +} + +/* vim: set expandtab: */ + +?> diff --git a/upload/includes/templatelib/plugins/function.eval.php b/upload/includes/templatelib/plugins/function.eval.php new file mode 100644 index 00000000..3bb8cbb4 --- /dev/null +++ b/upload/includes/templatelib/plugins/function.eval.php @@ -0,0 +1,49 @@ + + * Name: eval
    + * Purpose: evaluate a template variable as a template
    + * @link http://smarty.php.net/manual/en/language.function.eval.php {eval} + * (Smarty online manual) + * @author Monte Ohrt + * @param array + * @param Smarty + */ +function smarty_function_eval($params, &$smarty) +{ + + if (!isset($params['var'])) { + $smarty->trigger_error("eval: missing 'var' parameter"); + return; + } + + if($params['var'] == '') { + return; + } + + $smarty->_compile_source('evaluated template', $params['var'], $_var_compiled); + + ob_start(); + $smarty->_eval('?>' . $_var_compiled); + $_contents = ob_get_contents(); + ob_end_clean(); + + if (!empty($params['assign'])) { + $smarty->assign($params['assign'], $_contents); + } else { + return $_contents; + } +} + +/* vim: set expandtab: */ + +?> diff --git a/upload/includes/templatelib/plugins/function.fetch.php b/upload/includes/templatelib/plugins/function.fetch.php new file mode 100644 index 00000000..0d5ce7f7 --- /dev/null +++ b/upload/includes/templatelib/plugins/function.fetch.php @@ -0,0 +1,221 @@ + + * Name: fetch
    + * Purpose: fetch file, web or ftp data and display results + * @link http://smarty.php.net/manual/en/language.function.fetch.php {fetch} + * (Smarty online manual) + * @author Monte Ohrt + * @param array + * @param Smarty + * @return string|null if the assign parameter is passed, Smarty assigns the + * result to a template variable + */ +function smarty_function_fetch($params, &$smarty) +{ + if (empty($params['file'])) { + $smarty->_trigger_fatal_error("[plugin] parameter 'file' cannot be empty"); + return; + } + + $content = ''; + if ($smarty->security && !preg_match('!^(http|ftp)://!i', $params['file'])) { + $_params = array('resource_type' => 'file', 'resource_name' => $params['file']); + require_once(SMARTY_CORE_DIR . 'core.is_secure.php'); + if(!smarty_core_is_secure($_params, $smarty)) { + $smarty->_trigger_fatal_error('[plugin] (secure mode) fetch \'' . $params['file'] . '\' is not allowed'); + return; + } + + // fetch the file + if($fp = @fopen($params['file'],'r')) { + while(!feof($fp)) { + $content .= fgets ($fp,4096); + } + fclose($fp); + } else { + $smarty->_trigger_fatal_error('[plugin] fetch cannot read file \'' . $params['file'] . '\''); + return; + } + } else { + // not a local file + if(preg_match('!^http://!i',$params['file'])) { + // http fetch + if($uri_parts = parse_url($params['file'])) { + // set defaults + $host = $server_name = $uri_parts['host']; + $timeout = 30; + $accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*"; + $agent = "Smarty Template Engine ".$smarty->_version; + $referer = ""; + $uri = !empty($uri_parts['path']) ? $uri_parts['path'] : '/'; + $uri .= !empty($uri_parts['query']) ? '?' . $uri_parts['query'] : ''; + $_is_proxy = false; + if(empty($uri_parts['port'])) { + $port = 80; + } else { + $port = $uri_parts['port']; + } + if(!empty($uri_parts['user'])) { + $user = $uri_parts['user']; + } + if(!empty($uri_parts['pass'])) { + $pass = $uri_parts['pass']; + } + // loop through parameters, setup headers + foreach($params as $param_key => $param_value) { + switch($param_key) { + case "file": + case "assign": + case "assign_headers": + break; + case "user": + if(!empty($param_value)) { + $user = $param_value; + } + break; + case "pass": + if(!empty($param_value)) { + $pass = $param_value; + } + break; + case "accept": + if(!empty($param_value)) { + $accept = $param_value; + } + break; + case "header": + if(!empty($param_value)) { + if(!preg_match('![\w\d-]+: .+!',$param_value)) { + $smarty->_trigger_fatal_error("[plugin] invalid header format '".$param_value."'"); + return; + } else { + $extra_headers[] = $param_value; + } + } + break; + case "proxy_host": + if(!empty($param_value)) { + $proxy_host = $param_value; + } + break; + case "proxy_port": + if(!preg_match('!\D!', $param_value)) { + $proxy_port = (int) $param_value; + } else { + $smarty->_trigger_fatal_error("[plugin] invalid value for attribute '".$param_key."'"); + return; + } + break; + case "agent": + if(!empty($param_value)) { + $agent = $param_value; + } + break; + case "referer": + if(!empty($param_value)) { + $referer = $param_value; + } + break; + case "timeout": + if(!preg_match('!\D!', $param_value)) { + $timeout = (int) $param_value; + } else { + $smarty->_trigger_fatal_error("[plugin] invalid value for attribute '".$param_key."'"); + return; + } + break; + default: + $smarty->_trigger_fatal_error("[plugin] unrecognized attribute '".$param_key."'"); + return; + } + } + if(!empty($proxy_host) && !empty($proxy_port)) { + $_is_proxy = true; + $fp = fsockopen($proxy_host,$proxy_port,$errno,$errstr,$timeout); + } else { + $fp = fsockopen($server_name,$port,$errno,$errstr,$timeout); + } + + if(!$fp) { + $smarty->_trigger_fatal_error("[plugin] unable to fetch: $errstr ($errno)"); + return; + } else { + if($_is_proxy) { + fputs($fp, 'GET ' . $params['file'] . " HTTP/1.0\r\n"); + } else { + fputs($fp, "GET $uri HTTP/1.0\r\n"); + } + if(!empty($host)) { + fputs($fp, "Host: $host\r\n"); + } + if(!empty($accept)) { + fputs($fp, "Accept: $accept\r\n"); + } + if(!empty($agent)) { + fputs($fp, "User-Agent: $agent\r\n"); + } + if(!empty($referer)) { + fputs($fp, "Referer: $referer\r\n"); + } + if(isset($extra_headers) && is_array($extra_headers)) { + foreach($extra_headers as $curr_header) { + fputs($fp, $curr_header."\r\n"); + } + } + if(!empty($user) && !empty($pass)) { + fputs($fp, "Authorization: BASIC ".base64_encode("$user:$pass")."\r\n"); + } + + fputs($fp, "\r\n"); + while(!feof($fp)) { + $content .= fgets($fp,4096); + } + fclose($fp); + $csplit = split("\r\n\r\n",$content,2); + + $content = $csplit[1]; + + if(!empty($params['assign_headers'])) { + $smarty->assign($params['assign_headers'],split("\r\n",$csplit[0])); + } + } + } else { + $smarty->_trigger_fatal_error("[plugin] unable to parse URL, check syntax"); + return; + } + } else { + // ftp fetch + if($fp = @fopen($params['file'],'r')) { + while(!feof($fp)) { + $content .= fgets ($fp,4096); + } + fclose($fp); + } else { + $smarty->_trigger_fatal_error('[plugin] fetch cannot read file \'' . $params['file'] .'\''); + return; + } + } + + } + + + if (!empty($params['assign'])) { + $smarty->assign($params['assign'],$content); + } else { + return $content; + } +} + +/* vim: set expandtab: */ + +?> diff --git a/upload/includes/templatelib/plugins/function.html_checkboxes.php b/upload/includes/templatelib/plugins/function.html_checkboxes.php new file mode 100644 index 00000000..45a161be --- /dev/null +++ b/upload/includes/templatelib/plugins/function.html_checkboxes.php @@ -0,0 +1,143 @@ + + * Type: function
    + * Name: html_checkboxes
    + * Date: 24.Feb.2003
    + * Purpose: Prints out a list of checkbox input types
    + * Input:
    + * - name (optional) - string default "checkbox" + * - values (required) - array + * - options (optional) - associative array + * - checked (optional) - array default not set + * - separator (optional) - ie
    or   + * - output (optional) - the output next to each checkbox + * - assign (optional) - assign the output as an array to this variable + * Examples: + *
    + * {html_checkboxes values=$ids output=$names}
    + * {html_checkboxes values=$ids name='box' separator='
    ' output=$names} + * {html_checkboxes values=$ids checked=$checked separator='
    ' output=$names} + *
    + * @link http://smarty.php.net/manual/en/language.function.html.checkboxes.php {html_checkboxes} + * (Smarty online manual) + * @author Christopher Kvarme + * @author credits to Monte Ohrt + * @version 1.0 + * @param array + * @param Smarty + * @return string + * @uses smarty_function_escape_special_chars() + */ +function smarty_function_html_checkboxes($params, &$smarty) +{ + require_once $smarty->_get_plugin_filepath('shared','escape_special_chars'); + + $name = 'checkbox'; + $values = null; + $options = null; + $selected = null; + $separator = ''; + $labels = true; + $output = null; + + $extra = ''; + + foreach($params as $_key => $_val) { + switch($_key) { + case 'name': + case 'separator': + $$_key = $_val; + break; + + case 'labels': + $$_key = (bool)$_val; + break; + + case 'options': + $$_key = (array)$_val; + break; + + case 'values': + case 'output': + $$_key = array_values((array)$_val); + break; + + case 'checked': + case 'selected': + $selected = array_map('strval', array_values((array)$_val)); + break; + + case 'checkboxes': + $smarty->trigger_error('html_checkboxes: the use of the "checkboxes" attribute is deprecated, use "options" instead', E_USER_WARNING); + $options = (array)$_val; + break; + + case 'assign': + break; + + default: + if(!is_array($_val)) { + $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"'; + } else { + $smarty->trigger_error("html_checkboxes: extra attribute '$_key' cannot be an array", E_USER_NOTICE); + } + break; + } + } + + if (!isset($options) && !isset($values)) + return ''; /* raise error here? */ + + settype($selected, 'array'); + $_html_result = array(); + + if (isset($options)) { + + foreach ($options as $_key=>$_val) + $_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels); + + + } else { + foreach ($values as $_i=>$_key) { + $_val = isset($output[$_i]) ? $output[$_i] : ''; + $_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels); + } + + } + + if(!empty($params['assign'])) { + $smarty->assign($params['assign'], $_html_result); + } else { + return implode("\n",$_html_result); + } + +} + +function smarty_function_html_checkboxes_output($name, $value, $output, $selected, $extra, $separator, $labels) { + $_output = ''; + if ($labels) $_output .= ''; + $_output .= $separator; + + return $_output; +} + +?> diff --git a/upload/includes/templatelib/plugins/function.html_image.php b/upload/includes/templatelib/plugins/function.html_image.php new file mode 100644 index 00000000..d758ebe7 --- /dev/null +++ b/upload/includes/templatelib/plugins/function.html_image.php @@ -0,0 +1,142 @@ + + * Name: html_image
    + * Date: Feb 24, 2003
    + * Purpose: format HTML tags for the image
    + * Input:
    + * - file = file (and path) of image (required) + * - height = image height (optional, default actual height) + * - width = image width (optional, default actual width) + * - basedir = base directory for absolute paths, default + * is environment variable DOCUMENT_ROOT + * - path_prefix = prefix for path output (optional, default empty) + * + * Examples: {html_image file="/images/masthead.gif"} + * Output: + * @link http://smarty.php.net/manual/en/language.function.html.image.php {html_image} + * (Smarty online manual) + * @author Monte Ohrt + * @author credits to Duda - wrote first image function + * in repository, helped with lots of functionality + * @version 1.0 + * @param array + * @param Smarty + * @return string + * @uses smarty_function_escape_special_chars() + */ +function smarty_function_html_image($params, &$smarty) +{ + require_once $smarty->_get_plugin_filepath('shared','escape_special_chars'); + + $alt = ''; + $file = ''; + $height = ''; + $width = ''; + $extra = ''; + $prefix = ''; + $suffix = ''; + $path_prefix = ''; + $server_vars = ($smarty->request_use_auto_globals) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS']; + $basedir = isset($server_vars['DOCUMENT_ROOT']) ? $server_vars['DOCUMENT_ROOT'] : ''; + foreach($params as $_key => $_val) { + switch($_key) { + case 'file': + case 'height': + case 'width': + case 'dpi': + case 'path_prefix': + case 'basedir': + $$_key = $_val; + break; + + case 'alt': + if(!is_array($_val)) { + $$_key = smarty_function_escape_special_chars($_val); + } else { + $smarty->trigger_error("html_image: extra attribute '$_key' cannot be an array", E_USER_NOTICE); + } + break; + + case 'link': + case 'href': + $prefix = ''; + $suffix = ''; + break; + + default: + if(!is_array($_val)) { + $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"'; + } else { + $smarty->trigger_error("html_image: extra attribute '$_key' cannot be an array", E_USER_NOTICE); + } + break; + } + } + + if (empty($file)) { + $smarty->trigger_error("html_image: missing 'file' parameter", E_USER_NOTICE); + return; + } + + if (substr($file,0,1) == '/') { + $_image_path = $basedir . $file; + } else { + $_image_path = $file; + } + + if(!isset($params['width']) || !isset($params['height'])) { + if(!$_image_data = @getimagesize($_image_path)) { + if(!file_exists($_image_path)) { + $smarty->trigger_error("html_image: unable to find '$_image_path'", E_USER_NOTICE); + return; + } else if(!is_readable($_image_path)) { + $smarty->trigger_error("html_image: unable to read '$_image_path'", E_USER_NOTICE); + return; + } else { + $smarty->trigger_error("html_image: '$_image_path' is not a valid image file", E_USER_NOTICE); + return; + } + } + if ($smarty->security && + ($_params = array('resource_type' => 'file', 'resource_name' => $_image_path)) && + (require_once(SMARTY_CORE_DIR . 'core.is_secure.php')) && + (!smarty_core_is_secure($_params, $smarty)) ) { + $smarty->trigger_error("html_image: (secure) '$_image_path' not in secure directory", E_USER_NOTICE); + } + + if(!isset($params['width'])) { + $width = $_image_data[0]; + } + if(!isset($params['height'])) { + $height = $_image_data[1]; + } + + } + + if(isset($params['dpi'])) { + if(strstr($server_vars['HTTP_USER_AGENT'], 'Mac')) { + $dpi_default = 72; + } else { + $dpi_default = 96; + } + $_resize = $dpi_default/$params['dpi']; + $width = round($width * $_resize); + $height = round($height * $_resize); + } + + return $prefix . ''.$alt.'' . $suffix; +} + +/* vim: set expandtab: */ + +?> diff --git a/upload/includes/templatelib/plugins/function.html_options.php b/upload/includes/templatelib/plugins/function.html_options.php new file mode 100644 index 00000000..f84b6313 --- /dev/null +++ b/upload/includes/templatelib/plugins/function.html_options.php @@ -0,0 +1,122 @@ + + * Name: html_options
    + * Input:
    + * - name (optional) - string default "select" + * - values (required if no options supplied) - array + * - options (required if no values supplied) - associative array + * - selected (optional) - string default not set + * - output (required if not options supplied) - array + * Purpose: Prints the list of