commit fed890a26adc5886224f1b463edec169e40a5be6 Author: david Date: Wed Mar 9 18:42:43 2011 +0000 MatchForm 2.3 original git-svn-id: https://192.168.0.254/svn/Proyectos.Incam_FormulariosCalidad/trunk@1 e2c41b2c-0c6f-0149-8b81-50b1a9191bb3 diff --git a/INSTALL.TXT b/INSTALL.TXT new file mode 100644 index 0000000..8e309da --- /dev/null +++ b/INSTALL.TXT @@ -0,0 +1,16 @@ +INSTALLATION +============ + +For the most up to date installation instructions go to: + +http://www.appnitro.com/machform/installation + + + + +UPGRADING +========= + +If you are upgrading from version 1.2 to version 2 go to: + +http://www.appnitro.com/machform/upgrade_instructions \ No newline at end of file diff --git a/ajax_form_activation.php b/ajax_form_activation.php new file mode 100644 index 0000000..cd6fa01 --- /dev/null +++ b/ajax_form_activation.php @@ -0,0 +1,34 @@ + \ No newline at end of file diff --git a/blank.gif b/blank.gif new file mode 100644 index 0000000..75b945d Binary files /dev/null and b/blank.gif differ diff --git a/captcha.php b/captcha.php new file mode 100644 index 0000000..6c05630 --- /dev/null +++ b/captcha.php @@ -0,0 +1,20 @@ +Create(); + +?> \ No newline at end of file diff --git a/changelog.txt b/changelog.txt new file mode 100644 index 0000000..bae8b9c --- /dev/null +++ b/changelog.txt @@ -0,0 +1,146 @@ +MachForm Changelog +================== + +=============================== +VERSION 1.2 - 15 September 2007 +=============================== +* New feature: added CAPTCHA for spam protection +* New feature: added panel to embed form code +* Bugfix on entry manager, column header didn't escape newlines, this break the whole extjs grid javascript +* Bugfix on excel export for UTF-8 encoding +* Bugfix on email name saving +* Bugfix on today's entry counter +* Bugfix on domain guessing for mail +* Bugfix on mkdir umask +* Bugfix on redirect for iframe +* Enhanchement on entry manager, provided a constant to limit the maximum columns to be displayed, large forms tend to be slower +* Expand last used tab on form manager + +=============================== +VERSION 1.2.b - 4 November 2007 +=============================== +* Bugfix on form submission anchor, it does not go to the top of the page where the error message is. +* Bugfix on export to excel. temporary folder wasn't explicitly configured, causing problem to some. +* Bugfix on email field ordering +* Bugfix on export to excel. header ordering. + +=============================== +VERSION 1.2.c - 15 November 2007 +=============================== +* Bugfix on export to excel. unexpected repeated data. + +=============================== +VERSION 1.2.d - 28 November 2007 +=============================== +* Bugfix on export to excel. header ordering fix somehow missed from the previous release. + +=============================== +VERSION 1.2.e - 20 February 2008 +=============================== +* Small bugfix on CSS for IE7. + +=============================== +VERSION 1.2.f - 25 February 2008 +=============================== +* Bugfix on section break. Shouldn't be displayed on email. +* Bugfix on checkbox with only one option. Doesn't displayed on email and exported files. + +=============================== +VERSION 2.0 - 28 April 2008 +=============================== +* New feature: added email autoresponder control panel +* New feature: new html email design +* New feature: fully customizable email template +* New feature: revamped entry manager +* New feature: added email autoresponder control panel +* New feature: entry viewer +* New feature: printer friendly version of an entry +* New feature: forward an entry to email +* New feature: form submission review page +* New feature: full PHP embed code +* New feature: built-in CAPTCHA +* New feature: added language file for easy translation +* New feature: form duplication +* Improved navigation +* SSL Support +* Numerous minor bugfixes + +=============================== +VERSION 2.0.b - 30 April 2008 +=============================== +* Bugfix on quotes not displayed properly in email +* Bugfix on form redirect not being sent properly + +=============================== +VERSION 2.0.c - 1 May 2008 +=============================== +* Bugfix on calendar javascript doesn't loaded properly for DD-MM-YYYY +* Improvement: full UTF-8 encoding in MySQL table + +=============================== +VERSION 2.0.d - 5 May 2008 +=============================== +* Bugfix on website validation. + +=============================== +VERSION 2.0.e - 7 May 2008 +=============================== +* Added charset header to config file, to force UTF-8 encoding. + +=============================== +VERSION 2.0.f - 21 May 2008 +=============================== +* Typo in template variables page for {form_data}. Should be {entry_data}. +* Added translation into language file for review page buttons. +* Bugfix: Checkboxes trimming 'b' and 'r' characters at the end of the label. +* Bugfix: Email validation doesn't allow single character domain. +* Bugfix: Updating checkboxes more than 10 options caused error. +* Bugfix: When deleting fields, column preference for that field should be removed. +* Bugfix: Saving large form on PHP 5.2.x sometimes doesn't work. + +=============================== +VERSION 2.0.g - 16 June 2008 +=============================== +* Bugfix: Using advanced form code, Enter key won't submit password form in IE7. +* Bugfix: Form redirect is not being sent properly when using advanced form code. +* Bugfix: IE7 reject CAPTCHA cookies when using iframe code. +* Bugfix: IE7 reject session cookies for form review. + +=============================== +VERSION 2.1 - 11 November 2008 +=============================== +* PHPMailer library upgrade. Now support secure SMTP (TLS/SSL). +* Added UPLOAD_DIR into config file, to separate upload folder with data folder. +* Added file upload type checking. +* Added random token to file upload, increased security. +* Added default .htaccess file, increased security. +* Bugfix: Zero values are not displayed properly on review page and email. +* Bugfix: Dropdowns and checkboxes are having maximum value of 255. +* Bugfix: '0' values are not being saved for dropdown/multiple choices +* Bugfix: Uploading file with quotes doesn't work properly. +* Bugfix: Download link in exported excel file doesn't work properly. + +=============================== +VERSION 2.1.b - 13 November 2008 +=============================== +* Bugfix: .htaccess file caused error on some server. + +=============================== +VERSION 2.2 - 15 May 2009 +=============================== +* Bugfix: Uploaded files are having broken link in the email when the form is using advanced form code. +* Bugfix: File upload type shouldn't be checked if the field is not required and left empty. +* Bugfix: Apostrophe causing error for field being set as unique. +* Bugfix: Editing empty date/time field within the admin causing error value for those fields. +* Bugfix: Checkboxes doesn't completely exported after some options being deleted. +* Bugfix: Linebreak doesn't displayed properly on field labels or section break. + +=============================== +VERSION 2.3 - 24 March 2010 +=============================== +* Bugfix: Double linebreak within form description. +* Bugfix: Linebreak within excel causing weird ascii characters. +* Bugfix: Excess head tag at review page when using the advanced form code. +* Bugfix: Uploading file with quotes doesn't work properly when form review being enabled. +* Bugfix: Required file upload field doesn't validate properly when form review enabled and back button pressed. +* Bugfix: Removed any deprecated messages within form view, form editor and excel export due to PHP 5.3 new rules. \ No newline at end of file diff --git a/columns_preference.php b/columns_preference.php new file mode 100644 index 0000000..a475bfb --- /dev/null +++ b/columns_preference.php @@ -0,0 +1,283 @@ +$element_name){ + do_query("insert into `ap_column_preferences`(form_id,element_name,position) values('{$form_id}','{$element_name}','{$position}')"); + } + + $_SESSION['AP_SUCCESS']['title'] = 'Success'; + $_SESSION['AP_SUCCESS']['desc'] = 'Columns preference successfully saved.'; + + header("Location: manage_entries.php?id={$form_id}"); + exit; + }else{ + $_SESSION['AP_ERROR']['title'] = 'An error occured while saving'; + $_SESSION['AP_ERROR']['desc'] = 'Please select at least one column.'; + } + } + + //get form name + $query = "select form_name from `ap_forms` where form_id='$form_id'"; + $result = do_query($query); + $row = do_fetch_result($result); + $form_name = $row['form_name']; + + //get form element options + $query = "select element_id,option_id,`option` from ap_element_options where form_id='$form_id' and live=1 order by element_id,option_id asc"; + $result = do_query($query); + while($row = do_fetch_result($result)){ + $element_id = $row['element_id']; + $option_id = $row['option_id']; + + //limit the data length + if(strlen($row['option']) > MAX_TITLE_LENGTH){ + $element_option_lookup[$element_id][$option_id] = htmlspecialchars(substr($row['option'],0,MAX_TITLE_LENGTH),ENT_QUOTES); + }else{ + $element_option_lookup[$element_id][$option_id] = htmlspecialchars($row['option'],ENT_QUOTES); + } + } + + /******************************************************************************************/ + //prepare column header names lookup + $query = "select element_id,element_title,element_type,element_constraint from `ap_form_elements` where form_id='$form_id' and element_type != 'section' order by element_position asc"; + $result = do_query($query); + + $column_name_lookup['date_created'] = 'Date Created'; + $column_name_lookup['date_updated'] = 'Date Updated'; + $column_name_lookup['ip_address'] = 'IP Address'; + + while($row = do_fetch_result($result)){ + $element_type = $row['element_type']; + $element_constraint = $row['element_constraint']; + + //limit the title length + if(strlen($row['element_title']) > MAX_TITLE_LENGTH){ + $row['element_title'] = substr($row['element_title'],0,MAX_TITLE_LENGTH); + } + + $row['element_title'] = htmlspecialchars($row['element_title']); + + if('address' == $element_type){ //address has 6 fields + $column_name_lookup['element_'.$row['element_id'].'_1'] = $row['element_title'].' - Street Address'; + $column_name_lookup['element_'.$row['element_id'].'_2'] = 'Address Line 2'; + $column_name_lookup['element_'.$row['element_id'].'_3'] = 'City'; + $column_name_lookup['element_'.$row['element_id'].'_4'] = 'State/Province/Region'; + $column_name_lookup['element_'.$row['element_id'].'_5'] = 'Zip/Postal Code'; + $column_name_lookup['element_'.$row['element_id'].'_6'] = 'Country'; + + $column_type_lookup['element_'.$row['element_id'].'_1'] = $row['element_type']; + $column_type_lookup['element_'.$row['element_id'].'_2'] = $row['element_type']; + $column_type_lookup['element_'.$row['element_id'].'_3'] = $row['element_type']; + $column_type_lookup['element_'.$row['element_id'].'_4'] = $row['element_type']; + $column_type_lookup['element_'.$row['element_id'].'_5'] = $row['element_type']; + $column_type_lookup['element_'.$row['element_id'].'_6'] = $row['element_type']; + + }elseif ('simple_name' == $element_type){ //simple name has 2 fields + $column_name_lookup['element_'.$row['element_id'].'_1'] = $row['element_title'].' - First'; + $column_name_lookup['element_'.$row['element_id'].'_2'] = $row['element_title'].' - Last'; + + $column_type_lookup['element_'.$row['element_id'].'_1'] = $row['element_type']; + $column_type_lookup['element_'.$row['element_id'].'_2'] = $row['element_type']; + + }elseif ('name' == $element_type){ //name has 4 fields + $column_name_lookup['element_'.$row['element_id'].'_1'] = $row['element_title'].' - Title'; + $column_name_lookup['element_'.$row['element_id'].'_2'] = $row['element_title'].' - First'; + $column_name_lookup['element_'.$row['element_id'].'_3'] = $row['element_title'].' - Last'; + $column_name_lookup['element_'.$row['element_id'].'_4'] = $row['element_title'].' - Suffix'; + + $column_type_lookup['element_'.$row['element_id'].'_1'] = $row['element_type']; + $column_type_lookup['element_'.$row['element_id'].'_2'] = $row['element_type']; + $column_type_lookup['element_'.$row['element_id'].'_3'] = $row['element_type']; + $column_type_lookup['element_'.$row['element_id'].'_4'] = $row['element_type']; + + }elseif('money' == $element_type){//money format + $column_name_lookup['element_'.$row['element_id']] = $row['element_title']; + if(!empty($element_constraint)){ + $column_type_lookup['element_'.$row['element_id']] = $element_constraint; //euro, pound, yen + }else{ + $column_type_lookup['element_'.$row['element_id']] = 'dollar'; //default is dollar + } + }elseif('checkbox' == $element_type){ //checkboxes, get childs elements + + $this_checkbox_options = $element_option_lookup[$row['element_id']]; + foreach ($this_checkbox_options as $option_id=>$option){ + $column_name_lookup['element_'.$row['element_id'].'_'.$option_id] = $option; + $column_type_lookup['element_'.$row['element_id'].'_'.$option_id] = $row['element_type']; + } + }else{ //for other elements with only 1 field + $column_name_lookup['element_'.$row['element_id']] = $row['element_title']; + $column_type_lookup['element_'.$row['element_id']] = $row['element_type']; + } + } + /******************************************************************************************/ + + //get values from ap_column_preferences table + $query = "select element_name from ap_column_preferences where form_id='{$form_id}'"; + $result = do_query($query); + + $column_prefs = array(); + while($row = do_fetch_result($result)){ + $column_prefs[] = $row['element_name']; + } + + $header_data =<< + + + +EOT; + +?> + + + + +
+ +
+

Entries Choose Columns

+

Specify which columns are displayed in Entries table

+
+ + +
+
+
+ + + + + + + + + +$element_label){ + if($toggle){ + $toggle = false; + $row_style = 'class="alt"'; + }else{ + $toggle = true; + $row_style = ''; + } + + if(in_array($element_name,$column_prefs)){ + $checked = 'checked="checked"'; + $img_name = 'checkbox_16.gif'; + }else{ + $checked = ''; + $img_name = 'cross_16.gif'; + } + +$table_row =<< + + + + +EOT; + echo $table_row; + $i++; + } +?> + + +
Choose columns to be displayed: 
{$element_label}

+ + + +
+
+ + + +
+ \ No newline at end of file diff --git a/config-empty.php b/config-empty.php new file mode 100644 index 0000000..791c6bc --- /dev/null +++ b/config-empty.php @@ -0,0 +1,59 @@ + \ No newline at end of file diff --git a/confirm.php b/confirm.php new file mode 100644 index 0000000..694ec0c --- /dev/null +++ b/confirm.php @@ -0,0 +1,72 @@ +top.location.replace('{$commit_result['form_redirect']}')"; + exit; + } + + }elseif (!empty($_POST['review_back'])){ + //go back to form + $ssl_suffix = get_ssl_suffix(); + header("Location: http{$ssl_suffix}://".$_SERVER['HTTP_HOST'].get_dirname($_SERVER['PHP_SELF'])."/view.php?id={$form_id}"); + exit; + }else{ + + if(empty($form_id)){ + die('ID required.'); + } + + if(!empty($_GET['done'])){ + $markup = display_success($form_id); + }else{ + if(empty($_SESSION['review_id'])){ + die("Your session has been expired. Please click here to start again."); + }else{ + $record_id = $_SESSION['review_id']; + } + $markup = display_form_review($form_id,$record_id); + } + } + + header("Content-Type: text/html; charset=UTF-8"); + echo $markup; + +?> diff --git a/confirm_embed.php b/confirm_embed.php new file mode 100644 index 0000000..79bafac --- /dev/null +++ b/confirm_embed.php @@ -0,0 +1,68 @@ +top.location.replace('{$commit_result['form_redirect']}')"; + exit; + } + }elseif (!empty($_POST['review_back'])){ + //go back to form + $ssl_suffix = get_ssl_suffix(); + header("Location: http{$ssl_suffix}://".$_SERVER['HTTP_HOST'].get_dirname($_SERVER['PHP_SELF'])."/embed.php?id={$form_id}"); + exit; + }else{ + + if(empty($form_id)){ + die('ID required.'); + } + + if(!empty($_GET['done'])){ + $markup = display_success($form_id,true); + }else{ + if(empty($_SESSION['review_id'])){ + die("Your session has been expired. Please click here to start again."); + }else{ + $record_id = $_SESSION['review_id']; + } + $markup = display_form_review($form_id,$record_id,true); + } + } + + header("Content-Type: text/html; charset=UTF-8"); + echo $markup; + +?> diff --git a/css/blank.gif b/css/blank.gif new file mode 100644 index 0000000..75b945d Binary files /dev/null and b/css/blank.gif differ diff --git a/css/email_entry.css b/css/email_entry.css new file mode 100644 index 0000000..04592a2 --- /dev/null +++ b/css/email_entry.css @@ -0,0 +1,47 @@ +/* + * SimpleModal Contact Form + * http://www.ericmmartin.com/projects/simplemodal/ + * http://code.google.com/p/simplemodal/ + * + * Copyright (c) 2007 Eric Martin - http://ericmmartin.com + * + * Licensed under the MIT license: + * http://www.opensource.org/licenses/mit-license.php + * + * Revision: $Id: contact.css 114 2008-03-20 00:53:05Z emartin24 $ + * + */ + +body {padding:0; margin:0; height:100%; width:100%;} + +/* Overlay */ +#contact-overlay {background-color:#000; } + +/* Container */ +#contact-container {width:420px; left:50%; top:25%; margin-left:-210px; font-family:'Trebuchet MS', Verdana, Arial; font-size:16px; text-align:center;} +#contact-container .contact-content {background-color:#144282; color:#ddd; height:40px;} +#contact-container h1 {color:#fff; margin:0; padding:20px 0 20px 0px; font-size:1.2em; text-align:center;text-indent: 0px} +#contact-container .contact-loading {position:absolute; background:url(../images/simple_modal/ajax-loader.gif) no-repeat; z-index:8000; height:55px; width:54px; margin:-14px 0 0 170px; padding:0;} + +#contact-container .contact-message {text-align:center;} +#contact-container .contact-error {width:92%; font-size:.8em; background:#000; border:2px solid #ccc; font-size:0.8em; font-weight:bold; margin:0 auto; padding:2px;} +#contact-container br {clear:both;} +#contact-container form {padding:0; margin:0;} +#contact-container label {clear:left; display:block; width:100px; float:left; text-align:right; padding-right:4px; font-weight:bold;} +#contact-container .contact-input {font-family:'Trebuchet MS', Verdana, Arial; padding:2px; margin:2px; background:#eee; border:1px solid #fff; width:350px;text-align: center} +#contact-container textarea {height:84px;} +#contact-container .contact-top {height:13px; background:url(../images/simple_modal/form_top.gif) no-repeat; padding:0; margin:0;} +#contact-container .contact-bottom {height:13px; background:url(../images/simple_modal/form_bottom.gif) no-repeat; font-size:.7em; text-align:center;} +#contact-container .contact-bottom a, +#contact-container .contact-bottom a:link, +#contact-container .contact-bottom a:active, +#contact-container .contact-bottom a:visited {position:relative; top:-4px; text-decoration:none; color:#666;} +#contact-container .contact-bottom a:hover {color:#888;} +#contact-container .contact-button {margin:4px 0 0 4px; cursor:pointer; height:24px; border:0; font-size:1em; font-weight:bold; color:#fff; text-align:center; vertical-align:middle;display: inline !important; float: inherit !important} +#contact-container .contact-send {width:50px; background:url(../images/simple_modal/send.png) no-repeat;padding: 0px;} +#contact-container .contact-cancel {width:65px; background:url(../images/simple_modal/cancel.png) no-repeat;padding: 0px;} +#contact-container a.modalCloseX, +#contact-container a.modalCloseX:link, +#contact-container a.modalCloseX:active, +#contact-container a.modalCloseX:visited {text-decoration:none; font-weight:bold; font-size:1.2em; position:absolute; top:-2px; left:400px; color:#fff;} +#contact-container a.modalCloseX:hover {color:#fff;} \ No newline at end of file diff --git a/css/email_entry_ie.css b/css/email_entry_ie.css new file mode 100644 index 0000000..92f6b5d --- /dev/null +++ b/css/email_entry_ie.css @@ -0,0 +1,18 @@ +/* + * SimpleModal Contact Form + * http://www.ericmmartin.com/projects/simplemodal/ + * http://code.google.com/p/simplemodal/ + * + * Copyright (c) 2007 Eric Martin - http://ericmmartin.com + * + * Licensed under the MIT license: + * http://www.opensource.org/licenses/mit-license.php + * + * Revision: $Id: contact_ie.css 113 2008-03-15 15:36:21Z emartin24 $ + * + */ + +/* IE 6 hacks*/ +#contact-container {top:expression((document.documentElement.scrollTop || document.body.scrollTop) + Math.round(15 * (document.documentElement.offsetHeight || document.body.clientHeight) / 100) + 'px');} +#contact-container .contact-top {background:url(../img/contact/form_top_ie.gif) no-repeat;} +#contact-container form {padding:0; margin:0;} \ No newline at end of file diff --git a/css/entry_print.css b/css/entry_print.css new file mode 100644 index 0000000..77dbac3 --- /dev/null +++ b/css/entry_print.css @@ -0,0 +1,52 @@ +body { + background: none !important; + margin: 0px !important; + padding: 0px !important; + font-size : 11pt !important; + overflow-y : visible !important; +} +#form_manager{ + margin: 0px !important; + padding: 0px !important; +} +#header, #footer{ + display: none !important; +} +#top, #bottom{ + display: none !important; + height: 0px !important; +} + +#ve_action_container{ + display: none !important; +} +#ve_detail{ + width: 100% !important; + float: none !important; +} +.alt{ + background-color: #fff !important; +} +.info{ + border-bottom: none !important; + padding-bottom: 10px !important; +} +.info p{ + display: none !important; +} +.breadcrumb{ + border-bottom: none !important; + color: #000 !important; +} +#ve_a_entries, #ve_a_next{ + display: none !important; +} +.global_message{ + display: none !important; +} +#view_entry{ + overflow: inherit !important; +} +#panel{ + overflow: inherit !important; +} \ No newline at end of file diff --git a/css/iepngfix.htc b/css/iepngfix.htc new file mode 100644 index 0000000..6d15f32 --- /dev/null +++ b/css/iepngfix.htc @@ -0,0 +1,68 @@ + + + + + \ No newline at end of file diff --git a/css/jquery-tabs.css b/css/jquery-tabs.css new file mode 100644 index 0000000..657c30d --- /dev/null +++ b/css/jquery-tabs.css @@ -0,0 +1,107 @@ +.ui-wrapper { border: 1px solid #50A029; } +.ui-wrapper input, .ui-wrapper textarea { border: 0; } + + +/* Caution! Ensure accessibility in print and other media types... */ +@media projection, screen { /* Use class for showing/hiding tab content, so that visibility can be better controlled in different media types... */ + .ui-tabs-hide { + display: none; + } +} + +/* Hide useless elements in print layouts... */ +@media print { + .ui-tabs-nav { + display: none; + } +} + +/* Skin */ +.ui-tabs-nav, .ui-tabs-panel { + + font-size: 12px; +} +.ui-tabs-nav { + list-style: none; + margin: 0; + padding: 0 0 0 3px; +} +.ui-tabs-nav:after { /* clearing without presentational markup, IE gets extra treatment */ + display: block; + clear: both; + content: " "; +} +.ui-tabs-nav li { + float: left; + margin: 0 0 0 2px; + font-weight: bold; +} +.ui-tabs-nav a, .ui-tabs-nav a span { + float: left; /* fixes dir=ltr problem and other quirks IE */ + padding: 0 12px; + background: url(../images/embed_code_tabs.gif) no-repeat; +} +.ui-tabs-nav a { + margin: 5px 0 0; /* position: relative makes opacity fail for disabled tab in IE */ + padding-left: 0; + background-position: 100% 0; + text-decoration: none; + white-space: nowrap; /* @ IE 6 */ + outline: 0; /* @ Firefox, prevent dotted border after click */ +} +.ui-tabs-nav a:link, .ui-tabs-nav a:visited { + color: #fff; +} +.ui-tabs-nav .ui-tabs-selected a { + position: relative; + top: 1px; + z-index: 2; + margin-top: 0; + background-position: 100% -23px; +} +.ui-tabs-nav a span { + padding-top: 1px; + padding-right: 0; + height: 20px; + background-position: 0 0; + line-height: 20px; +} +.ui-tabs-nav .ui-tabs-selected a span { + padding-top: 0; + height: 27px; + background-position: 0 -23px; + line-height: 27px; +} +.ui-tabs-nav .ui-tabs-selected a:link, .ui-tabs-nav .ui-tabs-selected a:visited, +.ui-tabs-nav .ui-tabs-disabled a:link, .ui-tabs-nav .ui-tabs-disabled a:visited { /* @ Opera, use pseudo classes otherwise it confuses cursor... */ + cursor: text; +} +.ui-tabs-nav a:hover, .ui-tabs-nav a:focus, .ui-tabs-nav a:active, +.ui-tabs-nav .ui-tabs-unselect a:hover, .ui-tabs-nav .ui-tabs-unselect a:focus, .ui-tabs-nav .ui-tabs-unselect a:active { /* @ Opera, we need to be explicit again here now... */ + cursor: pointer; +} +.ui-tabs-disabled { + opacity: .4; + filter: alpha(opacity=40); +} +.ui-tabs-nav .ui-tabs-disabled a:link, .ui-tabs-nav .ui-tabs-disabled a:visited { + color: #000; +} +.ui-tabs-panel { + padding: 10px; + padding-left: 5px; + background: #fff; /* declare background color for container to avoid distorted fonts in IE while fading */ +} +/*.ui-tabs-loading em { + padding: 0 0 0 20px; + background: url(loading.gif) no-repeat 0 50%; +}*/ + +/* Additional IE specific bug fixes... */ +* html .ui-tabs-nav { /* auto clear @ IE 6 & IE 7 Quirks Mode */ + display: inline-block; +} +*:first-child+html .ui-tabs-nav { /* auto clear @ IE 7 Standards Mode - do not group selectors, otherwise IE 6 will ignore complete rule (because of the unknown + combinator)... */ + display: inline-block; +} + diff --git a/data/.htaccess b/data/.htaccess new file mode 100644 index 0000000..9b3d22c --- /dev/null +++ b/data/.htaccess @@ -0,0 +1,16 @@ +# no access to .htaccess + +order allow,deny +deny from all + + +# view.css is required by public visitors + +allow from all + + +# limit public access + +order deny,allow +deny from all + \ No newline at end of file diff --git a/delete_element.php b/delete_element.php new file mode 100644 index 0000000..a769bd0 --- /dev/null +++ b/delete_element.php @@ -0,0 +1,118 @@ + \ No newline at end of file diff --git a/delete_element_option.php b/delete_element_option.php new file mode 100644 index 0000000..2911e42 --- /dev/null +++ b/delete_element_option.php @@ -0,0 +1,50 @@ + \ No newline at end of file diff --git a/download.php b/download.php new file mode 100644 index 0000000..8e4b4d2 --- /dev/null +++ b/download.php @@ -0,0 +1,141 @@ + \ No newline at end of file diff --git a/edit_css.php b/edit_css.php new file mode 100644 index 0000000..2d87d38 --- /dev/null +++ b/edit_css.php @@ -0,0 +1,82 @@ + + + + +
+ +
+

CSS File

+

Editing

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

+ +
+ \ No newline at end of file diff --git a/edit_entry.css b/edit_entry.css new file mode 100644 index 0000000..8d15a63 --- /dev/null +++ b/edit_entry.css @@ -0,0 +1,837 @@ +#main_body +{ + background:#fffff; + font-family:"Lucida Grande", Tahoma, Arial, Verdana, sans-serif; + font-size:small; + margin:8px 0 16px; + text-align:center; +} + +#form_container +{ + background:#fff; + border:1px solid #ccc; + margin:0 auto; + text-align:left; + width:640px; +} + + + + + +form.appnitro +{ + margin:20px 20px 0; + padding:0 0 20px; +} + +/**** Logo Section *****/ +#main_body h1 +{ + background-color:#dedede; + margin:0; + min-height:0; + padding:0; + text-decoration:none; + text-indent:-8000px; + background-image: url('../../../images/machform.gif'); + background-repeat: no-repeat; +} + +#main_body h1 a +{ + + display:block; + height:100%; + min-height:40px; + overflow:hidden; +} + + +#main_body img +{ + behavior:url(css/iepngfix.htc); + border:none; +} + + +/**** Form Section ****/ +.appnitro +{ + font-family:Lucida Grande, Tahoma, Arial, Verdana, sans-serif; + font-size:small; +} + +.appnitro li +{ + width:61%; +} + +#main_body form ul +{ + font-size:100%; + list-style-type:none; + margin:0; + padding:0; + width:100%; +} + +#main_body form li +{ + display:block; + margin:0; + padding:4px 5px 2px 9px; + position:relative; +} + +#main_body form li:after +{ + clear:both; + content:"."; + display:block; + height:0; + visibility:hidden; +} + +#main_body .buttons:after +{ + clear:both; + content:"."; + display:block; + height:0; + visibility:hidden; +} + +#main_body .buttons +{ + clear:both; + display:block; + margin-top:10px; +} + +#main_body html form li div +{ + display:inline-block; +} + +#main_body form li div +{ + color:#444; + margin:0 4px 0 0; + padding:0 0 8px; +} + +#main_body form li span +{ + color:#444; + float:left; + margin:0 4px 0 0; + padding:0 0 8px; +} + +#main_body form li div.left +{ + display:inline; + float:left; + width:48%; +} + +#main_body form li div.right +{ + display:inline; + float:right; + width:48%; +} + +#main_body form li div.left .medium +{ + width:100%; +} + +#main_body form li div.right .medium +{ + width:100%; +} + +#main_body .clear +{ + clear:both; +} + +#main_body form li div label +{ + clear:both; + color:#444; + display:block; + font-size:9px; + line-height:9px; + margin:0; + padding-top:3px; +} + +#main_body form li span label +{ + clear:both; + color:#444; + display:block; + font-size:9px; + line-height:9px; + margin:0; + padding-top:3px; +} + +#main_body form li .datepicker +{ + cursor:pointer !important; + float:left; + height:16px; + margin:.1em 5px 0 0; + padding:0; + width:16px; +} + +#main_body .form_description +{ + + display: none; + +} + + + +#main_body form hr +{ + display:none; +} + +#main_body form li.section_break +{ + border-top:1px dotted #ccc; + margin-top:9px; + padding-bottom:0; + padding-left:9px; + padding-top:13px; + width:97% !important; +} + +#main_body form ul li.first +{ + border-top:none !important; + margin-top:0 !important; + padding-top:0 !important; +} + +#main_body form .section_break h3 +{ + font-size:110%; + font-weight:400; + line-height:130%; + margin:0 0 2px; +} + +#main_body form .section_break p +{ + font-size:85%; + + margin:0 0 10px; +} + +/**** Buttons ****/ +#main_body input.button_text +{ + overflow:visible; + padding:0 7px; + width:auto; +} + +#main_body .buttons input +{ + font-size:110%; + margin-right:5px; + font-family: "Lucida Grande",Tahoma,Arial,Verdana,sans-serif; +} + +/**** Inputs and Labels ****/ +#main_body label.description +{ + border:none; + color:#222; + display:block; + font-size:95%; + font-weight:700; + line-height:150%; + padding:0 0 1px; +} + +#main_body span.symbol +{ + font-size:115%; + line-height:130%; +} + +#main_body input.text +{ + background:#fff url(images/shadow.gif) repeat-x top; + border-bottom:1px solid #ddd; + border-left:1px solid #c3c3c3; + border-right:1px solid #c3c3c3; + border-top:1px solid #7c7c7c; + color:#333; + font-size:100%; + margin:0; + padding:2px 0; +} + +#main_body input.file +{ + color:#333; + font-size:100%; + margin:0; + padding:2px 0; +} + +#main_body textarea.textarea +{ + background:#fff url(../../../images/shadow.gif) repeat-x top; + border-bottom:1px solid #ddd; + border-left:1px solid #c3c3c3; + border-right:1px solid #c3c3c3; + border-top:1px solid #7c7c7c; + color:#333; + font-family:"Lucida Grande", Tahoma, Arial, Verdana, sans-serif; + font-size:100%; + margin:0; + width:99%; +} + +#main_body select.select +{ + color:#333; + font-size:100%; + margin:1px 0; + padding:1px 0 0; + background:#fff url(../../../images/shadow.gif) repeat-x top; + border-bottom:1px solid #ddd; + border-left:1px solid #c3c3c3; + border-right:1px solid #c3c3c3; + border-top:1px solid #7c7c7c; +} + + +#main_body input.currency +{ + text-align:right; +} + +#main_body input.checkbox +{ + display:block; + height:13px; + line-height:1.4em; + margin:6px 0 0 3px; + width:13px; +} + +#main_body input.radio +{ + display:block; + height:13px; + line-height:1.4em; + margin:6px 0 0 3px; + width:13px; +} + +#main_body label.choice +{ + color:#444; + display:block; + font-size:100%; + line-height:1.4em; + margin:-1.55em 0 0 25px; + padding:4px 0 5px; + width:90%; +} + +#main_body select.select[class] +{ + margin:0; + padding:1px 0; +} + +*:first-child+html select.select[class] +{ + margin:1px 0; +} + +#main_body .safari select.select +{ + font-size:120% !important; + margin-bottom:1px; +} + +#main_body input.small +{ + width:25%; +} + +#main_body select.small +{ + width:25%; +} + +#main_body input.medium +{ + width:50%; +} + +#main_body select.medium +{ + width:50%; +} + +#main_body input.large +{ + width:99%; +} + +#main_body select.large +{ + width:100%; +} + +#main_body textarea.small +{ + height:5.5em; +} + +#main_body textarea.medium +{ + height:10em; +} + +#main_body textarea.large +{ + height:20em; +} + +/**** Errors ****/ +#error_message +{ + background:#fff; + border:1px dotted red; + margin-bottom:1em; + padding-left:0; + padding-right:0; + padding-top:4px; + text-align:center; + width:97%; +} + +#error_message_title +{ + color:#DF0000; + font-size:125%; + margin:7px 0 5px !important; + padding:0 !important; +} + +#error_message_desc +{ + color:#000; + font-size:100%; + margin:0 0 .8em !important; +} + +#error_message_desc strong +{ + background-color:#FFDFDF; + color:red; + padding:2px 3px; +} + +#main_body form li.error +{ + background-color:#FFDFDF !important; + border-bottom:1px solid #EACBCC; + border-right:1px solid #EACBCC; + margin:3px 0; +} + +#main_body form li.error label +{ + color:#DF0000 !important; +} + +#main_body form p.error +{ + clear:both; + color:red; + font-size:10px; + font-weight:700; + margin:0 0 5px !important; +} + +#main_body form .required +{ + color:red !important; + float:none !important; + font-weight:700; +} + +/**** Guidelines and Error Highlight ****/ +#main_body form li.highlighted +{ + background-color:#fff7c0; +} + +#main_body form .guidelines +{ + background:#f5f5f5; + border:1px solid #e6e6e6; + color:#444; + font-size:80%; + left:100%; + line-height:130%; + margin:0 0 0 8px !important; + padding:8px 10px 9px; + position:absolute; + top:0; + visibility:hidden; + width:42%; + z-index:1000; +} + +#main_body form .guidelines small +{ + font-size:105%; +} + +#main_body form li.highlighted .guidelines +{ + visibility:visible; +} + +#main_body form li:hover .guidelines +{ + visibility:visible; +} + +.no_guidelines .guidelines +{ + display:none !important; +} + +.no_guidelines form li +{ + width:97%; +} + +.no_guidelines li.section +{ + padding-left:9px; +} + +/*** Success Message ****/ +.form_success +{ + clear: both; + margin: 0; + padding: 90px 0pt 100px; + text-align: center +} + +.form_success h2 { + clear:left; + font-size:160%; + font-weight:normal; + margin:0pt 0pt 3px; +} + +/*** Password ****/ +#main_body ul.password{ + margin-top:60px; + margin-bottom: 60px; + text-align: center; +} +.password h2{ + color:#DF0000; + font-weight:bold; + margin:0pt auto 10px; +} + +.password input.text { + font-size:170% !important; + width:380px; + text-align: center; +} +.password label{ + display:block; + font-size:120% !important; + padding-top:10px; + font-weight:bold; +} + +#li_captcha{ + padding-left: 5px; +} + + +#li_captcha span{ + float:none; + padding: 0px !important; +} + +#li_captcha div{ + padding: 0px !important; +} + + + +/** Integrated Form **/ +.integrated *{ + font-family:"Lucida Grande", Tahoma, Arial, Verdana, sans-serif; + color: #000; +} + +.integrated #top, .integrated #bottom, .integrated h1{ + display: none; +} + +.integrated #form_container{ + border: none; + width: 99%; + background: none; +} + +.integrated #footer{ + display: none; +} + +.integrated #footer.success{ + text-align: center; +} + +.integrated form.appnitro +{ + margin:0px 0px 0; + +} + +.integrated form .section_break h3 +{ + border: none !important; +} + +.integrated #error_message h3 +{ + border: none !important; + +} + + + +/*** Calendar **********************/ +div.calendar { position: relative; } + + +.calendar table { +cursor:pointer; +border:1px solid #ccc; +font-size: 11px; +color: #000; +background: #fff; +font-family:"Lucida Grande", Tahoma, Arial, Verdana, sans-serif; +} + +.calendar table .title,.calendar table .button{ +font-size: 11px; +} + +.calendar * { +font-size: 11px; +font-family:"Lucida Grande", Tahoma, Arial, Verdana, sans-serif; +} + +.calendar .button { +text-align: center; +padding: 2px; +} + +.calendar .nav { +background:#f5f5f5; +} + +.calendar thead .title { +font-weight: bold; +text-align: center; +background: #dedede; +color: #000; +padding: 2px 0 3px 0; +} + +.calendar thead .headrow { +background: #f5f5f5; +color: #444; +font-weight:bold; +} + +.calendar thead .daynames { +background: #fff; +color:#333; +font-weight:bold; +} + +.calendar thead .name { +border-bottom: 1px dotted #ccc; +padding: 2px; +text-align: center; +color: #000; +} + +.calendar thead .weekend { +color: #666; +} + +.calendar thead .hilite { +background-color: #444; +color: #fff; +padding: 1px; +} + +.calendar thead .active { +background-color: #d12f19; +color:#fff; +padding: 2px 0px 0px 2px; +} + + +.calendar tbody .day { +width:1.8em; +color: #222; +text-align: right; +padding: 2px 2px 2px 2px; +} +.calendar tbody .day.othermonth { +font-size: 80%; +color: #bbb; +} +.calendar tbody .day.othermonth.oweekend { +color: #fbb; +} + +.calendar table .wn { +padding: 2px 2px 2px 2px; +border-right: 1px solid #000; +background: #666; +} + +.calendar tbody .rowhilite td { +background: #FFF1AF; +} + +.calendar tbody .rowhilite td.wn { +background: #FFF1AF; +} + +.calendar tbody td.hilite { +padding: 1px 1px 1px 1px; +background:#444 !important; +color:#fff !important; +} + +.calendar tbody td.active { +color:#fff; +background: #529214 !important; +padding: 2px 2px 0px 2px; +} + +.calendar tbody td.selected { +font-weight: bold; +border: 1px solid #888; +padding: 1px 1px 1px 1px; +background: #f5f5f5 !important; +color: #222 !important; +} + +.calendar tbody td.weekend { +color: #666; +} + +.calendar tbody td.today { +font-weight: bold; +color: #529214; +background:#D9EFC2; +} + +.calendar tbody .disabled { color: #999; } + +.calendar tbody .emptycell { +visibility: hidden; +} + +.calendar tbody .emptyrow { +display: none; +} + +.calendar tfoot .footrow { +text-align: center; +background: #556; +color: #fff; +} + +.calendar tfoot .ttip { +background: #222; +color: #fff; +font-size:10px; +border-top: 1px solid #dedede; +padding: 3px; +} + +.calendar tfoot .hilite { +background: #aaf; +border: 1px solid #04f; +color: #000; +padding: 1px; +} + +.calendar tfoot .active { +background: #77c; +padding: 2px 0px 0px 2px; +} + +.calendar .combo { +position: absolute; +display: none; +top: 0px; +left: 0px; +width: 4em; +border: 1px solid #ccc; +background: #f5f5f5; +color: #222; +font-size: 90%; +z-index: 100; +} + +.calendar .combo .label, +.calendar .combo .label-IEfix { +text-align: center; +padding: 1px; +} + +.calendar .combo .label-IEfix { +width: 4em; +} + +.calendar .combo .hilite { +background: #444; +color:#fff; +} + +.calendar .combo .active { +border-top: 1px solid #999; +border-bottom: 1px solid #999; +background: #dedede; +font-weight: bold; +} + diff --git a/edit_entry.php b/edit_entry.php new file mode 100644 index 0000000..7e8edd3 --- /dev/null +++ b/edit_entry.php @@ -0,0 +1,203 @@ + $entry_id order by id asc limit 1"); + $row = do_fetch_result($result); + $newer_entry_id = $row['id']; + + //newest entry id + $result = do_query("select id from ap_form_{$form_id} order by id desc limit 1"); + $row = do_fetch_result($result); + $newest_entry_id = $row['id']; + + if(($entry_id == $newest_entry_id) && ($entry_id == $oldest_entry_id)){ + $nav_position = 'disabled'; + }elseif($entry_id == $newest_entry_id){ + $nav_position = 'newest'; + }elseif ($entry_id == $oldest_entry_id){ + $nav_position = 'oldest'; + }else{ + $nav_position = 'middle'; + } + +?> + + + + +
+ +
+

Entries #

+

Editing entry #

+
+ + +
+
+ +
+ +
+
+ + " alt="Newest">  + " alt="Newer">  + + + +   +   + + + +" alt="Older">  + " alt="Oldest"> + + +   + + +
+
Entry Options
+
+ +
+
+ + +
+ \ No newline at end of file diff --git a/edit_form.php b/edit_form.php new file mode 100644 index 0000000..2fcf786 --- /dev/null +++ b/edit_form.php @@ -0,0 +1,721 @@ +id = $form_id; + $form->name = $row['form_name']; + $form->description = $row['form_description']; + $form->redirect = $row['form_redirect']; + $form->success_message = $row['form_success_message']; + $form->password = $row['form_password']; + $form->frame_height = $row['form_frame_height']; + $form->unique_ip = $row['form_unique_ip']; + $form->captcha = $row['form_captcha']; + $form->review = $row['form_review']; + }else{ + $form->id = 0; + $form->name = 'Untitled Form'; + $form->description = 'This is your form description. Click here to edit.'; + $form->redirect = ''; + $form->success_message = 'Success! Your submission has been saved!'; + $form->password = ''; + $form->frame_height = 0; + $form->unique_ip = 0; + $form->captcha = 0; + $form->review = 0; + } + + //get element options first and store it into array + $query = "select + element_id, + option_id, + `position`, + `option`, + option_is_default + from + ap_element_options + where + form_id='$form_id' and live=1 + order by + element_id asc,`position` asc"; + $result = do_query($query); + while($row = do_fetch_result($result)){ + $element_id = $row['element_id']; + $option_id = $row['option_id']; + $options_lookup[$element_id][$option_id]['position'] = $row['position']; + $options_lookup[$element_id][$option_id]['option'] = $row['option']; + $options_lookup[$element_id][$option_id]['option_is_default'] = $row['option_is_default']; + } + + + //get elements data + $element = array(); + $query = "select + element_id, + element_title, + element_guidelines, + element_size, + element_is_required, + element_is_unique, + element_is_private, + element_type, + element_position, + element_default_value, + element_constraint + from + ap_form_elements + where + form_id='$form_id' + order by + element_position asc"; + $result = do_query($query); + $j=0; + while($row = do_fetch_result($result)){ + $element_id = $row['element_id']; + + //lookup element options first + if(!empty($options_lookup[$element_id])){ + $element_options = array(); + $i=0; + foreach ($options_lookup[$element_id] as $option_id=>$data){ + $element_options[$i] = new stdClass(); + $element_options[$i]->id = $option_id; + $element_options[$i]->option = $data['option']; + $element_options[$i]->is_default = $data['option_is_default']; + $element_options[$i]->is_db_live = 1; + $i++; + } + } + + + //populate elements + $element[$j] = new stdClass(); + $element[$j]->title = $row['element_title']; + $element[$j]->guidelines = $row['element_guidelines']; + $element[$j]->size = $row['element_size']; + $element[$j]->is_required = $row['element_is_required']; + $element[$j]->is_unique = $row['element_is_unique']; + $element[$j]->is_private = $row['element_is_private']; + $element[$j]->type = $row['element_type']; + $element[$j]->position = $row['element_position']; + $element[$j]->id = $row['element_id']; + $element[$j]->is_db_live = 1; + $element[$j]->default_value = $row['element_default_value']; + $element[$j]->constraint = $row['element_constraint']; + if(!empty($element_options)){ + $element[$j]->options = $element_options; + }else{ + $element[$j]->options = ''; + } + $j++; + } + + + $json = new Services_JSON(); + $json_form = $json->encode($form); + + + $all_element = array('elements' => $element); + + $json_element = $json->encode($all_element); + + + $header_data =<< + +EOT; + + $show_status_bar = true; //for header.php + + require('includes/header.php'); +?> + +
+
+
    + +
    +

    You have no fields yet!

    +

    Click the buttons on the right to add fields to your form.

    +
    + + +
    +
    +
    + + + + + +var json_form = {$json_form}; +var json_elements = {$json_element}; + +EOT; + require('includes/footer.php'); +?> diff --git a/email_entry.php b/email_entry.php new file mode 100644 index 0000000..3a274ec --- /dev/null +++ b/email_entry.php @@ -0,0 +1,127 @@ + + x +
    +
    +

    Email Entry #{$entry_id} to:

    + + +
    +
    + Use commas to separate email addresses

    + + +
    + + +
    +
    +
    +
    "; + }elseif ($action == 'send') { + + $to_emails = trim($_REQUEST['email']); + + //get form properties data + $query = "select + esl_from_name, + esl_from_email_address, + esl_subject, + esl_content, + esl_plain_text + from + `ap_forms` + where + form_id='$form_id'"; + + $result = do_query($query); + $row = do_fetch_result($result); + + $esl_from_name = $row['esl_from_name']; + $esl_from_email_address = $row['esl_from_email_address']; + $esl_subject = $row['esl_subject']; + $esl_content = $row['esl_content']; + $esl_plain_text = $row['esl_plain_text']; + + //get parameters for the email + + //from name + if(!empty($esl_from_name)){ + $admin_email_param['from_name'] = $esl_from_name; + }elseif (NOTIFICATION_MAIL_FROM_NAME != ''){ + $admin_email_param['from_name'] = NOTIFICATION_MAIL_FROM_NAME; + }else{ + $admin_email_param['from_name'] = 'MachForm'; + } + + //from email address + if(!empty($esl_from_email_address)){ + if(is_numeric($esl_from_email_address)){ + $admin_email_param['from_email'] = '{element_'.$esl_from_email_address.'}'; + }else{ + $admin_email_param['from_email'] = $esl_from_email_address; + } + }elseif(NOTIFICATION_MAIL_FROM != ''){ + $admin_email_param['from_email'] = NOTIFICATION_MAIL_FROM; + }else{ + $domain = str_replace('www.','',$_SERVER['SERVER_NAME']); + $admin_email_param['from_email'] = "no-reply@{$domain}"; + } + + //subject + if(!empty($esl_subject)){ + $admin_email_param['subject'] = $esl_subject; + }elseif (NOTIFICATION_MAIL_SUBJECT != ''){ + $admin_email_param['subject'] = NOTIFICATION_MAIL_SUBJECT; + }else{ + $admin_email_param['subject'] = '{form_name} [#{entry_no}]'; + } + + //content + if(!empty($esl_content)){ + $admin_email_param['content'] = $esl_content; + }else{ + $admin_email_param['content'] = '{entry_data}'; + } + + $admin_email_param['as_plain_text'] = $esl_plain_text; + $admin_email_param['target_is_admin'] = true; + + send_notification($form_id,$entry_id,$to_emails,$admin_email_param); + + echo "Entry #{$entry_id} successfully sent."; + } + + + + +?> \ No newline at end of file diff --git a/email_settings.css b/email_settings.css new file mode 100644 index 0000000..c2cfc04 --- /dev/null +++ b/email_settings.css @@ -0,0 +1,539 @@ +#esl_main_body, #esr_main_body +{ + background:#fffff; + font-family:"Lucida Grande", Tahoma, Arial, Verdana, sans-serif; + font-size:small; + margin:8px 0 16px; + text-align:center; +} + +#esl_form_container, #esr_form_container +{ + background:#fff; + border:1px solid #ccc; + margin:0 auto; + text-align:left; + width:640px; +} + + +form.appnitro +{ + margin:20px 20px 0; + padding:0px; +} + +.esl_options{ + display: none; +} +.esr_options{ + display: none; +} +/**** Form Section ****/ +.appnitro +{ + font-family:Lucida Grande, Tahoma, Arial, Verdana, sans-serif; + font-size:small; +} + +.appnitro li +{ + width:98%; + padding-right: 0px !important; + +} + +#esl_main_body form ul,#esr_main_body form ul +{ + font-size:100%; + list-style-type:none; + margin:0; + padding:0; + width:100%; +} + +#esl_main_body form li,#esr_main_body form li +{ + /*display:block;*/ + margin:0; + padding:4px 5px 2px 9px; + position:relative; +} + +#esl_main_body form li:after,#esr_main_body form li:after +{ + clear:both; + content:"."; + display:block; + height:0; + visibility:hidden; +} + +#esl_main_body .buttons:after,#esr_main_body .buttons:after +{ + clear:both; + content:"."; + display:block; + height:0; + visibility:hidden; +} + +#esl_main_body .buttons,#esr_main_body .buttons +{ + clear:both; + display:block; + width: 100%; + +} + +#esl_main_body html form li div,#esr_main_body html form li div +{ + display:inline-block; +} + +#esl_main_body form li div,#esr_main_body form li div +{ + color:#444; + margin:0 4px 0 0; + padding:0 0 8px; +} + +#esl_main_body form li span,#esr_main_body form li span +{ + color:#444; + float:left; + margin:0 4px 0 0; + padding:0px !important; +} + +#esl_main_body form li div.left,#esr_main_body form li div.left +{ + display:inline; + float:left; + width:48%; +} + +#esl_main_body form li div.right,#esr_main_body form li div.right +{ + display:inline; + float:right; + width:48%; +} + +#esl_main_body form li div.left .medium,#esr_main_body form li div.left .medium +{ + width:100%; +} + +#esl_main_body form li div.right .medium,#esr_main_body form li div.right .medium +{ + width:100%; +} + +#esl_main_body .clear,#esr_main_body .clear +{ + clear:both; +} + +#esl_main_body form li div label,#esr_main_body form li div label +{ + clear:both; + color:#444; + display:block; + font-size:9px; + line-height:9px; + margin:0; + padding-top:3px; +} + +#esl_main_body form li span label,#esr_main_body form li span label +{ + clear:both; + color:#444; + display:block; + font-size:9px; + line-height:9px; + margin:0; + padding-top:3px; +} + + + +#esl_main_body form hr,#esr_main_body form hr +{ + display:none; +} + +#esl_main_body form li.section_break,#esr_main_body form li.section_break +{ + border-top:1px dotted #ccc; + margin-top:9px; + padding-bottom:0; + padding-left:9px; + padding-top:13px; + width:97% !important; +} + +#esl_main_body form ul li.first,#esr_main_body form ul li.first +{ + border-top:none !important; + margin-top:0 !important; + padding-top:0 !important; +} + +#esl_main_body form .section_break h3,#esr_main_body form .section_break h3 +{ + font-size:110%; + font-weight:400; + line-height:130%; + margin:0 0 2px; + color: #444; + padding: 0px; +} + +#esl_main_body form .section_break p,#esr_main_body form .section_break p +{ + font-size:85%; + + margin:0 0 10px; +} + +/**** Buttons ****/ +#esl_main_body input.button_text,#esr_main_body input.button_text +{ + overflow:visible; + padding:0 7px; + width:auto; +} + +#esl_main_body .buttons input,#esr_main_body .buttons input +{ + font-size:120%; + margin-right:5px; +} + +/**** Inputs and Labels ****/ +#esl_main_body label.description,#esr_main_body label.description +{ + border:none; + color:#222; + display:block; + font-size:95%; + font-weight:700; + line-height:150%; + padding:0 0 1px; +} + +#esl_main_body span.symbol,#esr_main_body span.symbol +{ + font-size:115%; + line-height:130%; +} + +#esl_main_body input.text,#esr_main_body input.text +{ + background:#fff url(images/shadow.gif) repeat-x top; + border-bottom:1px solid #ddd; + border-left:1px solid #c3c3c3; + border-right:1px solid #c3c3c3; + border-top:1px solid #7c7c7c; + color:#333; + font-size:100%; + margin:0; + padding:2px 0; +} + +#esl_main_body input.file,#esr_main_body input.file +{ + color:#333; + font-size:100%; + margin:0; + padding:2px 0; +} + +#esl_main_body textarea.textarea,#esr_main_body textarea.textarea +{ + background:#fff url(images/shadow.gif) repeat-x top; + border-bottom:1px solid #ddd; + border-left:1px solid #c3c3c3; + border-right:1px solid #c3c3c3; + border-top:1px solid #7c7c7c; + color:#333; + font-family:"Lucida Grande", Tahoma, Arial, Verdana, sans-serif; + font-size:100%; + margin:0; + width:98%; +} + +#esl_main_body select.select,#esr_main_body select.select +{ + color:#333; + font-size:100%; + margin:1px 0; + padding:1px 0 0; + background:#fff url(images/shadow.gif) repeat-x top; + border-bottom:1px solid #ddd; + border-left:1px solid #c3c3c3; + border-right:1px solid #c3c3c3; + border-top:1px solid #7c7c7c; +} + + +#esl_main_body input.currency,#esr_main_body input.currency +{ + text-align:right; +} + +#esl_main_body input.checkbox,#esr_main_body input.checkbox +{ + display:block; + height:13px; + line-height:1.4em; + margin:6px 0 0 3px; + width:13px; +} + +#esl_main_body input.radio,#esr_main_body input.radio +{ + display:block; + height:13px; + line-height:1.4em; + margin:6px 0 0 3px; + width:13px; +} + +#esl_main_body label.choice,#esr_main_body label.choice +{ + color:#444; + display:block; + font-size:100%; + line-height:1.4em; + margin:-1.55em 0 0 25px; + padding:4px 0 5px; + width:90%; +} + +#esl_main_body select.select[class],#esr_main_body select.select[class] +{ + margin:0; + padding:1px 0; +} + +*:first-child+html select.select[class] +{ + margin:1px 0; +} + +#esl_main_body .safari select.select,#esr_main_body .safari select.select +{ + font-size:120% !important; + margin-bottom:1px; +} + +#esl_main_body input.small,#esr_main_body input.small +{ + width:25%; +} + +#esl_main_body select.small,#esr_main_body select.small +{ + width:25%; +} + +#esl_main_body input.medium,#esr_main_body input.medium +{ + width:50%; +} + +#esl_main_body select.medium,#esr_main_body select.medium +{ + width:50%; +} + +#esl_main_body input.large,#esr_main_body input.large +{ + width:98%; +} + +#esl_main_body select.large,#esr_main_body select.large +{ + width:100%; +} + +#esl_main_body textarea.small,#esr_main_body textarea.small +{ + height:5.5em; +} + +#esl_main_body textarea.medium,#esr_main_body textarea.medium +{ + height:10em; +} + +#esl_main_body textarea.large,#esr_main_body textarea.large +{ + height:20em; +} + +/**** Errors ****/ +#error_message +{ + background:#fff; + border:1px dotted red; + margin-bottom:1em; + padding-left:0; + padding-right:0; + padding-top:4px; + text-align:center; + width:97%; +} + +#error_message_title +{ + color:#DF0000; + font-size:125%; + margin:7px 0 5px !important; + padding:0 !important; +} + +#error_message_desc +{ + color:#000; + font-size:100%; + margin:0 0 .8em !important; +} + +#error_message_desc strong +{ + background-color:#FFDFDF; + color:red; + padding:2px 3px; +} + +#esl_main_body form li.error,#esr_main_body form li.error +{ + background-color:#FFDFDF !important; + border-bottom:1px solid #EACBCC; + border-right:1px solid #EACBCC; + margin:3px 0; +} + +#esl_main_body form li.error label,#esr_main_body form li.error label +{ + color:#DF0000 !important; +} + +#esl_main_body form p.error,#esr_main_body form p.error +{ + clear:both; + color:red; + font-size:10px; + font-weight:700; + margin:0 0 5px !important; +} + +#esl_main_body form .required,#esr_main_body form .required +{ + color:red !important; + float:none !important; + font-weight:700; +} + +/**** Guidelines and Error Highlight ****/ +#esl_main_body form li.highlighted,#esr_main_body form li.highlighted +{ + background-color:#fff7c0; +} + +#esl_main_body form .guidelines,#esr_main_body form .guidelines +{ + background:#f5f5f5; + border:1px solid #e6e6e6; + color:#444; + font-size:80%; + left:100%; + line-height:130%; + margin:0 0 0 8px !important; + padding:8px 10px 9px; + position:absolute; + top:0; + visibility:hidden; + width:42%; + z-index:1000; +} + +#esl_main_body form .guidelines small,#esr_main_body form .guidelines small +{ + font-size:105%; +} + +#esl_main_body form li.highlighted .guidelines,#esr_main_body form li.highlighted .guidelines +{ + visibility:visible; +} + +#esl_main_body form li:hover .guidelines,#esr_main_body form li:hover .guidelines +{ + visibility:visible; +} + +.no_guidelines .guidelines +{ + display:none !important; +} + +.no_guidelines form li +{ + width:97%; +} + +.no_guidelines li.section +{ + padding-left:9px; +} + + +/** Integrated Form **/ +.integrated *{ + font-family:"Lucida Grande", Tahoma, Arial, Verdana, sans-serif; + color: #000; +} + +.integrated #top, .integrated #bottom, .integrated h1{ + display: none; +} + +.integrated #esl_form_container,.integrated #esr_form_container{ + border: none; + width: 100%; + background: none; + +} + +.integrated #footer{ + text-align: left; + padding-left: 10px; + width: 99%; +} + +.integrated #footer.success{ + text-align: center; +} + +.integrated form.appnitro +{ + margin:0px 0px 0; + +} + +.integrated form .section_break h3 +{ + border: none !important; +} + +.integrated #error_message h3 +{ + border: none !important; + +} + diff --git a/email_settings.php b/email_settings.php new file mode 100644 index 0000000..e4d4103 --- /dev/null +++ b/email_settings.php @@ -0,0 +1,526 @@ +$value){ + $value = mysql_real_escape_string($value); + $update_values .= "`$key`='$value',"; + } + $update_values = substr($update_values,0,-1); + + $query = "UPDATE `ap_forms` set + $update_values + where + form_id='{$form_id}';"; + + do_query($query); + + $_SESSION['AP_SUCCESS']['title'] = 'Success'; + $_SESSION['AP_SUCCESS']['desc'] = 'Notification settings have been saved.'; + + header("Location: email_settings.php?id={$form_id}"); + exit; + }else{ + $_SESSION['AP_ERROR']['title'] = $lang['error_title']; + $_SESSION['AP_ERROR']['desc'] = $lang['error_desc']; + } + + }else{ + //populate current values or default values + $_POST['esl_email_address'] = $form_email; + + if(!empty($esl_from_name)){ + $_POST['esl_from_name'] = $esl_from_name; + }elseif (NOTIFICATION_MAIL_FROM_NAME != ''){ + $_POST['esl_from_name'] = NOTIFICATION_MAIL_FROM_NAME; + }else{ + $_POST['esl_from_name'] = 'MachForm'; + } + + $_POST['esl_from_email_address'] = $esl_from_email_address; + + if(!empty($esl_subject)){ + $_POST['esl_subject'] = $esl_subject; + }elseif (NOTIFICATION_MAIL_SUBJECT != ''){ + $_POST['esl_subject'] = NOTIFICATION_MAIL_SUBJECT; + }else{ + $_POST['esl_subject'] = '{form_name} [#{entry_no}]'; + } + + if(!empty($esl_content)){ + $_POST['esl_content'] = $esl_content; + }else{ + $_POST['esl_content'] = '{entry_data}'; + } + + $_POST['esl_plain_text'] = $esl_plain_text; + $_POST['esl_options_expand'] = 0; + } + //end left form handler -------- + + //start right form handler -------- + $esr_email_fields = $email_fields; + $esr_valid_email = true; + + if(!empty($_POST['esr_submit'])){ + unset($_POST['esr_submit']); + $input_array = ap_sanitize_input($_POST); + + //validate for valid email address + if(!empty($input_array['esr_from_email_address'])){ + $regex = '/^[A-z0-9][\w.-]*@[A-z0-9][\w\-\.]+\.[A-z0-9]{2,6}$/'; + $email = trim($input_array['esr_from_email_address']); + $result = preg_match($regex, $email); + + if(empty($result)){ + $esr_valid_email = false; + } + + } + + //if passed, store into database + if($esr_valid_email){ + $esr_input['esr_email_address'] = $input_array['esr_email_address']; + $esr_input['esr_from_name'] = $input_array['esr_from_name']; + $esr_input['esr_from_email_address'] = $input_array['esr_from_email_address']; + $esr_input['esr_subject'] = $input_array['esr_subject']; + $esr_input['esr_content'] = $input_array['esr_content']; + $esr_input['esr_plain_text'] = $input_array['esr_plain_text']; + + if(empty($esr_input['esr_plain_text'])){ + $esr_input['esr_plain_text'] = 0; + } + + //create the sql update string + foreach ($esr_input as $key=>$value){ + $value = mysql_real_escape_string($value); + $update_values .= "`$key`='$value',"; + } + $update_values = substr($update_values,0,-1); + + $query = "UPDATE `ap_forms` set + $update_values + where + form_id='{$form_id}';"; + + do_query($query); + + $_SESSION['AP_SUCCESS']['title'] = 'Success'; + $_SESSION['AP_SUCCESS']['desc'] = 'Notification settings have been saved.'; + + header("Location: email_settings.php?id={$form_id}"); + exit; + }else{ + $_SESSION['AP_ERROR']['title'] = $lang['error_title']; + $_SESSION['AP_ERROR']['desc'] = $lang['error_desc']; + $_POST['esr_options_expand'] = 1; + } + }else{ + //populate current values or default values + $_POST['esr_email_address'] = $esr_email_address; + + if(!empty($esr_from_name)){ + $_POST['esr_from_name'] = $esr_from_name; + }elseif (NOTIFICATION_MAIL_FROM_NAME != ''){ + $_POST['esr_from_name'] = NOTIFICATION_MAIL_FROM_NAME; + }else{ + $_POST['esr_from_name'] = 'MachForm'; + } + + if(!empty($esr_from_email_address)){ + $_POST['esr_from_email_address'] = $esr_from_email_address; + }elseif(NOTIFICATION_MAIL_FROM != ''){ + $_POST['esr_from_email_address'] = NOTIFICATION_MAIL_FROM; + }else{ + $domain = str_replace('www.','',$_SERVER['SERVER_NAME']); + $_POST['esr_from_email_address'] = "no-reply@{$domain}"; + } + + if(!empty($esr_subject)){ + $_POST['esr_subject'] = $esr_subject; + }else{ + $_POST['esr_subject'] = '{form_name} - Receipt'; + } + + if(!empty($esr_content)){ + $_POST['esr_content'] = $esr_content; + }else{ + $_POST['esr_content'] = '{entry_data}'; + } + + $_POST['esr_plain_text'] = $esr_plain_text; + $_POST['esr_options_expand'] = 0; + + } + //end right form handler --------- + + if(!empty($_POST['esl_options_expand'])){ + $esl_style = ''; + } + + if(!empty($_POST['esr_options_expand'])){ + $esr_style = ''; + } + + $header_data =<< + + + + {$esl_style} + {$esr_style} +EOT; +?> + + + +
    + +
    +

    Emails

    +

    Configure your email notification settings

    +
    +

    Send notification emails to

    +
    +

    You

    +
    + + +
    + +
    +
    +
      +
    • > + +
      + +
      + {$lang['val_email']}

      "; }; ?> +
    • +
    • +

       Email Header

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

       Email Content

      +
    • +
    • + +
      + +
      + +
    • +
    • + +
      + +
      +
    • +
    • + + + /> + + +
      + Info
      You can insert template variables into the above fields. +
      +
    • +
    • + +
      + +
      +
    • +
    • + + + + +
    • +
    +
    +
    + +
    + + +
    + +
    +
    +

    Your Users

    +
    + + +
    + +
    +
    +
      + +
    • + +
      + +
      +
    • + +
    • + +
      + To enable sending email to your users, an Email field is required on the form. +
      +
    • + +
    • +

       Email Header

      +
    • +
    • + +
      + +
      +
    • +
    • + +
      + +
      + {$lang['val_email']}

      "; }; ?> +
    • +
    • +

       Email Content

      +
    • +
    • + +
      + +
      +
    • +
    • + +
      + +
      +
    • +
    • + + + /> + + +
      + Info
      You can insert template variables into the above fields. +
      +
    • +
    • +
      + + + +
      +
    • +
    • + + + /> +
    • +
    +
    +
    + +
    + + +
    +
    +
    +
    + \ No newline at end of file diff --git a/embed.php b/embed.php new file mode 100644 index 0000000..a93fe8b --- /dev/null +++ b/embed.php @@ -0,0 +1,94 @@ +top.location = '{$submit_result['form_redirect']}'"; + exit; + } + }else{ //redirect to review page + $ssl_suffix = get_ssl_suffix(); + $_SESSION['review_id'] = $submit_result['review_id']; + + header("Location: http{$ssl_suffix}://".$_SERVER['HTTP_HOST'].get_dirname($_SERVER['PHP_SELF'])."/confirm_embed.php?id={$input_array['form_id']}"); + exit; + } + + }else{ + $old_values = $submit_result['old_values']; + $custom_error = $submit_result['custom_error']; + $error_elements = $submit_result['error_elements']; + + $markup = display_form($input_array['form_id'],$old_values,$error_elements,$custom_error,0,true); + } + }else{ //if password form submitted + if($submit_result['status'] === true){ //on success, display the form + $markup = display_form($input_array['form_id'],null,null,'',0,true); + }else{ + $custom_error = $submit_result['custom_error']; //error, display the pasword form again + $markup = display_form($input_array['form_id'],null,null,$custom_error,0,true); + } + } + }else{ + $form_id = (int) trim($_GET['id']); + if(empty($form_id)){ + die('ID required.'); + } + + //check for delete file option + //this is available for form with review enabled + if(!empty($_GET['delete_file']) && !empty($_SESSION['review_id'])){ + $element_id = (int) trim($_GET['delete_file']); + delete_review_file_entry($form_id,$_SESSION['review_id'],$element_id); + } + + if(!empty($_GET['done'])){ + $markup = display_success($form_id,true); + }else{ + $markup = display_form($form_id,null,null,'',0,true); + } + } + + header("Content-Type: text/html; charset=UTF-8"); + echo $markup; + +?> diff --git a/embed_code.php b/embed_code.php new file mode 100644 index 0000000..f59db1e --- /dev/null +++ b/embed_code.php @@ -0,0 +1,159 @@ +'.$form_name.''; + + $form_link_code = ''.$form_name.''; + + + $current_dir = rtrim(dirname($_SERVER['PHP_SELF'])); + if($current_dir == "/" || $current_dir == "\\"){ + $current_dir = ''; + } + + $absolute_dir_path = rtrim(dirname($_SERVER['SCRIPT_FILENAME'])); + + $advanced_form_code =<< +EOT; + + $header_data =<< + + + +EOT; +?> + + + +
    +
    +

    Embed Code

    +

    Copy and paste one of the code below into your website

    +
    +
    + +
    + +
    +
      +
    • + +
      + +
      + Use this code to embed your form to any page of your website or blog.

      + Instructions
      + +

      1. Copy and paste the code into your web page.

      +

      2. Publish the file on your server.

      +

      3. Adjust the "height" variable of the iframe as needed.

      +

      4. Adjust your form CSS file to match your website style as needed.

      +
      +
      +
      +
    • +
    +
    + +
    +
    + +
    +
      +
    • + +
      + +
      + This is for advanced user only. Use this code to integrate your form into your *.php pages without using iframe. Some PHP and CSS knowledge might be required.

      + Instructions
      + +

      1. Copy and paste the code into your PHP page.

      +

      2. Publish the file on your server.

      +

      3. Adjust the CSS of your form to match your current page.

      +

      4. This code might not work on certain PHP page, thus it's not guaranteed to work on all pages. In case of failure, use Standard Form Code instead.

      +
      +
      +
    • +
    +
    +
    +
    + +
    +
      +
    • + +
      + +
      + Use this code to provide a link to your complete form.

      + Instructions
      + +

      1. Copy and paste the code into your PHP page.

      +

      2. Publish the file on your server.

      +
      +
      +
    • +
    +


    +
    +
    + + +
    + + \ No newline at end of file diff --git a/export_entries.php b/export_entries.php new file mode 100644 index 0000000..6b28ed8 --- /dev/null +++ b/export_entries.php @@ -0,0 +1,417 @@ +$option){ + $column_name_lookup['element_'.$row['element_id'].'_'.$option_id] = $option; + $column_type_lookup['element_'.$row['element_id'].'_'.$option_id] = $row['element_type']; + } + }elseif ('time' == $element_type){ + if($element_constraint == 'show_seconds'){ + $column_type_lookup['element_'.$row['element_id']] = $row['element_type']; + }else{ + $column_type_lookup['element_'.$row['element_id']] = 'time_noseconds'; + } + + $column_name_lookup['element_'.$row['element_id']] = $row['element_title']; + }else{ //for other elements with only 1 field + $column_name_lookup['element_'.$row['element_id']] = $row['element_title']; + $column_type_lookup['element_'.$row['element_id']] = $row['element_type']; + } + } + /******************************************************************************************/ + + + + + //set column properties for basic fields + $column_name_lookup['id'] = $lang['export_num']; + $column_name_lookup['date_created'] = $lang['date_created']; + $column_name_lookup['date_updated'] = $lang['date_updated']; + $column_name_lookup['ip_address'] = $lang['ip_address']; + + $column_type_lookup['id'] = 'number'; + $column_type_lookup['date_created'] = 'text'; + $column_type_lookup['date_updated'] = 'text'; + $column_type_lookup['ip_address'] = 'text'; + + + /******************************************************************************************/ + //prepare headers + if($type == 'xls'){ + require('Spreadsheet/Excel/Writer.php'); + + // Creating a workbook + $workbook = new Spreadsheet_Excel_Writer(); + + $workbook->setTempDir(DATA_DIR); + + // sending HTTP headers + $clean_form_name = preg_replace("/[^A-Za-z0-9_-]/","",$form_name); + $workbook->send("{$clean_form_name}.xls"); + + if(function_exists('iconv')){ + $workbook->setVersion(8); + } + + // Creating a worksheet + $clean_form_name = substr($clean_form_name,0,30); //must be less than 31 characters + $worksheet =& $workbook->addWorksheet($clean_form_name); + + $format_bold =& $workbook->addFormat(); + $format_bold->setBold(); + $format_bold->setFgColor(22); + $format_bold->setPattern(1); + $format_bold->setBorder(1); + + if(function_exists('iconv')){ + $worksheet->setInputEncoding('UTF-8'); + } + + $format_wrap = $workbook->addFormat(); + $format_wrap->setTextWrap(); + + }elseif ($type == 'csv'){ + require('Compat/Function/fputcsv.php'); + + $clean_form_name = preg_replace("/[^A-Za-z0-9_-]/","",$form_name); + + //Prepare headers + header("Pragma: public"); + header("Expires: 0"); + header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); + header("Cache-Control: public", false); + header("Content-Description: File Transfer"); + header("Content-Type: application/vnd.ms-excel"); + header("Content-Disposition: attachment; filename=\"{$clean_form_name}.csv\""); + + $out = fopen('php://output', 'w'); + } + + /******************************************************************************************/ + + //get column labels, order in the correct position + $query = "select * from `ap_form_{$form_id}` limit 1"; //limit 1 being used so that we could get the headers + $result = do_query($query); + + //get actual field name from selected table + $i = 0; + $fields_num = mysql_num_fields($result); + while($i < $fields_num){ + $meta = mysql_fetch_field($result, $i); + $columns[$i] = $meta->name; + $i++; + } + + + $temp_columns = array_slice($columns,0,4); + + //first, reorder columns into the correct position + $query = "select + element_id, + element_total_child, + element_type + from + `ap_form_elements` + where + form_id='$form_id' and element_type != 'section' + order by + element_position asc"; + $result = do_query($query); + + while($row = do_fetch_result($result)){ + $element_id = $row['element_id']; + $total_child = $row['element_total_child']; + $element_type = $row['element_type']; + + if($total_child > 0){ + if($element_type != 'checkbox'){ + $max = $total_child + 1; + for($i=0;$i<=$max;$i++){ + if($i == 0){ + if(in_array('element_'.$element_id,$columns)){ + $temp_columns[] = 'element_'.$element_id; + } + }else{ + + if(in_array('element_'.$element_id.'_'.$i,$columns)){ + $temp_columns[] = 'element_'.$element_id.'_'.$i; + } + } + } + }elseif ($element_type == 'checkbox'){ + $checkbox_child_query = "select + `option_id` + from + `ap_element_options` + where + form_id='{$form_id}' and element_id='{$element_id}' and live=1 + order by + position asc"; + $checkbox_child_result = do_query($checkbox_child_query); + while($check_child_row = do_fetch_result($checkbox_child_result)){ + $option_id = $check_child_row['option_id']; + if(in_array('element_'.$element_id.'_'.$option_id,$columns)){ + $temp_columns[] = 'element_'.$element_id.'_'.$option_id; + } + } + + } + }else{ + + if($element_type != 'checkbox'){ + $temp_columns[] = 'element_'.$element_id; + }else{ + $temp_columns[] = 'element_'.$element_id.'_1'; + } + } + } + + + + + $columns = array(); + $columns = $temp_columns; + + + /******************************************************************************************/ + //get form entries + $query = "select * from `ap_form_{$form_id}` order by id asc"; + $result = do_query($query); + + $i=0; + $i_file=0; + $c=0; + $row_num = 1; + $column_label = array(); + $column_label_has_printed = false; + + while($row = do_fetch_result($result)){ + + for($j=0;$j<$fields_num;$j++){ + + $column_name = $columns[$j]; + + if(count($column_label) < $fields_num){ + $column_label[$c] = $column_name_lookup[$column_name]; + $c++; + } + + //initialize with empty value, so it won't break our grid + $form_data[$i][$j] = ''; + + if($column_type_lookup[$column_name] == 'time'){ + $form_data[$i][$j] = date("h:i:s A",strtotime($row[$column_name])); + }elseif($column_type_lookup[$column_name] == 'time_noseconds'){ + if(!empty($row[$column_name])){ + $form_data[$i][$j] = date("h:i A",strtotime($row[$column_name])); + } + }elseif(in_array($column_type_lookup[$column_name],array('dollar','euro','pound','yen'))){ //set column formatting for money fields + $form_data[$i][$j] = $row[$column_name]; + }elseif($column_type_lookup[$column_name] == 'date'){ //date with format MM/DD/YYYY + if(!empty($row[$column_name]) && ($row[$column_name] != '0000-00-00')){ + $form_data[$i][$j] = date("Y/m/d",strtotime($row[$column_name])); + } + }elseif($column_type_lookup[$column_name] == 'europe_date'){ //date with format MM/DD/YYYY + if(!empty($row[$column_name]) && ($row[$column_name] != '0000-00-00')){ + $form_data[$i][$j] = date("Y/m/d",strtotime($row[$column_name])); + } + }elseif($column_type_lookup[$column_name] == 'number'){ + $form_data[$i][$j] = $row[$column_name]; + }elseif (in_array($column_type_lookup[$column_name],array('radio','select'))){ //multiple choice or dropdown + $exploded = array(); + $exploded = explode('_',$column_name); + $this_element_id = $exploded[1]; + $this_option_id = $row[$column_name]; + + $form_data[$i][$j] = $element_option_lookup[$this_element_id][$this_option_id]; + }elseif($column_type_lookup[$column_name] == 'checkbox'){ + if(!empty($row[$column_name])){ + $form_data[$i][$j] = $column_label[$j]; + } + }elseif(in_array($column_type_lookup[$column_name],array('phone','simple_phone'))){ + $form_data[$i][$j] = $row[$column_name]; + }elseif($column_type_lookup[$column_name] == 'file'){ + if(!empty($row[$column_name])){ + $filename_only = $row[$column_name]; + + //remove the element_x-xx- suffix we added to all uploaded files + $file_1 = substr($filename_only,strpos($filename_only,'-')+1); + $filename_only = substr($file_1,strpos($file_1,'-')+1); + + $form_data[$i][$j] = $filename_only; + + $q_string = base64_encode("form_id={$form_id}&id={$row['id']}&el={$column_name}"); + $file_url[$i_file][$j] = "http://".$_SERVER['HTTP_HOST'].rtrim(dirname($_SERVER['PHP_SELF']), '/\\')."/download.php?q={$q_string}"; + } + + }else{ + $form_data[$i][$j] = $row[$column_name]; + } + + if($j == 0){ + $form_data[$i][$j] = $row_num; + } + + + } + $i_file++; + //print_r($file_url); + + if($type == 'xls'){ + //print column header + if(!$column_label_has_printed){ + $i=0; + foreach ($column_label as $label){ + $worksheet->write(0, $i, $label,$format_bold); + $i++; + } + $column_label_has_printed = true; + } + + //print column data + + foreach ($form_data as $row_data){ + $col_num = 0; + foreach ($row_data as $data){ + //echo "rownum -1: ".($row_num - 1)."\n"; + //echo "colnum: ".$col_num."\n"; + if(empty($file_url[$row_num-1][$col_num])){ + $data = str_replace("\r","",$data); + if($col_num > 4){ + $worksheet->write($row_num, $col_num, $data,$format_wrap); + }else{ + $worksheet->write($row_num, $col_num, $data); + } + }else{ + $worksheet->writeUrl($row_num,$col_num,$file_url[$row_num-1][$col_num],$data); + } + $col_num++; + } + + } + }elseif ($type == 'csv'){ + if(!$column_label_has_printed){ + fputcsv($out, $column_label); + $column_label_has_printed = true; + } + + foreach ($form_data as $row_data){ + fputcsv($out, $row_data); + } + } + + $row_num++; + unset($form_data); + unset($file_url); + } + + + /******************************************************************************************/ + + //start exporting data + if($type == 'xls'){ + // Let's send the file + $workbook->close(); + + }elseif ($type == 'csv'){ + fclose($out); + } + +?> \ No newline at end of file diff --git a/hooks/custom_hooks.php b/hooks/custom_hooks.php new file mode 100644 index 0000000..da30ef7 --- /dev/null +++ b/hooks/custom_hooks.php @@ -0,0 +1,26 @@ + +var RecaptchaOptions = { + theme : 'blackglass' +}; + +EOT; + return $capthca_theme; + } + +**/ +?> \ No newline at end of file diff --git a/images/ap_bg.gif b/images/ap_bg.gif new file mode 100644 index 0000000..e19cdd5 Binary files /dev/null and b/images/ap_bg.gif differ diff --git a/images/appnitro_logo.png b/images/appnitro_logo.png new file mode 100644 index 0000000..9d52aed Binary files /dev/null and b/images/appnitro_logo.png differ diff --git a/images/bottom.png b/images/bottom.png new file mode 100644 index 0000000..7f46c80 Binary files /dev/null and b/images/bottom.png differ diff --git a/images/button_icon/address_bg.gif b/images/button_icon/address_bg.gif new file mode 100644 index 0000000..f6359e0 Binary files /dev/null and b/images/button_icon/address_bg.gif differ diff --git a/images/button_icon/checkbox_bg.gif b/images/button_icon/checkbox_bg.gif new file mode 100644 index 0000000..68ec009 Binary files /dev/null and b/images/button_icon/checkbox_bg.gif differ diff --git a/images/button_icon/date_bg.gif b/images/button_icon/date_bg.gif new file mode 100644 index 0000000..e9624aa Binary files /dev/null and b/images/button_icon/date_bg.gif differ diff --git a/images/button_icon/dropdown_bg.gif b/images/button_icon/dropdown_bg.gif new file mode 100644 index 0000000..e6c5dff Binary files /dev/null and b/images/button_icon/dropdown_bg.gif differ diff --git a/images/button_icon/file_upload_bg.gif b/images/button_icon/file_upload_bg.gif new file mode 100644 index 0000000..358834b Binary files /dev/null and b/images/button_icon/file_upload_bg.gif differ diff --git a/images/button_icon/mail_bg.gif b/images/button_icon/mail_bg.gif new file mode 100644 index 0000000..d800a3a Binary files /dev/null and b/images/button_icon/mail_bg.gif differ diff --git a/images/button_icon/multiplechoice_bg.gif b/images/button_icon/multiplechoice_bg.gif new file mode 100644 index 0000000..d9c5108 Binary files /dev/null and b/images/button_icon/multiplechoice_bg.gif differ diff --git a/images/button_icon/name_bg.gif b/images/button_icon/name_bg.gif new file mode 100644 index 0000000..c0c1efc Binary files /dev/null and b/images/button_icon/name_bg.gif differ diff --git a/images/button_icon/number_bg.gif b/images/button_icon/number_bg.gif new file mode 100644 index 0000000..7c349ba Binary files /dev/null and b/images/button_icon/number_bg.gif differ diff --git a/images/button_icon/paragraph_text_bg.gif b/images/button_icon/paragraph_text_bg.gif new file mode 100644 index 0000000..6286f48 Binary files /dev/null and b/images/button_icon/paragraph_text_bg.gif differ diff --git a/images/button_icon/phone_bg.gif b/images/button_icon/phone_bg.gif new file mode 100644 index 0000000..54d1dd2 Binary files /dev/null and b/images/button_icon/phone_bg.gif differ diff --git a/images/button_icon/price_bg.gif b/images/button_icon/price_bg.gif new file mode 100644 index 0000000..d5abb71 Binary files /dev/null and b/images/button_icon/price_bg.gif differ diff --git a/images/button_icon/section_break_bg.gif b/images/button_icon/section_break_bg.gif new file mode 100644 index 0000000..6806476 Binary files /dev/null and b/images/button_icon/section_break_bg.gif differ diff --git a/images/button_icon/single_line_text_bg.gif b/images/button_icon/single_line_text_bg.gif new file mode 100644 index 0000000..879391f Binary files /dev/null and b/images/button_icon/single_line_text_bg.gif differ diff --git a/images/button_icon/time_bg.gif b/images/button_icon/time_bg.gif new file mode 100644 index 0000000..4dcdb76 Binary files /dev/null and b/images/button_icon/time_bg.gif differ diff --git a/images/button_icon/website_bg.gif b/images/button_icon/website_bg.gif new file mode 100644 index 0000000..c6601da Binary files /dev/null and b/images/button_icon/website_bg.gif differ diff --git a/images/button_text/address.gif b/images/button_text/address.gif new file mode 100644 index 0000000..155eb66 Binary files /dev/null and b/images/button_text/address.gif differ diff --git a/images/button_text/checkboxes.gif b/images/button_text/checkboxes.gif new file mode 100644 index 0000000..5ce4882 Binary files /dev/null and b/images/button_text/checkboxes.gif differ diff --git a/images/button_text/date.gif b/images/button_text/date.gif new file mode 100644 index 0000000..f868c19 Binary files /dev/null and b/images/button_text/date.gif differ diff --git a/images/button_text/drop_down.gif b/images/button_text/drop_down.gif new file mode 100644 index 0000000..d5e2293 Binary files /dev/null and b/images/button_text/drop_down.gif differ diff --git a/images/button_text/email.gif b/images/button_text/email.gif new file mode 100644 index 0000000..713310f Binary files /dev/null and b/images/button_text/email.gif differ diff --git a/images/button_text/file_upload.gif b/images/button_text/file_upload.gif new file mode 100644 index 0000000..241cfb9 Binary files /dev/null and b/images/button_text/file_upload.gif differ diff --git a/images/button_text/multiple_choice.gif b/images/button_text/multiple_choice.gif new file mode 100644 index 0000000..3f3cf25 Binary files /dev/null and b/images/button_text/multiple_choice.gif differ diff --git a/images/button_text/name.gif b/images/button_text/name.gif new file mode 100644 index 0000000..41546ad Binary files /dev/null and b/images/button_text/name.gif differ diff --git a/images/button_text/number.gif b/images/button_text/number.gif new file mode 100644 index 0000000..1d777dd Binary files /dev/null and b/images/button_text/number.gif differ diff --git a/images/button_text/paragraph_text.gif b/images/button_text/paragraph_text.gif new file mode 100644 index 0000000..8bec1ea Binary files /dev/null and b/images/button_text/paragraph_text.gif differ diff --git a/images/button_text/phone.gif b/images/button_text/phone.gif new file mode 100644 index 0000000..aadd42e Binary files /dev/null and b/images/button_text/phone.gif differ diff --git a/images/button_text/price.gif b/images/button_text/price.gif new file mode 100644 index 0000000..402412d Binary files /dev/null and b/images/button_text/price.gif differ diff --git a/images/button_text/section_break.gif b/images/button_text/section_break.gif new file mode 100644 index 0000000..6d34812 Binary files /dev/null and b/images/button_text/section_break.gif differ diff --git a/images/button_text/single_line_text.gif b/images/button_text/single_line_text.gif new file mode 100644 index 0000000..857fdfa Binary files /dev/null and b/images/button_text/single_line_text.gif differ diff --git a/images/button_text/time.gif b/images/button_text/time.gif new file mode 100644 index 0000000..1beba7c Binary files /dev/null and b/images/button_text/time.gif differ diff --git a/images/button_text/web_site.gif b/images/button_text/web_site.gif new file mode 100644 index 0000000..f7a4c9e Binary files /dev/null and b/images/button_text/web_site.gif differ diff --git a/images/calendar.gif b/images/calendar.gif new file mode 100644 index 0000000..59c7f08 Binary files /dev/null and b/images/calendar.gif differ diff --git a/images/click_to_add.gif b/images/click_to_add.gif new file mode 100644 index 0000000..8c2224f Binary files /dev/null and b/images/click_to_add.gif differ diff --git a/images/create_new_form.gif b/images/create_new_form.gif new file mode 100644 index 0000000..e23f011 Binary files /dev/null and b/images/create_new_form.gif differ diff --git a/images/embed_code_tabs.gif b/images/embed_code_tabs.gif new file mode 100644 index 0000000..cfc22bc Binary files /dev/null and b/images/embed_code_tabs.gif differ diff --git a/images/exec.png b/images/exec.png new file mode 100644 index 0000000..67174cb Binary files /dev/null and b/images/exec.png differ diff --git a/images/icons/add.gif b/images/icons/add.gif new file mode 100644 index 0000000..20488ef Binary files /dev/null and b/images/icons/add.gif differ diff --git a/images/icons/agt_family_48.gif b/images/icons/agt_family_48.gif new file mode 100644 index 0000000..316f745 Binary files /dev/null and b/images/icons/agt_family_48.gif differ diff --git a/images/icons/agt_utilities.gif b/images/icons/agt_utilities.gif new file mode 100644 index 0000000..76128e2 Binary files /dev/null and b/images/icons/agt_utilities.gif differ diff --git a/images/icons/agt_utilities.png b/images/icons/agt_utilities.png new file mode 100644 index 0000000..e312063 Binary files /dev/null and b/images/icons/agt_utilities.png differ diff --git a/images/icons/application_edit.gif b/images/icons/application_edit.gif new file mode 100644 index 0000000..b3980be Binary files /dev/null and b/images/icons/application_edit.gif differ diff --git a/images/icons/arrow.gif b/images/icons/arrow.gif new file mode 100644 index 0000000..286d22e Binary files /dev/null and b/images/icons/arrow.gif differ diff --git a/images/icons/arrow_left.gif b/images/icons/arrow_left.gif new file mode 100644 index 0000000..9aa3374 Binary files /dev/null and b/images/icons/arrow_left.gif differ diff --git a/images/icons/arrow_right.gif b/images/icons/arrow_right.gif new file mode 100644 index 0000000..67e8268 Binary files /dev/null and b/images/icons/arrow_right.gif differ diff --git a/images/icons/arrow_turn_left.gif b/images/icons/arrow_turn_left.gif new file mode 100644 index 0000000..c774338 Binary files /dev/null and b/images/icons/arrow_turn_left.gif differ diff --git a/images/icons/asterisk_orange.gif b/images/icons/asterisk_orange.gif new file mode 100644 index 0000000..8fe5dd5 Binary files /dev/null and b/images/icons/asterisk_orange.gif differ diff --git a/images/icons/attach.gif b/images/icons/attach.gif new file mode 100644 index 0000000..505c3f8 Binary files /dev/null and b/images/icons/attach.gif differ diff --git a/images/icons/calendar.gif b/images/icons/calendar.gif new file mode 100644 index 0000000..59c7f08 Binary files /dev/null and b/images/icons/calendar.gif differ diff --git a/images/icons/checkbox.gif b/images/icons/checkbox.gif new file mode 100644 index 0000000..7a47cad Binary files /dev/null and b/images/icons/checkbox.gif differ diff --git a/images/icons/checkbox_16.gif b/images/icons/checkbox_16.gif new file mode 100644 index 0000000..3ed6a06 Binary files /dev/null and b/images/icons/checkbox_16.gif differ diff --git a/images/icons/cog.gif b/images/icons/cog.gif new file mode 100644 index 0000000..730273e Binary files /dev/null and b/images/icons/cog.gif differ diff --git a/images/icons/colorize_32.gif b/images/icons/colorize_32.gif new file mode 100644 index 0000000..b30b20b Binary files /dev/null and b/images/icons/colorize_32.gif differ diff --git a/images/icons/copy_32.gif b/images/icons/copy_32.gif new file mode 100644 index 0000000..4b8f28a Binary files /dev/null and b/images/icons/copy_32.gif differ diff --git a/images/icons/cross.gif b/images/icons/cross.gif new file mode 100644 index 0000000..3e5aebb Binary files /dev/null and b/images/icons/cross.gif differ diff --git a/images/icons/cross_16.gif b/images/icons/cross_16.gif new file mode 100644 index 0000000..40d748f Binary files /dev/null and b/images/icons/cross_16.gif differ diff --git a/images/icons/cross_22.gif b/images/icons/cross_22.gif new file mode 100644 index 0000000..d609375 Binary files /dev/null and b/images/icons/cross_22.gif differ diff --git a/images/icons/date.gif b/images/icons/date.gif new file mode 100644 index 0000000..d5e1293 Binary files /dev/null and b/images/icons/date.gif differ diff --git a/images/icons/decrypted.gif b/images/icons/decrypted.gif new file mode 100644 index 0000000..98a11d1 Binary files /dev/null and b/images/icons/decrypted.gif differ diff --git a/images/icons/delete.gif b/images/icons/delete.gif new file mode 100644 index 0000000..838f2c8 Binary files /dev/null and b/images/icons/delete.gif differ diff --git a/images/icons/disabled.gif b/images/icons/disabled.gif new file mode 100644 index 0000000..0a49f2c Binary files /dev/null and b/images/icons/disabled.gif differ diff --git a/images/icons/duplicate.gif b/images/icons/duplicate.gif new file mode 100644 index 0000000..e4cab36 Binary files /dev/null and b/images/icons/duplicate.gif differ diff --git a/images/icons/edit_form_32.gif b/images/icons/edit_form_32.gif new file mode 100644 index 0000000..4a771fc Binary files /dev/null and b/images/icons/edit_form_32.gif differ diff --git a/images/icons/edit_user.gif b/images/icons/edit_user.gif new file mode 100644 index 0000000..78d46c2 Binary files /dev/null and b/images/icons/edit_user.gif differ diff --git a/images/icons/edit_user_48.gif b/images/icons/edit_user_48.gif new file mode 100644 index 0000000..8579570 Binary files /dev/null and b/images/icons/edit_user_48.gif differ diff --git a/images/icons/embed_code_32.gif b/images/icons/embed_code_32.gif new file mode 100644 index 0000000..b849977 Binary files /dev/null and b/images/icons/embed_code_32.gif differ diff --git a/images/icons/entries_32.gif b/images/icons/entries_32.gif new file mode 100644 index 0000000..8d397ea Binary files /dev/null and b/images/icons/entries_32.gif differ diff --git a/images/icons/fileprint.gif b/images/icons/fileprint.gif new file mode 100644 index 0000000..88b0332 Binary files /dev/null and b/images/icons/fileprint.gif differ diff --git a/images/icons/filesave.gif b/images/icons/filesave.gif new file mode 100644 index 0000000..ba99ed1 Binary files /dev/null and b/images/icons/filesave.gif differ diff --git a/images/icons/flag_green.gif b/images/icons/flag_green.gif new file mode 100644 index 0000000..c39406e Binary files /dev/null and b/images/icons/flag_green.gif differ diff --git a/images/icons/flag_red.gif b/images/icons/flag_red.gif new file mode 100644 index 0000000..161d221 Binary files /dev/null and b/images/icons/flag_red.gif differ diff --git a/images/icons/flag_red.png b/images/icons/flag_red.png new file mode 100644 index 0000000..e8a602d Binary files /dev/null and b/images/icons/flag_red.png differ diff --git a/images/icons/form_add.gif b/images/icons/form_add.gif new file mode 100644 index 0000000..d102118 Binary files /dev/null and b/images/icons/form_add.gif differ diff --git a/images/icons/information.gif b/images/icons/information.gif new file mode 100644 index 0000000..05f30fc Binary files /dev/null and b/images/icons/information.gif differ diff --git a/images/icons/kate.gif b/images/icons/kate.gif new file mode 100644 index 0000000..67f99af Binary files /dev/null and b/images/icons/kate.gif differ diff --git a/images/icons/key.gif b/images/icons/key.gif new file mode 100644 index 0000000..db2f8d9 Binary files /dev/null and b/images/icons/key.gif differ diff --git a/images/icons/lock.gif b/images/icons/lock.gif new file mode 100644 index 0000000..e870736 Binary files /dev/null and b/images/icons/lock.gif differ diff --git a/images/icons/locksmall.gif b/images/icons/locksmall.gif new file mode 100644 index 0000000..0432dd7 Binary files /dev/null and b/images/icons/locksmall.gif differ diff --git a/images/icons/magnifier.gif b/images/icons/magnifier.gif new file mode 100644 index 0000000..ce4168c Binary files /dev/null and b/images/icons/magnifier.gif differ diff --git a/images/icons/mail_forward_16.gif b/images/icons/mail_forward_16.gif new file mode 100644 index 0000000..a822ebb Binary files /dev/null and b/images/icons/mail_forward_16.gif differ diff --git a/images/icons/mail_forward_16.png b/images/icons/mail_forward_16.png new file mode 100644 index 0000000..150b624 Binary files /dev/null and b/images/icons/mail_forward_16.png differ diff --git a/images/icons/mail_forward_32.gif b/images/icons/mail_forward_32.gif new file mode 100644 index 0000000..1473349 Binary files /dev/null and b/images/icons/mail_forward_32.gif differ diff --git a/images/icons/mail_generic2.gif b/images/icons/mail_generic2.gif new file mode 100644 index 0000000..b1147b7 Binary files /dev/null and b/images/icons/mail_generic2.gif differ diff --git a/images/icons/mail_reply_16.gif b/images/icons/mail_reply_16.gif new file mode 100644 index 0000000..99da354 Binary files /dev/null and b/images/icons/mail_reply_16.gif differ diff --git a/images/icons/mail_reply_16.png b/images/icons/mail_reply_16.png new file mode 100644 index 0000000..cfb9379 Binary files /dev/null and b/images/icons/mail_reply_16.png differ diff --git a/images/icons/nav_end.gif b/images/icons/nav_end.gif new file mode 100644 index 0000000..875447b Binary files /dev/null and b/images/icons/nav_end.gif differ diff --git a/images/icons/nav_end_grey.gif b/images/icons/nav_end_grey.gif new file mode 100644 index 0000000..b1d7561 Binary files /dev/null and b/images/icons/nav_end_grey.gif differ diff --git a/images/icons/nav_next.gif b/images/icons/nav_next.gif new file mode 100644 index 0000000..cc6862c Binary files /dev/null and b/images/icons/nav_next.gif differ diff --git a/images/icons/nav_next_grey.gif b/images/icons/nav_next_grey.gif new file mode 100644 index 0000000..c44ba0c Binary files /dev/null and b/images/icons/nav_next_grey.gif differ diff --git a/images/icons/nav_prev.gif b/images/icons/nav_prev.gif new file mode 100644 index 0000000..557e6bc Binary files /dev/null and b/images/icons/nav_prev.gif differ diff --git a/images/icons/nav_prev_grey.gif b/images/icons/nav_prev_grey.gif new file mode 100644 index 0000000..f392ca0 Binary files /dev/null and b/images/icons/nav_prev_grey.gif differ diff --git a/images/icons/nav_start.gif b/images/icons/nav_start.gif new file mode 100644 index 0000000..4d64c66 Binary files /dev/null and b/images/icons/nav_start.gif differ diff --git a/images/icons/nav_start_grey.gif b/images/icons/nav_start_grey.gif new file mode 100644 index 0000000..2e50c82 Binary files /dev/null and b/images/icons/nav_start_grey.gif differ diff --git a/images/icons/package_applications.gif b/images/icons/package_applications.gif new file mode 100644 index 0000000..f7578c3 Binary files /dev/null and b/images/icons/package_applications.gif differ diff --git a/images/icons/page_excel.gif b/images/icons/page_excel.gif new file mode 100644 index 0000000..f75e8a1 Binary files /dev/null and b/images/icons/page_excel.gif differ diff --git a/images/icons/page_white_code.gif b/images/icons/page_white_code.gif new file mode 100644 index 0000000..f06a205 Binary files /dev/null and b/images/icons/page_white_code.gif differ diff --git a/images/icons/pencil.gif b/images/icons/pencil.gif new file mode 100644 index 0000000..9bc91a9 Binary files /dev/null and b/images/icons/pencil.gif differ diff --git a/images/icons/resultset_down.gif b/images/icons/resultset_down.gif new file mode 100644 index 0000000..585e23a Binary files /dev/null and b/images/icons/resultset_down.gif differ diff --git a/images/icons/resultset_next.gif b/images/icons/resultset_next.gif new file mode 100644 index 0000000..534f123 Binary files /dev/null and b/images/icons/resultset_next.gif differ diff --git a/images/icons/resultset_up.gif b/images/icons/resultset_up.gif new file mode 100644 index 0000000..29ddb97 Binary files /dev/null and b/images/icons/resultset_up.gif differ diff --git a/images/icons/search.gif b/images/icons/search.gif new file mode 100644 index 0000000..5e4ed4a Binary files /dev/null and b/images/icons/search.gif differ diff --git a/images/icons/show_table_column.gif b/images/icons/show_table_column.gif new file mode 100644 index 0000000..3c6759c Binary files /dev/null and b/images/icons/show_table_column.gif differ diff --git a/images/icons/star.gif b/images/icons/star.gif new file mode 100644 index 0000000..ff359de Binary files /dev/null and b/images/icons/star.gif differ diff --git a/images/icons/stardim.gif b/images/icons/stardim.gif new file mode 100644 index 0000000..8f81dec Binary files /dev/null and b/images/icons/stardim.gif differ diff --git a/images/icons/start.png b/images/icons/start.png new file mode 100644 index 0000000..2a575fd Binary files /dev/null and b/images/icons/start.png differ diff --git a/images/icons/stop.gif b/images/icons/stop.gif new file mode 100644 index 0000000..143d1f7 Binary files /dev/null and b/images/icons/stop.gif differ diff --git a/images/icons/textfield_add.gif b/images/icons/textfield_add.gif new file mode 100644 index 0000000..a0544c3 Binary files /dev/null and b/images/icons/textfield_add.gif differ diff --git a/images/icons/view_form_32.gif b/images/icons/view_form_32.gif new file mode 100644 index 0000000..6891157 Binary files /dev/null and b/images/icons/view_form_32.gif differ diff --git a/images/icons/warning.gif b/images/icons/warning.gif new file mode 100644 index 0000000..a8b1c6e Binary files /dev/null and b/images/icons/warning.gif differ diff --git a/images/input_bg.gif b/images/input_bg.gif new file mode 100644 index 0000000..f477e2d Binary files /dev/null and b/images/input_bg.gif differ diff --git a/images/loader-red.gif b/images/loader-red.gif new file mode 100644 index 0000000..5b44ef7 Binary files /dev/null and b/images/loader-red.gif differ diff --git a/images/logout.gif b/images/logout.gif new file mode 100644 index 0000000..c13b73d Binary files /dev/null and b/images/logout.gif differ diff --git a/images/machform.gif b/images/machform.gif new file mode 100644 index 0000000..34641ab Binary files /dev/null and b/images/machform.gif differ diff --git a/images/manage_forms.gif b/images/manage_forms.gif new file mode 100644 index 0000000..c94dd27 Binary files /dev/null and b/images/manage_forms.gif differ diff --git a/images/manage_forms_active.gif b/images/manage_forms_active.gif new file mode 100644 index 0000000..0fc77a5 Binary files /dev/null and b/images/manage_forms_active.gif differ diff --git a/images/reports.gif b/images/reports.gif new file mode 100644 index 0000000..4faec83 Binary files /dev/null and b/images/reports.gif differ diff --git a/images/reports_active.gif b/images/reports_active.gif new file mode 100644 index 0000000..c0d56a4 Binary files /dev/null and b/images/reports_active.gif differ diff --git a/images/settings.gif b/images/settings.gif new file mode 100644 index 0000000..3c33675 Binary files /dev/null and b/images/settings.gif differ diff --git a/images/settings_active.gif b/images/settings_active.gif new file mode 100644 index 0000000..e894b2c Binary files /dev/null and b/images/settings_active.gif differ diff --git a/images/shadow.gif b/images/shadow.gif new file mode 100644 index 0000000..026d52a Binary files /dev/null and b/images/shadow.gif differ diff --git a/images/simple_modal/ajax-loader.gif b/images/simple_modal/ajax-loader.gif new file mode 100644 index 0000000..37272a2 Binary files /dev/null and b/images/simple_modal/ajax-loader.gif differ diff --git a/images/simple_modal/cancel.png b/images/simple_modal/cancel.png new file mode 100644 index 0000000..41dea1e Binary files /dev/null and b/images/simple_modal/cancel.png differ diff --git a/images/simple_modal/form_bottom.gif b/images/simple_modal/form_bottom.gif new file mode 100644 index 0000000..beae743 Binary files /dev/null and b/images/simple_modal/form_bottom.gif differ diff --git a/images/simple_modal/form_top.gif b/images/simple_modal/form_top.gif new file mode 100644 index 0000000..605e277 Binary files /dev/null and b/images/simple_modal/form_top.gif differ diff --git a/images/simple_modal/form_top_ie.gif b/images/simple_modal/form_top_ie.gif new file mode 100644 index 0000000..f2a1cb1 Binary files /dev/null and b/images/simple_modal/form_top_ie.gif differ diff --git a/images/simple_modal/send.png b/images/simple_modal/send.png new file mode 100644 index 0000000..3f1b0ed Binary files /dev/null and b/images/simple_modal/send.png differ diff --git a/images/top.png b/images/top.png new file mode 100644 index 0000000..48749b7 Binary files /dev/null and b/images/top.png differ diff --git a/includes/JSON.php b/includes/JSON.php new file mode 100644 index 0000000..0cddbdd --- /dev/null +++ b/includes/JSON.php @@ -0,0 +1,806 @@ + + * @author Matt Knapp + * @author Brett Stimmerman + * @copyright 2005 Michal Migurski + * @version CVS: $Id: JSON.php,v 1.31 2006/06/28 05:54:17 migurski Exp $ + * @license http://www.opensource.org/licenses/bsd-license.php + * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198 + */ + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_SLICE', 1); + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_IN_STR', 2); + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_IN_ARR', 3); + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_IN_OBJ', 4); + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_IN_CMT', 5); + +/** + * Behavior switch for Services_JSON::decode() + */ +define('SERVICES_JSON_LOOSE_TYPE', 16); + +/** + * Behavior switch for Services_JSON::decode() + */ +define('SERVICES_JSON_SUPPRESS_ERRORS', 32); + +/** + * Converts to and from JSON format. + * + * Brief example of use: + * + * + * // create a new instance of Services_JSON + * $json = new Services_JSON(); + * + * // convert a complexe value to JSON notation, and send it to the browser + * $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4))); + * $output = $json->encode($value); + * + * print($output); + * // prints: ["foo","bar",[1,2,"baz"],[3,[4]]] + * + * // accept incoming POST data, assumed to be in JSON notation + * $input = file_get_contents('php://input', 1000000); + * $value = $json->decode($input); + * + */ +class Services_JSON +{ + /** + * constructs a new JSON instance + * + * @param int $use object behavior flags; combine with boolean-OR + * + * possible values: + * - SERVICES_JSON_LOOSE_TYPE: loose typing. + * "{...}" syntax creates associative arrays + * instead of objects in decode(). + * - SERVICES_JSON_SUPPRESS_ERRORS: error suppression. + * Values which can't be encoded (e.g. resources) + * appear as NULL instead of throwing errors. + * By default, a deeply-nested resource will + * bubble up with an error, so all return values + * from encode() should be checked with isError() + */ + function Services_JSON($use = 0) + { + $this->use = $use; + } + + /** + * convert a string from one UTF-16 char to one UTF-8 char + * + * Normally should be handled by mb_convert_encoding, but + * provides a slower PHP-only method for installations + * that lack the multibye string extension. + * + * @param string $utf16 UTF-16 character + * @return string UTF-8 character + * @access private + */ + function utf162utf8($utf16) + { + // oh please oh please oh please oh please oh please + if(function_exists('mb_convert_encoding')) { + return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16'); + } + + $bytes = (ord($utf16{0}) << 8) | ord($utf16{1}); + + switch(true) { + case ((0x7F & $bytes) == $bytes): + // this case should never be reached, because we are in ASCII range + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr(0x7F & $bytes); + + case (0x07FF & $bytes) == $bytes: + // return a 2-byte UTF-8 character + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr(0xC0 | (($bytes >> 6) & 0x1F)) + . chr(0x80 | ($bytes & 0x3F)); + + case (0xFFFF & $bytes) == $bytes: + // return a 3-byte UTF-8 character + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr(0xE0 | (($bytes >> 12) & 0x0F)) + . chr(0x80 | (($bytes >> 6) & 0x3F)) + . chr(0x80 | ($bytes & 0x3F)); + } + + // ignoring UTF-32 for now, sorry + return ''; + } + + /** + * convert a string from one UTF-8 char to one UTF-16 char + * + * Normally should be handled by mb_convert_encoding, but + * provides a slower PHP-only method for installations + * that lack the multibye string extension. + * + * @param string $utf8 UTF-8 character + * @return string UTF-16 character + * @access private + */ + function utf82utf16($utf8) + { + // oh please oh please oh please oh please oh please + if(function_exists('mb_convert_encoding')) { + return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8'); + } + + switch(strlen($utf8)) { + case 1: + // this case should never be reached, because we are in ASCII range + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return $utf8; + + case 2: + // return a UTF-16 character from a 2-byte UTF-8 char + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr(0x07 & (ord($utf8{0}) >> 2)) + . chr((0xC0 & (ord($utf8{0}) << 6)) + | (0x3F & ord($utf8{1}))); + + case 3: + // return a UTF-16 character from a 3-byte UTF-8 char + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr((0xF0 & (ord($utf8{0}) << 4)) + | (0x0F & (ord($utf8{1}) >> 2))) + . chr((0xC0 & (ord($utf8{1}) << 6)) + | (0x7F & ord($utf8{2}))); + } + + // ignoring UTF-32 for now, sorry + return ''; + } + + /** + * encodes an arbitrary variable into JSON format + * + * @param mixed $var any number, boolean, string, array, or object to be encoded. + * see argument 1 to Services_JSON() above for array-parsing behavior. + * if var is a strng, note that encode() always expects it + * to be in ASCII or UTF-8 format! + * + * @return mixed JSON string representation of input var or an error if a problem occurs + * @access public + */ + function encode($var) + { + switch (gettype($var)) { + case 'boolean': + return $var ? 'true' : 'false'; + + case 'NULL': + return 'null'; + + case 'integer': + return (int) $var; + + case 'double': + case 'float': + return (float) $var; + + case 'string': + // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT + $ascii = ''; + $strlen_var = strlen($var); + + /* + * Iterate over every character in the string, + * escaping with a slash or encoding to UTF-8 where necessary + */ + for ($c = 0; $c < $strlen_var; ++$c) { + + $ord_var_c = ord($var{$c}); + + switch (true) { + case $ord_var_c == 0x08: + $ascii .= '\b'; + break; + case $ord_var_c == 0x09: + $ascii .= '\t'; + break; + case $ord_var_c == 0x0A: + $ascii .= '\n'; + break; + case $ord_var_c == 0x0C: + $ascii .= '\f'; + break; + case $ord_var_c == 0x0D: + $ascii .= '\r'; + break; + + case $ord_var_c == 0x22: + case $ord_var_c == 0x2F: + case $ord_var_c == 0x5C: + // double quote, slash, slosh + $ascii .= '\\'.$var{$c}; + break; + + case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)): + // characters U-00000000 - U-0000007F (same as ASCII) + $ascii .= $var{$c}; + break; + + case (($ord_var_c & 0xE0) == 0xC0): + // characters U-00000080 - U-000007FF, mask 110XXXXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, ord($var{$c + 1})); + $c += 1; + $utf16 = $this->utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xF0) == 0xE0): + // characters U-00000800 - U-0000FFFF, mask 1110XXXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2})); + $c += 2; + $utf16 = $this->utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xF8) == 0xF0): + // characters U-00010000 - U-001FFFFF, mask 11110XXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2}), + ord($var{$c + 3})); + $c += 3; + $utf16 = $this->utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xFC) == 0xF8): + // characters U-00200000 - U-03FFFFFF, mask 111110XX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2}), + ord($var{$c + 3}), + ord($var{$c + 4})); + $c += 4; + $utf16 = $this->utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xFE) == 0xFC): + // characters U-04000000 - U-7FFFFFFF, mask 1111110X + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2}), + ord($var{$c + 3}), + ord($var{$c + 4}), + ord($var{$c + 5})); + $c += 5; + $utf16 = $this->utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + } + } + + return '"'.$ascii.'"'; + + case 'array': + /* + * As per JSON spec if any array key is not an integer + * we must treat the the whole array as an object. We + * also try to catch a sparsely populated associative + * array with numeric keys here because some JS engines + * will create an array with empty indexes up to + * max_index which can cause memory issues and because + * the keys, which may be relevant, will be remapped + * otherwise. + * + * As per the ECMA and JSON specification an object may + * have any string as a property. Unfortunately due to + * a hole in the ECMA specification if the key is a + * ECMA reserved word or starts with a digit the + * parameter is only accessible using ECMAScript's + * bracket notation. + */ + + // treat as a JSON object + if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) { + $properties = array_map(array($this, 'name_value'), + array_keys($var), + array_values($var)); + + foreach($properties as $property) { + if(Services_JSON::isError($property)) { + return $property; + } + } + + return '{' . join(',', $properties) . '}'; + } + + // treat it like a regular array + $elements = array_map(array($this, 'encode'), $var); + + foreach($elements as $element) { + if(Services_JSON::isError($element)) { + return $element; + } + } + + return '[' . join(',', $elements) . ']'; + + case 'object': + $vars = get_object_vars($var); + + $properties = array_map(array($this, 'name_value'), + array_keys($vars), + array_values($vars)); + + foreach($properties as $property) { + if(Services_JSON::isError($property)) { + return $property; + } + } + + return '{' . join(',', $properties) . '}'; + + default: + return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS) + ? 'null' + : new Services_JSON_Error(gettype($var)." can not be encoded as JSON string"); + } + } + + /** + * array-walking function for use in generating JSON-formatted name-value pairs + * + * @param string $name name of key to use + * @param mixed $value reference to an array element to be encoded + * + * @return string JSON-formatted name-value pair, like '"name":value' + * @access private + */ + function name_value($name, $value) + { + $encoded_value = $this->encode($value); + + if(Services_JSON::isError($encoded_value)) { + return $encoded_value; + } + + return $this->encode(strval($name)) . ':' . $encoded_value; + } + + /** + * reduce a string by removing leading and trailing comments and whitespace + * + * @param $str string string value to strip of comments and whitespace + * + * @return string string value stripped of comments and whitespace + * @access private + */ + function reduce_string($str) + { + $str = preg_replace(array( + + // eliminate single line comments in '// ...' form + '#^\s*//(.+)$#m', + + // eliminate multi-line comments in '/* ... */' form, at start of string + '#^\s*/\*(.+)\*/#Us', + + // eliminate multi-line comments in '/* ... */' form, at end of string + '#/\*(.+)\*/\s*$#Us' + + ), '', $str); + + // eliminate extraneous space + return trim($str); + } + + /** + * decodes a JSON string into appropriate variable + * + * @param string $str JSON-formatted string + * + * @return mixed number, boolean, string, array, or object + * corresponding to given JSON input string. + * See argument 1 to Services_JSON() above for object-output behavior. + * Note that decode() always returns strings + * in ASCII or UTF-8 format! + * @access public + */ + function decode($str) + { + $str = $this->reduce_string($str); + + switch (strtolower($str)) { + case 'true': + return true; + + case 'false': + return false; + + case 'null': + return null; + + default: + $m = array(); + + if (is_numeric($str)) { + // Lookie-loo, it's a number + + // This would work on its own, but I'm trying to be + // good about returning integers where appropriate: + // return (float)$str; + + // Return float or int, as appropriate + return ((float)$str == (integer)$str) + ? (integer)$str + : (float)$str; + + } elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) { + // STRINGS RETURNED IN UTF-8 FORMAT + $delim = substr($str, 0, 1); + $chrs = substr($str, 1, -1); + $utf8 = ''; + $strlen_chrs = strlen($chrs); + + for ($c = 0; $c < $strlen_chrs; ++$c) { + + $substr_chrs_c_2 = substr($chrs, $c, 2); + $ord_chrs_c = ord($chrs{$c}); + + switch (true) { + case $substr_chrs_c_2 == '\b': + $utf8 .= chr(0x08); + ++$c; + break; + case $substr_chrs_c_2 == '\t': + $utf8 .= chr(0x09); + ++$c; + break; + case $substr_chrs_c_2 == '\n': + $utf8 .= chr(0x0A); + ++$c; + break; + case $substr_chrs_c_2 == '\f': + $utf8 .= chr(0x0C); + ++$c; + break; + case $substr_chrs_c_2 == '\r': + $utf8 .= chr(0x0D); + ++$c; + break; + + case $substr_chrs_c_2 == '\\"': + case $substr_chrs_c_2 == '\\\'': + case $substr_chrs_c_2 == '\\\\': + case $substr_chrs_c_2 == '\\/': + if (($delim == '"' && $substr_chrs_c_2 != '\\\'') || + ($delim == "'" && $substr_chrs_c_2 != '\\"')) { + $utf8 .= $chrs{++$c}; + } + break; + + case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)): + // single, escaped unicode character + $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2))) + . chr(hexdec(substr($chrs, ($c + 4), 2))); + $utf8 .= $this->utf162utf8($utf16); + $c += 5; + break; + + case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F): + $utf8 .= $chrs{$c}; + break; + + case ($ord_chrs_c & 0xE0) == 0xC0: + // characters U-00000080 - U-000007FF, mask 110XXXXX + //see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $utf8 .= substr($chrs, $c, 2); + ++$c; + break; + + case ($ord_chrs_c & 0xF0) == 0xE0: + // characters U-00000800 - U-0000FFFF, mask 1110XXXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $utf8 .= substr($chrs, $c, 3); + $c += 2; + break; + + case ($ord_chrs_c & 0xF8) == 0xF0: + // characters U-00010000 - U-001FFFFF, mask 11110XXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $utf8 .= substr($chrs, $c, 4); + $c += 3; + break; + + case ($ord_chrs_c & 0xFC) == 0xF8: + // characters U-00200000 - U-03FFFFFF, mask 111110XX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $utf8 .= substr($chrs, $c, 5); + $c += 4; + break; + + case ($ord_chrs_c & 0xFE) == 0xFC: + // characters U-04000000 - U-7FFFFFFF, mask 1111110X + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $utf8 .= substr($chrs, $c, 6); + $c += 5; + break; + + } + + } + + return $utf8; + + } elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) { + // array, or object notation + + if ($str{0} == '[') { + $stk = array(SERVICES_JSON_IN_ARR); + $arr = array(); + } else { + if ($this->use & SERVICES_JSON_LOOSE_TYPE) { + $stk = array(SERVICES_JSON_IN_OBJ); + $obj = array(); + } else { + $stk = array(SERVICES_JSON_IN_OBJ); + $obj = new stdClass(); + } + } + + array_push($stk, array('what' => SERVICES_JSON_SLICE, + 'where' => 0, + 'delim' => false)); + + $chrs = substr($str, 1, -1); + $chrs = $this->reduce_string($chrs); + + if ($chrs == '') { + if (reset($stk) == SERVICES_JSON_IN_ARR) { + return $arr; + + } else { + return $obj; + + } + } + + //print("\nparsing {$chrs}\n"); + + $strlen_chrs = strlen($chrs); + + for ($c = 0; $c <= $strlen_chrs; ++$c) { + + $top = end($stk); + $substr_chrs_c_2 = substr($chrs, $c, 2); + + if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == SERVICES_JSON_SLICE))) { + // found a comma that is not inside a string, array, etc., + // OR we've reached the end of the character list + $slice = substr($chrs, $top['where'], ($c - $top['where'])); + array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false)); + //print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); + + if (reset($stk) == SERVICES_JSON_IN_ARR) { + // we are in an array, so just push an element onto the stack + array_push($arr, $this->decode($slice)); + + } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) { + // we are in an object, so figure + // out the property name and set an + // element in an associative array, + // for now + $parts = array(); + + if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { + // "name":value pair + $key = $this->decode($parts[1]); + $val = $this->decode($parts[2]); + + if ($this->use & SERVICES_JSON_LOOSE_TYPE) { + $obj[$key] = $val; + } else { + $obj->$key = $val; + } + } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { + // name:value pair, where name is unquoted + $key = $parts[1]; + $val = $this->decode($parts[2]); + + if ($this->use & SERVICES_JSON_LOOSE_TYPE) { + $obj[$key] = $val; + } else { + $obj->$key = $val; + } + } + + } + + } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) { + // found a quote, and we are not inside a string + array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c})); + //print("Found start of string at {$c}\n"); + + } elseif (($chrs{$c} == $top['delim']) && + ($top['what'] == SERVICES_JSON_IN_STR) && + ((strlen(substr($chrs, 0, $c)) - strlen(rtrim(substr($chrs, 0, $c), '\\'))) % 2 != 1)) { + // found a quote, we're in a string, and it's not escaped + // we know that it's not escaped becase there is _not_ an + // odd number of backslashes at the end of the string so far + array_pop($stk); + //print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n"); + + } elseif (($chrs{$c} == '[') && + in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { + // found a left-bracket, and we are in an array, object, or slice + array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false)); + //print("Found start of array at {$c}\n"); + + } elseif (($chrs{$c} == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) { + // found a right-bracket, and we're in an array + array_pop($stk); + //print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); + + } elseif (($chrs{$c} == '{') && + in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { + // found a left-brace, and we are in an array, object, or slice + array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false)); + //print("Found start of object at {$c}\n"); + + } elseif (($chrs{$c} == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) { + // found a right-brace, and we're in an object + array_pop($stk); + //print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); + + } elseif (($substr_chrs_c_2 == '/*') && + in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { + // found a comment start, and we are in an array, object, or slice + array_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false)); + $c++; + //print("Found start of comment at {$c}\n"); + + } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) { + // found a comment end, and we're in one now + array_pop($stk); + $c++; + + for ($i = $top['where']; $i <= $c; ++$i) + $chrs = substr_replace($chrs, ' ', $i, 1); + + //print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); + + } + + } + + if (reset($stk) == SERVICES_JSON_IN_ARR) { + return $arr; + + } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) { + return $obj; + + } + + } + } + } + + /** + * @todo Ultimately, this should just call PEAR::isError() + */ + function isError($data, $code = null) + { + if (class_exists('pear')) { + return PEAR::isError($data, $code); + } elseif (is_object($data) && (get_class($data) == 'services_json_error' || + is_subclass_of($data, 'services_json_error'))) { + return true; + } + + return false; + } +} + +if (class_exists('PEAR_Error')) { + + class Services_JSON_Error extends PEAR_Error + { + function Services_JSON_Error($message = 'unknown error', $code = null, + $mode = null, $options = null, $userinfo = null) + { + parent::PEAR_Error($message, $code, $mode, $options, $userinfo); + } + } + +} else { + + /** + * @todo Ultimately, this class shall be descended from PEAR_Error + */ + class Services_JSON_Error + { + function Services_JSON_Error($message = 'unknown error', $code = null, + $mode = null, $options = null, $userinfo = null) + { + + } + } + +} + +?> diff --git a/includes/check-session.php b/includes/check-session.php new file mode 100644 index 0000000..c54afc1 --- /dev/null +++ b/includes/check-session.php @@ -0,0 +1,27 @@ + \ No newline at end of file diff --git a/includes/common-validator.php b/includes/common-validator.php new file mode 100644 index 0000000..0d3af64 --- /dev/null +++ b/includes/common-validator.php @@ -0,0 +1,420 @@ + 3)){ + return true; + }else{ + return $error_message; + } + } + + //validation for minimum value + function validate_min($value){ + $error_message = VAL_MIN; + + if(strlen($value[0]) < $value[1]){ + return sprintf($error_message,$value[1]); + }else{ + return true; + } + } + + //validation for maximum value + function validate_max($value){ + + $error_message = VAL_MAX; + + if(strlen($value[0]) > $value[1]){ + return sprintf($error_message,$value[1]); + }else{ + return true; + } + } + + //validation for range value + function validate_range($value){ + $error_message = VAL_RANGE; + + //$value[0] is the entered value to be compared + //$value[1] contains the value range. eg '2-10' + + $exp_array = explode('-',$value[1]); + $min = $exp_array[0]; + $max = $exp_array[1]; + + + if(!((strlen($value[0]) >= $min) && (strlen($value[0]) <= $max))){ + return sprintf($error_message,'%s',$min,$max); + }else{ + return true; + } + } + + //validation to check email address format + function validate_email($value) { + $error_message = VAL_EMAIL; + + if(!empty($value[0])){ + $regex = '/^[A-z0-9][\w.-]*@[A-z0-9][\w\-\.]*\.[A-z0-9]{2,6}$/'; + $result = preg_match($regex, $value[0]); + + if(empty($result)){ + return sprintf($error_message,'%s',$value[0]); + }else{ + return true; + } + }else{ + return true; + } + } + + //validation to check URL format + function validate_website($value) { + $error_message = VAL_WEBSITE; + $value[0] = $value[0].'/'; + + if(!empty($value[0]) && ($value[0] != '/')){ + $regex = '/^https?:\/\/([a-z0-9]([-a-z0-9]*[a-z0-9])?\.)+((a[cdefgilmnoqrstuwxz]|aero|arpa)|(b[abdefghijmnorstvwyz]|biz)|(c[acdfghiklmnorsuvxyz]|cat|com|coop)|d[ejkmoz]|(e[ceghrstu]|edu)|f[ijkmor]|(g[abdefghilmnpqrstuwy]|gov)|h[kmnrtu]|(i[delmnoqrst]|info|int)|(j[emop]|jobs)|k[eghimnprwyz]|l[abcikrstuvy]|(m[acdghklmnopqrstuvwxyz]|mil|mobi|museum)|(n[acefgilopruz]|name|net)|(om|org)|(p[aefghklmnrstwy]|pro)|qa|r[eouw]|s[abcdeghijklmnortvyz]|(t[cdfghjklmnoprtvwz]|travel)|u[agkmsyz]|v[aceginu]|w[fs]|y[etu]|z[amw])(\/)(.*)$/i'; + $result = preg_match($regex, $value[0]); + + if(empty($result)){ + return sprintf($error_message,'%s',$value[0]); + }else{ + return true; + } + }else{ + return true; + } + } + + //validation to allow only a-z 0-9 and underscores + function validate_username($value){ + + $error_message = VAL_USERNAME; + + if(!preg_match("/^[a-z0-9][\w]*$/i",$value[0])){ + return sprintf($error_message,'%s',$value[0]); + }else{ + return true; + } + } + + + + //validation to check two variable equality. usefull for checking password + function validate_equal($value){ + $error_message = VAL_EQUAL; + + if($value[0] != $value[2][$value[1]]){ + return $error_message; + }else{ + return true; + } + } + + //validate date format + //currently only support this format: mm/dd/yyyy or mm-dd-yyyy, yyyy/mm/dd or yyyy-mm-dd + function validate_date($value) { + $error_message = VAL_DATE; + + if(!empty($value[0])){ + if($value[1] == 'yyyy/mm/dd'){ + $regex = "/^([1-9][0-9])\d\d[-\/](0?[1-9]|1[012])[-\/](0?[1-9]|[12][0-9]|3[01])$/"; + }elseif($value[1] == 'mm/dd/yyyy'){ + $regex = "/^(0[1-9]|1[012])[-\/](0[1-9]|[12][0-9]|3[01])[-\/](19|20)\d\d$/"; + } + + $result = preg_match($regex, $value[0]); + } + + + if(empty($result)){ + return sprintf($error_message,'%s',$value[1]); + }else{ + return true; + } + } + + //validation to check valid time format + function validate_time($value){ + + $error_message = VAL_TIME; + + $timestamp = strtotime($value[0]); + + if($timestamp == -1 || $timestamp === false){ + return $error_message; + }else{ + return true; + } + } + + + //validation for required file + function validate_required_file($value){ + $error_message = VAL_REQUIRED_FILE; + $element_file = $value[0]; + + if($_FILES[$element_file]['size'] > 0){ + return true; + }else{ + return $error_message; + } + } + + //validation for file upload filetype + function validate_filetype($value){ + + $error_message = VAL_FILETYPE; + $value = $value[0]; + + $ext = pathinfo(strtolower($_FILES[$value]['name']), PATHINFO_EXTENSION); + + if(defined('UPLOAD_FILETYPE_ALLOW') && (UPLOAD_FILETYPE_ALLOW != '')){ + //only allow these filetypes + $allowed_filetypes = explode(';',strtolower(UPLOAD_FILETYPE_ALLOW)); + if(!in_array($ext,$allowed_filetypes)){ + return $error_message; + } + + }elseif(defined('UPLOAD_FILETYPE_DENY') && (UPLOAD_FILETYPE_DENY != '')){ + //disallow these filetypes + $blacklisted_filetypes = explode(';',strtolower(UPLOAD_FILETYPE_DENY)); + if(in_array($ext,$blacklisted_filetypes)){ + return $error_message; + } + } + + return true; + } + + /********************************************************* + * This is main validation function + * This function will call sub function, called validate_xx + * Each sub function is specific for one rule + * + * Syntax: $rules[field_name][validation_type] = value + * validation_type: required,integer,float,min,max,range,email,username,equal,date + * Example rules: + * + * $rules['author_id']['required'] = true; //author_id is required + * $rules['author_id']['integer'] = true; //author_id must be an integer + * $rules['author_id']['range'] = '2-10'; //author_id length must be between 2 - 10 characters + * + **********************************************************/ + function validate_rules($input,$rules){ + + //traverse for each input, check for rules to be applied + foreach ($input as $key=>$value){ + $current_rules = @$rules[$key]; + $error_message = array(); + + if(!empty($current_rules)){ + //an input can be validated by many rules, check that here + foreach ($current_rules as $key2=>$value2){ + $argument_array = array($value,$value2,$input); + $result = call_user_func('validate_'.$key2,$argument_array); + + if($result !== true){ //if we got error message, break the loop + $error_message = $result; + break; + } + } + } + if(count($error_message) > 0){ + $total_error_message[$key] = $error_message; + } + } + + if(@is_array($total_error_message)){ + return $total_error_message; + }else{ + return true; + } + } + + //similar as function above, but this is specific for validating form inputs, with only one error message per input + function validate_element($input,$rules){ + + //traverse for each input, check for rules to be applied + foreach ($input as $key=>$value){ + $current_rules = @$rules[$key]; + $error_message = array(); + + if(!empty($current_rules)){ + //an input can be validated by many rules, check that here + foreach ($current_rules as $key2=>$value2){ + $argument_array = array($value,$value2,$input); + $result = call_user_func('validate_'.$key2,$argument_array); + + if($result !== true){ //if we got error message, break the loop + $error_message = $result; + break; + } + } + } + if(count($error_message) > 0){ + $last_error_message = $error_message; + break; + } + } + + if(!empty($last_error_message)){ + return $last_error_message; + }else{ + return true; + } + } +?> \ No newline at end of file diff --git a/includes/db-core.php b/includes/db-core.php new file mode 100644 index 0000000..507d1a6 --- /dev/null +++ b/includes/db-core.php @@ -0,0 +1,27 @@ + \ No newline at end of file diff --git a/includes/db-functions.php b/includes/db-functions.php new file mode 100644 index 0000000..0b87e7c --- /dev/null +++ b/includes/db-functions.php @@ -0,0 +1,237 @@ +$value){ + $value = mysql_real_escape_string($value); + $field_list .= "`$key`,"; + $field_values .= "'$value',"; + } + + $field_list = substr($field_list,0,-1); + $field_values = substr($field_values,0,-1); + + $query = "INSERT INTO `ap_forms` ($field_list) VALUES ($field_values);"; + $result = mysql_query($query); + if(!$result){ + $error_message = 'Query failed! Error code: '.mysql_errno().' - '.mysql_error().' - Query: '.$query; + return $error_message; + } + + return true; + } + + function ap_forms_update($id,$data){ + + /** start validation **/ + //1.common validation + $rules['form_name']['max'] = 50; + + + $error_message = validate_rules($data,$rules); + if(is_array($error_message)){ + return $error_message; + } + + /** end validation **/ + + $update_values = ''; + + //dynamically create the sql update string, based on the input given + foreach ($data as $key=>$value){ + $value = mysql_real_escape_string($value); + $update_values .= "`$key`='$value',"; + } + $update_values = substr($update_values,0,-1); + + $query = "UPDATE `ap_forms` set + $update_values + where + form_id='$id';"; + + $result = mysql_query($query); + if(!$result){ + $error_message = 'Query failed! Error code: '.mysql_errno().' - '.mysql_error().' - Query: '.$query; + return $error_message; + } + + return true; + } + + /** ap_form_elements table ************************************/ + function ap_form_elements_insert($data){ + + /** start validation **/ + //1.common validation + $rules['form_id']['required'] = true; + $rules['element_id']['required'] = true; + + $error_message = validate_rules($data,$rules); + if(is_array($error_message)){ + return $error_message; + } + + /** end validation **/ + + $field_list = ''; + $field_values = ''; + + //dynamically create the field list and field values, based on the input given + foreach ($data as $key=>$value){ + $value = mysql_real_escape_string($value); + $field_list .= "`$key`,"; + $field_values .= "'$value',"; + } + + $field_list = substr($field_list,0,-1); + $field_values = substr($field_values,0,-1); + + $query = "INSERT INTO `ap_form_elements` ($field_list) VALUES ($field_values);"; + $result = mysql_query($query); + if(!$result){ + $error_message = 'Query failed! Error code: '.mysql_errno().' - '.mysql_error().' - Query: '.$query; + return $error_message; + } + + return true; + } + + function ap_form_elements_update($form_id,$element_id,$data){ + + /** start validation **/ + //1.common validation + $rules['form_id']['required'] = true; + $rules['element_id']['required'] = true; + + + $error_message = validate_rules($data,$rules); + if(is_array($error_message)){ + return $error_message; + } + + /** end validation **/ + + $update_values = ''; + + //dynamically create the sql update string, based on the input given + foreach ($data as $key=>$value){ + $value = mysql_real_escape_string($value); + $update_values .= "`$key`='$value',"; + } + $update_values = substr($update_values,0,-1); + + $query = "UPDATE `ap_form_elements` set + $update_values + where + form_id='$form_id' and element_id='$element_id';"; + + $result = mysql_query($query); + if(!$result){ + $error_message = 'Query failed! Error code: '.mysql_errno().' - '.mysql_error().' - Query: '.$query; + return $error_message; + } + + return true; + } + + /** ap_element_options table ************************************/ + function ap_element_options_insert($data){ + + /** start validation **/ + //1.common validation + $rules['form_id']['required'] = true; + $rules['element_id']['required'] = true; + $rules['option_id']['required'] = true; + + $error_message = validate_rules($data,$rules); + if(is_array($error_message)){ + return $error_message; + } + + /** end validation **/ + + $field_list = ''; + $field_values = ''; + + //dynamically create the field list and field values, based on the input given + foreach ($data as $key=>$value){ + $value = mysql_real_escape_string($value); + $field_list .= "`$key`,"; + $field_values .= "'$value',"; + } + + $field_list = substr($field_list,0,-1); + $field_values = substr($field_values,0,-1); + + $query = "INSERT INTO `ap_element_options` ($field_list) VALUES ($field_values);"; + + $result = mysql_query($query); + if(!$result){ + $error_message = 'Query failed! Error code: '.mysql_errno().' - '.mysql_error().' - Query: '.$query; + return $error_message; + } + + return true; + } + + function ap_element_options_update($form_id,$element_id,$option_id,$data){ + + /** start validation **/ + //1.common validation + $rules['form_id']['required'] = true; + $rules['element_id']['required'] = true; + $rules['option_id']['required'] = true; + + $error_message = validate_rules($data,$rules); + if(is_array($error_message)){ + return $error_message; + } + + /** end validation **/ + + $update_values = ''; + + //dynamically create the sql update string, based on the input given + foreach ($data as $key=>$value){ + $value = mysql_real_escape_string($value); + $update_values .= "`$key`='$value',"; + } + $update_values = substr($update_values,0,-1); + + $query = "UPDATE `ap_element_options` set + $update_values + where + form_id='$form_id' and element_id='$element_id' and option_id='$option_id';"; + + $result = mysql_query($query); + if(!$result){ + $error_message = 'Query failed! Error code: '.mysql_errno().' - '.mysql_error().' - Query: '.$query; + return $error_message; + } + + return true; + } +?> \ No newline at end of file diff --git a/includes/entry-functions.php b/includes/entry-functions.php new file mode 100644 index 0000000..15f44ab --- /dev/null +++ b/includes/entry-functions.php @@ -0,0 +1,487 @@ +name; + $i++; + } + + $row = do_fetch_result($result); + //store the result into array + for($i=0;$i<$fields_num;$i++){ + $column_name = $columns[$i]; + $entry_data[$column_name] = htmlspecialchars($row[$column_name],ENT_QUOTES); + } + + + //get form element options + $query = "select element_id,option_id,`option` from ap_element_options where form_id='$form_id' and live=1"; + $result = do_query($query); + while($row = do_fetch_result($result)){ + $element_id = $row['element_id']; + $option_id = $row['option_id']; + + $element_option_lookup[$element_id][$option_id] = true; //array index will hold option_id + } + + + //loop through each element to get the values + foreach ($form_elements as $element){ + $element_type = $element['element_type']; + $element_id = $element['element_id']; + $element_constraint = $element['element_constraint']; + + if('simple_name' == $element_type){ //Simple Name - 2 elements + $form_values['element_'.$element_id.'_1']['default_value'] = $entry_data['element_'.$element_id.'_1']; + $form_values['element_'.$element_id.'_2']['default_value'] = $entry_data['element_'.$element_id.'_2']; + }elseif ('name' == $element_type){ //Extended Name - 4 elements + $form_values['element_'.$element_id.'_1']['default_value'] = $entry_data['element_'.$element_id.'_1']; + $form_values['element_'.$element_id.'_2']['default_value'] = $entry_data['element_'.$element_id.'_2']; + $form_values['element_'.$element_id.'_3']['default_value'] = $entry_data['element_'.$element_id.'_3']; + $form_values['element_'.$element_id.'_4']['default_value'] = $entry_data['element_'.$element_id.'_4']; + }elseif ('time' == $element_type){ //Time - 4 elements + //convert into time and split into 4 elements + if(!empty($entry_data['element_'.$element_id]) && ($entry_data['element_'.$element_id] != '00:00:00')){ + $time_value = $entry_data['element_'.$element_id]; + $time_value = date("h/i/s/A",strtotime($time_value)); + + $exploded = array(); + $exploded = explode('/',$time_value); + + $form_values['element_'.$element_id.'_1']['default_value'] = $exploded[0]; + $form_values['element_'.$element_id.'_2']['default_value'] = $exploded[1]; + $form_values['element_'.$element_id.'_3']['default_value'] = $exploded[2]; + $form_values['element_'.$element_id.'_4']['default_value'] = $exploded[3]; + } + }elseif ('address' == $element_type){ //Address - 6 elements + $form_values['element_'.$element_id.'_1']['default_value'] = $entry_data['element_'.$element_id.'_1']; + $form_values['element_'.$element_id.'_2']['default_value'] = $entry_data['element_'.$element_id.'_2']; + $form_values['element_'.$element_id.'_3']['default_value'] = $entry_data['element_'.$element_id.'_3']; + $form_values['element_'.$element_id.'_4']['default_value'] = $entry_data['element_'.$element_id.'_4']; + $form_values['element_'.$element_id.'_5']['default_value'] = $entry_data['element_'.$element_id.'_5']; + $form_values['element_'.$element_id.'_6']['default_value'] = $entry_data['element_'.$element_id.'_6']; + }elseif ('money' == $element_type){ //Price + if($element_constraint == 'yen'){ //yen only has 1 element + $form_values['element_'.$element_id]['default_value'] = $entry_data['element_'.$element_id]; + }else{ //other has 2 fields + $exploded = array(); + $exploded = explode('.',$entry_data['element_'.$element_id]); + + $form_values['element_'.$element_id.'_1']['default_value'] = $exploded[0]; + $form_values['element_'.$element_id.'_2']['default_value'] = $exploded[1]; + } + + }elseif ('date' == $element_type){ //date with format MM/DD/YYYY + if(!empty($entry_data['element_'.$element_id]) && ($entry_data['element_'.$element_id] != '0000-00-00')){ + $date_value = $entry_data['element_'.$element_id]; + $date_value = date("m/d/Y",strtotime($date_value)); + + $exploded = array(); + $exploded = explode('/',$date_value); + + $form_values['element_'.$element_id.'_1']['default_value'] = $exploded[0]; + $form_values['element_'.$element_id.'_2']['default_value'] = $exploded[1]; + $form_values['element_'.$element_id.'_3']['default_value'] = $exploded[2]; + } + + }elseif ('europe_date' == $element_type){ //date with format DD/MM/YYYY + if(!empty($entry_data['element_'.$element_id]) && ($entry_data['element_'.$element_id] != '0000-00-00')){ + $date_value = $entry_data['element_'.$element_id]; + $date_value = date("d/m/Y",strtotime($date_value)); + + $exploded = array(); + $exploded = explode('/',$date_value); + + $form_values['element_'.$element_id.'_1']['default_value'] = $exploded[0]; + $form_values['element_'.$element_id.'_2']['default_value'] = $exploded[1]; + $form_values['element_'.$element_id.'_3']['default_value'] = $exploded[2]; + } + + }elseif ('phone' == $element_type){ //Phone - 3 elements + + $phone_value = $entry_data['element_'.$element_id]; + $phone_1 = substr($phone_value,0,3); + $phone_2 = substr($phone_value,3,3); + $phone_3 = substr($phone_value,-4); + + $form_values['element_'.$element_id.'_1']['default_value'] = $phone_1; + $form_values['element_'.$element_id.'_2']['default_value'] = $phone_2; + $form_values['element_'.$element_id.'_3']['default_value'] = $phone_3; + + }elseif ('checkbox' == $element_type){ //Checkbox - multiple elements + $checkbox_childs = $element_option_lookup[$element_id]; + + foreach ($checkbox_childs as $option_id=>$dumb){ + $form_values['element_'.$element_id.'_'.$option_id]['default_value'] = $entry_data['element_'.$element_id.'_'.$option_id]; + } + + }elseif ('file' == $element_type){ //File + + $filename_value = $entry_data['element_'.$element_id]; + + if(!empty($filename_value)){ + $file_1 = substr($filename_value,strpos($filename_value,'-')+1); + $filename_value = substr($file_1,strpos($file_1,'-')+1); + + //encode the long query string for more readibility + $q_string = base64_encode("form_id={$form_id}&id={$entry_id}&el=element_{$element_id}"); + + + //special for file,just provide a markup to download or delete the file + if($use_review_table == false){ + $form_values['element_'.$element_id]['default_value'] =<< {$filename_value}   + Download | + Delete +EOT; + }else{ //if using review table, only show attached filename and delete file + if(strpos($_SERVER['REQUEST_URI'],'?') === false){ + $href_url = $_SERVER['REQUEST_URI']."?delete_file={$element_id}"; + }else{ + $href_url = $_SERVER['REQUEST_URI']."&delete_file={$element_id}"; + } + + $form_values['element_'.$element_id]['default_value'] =<< {$filename_value}   + Delete +EOT; + } + } + }else{ //element with only 1 input + $form_values['element_'.$element_id]['default_value'] = $entry_data['element_'.$element_id]; + } + + } + + + return $form_values; + + + } + + //get an array containing values from respective table for certain id + //similar to get_entry_values() function, but this one is higher level and include labels + function get_entry_details($form_id,$entry_id,$options=array()){ + + $admin_clause = ''; + if(!empty($options['review_mode'])){ //hide admin fields in review page + $admin_clause = ' and element_is_private=0 '; + } + + //get form elements + $query = "select + element_id, + element_type, + element_constraint, + element_title + from + `ap_form_elements` + where + form_id='$form_id' and + element_type <> 'section' + {$admin_clause} + order by + element_position asc"; + $result = do_query($query); + $i=0; + while($row = do_fetch_result($result)){ + $form_elements[$i]['element_id'] = $row['element_id']; + $form_elements[$i]['element_type'] = $row['element_type']; + $form_elements[$i]['element_constraint'] = $row['element_constraint']; + + //store element title into array for reference later + $element_title_lookup[$row['element_id']] = $row['element_title']; + + $i++; + } + + if(!empty($options['review_mode'])){ + $table_suffix = '_review'; + }else{ + $table_suffix = ''; + } + + //get whole entry for current id + $query = "select * from `ap_form_{$form_id}{$table_suffix}` where id='$entry_id' limit 1"; + $result = do_query($query); + + //get actual field name from selected table + $i = 0; + $fields_num = mysql_num_fields($result); + while($i < $fields_num){ + $meta = mysql_fetch_field($result, $i); + $columns[$i] = $meta->name; + $i++; + } + + $row = do_fetch_result($result); + //store the result into array + for($i=0;$i<$fields_num;$i++){ + $column_name = $columns[$i]; + $entry_data[$column_name] = htmlspecialchars($row[$column_name],ENT_QUOTES); + } + + + //get form element options + $query = "select element_id,option_id,`option` from ap_element_options where form_id='$form_id' and live=1 order by position asc"; + $result = do_query($query); + while($row = do_fetch_result($result)){ + $element_id = $row['element_id']; + $option_id = $row['option_id']; + + $element_option_lookup[$element_id][$option_id] = $row['option']; //array index will hold option_id + } + + + + + //loop through each element to get the values + $i = 0; + foreach ($form_elements as $element){ + $element_type = $element['element_type']; + $element_id = $element['element_id']; + $element_constraint = $element['element_constraint']; + + $entry_details[$i]['label'] = $element_title_lookup[$element_id]; + $entry_details[$i]['value'] = ' '; //default value + $entry_details[$i]['element_id'] = $element_id; + $entry_details[$i]['element_type'] = $element_type; + + + if('simple_name' == $element_type){ //Simple Name - 2 elements + $simple_name_value = trim($entry_data['element_'.$element_id.'_1'].' '.$entry_data['element_'.$element_id.'_2']); + if(!empty($simple_name_value)){ + $entry_details[$i]['value'] = $simple_name_value; + } + }elseif ('name' == $element_type){ //Extended Name - 4 elements + $name_value = trim($entry_data['element_'.$element_id.'_1'].' '. $entry_data['element_'.$element_id.'_2'].' '.$entry_data['element_'.$element_id.'_3'].' '.$entry_data['element_'.$element_id.'_4']); + if(!empty($name_value)){ + $entry_details[$i]['value'] = $name_value; + } + }elseif ('time' == $element_type){ //Time - 4 elements + //convert into time and split into 4 elements + if(!empty($entry_data['element_'.$element_id]) && ($entry_data['element_'.$element_id] != '00:00:00')){ + $time_value = $entry_data['element_'.$element_id]; + + if($element_constraint == 'show_seconds'){ + $time_value = date("h:i:s A",strtotime($time_value)); + }else{ + $time_value = date("h:i A",strtotime($time_value)); + } + + $entry_details[$i]['value'] = $time_value; + } + }elseif ('address' == $element_type){ //Address - 6 elements + + if(!empty($entry_data['element_'.$element_id.'_3'])){ + $entry_data['element_'.$element_id.'_3'] = $entry_data['element_'.$element_id.'_3'].','; + } + + $entry_details[$i]['value'] = $entry_data['element_'.$element_id.'_1'].' '.$entry_data['element_'.$element_id.'_2'].'
    '.$entry_data['element_'.$element_id.'_3'].' '.$entry_data['element_'.$element_id.'_4'].' '.$entry_data['element_'.$element_id.'_5'].'
    '.$entry_data['element_'.$element_id.'_6']; + + //if empty, shows blank instead of breaks + if(trim(str_replace("
    ","",$entry_details[$i]['value'])) == ""){ + $entry_details[$i]['value'] = ' '; + } + + }elseif ('money' == $element_type){ //Price + switch ($element_constraint){ + case 'pound' : $currency = '£';break; + case 'euro' : $currency = '€';break; + case 'yen' : $currency = '¥';break; + default : $currency = '$';break; + } + + if(!empty($entry_data['element_'.$element_id]) || $entry_data['element_'.$element_id] === 0 || $entry_data['element_'.$element_id] === '0'){ + $entry_details[$i]['value'] = $currency.$entry_data['element_'.$element_id]; + } + + }elseif ('date' == $element_type){ //date with format MM/DD/YYYY + if(!empty($entry_data['element_'.$element_id]) && ($entry_data['element_'.$element_id] != '0000-00-00')){ + $date_value = $entry_data['element_'.$element_id]; + $date_value = date("m/d/Y",strtotime($date_value)); + + $entry_details[$i]['value'] = $date_value; + } + + }elseif ('europe_date' == $element_type){ //date with format DD/MM/YYYY + if(!empty($entry_data['element_'.$element_id]) && ($entry_data['element_'.$element_id] != '0000-00-00')){ + $date_value = $entry_data['element_'.$element_id]; + $date_value = date("d/m/Y",strtotime($date_value)); + + $entry_details[$i]['value'] = $date_value; + } + + }elseif ('phone' == $element_type){ //Phone - 3 elements + + $phone_value = $entry_data['element_'.$element_id]; + $phone_1 = substr($phone_value,0,3); + $phone_2 = substr($phone_value,3,3); + $phone_3 = substr($phone_value,-4); + + if(!empty($phone_value)){ + $entry_details[$i]['value'] = "($phone_1) - $phone_2 - $phone_3"; + } + + }elseif ('checkbox' == $element_type){ //Checkbox - multiple elements + $checkbox_childs = $element_option_lookup[$element_id]; + + $checkbox_content = ''; + foreach ($checkbox_childs as $option_id=>$option_label){ + if(!empty($entry_data['element_'.$element_id.'_'.$option_id])){ + if(empty($options['strip_checkbox_image'])){ + $checkbox_content .= ' '.$option_label.'
    '; + }else{ + $checkbox_content .= '- '.$option_label.'
    '; + } + } + } + + if(!empty($checkbox_content)){ + $entry_details[$i]['value'] = $checkbox_content; + } + }elseif ('file' == $element_type){ //File + + $filename_value = $entry_data['element_'.$element_id]; + + if(!empty($filename_value)){ + $file_1 = substr($filename_value,strpos($filename_value,'-')+1); + $filename_value = substr($file_1,strpos($file_1,'-')+1); + + //encode the long query string for more readibility + $q_string = base64_encode("form_id={$form_id}&id={$entry_id}&el=element_{$element_id}"); + + if(!empty($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] != 'off')){ + $ssl_suffix = 's'; + }else{ + $ssl_suffix = ''; + } + + //special for file,just provide a markup to download or delete the file + if(!empty($options['machform_base_path'])){ //if the form is called from advanced form code + $entry_details[$i]['value'] = ' '.$filename_value.''; + }else{ + $entry_details[$i]['value'] = ' '.$filename_value.''; + } + + if(!empty($options['strip_download_link'])){ + $entry_details[$i]['value'] = $filename_value; + } + + if(!empty($options['show_attach_image'])){ + $entry_details[$i]['value'] = ' '.$filename_value; + } + } + }elseif('select' == $element_type || 'radio' == $element_type){ + if(!empty($entry_data['element_'.$element_id])){ + $entry_details[$i]['value'] = $element_option_lookup[$element_id][$entry_data['element_'.$element_id]]; + } + }elseif ('url' == $element_type){ + if(!empty($entry_data['element_'.$element_id])){ + $entry_details[$i]['value'] = "{$entry_data['element_'.$element_id]}"; + } + }else{ //element with only 1 input + if(isset($entry_data['element_'.$element_id])){ + $entry_details[$i]['value'] = $entry_data['element_'.$element_id]; + } + } + + $i++; + } + + return $entry_details; + } + + + //delete a file element from an entry + function delete_file_entry($form_id,$entry_id,$element_id){ + //delete actual file + $query = "select element_{$element_id} from `ap_form_{$form_id}` where id='$entry_id'"; + $result = do_query($query); + $row = do_fetch_result($result); + $filename = $row['element_'.$element_id]; + @unlink(UPLOAD_DIR."/form_{$form_id}/files/".$filename); + + //delete from table + $query = "update `ap_form_{$form_id}` set element_{$element_id}=NULL where id='$entry_id'"; + do_query($query); + } + + //delete a file element from an entry in review table + function delete_review_file_entry($form_id,$entry_id,$element_id,$options=array()){ + //delete actual file + $query = "select element_{$element_id} from `ap_form_{$form_id}_review` where id='$entry_id'"; + $result = do_query($query); + $row = do_fetch_result($result); + $filename = $row['element_'.$element_id].'.tmp'; + @unlink($options['machform_data_path'].UPLOAD_DIR."/form_{$form_id}/files/".$filename); + + //delete from table + $query = "update `ap_form_{$form_id}_review` set element_{$element_id}=NULL where id='$entry_id'"; + do_query($query); + } + + //delete multiple entries and related uploads (if any) + function delete_entries($form_id,$entries_id){ + + //delete from table + $deleted_entry_id_joined = implode("','",$entries_id); + do_query("delete from `ap_form_{$form_id}` where id in('{$deleted_entry_id_joined}')"); + + + //get the element id for file fields + $query = "select element_id from ap_form_elements where element_type='file' and form_id='{$form_id}'"; + $result = do_query($query); + while($row = do_fetch_result($result)){ + $file_element_id_array[] = $row['element_id']; + } + + //delete the files from data folder + if(!empty($file_element_id_array)){ + foreach ($entries_id as $entry_id){ + foreach ($file_element_id_array as $element_id){ + $filename = array(); + $filename = glob(UPLOAD_DIR."/form_{$form_id}/files/element_{$element_id}_*-{$entry_id}-*"); + @unlink($filename[0]); + } + } + } + + return true; + } + +?> \ No newline at end of file diff --git a/includes/filter-functions.php b/includes/filter-functions.php new file mode 100644 index 0000000..358c984 --- /dev/null +++ b/includes/filter-functions.php @@ -0,0 +1,44 @@ +$value){ + if(!empty($value)){ + + //stripslashes added by magic quotes + if(get_magic_quotes_gpc()){ + $input_array[$key] = stripslashes($input_array[$key]); + } + + if($sanitize_html){ + $input_array[$key] = strip_tags($input_array[$key],$allowable_tags); + } + + if($sanitize_special_chars){ + $input_array[$key] = htmlspecialchars($input_array[$key]); + } + + if($escape_mysql){ + $input_array[$key] = mysql_real_escape_string($input_array[$key]); + } + } + } + + return $input_array; + + } + +?> \ No newline at end of file diff --git a/includes/footer.php b/includes/footer.php new file mode 100644 index 0000000..0861d69 --- /dev/null +++ b/includes/footer.php @@ -0,0 +1,12 @@ + +
    + + + + + + + + \ No newline at end of file diff --git a/includes/header.php b/includes/header.php new file mode 100644 index 0000000..dd21a79 --- /dev/null +++ b/includes/header.php @@ -0,0 +1,37 @@ + + + + +MachForm - PHP Form Builder + + + + + + + + +
    +
    +
    Loading Data ...
    +
    +
    + + + +
    + + + + + + +
    diff --git a/includes/helper-functions.php b/includes/helper-functions.php new file mode 100644 index 0000000..35ba3cf --- /dev/null +++ b/includes/helper-functions.php @@ -0,0 +1,514 @@ +0) { + // over a month old, just show date ("Month, Day Year") + if(!empty($input_date)){ + return date('F jS, Y',strtotime($input_date)); + }else{ + return 'N/A'; + } + } else { + if ($weeks>0) { + // weeks and days + $relative_date .= ($relative_date?', ':'').$weeks.' week'.($weeks>1?'s':''); + $relative_date .= $days>0?($relative_date?', ':'').$days.' day'.($days>1?'s':''):''; + } elseif ($days>0) { + // days and hours + $relative_date .= ($relative_date?', ':'').$days.' day'.($days>1?'s':''); + $relative_date .= $hours>0?($relative_date?', ':'').$hours.' hour'.($hours>1?'s':''):''; + } elseif ($hours>0) { + // hours and minutes + $relative_date .= ($relative_date?', ':'').$hours.' hour'.($hours>1?'s':''); + $relative_date .= $minutes>0?($relative_date?', ':'').$minutes.' minute'.($minutes>1?'s':''):''; + } elseif ($minutes>0) { + // minutes only + $relative_date .= ($relative_date?', ':'').$minutes.' minute'.($minutes>1?'s':''); + } else { + // seconds only + $relative_date .= ($relative_date?', ':'').$seconds.' second'.($seconds>1?'s':''); + } + + // show relative date and add proper verbiage + return $relative_date.' ago'; + } + + } + + //this function accept 'YYYY-MM-DD HH:MM:SS' + function short_relative_date($input_date) { + + $tz = 0; // change this if your web server and weblog are in different timezones + + $posted_date = str_replace(array('-',' ',':'),'',$input_date); + $month = substr($posted_date,4,2); + $year = substr($posted_date,0,4); + + if ($month == "02") { // february + // check for leap year + $leapYear = isLeapYear($year); + if ($leapYear) $month_in_seconds = 2505600; // leap year + else $month_in_seconds = 2419200; + } + else { // not february + // check to see if the month has 30/31 days in it + if ($month == "04" or + $month == "06" or + $month == "09" or + $month == "11") + $month_in_seconds = 2592000; // 30 day month + else $month_in_seconds = 2678400; // 31 day month; + } + + $in_seconds = strtotime(substr($posted_date,0,8).' '. + substr($posted_date,8,2).':'. + substr($posted_date,10,2).':'. + substr($posted_date,12,2)); + $diff = time() - ($in_seconds + ($tz*3600)); + $months = floor($diff/$month_in_seconds); + $diff -= $months*2419200; + $weeks = floor($diff/604800); + $diff -= $weeks*604800; + $days = floor($diff/86400); + $diff -= $days*86400; + $hours = floor($diff/3600); + $diff -= $hours*3600; + $minutes = floor($diff/60); + $diff -= $minutes*60; + $seconds = $diff; + + $relative_date = ''; + if ($months>0) { + + // over a month old + if(!empty($input_date)){ + if($year < date('Y')){ //over a year, show international date + return date('Y-m-d',strtotime($input_date)); + }else{ //less than a year + return date('M j',strtotime($input_date)); + } + + }else{ + return ''; + } + } else { + if ($weeks>0) { + // weeks and days + $relative_date .= ($relative_date?', ':'').$weeks.' week'.($weeks>1?'s':''); + //$relative_date .= $days>0?($relative_date?', ':'').$days.' day'.($days>1?'s':''):''; + } elseif ($days>0) { + // days and hours + $relative_date .= ($relative_date?', ':'').$days.' day'.($days>1?'s':''); + //$relative_date .= $hours>0?($relative_date?', ':'').$hours.' hour'.($hours>1?'s':''):''; + } elseif ($hours>0) { + // hours and minutes + $relative_date .= ($relative_date?', ':'').$hours.' hour'.($hours>1?'s':''); + //$relative_date .= $minutes>0?($relative_date?', ':'').$minutes.' minute'.($minutes>1?'s':''):''; + } elseif ($minutes>0) { + // minutes only + $relative_date .= ($relative_date?', ':'').$minutes.' minute'.($minutes>1?'s':''); + } else { + // seconds only + $relative_date .= ($relative_date?', ':'').$seconds.' second'.($seconds>1?'s':''); + } + + // show relative date and add proper verbiage + return $relative_date.' ago'; + } + + } + + function isLeapYear($year) { + return $year % 4 == 0 && ($year % 400 == 0 || $year % 100 != 0); + } + + //remove a folder and all it's content + function full_rmdir($dirname){ + if ($dirHandle = opendir($dirname)){ + $old_cwd = getcwd(); + chdir($dirname); + + while ($file = readdir($dirHandle)){ + if ($file == '.' || $file == '..') continue; + + if (is_dir($file)){ + if (!full_rmdir($file)) return false; + }else{ + if (!unlink($file)) return false; + } + } + + closedir($dirHandle); + chdir($old_cwd); + if (!rmdir($dirname)) return false; + + return true; + }else{ + return false; + } + } + + //show success or error messages + function show_message(){ + + if(!empty($_SESSION['AP_ERROR'])){ + if(!empty($_SESSION['AP_ERROR']['desc'])){ + $error_desc = '

    '.$_SESSION['AP_ERROR']['desc'].'

    '; + }else{ + $error_desc = ''; + } + + $ul_markup =<< +
  • +

    {$_SESSION['AP_ERROR']['title']}  

    + {$error_desc} +
  • + +EOT; + + echo $ul_markup; + + $_SESSION['AP_ERROR'] = array(); + unset($_SESSION['AP_ERROR']); + } + + if(!empty($_SESSION['AP_SUCCESS'])){ + if(!empty($_SESSION['AP_SUCCESS']['desc'])){ + $success_desc = '

    '.$_SESSION['AP_SUCCESS']['desc'].'

    '; + }else{ + $success_desc = ''; + } + + $ul_markup =<< +
  • +

    {$_SESSION['AP_SUCCESS']['title']} 

    + {$success_desc} +
  • + +EOT; + + echo $ul_markup; + + $_SESSION['AP_SUCCESS'] = array(); + unset($_SESSION['AP_SUCCESS']); + } + + } + + //send notification email + //$to_emails is a comma separated list of email address or {element_x} field + function send_notification($form_id,$entry_id,$to_emails,$email_param){ + + $from_name = $email_param['from_name']; + $from_email = $email_param['from_email']; + $subject = $email_param['subject']; + $content = nl2br($email_param['content']); + $as_plain_text = $email_param['as_plain_text']; //if set to 'true' the email content will be a simple plain text + $target_is_admin = $email_param['target_is_admin']; //if set to 'false', the download link for uploaded file will be removed + + + //get data for the particular entry id + if($target_is_admin === false){ + $options['strip_download_link'] = true; + } + + $options['strip_checkbox_image'] = true; + $options['machform_base_path'] = $email_param['machform_base_path']; //the path to machform + $entry_details = get_entry_details($form_id,$entry_id,$options); + + //populate field values to template variables + $i=0; + foreach ($entry_details as $data){ + $template_variables[$i] = '{element_'.$data['element_id'].'}'; + $template_values[$i] = $data['value']; + + if($data['element_type'] == 'textarea'){ + $template_values[$i] = nl2br($data['value']); + }elseif ($data['element_type'] == 'file'){ + if($target_is_admin === false){ + $template_values[$i] = strip_tags($data['value']); + }else{ + $template_values[$i] = strip_tags($data['value'],''); + } + }else{ + $template_values[$i] = $data['value']; + } + + $i++; + } + + //get entry timestamp + $query = "select date_created,ip_address from `ap_form_{$form_id}` where id='$entry_id'"; + $result = do_query($query); + $row = do_fetch_result($result); + + $date_created = $row['date_created']; + $ip_address = $row['ip_address']; + + //get form name + $query = "select form_name from `ap_forms` where form_id='$form_id'"; + $result = do_query($query); + $row = do_fetch_result($result); + $form_name = $row['form_name']; + + + $template_variables[$i] = '{date_created}'; + $template_values[$i] = $date_created; + $i++; + $template_variables[$i] = '{ip_address}'; + $template_values[$i] = $ip_address; + $i++; + $template_variables[$i] = '{form_name}'; + $template_values[$i] = $form_name; + $i++; + $template_variables[$i] = '{entry_no}'; + $template_values[$i] = $entry_id; + $i++; + $template_variables[$i] = '{form_id}'; + $template_values[$i] = $form_id; + + + //compose {entry_data} based on 'as_plain_text' preferences + $email_body = ''; + if(!$as_plain_text){ + //compose html format + $email_body = ''."\n"; + + $toggle = false; + foreach ($entry_details as $data){ + //0 should be displayed, empty string don't + if((empty($data['value']) || $data['value'] == ' ') && $data['value'] !== 0 && $data['value'] !== '0'){ + continue; + } + + if($toggle){ + $toggle = false; + $row_style = 'style="background-color:#F3F7FB"'; + }else{ + $toggle = true; + $row_style = ''; + } + + if($data['element_type'] == 'textarea'){ + $data['value'] = nl2br($data['value']); + }elseif ($data['element_type'] == 'file'){ + + if($target_is_admin === false){ + $data['value'] = strip_tags($data['value']); + }else{ + $data['value'] = strip_tags($data['value'],''); + } + } + + $email_body .= "\n"; + $email_body .= ''."\n"; + $email_body .= ''."\n"; + $email_body .= ''."\n"; + + $i++; + } + $email_body .= "
    '.$data['label'].' '.$data['value'].'
    \n"; + }else{ + + //compose text format + foreach ($entry_details as $data){ + + //0 should be displayed, empty string don't + if((empty($data['value']) || $data['value'] == ' ') && $data['value'] !== 0 && $data['value'] !== '0'){ + continue; + } + + if($data['element_type'] == 'textarea'){ + $email_body .= "{$data['label']}
    ".nl2br($data['value'])."

    \n"; + }elseif ($data['element_type'] == 'checkbox' || $data['element_type'] == 'address'){ + $email_body .= "{$data['label']}
    ".$data['value']."

    \n"; + }elseif ($data['element_type'] == 'file'){ + if($target_is_admin === false){ + $data['value'] = strip_tags($data['value']); + $email_body .= "{$data['label']} - {$data['value']}
    \n"; + }else{ + $data['value'] = strip_tags($data['value'],'
    '); + $email_body .= "{$data['label']}
    ".$data['value']."

    \n"; + } + }else{ + $email_body .= "{$data['label']} - {$data['value']}
    \n"; + } + + + } + } + + $i = count($template_variables); + $template_variables[$i] = '{entry_data}'; + $template_values[$i] = $email_body; + + $mail = new PHPMailer(); + $mail->CharSet = 'UTF-8'; + $mail->Host = "127.0.0.1"; + $mail->IsHTML(true); + $mail->Mailer = "mail"; + $mail->SMTPAuth = false; + + if(USE_SMTP === true){ + $mail->Mailer = "smtp"; + $mail->Host = SMTP_HOST; + $mail->Port = SMTP_PORT; + + if(SMTP_AUTH === true){ + $mail->SMTPAuth = true; + $mail->Username = SMTP_USERNAME; + $mail->Password = SMTP_PASSWORD; + } + + if(SMTP_SECURE === true){ + $mail->SMTPSecure = 'tls'; + } + } + + //parse from_name template + if(!empty($from_name)){ + $from_name = str_replace($template_variables,$template_values,$from_name); + $mail->FromName = str_replace(' ','',$from_name); + }elseif (NOTIFICATION_MAIL_FROM_NAME != ''){ + $mail->FromName = utf8_encode(str_replace(' ','',str_replace($template_variables,$template_values,NOTIFICATION_MAIL_FROM_NAME))); + }else{ + $mail->FromName = 'MachForm'; + } + + //decode any html entity + $mail->FromName = html_entity_decode($mail->FromName,ENT_QUOTES); + + //parse from_email_address template + if(!empty($from_email)){ + $from_email = str_replace($template_variables,$template_values,$from_email); + $mail->From = $from_email; + }elseif(NOTIFICATION_MAIL_FROM != ''){ + $mail->From = utf8_encode(str_replace($template_variables,$template_values,NOTIFICATION_MAIL_FROM)); + }else{ + $domain = str_replace('www.','',$_SERVER['SERVER_NAME']); + $mail->From = "no-reply@{$domain}"; + } + + //parse subject template + if(!empty($subject)){ + $subject = str_replace($template_variables,$template_values,$subject); + $mail->Subject = str_replace(' ','',$subject); + }elseif (NOTIFICATION_MAIL_SUBJECT != ''){ + $mail->Subject = utf8_encode(str_replace(' ','',str_replace($template_variables,$template_values,NOTIFICATION_MAIL_SUBJECT))); + }else{ + if($target_is_admin){ + $mail->Subject = utf8_encode("{$form_name} [#{$entry_id}]"); + }else{ + $mail->Subject = utf8_encode("{$form_name} - Receipt"); + } + } + //decode any html entity + $mail->Subject = html_entity_decode($mail->Subject,ENT_QUOTES); + + + //parse content template + $email_content = str_replace($template_variables,$template_values,$content); + + //add footer + $email_content .= "




    Powered by
    MachForm"; + + //enclose with container div + $email_content = '
    '.$email_content.'
    '; + + $mail->Body = $email_content; + + //send email + $to_emails = str_replace(' ','',str_replace($template_variables,$template_values,$to_emails)); + $email_address = explode(',',$to_emails); + + $has_email = false; + foreach ($email_address as $email){ + $email = trim($email); + if(!empty($email)){ + $mail->AddAddress($email); + $has_email = true; + } + } + + if($has_email){ + $send_status = $mail->Send(); + $mail->ClearAddresses(); + + if($send_status !== true){ + echo "Error sending email: ".$mail->ErrorInfo; + } + } + } + + function get_ssl_suffix(){ + if(!empty($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] != 'off')){ + $ssl_suffix = 's'; + }else{ + $ssl_suffix = ''; + } + + return $ssl_suffix; + } + + function get_dirname($path){ + $current_dir = dirname($path); + + if($current_dir == "/" || $current_dir == "\\"){ + $current_dir = ''; + } + + return $current_dir; + } + +?> \ No newline at end of file diff --git a/includes/language.php b/includes/language.php new file mode 100644 index 0000000..b91e06a --- /dev/null +++ b/includes/language.php @@ -0,0 +1,96 @@ +highlighted below.'; + + //form buttons + $lang['submit_button'] = 'Submit'; + $lang['continue_button'] = 'Continue'; + $lang['back_button'] = 'Back'; + + //form status + $lang['form_inactive'] = 'This form is currently inactive.'; + + //form password + $lang['form_pass_title'] = 'This form is password protected.'; + $lang['form_pass_desc'] = 'Please enter your password.'; + $lang['form_pass_invalid'] = 'Invalid Password!'; + + //form review + $lang['review_title'] = 'Review Your Entry'; + $lang['review_message'] = 'Please review your entry below. Click Submit button to finish.'; + + //validation message + $lang['val_required'] = 'This field is required. Please enter a value.'; + $lang['val_required_file'] = 'This field is required. Please upload a file.'; + $lang['val_unique'] = 'This field requires a unique entry and this value has already been used.'; + $lang['val_integer'] = 'This field must be an integer.'; + $lang['val_float'] = 'This field must be a float.'; + $lang['val_numeric'] = 'This field must be a number.'; + $lang['val_min'] = 'This field can not be less than %s characters.'; + $lang['val_max'] = 'This field can not be greater than %s characters.'; + $lang['val_range'] = 'This field is not in the range %s through %s characters.'; + $lang['val_email'] = 'This field is not in the correct email format.'; + $lang['val_website'] = 'This field is not in the correct website address format.'; + $lang['val_username'] = 'This field may only consist of a-z 0-9 and underscores.'; + $lang['val_equal'] = '%s must match.'; + $lang['val_date'] = 'This field is not in the correct date format.'; + $lang['val_time'] = 'This field is not in the correct time format.'; + $lang['val_phone'] = 'Please enter a valid phone number.'; + $lang['val_filetype'] = 'The filetype you are attempting to upload is not allowed.'; + + //fields on excel/csv + $lang['export_num'] = 'No.'; + $lang['date_created'] = 'Date Created'; + $lang['date_updated'] = 'Date Updated'; + $lang['ip_address'] = 'IP Address'; +?> \ No newline at end of file diff --git a/includes/post-functions.php b/includes/post-functions.php new file mode 100644 index 0000000..706b634 --- /dev/null +++ b/includes/post-functions.php @@ -0,0 +1,2328 @@ + address, simple_name, name + //element has virtual child -> phone, date, europe_date, time, money + + $query = "select + element_id, + element_title, + element_is_required, + element_is_unique, + element_type, + element_constraint, + element_total_child, + element_is_private, + element_default_value + from + ap_form_elements + where + form_id='$form_id' order by element_id asc"; + + $result = do_query($query); + + $element_to_get = array(); + $private_elements = array(); //admin-only fields + + while($row = do_fetch_result($result)){ + if($row['element_type'] == 'section'){ + continue; + } + //store element info + $element_info[$row['element_id']]['title'] = $row['element_title']; + $element_info[$row['element_id']]['type'] = $row['element_type']; + $element_info[$row['element_id']]['is_required'] = $row['element_is_required']; + $element_info[$row['element_id']]['is_unique'] = $row['element_is_unique']; + $element_info[$row['element_id']]['is_private'] = $row['element_is_private']; + $element_info[$row['element_id']]['constraint'] = $row['element_constraint']; + $element_info[$row['element_id']]['default_value'] = $row['element_default_value']; + + //get element form name, complete with the childs + if(empty($element_child_lookup[$row['element_type']]) || ($row['element_constraint'] == 'yen')){ //elements with no child + $element_to_get[] = 'element_'.$row['element_id']; + + }else{ //elements with child + if($row['element_type'] != 'checkbox'){ + $max = $element_child_lookup[$row['element_type']] + 1; + + for ($j=1;$j<=$max;$j++){ + $element_to_get[] = "element_{$row['element_id']}_{$j}"; + } + }else{ + //for checkbox, get childs elements from ap_element_options table + $sub_query = "select + option_id + from + ap_element_options + where + form_id='{$form_id}' and element_id='{$row['element_id']}' and live=1 + order by + `position` asc"; + $sub_result = do_query($sub_query); + while($sub_row = do_fetch_result($sub_result)){ + $element_to_get[] = "element_{$row['element_id']}_{$sub_row['option_id']}"; + $checkbox_childs[$row['element_id']][] = $sub_row['option_id']; //store the child into array for further reference + } + } + } + + //if the back button pressed after review page, we need to store the file info + if(!empty($_SESSION['review_id'])){ + if($row['element_type'] == 'file'){ + $existing_file_id[] = $row['element_id']; + } + } + } + + + if(!empty($existing_file_id)){ + $existing_file_id_list = ''; + foreach ($existing_file_id as $value){ + $existing_file_id_list .= 'element_'.$value.','; + } + $existing_file_id_list = rtrim($existing_file_id_list,','); + + $query = "select {$existing_file_id_list} from ap_form_{$form_id}_review where `id`='{$_SESSION['review_id']}'"; + $result = do_query($query); + $row = do_fetch_result($result); + + foreach ($existing_file_id as $value){ + if(!empty($row['element_'.$value])){ + $element_info[$value]['existing_file'] = $row['element_'.$value]; + } + } + } + + //pick user input + $user_input = array(); + foreach ($element_to_get as $element_name){ + $user_input[$element_name] = @$input[$element_name]; + } + + + $error_elements = array(); + $table_data = array(); + //validate input based on rules specified for each field + foreach ($user_input as $element_name=>$element_data){ + + //get element_id from element_name + $exploded = array(); + $exploded = explode('_',$element_name); + $element_id = $exploded[1]; + + $rules = array(); + $target_input = array(); + + $element_type = $element_info[$element_id]['type']; + + + //if this is private fields and not logged-in as admin, bypass operation below, just supply the default value if any + if(($element_info[$element_id]['is_private'] == 1) && empty($_SESSION['logged_in'])){ + if(!empty($element_info[$element_id]['default_value'])){ + $table_data['element_'.$element_id] = $element_info[$element_id]['default_value']; + } + continue; + } + + + if('text' == $element_type){ //Single Line Text + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + } + + if($element_info[$element_id]['is_unique']){ + $rules[$element_name]['unique'] = $form_id.'#'.$element_name; + } + + $rules[$element_name]['max'] = 255; + + $target_input[$element_name] = $element_data; + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($element_data); + + //prepare data for table column + $table_data[$element_name] = $element_data; + + }elseif ('textarea' == $element_type){ //Paragraph + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + } + + if($element_info[$element_id]['is_unique']){ + $rules[$element_name]['unique'] = $form_id.'#'.$element_name; + } + + $target_input[$element_name] = $element_data; + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($element_data); + + //prepare data for table column + $table_data[$element_name] = $element_data; + + }elseif ('radio' == $element_type){ //Multiple Choice + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + } + + $target_input[$element_name] = $element_data; + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = $element_data; + + //prepare data for table column + $table_data[$element_name] = $element_data; + + }elseif ('number' == $element_type){ //Number + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + } + + if($element_info[$element_id]['is_unique']){ + $rules[$element_name]['unique'] = $form_id.'#'.$element_name; + } + + //check for numeric if not empty + if(!empty($user_input[$element_name])){ + $rules[$element_name]['numeric'] = true; + } + + $target_input[$element_name] = $element_data; + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = $element_data; + + //prepare data for table column + $table_data[$element_name] = $element_data; + + }elseif ('url' == $element_type){ //Website + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + } + + if($element_info[$element_id]['is_unique']){ + $rules[$element_name]['unique'] = $form_id.'#'.$element_name; + } + + $rules[$element_name]['website'] = true; + + if($element_data == 'http://'){ + $element_data = ''; + } + + $target_input[$element_name] = $element_data; + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($element_data); + + //prepare data for table column + $table_data[$element_name] = $element_data; + + }elseif ('email' == $element_type){ //Email + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + } + + if($element_info[$element_id]['is_unique']){ + $rules[$element_name]['unique'] = $form_id.'#'.$element_name; + } + + $rules[$element_name]['email'] = true; + + + $target_input[$element_name] = $element_data; + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($element_data); + + //prepare data for table column + $table_data[$element_name] = $element_data; + + }elseif ('simple_name' == $element_type){ //Simple Name + + if(!empty($processed_elements) && is_array($processed_elements) && in_array($element_name,$processed_elements)){ + continue; + } + + //compound element, grab the other element, 2 elements total + $element_name_2 = substr($element_name,0,-1).'2'; + + $processed_elements[] = $element_name_2; //put this element into array so that it won't be processed on next loop + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + $rules[$element_name_2]['required'] = true; + } + + $target_input[$element_name] = $user_input[$element_name]; + $target_input[$element_name_2] = $user_input[$element_name_2]; + + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($user_input[$element_name]); + $form_data[$element_name_2]['default_value'] = htmlspecialchars($user_input[$element_name_2]); + + //prepare data for table column + $table_data[$element_name] = $user_input[$element_name]; + $table_data[$element_name_2] = $user_input[$element_name_2]; + + }elseif ('name' == $element_type){ //Name - Extended + + if(!empty($processed_elements) && is_array($processed_elements) && in_array($element_name,$processed_elements)){ + continue; + } + + //compound element, grab the other element, 4 elements total + //only element no 2&3 matters (first and last name) + $element_name_2 = substr($element_name,0,-1).'2'; + $element_name_3 = substr($element_name,0,-1).'3'; + $element_name_4 = substr($element_name,0,-1).'4'; + + $processed_elements[] = $element_name_2; //put this element into array so that it won't be processed next + $processed_elements[] = $element_name_3; + $processed_elements[] = $element_name_4; + + if($element_info[$element_id]['is_required']){ + $rules[$element_name_2]['required'] = true; + $rules[$element_name_3]['required'] = true; + } + + $target_input[$element_name_2] = $user_input[$element_name_2]; + $target_input[$element_name_3] = $user_input[$element_name_3]; + + + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($user_input[$element_name]); + $form_data[$element_name_2]['default_value'] = htmlspecialchars($user_input[$element_name_2]); + $form_data[$element_name_3]['default_value'] = htmlspecialchars($user_input[$element_name_3]); + $form_data[$element_name_4]['default_value'] = htmlspecialchars($user_input[$element_name_4]); + + //prepare data for table column + $table_data[$element_name] = $user_input[$element_name]; + $table_data[$element_name_2] = $user_input[$element_name_2]; + $table_data[$element_name_3] = $user_input[$element_name_3]; + $table_data[$element_name_4] = $user_input[$element_name_4]; + + }elseif ('time' == $element_type){ //Time + + if(!empty($processed_elements) && is_array($processed_elements) && in_array($element_name,$processed_elements)){ + continue; + } + + //compound element, grab the other element, 4 elements total + + $element_name_2 = substr($element_name,0,-1).'2'; + $element_name_3 = substr($element_name,0,-1).'3'; + $element_name_4 = substr($element_name,0,-1).'4'; + + $processed_elements[] = $element_name_2; //put this element into array so that it won't be processed next + $processed_elements[] = $element_name_3; + $processed_elements[] = $element_name_4; + + if($element_info[$element_id]['is_required']){ + $rules[$element_name_2]['required'] = true; + $rules[$element_name_3]['required'] = true; + $rules[$element_name_4]['required'] = true; + } + + //check time validity if any of the compound field entered + $time_entry_exist = false; + if(!empty($user_input[$element_name]) || !empty($user_input[$element_name_2]) || !empty($user_input[$element_name_3])){ + $rules['element_time']['time'] = true; + $time_entry_exist = true; + } + + if($time_entry_exist && empty($element_info[$element_id]['constraint'])){ + $user_input[$element_name_3] = '00'; + } + + if($element_info[$element_id]['is_unique']){ + $rules['element_time_no_meridiem']['unique'] = $form_id.'#'.substr($element_name,0,-2); //to check uniquenes we need to use 24 hours HH:MM:SS format + } + + $target_input[$element_name_2] = $user_input[$element_name_2]; + $target_input[$element_name_3] = $user_input[$element_name_3]; + $target_input[$element_name_4] = $user_input[$element_name_4]; + if($time_entry_exist){ + $target_input['element_time'] = $user_input[$element_name].':'.$user_input[$element_name_2].':'.$user_input[$element_name_3].' '.$user_input[$element_name_4]; + $target_input['element_time_no_meridiem'] = @date("G:i:s",strtotime($target_input['element_time'])); + } + + + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($user_input[$element_name]); + $form_data[$element_name_2]['default_value'] = htmlspecialchars($user_input[$element_name_2]); + $form_data[$element_name_3]['default_value'] = htmlspecialchars($user_input[$element_name_3]); + $form_data[$element_name_4]['default_value'] = htmlspecialchars($user_input[$element_name_4]); + + //prepare data for table column + $table_data[substr($element_name,0,-2)] = @$target_input['element_time_no_meridiem']; + + }elseif ('address' == $element_type){ //Address + + if(!empty($processed_elements) && is_array($processed_elements) && in_array($element_name,$processed_elements)){ + continue; + } + + //compound element, grab the other element, 6 elements total, element #2 (address line 2) is optional + $element_name_2 = substr($element_name,0,-1).'2'; + $element_name_3 = substr($element_name,0,-1).'3'; + $element_name_4 = substr($element_name,0,-1).'4'; + $element_name_5 = substr($element_name,0,-1).'5'; + $element_name_6 = substr($element_name,0,-1).'6'; + + $processed_elements[] = $element_name_2; //put this element into array so that it won't be processed next + $processed_elements[] = $element_name_3; + $processed_elements[] = $element_name_4; + $processed_elements[] = $element_name_5; + $processed_elements[] = $element_name_6; + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + $rules[$element_name_3]['required'] = true; + $rules[$element_name_4]['required'] = true; + $rules[$element_name_5]['required'] = true; + $rules[$element_name_6]['required'] = true; + + } + + $target_input[$element_name] = $user_input[$element_name]; + $target_input[$element_name_3] = $user_input[$element_name_3]; + $target_input[$element_name_4] = $user_input[$element_name_4]; + $target_input[$element_name_5] = $user_input[$element_name_5]; + $target_input[$element_name_6] = $user_input[$element_name_6]; + + + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($user_input[$element_name]); + $form_data[$element_name_2]['default_value'] = htmlspecialchars($user_input[$element_name_2]); + $form_data[$element_name_3]['default_value'] = htmlspecialchars($user_input[$element_name_3]); + $form_data[$element_name_4]['default_value'] = htmlspecialchars($user_input[$element_name_4]); + $form_data[$element_name_5]['default_value'] = htmlspecialchars($user_input[$element_name_5]); + $form_data[$element_name_6]['default_value'] = htmlspecialchars($user_input[$element_name_6]); + + //prepare data for table column + $table_data[$element_name] = $user_input[$element_name]; + $table_data[$element_name_2] = $user_input[$element_name_2]; + $table_data[$element_name_3] = $user_input[$element_name_3]; + $table_data[$element_name_4] = $user_input[$element_name_4]; + $table_data[$element_name_5] = $user_input[$element_name_5]; + $table_data[$element_name_6] = $user_input[$element_name_6]; + + }elseif ('money' == $element_type){ //Price + + if(!empty($processed_elements) && is_array($processed_elements) && in_array($element_name,$processed_elements)){ + continue; + } + + //compound element, grab the other element, 2 elements total (for currency other than yen) + if($element_info[$element_id]['constraint'] != 'yen'){ //if other than yen + $base_element_name = substr($element_name,0,-1); + $element_name_2 = $base_element_name.'2'; + $processed_elements[] = $element_name_2; + + if($element_info[$element_id]['is_required']){ + $rules[$base_element_name]['required'] = true; + } + + //check for numeric if not empty + if(!empty($user_input[$element_name]) || !empty($user_input[$element_name_2])){ + $rules[$base_element_name]['numeric'] = true; + } + + if($element_info[$element_id]['is_unique']){ + $rules[$base_element_name]['unique'] = $form_id.'#'.substr($element_name,0,-2); + } + + $target_input[$base_element_name] = $user_input[$element_name].'.'.$user_input[$element_name_2]; //join dollar+cent + if($target_input[$base_element_name] == '.'){ + $target_input[$base_element_name] = ''; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($user_input[$element_name]); + $form_data[$element_name_2]['default_value'] = htmlspecialchars($user_input[$element_name_2]); + + //prepare data for table column + if(!empty($user_input[$element_name]) || !empty($user_input[$element_name_2]) + || $user_input[$element_name] === '0' || $user_input[$element_name_2] === '0'){ + $table_data[substr($element_name,0,-2)] = $user_input[$element_name].'.'.$user_input[$element_name_2]; + } + }else{ + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + } + + //check for numeric if not empty + if(!empty($user_input[$element_name])){ + $rules[$element_name]['numeric'] = true; + } + + if($element_info[$element_id]['is_unique']){ + $rules[$element_name]['unique'] = $form_id.'#'.$element_name; + } + + $target_input[$element_name] = $user_input[$element_name]; + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($user_input[$element_name]); + + //prepare data for table column + $table_data[$element_name] = $user_input[$element_name]; + + } + + + + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + }elseif ('checkbox' == $element_type){ //Checkboxes + if(!empty($processed_elements) && is_array($processed_elements) && in_array($element_name,$processed_elements)){ + continue; + } + + if($element_info[$element_id]['is_required']){ + //checking 'required' for checkboxes is more complex + //we need to get total child, and join it into one element + //only one element is required to be checked + $all_child_array = array(); + $all_child_array = $checkbox_childs[$element_id]; + $base_element_name = 'element_' . $element_id . '_'; + + $all_checkbox_value = ''; + foreach ($all_child_array as $i){ + $all_checkbox_value .= $user_input[$base_element_name.$i]; + $processed_elements[] = $base_element_name.$i; + + //save old data into array, for form redisplay in case errors occured + $form_data[$base_element_name.$i]['default_value'] = $user_input[$base_element_name.$i]; + + //prepare data for table column + $table_data[$base_element_name.$i] = $user_input[$base_element_name.$i]; + + } + + $rules[$base_element_name]['required'] = true; + + $target_input[$base_element_name] = $all_checkbox_value; + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + }else{ //if not required, we only need to capture all data + $all_child_array = array(); + $base_exploded = array(); + $all_child_array = $checkbox_childs[$element_id]; + + $base_exploded = explode("_",$element_name); + $base_element_name = "element_".$base_exploded[1]."_"; + + + foreach ($all_child_array as $i){ + + //save old data into array, for form redisplay in case errors occured + $form_data[$base_element_name.$i]['default_value'] = $user_input[$base_element_name.$i]; + + //prepare data for table column + $table_data[$base_element_name.$i] = $user_input[$base_element_name.$i]; + } + + } + }elseif ('select' == $element_type){ //Drop Down + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + } + + $target_input[$element_name] = $element_data; + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = $user_input[$element_name]; + + //prepare data for table column + $table_data[$element_name] = $user_input[$element_name]; + + }elseif ('date' == $element_type || 'europe_date' == $element_type){ //Date + + if(!empty($processed_elements) && is_array($processed_elements) && in_array($element_name,$processed_elements)){ + continue; + } + + //compound element, grab the other element, 3 elements total + + $element_name_2 = substr($element_name,0,-1).'2'; + $element_name_3 = substr($element_name,0,-1).'3'; + + $processed_elements[] = $element_name_2; //put this element into array so that it won't be processed next + $processed_elements[] = $element_name_3; + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + $rules[$element_name_2]['required'] = true; + $rules[$element_name_3]['required'] = true; + } + + $rules['element_date']['date'] = 'yyyy/mm/dd'; + + if($element_info[$element_id]['is_unique']){ + $rules['element_date']['unique'] = $form_id.'#'.substr($element_name,0,-2); + } + + $target_input[$element_name] = $user_input[$element_name]; + $target_input[$element_name_2] = $user_input[$element_name_2]; + $target_input[$element_name_3] = $user_input[$element_name_3]; + + $base_element_name = substr($element_name,0,-2); + if('date' == $element_type){ //MM/DD/YYYY + $target_input['element_date'] = $user_input[$element_name_3].'-'.$user_input[$element_name].'-'.$user_input[$element_name_2]; + + //prepare data for table column + $table_data[$base_element_name] = $user_input[$element_name_3].'-'.$user_input[$element_name].'-'.$user_input[$element_name_2]; + }else{ //DD/MM/YYYY + $target_input['element_date'] = $user_input[$element_name_3].'-'.$user_input[$element_name_2].'-'.$user_input[$element_name]; + + //prepare data for table column + $table_data[$base_element_name] = $user_input[$element_name_3].'-'.$user_input[$element_name_2].'-'.$user_input[$element_name]; + } + + $test_empty = str_replace('-','',$target_input['element_date']); //if user not submitting any entry, remove the dashes + if(empty($test_empty)){ + unset($target_input['element_date']); + $table_data[$base_element_name] = ''; + } + + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($user_input[$element_name]); + $form_data[$element_name_2]['default_value'] = htmlspecialchars($user_input[$element_name_2]); + $form_data[$element_name_3]['default_value'] = htmlspecialchars($user_input[$element_name_3]); + + }elseif ('simple_phone' == $element_type){ //Simple Phone + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + } + + if(!empty($user_input[$element_name])){ + $rules[$element_name]['simple_phone'] = true; + } + + if($element_info[$element_id]['is_unique']){ + $rules[$element_name]['unique'] = $form_id.'#'.$element_name; + } + + $target_input[$element_name] = $user_input[$element_name]; + + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($user_input[$element_name]); + + //prepare data for table column + $table_data[$element_name] = $user_input[$element_name]; + + }elseif ('phone' == $element_type){ //Phone - US format + + if(!empty($processed_elements) && is_array($processed_elements) && in_array($element_name,$processed_elements)){ + continue; + } + + //compound element, grab the other element, 3 elements total + + $element_name_2 = substr($element_name,0,-1).'2'; + $element_name_3 = substr($element_name,0,-1).'3'; + + $processed_elements[] = $element_name_2; //put this element into array so that it won't be processed next + $processed_elements[] = $element_name_3; + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + $rules[$element_name_2]['required'] = true; + $rules[$element_name_3]['required'] = true; + } + + $rules['element_phone']['phone'] = true; + + + if($element_info[$element_id]['is_unique']){ + $rules['element_phone']['unique'] = $form_id.'#'.substr($element_name,0,-2); + } + + $target_input[$element_name] = $user_input[$element_name]; + $target_input[$element_name_2] = $user_input[$element_name_2]; + $target_input[$element_name_3] = $user_input[$element_name_3]; + $target_input['element_phone'] = $user_input[$element_name].$user_input[$element_name_2].$user_input[$element_name_3]; + + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($user_input[$element_name]); + $form_data[$element_name_2]['default_value'] = htmlspecialchars($user_input[$element_name_2]); + $form_data[$element_name_3]['default_value'] = htmlspecialchars($user_input[$element_name_3]); + + //prepare data for table column + $table_data[substr($element_name,0,-2)] = $user_input[$element_name].$user_input[$element_name_2].$user_input[$element_name_3]; + + }elseif ('email' == $element_type){ //Email + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + } + + if($element_info[$element_id]['is_unique']){ + $rules[$element_name]['unique'] = $form_id.'#'.$element_name; + } + + $rules[$element_name]['email'] = true; + + $target_input[$element_name] = $element_data; + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($user_input[$element_name]); + + //prepare data for table column + $table_data[$element_name] = $user_input[$element_name]; + + }elseif ('file' == $element_type){ //File + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required_file'] = true; + $rules[$element_name]['filetype'] = true; + + //if form review enabled, and user pressed back button after going to review page + //disable the required file checking if file already uploaded + if(!empty($_SESSION['review_id'])){ + if(!empty($element_info[$element_id]['existing_file'])){ + unset($rules[$element_name]['required_file']); + unset($rules[$element_name]['filetype']); + } + } + }else{ + if($_FILES[$element_name]['size'] > 0){ + $rules[$element_name]['filetype'] = true; + } + } + + $target_input[$element_name] = $element_name; //special for file, only need to pass input name + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + }else{ + //if validation passed, store uploaded file info into array + if($_FILES[$element_name]['size'] > 0){ + $uploaded_files[] = $element_name; + } + } + + + } + + } + + + + //get form redirect info, if any + //get form properties data + $query = "select + form_redirect, + form_email, + form_unique_ip, + form_captcha, + form_review, + esl_from_name, + esl_from_email_address, + esl_subject, + esl_content, + esl_plain_text, + esr_email_address, + esr_from_name, + esr_from_email_address, + esr_subject, + esr_content, + esr_plain_text + from + `ap_forms` + where + form_id='$form_id'"; + + $result = do_query($query); + $row = do_fetch_result($result); + $form_redirect = $row['form_redirect']; + $form_unique_ip = $row['form_unique_ip']; + $form_email = $row['form_email']; + $form_captcha = $row['form_captcha']; + $form_review = $row['form_review']; + $user_ip_address = $_SERVER['REMOTE_ADDR']; + + $esl_from_name = $row['esl_from_name']; + $esl_from_email_address = $row['esl_from_email_address']; + $esl_subject = $row['esl_subject']; + $esl_content = $row['esl_content']; + $esl_plain_text = $row['esl_plain_text']; + + $esr_email_address = $row['esr_email_address']; + $esr_from_name = $row['esr_from_name']; + $esr_from_email_address = $row['esr_from_email_address']; + $esr_subject = $row['esr_subject']; + $esr_content = $row['esr_content']; + $esr_plain_text = $row['esr_plain_text']; + + $process_result['form_redirect'] = $form_redirect; + $process_result['old_values'] = $form_data; + $process_result['error_elements'] = $error_elements; + + //check for ip address + if(!empty($form_unique_ip)){ + //if ip address checking enabled, compare user ip address with value in db + $query = "select count(id) total_ip from `ap_form_{$form_id}` where ip_address='$user_ip_address'"; + $result = do_query($query); + $row = do_fetch_result($result); + if(!empty($row['total_ip'])){ + $process_result['custom_error'] = 'Sorry, but this form is limited to one submission per user.'; + } + } + + //check for captcha if enabled and there is no errors from previous fields + if(!empty($form_captcha) && empty($error_elements)){ + + if(USE_INTERNAL_CAPTCHA === true){//if internal captcha is being used + if(!empty($_POST['captcha_response_field'])){ + $captcha_response_field = trim($_POST['captcha_response_field']); + if (PhpCaptcha::Validate($captcha_response_field) !== true) { + $error_elements['element_captcha'] = 'incorrect-captcha-sol'; + $process_result['error_elements'] = $error_elements; + } + }else{ //user not entered the words at all + $error_elements['element_captcha'] = 'el-required'; + $process_result['error_elements'] = $error_elements; + } + }else{ //otherwise reCaptcha is being used + if(!empty($_POST['recaptcha_response_field'])){ + $recaptcha_response = recaptcha_check_answer (RECAPTCHA_PRIVATE_KEY, + $user_ip_address, + $_POST["recaptcha_challenge_field"], + $_POST["recaptcha_response_field"]); + + if($recaptcha_response !== false){ //if false, then we can't connect to captcha server, bypass captcha checking + if ($recaptcha_response->is_valid === false) { + $error_elements['element_captcha'] = $recaptcha_response->error; + $process_result['error_elements'] = $error_elements; + } + } + }else{ //user not entered the words at all + $error_elements['element_captcha'] = 'el-required'; + $process_result['error_elements'] = $error_elements; + } + } + + } + + + //insert ip address and date created + $table_data['ip_address'] = $user_ip_address; + $table_data['date_created'] = date("Y-m-d H:i:s"); + + $is_inserted = false; + + //start insert data into table ---------------------- + //dynamically create the field list and field values, based on the input given + if(!empty($table_data) && empty($error_elements) && empty($process_result['custom_error'])){ + $has_value = false; + + $field_list = ''; + $field_values = ''; + + foreach ($table_data as $key=>$value){ + + if($value == ''){ //don't insert blank entry + continue; + } + $value = mysql_real_escape_string($value); + $field_list .= "`$key`,"; + $field_values .= "'$value',"; + + if(!empty($value)){ + $has_value = true; + } + } + + //add session_id to query if 'form review' enabled + if(!empty($form_review)){ + //save previously uploaded file list, so users don't need to reupload files + //get all file uploads elements first + + if(!empty($_SESSION['review_id'])){ + + $query = "SELECT + element_id + FROM + ap_form_elements + WHERE + form_id='{$form_id}' AND + element_type='file' AND + element_is_private=0"; + $result = do_query($query); + $file_uploads_array = array(); + while($row = do_fetch_result($result)){ + $file_uploads_array[] = 'element_'.$row['element_id']; + } + + $file_uploads_column = implode('`,`',$file_uploads_array); + $file_uploads_column = '`'.$file_uploads_column.'`'; + + if(!empty($file_uploads_array)){ + $query = "SELECT {$file_uploads_column} FROM `ap_form_{$form_id}_review` where id='{$_SESSION['review_id']}'"; + $result = do_query($query); + $row = do_fetch_result($result); + foreach ($file_uploads_array as $element_name){ + if(!empty($row[$element_name])){ + $uploaded_file_lookup[$element_name] = $row[$element_name]; + } + } + } + } + + + //add session_id to query if 'form review' enabled + $session_id = session_id(); + + do_query("DELETE FROM `ap_form_{$form_id}_review` where session_id='{$session_id}'"); + + $field_list .= "`session_id`,"; + $field_values .= "'{$session_id}',"; + } + + + if($has_value){ //if blank form submitted, dont insert anything + + //start insert query ---------------------------------------- + $field_list = substr($field_list,0,-1); + $field_values = substr($field_values,0,-1); + + if(empty($form_review)){ + $query = "INSERT INTO `ap_form_{$form_id}` ($field_list) VALUES ($field_values);"; + }else{ //insert to temporary table, if form review is enabled + $query = "INSERT INTO `ap_form_{$form_id}_review` ($field_list) VALUES ($field_values);"; + } + + do_query($query); + + $record_insert_id = mysql_insert_id(); + //end insert query ------------------------------------------ + + $is_inserted = true; + } + } + //end insert data into table ------------------------- + + //upload the files + if(!empty($record_insert_id)){ + if(!empty($uploaded_files)){ + foreach ($uploaded_files as $element_name){ + $file_token = md5(uniqid(rand(), true)); //add random token to uploaded filename, to increase security + + if(empty($form_review)){ + //move file and check for invalid file + $destination_file = $input['machform_data_path'].UPLOAD_DIR."/form_{$form_id}/files/{$element_name}_{$file_token}-{$record_insert_id}-{$_FILES[$element_name]['name']}"; + if (move_uploaded_file($_FILES[$element_name]['tmp_name'], $destination_file)) { + $filename = mysql_real_escape_string($_FILES[$element_name]['name']); + $query = "update ap_form_{$form_id} set $element_name='{$element_name}_{$file_token}-{$record_insert_id}-{$filename}' where id='$record_insert_id'"; + do_query($query); + } + }else{ + //for form with review enabled, append .tmp suffix to all uploaded files + //move file and check for invalid file + $destination_file = $input['machform_data_path'].UPLOAD_DIR."/form_{$form_id}/files/{$element_name}_{$file_token}-{$record_insert_id}-{$_FILES[$element_name]['name']}.tmp"; + if (move_uploaded_file($_FILES[$element_name]['tmp_name'], $destination_file)) { + $filename = mysql_real_escape_string($_FILES[$element_name]['name']); + $query = "update ap_form_{$form_id}_review set $element_name='{$element_name}_{$file_token}-{$record_insert_id}-{$filename}' where id='$record_insert_id'"; + do_query($query); + } + + if(!empty($uploaded_file_lookup[$element_name])){ + unset($uploaded_file_lookup[$element_name]); + } + } + } + } + + //update the previouly uploaded file to the current record + if(!empty($form_review) && !empty($uploaded_file_lookup)){ + //update the database record + $update_clause = ''; + foreach ($uploaded_file_lookup as $element_name=>$filename){ + $update_clause .= "`{$element_name}`='{$filename}',"; + } + $update_clause = rtrim($update_clause,","); + do_query("UPDATE `ap_form_{$form_id}_review` SET {$update_clause} WHERE id='{$record_insert_id}'"); + } + } + + + //start sending notification email to admin ------------------------------------------ + if($is_inserted && !empty($form_email) && empty($form_review)){ + //get parameters for the email + + //from name + if(!empty($esl_from_name)){ + $admin_email_param['from_name'] = $esl_from_name; + }elseif (NOTIFICATION_MAIL_FROM_NAME != ''){ + $admin_email_param['from_name'] = NOTIFICATION_MAIL_FROM_NAME; + }else{ + $admin_email_param['from_name'] = 'MachForm'; + } + + //from email address + if(!empty($esl_from_email_address)){ + if(is_numeric($esl_from_email_address)){ + $admin_email_param['from_email'] = '{element_'.$esl_from_email_address.'}'; + }else{ + $admin_email_param['from_email'] = $esl_from_email_address; + } + }elseif(NOTIFICATION_MAIL_FROM != ''){ + $admin_email_param['from_email'] = NOTIFICATION_MAIL_FROM; + }else{ + $domain = str_replace('www.','',$_SERVER['SERVER_NAME']); + $admin_email_param['from_email'] = "no-reply@{$domain}"; + } + + //subject + if(!empty($esl_subject)){ + $admin_email_param['subject'] = $esl_subject; + }elseif (NOTIFICATION_MAIL_SUBJECT != ''){ + $admin_email_param['subject'] = NOTIFICATION_MAIL_SUBJECT; + }else{ + $admin_email_param['subject'] = '{form_name} [#{entry_no}]'; + } + + //content + if(!empty($esl_content)){ + $admin_email_param['content'] = $esl_content; + }else{ + $admin_email_param['content'] = '{entry_data}'; + } + + $admin_email_param['as_plain_text'] = $esl_plain_text; + $admin_email_param['target_is_admin'] = true; + $admin_email_param['machform_base_path'] = $input['machform_base_path']; + send_notification($form_id,$record_insert_id,$form_email,$admin_email_param); + + } + //end emailing notifications to admin ---------------------------------------------- + + + //start sending notification email to user ------------------------------------------ + if($is_inserted && !empty($esr_email_address) && empty($form_review)){ + //get parameters for the email + + //to email + if(is_numeric($esr_email_address)){ + $esr_email_address = '{element_'.$esr_email_address.'}'; + } + + //from name + if(!empty($esr_from_name)){ + $user_email_param['from_name'] = $esr_from_name; + }elseif (NOTIFICATION_MAIL_FROM_NAME != ''){ + $user_email_param['from_name'] = NOTIFICATION_MAIL_FROM_NAME; + }else{ + $user_email_param['from_name'] = 'MachForm'; + } + + //from email address + if(!empty($esr_from_email_address)){ + if(is_numeric($esr_from_email_address)){ + $user_email_param['from_email'] = '{element_'.$esr_from_email_address.'}'; + }else{ + $user_email_param['from_email'] = $esr_from_email_address; + } + }elseif(NOTIFICATION_MAIL_FROM != ''){ + $user_email_param['from_email'] = NOTIFICATION_MAIL_FROM; + }else{ + $domain = str_replace('www.','',$_SERVER['SERVER_NAME']); + $user_email_param['from_email'] = "no-reply@{$domain}"; + } + + //subject + if(!empty($esr_subject)){ + $user_email_param['subject'] = $esr_subject; + }elseif (NOTIFICATION_MAIL_SUBJECT != ''){ + $user_email_param['subject'] = NOTIFICATION_MAIL_SUBJECT; + }else{ + $user_email_param['subject'] = '{form_name} - Receipt'; + } + + //content + if(!empty($esr_content)){ + $user_email_param['content'] = $esr_content; + }else{ + $user_email_param['content'] = '{entry_data}'; + } + + $user_email_param['as_plain_text'] = $esr_plain_text; + $user_email_param['target_is_admin'] = false; + + send_notification($form_id,$record_insert_id,$esr_email_address,$user_email_param); + } + //end emailing notifications to user ---------------------------------------------- + + + //if there is any error message or elements, send false as status + if(empty($error_elements) && empty($process_result['custom_error'])){ + $process_result['status'] = true; + + //if 'form review' enabled, send review_id + if(!empty($form_review)){ + $process_result['review_id'] = $record_insert_id; + } + }else{ + $process_result['status'] = false; + } + + + return $process_result; + } + + + //similar to above, except this function is being used to update form data + function process_form_update($input){ + + $form_id = (int) trim($input['form_id']); + $entry_id = (int) trim($input['edit_id']); + + global $lang; + + //this function handle password submission and general form submission + if(isset($input['password'])){ //if there is password input, do validation + $query = "select count(form_id) valid_password from `ap_forms` where form_password='{$input['password']}'"; + $result = do_query($query); + $row = do_fetch_result($result); + if(!empty($row['valid_password'])){ + $process_result['status'] = true; + $_SESSION['user_authenticated'] = $form_id; + }else{ + $process_result['status'] = false; + $process_result['custom_error'] = $lang['form_pass_invalid']; + } + + return $process_result; + } + + + $element_child_lookup['address'] = 5; + $element_child_lookup['simple_name'] = 1; + $element_child_lookup['name'] = 3; + $element_child_lookup['phone'] = 2; + $element_child_lookup['date'] = 2; + $element_child_lookup['europe_date'] = 2; + $element_child_lookup['time'] = 3; + $element_child_lookup['money'] = 1; //this applies to dollar,euro and pound. yen don't have child + $element_child_lookup['checkbox'] = 1; //this is just a dumb value + + //never trust user input, get a list of input fields based on info stored on table + //element has real child -> address, simple_name, name + //element has virtual child -> phone, date, europe_date, time, money + + $query = "select + element_id, + element_title, + element_is_required, + element_is_unique, + element_type, + element_constraint, + element_total_child + from + ap_form_elements + where + form_id='$form_id' order by element_id asc"; + + $result = do_query($query); + + $element_to_get = array(); + + while($row = do_fetch_result($result)){ + if($row['element_type'] == 'section'){ + continue; + } + //store element info + $element_info[$row['element_id']]['title'] = $row['element_title']; + $element_info[$row['element_id']]['type'] = $row['element_type']; + $element_info[$row['element_id']]['is_required'] = $row['element_is_required']; + $element_info[$row['element_id']]['is_unique'] = $row['element_is_unique']; + $element_info[$row['element_id']]['constraint'] = $row['element_constraint']; + + //get element form name, complete with the childs + if(empty($element_child_lookup[$row['element_type']]) || ($row['element_constraint'] == 'yen')){ //elements with no child + $element_to_get[] = 'element_'.$row['element_id']; + }else{ //elements with child + if($row['element_type'] != 'checkbox'){ + $max = $element_child_lookup[$row['element_type']] + 1; + + for ($j=1;$j<=$max;$j++){ + $element_to_get[] = "element_{$row['element_id']}_{$j}"; + } + }else{ + //for checkbox, get childs elements from ap_element_options table + $sub_query = "select + option_id + from + ap_element_options + where + form_id='{$form_id}' and element_id='{$row['element_id']}' and live=1 + order by + `position` asc"; + $sub_result = do_query($sub_query); + while($sub_row = do_fetch_result($sub_result)){ + $element_to_get[] = "element_{$row['element_id']}_{$sub_row['option_id']}"; + $checkbox_childs[$row['element_id']][] = $sub_row['option_id']; //store the child into array for further reference + } + + //add base element id for checkbox processing + //add "_" in the end to indicate base element + $element_to_get[] = "element_{$row['element_id']}_"; + } + + + + } + + } + + //pick user input + $user_input = array(); + foreach ($element_to_get as $element_name){ + $user_input[$element_name] = $input[$element_name]; + } + + + $error_elements = array(); + $table_data = array(); + //validate input based on rules specified for each field + foreach ($user_input as $element_name=>$element_data){ + + //get element_id from element_name + $exploded = array(); + $exploded = explode('_',$element_name); + $element_id = $exploded[1]; + + $rules = array(); + $target_input = array(); + + $element_type = $element_info[$element_id]['type']; + + if('text' == $element_type){ //Single Line Text + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + } + + if($element_info[$element_id]['is_unique']){ + $rules[$element_name]['unique'] = $form_id.'#'.$element_name; + } + + $rules[$element_name]['max'] = 255; + + $target_input[$element_name] = $element_data; + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($element_data); + + //prepare data for table column + $table_data[$element_name] = $element_data; + + }elseif ('textarea' == $element_type){ //Paragraph + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + } + + if($element_info[$element_id]['is_unique']){ + $rules[$element_name]['unique'] = $form_id.'#'.$element_name; + } + + $target_input[$element_name] = $element_data; + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($element_data); + + //prepare data for table column + $table_data[$element_name] = $element_data; + + }elseif ('radio' == $element_type){ //Multiple Choice + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + } + + $target_input[$element_name] = $element_data; + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = $element_data; + + //prepare data for table column + $table_data[$element_name] = $element_data; + + }elseif ('number' == $element_type){ //Number + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + } + + if($element_info[$element_id]['is_unique']){ + $rules[$element_name]['unique'] = $form_id.'#'.$element_name; + } + + //check for numeric if not empty + if(!empty($user_input[$element_name])){ + $rules[$element_name]['numeric'] = true; + } + + $target_input[$element_name] = $element_data; + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = $element_data; + + //prepare data for table column + $table_data[$element_name] = $element_data; + + }elseif ('url' == $element_type){ //Website + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + } + + if($element_info[$element_id]['is_unique']){ + $rules[$element_name]['unique'] = $form_id.'#'.$element_name; + } + + $rules[$element_name]['website'] = true; + + if($element_data == 'http://'){ + $element_data = ''; + } + + $target_input[$element_name] = $element_data; + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($element_data); + + //prepare data for table column + $table_data[$element_name] = $element_data; + + }elseif ('email' == $element_type){ //Email + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + } + + if($element_info[$element_id]['is_unique']){ + $rules[$element_name]['unique'] = $form_id.'#'.$element_name; + } + + $rules[$element_name]['email'] = true; + + + $target_input[$element_name] = $element_data; + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($element_data); + + //prepare data for table column + $table_data[$element_name] = $element_data; + + }elseif ('simple_name' == $element_type){ //Simple Name + + if(!empty($processed_elements) && is_array($processed_elements) && in_array($element_name,$processed_elements)){ + continue; + } + + //compound element, grab the other element, 2 elements total + $element_name_2 = substr($element_name,0,-1).'2'; + + $processed_elements[] = $element_name_2; //put this element into array so that it won't be processed on next loop + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + $rules[$element_name_2]['required'] = true; + } + + $target_input[$element_name] = $user_input[$element_name]; + $target_input[$element_name_2] = $user_input[$element_name_2]; + + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($user_input[$element_name]); + $form_data[$element_name_2]['default_value'] = htmlspecialchars($user_input[$element_name_2]); + + //prepare data for table column + $table_data[$element_name] = $user_input[$element_name]; + $table_data[$element_name_2] = $user_input[$element_name_2]; + + }elseif ('name' == $element_type){ //Name - Extended + + if(!empty($processed_elements) && is_array($processed_elements) && in_array($element_name,$processed_elements)){ + continue; + } + + //compound element, grab the other element, 4 elements total + //only element no 2&3 matters (first and last name) + $element_name_2 = substr($element_name,0,-1).'2'; + $element_name_3 = substr($element_name,0,-1).'3'; + $element_name_4 = substr($element_name,0,-1).'4'; + + $processed_elements[] = $element_name_2; //put this element into array so that it won't be processed next + $processed_elements[] = $element_name_3; + $processed_elements[] = $element_name_4; + + if($element_info[$element_id]['is_required']){ + $rules[$element_name_2]['required'] = true; + $rules[$element_name_3]['required'] = true; + } + + $target_input[$element_name_2] = $user_input[$element_name_2]; + $target_input[$element_name_3] = $user_input[$element_name_3]; + + + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($user_input[$element_name]); + $form_data[$element_name_2]['default_value'] = htmlspecialchars($user_input[$element_name_2]); + $form_data[$element_name_3]['default_value'] = htmlspecialchars($user_input[$element_name_3]); + $form_data[$element_name_4]['default_value'] = htmlspecialchars($user_input[$element_name_4]); + + //prepare data for table column + $table_data[$element_name] = $user_input[$element_name]; + $table_data[$element_name_2] = $user_input[$element_name_2]; + $table_data[$element_name_3] = $user_input[$element_name_3]; + $table_data[$element_name_4] = $user_input[$element_name_4]; + + }elseif ('time' == $element_type){ //Time + + if(!empty($processed_elements) && is_array($processed_elements) && in_array($element_name,$processed_elements)){ + continue; + } + + //compound element, grab the other element, 4 elements total + + $element_name_2 = substr($element_name,0,-1).'2'; + $element_name_3 = substr($element_name,0,-1).'3'; + $element_name_4 = substr($element_name,0,-1).'4'; + + $processed_elements[] = $element_name_2; //put this element into array so that it won't be processed next + $processed_elements[] = $element_name_3; + $processed_elements[] = $element_name_4; + + if($element_info[$element_id]['is_required']){ + $rules[$element_name_2]['required'] = true; + $rules[$element_name_3]['required'] = true; + $rules[$element_name_4]['required'] = true; + } + + //check time validity if any of the compound field entered + $time_entry_exist = false; + if(!empty($user_input[$element_name]) || !empty($user_input[$element_name_2]) || !empty($user_input[$element_name_3])){ + $rules['element_time']['time'] = true; + $time_entry_exist = true; + } + + if($time_entry_exist && empty($element_info[$element_id]['constraint'])){ + $user_input[$element_name_3] = '00'; + } + + if($element_info[$element_id]['is_unique']){ + $rules['element_time_no_meridiem']['unique'] = $form_id.'#'.substr($element_name,0,-2); //to check uniquenes we need to use 24 hours HH:MM:SS format + } + + $target_input[$element_name_2] = $user_input[$element_name_2]; + $target_input[$element_name_3] = $user_input[$element_name_3]; + $target_input[$element_name_4] = $user_input[$element_name_4]; + if($time_entry_exist){ + $target_input['element_time'] = $user_input[$element_name].':'.$user_input[$element_name_2].':'.$user_input[$element_name_3].' '.$user_input[$element_name_4]; + $target_input['element_time_no_meridiem'] = @date("G:i:s",strtotime($target_input['element_time'])); + } + + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($user_input[$element_name]); + $form_data[$element_name_2]['default_value'] = htmlspecialchars($user_input[$element_name_2]); + $form_data[$element_name_3]['default_value'] = htmlspecialchars($user_input[$element_name_3]); + $form_data[$element_name_4]['default_value'] = htmlspecialchars($user_input[$element_name_4]); + + //prepare data for table column + $table_data[substr($element_name,0,-2)] = $target_input['element_time_no_meridiem']; + + }elseif ('address' == $element_type){ //Address + + if(!empty($processed_elements) && is_array($processed_elements) && in_array($element_name,$processed_elements)){ + continue; + } + + //compound element, grab the other element, 6 elements total, element #2 (address line 2) is optional + $element_name_2 = substr($element_name,0,-1).'2'; + $element_name_3 = substr($element_name,0,-1).'3'; + $element_name_4 = substr($element_name,0,-1).'4'; + $element_name_5 = substr($element_name,0,-1).'5'; + $element_name_6 = substr($element_name,0,-1).'6'; + + $processed_elements[] = $element_name_2; //put this element into array so that it won't be processed next + $processed_elements[] = $element_name_3; + $processed_elements[] = $element_name_4; + $processed_elements[] = $element_name_5; + $processed_elements[] = $element_name_6; + + if($element_info[$element_id]['is_required']){ + $rules[$element_name_3]['required'] = true; + $rules[$element_name_4]['required'] = true; + $rules[$element_name_5]['required'] = true; + $rules[$element_name_6]['required'] = true; + + } + + $target_input[$element_name_3] = $user_input[$element_name_3]; + $target_input[$element_name_4] = $user_input[$element_name_4]; + $target_input[$element_name_5] = $user_input[$element_name_5]; + $target_input[$element_name_6] = $user_input[$element_name_6]; + + + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($user_input[$element_name]); + $form_data[$element_name_2]['default_value'] = htmlspecialchars($user_input[$element_name_2]); + $form_data[$element_name_3]['default_value'] = htmlspecialchars($user_input[$element_name_3]); + $form_data[$element_name_4]['default_value'] = htmlspecialchars($user_input[$element_name_4]); + $form_data[$element_name_5]['default_value'] = htmlspecialchars($user_input[$element_name_5]); + $form_data[$element_name_6]['default_value'] = htmlspecialchars($user_input[$element_name_6]); + + //prepare data for table column + $table_data[$element_name] = $user_input[$element_name]; + $table_data[$element_name_2] = $user_input[$element_name_2]; + $table_data[$element_name_3] = $user_input[$element_name_3]; + $table_data[$element_name_4] = $user_input[$element_name_4]; + $table_data[$element_name_5] = $user_input[$element_name_5]; + $table_data[$element_name_6] = $user_input[$element_name_6]; + + }elseif ('money' == $element_type){ //Price + + if(!empty($processed_elements) && is_array($processed_elements) && in_array($element_name,$processed_elements)){ + continue; + } + + //compound element, grab the other element, 2 elements total (for currency other than yen) + if($element_info[$element_id]['constraint'] != 'yen'){ //if other than yen + $base_element_name = substr($element_name,0,-1); + $element_name_2 = $base_element_name.'2'; + $processed_elements[] = $element_name_2; + + if($element_info[$element_id]['is_required']){ + $rules[$base_element_name]['required'] = true; + } + + //check for numeric if not empty + if(!empty($user_input[$element_name]) || !empty($user_input[$element_name_2])){ + $rules[$base_element_name]['numeric'] = true; + } + + if($element_info[$element_id]['is_unique']){ + $rules[$base_element_name]['unique'] = $form_id.'#'.substr($element_name,0,-2); + } + + $target_input[$base_element_name] = $user_input[$element_name].'.'.$user_input[$element_name_2]; //join dollar+cent + if($target_input[$base_element_name] == '.'){ + $target_input[$base_element_name] = ''; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($user_input[$element_name]); + $form_data[$element_name_2]['default_value'] = htmlspecialchars($user_input[$element_name_2]); + + //prepare data for table column + if(!empty($user_input[$element_name]) || !empty($user_input[$element_name_2])){ + $table_data[substr($element_name,0,-2)] = $user_input[$element_name].'.'.$user_input[$element_name_2]; + } + }else{ + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + } + + //check for numeric if not empty + if(!empty($user_input[$element_name])){ + $rules[$element_name]['numeric'] = true; + } + + if($element_info[$element_id]['is_unique']){ + $rules[$element_name]['unique'] = $form_id.'#'.$element_name; + } + + $target_input[$element_name] = $user_input[$element_name]; + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($user_input[$element_name]); + + //prepare data for table column + $table_data[$element_name] = $user_input[$element_name]; + + } + + + + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + }elseif ('checkbox' == $element_type){ //Checkboxes + if(!empty($processed_elements) && is_array($processed_elements) && in_array($element_name,$processed_elements)){ + continue; + } + + //validate base element, will not process child data + $base_element = substr($element_name,-1); + + if ($base_element != '_') { + continue; + } + + + //checking 'required' for checkboxes is more complex + //we need to get total child, and join it into one element + //only one element is required to be checked + $all_child_array = array(); + $all_child_array = $checkbox_childs[$element_id]; + $base_element_name = $element_name; + + $all_checkbox_value = ''; + + foreach ($all_child_array as $i){ + $all_checkbox_value .= $user_input[$base_element_name.$i]; + $processed_elements[] = $base_element_name.$i; + + //save old data into array, for form redisplay in case errors occured + $form_data[$base_element_name.$i]['default_value'] = $user_input[$base_element_name.$i]; + + //prepare data for table column + //add zero if no data + if (!empty($user_input[$base_element_name.$i])) + $table_data[$base_element_name.$i] = $user_input[$base_element_name.$i]; + else + $table_data[$base_element_name.$i] = '0'; + + } + + if($element_info[$element_id]['is_required']){ + $rules[$base_element_name]['required'] = true; + } + + $target_input[$base_element_name] = $all_checkbox_value; + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + }elseif ('select' == $element_type){ //Drop Down + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + } + + $target_input[$element_name] = $element_data; + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = $user_input[$element_name]; + + //prepare data for table column + $table_data[$element_name] = $user_input[$element_name]; + + }elseif ('date' == $element_type || 'europe_date' == $element_type){ //Date + + if(!empty($processed_elements) && is_array($processed_elements) && in_array($element_name,$processed_elements)){ + continue; + } + + //compound element, grab the other element, 3 elements total + + $element_name_2 = substr($element_name,0,-1).'2'; + $element_name_3 = substr($element_name,0,-1).'3'; + + $processed_elements[] = $element_name_2; //put this element into array so that it won't be processed next + $processed_elements[] = $element_name_3; + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + $rules[$element_name_2]['required'] = true; + $rules[$element_name_3]['required'] = true; + } + + $rules['element_date']['date'] = 'yyyy/mm/dd'; + + if($element_info[$element_id]['is_unique']){ + $rules['element_date']['unique'] = $form_id.'#'.substr($element_name,0,-2); + } + + $target_input[$element_name] = $user_input[$element_name]; + $target_input[$element_name_2] = $user_input[$element_name_2]; + $target_input[$element_name_3] = $user_input[$element_name_3]; + + $base_element_name = substr($element_name,0,-2); + if('date' == $element_type){ //MM/DD/YYYY + $target_input['element_date'] = $user_input[$element_name_3].'-'.$user_input[$element_name].'-'.$user_input[$element_name_2]; + + //prepare data for table column + $table_data[$base_element_name] = $user_input[$element_name_3].'-'.$user_input[$element_name].'-'.$user_input[$element_name_2]; + }else{ //DD/MM/YYYY + $target_input['element_date'] = $user_input[$element_name_3].'-'.$user_input[$element_name_2].'-'.$user_input[$element_name]; + + //prepare data for table column + $table_data[$base_element_name] = $user_input[$element_name_3].'-'.$user_input[$element_name_2].'-'.$user_input[$element_name]; + } + + $test_empty = str_replace('-','',$target_input['element_date']); //if user not submitting any entry, remove the dashes + if(empty($test_empty)){ + unset($target_input['element_date']); + $table_data[$base_element_name] = ''; + } + + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($user_input[$element_name]); + $form_data[$element_name_2]['default_value'] = htmlspecialchars($user_input[$element_name_2]); + $form_data[$element_name_3]['default_value'] = htmlspecialchars($user_input[$element_name_3]); + + }elseif ('simple_phone' == $element_type){ //Simple Phone + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + } + + if(!empty($user_input[$element_name])){ + $rules[$element_name]['simple_phone'] = true; + } + + if($element_info[$element_id]['is_unique']){ + $rules[$element_name]['unique'] = $form_id.'#'.$element_name; + } + + $target_input[$element_name] = $user_input[$element_name]; + + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($user_input[$element_name]); + + //prepare data for table column + $table_data[$element_name] = $user_input[$element_name]; + + }elseif ('phone' == $element_type){ //Phone - US format + + if(!empty($processed_elements) && is_array($processed_elements) && in_array($element_name,$processed_elements)){ + continue; + } + + //compound element, grab the other element, 3 elements total + + $element_name_2 = substr($element_name,0,-1).'2'; + $element_name_3 = substr($element_name,0,-1).'3'; + + $processed_elements[] = $element_name_2; //put this element into array so that it won't be processed next + $processed_elements[] = $element_name_3; + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + $rules[$element_name_2]['required'] = true; + $rules[$element_name_3]['required'] = true; + } + + $rules['element_phone']['phone'] = true; + + + if($element_info[$element_id]['is_unique']){ + $rules['element_phone']['unique'] = $form_id.'#'.substr($element_name,0,-2); + } + + $target_input[$element_name] = $user_input[$element_name]; + $target_input[$element_name_2] = $user_input[$element_name_2]; + $target_input[$element_name_3] = $user_input[$element_name_3]; + $target_input['element_phone'] = $user_input[$element_name].$user_input[$element_name_2].$user_input[$element_name_3]; + + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($user_input[$element_name]); + $form_data[$element_name_2]['default_value'] = htmlspecialchars($user_input[$element_name_2]); + $form_data[$element_name_3]['default_value'] = htmlspecialchars($user_input[$element_name_3]); + + //prepare data for table column + $table_data[substr($element_name,0,-2)] = $user_input[$element_name].$user_input[$element_name_2].$user_input[$element_name_3]; + + }elseif ('email' == $element_type){ //Email + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + } + + if($element_info[$element_id]['is_unique']){ + $rules[$element_name]['unique'] = $form_id.'#'.$element_name; + } + + $rules[$element_name]['email'] = true; + + $target_input[$element_name] = $element_data; + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($user_input[$element_name]); + + //prepare data for table column + $table_data[$element_name] = $user_input[$element_name]; + + }elseif ('file' == $element_type){ //File + //file upload field doesn't need to be required on edit mode + $element_info[$element_id]['is_required'] = false; + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required_file'] = true; + } + + $target_input[$element_name] = $element_name; //special for file, only need to pass input name + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + }else{ + //if validation passed, store uploaded file info into array + if($_FILES[$element_name]['size'] > 0){ + $uploaded_files[] = $element_name; + } + } + + + } + + } + + + + + $process_result['old_values'] = $form_data; + $process_result['error_elements'] = $error_elements; + + $table_data['date_updated'] = date("Y-m-d H:i:s"); + + //start update data into table ---------------------- + //dynamically create the field list and field values, based on the input given + if(!empty($table_data) && empty($error_elements) && empty($process_result['custom_error'])){ + + //dynamically create the sql update string, based on the input given + $update_values = ''; + foreach ($table_data as $key=>$value){ + $value = mysql_real_escape_string($value); + $update_values .= "`$key`='$value',"; + } + $update_values = substr($update_values,0,-1); + + $query = "UPDATE `ap_form_{$form_id}` set + $update_values + where + id='{$entry_id}';"; + do_query($query); + } + //end update data into table ------------------------- + + + //upload the files + if(!empty($uploaded_files)){ + + foreach ($uploaded_files as $element_name){ + //remove old file if any + $query = "select $element_name from `ap_form_{$form_id}` where id='$entry_id'"; + $result = do_query($query); + $row = do_fetch_result($result); + if(!empty($row[$element_name])){ + $old_filename = $row[$element_name]; + } + + $file_token = md5(uniqid(rand(), true)); //add random token to uploaded filename, to increase security + + //move new file and check for invalid file + $destination_file = UPLOAD_DIR."/form_{$form_id}/files/{$element_name}_{$file_token}-{$entry_id}-{$_FILES[$element_name]['name']}"; + if (move_uploaded_file($_FILES[$element_name]['tmp_name'], $destination_file)) { + $filename = mysql_real_escape_string($_FILES[$element_name]['name']); + $query = "update ap_form_{$form_id} set $element_name='{$element_name}_{$file_token}-{$entry_id}-{$filename}' where id='$entry_id'"; + do_query($query); + + //remove old file if any + if(!empty($old_filename)){ + @unlink(UPLOAD_DIR."/form_{$form_id}/files/".$old_filename); + } + } + } + } + + + + //if there is any error message or elements, send false as status + if(empty($error_elements) && empty($process_result['custom_error'])){ + $process_result['status'] = true; + }else{ + $process_result['status'] = false; + } + + + return $process_result; + } + + //process form review submit + //move the record from temporary review table to the actual table + function commit_form_review($form_id,$record_id,$options=array()){ + //move data from ap_form_x_review table to ap_form_x table + //get all column name except session_id and id + $query = "SELECT * FROM `ap_form_{$form_id}_review` WHERE id='$record_id'"; + $result = do_query($query); + + $i = 0; + $fields_num = mysql_num_fields($result); + $columns = array(); + while($i < $fields_num){ + $meta = mysql_fetch_field($result, $i); + if(($meta->name != 'session_id') && ($meta->name != 'id')){ + $columns[] = $meta->name; + } + $i++; + } + + $columns_joined = implode("`,`",$columns); + $columns_joined = '`'.$columns_joined.'`'; + + //copy data from review table + $query = "INSERT INTO `ap_form_{$form_id}`($columns_joined) SELECT {$columns_joined} from `ap_form_{$form_id}_review` WHERE id='{$record_id}'"; + do_query($query); + + $new_record_id = mysql_insert_id(); + + //rename file uploads, if any + //get all file uploads elements first + $query = "SELECT + element_id + FROM + ap_form_elements + WHERE + form_id='{$form_id}' AND + element_type='file' AND + element_is_private=0"; + $result = do_query($query); + $file_uploads_array = array(); + while($row = do_fetch_result($result)){ + $file_uploads_array[] = 'element_'.$row['element_id']; + } + if(!empty($file_uploads_array)){ + $file_uploads_column = implode('`,`',$file_uploads_array); + $file_uploads_column = '`'.$file_uploads_column.'`'; + + $query = "SELECT {$file_uploads_column} FROM `ap_form_{$form_id}_review` where id='{$record_id}'"; + $result = do_query($query); + $row = do_fetch_result($result); + $file_update_query = ''; + + foreach ($file_uploads_array as $element_name){ + $filename = $row[$element_name]; + + if(empty($filename)){ + continue; + } + + $target_filename = $options['machform_data_path'].UPLOAD_DIR."/form_{$form_id}/files/{$filename}.tmp"; + + $regex = '/^element_([0-9]*)_([0-9a-zA-Z]*)-([0-9]*)-(.*)$/'; + $matches = array(); + preg_match($regex, $filename,$matches); + $filename_noelement = $matches[4]; + + $file_token = md5(uniqid(rand(), true)); //add random token to uploaded filename, to increase security + $destination_filename = $options['machform_data_path'].UPLOAD_DIR."/form_{$form_id}/files/{$element_name}_{$file_token}-{$new_record_id}-{$filename_noelement}"; + + if(file_exists($target_filename)){ + rename($target_filename,$destination_filename); + } + + //build update query + $filename_noelement = mysql_real_escape_string($filename_noelement); + $file_update_query .= "`{$element_name}`='{$element_name}_{$file_token}-{$new_record_id}-{$filename_noelement}',"; + } + + $file_update_query = rtrim($file_update_query,','); + if(!empty($file_update_query)){ + do_query("UPDATE `ap_form_{$form_id}` SET {$file_update_query} WHERE id='{$new_record_id}'"); + } + } + + //send notification emails + //get form properties data + $query = "select + form_redirect, + form_email, + esl_from_name, + esl_from_email_address, + esl_subject, + esl_content, + esl_plain_text, + esr_email_address, + esr_from_name, + esr_from_email_address, + esr_subject, + esr_content, + esr_plain_text + from + `ap_forms` + where + form_id='$form_id'"; + + $result = do_query($query); + $row = do_fetch_result($result); + $form_redirect = $row['form_redirect']; + $form_email = $row['form_email']; + + $esl_from_name = $row['esl_from_name']; + $esl_from_email_address = $row['esl_from_email_address']; + $esl_subject = $row['esl_subject']; + $esl_content = $row['esl_content']; + $esl_plain_text = $row['esl_plain_text']; + + $esr_email_address = $row['esr_email_address']; + $esr_from_name = $row['esr_from_name']; + $esr_from_email_address = $row['esr_from_email_address']; + $esr_subject = $row['esr_subject']; + $esr_content = $row['esr_content']; + $esr_plain_text = $row['esr_plain_text']; + + //start sending notification email to admin ------------------------------------------ + if(!empty($form_email)){ + //get parameters for the email + + //from name + if(!empty($esl_from_name)){ + $admin_email_param['from_name'] = $esl_from_name; + }elseif (NOTIFICATION_MAIL_FROM_NAME != ''){ + $admin_email_param['from_name'] = NOTIFICATION_MAIL_FROM_NAME; + }else{ + $admin_email_param['from_name'] = 'MachForm'; + } + + //from email address + if(!empty($esl_from_email_address)){ + if(is_numeric($esl_from_email_address)){ + $admin_email_param['from_email'] = '{element_'.$esl_from_email_address.'}'; + }else{ + $admin_email_param['from_email'] = $esl_from_email_address; + } + }elseif(NOTIFICATION_MAIL_FROM != ''){ + $admin_email_param['from_email'] = NOTIFICATION_MAIL_FROM; + }else{ + $domain = str_replace('www.','',$_SERVER['SERVER_NAME']); + $admin_email_param['from_email'] = "no-reply@{$domain}"; + } + + //subject + if(!empty($esl_subject)){ + $admin_email_param['subject'] = $esl_subject; + }elseif (NOTIFICATION_MAIL_SUBJECT != ''){ + $admin_email_param['subject'] = NOTIFICATION_MAIL_SUBJECT; + }else{ + $admin_email_param['subject'] = '{form_name} [#{entry_no}]'; + } + + //content + if(!empty($esl_content)){ + $admin_email_param['content'] = $esl_content; + }else{ + $admin_email_param['content'] = '{entry_data}'; + } + + $admin_email_param['as_plain_text'] = $esl_plain_text; + $admin_email_param['target_is_admin'] = true; + $admin_email_param['machform_base_path'] = $options['machform_base_path']; + + send_notification($form_id,$new_record_id,$form_email,$admin_email_param); + + } + //end emailing notifications to admin ---------------------------------------------- + + + //start sending notification email to user ------------------------------------------ + if(!empty($esr_email_address)){ + //get parameters for the email + + //to email + if(is_numeric($esr_email_address)){ + $esr_email_address = '{element_'.$esr_email_address.'}'; + } + + //from name + if(!empty($esr_from_name)){ + $user_email_param['from_name'] = $esr_from_name; + }elseif (NOTIFICATION_MAIL_FROM_NAME != ''){ + $user_email_param['from_name'] = NOTIFICATION_MAIL_FROM_NAME; + }else{ + $user_email_param['from_name'] = 'MachForm'; + } + + //from email address + if(!empty($esr_from_email_address)){ + if(is_numeric($esr_from_email_address)){ + $user_email_param['from_email'] = '{element_'.$esr_from_email_address.'}'; + }else{ + $user_email_param['from_email'] = $esr_from_email_address; + } + }elseif(NOTIFICATION_MAIL_FROM != ''){ + $user_email_param['from_email'] = NOTIFICATION_MAIL_FROM; + }else{ + $domain = str_replace('www.','',$_SERVER['SERVER_NAME']); + $user_email_param['from_email'] = "no-reply@{$domain}"; + } + + //subject + if(!empty($esr_subject)){ + $user_email_param['subject'] = $esr_subject; + }elseif (NOTIFICATION_MAIL_SUBJECT != ''){ + $user_email_param['subject'] = NOTIFICATION_MAIL_SUBJECT; + }else{ + $user_email_param['subject'] = '{form_name} - Receipt'; + } + + //content + if(!empty($esr_content)){ + $user_email_param['content'] = $esr_content; + }else{ + $user_email_param['content'] = '{entry_data}'; + } + + $user_email_param['as_plain_text'] = $esr_plain_text; + $user_email_param['target_is_admin'] = false; + + send_notification($form_id,$new_record_id,$esr_email_address,$user_email_param); + } + //end emailing notifications to user ---------------------------------------------- + + //delete all entry from this user in review table + $session_id = session_id(); + do_query("DELETE FROM `ap_form_{$form_id}_review` where id='{$record_id}' or session_id='{$session_id}'"); + + $commit_result['form_redirect'] = $form_redirect; + + return $commit_result; + } +?> \ No newline at end of file diff --git a/includes/view-functions.php b/includes/view-functions.php new file mode 100644 index 0000000..4f118fa --- /dev/null +++ b/includes/view-functions.php @@ -0,0 +1,2495 @@ +is_error)){ + $error_class = 'class="error"'; + $error_message = "

    {$element->error_message}

    "; + } + + //check for required + if($element->is_required){ + $span_required = "id}\" class=\"required\">*"; + } + + //check for guidelines + if(!empty($element->guidelines)){ + $guidelines = "

    id}\">{$element->guidelines}

    "; + } + + //check for populated value, if exist, use it instead default_value + if(isset($element->populated_value['element_'.$element->id]['default_value'])){ + $element->default_value = $element->populated_value['element_'.$element->id]['default_value']; + } + + +$element_markup = << + +
    + +
    {$guidelines} {$error_message} + +EOT; + + return $element_markup; + } + + + + //Paragraph Text + function display_textarea($element){ + //check for error + $error_class = ''; + $error_message = ''; + $span_required = ''; + $guidelines = ''; + + if(!empty($element->is_error)){ + $error_class = 'class="error"'; + $error_message = "

    {$element->error_message}

    "; + } + + //check for required + if($element->is_required){ + $span_required = "id}\" class=\"required\">*"; + } + + //check for guidelines + if(!empty($element->guidelines)){ + $guidelines = "

    id}\">{$element->guidelines}

    "; + } + + //check for populated value, if exist, use it instead default_value + if(isset($element->populated_value['element_'.$element->id]['default_value'])){ + $element->default_value = $element->populated_value['element_'.$element->id]['default_value']; + } + +$element_markup = << + +
    + +
    {$guidelines} {$error_message} + +EOT; + + return $element_markup; + } + + + //File Upload + function display_file($element){ + //check for error + $error_class = ''; + $error_message = ''; + $span_required = ''; + $guidelines = ''; + + if(!empty($element->is_error)){ + $error_class = 'class="error"'; + $error_message = "

    {$element->error_message}

    "; + } + + //check for required + if($element->is_required){ + $span_required = "id}\" class=\"required\">*"; + } + + //check for guidelines + if(!empty($element->guidelines)){ + $guidelines = "

    id}\">{$element->guidelines}

    "; + } + + //check for populated value (this is being used for edit_entry.php only) + if(!empty($element->populated_value)){ + $file_option = $element->populated_value['element_'.$element->id]['default_value']; //this should be contain html markup to download or delete current file + } + +$element_markup = << + +
    + +
    {$file_option} {$guidelines} {$error_message} + +EOT; + + return $element_markup; + } + + //Website + function display_url($element){ + //check for error + $error_class = ''; + $error_message = ''; + $span_required = ''; + $guidelines = ''; + + if(!empty($element->is_error)){ + $error_class = 'class="error"'; + $error_message = "

    {$element->error_message}

    "; + } + + //check for required + if($element->is_required){ + $span_required = "id}\" class=\"required\">*"; + } + + //check for guidelines + if(!empty($element->guidelines)){ + $guidelines = "

    id}\">{$element->guidelines}

    "; + } + + //check for default value + if(empty($element->default_value)){ + $element->default_value = 'http://'; + } + + //check for populated value, if exist, use it instead default_value + if(!empty($element->populated_value['element_'.$element->id]['default_value'])){ + $element->default_value = $element->populated_value['element_'.$element->id]['default_value']; + } + +$element_markup = << + +
    + +
    {$guidelines} {$error_message} + +EOT; + + return $element_markup; + } + + //Email + function display_email($element){ + //check for error + $error_class = ''; + $error_message = ''; + $span_required = ''; + $guidelines = ''; + + if(!empty($element->is_error)){ + $error_class = 'class="error"'; + $error_message = "

    {$element->error_message}

    "; + } + + //check for required + if($element->is_required){ + $span_required = "id}\" class=\"required\">*"; + } + + //check for guidelines + if(!empty($element->guidelines)){ + $guidelines = "

    id}\">{$element->guidelines}

    "; + } + + //check for populated value, if exist, use it instead default_value + if(!empty($element->populated_value['element_'.$element->id]['default_value'])){ + $element->default_value = $element->populated_value['element_'.$element->id]['default_value']; + } + +$element_markup = << + +
    + +
    {$guidelines} {$error_message} + +EOT; + + return $element_markup; + } + + + //Phone - Extended + function display_phone($element){ + //check for error + $error_class = ''; + $error_message = ''; + $span_required = ''; + $guidelines = ''; + + if(!empty($element->is_error)){ + $error_class = 'class="error"'; + $error_message = "

    {$element->error_message}

    "; + } + + //check for required + if($element->is_required){ + $span_required = "id}\" class=\"required\">*"; + } + + //check for guidelines + if(!empty($element->guidelines)){ + $guidelines = "

    id}\">{$element->guidelines}

    "; + } + + //check default value + if(!empty($element->default_value)){ + //split into (xxx) xxx - xxxx + $default_value_1 = substr($element->default_value,0,3); + $default_value_2 = substr($element->default_value,3,3); + $default_value_3 = substr($element->default_value,6,4); + } + + if(!empty($element->populated_value['element_'.$element->id.'_1']['default_value']) || + !empty($element->populated_value['element_'.$element->id.'_2']['default_value']) || + !empty($element->populated_value['element_'.$element->id.'_3']['default_value']) + ){ + $default_value_1 = ''; + $default_value_2 = ''; + $default_value_3 = ''; + $default_value_1 = $element->populated_value['element_'.$element->id.'_1']['default_value']; + $default_value_2 = $element->populated_value['element_'.$element->id.'_2']['default_value']; + $default_value_3 = $element->populated_value['element_'.$element->id.'_3']['default_value']; + } + + +$element_markup = << + + + - + + + + - + + + + + + + {$guidelines} {$error_message} + +EOT; + + + return $element_markup; + } + + //Phone - Simple + function display_simple_phone($element){ + //check for error + $error_class = ''; + $error_message = ''; + $span_required = ''; + $guidelines = ''; + + if(!empty($element->is_error)){ + $error_class = 'class="error"'; + $error_message = "

    {$element->error_message}

    "; + } + + //check for required + if($element->is_required){ + $span_required = "id}\" class=\"required\">*"; + } + + //check for guidelines + if(!empty($element->guidelines)){ + $guidelines = "

    id}\">{$element->guidelines}

    "; + } + + //check for populated value + if(!empty($element->populated_value['element_'.$element->id]['default_value'])){ + $element->default_value = $element->populated_value['element_'.$element->id]['default_value']; + } + +$element_markup = << + +
    + +
    {$guidelines} {$error_message} + +EOT; + + return $element_markup; + } + + + + //Date - Normal + function display_date($element){ + //check for error + $error_class = ''; + $error_message = ''; + $span_required = ''; + $guidelines = ''; + global $lang; + + if(!empty($element->is_error)){ + $error_class = 'class="error"'; + $error_message = "

    {$element->error_message}

    "; + } + + //check for required + if($element->is_required){ + $span_required = "id}\" class=\"required\">*"; + } + + //check for guidelines + if(!empty($element->guidelines)){ + $guidelines = "

    id}\">{$element->guidelines}

    "; + } + + $machform_path = ''; + if(!empty($element->machform_path)){ + $machform_path = $element->machform_path; + } + + +$element_markup = << + + + / + + + + / + + + + + + + + + Pick a date. + + + {$guidelines} {$error_message} + +EOT; + + return $element_markup; + } + + //Date - Normal + function display_europe_date($element){ + //check for error + $error_class = ''; + $error_message = ''; + $span_required = ''; + $guidelines = ''; + global $lang; + + if(!empty($element->is_error)){ + $error_class = 'class="error"'; + $error_message = "

    {$element->error_message}

    "; + } + + //check for required + if($element->is_required){ + $span_required = "id}\" class=\"required\">*"; + } + + //check for guidelines + if(!empty($element->guidelines)){ + $guidelines = "

    id}\">{$element->guidelines}

    "; + } + + $machform_path = ''; + if(!empty($element->machform_path)){ + $machform_path = $element->machform_path; + } + +$element_markup = << + + + / + + + + / + + + + + + + + + Pick a date. + + + {$guidelines} {$error_message} + +EOT; + + return $element_markup; + } + + + //Multiple Choice + function display_radio($element){ + //check for error + $error_class = ''; + $error_message = ''; + $span_required = ''; + $guidelines = ''; + + if(!empty($element->is_error)){ + $error_class = 'class="error"'; + $error_message = "

    {$element->error_message}

    "; + } + + //check for required + if($element->is_required){ + $span_required = "id}\" class=\"required\">*"; + } + + //check for guidelines + if(!empty($element->guidelines)){ + $guidelines = "

    id}\">{$element->guidelines}

    "; + } + + $option_markup = ''; + + if($element->constraint == 'random'){ + $temp = $element->options; + shuffle($temp); + $element->options = $temp; + } + + foreach ($element->options as $option){ + + if($option->is_default){ + $checked = 'checked="checked"'; + }else{ + $checked = ''; + } + + //check for populated values + if(!empty($element->populated_value['element_'.$element->id]['default_value'])){ + $checked = ''; + if($element->populated_value['element_'.$element->id]['default_value'] == $option->id){ + $checked = 'checked="checked"'; + } + } + + $option_markup .= "id}_{$option->id}\" name=\"element_{$element->id}\" class=\"element radio\" type=\"radio\" value=\"{$option->id}\" {$checked} />\n"; + $option_markup .= "\n"; + } + +$element_markup = << + + + {$option_markup} + {$guidelines} {$error_message} + +EOT; + + return $element_markup; + } + + //Checkboxes + function display_checkbox($element){ + //check for error + $error_class = ''; + $error_message = ''; + $span_required = ''; + $guidelines = ''; + + if(!empty($element->is_error)){ + $error_class = 'class="error"'; + $error_message = "

    {$element->error_message}

    "; + } + + //check for required + if($element->is_required){ + $span_required = "id}\" class=\"required\">*"; + } + + //check for guidelines + if(!empty($element->guidelines)){ + $guidelines = "

    id}\">{$element->guidelines}

    "; + } + + //check for populated value first, if any exist, unselect all default value + $is_populated = false; + foreach ($element->options as $option){ + + if(!empty($element->populated_value['element_'.$element->id.'_'.$option->id]['default_value'])){ + $is_populated = true; + break; + } + } + + $option_markup = ''; + + foreach ($element->options as $option){ + if(!$is_populated){ + if($option->is_default){ + $checked = 'checked="checked"'; + }else{ + $checked = ''; + } + }else{ + + if(!empty($element->populated_value['element_'.$element->id.'_'.$option->id]['default_value'])){ + $checked = 'checked="checked"'; + }else{ + $checked = ''; + } + } + + + + $option_markup .= "id}_{$option->id}\" name=\"element_{$element->id}_{$option->id}\" class=\"element checkbox\" type=\"checkbox\" value=\"1\" {$checked} />\n"; + $option_markup .= "\n"; + } + +$element_markup = << + + + {$option_markup} + {$guidelines} {$error_message} + +EOT; + + return $element_markup; + } + + + //Dropdown + function display_select($element){ + //check for error + $error_class = ''; + $error_message = ''; + $span_required = ''; + $guidelines = ''; + + if(!empty($element->is_error)){ + $error_class = 'class="error"'; + $error_message = "

    {$element->error_message}

    "; + } + + //check for required + if($element->is_required){ + $span_required = "id}\" class=\"required\">*"; + } + + //check for guidelines + if(!empty($element->guidelines)){ + $guidelines = "

    id}\">{$element->guidelines}

    "; + } + + $option_markup = ''; + + $has_default = false; + foreach ($element->options as $option){ + + if($option->is_default){ + $selected = 'selected="selected"'; + $has_default = true; + }else{ + $selected = ''; + } + + if(!empty($element->populated_value['element_'.$element->id]['default_value'])){ + $selected = ''; + if($element->populated_value['element_'.$element->id]['default_value'] == $option->id){ + $selected = 'selected="selected"'; + } + } + + $option_markup .= "\n"; + } + + if(!$has_default){ + if(!empty($element->populated_value['element_'.$element->id]['default_value'])){ + $option_markup = ''."\n".$option_markup; + }else{ + $option_markup = ''."\n".$option_markup; + } + } + +$element_markup = << + +
    + +
    {$guidelines} {$error_message} + +EOT; + + return $element_markup; + } + + + //Name - Simple + function display_simple_name($element){ + //check for error + $error_class = ''; + $error_message = ''; + $span_required = ''; + $guidelines = ''; + global $lang; + + if(!empty($element->is_error)){ + $error_class = 'class="error"'; + $error_message = "

    {$element->error_message}

    "; + } + + //check for required + if($element->is_required){ + $span_required = "id}\" class=\"required\">*"; + } + + //check for guidelines + if(!empty($element->guidelines)){ + $guidelines = "

    id}\">{$element->guidelines}

    "; + } + +$element_markup = << + + + + + + + + + {$guidelines} {$error_message} + +EOT; + + return $element_markup; + } + + //Name + function display_name($element){ + //check for error + $error_class = ''; + $error_message = ''; + $span_required = ''; + $guidelines = ''; + global $lang; + + if(!empty($element->is_error)){ + $error_class = 'class="error"'; + $error_message = "

    {$element->error_message}

    "; + } + + //check for required + if($element->is_required){ + $span_required = "id}\" class=\"required\">*"; + } + + //check for guidelines + if(!empty($element->guidelines)){ + $guidelines = "

    id}\">{$element->guidelines}

    "; + } + +$element_markup = << + + + + + + + + + + + + + + + + + {$guidelines} {$error_message} + +EOT; + + return $element_markup; + } + + //Time + function display_time($element){ + //check for error + $error_class = ''; + $error_message = ''; + $span_required = ''; + $guidelines = ''; + global $lang; + + if(!empty($element->is_error)){ + $error_class = 'class="error"'; + $error_message = "

    {$element->error_message}

    "; + } + + //check for required + if($element->is_required){ + $span_required = "id}\" class=\"required\">*"; + } + + //check for guidelines + if(!empty($element->guidelines)){ + $guidelines = "

    id}\">{$element->guidelines}

    "; + } + + if(!empty($element->populated_value['element_'.$element->id.'_4']['default_value'])){ + if($element->populated_value['element_'.$element->id.'_4']['default_value'] == 'AM'){ + $selected_am = 'selected'; + }else{ + $selected_pm = 'selected'; + } + } + + if($element->constraint == 'show_seconds'){ + $seconds_markup =<< + + + +EOT; + $seconds_separator = ':'; + }else{ + $seconds_markup = ''; + $seconds_separator = ''; + } + +$element_markup = << + + + : + + + + {$seconds_separator} + + + {$seconds_markup} + + + + {$guidelines} {$error_message} + +EOT; + + return $element_markup; + } + + + //Price + function display_money($element){ + //check for error + $error_class = ''; + $error_message = ''; + $span_required = ''; + $guidelines = ''; + global $lang; + + if(!empty($element->is_error)){ + $error_class = 'class="error"'; + $error_message = "

    {$element->error_message}

    "; + } + + //check for required + if($element->is_required){ + $span_required = "id}\" class=\"required\">*"; + } + + //check for guidelines + if(!empty($element->guidelines)){ + $guidelines = "

    id}\">{$element->guidelines}

    "; + } + + if($element->constraint != 'yen'){ //for dollar, pound and euro + if($element->constraint == 'pound'){ + $main_cur = $lang['price_pound_main']; + $child_cur = $lang['price_pound_sub']; + $cur_symbol = '£'; + }elseif ($element->constraint == 'euro'){ + $main_cur = $lang['price_euro_main']; + $child_cur = $lang['price_euro_sub']; + $cur_symbol = '€'; + }else{ //dollar + $main_cur = $lang['price_dollar_main']; + $child_cur = $lang['price_dollar_sub']; + $cur_symbol = '$'; + } + +$element_markup = << + + {$cur_symbol} + + . + + + + + + + {$guidelines} {$error_message} + +EOT; + + }else{ //for yen, only display one textfield + $main_cur = $lang['price_yen']; + $cur_symbol = '¥'; + +$element_markup = << + + {$cur_symbol} + + + + + {$guidelines} {$error_message} + +EOT; + + } + + + + return $element_markup; + } + + //Section Break + function display_section($element){ + $element->guidelines = nl2br($element->guidelines); +$element_markup = << +

    {$element->title}

    +

    {$element->guidelines}

    + +EOT; + + return $element_markup; + } + + + + //Number + function display_number($element){ + //check for error + $error_class = ''; + $error_message = ''; + $span_required = ''; + $guidelines = ''; + + if(!empty($element->is_error)){ + $error_class = 'class="error"'; + $error_message = "

    {$element->error_message}

    "; + } + + //check for required + if($element->is_required){ + $span_required = "id}\" class=\"required\">*"; + } + + //check for guidelines + if(!empty($element->guidelines)){ + $guidelines = "

    id}\">{$element->guidelines}

    "; + } + + //check for populated value, if exist, use it instead default_value + if(isset($element->populated_value['element_'.$element->id]['default_value'])){ + $element->default_value = $element->populated_value['element_'.$element->id]['default_value']; + } + +$element_markup = << + +
    + +
    {$guidelines} {$error_message} + +EOT; + + return $element_markup; + } + + + + //Address + function display_address($element){ + + $country[0]['label'] = "Afghanistan"; + $country[1]['label'] = "Albania"; + $country[2]['label'] = "Algeria"; + $country[3]['label'] = "Andorra"; + $country[4]['label'] = "Antigua and Barbuda"; + $country[5]['label'] = "Argentina"; + $country[6]['label'] = "Armenia"; + $country[7]['label'] = "Australia"; + $country[8]['label'] = "Austria"; + $country[9]['label'] = "Azerbaijan"; + $country[10]['label'] = "Bahamas"; + $country[11]['label'] = "Bahrain"; + $country[12]['label'] = "Bangladesh"; + $country[13]['label'] = "Barbados"; + $country[14]['label'] = "Belarus"; + $country[15]['label'] = "Belgium"; + $country[16]['label'] = "Belize"; + $country[17]['label'] = "Benin"; + $country[18]['label'] = "Bhutan"; + $country[19]['label'] = "Bolivia"; + $country[20]['label'] = "Bosnia and Herzegovina"; + $country[21]['label'] = "Botswana"; + $country[22]['label'] = "Brazil"; + $country[23]['label'] = "Brunei"; + $country[24]['label'] = "Bulgaria"; + $country[25]['label'] = "Burkina Faso"; + $country[26]['label'] = "Burundi"; + $country[27]['label'] = "Cambodia"; + $country[28]['label'] = "Cameroon"; + $country[29]['label'] = "Canada"; + $country[30]['label'] = "Cape Verde"; + $country[31]['label'] = "Central African Republic"; + $country[32]['label'] = "Chad"; + $country[33]['label'] = "Chile"; + $country[34]['label'] = "China"; + $country[35]['label'] = "Colombia"; + $country[36]['label'] = "Comoros"; + $country[37]['label'] = "Congo"; + $country[38]['label'] = "Costa Rica"; + $country[39]['label'] = "Côte d'Ivoire"; + $country[40]['label'] = "Croatia"; + $country[41]['label'] = "Cuba"; + $country[42]['label'] = "Cyprus"; + $country[43]['label'] = "Czech Republic"; + $country[44]['label'] = "Denmark"; + $country[45]['label'] = "Djibouti"; + $country[46]['label'] = "Dominica"; + $country[47]['label'] = "Dominican Republic"; + $country[48]['label'] = "East Timor"; + $country[49]['label'] = "Ecuador"; + $country[50]['label'] = "Egypt"; + $country[51]['label'] = "El Salvador"; + $country[52]['label'] = "Equatorial Guinea"; + $country[53]['label'] = "Eritrea"; + $country[54]['label'] = "Estonia"; + $country[55]['label'] = "Ethiopia"; + $country[56]['label'] = "Fiji"; + $country[57]['label'] = "Finland"; + $country[58]['label'] = "France"; + $country[59]['label'] = "Gabon"; + $country[60]['label'] = "Gambia"; + $country[61]['label'] = "Georgia"; + $country[62]['label'] = "Germany"; + $country[63]['label'] = "Ghana"; + $country[64]['label'] = "Greece"; + $country[65]['label'] = "Grenada"; + $country[66]['label'] = "Guatemala"; + $country[67]['label'] = "Guinea"; + $country[68]['label'] = "Guinea-Bissau"; + $country[69]['label'] = "Guyana"; + $country[70]['label'] = "Haiti"; + $country[71]['label'] = "Honduras"; + $country[72]['label'] = "Hong Kong"; + $country[73]['label'] = "Hungary"; + $country[74]['label'] = "Iceland"; + $country[75]['label'] = "India"; + $country[76]['label'] = "Indonesia"; + $country[77]['label'] = "Iran"; + $country[78]['label'] = "Iraq"; + $country[79]['label'] = "Ireland"; + $country[80]['label'] = "Israel"; + $country[81]['label'] = "Italy"; + $country[82]['label'] = "Jamaica"; + $country[83]['label'] = "Japan"; + $country[84]['label'] = "Jordan"; + $country[85]['label'] = "Kazakhstan"; + $country[86]['label'] = "Kenya"; + $country[87]['label'] = "Kiribati"; + $country[88]['label'] = "North Korea"; + $country[89]['label'] = "South Korea"; + $country[90]['label'] = "Kuwait"; + $country[91]['label'] = "Kyrgyzstan"; + $country[92]['label'] = "Laos"; + $country[93]['label'] = "Latvia"; + $country[94]['label'] = "Lebanon"; + $country[95]['label'] = "Lesotho"; + $country[96]['label'] = "Liberia"; + $country[97]['label'] = "Libya"; + $country[98]['label'] = "Liechtenstein"; + $country[99]['label'] = "Lithuania"; + $country[100]['label'] = "Luxembourg"; + $country[101]['label'] = "Macedonia"; + $country[102]['label'] = "Madagascar"; + $country[103]['label'] = "Malawi"; + $country[104]['label'] = "Malaysia"; + $country[105]['label'] = "Maldives"; + $country[106]['label'] = "Mali"; + $country[107]['label'] = "Malta"; + $country[108]['label'] = "Marshall Islands"; + $country[109]['label'] = "Mauritania"; + $country[110]['label'] = "Mauritius"; + $country[111]['label'] = "Mexico"; + $country[112]['label'] = "Micronesia"; + $country[113]['label'] = "Moldova"; + $country[114]['label'] = "Monaco"; + $country[115]['label'] = "Mongolia"; + $country[116]['label'] = "Montenegro"; + $country[117]['label'] = "Morocco"; + $country[118]['label'] = "Mozambique"; + $country[119]['label'] = "Myanmar"; + $country[120]['label'] = "Namibia"; + $country[121]['label'] = "Nauru"; + $country[122]['label'] = "Nepal"; + $country[123]['label'] = "Netherlands"; + $country[124]['label'] = "New Zealand"; + $country[125]['label'] = "Nicaragua"; + $country[126]['label'] = "Niger"; + $country[127]['label'] = "Nigeria"; + $country[128]['label'] = "Norway"; + $country[129]['label'] = "Oman"; + $country[130]['label'] = "Pakistan"; + $country[131]['label'] = "Palau"; + $country[132]['label'] = "Panama"; + $country[133]['label'] = "Papua New Guinea"; + $country[134]['label'] = "Paraguay"; + $country[135]['label'] = "Peru"; + $country[136]['label'] = "Philippines"; + $country[137]['label'] = "Poland"; + $country[138]['label'] = "Portugal"; + $country[139]['label'] = "Puerto Rico"; + $country[140]['label'] = "Qatar"; + $country[141]['label'] = "Romania"; + $country[142]['label'] = "Russia"; + $country[143]['label'] = "Rwanda"; + $country[144]['label'] = "Saint Kitts and Nevis"; + $country[145]['label'] = "Saint Lucia"; + $country[146]['label'] = "Saint Vincent and the Grenadines"; + $country[147]['label'] = "Samoa"; + $country[148]['label'] = "San Marino"; + $country[149]['label'] = "Sao Tome and Principe"; + $country[150]['label'] = "Saudi Arabia"; + $country[151]['label'] = "Senegal"; + $country[152]['label'] = "Serbia and Montenegro"; + $country[153]['label'] = "Seychelles"; + $country[154]['label'] = "Sierra Leone"; + $country[155]['label'] = "Singapore"; + $country[156]['label'] = "Slovakia"; + $country[157]['label'] = "Slovenia"; + $country[158]['label'] = "Solomon Islands"; + $country[159]['label'] = "Somalia"; + $country[160]['label'] = "South Africa"; + $country[161]['label'] = "Spain"; + $country[162]['label'] = "Sri Lanka"; + $country[163]['label'] = "Sudan"; + $country[164]['label'] = "Suriname"; + $country[165]['label'] = "Swaziland"; + $country[166]['label'] = "Sweden"; + $country[167]['label'] = "Switzerland"; + $country[168]['label'] = "Syria"; + $country[169]['label'] = "Taiwan"; + $country[170]['label'] = "Tajikistan"; + $country[171]['label'] = "Tanzania"; + $country[172]['label'] = "Thailand"; + $country[173]['label'] = "Togo"; + $country[174]['label'] = "Tonga"; + $country[175]['label'] = "Trinidad and Tobago"; + $country[176]['label'] = "Tunisia"; + $country[177]['label'] = "Turkey"; + $country[178]['label'] = "Turkmenistan"; + $country[179]['label'] = "Tuvalu"; + $country[180]['label'] = "Uganda"; + $country[181]['label'] = "Ukraine"; + $country[182]['label'] = "United Arab Emirates"; + $country[183]['label'] = "United Kingdom"; + $country[184]['label'] = "United States"; + $country[185]['label'] = "Uruguay"; + $country[186]['label'] = "Uzbekistan"; + $country[187]['label'] = "Vanuatu"; + $country[188]['label'] = "Vatican City"; + $country[189]['label'] = "Venezuela"; + $country[190]['label'] = "Vietnam"; + $country[191]['label'] = "Yemen"; + $country[192]['label'] = "Zambia"; + $country[193]['label'] = "Zimbabwe"; + + + $country[0]['value'] = "Afghanistan"; + $country[1]['value'] = "Albania"; + $country[2]['value'] = "Algeria"; + $country[3]['value'] = "Andorra"; + $country[4]['value'] = "Antigua and Barbuda"; + $country[5]['value'] = "Argentina"; + $country[6]['value'] = "Armenia"; + $country[7]['value'] = "Australia"; + $country[8]['value'] = "Austria"; + $country[9]['value'] = "Azerbaijan"; + $country[10]['value'] = "Bahamas"; + $country[11]['value'] = "Bahrain"; + $country[12]['value'] = "Bangladesh"; + $country[13]['value'] = "Barbados"; + $country[14]['value'] = "Belarus"; + $country[15]['value'] = "Belgium"; + $country[16]['value'] = "Belize"; + $country[17]['value'] = "Benin"; + $country[18]['value'] = "Bhutan"; + $country[19]['value'] = "Bolivia"; + $country[20]['value'] = "Bosnia and Herzegovina"; + $country[21]['value'] = "Botswana"; + $country[22]['value'] = "Brazil"; + $country[23]['value'] = "Brunei"; + $country[24]['value'] = "Bulgaria"; + $country[25]['value'] = "Burkina Faso"; + $country[26]['value'] = "Burundi"; + $country[27]['value'] = "Cambodia"; + $country[28]['value'] = "Cameroon"; + $country[29]['value'] = "Canada"; + $country[30]['value'] = "Cape Verde"; + $country[31]['value'] = "Central African Republic"; + $country[32]['value'] = "Chad"; + $country[33]['value'] = "Chile"; + $country[34]['value'] = "China"; + $country[35]['value'] = "Colombia"; + $country[36]['value'] = "Comoros"; + $country[37]['value'] = "Congo"; + $country[38]['value'] = "Costa Rica"; + $country[39]['value'] = "Côte d'Ivoire"; + $country[40]['value'] = "Croatia"; + $country[41]['value'] = "Cuba"; + $country[42]['value'] = "Cyprus"; + $country[43]['value'] = "Czech Republic"; + $country[44]['value'] = "Denmark"; + $country[45]['value'] = "Djibouti"; + $country[46]['value'] = "Dominica"; + $country[47]['value'] = "Dominican Republic"; + $country[48]['value'] = "East Timor"; + $country[49]['value'] = "Ecuador"; + $country[50]['value'] = "Egypt"; + $country[51]['value'] = "El Salvador"; + $country[52]['value'] = "Equatorial Guinea"; + $country[53]['value'] = "Eritrea"; + $country[54]['value'] = "Estonia"; + $country[55]['value'] = "Ethiopia"; + $country[56]['value'] = "Fiji"; + $country[57]['value'] = "Finland"; + $country[58]['value'] = "France"; + $country[59]['value'] = "Gabon"; + $country[60]['value'] = "Gambia"; + $country[61]['value'] = "Georgia"; + $country[62]['value'] = "Germany"; + $country[63]['value'] = "Ghana"; + $country[64]['value'] = "Greece"; + $country[65]['value'] = "Grenada"; + $country[66]['value'] = "Guatemala"; + $country[67]['value'] = "Guinea"; + $country[68]['value'] = "Guinea-Bissau"; + $country[69]['value'] = "Guyana"; + $country[70]['value'] = "Haiti"; + $country[71]['value'] = "Honduras"; + $country[72]['value'] = "Hong Kong"; + $country[73]['value'] = "Hungary"; + $country[74]['value'] = "Iceland"; + $country[75]['value'] = "India"; + $country[76]['value'] = "Indonesia"; + $country[77]['value'] = "Iran"; + $country[78]['value'] = "Iraq"; + $country[79]['value'] = "Ireland"; + $country[80]['value'] = "Israel"; + $country[81]['value'] = "Italy"; + $country[82]['value'] = "Jamaica"; + $country[83]['value'] = "Japan"; + $country[84]['value'] = "Jordan"; + $country[85]['value'] = "Kazakhstan"; + $country[86]['value'] = "Kenya"; + $country[87]['value'] = "Kiribati"; + $country[88]['value'] = "North Korea"; + $country[89]['value'] = "South Korea"; + $country[90]['value'] = "Kuwait"; + $country[91]['value'] = "Kyrgyzstan"; + $country[92]['value'] = "Laos"; + $country[93]['value'] = "Latvia"; + $country[94]['value'] = "Lebanon"; + $country[95]['value'] = "Lesotho"; + $country[96]['value'] = "Liberia"; + $country[97]['value'] = "Libya"; + $country[98]['value'] = "Liechtenstein"; + $country[99]['value'] = "Lithuania"; + $country[100]['value'] = "Luxembourg"; + $country[101]['value'] = "Macedonia"; + $country[102]['value'] = "Madagascar"; + $country[103]['value'] = "Malawi"; + $country[104]['value'] = "Malaysia"; + $country[105]['value'] = "Maldives"; + $country[106]['value'] = "Mali"; + $country[107]['value'] = "Malta"; + $country[108]['value'] = "Marshall Islands"; + $country[109]['value'] = "Mauritania"; + $country[110]['value'] = "Mauritius"; + $country[111]['value'] = "Mexico"; + $country[112]['value'] = "Micronesia"; + $country[113]['value'] = "Moldova"; + $country[114]['value'] = "Monaco"; + $country[115]['value'] = "Mongolia"; + $country[116]['value'] = "Montenegro"; + $country[117]['value'] = "Morocco"; + $country[118]['value'] = "Mozambique"; + $country[119]['value'] = "Myanmar"; + $country[120]['value'] = "Namibia"; + $country[121]['value'] = "Nauru"; + $country[122]['value'] = "Nepal"; + $country[123]['value'] = "Netherlands"; + $country[124]['value'] = "New Zealand"; + $country[125]['value'] = "Nicaragua"; + $country[126]['value'] = "Niger"; + $country[127]['value'] = "Nigeria"; + $country[128]['value'] = "Norway"; + $country[129]['value'] = "Oman"; + $country[130]['value'] = "Pakistan"; + $country[131]['value'] = "Palau"; + $country[132]['value'] = "Panama"; + $country[133]['value'] = "Papua New Guinea"; + $country[134]['value'] = "Paraguay"; + $country[135]['value'] = "Peru"; + $country[136]['value'] = "Philippines"; + $country[137]['value'] = "Poland"; + $country[138]['value'] = "Portugal"; + $country[139]['value'] = "Puerto Rico"; + $country[140]['value'] = "Qatar"; + $country[141]['value'] = "Romania"; + $country[142]['value'] = "Russia"; + $country[143]['value'] = "Rwanda"; + $country[144]['value'] = "Saint Kitts and Nevis"; + $country[145]['value'] = "Saint Lucia"; + $country[146]['value'] = "Saint Vincent and the Grenadines"; + $country[147]['value'] = "Samoa"; + $country[148]['value'] = "San Marino"; + $country[149]['value'] = "Sao Tome and Principe"; + $country[150]['value'] = "Saudi Arabia"; + $country[151]['value'] = "Senegal"; + $country[152]['value'] = "Serbia and Montenegro"; + $country[153]['value'] = "Seychelles"; + $country[154]['value'] = "Sierra Leone"; + $country[155]['value'] = "Singapore"; + $country[156]['value'] = "Slovakia"; + $country[157]['value'] = "Slovenia"; + $country[158]['value'] = "Solomon Islands"; + $country[159]['value'] = "Somalia"; + $country[160]['value'] = "South Africa"; + $country[161]['value'] = "Spain"; + $country[162]['value'] = "Sri Lanka"; + $country[163]['value'] = "Sudan"; + $country[164]['value'] = "Suriname"; + $country[165]['value'] = "Swaziland"; + $country[166]['value'] = "Sweden"; + $country[167]['value'] = "Switzerland"; + $country[168]['value'] = "Syria"; + $country[169]['value'] = "Taiwan"; + $country[170]['value'] = "Tajikistan"; + $country[171]['value'] = "Tanzania"; + $country[172]['value'] = "Thailand"; + $country[173]['value'] = "Togo"; + $country[174]['value'] = "Tonga"; + $country[175]['value'] = "Trinidad and Tobago"; + $country[176]['value'] = "Tunisia"; + $country[177]['value'] = "Turkey"; + $country[178]['value'] = "Turkmenistan"; + $country[179]['value'] = "Tuvalu"; + $country[180]['value'] = "Uganda"; + $country[181]['value'] = "Ukraine"; + $country[182]['value'] = "United Arab Emirates"; + $country[183]['value'] = "United Kingdom"; + $country[184]['value'] = "United States"; + $country[185]['value'] = "Uruguay"; + $country[186]['value'] = "Uzbekistan"; + $country[187]['value'] = "Vanuatu"; + $country[188]['value'] = "Vatican City"; + $country[189]['value'] = "Venezuela"; + $country[190]['value'] = "Vietnam"; + $country[191]['value'] = "Yemen"; + $country[192]['value'] = "Zambia"; + $country[193]['value'] = "Zimbabwe"; + + //check for error + $error_class = ''; + $error_message = ''; + $span_required = ''; + $guidelines = ''; + global $lang; + + if(!empty($element->is_error)){ + $error_class = 'class="error"'; + $error_message = "

    {$element->error_message}

    "; + } + + //check for required + if($element->is_required){ + $span_required = "id}\" class=\"required\">*"; + } + + //check for guidelines + if(!empty($element->guidelines)){ + $guidelines = "

    id}\">{$element->guidelines}

    "; + } + + + //create country markup, if no default value, provide a blank option + if(empty($element->default_value)){ + $country_markup = ''."\n"; + }else{ + $country_markup = ''; + } + + foreach ($country as $data){ + if($data['value'] == $element->default_value){ + $selected = 'selected="selected"'; + }else{ + $selected = ''; + } + + //check for populated value, use it instead of default value + if(!empty($element->populated_value['element_'.$element->id.'_6']['default_value'])){ + $selected = ''; + if($element->populated_value['element_'.$element->id.'_6']['default_value'] == $data['value']){ + $selected = 'selected="selected"'; + } + } + + $country_markup .= "\n"; + } + +$element_markup = << + + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
     {$guidelines} {$error_message} + +EOT; + + + return $element_markup; + } + + + //Captcha + function display_captcha($element){ + + if(!empty($element->error_message)){ + $error_code = $element->error_message; + }else{ + $error_code = ''; + } + + //check for error + $error_class = ''; + $error_message = ''; + $span_required = ''; + $guidelines = ''; + global $lang; + + if(!empty($element->is_error)){ + + if($element->error_message == 'el-required'){ + $element->error_message = $lang['captcha_required']; + $error_code = ''; + }elseif ($element->error_message == 'incorrect-captcha-sol'){ + $element->error_message = $lang['captcha_mismatch']; + }else{ + $element->error_message = "{$lang['captcha_error']} ({$element->error_message})"; + } + + $error_class = 'class="error"'; + $error_message = "

    {$element->error_message}

    "; + } + + if(!empty($_SERVER['HTTPS'])){ + $use_ssl = true; + }else{ + $use_ssl = false; + } + + + if(USE_INTERNAL_CAPTCHA === true){ //use the internal captcha if enabled + + $machform_path = ''; + if(!empty($element->machform_path)){ + $machform_path = $element->machform_path; + } + + $timestamp = time(); //use this as paramater for captcha.php, to prevent caching + + $element->title = $lang['captcha_title']; +$captcha_html = <<
    +
    +EOT; + + }else{ //otherwise use the reCAPTCHA + $captcha_html = recaptcha_get_html(RECAPTCHA_PUBLIC_KEY, $error_code,$use_ssl); + + if($captcha_html === false){ + $domain = str_replace('www.','',$_SERVER['SERVER_NAME']); + $captcha_html = "Error! You have enabled CAPTCHA but no API key available.

    To use CAPTCHA you must get an API key from http://recaptcha.net/api/getkey

    After getting the API key, save them into your config.php file."; + $error_class = 'class="error"'; + } + } + + + if(function_exists("form{$element->form_id}_hook_pre_captcha")){ + $custom_precaptcha = call_user_func("form{$element->form_id}_hook_pre_captcha"); + } + +$element_markup = << {$custom_precaptcha} + +
    + {$captcha_html} +
    + {$guidelines} {$error_message} + +EOT; + + return $element_markup; + } + + + //Main function to display a form + //There are few mode when displaying a form + //1. New blank form (form populated with default values) + //2. New form with error (displayed when 1 submitted and having error, form populated with user inputs) + //3. Edit form (form populated with data from db) + //4. Edit form with error (displayed when 3 submiteed and having error) + function display_form($form_id,$populated_values=array(),$error_elements=array(),$custom_error='',$edit_id=0,$embed=false){ + + global $lang; + + //if there is custom error, don't show other errors + if(!empty($custom_error)){ + $error_elements = array(); + } + + //get form properties data + $query = "select + form_name, + form_description, + form_redirect, + form_success_message, + form_password, + form_unique_ip, + form_frame_height, + form_has_css, + form_active, + form_captcha, + form_review + from + ap_forms + where + form_id='$form_id'"; + $result = do_query($query); + $row = do_fetch_result($result); + + $form = new stdClass(); + + $form->id = $form_id; + $form->name = $row['form_name']; + $form->description = $row['form_description']; + $form->redirect = $row['form_redirect']; + $form->success_message = $row['form_success_message']; + $form->password = $row['form_password']; + $form->frame_height = $row['form_frame_height']; + $form->unique_ip = $row['form_unique_ip']; + $form->has_css = $row['form_has_css']; + $form->active = $row['form_active']; + $form->captcha = $row['form_captcha']; + $form->review = $row['form_review']; + + if(empty($error_elements)){ + $form->is_error = 0; + }else{ + $form->is_error = 1; + } + + //if this form has review enabled and user are having $_SESSION['review_id'], then populate the form with that values + if(!empty($form->review) && !empty($_SESSION['review_id']) && empty($populated_values)){ + $populated_values = get_entry_values($form_id,$_SESSION['review_id'],true); + } + + //get elements data + //get element options first and store it into array + $query = "select + element_id, + option_id, + `position`, + `option`, + option_is_default + from + ap_element_options + where + form_id='$form_id' and live=1 + order by + element_id asc,`position` asc"; + $result = do_query($query); + while($row = do_fetch_result($result)){ + $element_id = $row['element_id']; + $option_id = $row['option_id']; + $options_lookup[$element_id][$option_id]['position'] = $row['position']; + $options_lookup[$element_id][$option_id]['option'] = $row['option']; + $options_lookup[$element_id][$option_id]['option_is_default'] = $row['option_is_default']; + } + + + //get elements data + $element = array(); + $query = "select + element_id, + element_title, + element_guidelines, + element_size, + element_is_required, + element_is_unique, + element_is_private, + element_type, + element_position, + element_default_value, + element_constraint + from + ap_form_elements + where + form_id='$form_id' + order by + element_position asc"; + $result = do_query($query); + + $j=0; + $has_calendar = false; //assume the form doesn't have calendar, so it won't load calendar.js + while($row = do_fetch_result($result)){ + $element_id = $row['element_id']; + + //lookup element options first + if(!empty($options_lookup[$element_id])){ + $element_options = array(); + $i=0; + foreach ($options_lookup[$element_id] as $option_id=>$data){ + $element_options[$i] = new stdClass(); + $element_options[$i]->id = $option_id; + $element_options[$i]->option = $data['option']; + $element_options[$i]->is_default = $data['option_is_default']; + $element_options[$i]->is_db_live = 1; + $i++; + } + } + + + //populate elements + $element[$j] = new stdClass(); + $element[$j]->title = nl2br($row['element_title']); + $element[$j]->guidelines = $row['element_guidelines']; + $element[$j]->size = $row['element_size']; + $element[$j]->is_required = $row['element_is_required']; + $element[$j]->is_unique = $row['element_is_unique']; + $element[$j]->is_private = $row['element_is_private']; + $element[$j]->type = $row['element_type']; + $element[$j]->position = $row['element_position']; + $element[$j]->id = $row['element_id']; + $element[$j]->is_db_live = 1; + + //this data came from db or form submit + //being used to display edit form or redisplay form with errors and previous inputs + //this should be optimized in the future, only pass necessary data, not the whole array + $element[$j]->populated_value = $populated_values; + + //if there is file upload type, set form enctype to multipart + if($row['element_type'] == 'file'){ + $form_enc_type = 'enctype="multipart/form-data"'; + } + + if(!empty($error_elements[$element[$j]->id])){ + $element[$j]->is_error = 1; + $element[$j]->error_message = $error_elements[$element[$j]->id]; + } + + + $element[$j]->default_value = htmlspecialchars($row['element_default_value']); + + + $element[$j]->constraint = $row['element_constraint']; + if(!empty($element_options)){ + $element[$j]->options = $element_options; + }else{ + $element[$j]->options = ''; + } + + + //check for calendar type + if($row['element_type'] == 'date' || $row['element_type'] == 'europe_date'){ + $has_calendar = true; + } + + $j++; + } + + + //add captcha if enable + if(!empty($form->captcha) && (empty($edit_id))){ + $element[$j] = new stdClass(); + $element[$j]->type = 'captcha'; + $element[$j]->form_id = $form_id; + $element[$j]->is_private = 0; + + if(!empty($error_elements['element_captcha'])){ + $element[$j]->is_error = 1; + $element[$j]->error_message = $error_elements['element_captcha']; + } + } + + //generate html markup for each element + $all_element_markup = ''; + foreach ($element as $element_data){ + if($element_data->is_private && empty($_SESSION['logged_in'])){ //don't show private element + continue; + } + $all_element_markup .= call_user_func('display_'.$element_data->type,$element_data); + } + + if(!empty($custom_error)){ + $form->error_message =<< +

    {$custom_error}

    + +EOT; + }elseif(!empty($error_elements)){ + $form->error_message =<< +

    {$lang['error_title']}

    +

    {$lang['error_desc']}

    + +EOT; + } + + + //display edit_id if there is any + if(!empty($edit_id)){ + $edit_markup = "\n"; + }else{ + $edit_markup = ''; + } + + if(empty($form->review)){ + $button_text = $lang['submit_button']; + }else{ + $button_text = $lang['continue_button']; + } + + //markup for submit button + $button_markup =<< + + {$edit_markup} + + + +EOT; + + //check for specific form css, if any, use it instead + if($form->has_css){ + $css_dir = DATA_DIR."/form_{$form_id}/css/"; + } + + if(!empty($form->password) && empty($_SESSION['user_authenticated'])){ //if form require password and password hasn't set yet + $show_password_form = true; + + }elseif (!empty($form->password) && !empty($_SESSION['user_authenticated']) && $_SESSION['user_authenticated'] != $form_id){ //if user authenticated but not for this form + $show_password_form = true; + + }else{ //user authenticated for this form, or no password required + $show_password_form = false; + } + + + if(empty($form->active)){ //if form is not active, don't show the fields + $form_desc_div =''; + $all_element_markup = ''; + $button_markup = ''; + $ul_class = 'class="password"'; + $custom_element =<< +

    {$lang['form_inactive']}

    + +EOT; + }elseif($show_password_form){ //don't show form description if this page is password protected and user not authenticated + $form_desc_div =''; + $all_element_markup = ''; + $custom_element =<< +

    {$lang['form_pass_title']}

    +
    + + +
    + +EOT; + $ul_class = 'class="password"'; + }else{ + if(!empty($form->name) || !empty($form->description)){ + $form->description = nl2br($form->description); + $form_desc_div =<< +

    {$form->name}

    +

    {$form->description}

    +
    +EOT; + } + } + + if($embed){ + $embed_class = 'class="embed"'; + } + + if($has_calendar){ + $calendar_js = ''; + }else{ + $calendar_js = ''; + } + + //If you would like to remove the "Powered by MachForm" link, please contact us at customer.service@appnitro.com before doing so + $form_markup = << + + + +{$form->name} + + +{$calendar_js} + + + + +
    + +

    {$form->name}

    +
    + {$form_desc_div} +
      + {$form->error_message} + {$all_element_markup} + {$custom_element} + {$button_markup} +
    +
    + +
    + + + +EOT; + return $form_markup; + + } + + //this function is similar as display_form, but designed to display form without IFRAME + function display_integrated_form($form_id,$populated_values=array(),$error_elements=array(),$custom_error='',$edit_id=0,$machform_path){ + + global $lang; + + //if there is custom error, don't show other errors + if(!empty($custom_error)){ + $error_elements = array(); + } + + //get form properties data + $query = "select + form_name, + form_description, + form_redirect, + form_success_message, + form_password, + form_unique_ip, + form_frame_height, + form_has_css, + form_active, + form_captcha, + form_review + from + ap_forms + where + form_id='$form_id'"; + $result = do_query($query); + $row = do_fetch_result($result); + + $form = new stdClass(); + + $form->id = $form_id; + $form->name = $row['form_name']; + $form->description = $row['form_description']; + $form->redirect = $row['form_redirect']; + $form->success_message = $row['form_success_message']; + $form->password = $row['form_password']; + $form->frame_height = $row['form_frame_height']; + $form->unique_ip = $row['form_unique_ip']; + $form->has_css = $row['form_has_css']; + $form->active = $row['form_active']; + $form->captcha = $row['form_captcha']; + $form->review = $row['form_review']; + + if(empty($error_elements)){ + $form->is_error = 0; + }else{ + $form->is_error = 1; + } + + //if this form has review enabled and user are having $_SESSION['review_id'], then populate the form with that values + if(!empty($form->review) && !empty($_SESSION['review_id']) && empty($populated_values)){ + $param['machform_path'] = $machform_path; + $populated_values = get_entry_values($form_id,$_SESSION['review_id'],true,$param); + } + + //get elements data + //get element options first and store it into array + $query = "select + element_id, + option_id, + `position`, + `option`, + option_is_default + from + ap_element_options + where + form_id='$form_id' and live=1 + order by + element_id asc,`position` asc"; + $result = do_query($query); + while($row = do_fetch_result($result)){ + $element_id = $row['element_id']; + $option_id = $row['option_id']; + $options_lookup[$element_id][$option_id]['position'] = $row['position']; + $options_lookup[$element_id][$option_id]['option'] = $row['option']; + $options_lookup[$element_id][$option_id]['option_is_default'] = $row['option_is_default']; + } + + + //get elements data + $element = array(); + $query = "select + element_id, + element_title, + element_guidelines, + element_size, + element_is_required, + element_is_unique, + element_is_private, + element_type, + element_position, + element_default_value, + element_constraint + from + ap_form_elements + where + form_id='$form_id' + order by + element_position asc"; + $result = do_query($query); + + $j=0; + $has_calendar = false; + while($row = do_fetch_result($result)){ + $element_id = $row['element_id']; + + //lookup element options first + if(!empty($options_lookup[$element_id])){ + $element_options = array(); + $i=0; + foreach ($options_lookup[$element_id] as $option_id=>$data){ + $element_options[$i] = new stdClass(); + $element_options[$i]->id = $option_id; + $element_options[$i]->option = $data['option']; + $element_options[$i]->is_default = $data['option_is_default']; + $element_options[$i]->is_db_live = 1; + $i++; + } + } + + + //populate elements + $element[$j] = new stdClass(); + $element[$j]->title = nl2br($row['element_title']); + + if(empty($edit_id)){ + $element[$j]->guidelines = $row['element_guidelines']; + }else{ + $element[$j]->guidelines = ''; + } + + $element[$j]->size = $row['element_size']; + $element[$j]->is_required = $row['element_is_required']; + $element[$j]->is_unique = $row['element_is_unique']; + $element[$j]->is_private = $row['element_is_private']; + $element[$j]->type = $row['element_type']; + $element[$j]->position = $row['element_position']; + $element[$j]->id = $row['element_id']; + $element[$j]->is_db_live = 1; + $element[$j]->machform_path = $machform_path; + + //this data came from db or form submit + //being used to display edit form or redisplay form with errors and previous inputs + //this should be optimized in the future, only pass necessary data, not the whole array + $element[$j]->populated_value = $populated_values; + + //if there is file upload type, set form enctype to multipart + if($row['element_type'] == 'file'){ + $form_enc_type = 'enctype="multipart/form-data"'; + } + + if(!empty($error_elements[$element[$j]->id])){ + $element[$j]->is_error = 1; + $element[$j]->error_message = $error_elements[$element[$j]->id]; + } + + + $element[$j]->default_value = htmlspecialchars($row['element_default_value']); + + + $element[$j]->constraint = $row['element_constraint']; + if(!empty($element_options)){ + $element[$j]->options = $element_options; + }else{ + $element[$j]->options = ''; + } + + //check for calendar type + if($row['element_type'] == 'date' || $row['element_type'] == 'europe_date'){ + $has_calendar = true; + } + + $j++; + } + + + //add captcha if enable + if(!empty($form->captcha) && (empty($edit_id))){ + $element[$j] = new stdClass(); + $element[$j]->type = 'captcha'; + $element[$j]->form_id = $form_id; + $element[$j]->machform_path = $machform_path; + + if(!empty($error_elements['element_captcha'])){ + $element[$j]->is_error = 1; + $element[$j]->error_message = $error_elements['element_captcha']; + } + } + + //generate html markup for each element + $all_element_markup = ''; + foreach ($element as $element_data){ + if($element_data->is_private && empty($_SESSION['logged_in'])){ //don't show private element + continue; + } + $all_element_markup .= call_user_func('display_'.$element_data->type,$element_data); + } + + if(!empty($custom_error)){ + $form->error_message =<< +

    {$custom_error}

    + +EOT; + }elseif(!empty($error_elements)){ + $form->error_message =<< +

    {$lang['error_title']}

    +

    {$lang['error_desc']}

    + +EOT; + } + + if(!empty($form->password) && empty($_SESSION['user_authenticated'])){ //if form require password and password hasn't set yet + $show_password_form = true; + + }elseif (!empty($form->password) && !empty($_SESSION['user_authenticated']) && $_SESSION['user_authenticated'] != $form_id){ //if user authenticated but not for this form + $show_password_form = true; + + }else{ //user authenticated for this form, or no password required + $show_password_form = false; + } + + //display edit_id if there is any + if(!empty($edit_id)){ + $edit_markup = "\n"; + $submit_button = ''; + }else{ + $edit_markup = ''; + + if(!empty($form->review) && !$show_password_form){ + $submit_button = ''."\n".''; + }else{ + $submit_button = ''."\n".''; + } + } + + + //markup for submit button + $button_markup =<< + + {$edit_markup} + {$submit_button} + +EOT; + + //check for specific form css, if any, use it instead + if($form->has_css){ + $css_dir = DATA_DIR."/form_{$form_id}/css/"; + } + + + if(empty($form->active)){ //if form is not active, don't show the fields + $form_desc_div =''; + $all_element_markup = ''; + $button_markup = ''; + $ul_class = 'class="password"'; + $custom_element =<< +

    {$lang['form_inactive']}

    + +EOT; + }elseif($show_password_form){ //don't show form description if this page is password protected and user not authenticated + $form_desc_div =''; + $all_element_markup = ''; + $custom_element =<< +

    {$lang['form_pass_title']}

    +
    + + +
    + +EOT; + $ul_class = 'class="password"'; + }else{ + if(!empty($form->name) || !empty($form->description)){ + $form->description = nl2br($form->description); + $form_desc_div =<< +

    {$form->name}

    +

    {$form->description}

    +
    +EOT; + } + } + + + $embed_class = 'class="integrated"'; + + if(empty($edit_id)){ + $css_markup = ""; + }else{ + $css_markup = ""; + } + + if($has_calendar){ + $calendar_js = ""; + }else{ + $calendar_js = ''; + } + + + //If you would like to remove the "Powered by MachForm" link, please contact us at customer.service@appnitro.com before doing so + $form_markup =<< +{$calendar_js} + +
    + +
    + +

    {$form->name}

    +
    + {$form_desc_div} +
      + {$form->error_message} + {$all_element_markup} + {$custom_element} + {$button_markup} +
    +
    + +
    +
    +EOT; + return $form_markup; + + } + + function display_success($form_id,$embed=false){ + //get form properties data + $query = "select + form_success_message, + form_has_css, + form_name + from + ap_forms + where + form_id='$form_id'"; + + $result = do_query($query); + $row = do_fetch_result($result); + + $form = new stdClass(); + + $form->id = $form_id; + $form->success_message = nl2br($row['form_success_message']); + $form->has_css = $row['form_has_css']; + $form->name = $row['form_name']; + + + //check for specific form css, if any, use it instead + if($form->has_css){ + $css_dir = DATA_DIR."/form_{$form_id}/css/"; + } + + if($embed){ + $embed_class = 'class="embed"'; + } + + $form_markup = << + + + +{$form->name} + + + + + +
    + +

    Appnitro MachForm

    + +
    +

    {$form->success_message}

    +
    + +
    + + + +EOT; + return $form_markup; + } + + //this function is similar as display_success, but designed to display success page without IFRAME + function display_integrated_success($form_id,$machform_path){ + //get form properties data + $query = "select + form_success_message, + form_has_css + from + ap_forms + where + form_id='$form_id'"; + + $result = do_query($query); + $row = do_fetch_result($result); + + $form = new stdClass(); + + $form->id = $form_id; + $form->success_message = nl2br($row['form_success_message']); + $form->has_css = $row['form_has_css']; + + + //check for specific form css, if any, use it instead + if($form->has_css){ + $css_dir = DATA_DIR."/form_{$form_id}/css/"; + } + + + $form_markup = << +
    +
    +

    Appnitro MachForm

    + +
    +

    {$form->success_message}

    +
    + +
    +
    +EOT; + return $form_markup; + } + + //display form confirmation page + function display_form_review($form_id,$record_id,$embed=false){ + global $lang; + + //get form properties data + $query = "select + form_has_css, + form_redirect + from + ap_forms + where + form_id='$form_id'"; + + $result = do_query($query); + $row = do_fetch_result($result); + + + $form_has_css = $row['form_has_css']; + $form_redirect = $row['form_redirect']; + + //prepare entry data for previewing + $param['strip_download_link'] = true; + $param['review_mode'] = true; + $param['show_attach_image'] = true; + $entry_details = get_entry_details($form_id,$record_id,$param); + + $entry_data = ''."\n"; + + $toggle = false; + foreach ($entry_details as $data){ + if($toggle){ + $toggle = false; + $row_style = 'class="alt"'; + }else{ + $toggle = true; + $row_style = ''; + } + + $entry_data .= "\n"; + $entry_data .= "\n"; + $entry_data .= "\n"; + $entry_data .= "\n"; + } + + $entry_data .= '
    {$data['label']}".nl2br($data['value'])."
    '; + + //check for specific form css, if any, use it instead + if($form_has_css){ + $css_dir = DATA_DIR."/form_{$form_id}/css/"; + } + + if($embed){ + $embed_class = 'class="embed"'; + } + + $form_markup = << + + + +{$form_name} + + + + + + + + +
    + +

    Appnitro MachForm

    +
    +
    +

    {$lang['review_title']}

    +

    {$lang['review_message']}

    +
    + {$entry_data} +
      +
    • + + + +
    • +
    +
    + +
    + + + +EOT; + return $form_markup; + } + + //display form confirmation page for integrated embed code + function display_integrated_form_review($form_id,$record_id,$machform_path){ + global $lang; + + //get form properties data + $query = "select + form_has_css, + form_redirect + from + ap_forms + where + form_id='$form_id'"; + + $result = do_query($query); + $row = do_fetch_result($result); + + + $form_has_css = $row['form_has_css']; + $form_redirect = $row['form_redirect']; + + //prepare entry data for previewing + $param['strip_download_link'] = true; + $param['review_mode'] = true; + $param['show_attach_image'] = true; + $param['machform_path'] = $machform_path; + $entry_details = get_entry_details($form_id,$record_id,$param); + + $entry_data = ''."\n"; + + $toggle = false; + foreach ($entry_details as $data){ + if($toggle){ + $toggle = false; + $row_style = 'class="alt"'; + }else{ + $toggle = true; + $row_style = ''; + } + + $entry_data .= "\n"; + $entry_data .= "\n"; + $entry_data .= "\n"; + $entry_data .= "\n"; + } + + $entry_data .= '
    {$data['label']}".nl2br($data['value'])."
    '; + + //check for specific form css, if any, use it instead + if($form_has_css){ + $css_dir = DATA_DIR."/form_{$form_id}/css/"; + } + + if($embed){ + $embed_class = 'class="embed"'; + } + + $form_action = str_replace(array("&show_review=1","?show_review=1"),"",$_SERVER['REQUEST_URI']); + + $form_markup = << + + + + +
    +
    +

    Appnitro MachForm

    +
    +
    +

    {$lang['review_title']}

    +

    {$lang['review_message']}

    +
    + {$entry_data} +
      +
    • + + + +
    • +
    +
    + +
    +
    +EOT; + return $form_markup; + } +?> \ No newline at end of file diff --git a/index.css b/index.css new file mode 100644 index 0000000..6b2cad1 --- /dev/null +++ b/index.css @@ -0,0 +1,1236 @@ +* { + margin: 0pt; + padding: 0pt; +} +body { + margin: 7px 0pt 15px; + background:#E8DFEC url(images/ap_bg.gif) repeat scroll left top; + text-align: center; + font-size: small; + font-family: "Lucida Grande",Tahoma,Arial,Verdana,sans-serif; + +} +* html body { + font-size: small; +} +#container { + text-align: left; +} +#header { + background: rgb(20, 66, 130) none repeat; position: relative; height: 100px; +} + +#header[id] { + height: 100px; } +#panel { + border-style: none; + background: rgb(255, 255, 255) none repeat; + overflow: hidden; + width: 100%; +} +#container, #top, #bottom, #footer { + margin: 0pt auto; + width: 900px; +} +#top{ + height: 5px; + display: block ! important; +} +#bottom { + height: 10px; + display: block ! important; +} +.footer { + padding-top: 5px; + line-height: 40px; +} +#footer { + padding: 7px 0pt 10px; + text-align: left; +} +#footer h1 { + margin: -3px 5px 0pt 0pt; + float: right; +} +#footer p { + margin: 0pt 10px; + font-weight: bold; + color: rgb(182, 56, 31); +} +#footer a, #footer span { + font-size: 85%; + color: rgb(51, 51, 51); + text-decoration: none; +} +#footer a:hover { + text-decoration: underline; +} +#header_tab { + margin: 0pt 5px 0pt 0pt; + position: absolute; + bottom: 0pt; + left: 10pt; + list-style-type: none; + list-style-image: none; + list-style-position: outside; +} +#header_tab li { margin: 0px 0px; float: left; } +#header_tab li a { + + padding-left: 1px; + background: #144282 none repeat; + font-size: 95%; + display: block; + text-decoration: none; + color: rgb(255, 204, 102); + font-weight: bold; +} +#header_tab li a img { + margin: 0px; +} + +#statusBar { + margin: 0pt 0pt 0pt -435px; + position: absolute; + bottom: 0pt; + z-index: 5000; + width: 870px; + left: 50%; +} +#statusBar[id] { + position: fixed ! important; +} +#statusBar #statusPanel { + border: 1px solid #1A5BB2; + background-color: #1A5BB2; + position: relative; + text-align: left; +} +#statusText { + padding: 0pt 30px; + line-height: 30px; + color: rgb(255, 255, 204); +} + + +.tooltip { + font-weight: bold; + color: rgb(207, 153, 25) ! important; + text-decoration: none; + cursor: help ! important; +} +#tooltip { + border-style: solid; + border-color: rgb(107, 147, 191) rgb(69, 112, 159) rgb(69, 112, 159) rgb(107, 147, 191); + border-width: 1px; + margin: 7px 0pt 0pt 7px; + padding: 9px 15px 10px 10px; + position: absolute; z-index: 10000; + width: 250px; + background-color: rgb(87, 129, 175); + font-size: 11px; line-height: 15px ! important; + font-weight: normal; color: rgb(255, 255, 255); +} +#tooltip b { + margin: 0pt 0pt 3px; + display: block; + color: rgb(255, 255, 255) ! important; +} +#tooltip em { + display: block; font-style: normal; + letter-spacing: 0.02em; +} +h1, h2, h3 { + font-weight: normal; +} +p { color: rgb(34, 34, 34); } +hr { visibility: hidden; clear: both; height: 20px; width: 0pt; } +.inline { display: inline ! important; } +.center { text-align: center ! important; } +.left { float: left; } +.right { float: right; } +.hide { display: none ! important; } +.strong { font-weight: bold; } + + +* html #panel { height: 1%; } +#panel[id] { display: block; } +h1 { font-size: 100%; text-indent: -9000px; text-decoration: none; } +h1 a { + background: transparent url('images/appnitro_logo.png') no-repeat scroll left top; + overflow: hidden; height: 100%; + min-height: 3em; + display: block; +} +* html h1 a { background-image: none; } +#footer h1 a, .footer h1 a { height: 40px; width: 90px; } +.buttons a, button { + border-style: solid; + border-color: rgb(238, 238, 238) rgb(222, 222, 222) rgb(222, 222, 222) rgb(238, 238, 238); + border-width: 1px; + margin: 0pt 7px 0pt 0pt; + padding: 5px 10px 6px 7px; + cursor: pointer; + font-size: 100%; + line-height: 130%; + display: block; + float: left; + background-color: rgb(245, 245, 245); + text-decoration: none; + font-weight: bold; + color: rgb(86, 86, 86); +} + +fieldset { + border: 1px solid #CCCCCC; + margin: 7px 0pt 0pt; + padding: 0pt 10px 10px; + color: rgb(68, 68, 68); + line-height: 1.6em; +} +fieldset.choices { + padding: 7px 5px 10px 10px; +} +fieldset.fieldset { + padding: 3px 0pt 10px; +} +legend { + margin: 0pt 0pt 0pt -10px; + font-weight: bold; +} +#form_properties[id] legend, .choices[class] legend { margin: 0pt 0pt 0pt -5px; } +.fieldset legend { margin: 0pt; } +.fieldset[class] legend { margin: 0pt 0pt 0pt 5px; } +#form_properties fieldset div { + margin-bottom: 7px; +} +fieldset .small { + margin: 4px 20px 0pt 4px; +} +fieldset .small[class] { + margin: 3px 20px 0pt 4px; +} +fieldset p { + margin: 10px; +} +.choices input { + width: 200px; + margin-right: 3px; +} +.choices ol { margin: 10px 0pt 0pt; } +.choices[class] ol { margin: 0pt ! important; } +.choices img { margin: 0pt 0pt -4px; float: none; } +fieldset ol li { + margin: 0pt 5px 2px 3px ! important; + padding: 0pt ! important; + display: list-item ! important; + list-style-type: decimal; + list-style-image: none; + list-style-position: inside; +} + +button { + padding: 4px 10px 3px 7px; overflow: visible; + font-family: "Lucida Grande",Tahoma,Arial,Verdana,sans-serif; + width: auto; font-weight: bold; +} +button[type] { + padding: 5px 10px 5px 7px; + width: auto; + line-height: 17px; +} +button img, .buttons a img { + margin: 0pt 3px -3px 0pt ! important; + width: 16px; + height: 16px; +} +button:hover, .buttons a:hover { + border: 1px solid rgb(194, 225, 239); + background-color: rgb(223, 244, 255); + color: rgb(51, 102, 153); +} +.buttons a:active { + border: 1px solid rgb(98, 153, 197); + background-color: rgb(98, 153, 197); + color: rgb(255, 255, 255); +} +button.positive, .buttons a.positive { + color: rgb(82, 146, 20); +} +.buttons a.positive:hover, button.positive:hover { + border: 1px solid rgb(198, 216, 128); + background-color: rgb(230, 239, 194); + color: rgb(82, 146, 20); +} +.buttons a.positive:active { + border: 1px solid rgb(82, 146, 20); + background-color: rgb(82, 146, 20); + color: rgb(255, 255, 255); +} +.buttons a.negative, button.negative { + color: rgb(209, 47, 25); +} +.buttons a.negative:hover, button.negative:hover { + border: 1px solid rgb(251, 194, 196); + background: rgb(251, 227, 228) none repeat; + color: rgb(209, 47, 25); +} +.buttons a.negative:active { + border: 1px solid rgb(209, 47, 25); + background-color: rgb(209, 47, 25); + color: rgb(255, 255, 255); +} +.info .buttons { + margin: 6px 0pt 0pt; + padding: 0pt; + float: right; +} +.info .export { + margin: 6px 0pt 0pt; + padding: 0pt; + float: right; + +} + +.create_new_form { +float: right; +} + +.export a{ + color:#444444; + cursor:pointer; + font-size:85%; + font-weight:bold; + text-decoration:none; + padding:8px 5pt; +} + + + +.info .buttons a { + margin: 0pt 0pt 0pt 7px; } +.info b { + color: rgb(189, 61, 32); +} +.clearfix:after, #panel:after { + content: "."; + display: block; + height: 0pt; + clear: both; + visibility: hidden; +} +img { + border: medium none ; +} + +#info { + margin: 0pt 0pt 0pt -385px; + cursor: pointer; position: absolute; + left: 50%; z-index: 10000; text-align: left; +} + +#info h2 { + margin: 0pt 0pt 3px; + color: rgb(81, 115, 156); + font-weight: bold; +} +#info li { + margin: 5px 10px; + padding: 0pt; + list-style-type: disc; + list-style-image: none; + list-style-position: inside; + color: rgb(51, 51, 51); +} +.notification { + border: 2px solid #96B6DA; + margin: 10px 10px 0pt; padding: 10px 0px 10px 0pt; + background-color: #F3F7FB; +} +.element_inactive { + margin: 10px 10px 0pt; padding: 10px 0px 10px 0pt; + background-color: #F3F7FB; +} +.click_instruction{ + padding-top: 5px; +} +.notification h2 { + display: block; font-size: 150%; + color: rgb(205, 66, 36) ! important; +} +.notification b { + color: rgb(189, 61, 32); +} +.element_inactive h2 { + display: block; font-size: 150%; + color: rgb(205, 66, 36) ! important; +} +.element_inactive b { + color: rgb(189, 61, 32); +} + +a { + color: blue; + outline-color: invert; + outline-style: none; + outline-width: medium; +} +a:hover { + cursor: pointer; + color: green; +} +a img { + border: 0pt none ; +} +.icon { + width: 16px; height: 16px; +} + +#overlay { + position: absolute; + top: 0pt; left: 0pt; + width: 100%; + height: 100%; + z-index: 5000; + background-color: rgb(51, 51, 51); opacity: 0.8; +} +#overlay[id] { + position: fixed; +} + + +form ul { + margin: 0pt; + padding: 0pt; + list-style-type: none; + width: 100%; +} +form li { margin: 0pt; padding: 4px 5px 2px 9px; position: relative; } +form li:after, .buttons:after { + content: "."; display: block; + height: 0pt; clear: both; + visibility: hidden; +} +* html form li, * html .buttons { height: 1%; } +form li, .buttons { + display: block; +} +form li div, form li span { margin: 0pt 5px 0pt 0pt; padding: 0pt 0pt 8px; color: rgb(68, 68, 68); } +form li span { float: left; } +form li div.left { display: inline; float: left; width: 48%; } +form li div.right { display: inline; float: right; width: 48%; } +form li div.left .medium, form li div.right .medium { width: 100%; } +.clear { clear: both; } +form li div label, form li span label { + margin: 0pt; + padding-top: 3px; + clear: both; + font-size: 9px; + line-height: 9px; + color: rgb(68, 68, 68); + display: block; +} +form li .icon { + margin: 0.1em 5px 0pt 0pt; + padding: 0pt; + float: left; + width: 16px; + height: 16px; +} +.info { + border-bottom: 1px dotted rgb(204, 204, 204); + margin: 0pt 0pt 1em; + clear: both; +} +.info[class] { display: block; } +.info h2 { + margin: 0pt 0pt 3px; + font-weight: normal; + font-size: 160%; + clear: left; +} +.info p { + margin: 0pt 0pt 12px; + font-size: 95%; + line-height: 130%; +} +form hr { + display: none; +} +fieldset.section { + border: 1px dotted rgb(204, 204, 204); + margin: 12px 0pt 15px; + padding: 5px 0pt 0pt; } +fieldset ul { + margin: 0pt 10px 10px; + width: 97%; +} +fieldset.section legend { + margin: 0pt; + padding: 0pt 5px; + background: rgb(255, 255, 255) none repeat; + font-weight: normal; + font-size: 110%; + line-height: 110%; +} +fieldset.section[class] legend { + margin: 0pt 0pt 0pt 8px; + display: block; +} + +fieldset.section { + border-left: medium none; + border-right: medium none; + border-bottom: medium none; + display: block; + position: relative; + margin-bottom: 0pt; +} +fieldset.first { + border-top: medium none ! important; + margin-top: 0px; + padding-top: 1px; +} +fieldset.first h3 { margin-top: 0pt ! important; } +fieldset ul { margin: 0pt; } +fieldset.section legend { display: none ! important; } +form .section h3 { + margin: 9px 0pt 2px 9px; + font-weight: normal; + font-size: 110%; + line-height: 130%; +} +form .section { + margin-left: 9px; + margin-top: 3px; +} + +.buttons { + clear: both; margin-top: 10px; +} +.buttons input { font-size: 120%; margin-right: 5px; } +label.desc { + border: medium none ; + padding: 0pt 4px 1px 0pt; + line-height: 150%; + color: rgb(34, 34, 34); + display: block; + font-size: 95%; + font-weight: bold; +} +input.text, textarea.textarea, select.select { + border-style: solid; + border-color: rgb(124, 124, 124) rgb(195, 195, 195) rgb(221, 221, 221); + border-width: 1px; margin: 0pt; + background: rgb(255, 255, 255) url('images/input_bg.gif') repeat-x scroll center top; + font-size: 100%; + color: rgb(51, 51, 51); +} +input.text { padding: 2px 0pt; } +input.currency { text-align: right; } +input.checkbox, input.radio { + margin: 8px 0pt 0pt 3px; + display: block; + line-height: 1.4em; + width: 13px; + height: 13px; +} +label.choice { + margin: -19px 0pt 0pt 25px; + padding: 4px 0pt 5px; + font-size: 100%; + display: block; + line-height: 1.4em; + color: rgb(68, 68, 68); + width: 90%; +} +textarea.textarea { + margin-top: 1px; + font-family: "Lucida Grande",Tahoma,Arial,Verdana,sans-serif; +} +select.select { + margin: 1px 0pt; + padding: 1px 0pt 0pt; +} +select.select[class] { + margin: 0pt; + padding: 1px 0pt; +} +.third { width: 32% ! important; } +.half { width: 48% ! important; } +.full { width: 100% ! important; } +input.small, select.small { width: 25%; } +input.medium, select.medium { width: 50%; } +input.large, select.large, textarea.textarea { width: 100%; } +textarea.small { height: 5.5em; } +textarea.medium { height: 10em; } +textarea.large { height: 20em; } +#errorLi { + border: 1px dotted red; + background: rgb(255, 255, 255) none repeat; + width: 97%; margin-bottom: 1em; + text-align: center; +} +#errorMsg { + margin: 0pt 0pt 0.8em; + color: rgb(0, 0, 0); + font-size: 100%; +} +#errorMsg strong { + padding: 2px 3px; + background-color: rgb(255, 223, 223); + color: red; +} +form li.error { + border-right: 1px solid rgb(234, 203, 204); + border-bottom: 1px solid rgb(234, 203, 204); + margin: 3px 0pt; + background-color: rgb(255, 223, 223) ! important; +} +form li.error label { + color: rgb(223, 0, 0) ! important; +} +form p.error { + margin: 0pt 0pt 5px; + color: red; + font-weight: bold; + font-size: 10px; + clear: both; +} +form .req { + float: none; + color: red; + font-weight: bold; +} +form li.focused { + background-color: rgb(255, 247, 192); +} +form .instruct { + border: 1px solid rgb(230, 230, 230); + margin: 0pt 0pt 0pt 8px; + padding: 8px 10px 9px; + background: rgb(245, 245, 245) none repeat; + display: none; + position: absolute; + top: 0pt; left: 100%; + z-index: 1000; + width: 42%; + line-height: 130%; + font-size: 80%; + color: rgb(68, 68, 68); +} +form .instruct small { + font-size: 100%; +} +form li.focused .instruct, form li:hover .instruct { + display: block; +} + +ul.protected { + margin: 60px 0pt; + list-style-type: none; + list-style-image: none; + list-style-position: outside; +} +.protected li { + padding: 10px 0pt; + text-align: center; +} +.protected h2 { + margin: 0pt auto 10px; + font-weight: bold; + color: rgb(223, 0, 0); +} +.protected label { + font-size: 120% ! important; + padding-top: 10px; + display: block; +} +.protected input.text { + font-size: 170% ! important; + width: 380px; + text-align: center; +} +.protected .buttons { margin: 0pt; } +.protected #form_save_button { + font-size: 120% ! important; +} + +#form_builder #main { + padding: 0pt 0pt 20px; + float: left; + width: 490px +} +#form_builder #sidebar { + position: relative; + float: left; width: 360px; + height: 500px; + background-color:#FFFFFF; + margin-left:30px; +} +#form_builder #sidebar[id] { + height: auto; + width: 360px; + min-height: 500px; +} +#form_builder #main form { + margin: 10px 0pt 0pt 22px; + width: 466px; +} +#form_builder #main form ul { + width: 100%; +} +#form_builder #main form li { + margin: 0pt 0pt 8px; + width: 100%; +} +#form_result label.desc, #form_result legend { overflow: hidden; width: 100%; } +#sidebar .desc { + padding: 5px 0pt 0pt; font-weight: bold; +} + +#form_password { + padding: 6px 0pt 0pt; +} +fieldset .desc { color: rgb(34, 34, 34) ! important; } +#tabs { + background-color: #FFFFFF; + float: left; + width: 100%; + list-style-type: none; + list-style-image: none; + list-style-position: outside; +} +#tabs li { float: left; font-size: 85%; text-align: center; } +#tabs a { + display: block; + color: rgb(128, 102, 63); + text-decoration: none; + border-bottom: 5px; + border-bottom-style:solid; + border-bottom-color: #144282; + +} +#tabs a:hover { font-weight: bold; color: #1A5BB2; } +#add_field_tab { width: 105px; } +#field_prop_tab { width: 125px; } +#form_prop_tab { width: 130px; } +#add_field_tab a { margin: 4px 0pt 0pt 0px; padding: 4px 0pt 4px 20px; } +#field_prop_tab a { margin: 4px 0pt 0pt 0px; padding: 4px 0pt 4px 20px; } +#form_prop_tab a { margin: 4px 0pt 0pt 0px; padding: 4px 0pt 4px 20px; } +.add_field_tab #add_field_tab a, .field_prop_tab #field_prop_tab a, .form_prop_tab #form_prop_tab a { + background: url('images/icons/asterisk_orange.gif') no-repeat scroll 4px 0pt; + border-bottom: 5px; + border-bottom-style:solid; + border-bottom-color: #4B75B3; + color: #1A5BB2; + font-weight: bold; +} +input[disabled], select[disabled] { color: rgb(102, 102, 102) ! important; } +#add_elements { padding: 15px; clear: both; } +#add_elements[id] { margin: 25px 0pt 0pt; position: fixed; } +#element_buttons ul { float: left; list-style-type: none; list-style-image: none; list-style-position: outside; } +#first_column li { margin: 5px 5px 5px 0pt; text-align:right; padding: 0px } +#second_column li { margin: 5px 0pt 5px 5px; text-align:right; padding: 0px} +#element_buttons a { + border-style: solid; + border-color: rgb(238, 238, 238) rgb(222, 222, 222) rgb(222, 222, 222) rgb(238, 238, 238); + border-width: 1px; + padding: 0px 0pt 0px 25px; + display: block; + width: 128px; + background-color: #ffffff; + text-decoration: none; + font-weight: bold; + color: rgb(86, 86, 86); + background-repeat: no-repeat; + background-position: 6px center; +} +#element_buttons a:hover { + border: 1px solid #4B75B3; + background-color: #DDF0F8; + color: rgb(68, 68, 68); +} +#element_buttons a:active { + border: 1px solid rgb(147, 184, 37); + background-color: rgb(193, 223, 93); + color: rgb(51, 51, 51); +} + +#single_line_text { background-image: url('images/button_icon/single_line_text_bg.gif');} +#paragraph_text { background-image: url('images/button_icon/paragraph_text_bg.gif'); } +#multiple_choice { background-image: url('images/button_icon/multiplechoice_bg.gif'); } +#section_break { background-image: url('images/button_icon/section_break_bg.gif'); } +#checkboxes { background-image: url('images/button_icon/checkbox_bg.gif'); } +#drop_down { background-image: url('images/button_icon/dropdown_bg.gif'); } +#address { background-image: url('images/button_icon/address_bg.gif'); } +#web_site { background-image: url('images/button_icon/website_bg.gif'); } +#file_upload { background-image: url('images/button_icon/file_upload_bg.gif'); } +#number { background-image: url('images/button_icon/number_bg.gif'); } +#name_text { background-image: url('images/button_icon/name_bg.gif'); } +#date { background-image: url('images/button_icon/date_bg.gif'); } +#time { background-image: url('images/button_icon/time_bg.gif'); } +#phone { background-image: url('images/button_icon/phone_bg.gif'); } +#price { background-image: url('images/button_icon/price_bg.gif'); } +#email { background-image: url('images/button_icon/mail_bg.gif'); } +#nofields { cursor: pointer; } +#form_result .notification { margin: 0pt; padding: 15px; } +#add_elements .notification { margin: 0pt 0pt 10px; padding: 10px; text-align: center ! important; } +#add_elements .notification[class] { display: block; width: 308px; } +#element_properties .notification { margin: 20px; padding: 15px; } +#form_result li { + border: 1px solid white; + padding: 0pt; + background-color: rgb(255, 255, 255); +} +#form_result li * { cursor: pointer; } +#form_result li a.hover_ready { border: 1px solid rgb(255, 255, 255); padding: 4px 5px 2px 9px; display: block; text-decoration: none; color: rgb(68, 68, 68); } +#form_result li a.hover_ready:after { content: "."; display: block; height: 0pt; clear: both; visibility: hidden; } +#form_result li a.hover_ready { } +* html #form_result li a.hover_ready { height: 1%; } +#form_result li a.hover_ready { display: block; } +#form_result .info a { color: rgb(0, 0, 0); } +#form_result .info { border-bottom: 1px dotted rgb(204, 204, 204); width: 100% ! important; } +#form_result li a.hover_ready:hover { + border: 1px dotted #5F7EB2 ! important; + background: transparent url('images/icons/pencil.gif') no-repeat scroll 98% 4px; } +#form_result li.info a.hover_ready { padding: 7px 0pt 0pt; } +#form_result li.private { background-image: url('images/icons/locksmall.gif') ! important; background-repeat: no-repeat; background-position: 98% 7px; } +#form_result li.private .hover_ready:hover { + background-color: rgb(255, 255, 255); +} +#form_result li.current_edit { + border: 1px solid #CCCCCC; + background-color: #F3F7FB; +} +#form_result li.current_edit .hover_ready:hover { + background-color: #F3F7FB; +} +#form_result li.current_edit .desc { color: #1A5BB2 ! important; } +.arrow { + margin: 0pt 7px 0pt 0pt; + no-repeat; display: none; + position: absolute; + z-index: 0; right: 100%; +} +#form_result li.current_edit .arrow { + display: block; +} +#form_result .element_actions { + margin: -8px 10px 0px 0pt; + padding: 0pt; + display: none; + position: absolute; + right: 0pt; + line-height: 10px; + +} +#form_result li.current_edit .element_actions { + display: block; } +#sidebar form { + padding: 15px 20px; + clear: left; + border-top-style: solid; + border-top-width: 1px; + border-top-color: #CCCCCC; + border-bottom-style: solid; + border-bottom-width: 1px; + border-bottom-color: #CCCCCC; + background-color: #F3F7FB; +} +#sidebar form ul { font-size: 95%; } +#sidebar form li { padding: 0pt 0pt 7px; position: static; } +#sidebar[id] form li { display: block; } +#sidebar label, #sidebar legend { font-size: 90%; color: #1A5BB2; text-align: left; } +#sidebar .choice { font-size: 90%; color: #1A5BB2; text-align: left; } +#sidebar .choice b { color: #1A5BB2; } +#sidebar .textarea { height: 5em; } +#sidebar .radio, #sidebar .checkbox { margin: 0pt 5px 2px 15px; display: inline; } +#sidebar .radio[class] { margin-bottom: -2px; } +#sidebar .checkbox[class] { margin-bottom: 0pt; } +#sidebar .choice { margin: 0pt; display: inline; } +#sidebar .tooltip { border-bottom: medium none; } +fieldset .left, fieldset .right { margin: 3px 0pt 0pt; padding: 0pt; } +#form_properties { display: none; } +#form_properties li { margin: 4px 0pt; } +#form_properties .password { margin-left: 38px; } +.password img, .email img { margin: 2px 3px -2px 0pt; } +#element_properties { position: relative; display: none; } +#element_properties .num { + border: medium none ; + margin: 0px 15px 0pt 0pt; + padding: 0pt; + background: transparent none repeat; + position: absolute; right: 0pt; font-size: 300%; + text-align: right; width: auto; + color: #144282; } +#sidebar textarea#element_label { width: 70%; height: 3.7em; } +#sidebar .buttons { margin: 6px 0pt; text-align: center; } +#sidebar .buttons .button { margin: 0pt 5px; } + +#element_unique_span{ + margin: 0; + padding: 0; +} +#admin_only_span{ + margin: 0; + padding: 0; +} + +/* Form manager */ + +#form_manager { +margin:0pt 20px; +padding:20px 0px 10px; +} + + + +#form_manager td a { +color:#444444; +cursor:pointer; +font-size:85%; +text-decoration:none; +font-weight: bold; +} + +#grid-panel td a { +color: blue; +cursor:pointer; +font-size:100%; +font-weight: bold; +} + +#form_manager h3 { +font-size:115%; +position:relative; +font-weight: bold; +line-height: 30px; +padding-left: 5px; +} + +#form_manager td a:hover { +background-color: #D9E7FB; + +} + +#grid-panel td a:hover { +text-decoration:underline; +} + +/* Pagination */ +#paging { +clear:both; +margin-top: 0px; +padding-top: 5px; + +} +#paging a { +background-color:#EEEEEE; + +border-style: solid; +border-width: 1px; +padding:3px 6px; +text-align:center; +text-decoration:none; +color:#444444; +font-size:85%; +font-weight:bold; +} + +#paging a:hover { +background-color:#FFFFFF; +color:#350B51; +} +#form_manager .active_page { +font-size:115%; +background-color:#FFFFFF; +} + + + +.export a:hover{ + background:#D9E7FB none repeat scroll 0%; + color:#003366; + padding:8px 5pt; +} + +form li.highlighted +{ + background-color:#F3F7FB; + overflow:hidden; +} + +#error_message +{ + border:1px dashed red; + margin-bottom:1em; + padding-left:0; + padding-right:0; + padding-top:4px; + text-align:center; + width:99%; +} + +#error_message_title +{ + color:#DF0000; + font-size:125%; + margin:5px 0 5px; + padding:0; +} + +#error_message_desc +{ + color:#000; + font-size:100%; + margin:0 0 .8em; +} + +#success_message +{ + border:1px dashed #CF9919; + margin-bottom:1em; + padding-left:0; + padding-right:0; + padding-top:4px; + text-align:center; + width:99%; + background-color: #F3F7FB; +} + +#success_message_title +{ + color:#1A5BB2; + font-size:125%; + margin:5px 0 5px; + padding:0; +} + +#success_message_desc +{ + color:#000; + font-size:100%; + margin:0 0 .8em; +} + + +.global_message { + margin: 0pt; + padding: 0pt; + list-style-type: none; + width: 100%; +} + +.fix_png{ + behavior:url(css/iepngfix.htc); +} + +#appnitro_logos { + padding-left: 10px; + padding-top: 5px; +} + +/* Manage Entries page */ +#manage_entries{ + margin-bottom: 20px; +} +#manage_entries table{ + table-layout: fixed; +} +#manage_entries table div{ + overflow:hidden; + height:1.2em; + white-space: nowrap; + text-overflow:ellipsis; +} + +#manage_entries td{ + text-align: left; + border-bottom:1px solid #DEDEDE; + padding:5px; +} +#manage_entries th{ + background: #3661A1; + color: #fff; + border-right:1px dotted #fff; + padding: 5px; + text-align: left; + height:1.1em; +} +.alt{ + background: #F3F7FB; +} +#columns_preference{ + width: 100%; + margin-bottom: 20px; + overflow:hidden; +} +#columns_preference table{ + table-layout: fixed; +} +#columns_preference table div{ + overflow:hidden; + height:1.2em; + white-space: nowrap; + text-overflow:ellipsis; +} + +#columns_preference td{ + text-align: left; + border-bottom:1px solid #DEDEDE; + padding:5px 10px; +} +#columns_preference th{ + background: #3661A1; + color: #fff; + border-right:1px dotted #fff; + padding: 5px 10px; + text-align: left; +} +#cp_list{ + + float: left; + width: 50%; +} +#tv_list{ + + float: left; + width: 50%; +} +.me_action{ + width: 45px; + padding-right: 0px !important; + padding-left: 5px !important; +} +.me_number{ + width: 35px; + padding-right: 0px !important; + padding-left: 0px !important; + text-align: center !important; +} +.me_center_div{ + width: 100%; + text-align: center !important; +} +.me_right_div{ + width: 100%; + text-align: right !important; +} +#me_choose_col{ + float: right; + padding-bottom: 5px +} +#me_choose_col a{ + text-decoration:none; + border-bottom: 1px dotted #000; +} + +.breadcrumb{ + text-decoration:none; + border-bottom: 1px dotted #000; + color: #3661A1; +} +#view_entry{ + width: 100%; + margin-bottom: 20px; + overflow:hidden; +} + +#view_entry td{ + text-align: left; + border-bottom:1px solid #DEDEDE; + padding:5px 10px; +} +#view_entry th{ + background: #3661A1; + color: #fff; + border-right:1px dotted #fff; + padding: 5px 10px; + text-align: left; +} +#ve_detail{ + width: 70%; + float: left; + padding-bottom: 30px; +} +#ve_action_container{ + width: 25%; + margin-left: 20px; + float: left; +} +#ve_action{ + background-color: #FFFFCC; + overflow: hidden; + padding-bottom: 10px; + padding-left: 5px; +} +#ve_table_info{ + margin-top: 25px; +} +#ve_detail_table tbody tr:hover +{ + background-color: LemonChiffon; +} +.big_dotted_link{ + text-decoration:none; + border-bottom: 1px dotted #000; + color: #3661A1; + font-weight: bold; +} +#ve_action li{ + padding: 5px; + float: left; + width: 40%; + padding-bottom: 10px; +} +#ve_detail .entry_link{ + text-decoration:none; + border-bottom: 1px dotted #000; + color: #3661A1; + font-weight: bold; + font-size: 100%; +} + +/* edit entry */ +#edit_entry{ + width: 100%; + margin-bottom: 20px; + overflow:hidden; +} + +#ee_detail{ + width: 70%; + float: left; + padding-bottom: 30px; +} +#ee_action_container{ + width: 25%; + margin-left: 20px; + float: left; +} +#ee_action{ + background-color: #FFFFCC; + overflow: hidden; + padding-bottom: 10px; + padding-left: 5px; +} +#ee_action li{ + padding: 5px; + float: left; + width: 40%; + padding-bottom: 10px; +} +#list_buttons{ + list-style-type: none; +} + +/* email settings */ +#es_left{ + background-color:#F3F7FB; + margin-right: 20px; +} +#es_right{ + background-color:#F3F7FB; + margin-left: 20px; +} \ No newline at end of file diff --git a/index.php b/index.php new file mode 100644 index 0000000..8a08fc2 --- /dev/null +++ b/index.php @@ -0,0 +1,104 @@ + + + + +
    + +
    +

    Admin Panel Login

    +

    Please login below to access Admin Panel

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

    + +
    + \ No newline at end of file diff --git a/installer.php b/installer.php new file mode 100644 index 0000000..3557218 --- /dev/null +++ b/installer.php @@ -0,0 +1,345 @@ +Congratulations! You have completed the installation. MachForm is now installed."; + }else{ + $install_message = "An error has occured during installation."; + } + + $state = 'install_report'; + }else{ + + //do a pre installation check + $state = 'show_preinstall_check'; + + //check for PHP version + if(version_compare(PHP_VERSION,"4.3.0",">=")){ + $is_php_version_passed = true; + }else{ + $is_php_version_passed = false; + $pre_install_has_error = true; + } + + //check for MySQL version + if(version_compare(mysql_get_server_info(),"4.1.0",">=")){ + $is_mysql_version_passed = true; + }else{ + $is_mysql_version_passed = false; + $pre_install_has_error = true; + } + + //check for MySQL user,password and database existance + if(empty($mysql_connect_error)){ + $is_mysql_connect_passed = true; + }else{ + $is_mysql_connect_passed = false; + $pre_install_has_error = true; + } + + if(empty($mysql_select_db_error)){ + $is_mysql_select_db_passed = true; + }else{ + $is_mysql_select_db_passed = false; + $pre_install_has_error = true; + } + + //check for data folder permission + if(is_writable(DATA_DIR)){ + $is_data_dir_writable = true; + }else { + $is_data_dir_writable = false; + $pre_install_has_error = true; + $data_dir_writable_error = "MachForm require read and write access to this folder. Please set the correct permission."; + } + + if($pre_install_has_error){ + $pre_install_message = "Your system does not match the minimum requirements necessary. Please take the appropriate actions to correct the errors."; + }else{ + $pre_install_message = "Your system passed the minimum requirements necessary. You can now start the installation process."; + } + } + } + + } + + $hide_nav = true; +?> + + + +
    + + +
    +

    MachForm Installer Error

    +

    Please fix the following error before you can continue the installation process:

    +
    + +
    +
    +
      +
    • + +
      +

      + There doesn't seem to be a config.php file. We need this before we can get started. +

      +

      +

      In the base directory of your installation you'll find a file called config-empty.php. Open this file and fill in the required database information.



      +

      After the details are filled in you must rename the file config.php before continuing.


      +
      +
    • +
    • + +
    • +
    +
    +

    + + + +
    +

    MachForm Pre-Installation Check

    +

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

    + + + +
    +

    Remove Installer File

    +

    Please follow the step below to be able to continue:

    +
    + +
    +
    +
      +
    • + +
      +

      + MachForm is currently installed and ready. +

      +
      +

      Please remove this file (installer.php) before you can start using MachForm.


      +

      After you delete this file, you can login here.


      +
      +
    • +
    +
    +

    + + + + +
    +

    MachForm Installation Report

    +

    +
    + +
    +
    +
      + +
    • + +
    • +
    • + +
    • +
    • + +
    • +
    • + +
    • +
    • + +
    • +
    • + Important: Please delete this installer file (installer.php) now.

      After deleting this file, you can login to MachForm admin panel +
    • + +
    • + +
    • + + +
    • + +
    • + + + + +
    • + + +
    • + + +
    +
    +

    + + + +
    + \ No newline at end of file diff --git a/js/base.js b/js/base.js new file mode 100644 index 0000000..5a5c816 --- /dev/null +++ b/js/base.js @@ -0,0 +1,2993 @@ +/* Prototype JavaScript framework, version 1.5.0_rc0 + * (c) 2005 Sam Stephenson + * + * Prototype is freely distributable under the terms of an MIT-style license. + * For details, see the Prototype web site: http://prototype.conio.net/ + * +/*--------------------------------------------------------------------------*/ + +var Prototype = { + Version: '1.5.0_rc0', + ScriptFragment: '(?:)((\n|\r|.)*?)(?:<\/script>)', + + emptyFunction: function() {}, + K: function(x) {return x} +} + +var Class = { + create: function() { + return function() { + this.initialize.apply(this, arguments); + } + } +} + +var Abstract = new Object(); + +Object.extend = function(destination, source) { + for (var property in source) { + destination[property] = source[property]; + } + return destination; +} + +Object.inspect = function(object) { + try { + if (object == undefined) return 'undefined'; + if (object == null) return 'null'; + return object.inspect ? object.inspect() : object.toString(); + } catch (e) { + if (e instanceof RangeError) return '...'; + throw e; + } +} + +Function.prototype.bind = function() { + var __method = this, args = $A(arguments), object = args.shift(); + return function() { + return __method.apply(object, args.concat($A(arguments))); + } +} + +Function.prototype.bindAsEventListener = function(object) { + var __method = this; + return function(event) { + return __method.call(object, event || window.event); + } +} + +Object.extend(Number.prototype, { + toColorPart: function() { + var digits = this.toString(16); + if (this < 16) return '0' + digits; + return digits; + }, + + succ: function() { + return this + 1; + }, + + times: function(iterator) { + $R(0, this, true).each(iterator); + return this; + } +}); + +var Try = { + these: function() { + var returnValue; + + for (var i = 0; i < arguments.length; i++) { + var lambda = arguments[i]; + try { + returnValue = lambda(); + break; + } catch (e) {} + } + + return returnValue; + } +} + +/*--------------------------------------------------------------------------*/ + +Object.extend(String.prototype, { + gsub: function(pattern, replacement) { + var result = '', source = this, match; + replacement = arguments.callee.prepareReplacement(replacement); + + while (source.length > 0) { + if (match = source.match(pattern)) { + result += source.slice(0, match.index); + result += (replacement(match) || '').toString(); + source = source.slice(match.index + match[0].length); + } else { + result += source, source = ''; + } + } + return result; + }, + + sub: function(pattern, replacement, count) { + replacement = this.gsub.prepareReplacement(replacement); + count = count === undefined ? 1 : count; + + return this.gsub(pattern, function(match) { + if (--count < 0) return match[0]; + return replacement(match); + }); + }, + + scan: function(pattern, iterator) { + this.gsub(pattern, iterator); + return this; + }, + + truncate: function(length, truncation) { + length = length || 30; + truncation = truncation === undefined ? '...' : truncation; + return this.length > length ? + this.slice(0, length - truncation.length) + truncation : this; + }, + + strip: function() { + return this.replace(/^\s+/, '').replace(/\s+$/, ''); + }, + + stripTags: function() { + return this.replace(/<\/?[^>]+>/gi, ''); + }, + + stripScripts: function() { + return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), ''); + }, + + extractScripts: function() { + var matchAll = new RegExp(Prototype.ScriptFragment, 'img'); + var matchOne = new RegExp(Prototype.ScriptFragment, 'im'); + return (this.match(matchAll) || []).map(function(scriptTag) { + return (scriptTag.match(matchOne) || ['', ''])[1]; + }); + }, + + evalScripts: function() { + return this.extractScripts().map(function(script) { return eval(script) }); + }, + + escapeHTML: function() { + var div = document.createElement('div'); + var text = document.createTextNode(this); + div.appendChild(text); + return div.innerHTML; + }, + + unescapeHTML: function() { + var div = document.createElement('div'); + div.innerHTML = this.stripTags(); + return div.childNodes[0] ? div.childNodes[0].nodeValue : ''; + }, + + toQueryParams: function() { + var pairs = this.match(/^\??(.*)$/)[1].split('&'); + return pairs.inject({}, function(params, pairString) { + var pair = pairString.split('='); + params[pair[0]] = pair[1]; + return params; + }); + }, + + toArray: function() { + return this.split(''); + }, + + camelize: function() { + var oStringList = this.split('-'); + if (oStringList.length == 1) return oStringList[0]; + + var camelizedString = this.indexOf('-') == 0 + ? oStringList[0].charAt(0).toUpperCase() + oStringList[0].substring(1) + : oStringList[0]; + + for (var i = 1, len = oStringList.length; i < len; i++) { + var s = oStringList[i]; + camelizedString += s.charAt(0).toUpperCase() + s.substring(1); + } + + return camelizedString; + }, + + inspect: function() { + return "'" + this.replace(/\\/g, '\\\\').replace(/'/g, '\\\'') + "'"; + } +}); + +String.prototype.gsub.prepareReplacement = function(replacement) { + if (typeof replacement == 'function') return replacement; + var template = new Template(replacement); + return function(match) { return template.evaluate(match) }; +} + +String.prototype.parseQuery = String.prototype.toQueryParams; + +var Template = Class.create(); +Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/; +Template.prototype = { + initialize: function(template, pattern) { + this.template = template.toString(); + this.pattern = pattern || Template.Pattern; + }, + + evaluate: function(object) { + return this.template.gsub(this.pattern, function(match) { + var before = match[1]; + if (before == '\\') return match[2]; + return before + (object[match[3]] || '').toString(); + }); + } +} + +var $break = new Object(); +var $continue = new Object(); + +var Enumerable = { + each: function(iterator) { + var index = 0; + try { + this._each(function(value) { + try { + iterator(value, index++); + } catch (e) { + if (e != $continue) throw e; + } + }); + } catch (e) { + if (e != $break) throw e; + } + }, + + all: function(iterator) { + var result = true; + this.each(function(value, index) { + result = result && !!(iterator || Prototype.K)(value, index); + if (!result) throw $break; + }); + return result; + }, + + any: function(iterator) { + var result = true; + this.each(function(value, index) { + if (result = !!(iterator || Prototype.K)(value, index)) + throw $break; + }); + return result; + }, + + collect: function(iterator) { + var results = []; + this.each(function(value, index) { + results.push(iterator(value, index)); + }); + return results; + }, + + detect: function (iterator) { + var result; + this.each(function(value, index) { + if (iterator(value, index)) { + result = value; + throw $break; + } + }); + return result; + }, + + findAll: function(iterator) { + var results = []; + this.each(function(value, index) { + if (iterator(value, index)) + results.push(value); + }); + return results; + }, + + grep: function(pattern, iterator) { + var results = []; + this.each(function(value, index) { + var stringValue = value.toString(); + if (stringValue.match(pattern)) + results.push((iterator || Prototype.K)(value, index)); + }) + return results; + }, + + include: function(object) { + var found = false; + this.each(function(value) { + if (value == object) { + found = true; + throw $break; + } + }); + return found; + }, + + inject: function(memo, iterator) { + this.each(function(value, index) { + memo = iterator(memo, value, index); + }); + return memo; + }, + + invoke: function(method) { + var args = $A(arguments).slice(1); + return this.collect(function(value) { + return value[method].apply(value, args); + }); + }, + + max: function(iterator) { + var result; + this.each(function(value, index) { + value = (iterator || Prototype.K)(value, index); + if (result == undefined || value >= result) + result = value; + }); + return result; + }, + + min: function(iterator) { + var result; + this.each(function(value, index) { + value = (iterator || Prototype.K)(value, index); + if (result == undefined || value < result) + result = value; + }); + return result; + }, + + partition: function(iterator) { + var trues = [], falses = []; + this.each(function(value, index) { + ((iterator || Prototype.K)(value, index) ? + trues : falses).push(value); + }); + return [trues, falses]; + }, + + pluck: function(property) { + var results = []; + this.each(function(value, index) { + results.push(value[property]); + }); + return results; + }, + + reject: function(iterator) { + var results = []; + this.each(function(value, index) { + if (!iterator(value, index)) + results.push(value); + }); + return results; + }, + + sortBy: function(iterator) { + return this.collect(function(value, index) { + return {value: value, criteria: iterator(value, index)}; + }).sort(function(left, right) { + var a = left.criteria, b = right.criteria; + return a < b ? -1 : a > b ? 1 : 0; + }).pluck('value'); + }, + + toArray: function() { + return this.collect(Prototype.K); + }, + + zip: function() { + var iterator = Prototype.K, args = $A(arguments); + if (typeof args.last() == 'function') + iterator = args.pop(); + + var collections = [this].concat(args).map($A); + return this.map(function(value, index) { + return iterator(collections.pluck(index)); + }); + }, + + inspect: function() { + return '#'; + } +} + +Object.extend(Enumerable, { + map: Enumerable.collect, + find: Enumerable.detect, + select: Enumerable.findAll, + member: Enumerable.include, + entries: Enumerable.toArray +}); +var $A = Array.from = function(iterable) { + if (!iterable) return []; + if (iterable.toArray) { + return iterable.toArray(); + } else { + var results = []; + for (var i = 0; i < iterable.length; i++) + results.push(iterable[i]); + return results; + } +} + +Object.extend(Array.prototype, Enumerable); + +if (!Array.prototype._reverse) + Array.prototype._reverse = Array.prototype.reverse; + +Object.extend(Array.prototype, { + _each: function(iterator) { + for (var i = 0; i < this.length; i++) + iterator(this[i]); + }, + + clear: function() { + this.length = 0; + return this; + }, + + first: function() { + return this[0]; + }, + + last: function() { + return this[this.length - 1]; + }, + + compact: function() { + return this.select(function(value) { + return value != undefined || value != null; + }); + }, + + flatten: function() { + return this.inject([], function(array, value) { + return array.concat(value && value.constructor == Array ? + value.flatten() : [value]); + }); + }, + + without: function() { + var values = $A(arguments); + return this.select(function(value) { + return !values.include(value); + }); + }, + + indexOf: function(object) { + for (var i = 0; i < this.length; i++) + if (this[i] == object) return i; + return -1; + }, + + reverse: function(inline) { + return (inline !== false ? this : this.toArray())._reverse(); + }, + + inspect: function() { + return '[' + this.map(Object.inspect).join(', ') + ']'; + } +}); +var Hash = { + _each: function(iterator) { + for (var key in this) { + var value = this[key]; + if (typeof value == 'function') continue; + + var pair = [key, value]; + pair.key = key; + pair.value = value; + iterator(pair); + } + }, + + keys: function() { + return this.pluck('key'); + }, + + values: function() { + return this.pluck('value'); + }, + + merge: function(hash) { + return $H(hash).inject($H(this), function(mergedHash, pair) { + mergedHash[pair.key] = pair.value; + return mergedHash; + }); + }, + + toQueryString: function() { + return this.map(function(pair) { + return pair.map(encodeURIComponent).join('='); + }).join('&'); + }, + + inspect: function() { + return '#'; + } +} + +function $H(object) { + var hash = Object.extend({}, object || {}); + Object.extend(hash, Enumerable); + Object.extend(hash, Hash); + return hash; +} +ObjectRange = Class.create(); +Object.extend(ObjectRange.prototype, Enumerable); +Object.extend(ObjectRange.prototype, { + initialize: function(start, end, exclusive) { + this.start = start; + this.end = end; + this.exclusive = exclusive; + }, + + _each: function(iterator) { + var value = this.start; + do { + iterator(value); + value = value.succ(); + } while (this.include(value)); + }, + + include: function(value) { + if (value < this.start) + return false; + if (this.exclusive) + return value < this.end; + return value <= this.end; + } +}); + +var $R = function(start, end, exclusive) { + return new ObjectRange(start, end, exclusive); +} + +var Ajax = { + getTransport: function() { + return Try.these( + function() {return new XMLHttpRequest()}, + function() {return new ActiveXObject('Msxml2.XMLHTTP')}, + function() {return new ActiveXObject('Microsoft.XMLHTTP')} + ) || false; + }, + + activeRequestCount: 0 +} + +Ajax.Responders = { + responders: [], + + _each: function(iterator) { + this.responders._each(iterator); + }, + + register: function(responderToAdd) { + if (!this.include(responderToAdd)) + this.responders.push(responderToAdd); + }, + + unregister: function(responderToRemove) { + this.responders = this.responders.without(responderToRemove); + }, + + dispatch: function(callback, request, transport, json) { + this.each(function(responder) { + if (responder[callback] && typeof responder[callback] == 'function') { + try { + responder[callback].apply(responder, [request, transport, json]); + } catch (e) {} + } + }); + } +}; + +Object.extend(Ajax.Responders, Enumerable); + +Ajax.Responders.register({ + onCreate: function() { + Ajax.activeRequestCount++; + }, + + onComplete: function() { + Ajax.activeRequestCount--; + } +}); + +Ajax.Base = function() {}; +Ajax.Base.prototype = { + setOptions: function(options) { + this.options = { + method: 'post', + asynchronous: true, + contentType: 'application/x-www-form-urlencoded', + parameters: '' + } + Object.extend(this.options, options || {}); + }, + + responseIsSuccess: function() { + return this.transport.status == undefined + || this.transport.status == 0 + || (this.transport.status >= 200 && this.transport.status < 300); + }, + + responseIsFailure: function() { + return !this.responseIsSuccess(); + } +} + +Ajax.Request = Class.create(); +Ajax.Request.Events = + ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; + +Ajax.Request.prototype = Object.extend(new Ajax.Base(), { + initialize: function(url, options) { + this.transport = Ajax.getTransport(); + this.setOptions(options); + this.request(url); + }, + + request: function(url) { + var parameters = this.options.parameters || ''; + if (parameters.length > 0) parameters += '&_='; + + try { + this.url = url; + if (this.options.method == 'get' && parameters.length > 0) + this.url += (this.url.match(/\?/) ? '&' : '?') + parameters; + + Ajax.Responders.dispatch('onCreate', this, this.transport); + + this.transport.open(this.options.method, this.url, + this.options.asynchronous); + + if (this.options.asynchronous) { + this.transport.onreadystatechange = this.onStateChange.bind(this); + setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10); + } + + this.setRequestHeaders(); + + var body = this.options.postBody ? this.options.postBody : parameters; + this.transport.send(this.options.method == 'post' ? body : null); + + } catch (e) { + this.dispatchException(e); + } + }, + + setRequestHeaders: function() { + var requestHeaders = + ['X-Requested-With', 'XMLHttpRequest', + 'X-Prototype-Version', Prototype.Version, + 'Accept', 'text/javascript, text/html, application/xml, text/xml, */*']; + + if (this.options.method == 'post') { + requestHeaders.push('Content-type', this.options.contentType); + + /* Force "Connection: close" for Mozilla browsers to work around + * a bug where XMLHttpReqeuest sends an incorrect Content-length + * header. See Mozilla Bugzilla #246651. + */ + if (this.transport.overrideMimeType) + requestHeaders.push('Connection', 'close'); + } + + if (this.options.requestHeaders) + requestHeaders.push.apply(requestHeaders, this.options.requestHeaders); + + for (var i = 0; i < requestHeaders.length; i += 2) + this.transport.setRequestHeader(requestHeaders[i], requestHeaders[i+1]); + }, + + onStateChange: function() { + var readyState = this.transport.readyState; + if (readyState != 1) + this.respondToReadyState(this.transport.readyState); + }, + + header: function(name) { + try { + return this.transport.getResponseHeader(name); + } catch (e) {} + }, + + evalJSON: function() { + try { + return eval('(' + this.header('X-JSON') + ')'); + } catch (e) {} + }, + + evalResponse: function() { + try { + return eval(this.transport.responseText); + } catch (e) { + this.dispatchException(e); + } + }, + + respondToReadyState: function(readyState) { + var event = Ajax.Request.Events[readyState]; + var transport = this.transport, json = this.evalJSON(); + + if (event == 'Complete') { + try { + (this.options['on' + this.transport.status] + || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')] + || Prototype.emptyFunction)(transport, json); + } catch (e) { + this.dispatchException(e); + } + + if ((this.header('Content-type') || '').match(/^text\/javascript/i)) + this.evalResponse(); + } + + try { + (this.options['on' + event] || Prototype.emptyFunction)(transport, json); + Ajax.Responders.dispatch('on' + event, this, transport, json); + } catch (e) { + this.dispatchException(e); + } + + /* Avoid memory leak in MSIE: clean up the oncomplete event handler */ + if (event == 'Complete') + this.transport.onreadystatechange = Prototype.emptyFunction; + }, + + dispatchException: function(exception) { + (this.options.onException || Prototype.emptyFunction)(this, exception); + Ajax.Responders.dispatch('onException', this, exception); + } +}); + +Ajax.Updater = Class.create(); + +Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), { + initialize: function(container, url, options) { + this.containers = { + success: container.success ? $(container.success) : $(container), + failure: container.failure ? $(container.failure) : + (container.success ? null : $(container)) + } + + this.transport = Ajax.getTransport(); + this.setOptions(options); + + var onComplete = this.options.onComplete || Prototype.emptyFunction; + this.options.onComplete = (function(transport, object) { + this.updateContent(); + onComplete(transport, object); + }).bind(this); + + this.request(url); + }, + + updateContent: function() { + var receiver = this.responseIsSuccess() ? + this.containers.success : this.containers.failure; + var response = this.transport.responseText; + + if (!this.options.evalScripts) + response = response.stripScripts(); + + if (receiver) { + if (this.options.insertion) { + new this.options.insertion(receiver, response); + } else { + Element.update(receiver, response); + } + } + + if (this.responseIsSuccess()) { + if (this.onComplete) + setTimeout(this.onComplete.bind(this), 10); + } + } +}); + +Ajax.PeriodicalUpdater = Class.create(); +Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), { + initialize: function(container, url, options) { + this.setOptions(options); + this.onComplete = this.options.onComplete; + + this.frequency = (this.options.frequency || 2); + this.decay = (this.options.decay || 1); + + this.updater = {}; + this.container = container; + this.url = url; + + this.start(); + }, + + start: function() { + this.options.onComplete = this.updateComplete.bind(this); + this.onTimerEvent(); + }, + + stop: function() { + this.updater.onComplete = undefined; + clearTimeout(this.timer); + (this.onComplete || Prototype.emptyFunction).apply(this, arguments); + }, + + updateComplete: function(request) { + if (this.options.decay) { + this.decay = (request.responseText == this.lastText ? + this.decay * this.options.decay : 1); + + this.lastText = request.responseText; + } + this.timer = setTimeout(this.onTimerEvent.bind(this), + this.decay * this.frequency * 1000); + }, + + onTimerEvent: function() { + this.updater = new Ajax.Updater(this.container, this.url, this.options); + } +}); +function $() { + var results = [], element; + for (var i = 0; i < arguments.length; i++) { + element = arguments[i]; + if (typeof element == 'string') + element = document.getElementById(element); + results.push(Element.extend(element)); + } + return results.length < 2 ? results[0] : results; +} + +document.getElementsByClassName = function(className, parentElement) { + var children = ($(parentElement) || document.body).getElementsByTagName('*'); + return $A(children).inject([], function(elements, child) { + if (child.className.match(new RegExp("(^|\\s)" + className + "(\\s|$)"))) + elements.push(Element.extend(child)); + return elements; + }); +} + + + +if (!window.Element) + var Element = new Object(); + +Element.extend = function(element) { + if (!element) return; + if (_nativeExtensions) return element; + + if (!element._extended && element.tagName && element != window) { + var methods = Element.Methods, cache = Element.extend.cache; + for (property in methods) { + var value = methods[property]; + if (typeof value == 'function') + element[property] = cache.findOrStore(value); + } + } + + element._extended = true; + return element; +} + +Element.extend.cache = { + findOrStore: function(value) { + return this[value] = this[value] || function() { + return value.apply(null, [this].concat($A(arguments))); + } + } +} + +Element.Methods = { + visible: function(element) { + return $(element).style.display != 'none'; + }, + + toggle: function() { + for (var i = 0; i < arguments.length; i++) { + var element = $(arguments[i]); + Element[Element.visible(element) ? 'hide' : 'show'](element); + } + }, + + hide: function() { + for (var i = 0; i < arguments.length; i++) { + var element = $(arguments[i]); + element.style.display = 'none'; + } + }, + + show: function() { + for (var i = 0; i < arguments.length; i++) { + var element = $(arguments[i]); + element.style.display = ''; + } + }, + + remove: function(element) { + element = $(element); + element.parentNode.removeChild(element); + }, + + + showTitle: function(element) { + if ($("tooltip")) Element.removeTitle($("tooltip")); + var title = Builder.node('span', {style:'display:none', id:'tooltip', onclick:'Element.removeTitle (this)'}, [ + Builder.node('b',element.title), + Builder.node('em',element.rel) + ]); + element.parentNode.insertBefore(title, element.nextSibling); + Effect.Appear(title, {duration: 0.3}); + }, + + + removeTitle: function(element) { + Effect.Fade(element, {afterFinish:function() {Element.remove(element)},duration:0.3}); + }, + //-------------------------------------- + update: function(element, html) { + $(element).innerHTML = html.stripScripts(); + setTimeout(function() {html.evalScripts()}, 10); + }, + + replace: function(element, html) { + element = $(element); + if (element.outerHTML) { + element.outerHTML = html.stripScripts(); + } else { + var range = element.ownerDocument.createRange(); + range.selectNodeContents(element); + element.parentNode.replaceChild( + range.createContextualFragment(html.stripScripts()), element); + } + setTimeout(function() {html.evalScripts()}, 10); + }, + + getHeight: function(element) { + element = $(element); + return element.offsetHeight; + }, + + classNames: function(element) { + return new Element.ClassNames(element); + }, + + hasClassName: function(element, className) { + if (!(element = $(element))) return; + return Element.classNames(element).include(className); + }, + + addClassName: function(element, className) { + if (!(element = $(element))) return; + return Element.classNames(element).add(className); + }, + + removeClassName: function(element, className) { + if (!(element = $(element))) return; + return Element.classNames(element).remove(className); + }, + + // removes whitespace-only text node children + cleanWhitespace: function(element) { + element = $(element); + for (var i = 0; i < element.childNodes.length; i++) { + var node = element.childNodes[i]; + if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) + Element.remove(node); + } + }, + + empty: function(element) { + return $(element).innerHTML.match(/^\s*$/); + }, + + childOf: function(element, ancestor) { + element = $(element), ancestor = $(ancestor); + while (element = element.parentNode) + if (element == ancestor) return true; + return false; + }, + + scrollTo: function(element) { + element = $(element); + var x = element.x ? element.x : element.offsetLeft, + y = element.y ? element.y : element.offsetTop; + window.scrollTo(x, y); + }, + + getStyle: function(element, style) { + element = $(element); + var value = element.style[style.camelize()]; + if (!value) { + if (document.defaultView && document.defaultView.getComputedStyle) { + var css = document.defaultView.getComputedStyle(element, null); + value = css ? css.getPropertyValue(style) : null; + } else if (element.currentStyle) { + value = element.currentStyle[style.camelize()]; + } + } + + if (window.opera && ['left', 'top', 'right', 'bottom'].include(style)) + if (Element.getStyle(element, 'position') == 'static') value = 'auto'; + + return value == 'auto' ? null : value; + }, + + setStyle: function(element, style) { + element = $(element); + for (var name in style) + element.style[name.camelize()] = style[name]; + }, + + getDimensions: function(element) { + element = $(element); + if (Element.getStyle(element, 'display') != 'none') + return {width: element.offsetWidth, height: element.offsetHeight}; + + // All *Width and *Height properties give 0 on elements with display none, + // so enable the element temporarily + var els = element.style; + var originalVisibility = els.visibility; + var originalPosition = els.position; + els.visibility = 'hidden'; + els.position = 'absolute'; + els.display = ''; + var originalWidth = element.clientWidth; + var originalHeight = element.clientHeight; + els.display = 'none'; + els.position = originalPosition; + els.visibility = originalVisibility; + return {width: originalWidth, height: originalHeight}; + }, + + makePositioned: function(element) { + element = $(element); + var pos = Element.getStyle(element, 'position'); + if (pos == 'static' || !pos) { + element._madePositioned = true; + element.style.position = 'relative'; + // Opera returns the offset relative to the positioning context, when an + // element is position relative but top and left have not been defined + if (window.opera) { + element.style.top = 0; + element.style.left = 0; + } + } + }, + + undoPositioned: function(element) { + element = $(element); + if (element._madePositioned) { + element._madePositioned = undefined; + element.style.position = + element.style.top = + element.style.left = + element.style.bottom = + element.style.right = ''; + } + }, + + makeClipping: function(element) { + element = $(element); + if (element._overflow) return; + element._overflow = element.style.overflow; + if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden') + element.style.overflow = 'hidden'; + }, + + undoClipping: function(element) { + element = $(element); + if (element._overflow) return; + element.style.overflow = element._overflow; + element._overflow = undefined; + } +} + +Object.extend(Element, Element.Methods); + +var _nativeExtensions = false; + +if(!HTMLElement && /Konqueror|Safari|KHTML/.test(navigator.userAgent)) { + var HTMLElement = {} + HTMLElement.prototype = document.createElement('div').__proto__; +} + +Element.addMethods = function(methods) { + Object.extend(Element.Methods, methods || {}); + + if(typeof HTMLElement != 'undefined') { + var methods = Element.Methods, cache = Element.extend.cache; + for (property in methods) { + var value = methods[property]; + if (typeof value == 'function') + HTMLElement.prototype[property] = cache.findOrStore(value); + } + _nativeExtensions = true; + } +} + +Element.addMethods(); + +var Toggle = new Object(); +Toggle.display = Element.toggle; + + +Element.ClassNames = Class.create(); +Element.ClassNames.prototype = { + initialize: function(element) { + this.element = $(element); + }, + + _each: function(iterator) { + this.element.className.split(/\s+/).select(function(name) { + return name.length > 0; + })._each(iterator); + }, + + set: function(className) { + this.element.className = className; + }, + + add: function(classNameToAdd) { + if (this.include(classNameToAdd)) return; + this.set(this.toArray().concat(classNameToAdd).join(' ')); + }, + + remove: function(classNameToRemove) { + if (!this.include(classNameToRemove)) return; + this.set(this.select(function(className) { + return className != classNameToRemove; + }).join(' ')); + }, + + toString: function() { + return this.toArray().join(' '); + } +} + +Object.extend(Element.ClassNames.prototype, Enumerable); +var Selector = Class.create(); +Selector.prototype = { + initialize: function(expression) { + this.params = {classNames: []}; + this.expression = expression.toString().strip(); + this.parseExpression(); + this.compileMatcher(); + }, + + parseExpression: function() { + function abort(message) { throw 'Parse error in selector: ' + message; } + + if (this.expression == '') abort('empty expression'); + + var params = this.params, expr = this.expression, match, modifier, clause, rest; + while (match = expr.match(/^(.*)\[([a-z0-9_:-]+?)(?:([~\|!]?=)(?:"([^"]*)"|([^\]\s]*)))?\]$/i)) { + params.attributes = params.attributes || []; + params.attributes.push({name: match[2], operator: match[3], value: match[4] || match[5] || ''}); + expr = match[1]; + } + + if (expr == '*') return this.params.wildcard = true; + + while (match = expr.match(/^([^a-z0-9_-])?([a-z0-9_-]+)(.*)/i)) { + modifier = match[1], clause = match[2], rest = match[3]; + switch (modifier) { + case '#': params.id = clause; break; + case '.': params.classNames.push(clause); break; + case '': + case undefined: params.tagName = clause.toUpperCase(); break; + default: abort(expr.inspect()); + } + expr = rest; + } + + if (expr.length > 0) abort(expr.inspect()); + }, + + buildMatchExpression: function() { + var params = this.params, conditions = [], clause; + + if (params.wildcard) + conditions.push('true'); + if (clause = params.id) + conditions.push('element.id == ' + clause.inspect()); + if (clause = params.tagName) + conditions.push('element.tagName.toUpperCase() == ' + clause.inspect()); + if ((clause = params.classNames).length > 0) + for (var i = 0; i < clause.length; i++) + conditions.push('Element.hasClassName(element, ' + clause[i].inspect() + ')'); + if (clause = params.attributes) { + clause.each(function(attribute) { + var value = 'element.getAttribute(' + attribute.name.inspect() + ')'; + var splitValueBy = function(delimiter) { + return value + ' && ' + value + '.split(' + delimiter.inspect() + ')'; + } + + switch (attribute.operator) { + case '=': conditions.push(value + ' == ' + attribute.value.inspect()); break; + case '~=': conditions.push(splitValueBy(' ') + '.include(' + attribute.value.inspect() + ')'); break; + case '|=': conditions.push( + splitValueBy('-') + '.first().toUpperCase() == ' + attribute.value.toUpperCase().inspect() + ); break; + case '!=': conditions.push(value + ' != ' + attribute.value.inspect()); break; + case '': + case undefined: conditions.push(value + ' != null'); break; + default: throw 'Unknown operator ' + attribute.operator + ' in selector'; + } + }); + } + + return conditions.join(' && '); + }, + + compileMatcher: function() { + this.match = new Function('element', 'if (!element.tagName) return false; \ + return ' + this.buildMatchExpression()); + }, + + findElements: function(scope) { + var element; + + if (element = $(this.params.id)) + if (this.match(element)) + if (!scope || Element.childOf(element, scope)) + return [element]; + + scope = (scope || document).getElementsByTagName(this.params.tagName || '*'); + + var results = []; + for (var i = 0; i < scope.length; i++) + if (this.match(element = scope[i])) + results.push(Element.extend(element)); + + return results; + }, + + toString: function() { + return this.expression; + } +} + +function $$() { + return $A(arguments).map(function(expression) { + return expression.strip().split(/\s+/).inject([null], function(results, expr) { + var selector = new Selector(expr); + return results.map(selector.findElements.bind(selector)).flatten(); + }); + }).flatten(); +} +/*--------------------------------------------------------------------------*/ + +Abstract.EventObserver = function() {} +Abstract.EventObserver.prototype = { + initialize: function(element, callback) { + this.element = $(element); + this.callback = callback; + + this.lastValue = this.getValue(); + if (this.element.tagName.toLowerCase() == 'form') + this.registerFormCallbacks(); + else + this.registerCallback(this.element); + }, + + onElementEvent: function() { + var value = this.getValue(); + if (this.lastValue != value) { + this.callback(this.element, value); + this.lastValue = value; + } + }, + + registerFormCallbacks: function() { + var elements = Form.getElements(this.element); + for (var i = 0; i < elements.length; i++) + this.registerCallback(elements[i]); + }, + + registerCallback: function(element) { + if (element.type) { + switch (element.type.toLowerCase()) { + case 'checkbox': + case 'radio': + Event.observe(element, 'click', this.onElementEvent.bind(this)); + break; + case 'password': + case 'text': + case 'textarea': + case 'select-one': + case 'select-multiple': + Event.observe(element, 'change', this.onElementEvent.bind(this)); + break; + } + } + } +} + +if (!window.Event) { + var Event = new Object(); +} + +Object.extend(Event, { + KEY_BACKSPACE: 8, + KEY_TAB: 9, + KEY_RETURN: 13, + KEY_ESC: 27, + KEY_LEFT: 37, + KEY_UP: 38, + KEY_RIGHT: 39, + KEY_DOWN: 40, + KEY_DELETE: 46, + + element: function(event) { + return event.target || event.srcElement; + }, + + isLeftClick: function(event) { + return (((event.which) && (event.which == 1)) || + ((event.button) && (event.button == 1))); + }, + + pointerX: function(event) { + return event.pageX || (event.clientX + + (document.documentElement.scrollLeft || document.body.scrollLeft)); + }, + + pointerY: function(event) { + return event.pageY || (event.clientY + + (document.documentElement.scrollTop || document.body.scrollTop)); + }, + + stop: function(event) { + if (event.preventDefault) { + event.preventDefault(); + event.stopPropagation(); + } else { + event.returnValue = false; + event.cancelBubble = true; + } + }, + + // find the first node with the given tagName, starting from the + // node the event was triggered on; traverses the DOM upwards + findElement: function(event, tagName) { + var element = Event.element(event); + while (element.parentNode && (!element.tagName || + (element.tagName.toUpperCase() != tagName.toUpperCase()))) + element = element.parentNode; + return element; + }, + + observers: false, + + _observeAndCache: function(element, name, observer, useCapture) { + if (!this.observers) this.observers = []; + if (element.addEventListener) { + this.observers.push([element, name, observer, useCapture]); + element.addEventListener(name, observer, useCapture); + } else if (element.attachEvent) { + this.observers.push([element, name, observer, useCapture]); + element.attachEvent('on' + name, observer); + } + }, + + unloadCache: function() { + if (!Event.observers) return; + for (var i = 0; i < Event.observers.length; i++) { + Event.stopObserving.apply(this, Event.observers[i]); + Event.observers[i][0] = null; + } + Event.observers = false; + }, + + observe: function(element, name, observer, useCapture) { + var element = $(element); + useCapture = useCapture || false; + + if (name == 'keypress' && + (navigator.appVersion.match(/Konqueror|Safari|KHTML/) + || element.attachEvent)) + name = 'keydown'; + + this._observeAndCache(element, name, observer, useCapture); + }, + + stopObserving: function(element, name, observer, useCapture) { + var element = $(element); + useCapture = useCapture || false; + + if (name == 'keypress' && + (navigator.appVersion.match(/Konqueror|Safari|KHTML/) + || element.detachEvent)) + name = 'keydown'; + + if (element.removeEventListener) { + element.removeEventListener(name, observer, useCapture); + } else if (element.detachEvent) { + element.detachEvent('on' + name, observer); + } + } +}); + +/* prevent memory leaks in IE */ +if (navigator.appVersion.match(/\bMSIE\b/)) + Event.observe(window, 'unload', Event.unloadCache, false); +var Position = { + // set to true if needed, warning: firefox performance problems + // NOT neeeded for page scrolling, only if draggable contained in + // scrollable elements + includeScrollOffsets: false, + + // must be called before calling withinIncludingScrolloffset, every time the + // page is scrolled + prepare: function() { + this.deltaX = window.pageXOffset + || document.documentElement.scrollLeft + || document.body.scrollLeft + || 0; + this.deltaY = window.pageYOffset + || document.documentElement.scrollTop + || document.body.scrollTop + || 0; + }, + + realOffset: function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.scrollTop || 0; + valueL += element.scrollLeft || 0; + element = element.parentNode; + } while (element); + return [valueL, valueT]; + }, + + cumulativeOffset: function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + element = element.offsetParent; + } while (element); + return [valueL, valueT]; + }, + + positionedOffset: function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + element = element.offsetParent; + if (element) { + p = Element.getStyle(element, 'position'); + if (p == 'relative' || p == 'absolute') break; + } + } while (element); + return [valueL, valueT]; + }, + + offsetParent: function(element) { + if (element.offsetParent) return element.offsetParent; + if (element == document.body) return element; + + while ((element = element.parentNode) && element != document.body) + if (Element.getStyle(element, 'position') != 'static') + return element; + + return document.body; + }, + + // caches x/y coordinate pair to use with overlap + within: function(element, x, y) { + if (this.includeScrollOffsets) + return this.withinIncludingScrolloffsets(element, x, y); + this.xcomp = x; + this.ycomp = y; + this.offset = this.cumulativeOffset(element); + + return (y >= this.offset[1] && + y < this.offset[1] + element.offsetHeight && + x >= this.offset[0] && + x < this.offset[0] + element.offsetWidth); + }, + + withinIncludingScrolloffsets: function(element, x, y) { + var offsetcache = this.realOffset(element); + + this.xcomp = x + offsetcache[0] - this.deltaX; + this.ycomp = y + offsetcache[1] - this.deltaY; + this.offset = this.cumulativeOffset(element); + + return (this.ycomp >= this.offset[1] && + this.ycomp < this.offset[1] + element.offsetHeight && + this.xcomp >= this.offset[0] && + this.xcomp < this.offset[0] + element.offsetWidth); + }, + + // within must be called directly before + overlap: function(mode, element) { + if (!mode) return 0; + if (mode == 'vertical') + return ((this.offset[1] + element.offsetHeight) - this.ycomp) / + element.offsetHeight; + if (mode == 'horizontal') + return ((this.offset[0] + element.offsetWidth) - this.xcomp) / + element.offsetWidth; + }, + + clone: function(source, target) { + source = $(source); + target = $(target); + target.style.position = 'absolute'; + var offsets = this.cumulativeOffset(source); + target.style.top = offsets[1] + 'px'; + target.style.left = offsets[0] + 'px'; + target.style.width = source.offsetWidth + 'px'; + target.style.height = source.offsetHeight + 'px'; + }, + + page: function(forElement) { + var valueT = 0, valueL = 0; + + var element = forElement; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + + // Safari fix + if (element.offsetParent==document.body) + if (Element.getStyle(element,'position')=='absolute') break; + + } while (element = element.offsetParent); + + element = forElement; + do { + valueT -= element.scrollTop || 0; + valueL -= element.scrollLeft || 0; + } while (element = element.parentNode); + + return [valueL, valueT]; + }, + + clone: function(source, target) { + var options = Object.extend({ + setLeft: true, + setTop: true, + setWidth: true, + setHeight: true, + offsetTop: 0, + offsetLeft: 0 + }, arguments[2] || {}) + + // find page position of source + source = $(source); + var p = Position.page(source); + + // find coordinate system to use + target = $(target); + var delta = [0, 0]; + var parent = null; + // delta [0,0] will do fine with position: fixed elements, + // position:absolute needs offsetParent deltas + if (Element.getStyle(target,'position') == 'absolute') { + parent = Position.offsetParent(target); + delta = Position.page(parent); + } + + // correct by body offsets (fixes Safari) + if (parent == document.body) { + delta[0] -= document.body.offsetLeft; + delta[1] -= document.body.offsetTop; + } + + // set position + if(options.setLeft) target.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px'; + if(options.setTop) target.style.top = (p[1] - delta[1] + options.offsetTop) + 'px'; + if(options.setWidth) target.style.width = source.offsetWidth + 'px'; + if(options.setHeight) target.style.height = source.offsetHeight + 'px'; + }, + + absolutize: function(element) { + element = $(element); + if (element.style.position == 'absolute') return; + Position.prepare(); + + var offsets = Position.positionedOffset(element); + var top = offsets[1]; + var left = offsets[0]; + var width = element.clientWidth; + var height = element.clientHeight; + + element._originalLeft = left - parseFloat(element.style.left || 0); + element._originalTop = top - parseFloat(element.style.top || 0); + element._originalWidth = element.style.width; + element._originalHeight = element.style.height; + + element.style.position = 'absolute'; + element.style.top = top + 'px';; + element.style.left = left + 'px';; + element.style.width = width + 'px';; + element.style.height = height + 'px';; + }, + + relativize: function(element) { + element = $(element); + if (element.style.position == 'relative') return; + Position.prepare(); + + element.style.position = 'relative'; + var top = parseFloat(element.style.top || 0) - (element._originalTop || 0); + var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0); + + element.style.top = top + 'px'; + element.style.left = left + 'px'; + element.style.height = element._originalHeight; + element.style.width = element._originalWidth; + } +} + +// Safari returns margins on body which is incorrect if the child is absolutely +// positioned. For performance reasons, redefine Position.cumulativeOffset for +// KHTML/WebKit only. +if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) { + Position.cumulativeOffset = function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + if (element.offsetParent == document.body) + if (Element.getStyle(element, 'position') == 'absolute') break; + + element = element.offsetParent; + } while (element); + + return [valueL, valueT]; + } +} + +// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) +// Contributors: +// Justin Palmer (http://encytemedia.com/) +// Mark Pilgrim (http://diveintomark.org/) +// Martin Bialasinki +// +// See scriptaculous.js for full license. + +// converts rgb() and #xxx to #xxxxxx format, +// returns self (or first argument) if not convertable +String.prototype.parseColor = function() { + var color = '#'; + if(this.slice(0,4) == 'rgb(') { + var cols = this.slice(4,this.length-1).split(','); + var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3); + } else { + if(this.slice(0,1) == '#') { + if(this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase(); + if(this.length==7) color = this.toLowerCase(); + } + } + return(color.length==7 ? color : (arguments[0] || this)); +} + +/*--------------------------------------------------------------------------*/ + +Element.collectTextNodes = function(element) { + return $A($(element).childNodes).collect( function(node) { + return (node.nodeType==3 ? node.nodeValue : + (node.hasChildNodes() ? Element.collectTextNodes(node) : '')); + }).flatten().join(''); +} + +Element.collectTextNodesIgnoreClass = function(element, className) { + return $A($(element).childNodes).collect( function(node) { + return (node.nodeType==3 ? node.nodeValue : + ((node.hasChildNodes() && !Element.hasClassName(node,className)) ? + Element.collectTextNodesIgnoreClass(node, className) : '')); + }).flatten().join(''); +} + +Element.setContentZoom = function(element, percent) { + element = $(element); + Element.setStyle(element, {fontSize: (percent/100) + 'em'}); + if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0); +} + +Element.getOpacity = function(element){ + var opacity; + if (opacity = Element.getStyle(element, 'opacity')) + return parseFloat(opacity); + if (opacity = (Element.getStyle(element, 'filter') || '').match(/alpha\(opacity=(.*)\)/)) + if(opacity[1]) return parseFloat(opacity[1]) / 100; + return 1.0; +} + +Element.setOpacity = function(element, value){ + element= $(element); + if (value == 1){ + Element.setStyle(element, { opacity: + (/Gecko/.test(navigator.userAgent) && !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ? + 0.999999 : null }); + if(/MSIE/.test(navigator.userAgent)) + Element.setStyle(element, {filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'')}); + } else { + if(value < 0.00001) value = 0; + Element.setStyle(element, {opacity: value}); + if(/MSIE/.test(navigator.userAgent)) + Element.setStyle(element, + { filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'') + + 'alpha(opacity='+value*100+')' }); + } +} + +Element.getInlineOpacity = function(element){ + return $(element).style.opacity || ''; +} + +Element.childrenWithClassName = function(element, className, findFirst) { + var classNameRegExp = new RegExp("(^|\\s)" + className + "(\\s|$)"); + var results = $A($(element).getElementsByTagName('*'))[findFirst ? 'detect' : 'select']( function(c) { + return (c.className && c.className.match(classNameRegExp)); + }); + if(!results) results = []; + return results; +} + +Element.forceRerendering = function(element) { + try { + element = $(element); + var n = document.createTextNode(' '); + element.appendChild(n); + element.removeChild(n); + } catch(e) { } +}; + + + +/*--------------------------------------------------------------------------*/ + +var Effect = { + tagifyText: function(element) { + if(typeof Builder == 'undefined') + throw("Effect.tagifyText requires including script.aculo.us' builder.js library"); + + var tagifyStyle = 'position:relative'; + if(/MSIE/.test(navigator.userAgent)) tagifyStyle += ';zoom:1'; + element = $(element); + $A(element.childNodes).each( function(child) { + if(child.nodeType==3) { + child.nodeValue.toArray().each( function(character) { + element.insertBefore( + Builder.node('span',{style: tagifyStyle}, + character == ' ' ? String.fromCharCode(160) : character), + child); + }); + Element.remove(child); + } + }); + }, + multiple: function(element, effect) { + var elements; + if(((typeof element == 'object') || + (typeof element == 'function')) && + (element.length)) + elements = element; + else + elements = $(element).childNodes; + + var options = Object.extend({ + speed: 0.1, + delay: 0.0 + }, arguments[2] || {}); + var masterDelay = options.delay; + + $A(elements).each( function(element, index) { + new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay })); + }); + }, + PAIRS: { + 'slide': ['SlideDown','SlideUp'], + 'blind': ['BlindDown','BlindUp'], + 'appear': ['Appear','Fade'] + }, + toggle: function(element, effect) { + element = $(element); + effect = (effect || 'appear').toLowerCase(); + var options = Object.extend({ + queue: { position:'end', scope:(element.id || 'global'), limit: 1 } + }, arguments[2] || {}); + Effect[element.visible() ? + Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options); + } +}; + +var Effect2 = Effect; // deprecated + +/* ------------- transitions ------------- */ + +Effect.Transitions = {} + +Effect.Transitions.linear = Prototype.K; + +Effect.Transitions.sinoidal = function(pos) { + return (-Math.cos(pos*Math.PI)/2) + 0.5; +} +Effect.Transitions.reverse = function(pos) { + return 1-pos; +} +Effect.Transitions.flicker = function(pos) { + return ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4; +} +Effect.Transitions.wobble = function(pos) { + return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5; +} +Effect.Transitions.pulse = function(pos) { + return (Math.floor(pos*10) % 2 == 0 ? + (pos*10-Math.floor(pos*10)) : 1-(pos*10-Math.floor(pos*10))); +} +Effect.Transitions.none = function(pos) { + return 0; +} +Effect.Transitions.full = function(pos) { + return 1; +} + +/* ------------- core effects ------------- */ + +Effect.ScopedQueue = Class.create(); +Object.extend(Object.extend(Effect.ScopedQueue.prototype, Enumerable), { + initialize: function() { + this.effects = []; + this.interval = null; + }, + _each: function(iterator) { + this.effects._each(iterator); + }, + add: function(effect) { + var timestamp = new Date().getTime(); + + var position = (typeof effect.options.queue == 'string') ? + effect.options.queue : effect.options.queue.position; + + switch(position) { + case 'front': + // move unstarted effects after this effect + this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) { + e.startOn += effect.finishOn; + e.finishOn += effect.finishOn; + }); + break; + case 'end': + // start effect after last queued effect has finished + timestamp = this.effects.pluck('finishOn').max() || timestamp; + break; + } + + effect.startOn += timestamp; + effect.finishOn += timestamp; + + if(!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit)) + this.effects.push(effect); + + if(!this.interval) + this.interval = setInterval(this.loop.bind(this), 40); + }, + remove: function(effect) { + this.effects = this.effects.reject(function(e) { return e==effect }); + if(this.effects.length == 0) { + clearInterval(this.interval); + this.interval = null; + } + }, + loop: function() { + var timePos = new Date().getTime(); + this.effects.invoke('loop', timePos); + } +}); + +Effect.Queues = { + instances: $H(), + get: function(queueName) { + if(typeof queueName != 'string') return queueName; + + if(!this.instances[queueName]) + this.instances[queueName] = new Effect.ScopedQueue(); + + return this.instances[queueName]; + } +} +Effect.Queue = Effect.Queues.get('global'); + +Effect.DefaultOptions = { + transition: Effect.Transitions.sinoidal, + duration: 1.0, // seconds + fps: 25.0, // max. 25fps due to Effect.Queue implementation + sync: false, // true for combining + from: 0.0, + to: 1.0, + delay: 0.0, + queue: 'parallel' +} + +Effect.Base = function() {}; +Effect.Base.prototype = { + position: null, + start: function(options) { + this.options = Object.extend(Object.extend({},Effect.DefaultOptions), options || {}); + this.currentFrame = 0; + this.state = 'idle'; + this.startOn = this.options.delay*1000; + this.finishOn = this.startOn + (this.options.duration*1000); + this.event('beforeStart'); + if(!this.options.sync) + Effect.Queues.get(typeof this.options.queue == 'string' ? + 'global' : this.options.queue.scope).add(this); + }, + loop: function(timePos) { + if(timePos >= this.startOn) { + if(timePos >= this.finishOn) { + this.render(1.0); + this.cancel(); + this.event('beforeFinish'); + if(this.finish) this.finish(); + this.event('afterFinish'); + return; + } + var pos = (timePos - this.startOn) / (this.finishOn - this.startOn); + var frame = Math.round(pos * this.options.fps * this.options.duration); + if(frame > this.currentFrame) { + this.render(pos); + this.currentFrame = frame; + } + } + }, + render: function(pos) { + if(this.state == 'idle') { + this.state = 'running'; + this.event('beforeSetup'); + if(this.setup) this.setup(); + this.event('afterSetup'); + } + if(this.state == 'running') { + if(this.options.transition) pos = this.options.transition(pos); + pos *= (this.options.to-this.options.from); + pos += this.options.from; + this.position = pos; + this.event('beforeUpdate'); + if(this.update) this.update(pos); + this.event('afterUpdate'); + } + }, + cancel: function() { + if(!this.options.sync) + Effect.Queues.get(typeof this.options.queue == 'string' ? + 'global' : this.options.queue.scope).remove(this); + this.state = 'finished'; + }, + event: function(eventName) { + if(this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this); + if(this.options[eventName]) this.options[eventName](this); + }, + inspect: function() { + return '#'; + } +} + + + +Effect.Opacity = Class.create(); +Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), { + initialize: function(element) { + this.element = $(element); + // make this work on IE on elements without 'layout' + if(/MSIE/.test(navigator.userAgent) && (!this.element.currentStyle.hasLayout)) + this.element.setStyle({zoom: 1}); + var options = Object.extend({ + from: this.element.getOpacity() || 0.0, + to: 1.0 + }, arguments[1] || {}); + this.start(options); + }, + update: function(position) { + this.element.setOpacity(position); + } +}); + +Effect.Move = Class.create(); +Object.extend(Object.extend(Effect.Move.prototype, Effect.Base.prototype), { + initialize: function(element) { + this.element = $(element); + var options = Object.extend({ + x: 0, + y: 0, + mode: 'relative' + }, arguments[1] || {}); + this.start(options); + }, + setup: function() { + // Bug in Opera: Opera returns the "real" position of a static element or + // relative element that does not have top/left explicitly set. + // ==> Always set top and left for position relative elements in your stylesheets + // (to 0 if you do not need them) + this.element.makePositioned(); + this.originalLeft = parseFloat(this.element.getStyle('left') || '0'); + this.originalTop = parseFloat(this.element.getStyle('top') || '0'); + if(this.options.mode == 'absolute') { + // absolute movement, so we need to calc deltaX and deltaY + this.options.x = this.options.x - this.originalLeft; + this.options.y = this.options.y - this.originalTop; + } + }, + update: function(position) { + this.element.setStyle({ + left: Math.round(this.options.x * position + this.originalLeft) + 'px', + top: Math.round(this.options.y * position + this.originalTop) + 'px' + }); + } +}); + +// for backwards compatibility +Effect.MoveBy = function(element, toTop, toLeft) { + return new Effect.Move(element, + Object.extend({ x: toLeft, y: toTop }, arguments[3] || {})); +}; + + + + +['setOpacity','getOpacity','getInlineOpacity','forceRerendering','setContentZoom', + 'collectTextNodes','collectTextNodesIgnoreClass','childrenWithClassName'].each( + function(f) { Element.Methods[f] = Element[f]; } +); + +Element.Methods.visualEffect = function(element, effect, options) { + s = effect.gsub(/_/, '-').camelize(); + effect_class = s.charAt(0).toUpperCase() + s.substring(1); + new Effect[effect_class](element, options); + return $(element); +}; + +Element.addMethods(); + +// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) +// (c) 2005 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz) +// +// See scriptaculous.js for full license. + +/*--------------------------------------------------------------------------*/ + +if(typeof Effect == 'undefined') + throw("dragdrop.js requires including script.aculo.us' effects.js library"); + +var Droppables = { + drops: [], + + remove: function(element) { + this.drops = this.drops.reject(function(d) { return d.element==$(element) }); + }, + + add: function(element) { + element = $(element); + var options = Object.extend({ + greedy: true, + hoverclass: null, + tree: false + }, arguments[1] || {}); + + // cache containers + if(options.containment) { + options._containers = []; + var containment = options.containment; + if((typeof containment == 'object') && + (containment.constructor == Array)) { + containment.each( function(c) { options._containers.push($(c)) }); + } else { + options._containers.push($(containment)); + } + } + + if(options.accept) options.accept = [options.accept].flatten(); + + Element.makePositioned(element); // fix IE + options.element = element; + + this.drops.push(options); + }, + + findDeepestChild: function(drops) { + deepest = drops[0]; + + for (i = 1; i < drops.length; ++i) + if (Element.isParent(drops[i].element, deepest.element)) + deepest = drops[i]; + + return deepest; + }, + + isContained: function(element, drop) { + var containmentNode; + if(drop.tree) { + containmentNode = element.treeNode; + } else { + containmentNode = element.parentNode; + } + return drop._containers.detect(function(c) { return containmentNode == c }); + }, + + isAffected: function(point, element, drop) { + return ( + (drop.element!=element) && + ((!drop._containers) || + this.isContained(element, drop)) && + ((!drop.accept) || + (Element.classNames(element).detect( + function(v) { return drop.accept.include(v) } ) )) && + Position.within(drop.element, point[0], point[1]) ); + }, + + deactivate: function(drop) { + if(drop.hoverclass) + Element.removeClassName(drop.element, drop.hoverclass); + this.last_active = null; + }, + + activate: function(drop) { + if(drop.hoverclass) + Element.addClassName(drop.element, drop.hoverclass); + this.last_active = drop; + }, + + show: function(point, element) { + if(!this.drops.length) return; + var affected = []; + + if(this.last_active) this.deactivate(this.last_active); + this.drops.each( function(drop) { + if(Droppables.isAffected(point, element, drop)) + affected.push(drop); + }); + + if(affected.length>0) { + drop = Droppables.findDeepestChild(affected); + Position.within(drop.element, point[0], point[1]); + if(drop.onHover) + drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element)); + + Droppables.activate(drop); + } + }, + + fire: function(event, element) { + if(!this.last_active) return; + Position.prepare(); + + if (this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active)) + if (this.last_active.onDrop) + this.last_active.onDrop(element, this.last_active.element, event); + }, + + reset: function() { + if(this.last_active) + this.deactivate(this.last_active); + } +} + +var Draggables = { + drags: [], + observers: [], + + register: function(draggable) { + if(this.drags.length == 0) { + this.eventMouseUp = this.endDrag.bindAsEventListener(this); + this.eventMouseMove = this.updateDrag.bindAsEventListener(this); + this.eventKeypress = this.keyPress.bindAsEventListener(this); + + Event.observe(document, "mouseup", this.eventMouseUp); + Event.observe(document, "mousemove", this.eventMouseMove); + Event.observe(document, "keypress", this.eventKeypress); + } + this.drags.push(draggable); + }, + + unregister: function(draggable) { + this.drags = this.drags.reject(function(d) { return d==draggable }); + if(this.drags.length == 0) { + Event.stopObserving(document, "mouseup", this.eventMouseUp); + Event.stopObserving(document, "mousemove", this.eventMouseMove); + Event.stopObserving(document, "keypress", this.eventKeypress); + } + }, + + activate: function(draggable) { + window.focus(); // allows keypress events if window isn't currently focused, fails for Safari + this.activeDraggable = draggable; + }, + + deactivate: function() { + this.activeDraggable = null; + }, + + updateDrag: function(event) { + if(!this.activeDraggable) return; + var pointer = [Event.pointerX(event), Event.pointerY(event)]; + // Mozilla-based browsers fire successive mousemove events with + // the same coordinates, prevent needless redrawing (moz bug?) + if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return; + this._lastPointer = pointer; + this.activeDraggable.updateDrag(event, pointer); + }, + + endDrag: function(event) { + if(!this.activeDraggable) return; + this._lastPointer = null; + this.activeDraggable.endDrag(event); + this.activeDraggable = null; + }, + + keyPress: function(event) { + if(this.activeDraggable) + this.activeDraggable.keyPress(event); + }, + + addObserver: function(observer) { + this.observers.push(observer); + this._cacheObserverCallbacks(); + }, + + removeObserver: function(element) { // element instead of observer fixes mem leaks + this.observers = this.observers.reject( function(o) { return o.element==element }); + this._cacheObserverCallbacks(); + }, + + notify: function(eventName, draggable, event) { // 'onStart', 'onEnd', 'onDrag' + if(this[eventName+'Count'] > 0) + this.observers.each( function(o) { + if(o[eventName]) o[eventName](eventName, draggable, event); + }); + }, + + _cacheObserverCallbacks: function() { + ['onStart','onEnd','onDrag'].each( function(eventName) { + Draggables[eventName+'Count'] = Draggables.observers.select( + function(o) { return o[eventName]; } + ).length; + }); + } +} + + + +var Draggable = Class.create(); +Draggable._revertCache = {}; +Draggable._dragging = {}; + +Draggable.prototype = { + initialize: function(element) { + var options = Object.extend({ + handle: false, + starteffect: function(element) { + element._opacity = Element.getOpacity(element); + Draggable._dragging[element] = true; + new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7}); + }, + reverteffect: function(element, top_offset, left_offset) { + var dur = Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02; + Draggable._revertCache[element] = + new Effect.Move(element, { x: -left_offset, y: -top_offset, duration: dur, + queue: {scope:'_draggable', position:'end'} + }); + }, + endeffect: function(element) { + var toOpacity = typeof element._opacity == 'number' ? element._opacity : 1.0; + new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity, + queue: {scope:'_draggable', position:'end'}, + afterFinish: function(){ Draggable._dragging[element] = false } + }); + }, + zindex: 1000, + revert: false, + scroll: false, + scrollSensitivity: 20, + scrollSpeed: 15, + snap: false // false, or xy or [x,y] or function(x,y){ return [x,y] } + }, arguments[1] || {}); + + this.element = $(element); + + if(options.handle && (typeof options.handle == 'string')) { + var h = Element.childrenWithClassName(this.element, options.handle, true); + if(h.length>0) this.handle = h[0]; + } + if(!this.handle) this.handle = $(options.handle); + if(!this.handle) this.handle = this.element; + + if(options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML) + options.scroll = $(options.scroll); + + Element.makePositioned(this.element); // fix IE + + this.delta = this.currentDelta(); + this.options = options; + this.dragging = false; + + this.eventMouseDown = this.initDrag.bindAsEventListener(this); + Event.observe(this.handle, "mousedown", this.eventMouseDown); + + Draggables.register(this); + }, + + destroy: function() { + Event.stopObserving(this.handle, "mousedown", this.eventMouseDown); + Draggables.unregister(this); + }, + + currentDelta: function() { + return([ + parseInt(Element.getStyle(this.element,'left') || '0'), + parseInt(Element.getStyle(this.element,'top') || '0')]); + }, + + initDrag: function(event) { + if(typeof Draggable._dragging[this.element] != undefined && + Draggable._dragging[this.element]) return; + if(Event.isLeftClick(event)) { + // abort on form elements, fixes a Firefox issue + var src = Event.element(event); + if(src.tagName && ( + src.tagName=='INPUT' || + src.tagName=='SELECT' || + src.tagName=='OPTION' || + src.tagName=='BUTTON' || + src.tagName=='TEXTAREA')) return; + + if(Draggable._revertCache[this.element]) { + Draggable._revertCache[this.element].cancel(); + Draggable._revertCache[this.element] = null; + } + + var pointer = [Event.pointerX(event), Event.pointerY(event)]; + var pos = Position.cumulativeOffset(this.element); + this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) }); + + Draggables.activate(this); + Event.stop(event); + } + }, + + startDrag: function(event) { + this.dragging = true; + + if(this.options.zindex) { + this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0); + this.element.style.zIndex = this.options.zindex; + } + + if(this.options.ghosting) { + this._clone = this.element.cloneNode(true); + Position.absolutize(this.element); + this.element.parentNode.insertBefore(this._clone, this.element); + } + + if(this.options.scroll) { + if (this.options.scroll == window) { + var where = this._getWindowScroll(this.options.scroll); + this.originalScrollLeft = where.left; + this.originalScrollTop = where.top; + } else { + this.originalScrollLeft = this.options.scroll.scrollLeft; + this.originalScrollTop = this.options.scroll.scrollTop; + } + } + + Draggables.notify('onStart', this, event); + if(this.options.starteffect) this.options.starteffect(this.element); + }, + + updateDrag: function(event, pointer) { + if(!this.dragging) this.startDrag(event); + Position.prepare(); + Droppables.show(pointer, this.element); + Draggables.notify('onDrag', this, event); + this.draw(pointer); + if(this.options.change) this.options.change(this); + + if(this.options.scroll) { + this.stopScrolling(); + + var p; + if (this.options.scroll == window) { + with(this._getWindowScroll(this.options.scroll)) { p = [ left, top, left+width, top+height ]; } + } else { + p = Position.page(this.options.scroll); + p[0] += this.options.scroll.scrollLeft; + p[1] += this.options.scroll.scrollTop; + p.push(p[0]+this.options.scroll.offsetWidth); + p.push(p[1]+this.options.scroll.offsetHeight); + } + var speed = [0,0]; + if(pointer[0] < (p[0]+this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[0]+this.options.scrollSensitivity); + if(pointer[1] < (p[1]+this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[1]+this.options.scrollSensitivity); + if(pointer[0] > (p[2]-this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[2]-this.options.scrollSensitivity); + if(pointer[1] > (p[3]-this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[3]-this.options.scrollSensitivity); + this.startScrolling(speed); + } + + // fix AppleWebKit rendering + if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0); + + Event.stop(event); + }, + + finishDrag: function(event, success) { + this.dragging = false; + + if(this.options.ghosting) { + Position.relativize(this.element); + Element.remove(this._clone); + this._clone = null; + } + + if(success) Droppables.fire(event, this.element); + Draggables.notify('onEnd', this, event); + + var revert = this.options.revert; + if(revert && typeof revert == 'function') revert = revert(this.element); + + var d = this.currentDelta(); + if(revert && this.options.reverteffect) { + this.options.reverteffect(this.element, + d[1]-this.delta[1], d[0]-this.delta[0]); + } else { + this.delta = d; + } + + if(this.options.zindex) + this.element.style.zIndex = this.originalZ; + + if(this.options.endeffect) + this.options.endeffect(this.element); + + Draggables.deactivate(this); + Droppables.reset(); + }, + + keyPress: function(event) { + if(event.keyCode!=Event.KEY_ESC) return; + this.finishDrag(event, false); + Event.stop(event); + }, + + endDrag: function(event) { + if(!this.dragging) return; + this.stopScrolling(); + this.finishDrag(event, true); + Event.stop(event); + }, + + draw: function(point) { + var pos = Position.cumulativeOffset(this.element); + var d = this.currentDelta(); + pos[0] -= d[0]; pos[1] -= d[1]; + + if(this.options.scroll && (this.options.scroll != window)) { + pos[0] -= this.options.scroll.scrollLeft-this.originalScrollLeft; + pos[1] -= this.options.scroll.scrollTop-this.originalScrollTop; + } + + var p = [0,1].map(function(i){ + return (point[i]-pos[i]-this.offset[i]) + }.bind(this)); + + if(this.options.snap) { + if(typeof this.options.snap == 'function') { + p = this.options.snap(p[0],p[1],this); + } else { + if(this.options.snap instanceof Array) { + p = p.map( function(v, i) { + return Math.round(v/this.options.snap[i])*this.options.snap[i] }.bind(this)) + } else { + p = p.map( function(v) { + return Math.round(v/this.options.snap)*this.options.snap }.bind(this)) + } + }} + + var style = this.element.style; + if((!this.options.constraint) || (this.options.constraint=='horizontal')) + style.left = p[0] + "px"; + if((!this.options.constraint) || (this.options.constraint=='vertical')) + style.top = p[1] + "px"; + if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering + }, + + stopScrolling: function() { + if(this.scrollInterval) { + clearInterval(this.scrollInterval); + this.scrollInterval = null; + Draggables._lastScrollPointer = null; + } + }, + + startScrolling: function(speed) { + if(!(speed[0] || speed[1])) return; + this.scrollSpeed = [speed[0]*this.options.scrollSpeed,speed[1]*this.options.scrollSpeed]; + this.lastScrolled = new Date(); + this.scrollInterval = setInterval(this.scroll.bind(this), 10); + }, + + scroll: function() { + var current = new Date(); + var delta = current - this.lastScrolled; + this.lastScrolled = current; + if(this.options.scroll == window) { + with (this._getWindowScroll(this.options.scroll)) { + if (this.scrollSpeed[0] || this.scrollSpeed[1]) { + var d = delta / 1000; + this.options.scroll.scrollTo( left + d*this.scrollSpeed[0], top + d*this.scrollSpeed[1] ); + } + } + } else { + this.options.scroll.scrollLeft += this.scrollSpeed[0] * delta / 1000; + this.options.scroll.scrollTop += this.scrollSpeed[1] * delta / 1000; + } + + Position.prepare(); + Droppables.show(Draggables._lastPointer, this.element); + Draggables.notify('onDrag', this); + Draggables._lastScrollPointer = Draggables._lastScrollPointer || $A(Draggables._lastPointer); + Draggables._lastScrollPointer[0] += this.scrollSpeed[0] * delta / 1000; + Draggables._lastScrollPointer[1] += this.scrollSpeed[1] * delta / 1000; + if (Draggables._lastScrollPointer[0] < 0) + Draggables._lastScrollPointer[0] = 0; + if (Draggables._lastScrollPointer[1] < 0) + Draggables._lastScrollPointer[1] = 0; + this.draw(Draggables._lastScrollPointer); + + if(this.options.change) this.options.change(this); + }, + + _getWindowScroll: function(w) { + var T, L, W, H; + with (w.document) { + if (w.document.documentElement && documentElement.scrollTop) { + T = documentElement.scrollTop; + L = documentElement.scrollLeft; + } else if (w.document.body) { + T = body.scrollTop; + L = body.scrollLeft; + } + if (w.innerWidth) { + W = w.innerWidth; + H = w.innerHeight; + } else if (w.document.documentElement && documentElement.clientWidth) { + W = documentElement.clientWidth; + H = documentElement.clientHeight; + } else { + W = body.offsetWidth; + H = body.offsetHeight + } + } + return { top: T, left: L, width: W, height: H }; + } +} + +/*--------------------------------------------------------------------------*/ + +var SortableObserver = Class.create(); +SortableObserver.prototype = { + initialize: function(element, observer) { + this.element = $(element); + this.observer = observer; + this.lastValue = Sortable.serialize(this.element); + }, + + onStart: function() { + this.lastValue = Sortable.serialize(this.element); + }, + + onEnd: function() { + Sortable.unmark(); + if(this.lastValue != Sortable.serialize(this.element)) + this.observer(this.element) + } +} + +var Sortable = { + sortables: {}, + + _findRootElement: function(element) { + while (element.tagName != "BODY") { + if(element.id && Sortable.sortables[element.id]) return element; + element = element.parentNode; + } + }, + + options: function(element) { + element = Sortable._findRootElement($(element)); + if(!element) return; + return Sortable.sortables[element.id]; + }, + + destroy: function(element){ + var s = Sortable.options(element); + + if(s) { + Draggables.removeObserver(s.element); + s.droppables.each(function(d){ Droppables.remove(d) }); + s.draggables.invoke('destroy'); + + delete Sortable.sortables[s.element.id]; + } + }, + + create: function(element) { + element = $(element); + var options = Object.extend({ + element: element, + tag: 'li', // assumes li children, override with tag: 'tagname' + dropOnEmpty: false, + tree: false, + treeTag: 'ul', + overlap: 'vertical', // one of 'vertical', 'horizontal' + constraint: 'vertical', // one of 'vertical', 'horizontal', false + containment: element, // also takes array of elements (or id's); or false + handle: false, // or a CSS class + only: false, + hoverclass: null, + ghosting: false, + scroll: false, + scrollSensitivity: 20, + scrollSpeed: 15, + format: /^[^_]*_(.*)$/, + onChange: Prototype.emptyFunction, + onUpdate: Prototype.emptyFunction + }, arguments[1] || {}); + + // clear any old sortable with same element + this.destroy(element); + + // build options for the draggables + var options_for_draggable = { + revert: true, + scroll: options.scroll, + scrollSpeed: options.scrollSpeed, + scrollSensitivity: options.scrollSensitivity, + ghosting: options.ghosting, + constraint: options.constraint, + handle: options.handle }; + + if(options.starteffect) + options_for_draggable.starteffect = options.starteffect; + + if(options.reverteffect) + options_for_draggable.reverteffect = options.reverteffect; + else + if(options.ghosting) options_for_draggable.reverteffect = function(element) { + element.style.top = 0; + element.style.left = 0; + }; + + if(options.endeffect) + options_for_draggable.endeffect = options.endeffect; + + if(options.zindex) + options_for_draggable.zindex = options.zindex; + + // build options for the droppables + var options_for_droppable = { + overlap: options.overlap, + containment: options.containment, + tree: options.tree, + hoverclass: options.hoverclass, + onHover: Sortable.onHover + //greedy: !options.dropOnEmpty + } + + var options_for_tree = { + onHover: Sortable.onEmptyHover, + overlap: options.overlap, + containment: options.containment, + hoverclass: options.hoverclass + } + + // fix for gecko engine + Element.cleanWhitespace(element); + + options.draggables = []; + options.droppables = []; + + // drop on empty handling + if(options.dropOnEmpty || options.tree) { + Droppables.add(element, options_for_tree); + options.droppables.push(element); + } + + (this.findElements(element, options) || []).each( function(e) { + // handles are per-draggable + var handle = options.handle ? + Element.childrenWithClassName(e, options.handle)[0] : e; + options.draggables.push( + new Draggable(e, Object.extend(options_for_draggable, { handle: handle }))); + Droppables.add(e, options_for_droppable); + if(options.tree) e.treeNode = element; + options.droppables.push(e); + }); + + if(options.tree) { + (Sortable.findTreeElements(element, options) || []).each( function(e) { + Droppables.add(e, options_for_tree); + e.treeNode = element; + options.droppables.push(e); + }); + } + + // keep reference + this.sortables[element.id] = options; + + // for onupdate + Draggables.addObserver(new SortableObserver(element, options.onUpdate)); + + }, + + // return all suitable-for-sortable elements in a guaranteed order + findElements: function(element, options) { + return Element.findChildren( + element, options.only, options.tree ? true : false, options.tag); + }, + + findTreeElements: function(element, options) { + return Element.findChildren( + element, options.only, options.tree ? true : false, options.treeTag); + }, + + onHover: function(element, dropon, overlap) { + if(Element.isParent(dropon, element)) return; + + if(overlap > .33 && overlap < .66 && Sortable.options(dropon).tree) { + return; + } else if(overlap>0.5) { + Sortable.mark(dropon, 'before'); + if(dropon.previousSibling != element) { + var oldParentNode = element.parentNode; + element.style.visibility = "hidden"; // fix gecko rendering + dropon.parentNode.insertBefore(element, dropon); + if(dropon.parentNode!=oldParentNode) + Sortable.options(oldParentNode).onChange(element); + Sortable.options(dropon.parentNode).onChange(element); + } + } else { + Sortable.mark(dropon, 'after'); + var nextElement = dropon.nextSibling || null; + if(nextElement != element) { + var oldParentNode = element.parentNode; + element.style.visibility = "hidden"; // fix gecko rendering + dropon.parentNode.insertBefore(element, nextElement); + if(dropon.parentNode!=oldParentNode) + Sortable.options(oldParentNode).onChange(element); + Sortable.options(dropon.parentNode).onChange(element); + } + } + }, + + onEmptyHover: function(element, dropon, overlap) { + var oldParentNode = element.parentNode; + var droponOptions = Sortable.options(dropon); + + if(!Element.isParent(dropon, element)) { + var index; + + var children = Sortable.findElements(dropon, {tag: droponOptions.tag, only: droponOptions.only}); + var child = null; + + if(children) { + var offset = Element.offsetSize(dropon, droponOptions.overlap) * (1.0 - overlap); + + for (index = 0; index < children.length; index += 1) { + if (offset - Element.offsetSize (children[index], droponOptions.overlap) >= 0) { + offset -= Element.offsetSize (children[index], droponOptions.overlap); + } else if (offset - (Element.offsetSize (children[index], droponOptions.overlap) / 2) >= 0) { + child = index + 1 < children.length ? children[index + 1] : null; + break; + } else { + child = children[index]; + break; + } + } + } + + dropon.insertBefore(element, child); + + Sortable.options(oldParentNode).onChange(element); + droponOptions.onChange(element); + } + }, + + unmark: function() { + if(Sortable._marker) Element.hide(Sortable._marker); + }, + + mark: function(dropon, position) { + // mark on ghosting only + var sortable = Sortable.options(dropon.parentNode); + if(sortable && !sortable.ghosting) return; + + if(!Sortable._marker) { + Sortable._marker = $('dropmarker') || document.createElement('DIV'); + Element.hide(Sortable._marker); + Element.addClassName(Sortable._marker, 'dropmarker'); + Sortable._marker.style.position = 'absolute'; + document.getElementsByTagName("body").item(0).appendChild(Sortable._marker); + } + var offsets = Position.cumulativeOffset(dropon); + Sortable._marker.style.left = offsets[0] + 'px'; + Sortable._marker.style.top = offsets[1] + 'px'; + + if(position=='after') + if(sortable.overlap == 'horizontal') + Sortable._marker.style.left = (offsets[0]+dropon.clientWidth) + 'px'; + else + Sortable._marker.style.top = (offsets[1]+dropon.clientHeight) + 'px'; + + Element.show(Sortable._marker); + }, + + _tree: function(element, options, parent) { + var children = Sortable.findElements(element, options) || []; + + for (var i = 0; i < children.length; ++i) { + var match = children[i].id.match(options.format); + + if (!match) continue; + + var child = { + id: encodeURIComponent(match ? match[1] : null), + element: element, + parent: parent, + children: new Array, + position: parent.children.length, + container: Sortable._findChildrenElement(children[i], options.treeTag.toUpperCase()) + } + + /* Get the element containing the children and recurse over it */ + if (child.container) + this._tree(child.container, options, child) + + parent.children.push (child); + } + + return parent; + }, + + /* Finds the first element of the given tag type within a parent element. + Used for finding the first LI[ST] within a L[IST]I[TEM].*/ + _findChildrenElement: function (element, containerTag) { + if (element && element.hasChildNodes) + for (var i = 0; i < element.childNodes.length; ++i) + if (element.childNodes[i].tagName == containerTag) + return element.childNodes[i]; + + return null; + }, + + tree: function(element) { + element = $(element); + var sortableOptions = this.options(element); + var options = Object.extend({ + tag: sortableOptions.tag, + treeTag: sortableOptions.treeTag, + only: sortableOptions.only, + name: element.id, + format: sortableOptions.format + }, arguments[1] || {}); + + var root = { + id: null, + parent: null, + children: new Array, + container: element, + position: 0 + } + + return Sortable._tree (element, options, root); + }, + + /* Construct a [i] index for a particular node */ + _constructIndex: function(node) { + var index = ''; + do { + if (node.id) index = '[' + node.position + ']' + index; + } while ((node = node.parent) != null); + return index; + }, + + sequence: function(element) { + element = $(element); + var options = Object.extend(this.options(element), arguments[1] || {}); + + return $(this.findElements(element, options) || []).map( function(item) { + return item.id.match(options.format) ? item.id.match(options.format)[1] : ''; + }); + }, + + setSequence: function(element, new_sequence) { + element = $(element); + var options = Object.extend(this.options(element), arguments[2] || {}); + + var nodeMap = {}; + this.findElements(element, options).each( function(n) { + if (n.id.match(options.format)) + nodeMap[n.id.match(options.format)[1]] = [n, n.parentNode]; + n.parentNode.removeChild(n); + }); + + new_sequence.each(function(ident) { + var n = nodeMap[ident]; + if (n) { + n[1].appendChild(n[0]); + delete nodeMap[ident]; + } + }); + }, + + serialize: function(element) { + element = $(element); + var options = Object.extend(Sortable.options(element), arguments[1] || {}); + var name = encodeURIComponent( + (arguments[1] && arguments[1].name) ? arguments[1].name : element.id); + + if (options.tree) { + return Sortable.tree(element, arguments[1]).children.map( function (item) { + return [name + Sortable._constructIndex(item) + "[id]=" + + encodeURIComponent(item.id)].concat(item.children.map(arguments.callee)); + }).flatten().join('&'); + } else { + return Sortable.sequence(element, arguments[1]).map( function(item) { + return name + "[]=" + encodeURIComponent(item); + }).join('&'); + } + } +} + +/* Returns true if child is contained within element */ +Element.isParent = function(child, element) { + if (!child.parentNode || child == element) return false; + + if (child.parentNode == element) return true; + + return Element.isParent(child.parentNode, element); +} + +Element.findChildren = function(element, only, recursive, tagName) { + if(!element.hasChildNodes()) return null; + tagName = tagName.toUpperCase(); + if(only) only = [only].flatten(); + var elements = []; + $A(element.childNodes).each( function(e) { + if(e.tagName && e.tagName.toUpperCase()==tagName && + (!only || (Element.classNames(e).detect(function(v) { return only.include(v) })))) + elements.push(e); + if(recursive) { + var grandchildren = Element.findChildren(e, only, recursive, tagName); + if(grandchildren) elements.push(grandchildren); + } + }); + + return (elements.length>0 ? elements.flatten() : []); +} + +Element.offsetSize = function (element, type) { + if (type == 'vertical' || type == 'height') + return element.offsetHeight; + else + return element.offsetWidth; +} diff --git a/js/calendar.js b/js/calendar.js new file mode 100644 index 0000000..9a69936 --- /dev/null +++ b/js/calendar.js @@ -0,0 +1,2058 @@ +/* Copyright Mihai Bazon, 2002-2005 | www.bazon.net/mishoo + * ----------------------------------------------------------- + * + * The DHTML Calendar, version 1.0 "It is happening again" + * + * Details and latest version at: + * www.dynarch.com/projects/calendar + * + * This script is developed by Dynarch.com. Visit us at www.dynarch.com. + * + * This script is distributed under the GNU Lesser General Public License. + * Read the entire license text here: http://www.gnu.org/licenses/lgpl.html + */ + +// $Id: calendar.js,v 1.51 2005/03/07 16:44:31 mishoo Exp $ + +/** The Calendar object constructor. */ +Calendar = function (firstDayOfWeek, dateStr, onSelected, onClose) { + // member variables + this.activeDiv = null; + this.currentDateEl = null; + this.getDateStatus = null; + this.getDateToolTip = null; + this.getDateText = null; + this.timeout = null; + this.onSelected = onSelected || null; + this.onClose = onClose || null; + this.dragging = false; + this.hidden = false; + this.minYear = 1970; + this.maxYear = 2050; + this.dateFormat = Calendar._TT["DEF_DATE_FORMAT"]; + this.ttDateFormat = Calendar._TT["TT_DATE_FORMAT"]; + this.isPopup = true; + this.weekNumbers = true; + this.firstDayOfWeek = typeof firstDayOfWeek == "number" ? firstDayOfWeek : Calendar._FD; // 0 for Sunday, 1 for Monday, etc. + this.showsOtherMonths = false; + this.dateStr = dateStr; + this.ar_days = null; + this.showsTime = false; + this.time24 = true; + this.yearStep = 2; + this.hiliteToday = true; + this.multiple = null; + // HTML elements + this.table = null; + this.element = null; + this.tbody = null; + this.firstdayname = null; + // Combo boxes + this.monthsCombo = null; + this.yearsCombo = null; + this.hilitedMonth = null; + this.activeMonth = null; + this.hilitedYear = null; + this.activeYear = null; + // Information + this.dateClicked = false; + + // one-time initializations + if (typeof Calendar._SDN == "undefined") { + // table of short day names + if (typeof Calendar._SDN_len == "undefined") + Calendar._SDN_len = 3; + var ar = new Array(); + for (var i = 8; i > 0;) { + ar[--i] = Calendar._DN[i].substr(0, Calendar._SDN_len); + } + Calendar._SDN = ar; + // table of short month names + if (typeof Calendar._SMN_len == "undefined") + Calendar._SMN_len = 3; + ar = new Array(); + for (var i = 12; i > 0;) { + ar[--i] = Calendar._MN[i].substr(0, Calendar._SMN_len); + } + Calendar._SMN = ar; + } +}; + +// ** constants + +/// "static", needed for event handlers. +Calendar._C = null; + +/// detect a special case of "web browser" +Calendar.is_ie = ( /msie/i.test(navigator.userAgent) && + !/opera/i.test(navigator.userAgent) ); + +Calendar.is_ie5 = ( Calendar.is_ie && /msie 5\.0/i.test(navigator.userAgent) ); + +/// detect Opera browser +Calendar.is_opera = /opera/i.test(navigator.userAgent); + +/// detect KHTML-based browsers +Calendar.is_khtml = /Konqueror|Safari|KHTML/i.test(navigator.userAgent); + +// BEGIN: UTILITY FUNCTIONS; beware that these might be moved into a separate +// library, at some point. + +Calendar.getAbsolutePos = function(el) { + var SL = 0, ST = 0; + var is_div = /^div$/i.test(el.tagName); + if (is_div && el.scrollLeft) + SL = el.scrollLeft; + if (is_div && el.scrollTop) + ST = el.scrollTop; + var r = { x: el.offsetLeft - SL, y: el.offsetTop - ST }; + if (el.offsetParent) { + var tmp = this.getAbsolutePos(el.offsetParent); + r.x += tmp.x; + r.y += tmp.y; + } + return r; +}; + +Calendar.isRelated = function (el, evt) { + var related = evt.relatedTarget; + if (!related) { + var type = evt.type; + if (type == "mouseover") { + related = evt.fromElement; + } else if (type == "mouseout") { + related = evt.toElement; + } + } + while (related) { + if (related == el) { + return true; + } + related = related.parentNode; + } + return false; +}; + +Calendar.removeClass = function(el, className) { + if (!(el && el.className)) { + return; + } + var cls = el.className.split(" "); + var ar = new Array(); + for (var i = cls.length; i > 0;) { + if (cls[--i] != className) { + ar[ar.length] = cls[i]; + } + } + el.className = ar.join(" "); +}; + +Calendar.addClass = function(el, className) { + Calendar.removeClass(el, className); + el.className += " " + className; +}; + +// FIXME: the following 2 functions totally suck, are useless and should be replaced immediately. +Calendar.getElement = function(ev) { + var f = Calendar.is_ie ? window.event.srcElement : ev.currentTarget; + while (f.nodeType != 1 || /^div$/i.test(f.tagName)) + f = f.parentNode; + return f; +}; + +Calendar.getTargetElement = function(ev) { + var f = Calendar.is_ie ? window.event.srcElement : ev.target; + while (f.nodeType != 1) + f = f.parentNode; + return f; +}; + +Calendar.stopEvent = function(ev) { + ev || (ev = window.event); + if (Calendar.is_ie) { + ev.cancelBubble = true; + ev.returnValue = false; + } else { + ev.preventDefault(); + ev.stopPropagation(); + } + return false; +}; + +Calendar.addEvent = function(el, evname, func) { + if (el.attachEvent) { // IE + el.attachEvent("on" + evname, func); + } else if (el.addEventListener) { // Gecko / W3C + el.addEventListener(evname, func, true); + } else { + el["on" + evname] = func; + } +}; + +Calendar.removeEvent = function(el, evname, func) { + if (el.detachEvent) { // IE + el.detachEvent("on" + evname, func); + } else if (el.removeEventListener) { // Gecko / W3C + el.removeEventListener(evname, func, true); + } else { + el["on" + evname] = null; + } +}; + +Calendar.createElement = function(type, parent) { + var el = null; + if (document.createElementNS) { + // use the XHTML namespace; IE won't normally get here unless + // _they_ "fix" the DOM2 implementation. + el = document.createElementNS("http://www.w3.org/1999/xhtml", type); + } else { + el = document.createElement(type); + } + if (typeof parent != "undefined") { + parent.appendChild(el); + } + return el; +}; + +// END: UTILITY FUNCTIONS + +// BEGIN: CALENDAR STATIC FUNCTIONS + +/** Internal -- adds a set of events to make some element behave like a button. */ +Calendar._add_evs = function(el) { + with (Calendar) { + addEvent(el, "mouseover", dayMouseOver); + addEvent(el, "mousedown", dayMouseDown); + addEvent(el, "mouseout", dayMouseOut); + if (is_ie) { + addEvent(el, "dblclick", dayMouseDblClick); + el.setAttribute("unselectable", true); + } + } +}; + +Calendar.findMonth = function(el) { + if (typeof el.month != "undefined") { + return el; + } else if (typeof el.parentNode.month != "undefined") { + return el.parentNode; + } + return null; +}; + +Calendar.findYear = function(el) { + if (typeof el.year != "undefined") { + return el; + } else if (typeof el.parentNode.year != "undefined") { + return el.parentNode; + } + return null; +}; + +Calendar.showMonthsCombo = function () { + var cal = Calendar._C; + if (!cal) { + return false; + } + var cal = cal; + var cd = cal.activeDiv; + var mc = cal.monthsCombo; + if (cal.hilitedMonth) { + Calendar.removeClass(cal.hilitedMonth, "hilite"); + } + if (cal.activeMonth) { + Calendar.removeClass(cal.activeMonth, "active"); + } + var mon = cal.monthsCombo.getElementsByTagName("div")[cal.date.getMonth()]; + Calendar.addClass(mon, "active"); + cal.activeMonth = mon; + var s = mc.style; + s.display = "block"; + if (cd.navtype < 0) + s.left = cd.offsetLeft + "px"; + else { + var mcw = mc.offsetWidth; + if (typeof mcw == "undefined") + // Konqueror brain-dead techniques + mcw = 50; + s.left = (cd.offsetLeft + cd.offsetWidth - mcw) + "px"; + } + s.top = (cd.offsetTop + cd.offsetHeight) + "px"; +}; + +Calendar.showYearsCombo = function (fwd) { + var cal = Calendar._C; + if (!cal) { + return false; + } + var cal = cal; + var cd = cal.activeDiv; + var yc = cal.yearsCombo; + if (cal.hilitedYear) { + Calendar.removeClass(cal.hilitedYear, "hilite"); + } + if (cal.activeYear) { + Calendar.removeClass(cal.activeYear, "active"); + } + cal.activeYear = null; + var Y = cal.date.getFullYear() + (fwd ? 1 : -1); + var yr = yc.firstChild; + var show = false; + for (var i = 12; i > 0; --i) { + if (Y >= cal.minYear && Y <= cal.maxYear) { + yr.innerHTML = Y; + yr.year = Y; + yr.style.display = "block"; + show = true; + } else { + yr.style.display = "none"; + } + yr = yr.nextSibling; + Y += fwd ? cal.yearStep : -cal.yearStep; + } + if (show) { + var s = yc.style; + s.display = "block"; + if (cd.navtype < 0) + s.left = cd.offsetLeft + "px"; + else { + var ycw = yc.offsetWidth; + if (typeof ycw == "undefined") + // Konqueror brain-dead techniques + ycw = 50; + s.left = (cd.offsetLeft + cd.offsetWidth - ycw) + "px"; + } + s.top = (cd.offsetTop + cd.offsetHeight) + "px"; + } +}; + +// event handlers + +Calendar.tableMouseUp = function(ev) { + var cal = Calendar._C; + if (!cal) { + return false; + } + if (cal.timeout) { + clearTimeout(cal.timeout); + } + var el = cal.activeDiv; + if (!el) { + return false; + } + var target = Calendar.getTargetElement(ev); + ev || (ev = window.event); + Calendar.removeClass(el, "active"); + if (target == el || target.parentNode == el) { + Calendar.cellClick(el, ev); + } + var mon = Calendar.findMonth(target); + var date = null; + if (mon) { + date = new Date(cal.date); + if (mon.month != date.getMonth()) { + date.setMonth(mon.month); + cal.setDate(date); + cal.dateClicked = false; + cal.callHandler(); + } + } else { + var year = Calendar.findYear(target); + if (year) { + date = new Date(cal.date); + if (year.year != date.getFullYear()) { + date.setFullYear(year.year); + cal.setDate(date); + cal.dateClicked = false; + cal.callHandler(); + } + } + } + with (Calendar) { + removeEvent(document, "mouseup", tableMouseUp); + removeEvent(document, "mouseover", tableMouseOver); + removeEvent(document, "mousemove", tableMouseOver); + cal._hideCombos(); + _C = null; + return stopEvent(ev); + } +}; + +Calendar.tableMouseOver = function (ev) { + var cal = Calendar._C; + if (!cal) { + return; + } + var el = cal.activeDiv; + var target = Calendar.getTargetElement(ev); + if (target == el || target.parentNode == el) { + Calendar.addClass(el, "hilite active"); + Calendar.addClass(el.parentNode, "rowhilite"); + } else { + if (typeof el.navtype == "undefined" || (el.navtype != 50 && (el.navtype == 0 || Math.abs(el.navtype) > 2))) + Calendar.removeClass(el, "active"); + Calendar.removeClass(el, "hilite"); + Calendar.removeClass(el.parentNode, "rowhilite"); + } + ev || (ev = window.event); + if (el.navtype == 50 && target != el) { + var pos = Calendar.getAbsolutePos(el); + var w = el.offsetWidth; + var x = ev.clientX; + var dx; + var decrease = true; + if (x > pos.x + w) { + dx = x - pos.x - w; + decrease = false; + } else + dx = pos.x - x; + + if (dx < 0) dx = 0; + var range = el._range; + var current = el._current; + var count = Math.floor(dx / 10) % range.length; + for (var i = range.length; --i >= 0;) + if (range[i] == current) + break; + while (count-- > 0) + if (decrease) { + if (--i < 0) + i = range.length - 1; + } else if ( ++i >= range.length ) + i = 0; + var newval = range[i]; + el.innerHTML = newval; + + cal.onUpdateTime(); + } + var mon = Calendar.findMonth(target); + if (mon) { + if (mon.month != cal.date.getMonth()) { + if (cal.hilitedMonth) { + Calendar.removeClass(cal.hilitedMonth, "hilite"); + } + Calendar.addClass(mon, "hilite"); + cal.hilitedMonth = mon; + } else if (cal.hilitedMonth) { + Calendar.removeClass(cal.hilitedMonth, "hilite"); + } + } else { + if (cal.hilitedMonth) { + Calendar.removeClass(cal.hilitedMonth, "hilite"); + } + var year = Calendar.findYear(target); + if (year) { + if (year.year != cal.date.getFullYear()) { + if (cal.hilitedYear) { + Calendar.removeClass(cal.hilitedYear, "hilite"); + } + Calendar.addClass(year, "hilite"); + cal.hilitedYear = year; + } else if (cal.hilitedYear) { + Calendar.removeClass(cal.hilitedYear, "hilite"); + } + } else if (cal.hilitedYear) { + Calendar.removeClass(cal.hilitedYear, "hilite"); + } + } + return Calendar.stopEvent(ev); +}; + +Calendar.tableMouseDown = function (ev) { + if (Calendar.getTargetElement(ev) == Calendar.getElement(ev)) { + return Calendar.stopEvent(ev); + } +}; + +Calendar.calDragIt = function (ev) { + var cal = Calendar._C; + if (!(cal && cal.dragging)) { + return false; + } + var posX; + var posY; + if (Calendar.is_ie) { + posY = window.event.clientY + document.body.scrollTop; + posX = window.event.clientX + document.body.scrollLeft; + } else { + posX = ev.pageX; + posY = ev.pageY; + } + cal.hideShowCovered(); + var st = cal.element.style; + st.left = (posX - cal.xOffs) + "px"; + st.top = (posY - cal.yOffs) + "px"; + return Calendar.stopEvent(ev); +}; + +Calendar.calDragEnd = function (ev) { + var cal = Calendar._C; + if (!cal) { + return false; + } + cal.dragging = false; + with (Calendar) { + removeEvent(document, "mousemove", calDragIt); + removeEvent(document, "mouseup", calDragEnd); + tableMouseUp(ev); + } + cal.hideShowCovered(); +}; + +Calendar.dayMouseDown = function(ev) { + var el = Calendar.getElement(ev); + if (el.disabled) { + return false; + } + var cal = el.calendar; + cal.activeDiv = el; + Calendar._C = cal; + if (el.navtype != 300) with (Calendar) { + if (el.navtype == 50) { + el._current = el.innerHTML; + addEvent(document, "mousemove", tableMouseOver); + } else + addEvent(document, Calendar.is_ie5 ? "mousemove" : "mouseover", tableMouseOver); + addClass(el, "hilite active"); + addEvent(document, "mouseup", tableMouseUp); + } else if (cal.isPopup) { + cal._dragStart(ev); + } + if (el.navtype == -1 || el.navtype == 1) { + if (cal.timeout) clearTimeout(cal.timeout); + cal.timeout = setTimeout("Calendar.showMonthsCombo()", 250); + } else if (el.navtype == -2 || el.navtype == 2) { + if (cal.timeout) clearTimeout(cal.timeout); + cal.timeout = setTimeout((el.navtype > 0) ? "Calendar.showYearsCombo(true)" : "Calendar.showYearsCombo(false)", 250); + } else { + cal.timeout = null; + } + return Calendar.stopEvent(ev); +}; + +Calendar.dayMouseDblClick = function(ev) { + Calendar.cellClick(Calendar.getElement(ev), ev || window.event); + if (Calendar.is_ie) { + document.selection.empty(); + } +}; + +Calendar.dayMouseOver = function(ev) { + var el = Calendar.getElement(ev); + if (Calendar.isRelated(el, ev) || Calendar._C || el.disabled) { + return false; + } + if (el.ttip) { + if (el.ttip.substr(0, 1) == "_") { + el.ttip = el.caldate.print(el.calendar.ttDateFormat) + el.ttip.substr(1); + } + el.calendar.tooltips.innerHTML = el.ttip; + } + if (el.navtype != 300) { + Calendar.addClass(el, "hilite"); + if (el.caldate) { + Calendar.addClass(el.parentNode, "rowhilite"); + } + } + return Calendar.stopEvent(ev); +}; + +Calendar.dayMouseOut = function(ev) { + with (Calendar) { + var el = getElement(ev); + if (isRelated(el, ev) || _C || el.disabled) + return false; + removeClass(el, "hilite"); + if (el.caldate) + removeClass(el.parentNode, "rowhilite"); + if (el.calendar) + el.calendar.tooltips.innerHTML = _TT["SEL_DATE"]; + return stopEvent(ev); + } +}; + +/** + * A generic "click" handler :) handles all types of buttons defined in this + * calendar. + */ +Calendar.cellClick = function(el, ev) { + var cal = el.calendar; + var closing = false; + var newdate = false; + var date = null; + if (typeof el.navtype == "undefined") { + if (cal.currentDateEl) { + Calendar.removeClass(cal.currentDateEl, "selected"); + Calendar.addClass(el, "selected"); + closing = (cal.currentDateEl == el); + if (!closing) { + cal.currentDateEl = el; + } + } + cal.date.setDateOnly(el.caldate); + date = cal.date; + var other_month = !(cal.dateClicked = !el.otherMonth); + if (!other_month && !cal.currentDateEl) + cal._toggleMultipleDate(new Date(date)); + else + newdate = !el.disabled; + // a date was clicked + if (other_month) + cal._init(cal.firstDayOfWeek, date); + } else { + if (el.navtype == 200) { + Calendar.removeClass(el, "hilite"); + cal.callCloseHandler(); + return; + } + date = new Date(cal.date); + if (el.navtype == 0) + date.setDateOnly(new Date()); // TODAY + // unless "today" was clicked, we assume no date was clicked so + // the selected handler will know not to close the calenar when + // in single-click mode. + // cal.dateClicked = (el.navtype == 0); + cal.dateClicked = false; + var year = date.getFullYear(); + var mon = date.getMonth(); + function setMonth(m) { + var day = date.getDate(); + var max = date.getMonthDays(m); + if (day > max) { + date.setDate(max); + } + date.setMonth(m); + }; + switch (el.navtype) { + case 400: + Calendar.removeClass(el, "hilite"); + var text = Calendar._TT["ABOUT"]; + if (typeof text != "undefined") { + text += cal.showsTime ? Calendar._TT["ABOUT_TIME"] : ""; + } else { + // FIXME: this should be removed as soon as lang files get updated! + text = "Help and about box text is not translated into this language.\n" + + "If you know this language and you feel generous please update\n" + + "the corresponding file in \"lang\" subdir to match calendar-en.js\n" + + "and send it back to to get it into the distribution ;-)\n\n" + + "Thank you!\n" + + "http://dynarch.com/mishoo/calendar.epl\n"; + } + alert(text); + return; + case -2: + if (year > cal.minYear) { + date.setFullYear(year - 1); + } + break; + case -1: + if (mon > 0) { + setMonth(mon - 1); + } else if (year-- > cal.minYear) { + date.setFullYear(year); + setMonth(11); + } + break; + case 1: + if (mon < 11) { + setMonth(mon + 1); + } else if (year < cal.maxYear) { + date.setFullYear(year + 1); + setMonth(0); + } + break; + case 2: + if (year < cal.maxYear) { + date.setFullYear(year + 1); + } + break; + case 100: + cal.setFirstDayOfWeek(el.fdow); + return; + case 50: + var range = el._range; + var current = el.innerHTML; + for (var i = range.length; --i >= 0;) + if (range[i] == current) + break; + if (ev && ev.shiftKey) { + if (--i < 0) + i = range.length - 1; + } else if ( ++i >= range.length ) + i = 0; + var newval = range[i]; + el.innerHTML = newval; + cal.onUpdateTime(); + return; + case 0: + // TODAY will bring us here + if ((typeof cal.getDateStatus == "function") && + cal.getDateStatus(date, date.getFullYear(), date.getMonth(), date.getDate())) { + return false; + } + break; + } + if (!date.equalsTo(cal.date)) { + cal.setDate(date); + newdate = true; + } else if (el.navtype == 0) + newdate = closing = true; + } + if (newdate) { + ev && cal.callHandler(); + } + if (closing) { + Calendar.removeClass(el, "hilite"); + ev && cal.callCloseHandler(); + } +}; + +// END: CALENDAR STATIC FUNCTIONS + +// BEGIN: CALENDAR OBJECT FUNCTIONS + +/** + * This function creates the calendar inside the given parent. If _par is + * null than it creates a popup calendar inside the BODY element. If _par is + * an element, be it BODY, then it creates a non-popup calendar (still + * hidden). Some properties need to be set before calling this function. + */ +Calendar.prototype.create = function (_par) { + var parent = null; + if (! _par) { + // default parent is the document body, in which case we create + // a popup calendar. + parent = document.getElementsByTagName("body")[0]; + this.isPopup = true; + } else { + parent = _par; + this.isPopup = false; + } + this.date = this.dateStr ? new Date(this.dateStr) : new Date(); + + var table = Calendar.createElement("table"); + this.table = table; + table.cellSpacing = 0; + table.cellPadding = 0; + table.calendar = this; + Calendar.addEvent(table, "mousedown", Calendar.tableMouseDown); + + var div = Calendar.createElement("div"); + this.element = div; + div.className = "calendar"; + if (this.isPopup) { + div.style.position = "absolute"; + div.style.display = "none"; + } + div.appendChild(table); + + var thead = Calendar.createElement("thead", table); + var cell = null; + var row = null; + + var cal = this; + var hh = function (text, cs, navtype) { + cell = Calendar.createElement("td", row); + cell.colSpan = cs; + cell.className = "button"; + if (navtype != 0 && Math.abs(navtype) <= 2) + cell.className += " nav"; + Calendar._add_evs(cell); + cell.calendar = cal; + cell.navtype = navtype; + cell.innerHTML = "
    " + text + "
    "; + return cell; + }; + + row = Calendar.createElement("tr", thead); + var title_length = 6; + (this.isPopup) && --title_length; + (this.weekNumbers) && ++title_length; + + hh("?", 1, 400).ttip = Calendar._TT["INFO"]; + this.title = hh("", title_length, 300); + this.title.className = "title"; + if (this.isPopup) { + this.title.ttip = Calendar._TT["DRAG_TO_MOVE"]; + this.title.style.cursor = "move"; + hh("×", 1, 200).ttip = Calendar._TT["CLOSE"]; + } + + row = Calendar.createElement("tr", thead); + row.className = "headrow"; + + this._nav_py = hh("«", 1, -2); + this._nav_py.ttip = Calendar._TT["PREV_YEAR"]; + + this._nav_pm = hh("‹", 1, -1); + this._nav_pm.ttip = Calendar._TT["PREV_MONTH"]; + + this._nav_now = hh(Calendar._TT["TODAY"], this.weekNumbers ? 4 : 3, 0); + this._nav_now.ttip = Calendar._TT["GO_TODAY"]; + + this._nav_nm = hh("›", 1, 1); + this._nav_nm.ttip = Calendar._TT["NEXT_MONTH"]; + + this._nav_ny = hh("»", 1, 2); + this._nav_ny.ttip = Calendar._TT["NEXT_YEAR"]; + + // day names + row = Calendar.createElement("tr", thead); + row.className = "daynames"; + if (this.weekNumbers) { + cell = Calendar.createElement("td", row); + cell.className = "name wn"; + cell.innerHTML = Calendar._TT["WK"]; + } + for (var i = 7; i > 0; --i) { + cell = Calendar.createElement("td", row); + if (!i) { + cell.navtype = 100; + cell.calendar = this; + Calendar._add_evs(cell); + } + } + this.firstdayname = (this.weekNumbers) ? row.firstChild.nextSibling : row.firstChild; + this._displayWeekdays(); + + var tbody = Calendar.createElement("tbody", table); + this.tbody = tbody; + + for (i = 6; i > 0; --i) { + row = Calendar.createElement("tr", tbody); + if (this.weekNumbers) { + cell = Calendar.createElement("td", row); + } + for (var j = 7; j > 0; --j) { + cell = Calendar.createElement("td", row); + cell.calendar = this; + Calendar._add_evs(cell); + } + } + + if (this.showsTime) { + row = Calendar.createElement("tr", tbody); + row.className = "time"; + + cell = Calendar.createElement("td", row); + cell.className = "time"; + cell.colSpan = 2; + cell.innerHTML = Calendar._TT["TIME"] || " "; + + cell = Calendar.createElement("td", row); + cell.className = "time"; + cell.colSpan = this.weekNumbers ? 4 : 3; + + (function(){ + function makeTimePart(className, init, range_start, range_end) { + var part = Calendar.createElement("span", cell); + part.className = className; + part.innerHTML = init; + part.calendar = cal; + part.ttip = Calendar._TT["TIME_PART"]; + part.navtype = 50; + part._range = []; + if (typeof range_start != "number") + part._range = range_start; + else { + for (var i = range_start; i <= range_end; ++i) { + var txt; + if (i < 10 && range_end >= 10) txt = '0' + i; + else txt = '' + i; + part._range[part._range.length] = txt; + } + } + Calendar._add_evs(part); + return part; + }; + var hrs = cal.date.getHours(); + var mins = cal.date.getMinutes(); + var t12 = !cal.time24; + var pm = (hrs > 12); + if (t12 && pm) hrs -= 12; + var H = makeTimePart("hour", hrs, t12 ? 1 : 0, t12 ? 12 : 23); + var span = Calendar.createElement("span", cell); + span.innerHTML = ":"; + span.className = "colon"; + var M = makeTimePart("minute", mins, 0, 59); + var AP = null; + cell = Calendar.createElement("td", row); + cell.className = "time"; + cell.colSpan = 2; + if (t12) + AP = makeTimePart("ampm", pm ? "pm" : "am", ["am", "pm"]); + else + cell.innerHTML = " "; + + cal.onSetTime = function() { + var pm, hrs = this.date.getHours(), + mins = this.date.getMinutes(); + if (t12) { + pm = (hrs >= 12); + if (pm) hrs -= 12; + if (hrs == 0) hrs = 12; + AP.innerHTML = pm ? "pm" : "am"; + } + H.innerHTML = (hrs < 10) ? ("0" + hrs) : hrs; + M.innerHTML = (mins < 10) ? ("0" + mins) : mins; + }; + + cal.onUpdateTime = function() { + var date = this.date; + var h = parseInt(H.innerHTML, 10); + if (t12) { + if (/pm/i.test(AP.innerHTML) && h < 12) + h += 12; + else if (/am/i.test(AP.innerHTML) && h == 12) + h = 0; + } + var d = date.getDate(); + var m = date.getMonth(); + var y = date.getFullYear(); + date.setHours(h); + date.setMinutes(parseInt(M.innerHTML, 10)); + date.setFullYear(y); + date.setMonth(m); + date.setDate(d); + this.dateClicked = false; + this.callHandler(); + }; + })(); + } else { + this.onSetTime = this.onUpdateTime = function() {}; + } + + var tfoot = Calendar.createElement("tfoot", table); + + row = Calendar.createElement("tr", tfoot); + row.className = "footrow"; + + cell = hh(Calendar._TT["SEL_DATE"], this.weekNumbers ? 8 : 7, 300); + cell.className = "ttip"; + if (this.isPopup) { + cell.ttip = Calendar._TT["DRAG_TO_MOVE"]; + cell.style.cursor = "move"; + } + this.tooltips = cell; + + div = Calendar.createElement("div", this.element); + this.monthsCombo = div; + div.className = "combo"; + for (i = 0; i < Calendar._MN.length; ++i) { + var mn = Calendar.createElement("div"); + mn.className = Calendar.is_ie ? "label-IEfix" : "label"; + mn.month = i; + mn.innerHTML = Calendar._SMN[i]; + div.appendChild(mn); + } + + div = Calendar.createElement("div", this.element); + this.yearsCombo = div; + div.className = "combo"; + for (i = 12; i > 0; --i) { + var yr = Calendar.createElement("div"); + yr.className = Calendar.is_ie ? "label-IEfix" : "label"; + div.appendChild(yr); + } + + this._init(this.firstDayOfWeek, this.date); + parent.appendChild(this.element); +}; + +/** keyboard navigation, only for popup calendars */ +Calendar._keyEvent = function(ev) { + var cal = window._dynarch_popupCalendar; + if (!cal || cal.multiple) + return false; + (Calendar.is_ie) && (ev = window.event); + var act = (Calendar.is_ie || ev.type == "keypress"), + K = ev.keyCode; + if (ev.ctrlKey) { + switch (K) { + case 37: // KEY left + act && Calendar.cellClick(cal._nav_pm); + break; + case 38: // KEY up + act && Calendar.cellClick(cal._nav_py); + break; + case 39: // KEY right + act && Calendar.cellClick(cal._nav_nm); + break; + case 40: // KEY down + act && Calendar.cellClick(cal._nav_ny); + break; + default: + return false; + } + } else switch (K) { + case 32: // KEY space (now) + Calendar.cellClick(cal._nav_now); + break; + case 27: // KEY esc + act && cal.callCloseHandler(); + break; + case 37: // KEY left + case 38: // KEY up + case 39: // KEY right + case 40: // KEY down + if (act) { + var prev, x, y, ne, el, step; + prev = K == 37 || K == 38; + step = (K == 37 || K == 39) ? 1 : 7; + function setVars() { + el = cal.currentDateEl; + var p = el.pos; + x = p & 15; + y = p >> 4; + ne = cal.ar_days[y][x]; + };setVars(); + function prevMonth() { + var date = new Date(cal.date); + date.setDate(date.getDate() - step); + cal.setDate(date); + }; + function nextMonth() { + var date = new Date(cal.date); + date.setDate(date.getDate() + step); + cal.setDate(date); + }; + while (1) { + switch (K) { + case 37: // KEY left + if (--x >= 0) + ne = cal.ar_days[y][x]; + else { + x = 6; + K = 38; + continue; + } + break; + case 38: // KEY up + if (--y >= 0) + ne = cal.ar_days[y][x]; + else { + prevMonth(); + setVars(); + } + break; + case 39: // KEY right + if (++x < 7) + ne = cal.ar_days[y][x]; + else { + x = 0; + K = 40; + continue; + } + break; + case 40: // KEY down + if (++y < cal.ar_days.length) + ne = cal.ar_days[y][x]; + else { + nextMonth(); + setVars(); + } + break; + } + break; + } + if (ne) { + if (!ne.disabled) + Calendar.cellClick(ne); + else if (prev) + prevMonth(); + else + nextMonth(); + } + } + break; + case 13: // KEY enter + if (act) + Calendar.cellClick(cal.currentDateEl, ev); + break; + default: + return false; + } + return Calendar.stopEvent(ev); +}; + +/** + * (RE)Initializes the calendar to the given date and firstDayOfWeek + */ +Calendar.prototype._init = function (firstDayOfWeek, date) { + var today = new Date(), + TY = today.getFullYear(), + TM = today.getMonth(), + TD = today.getDate(); + this.table.style.visibility = "hidden"; + var year = date.getFullYear(); + if (year < this.minYear) { + year = this.minYear; + date.setFullYear(year); + } else if (year > this.maxYear) { + year = this.maxYear; + date.setFullYear(year); + } + this.firstDayOfWeek = firstDayOfWeek; + this.date = new Date(date); + var month = date.getMonth(); + var mday = date.getDate(); + var no_days = date.getMonthDays(); + + // calendar voodoo for computing the first day that would actually be + // displayed in the calendar, even if it's from the previous month. + // WARNING: this is magic. ;-) + date.setDate(1); + var day1 = (date.getDay() - this.firstDayOfWeek) % 7; + if (day1 < 0) + day1 += 7; + date.setDate(-day1); + date.setDate(date.getDate() + 1); + + var row = this.tbody.firstChild; + var MN = Calendar._SMN[month]; + var ar_days = this.ar_days = new Array(); + var weekend = Calendar._TT["WEEKEND"]; + var dates = this.multiple ? (this.datesCells = {}) : null; + for (var i = 0; i < 6; ++i, row = row.nextSibling) { + var cell = row.firstChild; + if (this.weekNumbers) { + cell.className = "day wn"; + cell.innerHTML = date.getWeekNumber(); + cell = cell.nextSibling; + } + row.className = "daysrow"; + var hasdays = false, iday, dpos = ar_days[i] = []; + for (var j = 0; j < 7; ++j, cell = cell.nextSibling, date.setDate(iday + 1)) { + iday = date.getDate(); + var wday = date.getDay(); + cell.className = "day"; + cell.pos = i << 4 | j; + dpos[j] = cell; + var current_month = (date.getMonth() == month); + if (!current_month) { + if (this.showsOtherMonths) { + cell.className += " othermonth"; + cell.otherMonth = true; + } else { + cell.className = "emptycell"; + cell.innerHTML = " "; + cell.disabled = true; + continue; + } + } else { + cell.otherMonth = false; + hasdays = true; + } + cell.disabled = false; + cell.innerHTML = this.getDateText ? this.getDateText(date, iday) : iday; + if (dates) + dates[date.print("%Y%m%d")] = cell; + if (this.getDateStatus) { + var status = this.getDateStatus(date, year, month, iday); + if (this.getDateToolTip) { + var toolTip = this.getDateToolTip(date, year, month, iday); + if (toolTip) + cell.title = toolTip; + } + if (status === true) { + cell.className += " disabled"; + cell.disabled = true; + } else { + if (/disabled/i.test(status)) + cell.disabled = true; + cell.className += " " + status; + } + } + if (!cell.disabled) { + cell.caldate = new Date(date); + cell.ttip = "_"; + if (!this.multiple && current_month + && iday == mday && this.hiliteToday) { + cell.className += " selected"; + this.currentDateEl = cell; + } + if (date.getFullYear() == TY && + date.getMonth() == TM && + iday == TD) { + cell.className += " today"; + cell.ttip += Calendar._TT["PART_TODAY"]; + } + if (weekend.indexOf(wday.toString()) != -1) + cell.className += cell.otherMonth ? " oweekend" : " weekend"; + } + } + if (!(hasdays || this.showsOtherMonths)) + row.className = "emptyrow"; + } + this.title.innerHTML = Calendar._MN[month] + ", " + year; + this.onSetTime(); + this.table.style.visibility = "visible"; + this._initMultipleDates(); + // PROFILE + // this.tooltips.innerHTML = "Generated in " + ((new Date()) - today) + " ms"; +}; + +Calendar.prototype._initMultipleDates = function() { + if (this.multiple) { + for (var i in this.multiple) { + var cell = this.datesCells[i]; + var d = this.multiple[i]; + if (!d) + continue; + if (cell) + cell.className += " selected"; + } + } +}; + +Calendar.prototype._toggleMultipleDate = function(date) { + if (this.multiple) { + var ds = date.print("%Y%m%d"); + var cell = this.datesCells[ds]; + if (cell) { + var d = this.multiple[ds]; + if (!d) { + Calendar.addClass(cell, "selected"); + this.multiple[ds] = date; + } else { + Calendar.removeClass(cell, "selected"); + delete this.multiple[ds]; + } + } + } +}; + +Calendar.prototype.setDateToolTipHandler = function (unaryFunction) { + this.getDateToolTip = unaryFunction; +}; + +/** + * Calls _init function above for going to a certain date (but only if the + * date is different than the currently selected one). + */ +Calendar.prototype.setDate = function (date) { + if (!date.equalsTo(this.date)) { + this._init(this.firstDayOfWeek, date); + } +}; + +/** + * Refreshes the calendar. Useful if the "disabledHandler" function is + * dynamic, meaning that the list of disabled date can change at runtime. + * Just * call this function if you think that the list of disabled dates + * should * change. + */ +Calendar.prototype.refresh = function () { + this._init(this.firstDayOfWeek, this.date); +}; + +/** Modifies the "firstDayOfWeek" parameter (pass 0 for Synday, 1 for Monday, etc.). */ +Calendar.prototype.setFirstDayOfWeek = function (firstDayOfWeek) { + this._init(firstDayOfWeek, this.date); + this._displayWeekdays(); +}; + +/** + * Allows customization of what dates are enabled. The "unaryFunction" + * parameter must be a function object that receives the date (as a JS Date + * object) and returns a boolean value. If the returned value is true then + * the passed date will be marked as disabled. + */ +Calendar.prototype.setDateStatusHandler = Calendar.prototype.setDisabledHandler = function (unaryFunction) { + this.getDateStatus = unaryFunction; +}; + +/** Customization of allowed year range for the calendar. */ +Calendar.prototype.setRange = function (a, z) { + this.minYear = a; + this.maxYear = z; +}; + +/** Calls the first user handler (selectedHandler). */ +Calendar.prototype.callHandler = function () { + if (this.onSelected) { + this.onSelected(this, this.date.print(this.dateFormat)); + } +}; + +/** Calls the second user handler (closeHandler). */ +Calendar.prototype.callCloseHandler = function () { + if (this.onClose) { + this.onClose(this); + } + this.hideShowCovered(); +}; + +/** Removes the calendar object from the DOM tree and destroys it. */ +Calendar.prototype.destroy = function () { + var el = this.element.parentNode; + el.removeChild(this.element); + Calendar._C = null; + window._dynarch_popupCalendar = null; +}; + +/** + * Moves the calendar element to a different section in the DOM tree (changes + * its parent). + */ +Calendar.prototype.reparent = function (new_parent) { + var el = this.element; + el.parentNode.removeChild(el); + new_parent.appendChild(el); +}; + +// This gets called when the user presses a mouse button anywhere in the +// document, if the calendar is shown. If the click was outside the open +// calendar this function closes it. +Calendar._checkCalendar = function(ev) { + var calendar = window._dynarch_popupCalendar; + if (!calendar) { + return false; + } + var el = Calendar.is_ie ? Calendar.getElement(ev) : Calendar.getTargetElement(ev); + for (; el != null && el != calendar.element; el = el.parentNode); + if (el == null) { + // calls closeHandler which should hide the calendar. + window._dynarch_popupCalendar.callCloseHandler(); + return Calendar.stopEvent(ev); + } +}; + +/** Shows the calendar. */ +Calendar.prototype.show = function () { + var rows = this.table.getElementsByTagName("tr"); + for (var i = rows.length; i > 0;) { + var row = rows[--i]; + Calendar.removeClass(row, "rowhilite"); + var cells = row.getElementsByTagName("td"); + for (var j = cells.length; j > 0;) { + var cell = cells[--j]; + Calendar.removeClass(cell, "hilite"); + Calendar.removeClass(cell, "active"); + } + } + this.element.style.display = "block"; + this.hidden = false; + if (this.isPopup) { + window._dynarch_popupCalendar = this; + Calendar.addEvent(document, "keydown", Calendar._keyEvent); + Calendar.addEvent(document, "keypress", Calendar._keyEvent); + Calendar.addEvent(document, "mousedown", Calendar._checkCalendar); + } + this.hideShowCovered(); +}; + +/** + * Hides the calendar. Also removes any "hilite" from the class of any TD + * element. + */ +Calendar.prototype.hide = function () { + if (this.isPopup) { + Calendar.removeEvent(document, "keydown", Calendar._keyEvent); + Calendar.removeEvent(document, "keypress", Calendar._keyEvent); + Calendar.removeEvent(document, "mousedown", Calendar._checkCalendar); + } + this.element.style.display = "none"; + this.hidden = true; + this.hideShowCovered(); +}; + +/** + * Shows the calendar at a given absolute position (beware that, depending on + * the calendar element style -- position property -- this might be relative + * to the parent's containing rectangle). + */ +Calendar.prototype.showAt = function (x, y) { + var s = this.element.style; + s.left = x + "px"; + s.top = y + "px"; + this.show(); +}; + +/** Shows the calendar near a given element. */ +Calendar.prototype.showAtElement = function (el, opts) { + var self = this; + var p = Calendar.getAbsolutePos(el); + if (!opts || typeof opts != "string") { + this.showAt(p.x, p.y + el.offsetHeight); + return true; + } + function fixPosition(box) { + if (box.x < 0) + box.x = 0; + if (box.y < 0) + box.y = 0; + var cp = document.createElement("div"); + var s = cp.style; + s.position = "absolute"; + s.right = s.bottom = s.width = s.height = "0px"; + document.body.appendChild(cp); + var br = Calendar.getAbsolutePos(cp); + document.body.removeChild(cp); + br.y += window.scrollY; + br.x += window.scrollX; + var tmp = box.x + box.width - br.x; + if (tmp > 0) box.x -= tmp; + tmp = box.y + box.height - br.y; + if (tmp > 0) box.y -= tmp; + }; + this.element.style.display = "block"; + Calendar.continuation_for_khtml_browser = function() { + var w = self.element.offsetWidth; + var h = self.element.offsetHeight; + self.element.style.display = "none"; + var valign = opts.substr(0, 1); + var halign = "l"; + if (opts.length > 1) { + halign = opts.substr(1, 1); + } + // vertical alignment + switch (valign) { + case "T": p.y -= h; break; + case "B": p.y += el.offsetHeight; break; + case "C": p.y += (el.offsetHeight - h) / 2; break; + case "t": p.y += el.offsetHeight - h; break; + case "b": break; // already there + } + // horizontal alignment + switch (halign) { + case "L": p.x -= w; break; + case "R": p.x += el.offsetWidth; break; + case "C": p.x += (el.offsetWidth - w) / 2; break; + case "l": p.x += el.offsetWidth - w; break; + case "r": break; // already there + } + p.width = w; + p.height = h + 40; + self.monthsCombo.style.display = "none"; + fixPosition(p); + self.showAt(p.x, p.y); + }; + if (Calendar.is_khtml) + setTimeout("Calendar.continuation_for_khtml_browser()", 10); + else + Calendar.continuation_for_khtml_browser(); +}; + +/** Customizes the date format. */ +Calendar.prototype.setDateFormat = function (str) { + this.dateFormat = str; +}; + +/** Customizes the tooltip date format. */ +Calendar.prototype.setTtDateFormat = function (str) { + this.ttDateFormat = str; +}; + +/** + * Tries to identify the date represented in a string. If successful it also + * calls this.setDate which moves the calendar to the given date. + */ +Calendar.prototype.parseDate = function(str, fmt) { + if (!fmt) + fmt = this.dateFormat; + this.setDate(Date.parseDate(str, fmt)); +}; + +Calendar.prototype.hideShowCovered = function () { + if (!Calendar.is_ie && !Calendar.is_opera) + return; + function getVisib(obj){ + var value = obj.style.visibility; + if (!value) { + if (document.defaultView && typeof (document.defaultView.getComputedStyle) == "function") { // Gecko, W3C + if (!Calendar.is_khtml) + value = document.defaultView. + getComputedStyle(obj, "").getPropertyValue("visibility"); + else + value = ''; + } else if (obj.currentStyle) { // IE + value = obj.currentStyle.visibility; + } else + value = ''; + } + return value; + }; + + var tags = new Array("applet", "iframe", "select"); + var el = this.element; + + var p = Calendar.getAbsolutePos(el); + var EX1 = p.x; + var EX2 = el.offsetWidth + EX1; + var EY1 = p.y; + var EY2 = el.offsetHeight + EY1; + + for (var k = tags.length; k > 0; ) { + var ar = document.getElementsByTagName(tags[--k]); + var cc = null; + + for (var i = ar.length; i > 0;) { + cc = ar[--i]; + + p = Calendar.getAbsolutePos(cc); + var CX1 = p.x; + var CX2 = cc.offsetWidth + CX1; + var CY1 = p.y; + var CY2 = cc.offsetHeight + CY1; + + if (this.hidden || (CX1 > EX2) || (CX2 < EX1) || (CY1 > EY2) || (CY2 < EY1)) { + if (!cc.__msh_save_visibility) { + cc.__msh_save_visibility = getVisib(cc); + } + cc.style.visibility = cc.__msh_save_visibility; + } else { + if (!cc.__msh_save_visibility) { + cc.__msh_save_visibility = getVisib(cc); + } + cc.style.visibility = "hidden"; + } + } + } +}; + +/** Internal function; it displays the bar with the names of the weekday. */ +Calendar.prototype._displayWeekdays = function () { + var fdow = this.firstDayOfWeek; + var cell = this.firstdayname; + var weekend = Calendar._TT["WEEKEND"]; + for (var i = 0; i < 7; ++i) { + cell.className = "day name"; + var realday = (i + fdow) % 7; + if (i) { + cell.ttip = Calendar._TT["DAY_FIRST"].replace("%s", Calendar._DN[realday]); + cell.navtype = 100; + cell.calendar = this; + cell.fdow = realday; + Calendar._add_evs(cell); + } + if (weekend.indexOf(realday.toString()) != -1) { + Calendar.addClass(cell, "weekend"); + } + cell.innerHTML = Calendar._SDN[(i + fdow) % 7]; + cell = cell.nextSibling; + } +}; + +/** Internal function. Hides all combo boxes that might be displayed. */ +Calendar.prototype._hideCombos = function () { + this.monthsCombo.style.display = "none"; + this.yearsCombo.style.display = "none"; +}; + +/** Internal function. Starts dragging the element. */ +Calendar.prototype._dragStart = function (ev) { + if (this.dragging) { + return; + } + this.dragging = true; + var posX; + var posY; + if (Calendar.is_ie) { + posY = window.event.clientY + document.body.scrollTop; + posX = window.event.clientX + document.body.scrollLeft; + } else { + posY = ev.clientY + window.scrollY; + posX = ev.clientX + window.scrollX; + } + var st = this.element.style; + this.xOffs = posX - parseInt(st.left); + this.yOffs = posY - parseInt(st.top); + with (Calendar) { + addEvent(document, "mousemove", calDragIt); + addEvent(document, "mouseup", calDragEnd); + } +}; + +// BEGIN: DATE OBJECT PATCHES + +/** Adds the number of days array to the Date object. */ +Date._MD = new Array(31,28,31,30,31,30,31,31,30,31,30,31); + +/** Constants used for time computations */ +Date.SECOND = 1000 /* milliseconds */; +Date.MINUTE = 60 * Date.SECOND; +Date.HOUR = 60 * Date.MINUTE; +Date.DAY = 24 * Date.HOUR; +Date.WEEK = 7 * Date.DAY; + +Date.parseDate = function(str, fmt) { + var today = new Date(); + var y = 0; + var m = -1; + var d = 0; + var a = str.split(/\W+/); + var b = fmt.match(/%./g); + var i = 0, j = 0; + var hr = 0; + var min = 0; + for (i = 0; i < a.length; ++i) { + if (!a[i]) + continue; + switch (b[i]) { + case "%d": + case "%e": + d = parseInt(a[i], 10); + break; + + case "%m": + m = parseInt(a[i], 10) - 1; + break; + + case "%Y": + case "%y": + y = parseInt(a[i], 10); + (y < 100) && (y += (y > 29) ? 1900 : 2000); + break; + + case "%b": + case "%B": + for (j = 0; j < 12; ++j) { + if (Calendar._MN[j].substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) { m = j; break; } + } + break; + + case "%H": + case "%I": + case "%k": + case "%l": + hr = parseInt(a[i], 10); + break; + + case "%P": + case "%p": + if (/pm/i.test(a[i]) && hr < 12) + hr += 12; + else if (/am/i.test(a[i]) && hr >= 12) + hr -= 12; + break; + + case "%M": + min = parseInt(a[i], 10); + break; + } + } + if (isNaN(y)) y = today.getFullYear(); + if (isNaN(m)) m = today.getMonth(); + if (isNaN(d)) d = today.getDate(); + if (isNaN(hr)) hr = today.getHours(); + if (isNaN(min)) min = today.getMinutes(); + if (y != 0 && m != -1 && d != 0) + return new Date(y, m, d, hr, min, 0); + y = 0; m = -1; d = 0; + for (i = 0; i < a.length; ++i) { + if (a[i].search(/[a-zA-Z]+/) != -1) { + var t = -1; + for (j = 0; j < 12; ++j) { + if (Calendar._MN[j].substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) { t = j; break; } + } + if (t != -1) { + if (m != -1) { + d = m+1; + } + m = t; + } + } else if (parseInt(a[i], 10) <= 12 && m == -1) { + m = a[i]-1; + } else if (parseInt(a[i], 10) > 31 && y == 0) { + y = parseInt(a[i], 10); + (y < 100) && (y += (y > 29) ? 1900 : 2000); + } else if (d == 0) { + d = a[i]; + } + } + if (y == 0) + y = today.getFullYear(); + if (m != -1 && d != 0) + return new Date(y, m, d, hr, min, 0); + return today; +}; + +/** Returns the number of days in the current month */ +Date.prototype.getMonthDays = function(month) { + var year = this.getFullYear(); + if (typeof month == "undefined") { + month = this.getMonth(); + } + if (((0 == (year%4)) && ( (0 != (year%100)) || (0 == (year%400)))) && month == 1) { + return 29; + } else { + return Date._MD[month]; + } +}; + +/** Returns the number of day in the year. */ +Date.prototype.getDayOfYear = function() { + var now = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0); + var then = new Date(this.getFullYear(), 0, 0, 0, 0, 0); + var time = now - then; + return Math.floor(time / Date.DAY); +}; + +/** Returns the number of the week in year, as defined in ISO 8601. */ +Date.prototype.getWeekNumber = function() { + var d = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0); + var DoW = d.getDay(); + d.setDate(d.getDate() - (DoW + 6) % 7 + 3); // Nearest Thu + var ms = d.valueOf(); // GMT + d.setMonth(0); + d.setDate(4); // Thu in Week 1 + return Math.round((ms - d.valueOf()) / (7 * 864e5)) + 1; +}; + +/** Checks date and time equality */ +Date.prototype.equalsTo = function(date) { + return ((this.getFullYear() == date.getFullYear()) && + (this.getMonth() == date.getMonth()) && + (this.getDate() == date.getDate()) && + (this.getHours() == date.getHours()) && + (this.getMinutes() == date.getMinutes())); +}; + +/** Set only the year, month, date parts (keep existing time) */ +Date.prototype.setDateOnly = function(date) { + var tmp = new Date(date); + this.setDate(1); + this.setFullYear(tmp.getFullYear()); + this.setMonth(tmp.getMonth()); + this.setDate(tmp.getDate()); +}; + +/** Prints the date in a string according to the given format. */ +Date.prototype.print = function (str) { + var m = this.getMonth(); + var d = this.getDate(); + var y = this.getFullYear(); + var wn = this.getWeekNumber(); + var w = this.getDay(); + var s = {}; + var hr = this.getHours(); + var pm = (hr >= 12); + var ir = (pm) ? (hr - 12) : hr; + var dy = this.getDayOfYear(); + if (ir == 0) + ir = 12; + var min = this.getMinutes(); + var sec = this.getSeconds(); + s["%a"] = Calendar._SDN[w]; // abbreviated weekday name [FIXME: I18N] + s["%A"] = Calendar._DN[w]; // full weekday name + s["%b"] = Calendar._SMN[m]; // abbreviated month name [FIXME: I18N] + s["%B"] = Calendar._MN[m]; // full month name + // FIXME: %c : preferred date and time representation for the current locale + s["%C"] = 1 + Math.floor(y / 100); // the century number + s["%d"] = (d < 10) ? ("0" + d) : d; // the day of the month (range 01 to 31) + s["%e"] = d; // the day of the month (range 1 to 31) + // FIXME: %D : american date style: %m/%d/%y + // FIXME: %E, %F, %G, %g, %h (man strftime) + s["%H"] = (hr < 10) ? ("0" + hr) : hr; // hour, range 00 to 23 (24h format) + s["%I"] = (ir < 10) ? ("0" + ir) : ir; // hour, range 01 to 12 (12h format) + s["%j"] = (dy < 100) ? ((dy < 10) ? ("00" + dy) : ("0" + dy)) : dy; // day of the year (range 001 to 366) + s["%k"] = hr; // hour, range 0 to 23 (24h format) + s["%l"] = ir; // hour, range 1 to 12 (12h format) + s["%m"] = (m < 9) ? ("0" + (1+m)) : (1+m); // month, range 01 to 12 + s["%M"] = (min < 10) ? ("0" + min) : min; // minute, range 00 to 59 + s["%n"] = "\n"; // a newline character + s["%p"] = pm ? "PM" : "AM"; + s["%P"] = pm ? "pm" : "am"; + // FIXME: %r : the time in am/pm notation %I:%M:%S %p + // FIXME: %R : the time in 24-hour notation %H:%M + s["%s"] = Math.floor(this.getTime() / 1000); + s["%S"] = (sec < 10) ? ("0" + sec) : sec; // seconds, range 00 to 59 + s["%t"] = "\t"; // a tab character + // FIXME: %T : the time in 24-hour notation (%H:%M:%S) + s["%U"] = s["%W"] = s["%V"] = (wn < 10) ? ("0" + wn) : wn; + s["%u"] = w + 1; // the day of the week (range 1 to 7, 1 = MON) + s["%w"] = w; // the day of the week (range 0 to 6, 0 = SUN) + // FIXME: %x : preferred date representation for the current locale without the time + // FIXME: %X : preferred time representation for the current locale without the date + s["%y"] = ('' + y).substr(2, 2); // year without the century (range 00 to 99) + s["%Y"] = y; // year with the century + s["%%"] = "%"; // a literal '%' character + + var re = /%./g; + if (!Calendar.is_ie5 && !Calendar.is_khtml) + return str.replace(re, function (par) { return s[par] || par; }); + + var a = str.match(re); + for (var i = 0; i < a.length; i++) { + var tmp = s[a[i]]; + if (tmp) { + re = new RegExp(a[i], 'g'); + str = str.replace(re, tmp); + } + } + + return str; +}; + +Date.prototype.__msh_oldSetFullYear = Date.prototype.setFullYear; +Date.prototype.setFullYear = function(y) { + var d = new Date(this); + d.__msh_oldSetFullYear(y); + if (d.getMonth() != this.getMonth()) + this.setDate(28); + this.__msh_oldSetFullYear(y); +}; + +// END: DATE OBJECT PATCHES + + +// global object that remembers the calendar +window._dynarch_popupCalendar = null; + + +function selectDate(cal) { + var p = cal.params; + var update = (cal.dateClicked || p.electric); + year = p.inputField.id; + + day = p.baseField + '_2'; + month = p.baseField + '_1'; + + document.getElementById(month).value = cal.date.print('%m'); + document.getElementById(day).value = cal.date.print('%e'); + document.getElementById(year).value = cal.date.print('%Y'); +} + +function selectEuropeDate(cal) { + var p = cal.params; + var update = (cal.dateClicked || p.electric); + year = p.inputField.id; + + day = p.baseField + '_1'; + month = p.baseField + '_2'; + + document.getElementById(month).value = cal.date.print('%m'); + document.getElementById(day).value = cal.date.print('%e'); + document.getElementById(year).value = cal.date.print('%Y'); +} + +// ** I18N + +// Calendar EN language +// Author: Mihai Bazon, +// Encoding: any +// Distributed under the same terms as the calendar itself. + +// full day names +Calendar._DN = new Array +("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"); + +// short day names +Calendar._SDN = new Array +("S", "M", "T", "W", "T", "F", "S", "S"); + +// First day of the week. "0" means display Sunday first, "1" means display +// Monday first, etc. +Calendar._FD = 0; + +// full month names +Calendar._MN = new Array +("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"); + +// short month names +Calendar._SMN = new Array +("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"); + +// tooltips +Calendar._TT = {}; +Calendar._TT["INFO"] = "About the Calendar"; + +Calendar._TT["ABOUT"] = +"DHTML Date/Time Selector\n" + +"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this ;-) +"For latest version visit: http://www.dynarch.com/projects/calendar/\n" + +"Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." + +"\n\n" + +"Date selection:\n" + +"- Use the \xab, \xbb buttons to select year\n" + +"- Use the " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " buttons to select month\n" + +"- Hold mouse button on any of the above buttons for faster selection."; +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"Time selection:\n" + +"- Click on any of the time parts to increase it\n" + +"- or Shift-click to decrease it\n" + +"- or click and drag for faster selection."; + +Calendar._TT["PREV_YEAR"] = "Prev. Year (Hold for Menu)"; +Calendar._TT["PREV_MONTH"] = "Prev. Month (Hold for Menu)"; +Calendar._TT["GO_TODAY"] = "Go to Today"; +Calendar._TT["NEXT_MONTH"] = "Next Month (Hold for Menu)"; +Calendar._TT["NEXT_YEAR"] = "Next Year (Hold for Menu)"; +Calendar._TT["SEL_DATE"] = "Select Date"; +Calendar._TT["DRAG_TO_MOVE"] = "Drag to Move"; +Calendar._TT["PART_TODAY"] = " (Today)"; + +// the following is to inform that "%s" is to be the first day of week +// %s will be replaced with the day name. +Calendar._TT["DAY_FIRST"] = "Display %ss first"; + +// This may be locale-dependent. It specifies the week-end days, as an array +// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 +// means Monday, etc. +Calendar._TT["WEEKEND"] = "0,6"; + +Calendar._TT["CLOSE"] = "Close Calendar"; +Calendar._TT["TODAY"] = "Today"; +Calendar._TT["TIME_PART"] = "(Shift-)Click or Drag to Change Value"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; +Calendar._TT["TT_DATE_FORMAT"] = "%b %e, %Y"; + +Calendar._TT["WK"] = "wk"; +Calendar._TT["TIME"] = "Time:"; +/* Copyright Mihai Bazon, 2002, 2003 | http://dynarch.com/mishoo/ + * --------------------------------------------------------------------------- + * + * The DHTML Calendar + * + * Details and latest version at: + * http://dynarch.com/mishoo/calendar.epl + * + * This script is distributed under the GNU Lesser General Public License. + * Read the entire license text here: http://www.gnu.org/licenses/lgpl.html + * + */ + +// $Id: calendar-setup.js,v 1.25 2005/03/07 09:51:33 mishoo Exp $ + +Calendar.setup = function (params) { + function param_default(pname, def) { if (typeof params[pname] == "undefined") { params[pname] = def; } }; + + param_default("inputField", null); + param_default("displayArea", null); + param_default("button", null); + param_default("eventName", "click"); + param_default("ifFormat", "%Y/%m/%d"); + param_default("daFormat", "%Y/%m/%d"); + param_default("singleClick", true); + param_default("disableFunc", null); + param_default("dateStatusFunc", params["disableFunc"]); // takes precedence if both are defined + param_default("dateText", null); + param_default("firstDay", null); + param_default("align", "BR"); + param_default("range", [1900, 2999]); + param_default("weekNumbers", false); + param_default("flat", null); + param_default("flatCallback", null); + param_default("onSelect", null); + param_default("onClose", null); + param_default("onUpdate", null); + param_default("date", null); + param_default("showsTime", false); + param_default("timeFormat", "24"); + param_default("electric", true); + param_default("step", 2); + param_default("position", null); + param_default("cache", false); + param_default("showOthers", false); + param_default("multiple", null); + + var tmp = ["inputField", "displayArea", "button"]; + for (var i in tmp) { + if (typeof params[tmp[i]] == "string") { + params[tmp[i]] = document.getElementById(params[tmp[i]]); + } + } + if (!(params.flat || params.multiple || params.inputField || params.displayArea || params.button)) { + alert("Calendar.setup:\n Nothing to setup (no fields found). Please check your code"); + return false; + } + + function onSelect(cal) { + var p = cal.params; + var update = (cal.dateClicked || p.electric); + if (update && p.inputField) { + p.inputField.value = cal.date.print(p.ifFormat); + if (typeof p.inputField.onchange == "function") + p.inputField.onchange(); + } + if (update && p.displayArea) + p.displayArea.innerHTML = cal.date.print(p.daFormat); + if (update && typeof p.onUpdate == "function") + p.onUpdate(cal); + if (update && p.flat) { + if (typeof p.flatCallback == "function") + p.flatCallback(cal); + } + if (update && p.singleClick && cal.dateClicked) + cal.callCloseHandler(); + }; + + if (params.flat != null) { + if (typeof params.flat == "string") + params.flat = document.getElementById(params.flat); + if (!params.flat) { + alert("Calendar.setup:\n Flat specified but can't find parent."); + return false; + } + var cal = new Calendar(params.firstDay, params.date, params.onSelect || onSelect); + cal.showsOtherMonths = params.showOthers; + cal.showsTime = params.showsTime; + cal.time24 = (params.timeFormat == "24"); + cal.params = params; + cal.weekNumbers = params.weekNumbers; + cal.setRange(params.range[0], params.range[1]); + cal.setDateStatusHandler(params.dateStatusFunc); + cal.getDateText = params.dateText; + if (params.ifFormat) { + cal.setDateFormat(params.ifFormat); + } + if (params.inputField && typeof params.inputField.value == "string") { + cal.parseDate(params.inputField.value); + } + cal.create(params.flat); + cal.show(); + return false; + } + + var triggerEl = params.button || params.displayArea || params.inputField; + triggerEl["on" + params.eventName] = function() { + var dateEl = params.inputField || params.displayArea; + var dateFmt = params.inputField ? params.ifFormat : params.daFormat; + var mustCreate = false; + var cal = window.calendar; + if (dateEl) + params.date = Date.parseDate(dateEl.value || dateEl.innerHTML, dateFmt); + if (!(cal && params.cache)) { + window.calendar = cal = new Calendar(params.firstDay, + params.date, + params.onSelect || onSelect, + params.onClose || function(cal) { cal.hide(); }); + cal.showsTime = params.showsTime; + cal.time24 = (params.timeFormat == "24"); + cal.weekNumbers = params.weekNumbers; + mustCreate = true; + } else { + if (params.date) + cal.setDate(params.date); + cal.hide(); + } + if (params.multiple) { + cal.multiple = {}; + for (var i = params.multiple.length; --i >= 0;) { + var d = params.multiple[i]; + var ds = d.print("%Y%m%d"); + cal.multiple[ds] = d; + } + } + cal.showsOtherMonths = params.showOthers; + cal.yearStep = params.step; + cal.setRange(params.range[0], params.range[1]); + cal.params = params; + cal.setDateStatusHandler(params.dateStatusFunc); + cal.getDateText = params.dateText; + cal.setDateFormat(dateFmt); + if (mustCreate) + cal.create(); + cal.refresh(); + if (!params.position) + cal.showAtElement(params.button || params.displayArea || params.inputField, params.align); + else + cal.showAt(params.position[0], params.position[1]); + return false; + }; + + return cal; +}; \ No newline at end of file diff --git a/js/email_entry.js b/js/email_entry.js new file mode 100644 index 0000000..89e939e --- /dev/null +++ b/js/email_entry.js @@ -0,0 +1,305 @@ +/* + * SimpleModal Contact Form + * http://www.ericmmartin.com/projects/simplemodal/ + * http://code.google.com/p/simplemodal/ + * + * Copyright (c) 2007 Eric Martin - http://ericmmartin.com + * + * Licensed under the MIT license: + * http://www.opensource.org/licenses/mit-license.php + * + * Revision: $Id: contact.js 113 2008-03-15 15:36:21Z emartin24 $ + * + */ +function email_entry(i_form_id,i_entry_id){ + // load the contact form using ajax + $.get("email_entry.php",{form_id: i_form_id, entry_id: i_entry_id}, function(data){ + // create a modal dialog with the data + $(data).modal({ + close: false, + overlayId: 'contact-overlay', + containerId: 'contact-container', + onOpen: contact.open, + onShow: contact.show, + onClose: contact.close + }); + }); +} + +$(document).ready(function () { + $('#ve_detail_table').columnHover(); + + + // preload images + var img = ['cancel.png','form_bottom.gif','form_top.gif','form_top_ie.gif','ajax-loader.gif','send.png']; + $(img).each(function () { + var i = new Image(); + i.src = 'images/simple_modal/' + this; + }); +}); + +function explode( delimiter, string ) { + // http://kevin.vanzonneveld.net + // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // + improved by: kenneth + // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // * example 1: explode(' ', 'Kevin van Zonneveld'); + // * returns 1: {0: 'Kevin', 1: 'van', 2: 'Zonneveld'} + + var emptyArray = { 0: '' }; + + if ( arguments.length != 2 + || typeof arguments[0] == 'undefined' + || typeof arguments[1] == 'undefined' ) + { + return null; + } + + if ( delimiter === '' + || delimiter === false + || delimiter === null ) + { + return false; + } + + if ( typeof delimiter == 'function' + || typeof delimiter == 'object' + || typeof string == 'function' + || typeof string == 'object' ) + { + return emptyArray; + } + + if ( delimiter === true ) { + delimiter = '1'; + } + + return string.toString().split ( delimiter.toString() ); +} + +function trim( str, charlist ) { + // http://kevin.vanzonneveld.net + // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // + improved by: mdsjack (http://www.mdsjack.bo.it) + // + improved by: Alexander Ermolaev (http://snippets.dzone.com/user/AlexanderErmolaev) + // + input by: Erkekjetter + // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // + input by: DxGx + // + improved by: Steven Levithan (http://blog.stevenlevithan.com) + // * example 1: trim(' Kevin van Zonneveld '); + // * returns 1: 'Kevin van Zonneveld' + // * example 2: trim('Hello World', 'Hdle'); + // * returns 2: 'o Wor' + + var whitespace; + + if(!charlist){ + whitespace = ' \n\r\t\f\x0b\xa0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000'; + } else{ + whitespace = charlist.replace(/([\[\]\(\)\.\?\/\*\{\}\+\$\^\:])/g, '\$1'); + } + + for (var i = 0; i < str.length; i++) { + if (whitespace.indexOf(str.charAt(i)) === -1) { + str = str.substring(i); + break; + } + } + for (i = str.length - 1; i >= 0; i--) { + if (whitespace.indexOf(str.charAt(i)) === -1) { + str = str.substring(0, i + 1); + break; + } + } + return whitespace.indexOf(str.charAt(0)) === -1 ? str : ''; +} + +var contact = { + message: null, + open: function (dialog) { + // add padding to the buttons in firefox/mozilla + if ($.browser.mozilla) { + $('#contact-container .contact-button').css({ + 'padding-bottom': '2px' + }); + } + // input field font size + if ($.browser.safari) { + $('#contact-container .contact-input').css({ + 'font-size': '.9em' + }); + } + + var title = $('#contact-container .contact-title').html(); + $('#contact-container .contact-title').html('Loading...'); + dialog.overlay.fadeIn(200, function () { + dialog.container.fadeIn(200, function () { + dialog.data.fadeIn(200, function () { + $('#contact-container .contact-content').animate({ + height: 205 + }, function () { + $('#contact-container .contact-title').html(title); + $('#contact-container form').fadeIn(200, function () { + $('#contact-container #contact-name').focus(); + + // fix png's for IE 6 + if ($.browser.msie && $.browser.version < 7) { + $('#contact-container .contact-button').each(function () { + if ($(this).css('backgroundImage').match(/^url[("']+(.*\.png)[)"']+$/i)) { + var src = RegExp.$1; + $(this).css({ + backgroundImage: 'none', + filter: 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' + src + '", sizingMethod="crop")' + }); + } + }); + } + }); + }); + }); + }); + }); + }, + show: function (dialog) { + $('#contact-container .contact-send').click(function (e) { + e.preventDefault(); + // validate form + if (contact.validate()) { + $('#contact-container .contact-message').fadeOut(function () { + $('#contact-container .contact-message').removeClass('contact-error').empty(); + }); + $('#contact-container .contact-title').html('Sending...'); + $('#contact-container form').fadeOut(200); + $('#contact-container .contact-content').animate({ + height: '110px' + }, function () { + if ($.browser.msie){ + $('#contact-container .contact-loading').css("margin-left","-40px"); + } + $('#contact-container .contact-loading').fadeIn(200, function () { + $.ajax({ + url: 'email_entry.php', + data: $('#contact-container form').serialize() + '&action=send', + type: 'post', + cache: false, + dataType: 'html', + complete: function (xhr) { + $('#contact-container .contact-loading').fadeOut(200, function () { + $('#contact-container .contact-title').html('Email sent.'); + $('#contact-container .contact-message').html(xhr.responseText).fadeIn(200); + }); + }, + error: contact.error + }); + }); + }); + } + else { + if ($('#contact-container .contact-message:visible').length > 0) { + var msg = $('#contact-container .contact-message div'); + msg.fadeOut(200, function () { + msg.empty(); + contact.showError(); + msg.fadeIn(200); + }); + } + else { + $('#contact-container .contact-message').animate({ + height: '30px' + }, contact.showError); + } + + } + }); + }, + close: function (dialog) { + $('#contact-container .contact-message').fadeOut(); + $('#contact-container .contact-title').html(' '); + $('#contact-container form').fadeOut(200); + $('#contact-container .contact-content').animate({ + height: 40 + }, function () { + dialog.data.fadeOut(200, function () { + dialog.container.fadeOut(200, function () { + dialog.overlay.fadeOut(200, function () { + $.modal.close(); + }); + }); + }); + }); + }, + error: function (xhr) { + alert(xhr.statusText); + }, + validate: function () { + contact.message = ''; + + var email = $('#contact-container #contact-email').val(); + if (!email) { + contact.message += 'Email is required. '; + } + else { + email_array = explode(',',email); + var arLen=email_array.length; + for ( var i=0; i 0) { + return false; + } + else { + return true; + } + }, + validateEmail: function (email) { + var at = email.lastIndexOf("@"); + + // Make sure the at (@) sybmol exists and + // it is not the first or last character + if (at < 1 || (at + 1) === email.length) + return false; + + // Make sure there aren't multiple periods together + if (/(\.{2,})/.test(email)) + return false; + + // Break up the local and domain portions + var local = email.substring(0, at); + var domain = email.substring(at + 1); + + // Check lengths + if (local.length < 1 || local.length > 64 || domain.length < 4 || domain.length > 255) + return false; + + // Make sure local and domain don't start with or end with a period + if (/(^\.|\.$)/.test(local) || /(^\.|\.$)/.test(domain)) + return false; + + // Check for quoted-string addresses + // Since almost anything is allowed in a quoted-string address, + // we're just going to let them go through + if (!/^"(.+)"$/.test(local)) { + // It's a dot-string address...check for valid characters + if (!/^[-a-zA-Z0-9!#$%*\/?|^{}`~&'+=_\.]*$/.test(local)) + return false; + } + + // Make sure domain contains only valid characters and at least one period + if (!/^[-a-zA-Z0-9\.]*$/.test(domain) || domain.indexOf(".") === -1) + return false; + + return true; + }, + showError: function () { + $('#contact-container .contact-message') + .html($('
    ').append(contact.message)) + .fadeIn(200); + } +}; \ No newline at end of file diff --git a/js/jquery/jquery-columnhover.js b/js/jquery/jquery-columnhover.js new file mode 100644 index 0000000..3d650bd --- /dev/null +++ b/js/jquery/jquery-columnhover.js @@ -0,0 +1,200 @@ +/* + * jQuery columnHover plugin + * Version: 0.1.1 + * + * Copyright (c) 2007 Roman Weich + * http://p.sohei.org + * + * Dual licensed under the MIT and GPL licenses + * (This means that you can choose the license that best suits your project, and use it accordingly): + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + * + * Changelog: + * v 0.1.1 - 2007-08-05 + * -change: included new option "ignoreCols", through which columns can be excluded from the highlighting process + * v 0.1.0 - 2007-05-25 + */ + +(function($) +{ + /** + * Calculates the actual cellIndex value of all cells in the table and stores it in the realCell property of each cell. + * Thats done because the cellIndex value isn't correct when colspans or rowspans are used. + * Originally created by Matt Kruse for his table library - Big Thanks! (see http://www.javascripttoolbox.com/) + * @param {element} table The table element. + */ + var fixCellIndexes = function(table) + { + var rows = table.rows; + var len = rows.length; + var matrix = []; + for ( var i = 0; i < len; i++ ) + { + var cells = rows[i].cells; + var clen = cells.length; + for ( var j = 0; j < clen; j++ ) + { + var c = cells[j]; + var rowSpan = c.rowSpan || 1; + var colSpan = c.colSpan || 1; + var firstAvailCol = -1; + if ( !matrix[i] ) + { + matrix[i] = []; + } + var m = matrix[i]; + // Find first available column in the first row + while ( m[++firstAvailCol] ) {} + c.realIndex = firstAvailCol; + for ( var k = i; k < i + rowSpan; k++ ) + { + if ( !matrix[k] ) + { + matrix[k] = []; + } + var matrixrow = matrix[k]; + for ( var l = firstAvailCol; l < firstAvailCol + colSpan; l++ ) + { + matrixrow[l] = 1; + } + } + } + } + }; + + /** + * Highlight whole table columns when hovering over a table. + * Works on tables with rowspans and colspans. + * + * @param {map} options An object for optional settings (options described below). + * + * @option {string} hoverClass A CSS class that is set on the cells in the column with the mouse over. + * Default value: 'hover' + * @option {boolean} eachCell Allows highlighting the column while hovering over the table body or table footer. When disabled, highlighting is allowed only through the table header. + * Default value: false + * @option {boolean} includeSpans Includes columns with the colspan attribute set in the hover and highlight process. + * Default value: true + * @option {array} ignoreCols An array of numbers. Each column with the matching column index won't be included in the highlighting process. + * Index starting at 1! + * Default value: [] (empty array) + * + * @example $('#table').columnHover(); + * @desc Allow column hovering/highlighting for the table using the default settings. + * + * @example $('#table').columnHover({eachCell:true, hoverClass:'someclass'}); + * @desc Allow column hovering/highlighting for the whole table (including the body and footer). Set the class "someclass" to the cells in the column with the mouse over. + * + * @type jQuery + * + * @name columnHover + * @cat Plugins/columnHover + * @author Roman Weich (http://p.sohei.org) + */ + $.fn.columnHover = function(options) + { + var settings = $.extend({ + hoverClass: 'hover', + eachCell: false, + includeSpans : true, + ignoreCols : [] + }, options); + + /** + * Adds or removes the hover style on the column. + * @param {element} cell The cell with the mouseover/mouseout event. + * @param {array} colIndex The index with the stored columns. + * @param {boolean} on Defines whether the style will be set or removed. + */ + var hover = function(cell, colIndex, on) + { + var a = colIndex[cell.realIndex]; + var i = 0; + if ( $(settings.ignoreCols).index(cell.realIndex + 1) != -1 ) + { + return; //dont highlight the columns in the ignoreCols array + } + while ( ++i < cell.colSpan ) + { + a = a.concat(colIndex[cell.realIndex + i]); + } + if ( on ) + { + $(a).addClass(settings.hoverClass); + } + else + { + $(a).removeClass(settings.hoverClass); + } + }; + + /** + * Adds the hover events to the cell. + * @param {jQuery result array} $s The elements to add the events to. + * @param {array} colIndex The index with the stored columns. + */ + var addHover = function($s, colIndex) + { + $s.bind('mouseover', function(){ + hover(this, colIndex, true); + }).bind('mouseout', function(){ + hover(this, colIndex, false); + }); + }; + + return this.each(function() + { + var colIndex = []; + var tbl = this; + var body, row, c, tboI, rowI, cI, rI, s; + + if ( !tbl.tBodies || !tbl.tBodies.length || !tbl.tHead || !settings.hoverClass.length ) + { + return; + } + fixCellIndexes(tbl); + //create index - loop through the bodies + for ( tboI = 0; tboI < tbl.tBodies.length; tboI++ ) + { + body = tbl.tBodies[tboI]; + //loop through the rows + for ( rowI = 0; rowI < body.rows.length; rowI++ ) + { + row = body.rows[rowI]; + //each cell + for ( cI = 0; cI < row.cells.length; cI++ ) + { + c = row.cells[cI]; + //ignore cells with colspan? + if ( !settings.includeSpans && c.colSpan > 1 ) + { + continue; + } + s = (settings.includeSpans) ? c.colSpan : 1; + while ( --s >= 0 ) + { + rI = c.realIndex + s; + if ( !colIndex[rI] ) + { + colIndex[rI] = []; + } + colIndex[rI].push(c); + } + //add hover event? + if ( settings.eachCell ) + { + addHover($(c), colIndex); + } + } + } + } + //events + addHover($('td, th', tbl.tHead), colIndex); + //add hover event to footer? + if ( settings.eachCell && tbl.tFoot ) + { + addHover($('td, th', tbl.tFoot), colIndex); + } + }); + }; +})(jQuery); diff --git a/js/jquery/jquery-core.js b/js/jquery/jquery-core.js new file mode 100644 index 0000000..3747929 --- /dev/null +++ b/js/jquery/jquery-core.js @@ -0,0 +1,32 @@ +/* + * jQuery 1.2.3 - New Wave Javascript + * + * Copyright (c) 2008 John Resig (jquery.com) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * $Date: 2008-02-06 00:21:25 -0500 (Wed, 06 Feb 2008) $ + * $Rev: 4663 $ + */ +(function(){if(window.jQuery)var _jQuery=window.jQuery;var jQuery=window.jQuery=function(selector,context){return new jQuery.prototype.init(selector,context);};if(window.$)var _$=window.$;window.$=jQuery;var quickExpr=/^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/;var isSimple=/^.[^:#\[\.]*$/;jQuery.fn=jQuery.prototype={init:function(selector,context){selector=selector||document;if(selector.nodeType){this[0]=selector;this.length=1;return this;}else if(typeof selector=="string"){var match=quickExpr.exec(selector);if(match&&(match[1]||!context)){if(match[1])selector=jQuery.clean([match[1]],context);else{var elem=document.getElementById(match[3]);if(elem)if(elem.id!=match[3])return jQuery().find(selector);else{this[0]=elem;this.length=1;return this;}else +selector=[];}}else +return new jQuery(context).find(selector);}else if(jQuery.isFunction(selector))return new jQuery(document)[jQuery.fn.ready?"ready":"load"](selector);return this.setArray(selector.constructor==Array&&selector||(selector.jquery||selector.length&&selector!=window&&!selector.nodeType&&selector[0]!=undefined&&selector[0].nodeType)&&jQuery.makeArray(selector)||[selector]);},jquery:"1.2.3",size:function(){return this.length;},length:0,get:function(num){return num==undefined?jQuery.makeArray(this):this[num];},pushStack:function(elems){var ret=jQuery(elems);ret.prevObject=this;return ret;},setArray:function(elems){this.length=0;Array.prototype.push.apply(this,elems);return this;},each:function(callback,args){return jQuery.each(this,callback,args);},index:function(elem){var ret=-1;this.each(function(i){if(this==elem)ret=i;});return ret;},attr:function(name,value,type){var options=name;if(name.constructor==String)if(value==undefined)return this.length&&jQuery[type||"attr"](this[0],name)||undefined;else{options={};options[name]=value;}return this.each(function(i){for(name in options)jQuery.attr(type?this.style:this,name,jQuery.prop(this,options[name],type,i,name));});},css:function(key,value){if((key=='width'||key=='height')&&parseFloat(value)<0)value=undefined;return this.attr(key,value,"curCSS");},text:function(text){if(typeof text!="object"&&text!=null)return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(text));var ret="";jQuery.each(text||this,function(){jQuery.each(this.childNodes,function(){if(this.nodeType!=8)ret+=this.nodeType!=1?this.nodeValue:jQuery.fn.text([this]);});});return ret;},wrapAll:function(html){if(this[0])jQuery(html,this[0].ownerDocument).clone().insertBefore(this[0]).map(function(){var elem=this;while(elem.firstChild)elem=elem.firstChild;return elem;}).append(this);return this;},wrapInner:function(html){return this.each(function(){jQuery(this).contents().wrapAll(html);});},wrap:function(html){return this.each(function(){jQuery(this).wrapAll(html);});},append:function(){return this.domManip(arguments,true,false,function(elem){if(this.nodeType==1)this.appendChild(elem);});},prepend:function(){return this.domManip(arguments,true,true,function(elem){if(this.nodeType==1)this.insertBefore(elem,this.firstChild);});},before:function(){return this.domManip(arguments,false,false,function(elem){this.parentNode.insertBefore(elem,this);});},after:function(){return this.domManip(arguments,false,true,function(elem){this.parentNode.insertBefore(elem,this.nextSibling);});},end:function(){return this.prevObject||jQuery([]);},find:function(selector){var elems=jQuery.map(this,function(elem){return jQuery.find(selector,elem);});return this.pushStack(/[^+>] [^+>]/.test(selector)||selector.indexOf("..")>-1?jQuery.unique(elems):elems);},clone:function(events){var ret=this.map(function(){if(jQuery.browser.msie&&!jQuery.isXMLDoc(this)){var clone=this.cloneNode(true),container=document.createElement("div");container.appendChild(clone);return jQuery.clean([container.innerHTML])[0];}else +return this.cloneNode(true);});var clone=ret.find("*").andSelf().each(function(){if(this[expando]!=undefined)this[expando]=null;});if(events===true)this.find("*").andSelf().each(function(i){if(this.nodeType==3)return;var events=jQuery.data(this,"events");for(var type in events)for(var handler in events[type])jQuery.event.add(clone[i],type,events[type][handler],events[type][handler].data);});return ret;},filter:function(selector){return this.pushStack(jQuery.isFunction(selector)&&jQuery.grep(this,function(elem,i){return selector.call(elem,i);})||jQuery.multiFilter(selector,this));},not:function(selector){if(selector.constructor==String)if(isSimple.test(selector))return this.pushStack(jQuery.multiFilter(selector,this,true));else +selector=jQuery.multiFilter(selector,this);var isArrayLike=selector.length&&selector[selector.length-1]!==undefined&&!selector.nodeType;return this.filter(function(){return isArrayLike?jQuery.inArray(this,selector)<0:this!=selector;});},add:function(selector){return!selector?this:this.pushStack(jQuery.merge(this.get(),selector.constructor==String?jQuery(selector).get():selector.length!=undefined&&(!selector.nodeName||jQuery.nodeName(selector,"form"))?selector:[selector]));},is:function(selector){return selector?jQuery.multiFilter(selector,this).length>0:false;},hasClass:function(selector){return this.is("."+selector);},val:function(value){if(value==undefined){if(this.length){var elem=this[0];if(jQuery.nodeName(elem,"select")){var index=elem.selectedIndex,values=[],options=elem.options,one=elem.type=="select-one";if(index<0)return null;for(var i=one?index:0,max=one?index+1:options.length;i=0||jQuery.inArray(this.name,value)>=0);else if(jQuery.nodeName(this,"select")){var values=value.constructor==Array?value:[value];jQuery("option",this).each(function(){this.selected=(jQuery.inArray(this.value,values)>=0||jQuery.inArray(this.text,values)>=0);});if(!values.length)this.selectedIndex=-1;}else +this.value=value;});},html:function(value){return value==undefined?(this.length?this[0].innerHTML:null):this.empty().append(value);},replaceWith:function(value){return this.after(value).remove();},eq:function(i){return this.slice(i,i+1);},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments));},map:function(callback){return this.pushStack(jQuery.map(this,function(elem,i){return callback.call(elem,i,elem);}));},andSelf:function(){return this.add(this.prevObject);},data:function(key,value){var parts=key.split(".");parts[1]=parts[1]?"."+parts[1]:"";if(value==null){var data=this.triggerHandler("getData"+parts[1]+"!",[parts[0]]);if(data==undefined&&this.length)data=jQuery.data(this[0],key);return data==null&&parts[1]?this.data(parts[0]):data;}else +return this.trigger("setData"+parts[1]+"!",[parts[0],value]).each(function(){jQuery.data(this,key,value);});},removeData:function(key){return this.each(function(){jQuery.removeData(this,key);});},domManip:function(args,table,reverse,callback){var clone=this.length>1,elems;return this.each(function(){if(!elems){elems=jQuery.clean(args,this.ownerDocument);if(reverse)elems.reverse();}var obj=this;if(table&&jQuery.nodeName(this,"table")&&jQuery.nodeName(elems[0],"tr"))obj=this.getElementsByTagName("tbody")[0]||this.appendChild(this.ownerDocument.createElement("tbody"));var scripts=jQuery([]);jQuery.each(elems,function(){var elem=clone?jQuery(this).clone(true)[0]:this;if(jQuery.nodeName(elem,"script")){scripts=scripts.add(elem);}else{if(elem.nodeType==1)scripts=scripts.add(jQuery("script",elem).remove());callback.call(obj,elem);}});scripts.each(evalScript);});}};jQuery.prototype.init.prototype=jQuery.prototype;function evalScript(i,elem){if(elem.src)jQuery.ajax({url:elem.src,async:false,dataType:"script"});else +jQuery.globalEval(elem.text||elem.textContent||elem.innerHTML||"");if(elem.parentNode)elem.parentNode.removeChild(elem);}jQuery.extend=jQuery.fn.extend=function(){var target=arguments[0]||{},i=1,length=arguments.length,deep=false,options;if(target.constructor==Boolean){deep=target;target=arguments[1]||{};i=2;}if(typeof target!="object"&&typeof target!="function")target={};if(length==1){target=this;i=0;}for(;i-1;}},swap:function(elem,options,callback){var old={};for(var name in options){old[name]=elem.style[name];elem.style[name]=options[name];}callback.call(elem);for(var name in options)elem.style[name]=old[name];},css:function(elem,name,force){if(name=="width"||name=="height"){var val,props={position:"absolute",visibility:"hidden",display:"block"},which=name=="width"?["Left","Right"]:["Top","Bottom"];function getWH(){val=name=="width"?elem.offsetWidth:elem.offsetHeight;var padding=0,border=0;jQuery.each(which,function(){padding+=parseFloat(jQuery.curCSS(elem,"padding"+this,true))||0;border+=parseFloat(jQuery.curCSS(elem,"border"+this+"Width",true))||0;});val-=Math.round(padding+border);}if(jQuery(elem).is(":visible"))getWH();else +jQuery.swap(elem,props,getWH);return Math.max(0,val);}return jQuery.curCSS(elem,name,force);},curCSS:function(elem,name,force){var ret;function color(elem){if(!jQuery.browser.safari)return false;var ret=document.defaultView.getComputedStyle(elem,null);return!ret||ret.getPropertyValue("color")=="";}if(name=="opacity"&&jQuery.browser.msie){ret=jQuery.attr(elem.style,"opacity");return ret==""?"1":ret;}if(jQuery.browser.opera&&name=="display"){var save=elem.style.outline;elem.style.outline="0 solid black";elem.style.outline=save;}if(name.match(/float/i))name=styleFloat;if(!force&&elem.style&&elem.style[name])ret=elem.style[name];else if(document.defaultView&&document.defaultView.getComputedStyle){if(name.match(/float/i))name="float";name=name.replace(/([A-Z])/g,"-$1").toLowerCase();var getComputedStyle=document.defaultView.getComputedStyle(elem,null);if(getComputedStyle&&!color(elem))ret=getComputedStyle.getPropertyValue(name);else{var swap=[],stack=[];for(var a=elem;a&&color(a);a=a.parentNode)stack.unshift(a);for(var i=0;i]*?)\/>/g,function(all,front,tag){return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?all:front+">";});var tags=jQuery.trim(elem).toLowerCase(),div=context.createElement("div");var wrap=!tags.indexOf("",""]||!tags.indexOf("",""]||tags.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"","
    "]||!tags.indexOf("",""]||(!tags.indexOf("",""]||!tags.indexOf("",""]||jQuery.browser.msie&&[1,"div
    ","
    "]||[0,"",""];div.innerHTML=wrap[1]+elem+wrap[2];while(wrap[0]--)div=div.lastChild;if(jQuery.browser.msie){var tbody=!tags.indexOf(""&&tags.indexOf("=0;--j)if(jQuery.nodeName(tbody[j],"tbody")&&!tbody[j].childNodes.length)tbody[j].parentNode.removeChild(tbody[j]);if(/^\s/.test(elem))div.insertBefore(context.createTextNode(elem.match(/^\s*/)[0]),div.firstChild);}elem=jQuery.makeArray(div.childNodes);}if(elem.length===0&&(!jQuery.nodeName(elem,"form")&&!jQuery.nodeName(elem,"select")))return;if(elem[0]==undefined||jQuery.nodeName(elem,"form")||elem.options)ret.push(elem);else +ret=jQuery.merge(ret,elem);});return ret;},attr:function(elem,name,value){if(!elem||elem.nodeType==3||elem.nodeType==8)return undefined;var fix=jQuery.isXMLDoc(elem)?{}:jQuery.props;if(name=="selected"&&jQuery.browser.safari)elem.parentNode.selectedIndex;if(fix[name]){if(value!=undefined)elem[fix[name]]=value;return elem[fix[name]];}else if(jQuery.browser.msie&&name=="style")return jQuery.attr(elem.style,"cssText",value);else if(value==undefined&&jQuery.browser.msie&&jQuery.nodeName(elem,"form")&&(name=="action"||name=="method"))return elem.getAttributeNode(name).nodeValue;else if(elem.tagName){if(value!=undefined){if(name=="type"&&jQuery.nodeName(elem,"input")&&elem.parentNode)throw"type property can't be changed";elem.setAttribute(name,""+value);}if(jQuery.browser.msie&&/href|src/.test(name)&&!jQuery.isXMLDoc(elem))return elem.getAttribute(name,2);return elem.getAttribute(name);}else{if(name=="opacity"&&jQuery.browser.msie){if(value!=undefined){elem.zoom=1;elem.filter=(elem.filter||"").replace(/alpha\([^)]*\)/,"")+(parseFloat(value).toString()=="NaN"?"":"alpha(opacity="+value*100+")");}return elem.filter&&elem.filter.indexOf("opacity=")>=0?(parseFloat(elem.filter.match(/opacity=([^)]*)/)[1])/100).toString():"";}name=name.replace(/-([a-z])/ig,function(all,letter){return letter.toUpperCase();});if(value!=undefined)elem[name]=value;return elem[name];}},trim:function(text){return(text||"").replace(/^\s+|\s+$/g,"");},makeArray:function(array){var ret=[];if(typeof array!="array")for(var i=0,length=array.length;i*",this).remove();while(this.firstChild)this.removeChild(this.firstChild);}},function(name,fn){jQuery.fn[name]=function(){return this.each(fn,arguments);};});jQuery.each(["Height","Width"],function(i,name){var type=name.toLowerCase();jQuery.fn[type]=function(size){return this[0]==window?jQuery.browser.opera&&document.body["client"+name]||jQuery.browser.safari&&window["inner"+name]||document.compatMode=="CSS1Compat"&&document.documentElement["client"+name]||document.body["client"+name]:this[0]==document?Math.max(Math.max(document.body["scroll"+name],document.documentElement["scroll"+name]),Math.max(document.body["offset"+name],document.documentElement["offset"+name])):size==undefined?(this.length?jQuery.css(this[0],type):null):this.css(type,size.constructor==String?size:size+"px");};});var chars=jQuery.browser.safari&&parseInt(jQuery.browser.version)<417?"(?:[\\w*_-]|\\\\.)":"(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",quickChild=new RegExp("^>\\s*("+chars+"+)"),quickID=new RegExp("^("+chars+"+)(#)("+chars+"+)"),quickClass=new RegExp("^([#.]?)("+chars+"*)");jQuery.extend({expr:{"":function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);},"#":function(a,i,m){return a.getAttribute("id")==m[2];},":":{lt:function(a,i,m){return im[3]-0;},nth:function(a,i,m){return m[3]-0==i;},eq:function(a,i,m){return m[3]-0==i;},first:function(a,i){return i==0;},last:function(a,i,m,r){return i==r.length-1;},even:function(a,i){return i%2==0;},odd:function(a,i){return i%2;},"first-child":function(a){return a.parentNode.getElementsByTagName("*")[0]==a;},"last-child":function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;},"only-child":function(a){return!jQuery.nth(a.parentNode.lastChild,2,"previousSibling");},parent:function(a){return a.firstChild;},empty:function(a){return!a.firstChild;},contains:function(a,i,m){return(a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;},visible:function(a){return"hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";},hidden:function(a){return"hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";},enabled:function(a){return!a.disabled;},disabled:function(a){return a.disabled;},checked:function(a){return a.checked;},selected:function(a){return a.selected||jQuery.attr(a,"selected");},text:function(a){return"text"==a.type;},radio:function(a){return"radio"==a.type;},checkbox:function(a){return"checkbox"==a.type;},file:function(a){return"file"==a.type;},password:function(a){return"password"==a.type;},submit:function(a){return"submit"==a.type;},image:function(a){return"image"==a.type;},reset:function(a){return"reset"==a.type;},button:function(a){return"button"==a.type||jQuery.nodeName(a,"button");},input:function(a){return/input|select|textarea|button/i.test(a.nodeName);},has:function(a,i,m){return jQuery.find(m[3],a).length;},header:function(a){return/h\d/i.test(a.nodeName);},animated:function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;}}},parse:[/^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,/^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,new RegExp("^([:.#]*)("+chars+"+)")],multiFilter:function(expr,elems,not){var old,cur=[];while(expr&&expr!=old){old=expr;var f=jQuery.filter(expr,elems,not);expr=f.t.replace(/^\s*,\s*/,"");cur=not?elems=f.r:jQuery.merge(cur,f.r);}return cur;},find:function(t,context){if(typeof t!="string")return[t];if(context&&context.nodeType!=1&&context.nodeType!=9)return[];context=context||document;var ret=[context],done=[],last,nodeName;while(t&&last!=t){var r=[];last=t;t=jQuery.trim(t);var foundToken=false;var re=quickChild;var m=re.exec(t);if(m){nodeName=m[1].toUpperCase();for(var i=0;ret[i];i++)for(var c=ret[i].firstChild;c;c=c.nextSibling)if(c.nodeType==1&&(nodeName=="*"||c.nodeName.toUpperCase()==nodeName))r.push(c);ret=r;t=t.replace(re,"");if(t.indexOf(" ")==0)continue;foundToken=true;}else{re=/^([>+~])\s*(\w*)/i;if((m=re.exec(t))!=null){r=[];var merge={};nodeName=m[2].toUpperCase();m=m[1];for(var j=0,rl=ret.length;j=0;if(!not&&pass||not&&!pass)tmp.push(r[i]);}return tmp;},filter:function(t,r,not){var last;while(t&&t!=last){last=t;var p=jQuery.parse,m;for(var i=0;p[i];i++){m=p[i].exec(t);if(m){t=t.substring(m[0].length);m[2]=m[2].replace(/\\/g,"");break;}}if(!m)break;if(m[1]==":"&&m[2]=="not")r=isSimple.test(m[3])?jQuery.filter(m[3],r,true).r:jQuery(r).not(m[3]);else if(m[1]==".")r=jQuery.classFilter(r,m[2],not);else if(m[1]=="["){var tmp=[],type=m[3];for(var i=0,rl=r.length;i=0)^not)tmp.push(a);}r=tmp;}else if(m[1]==":"&&m[2]=="nth-child"){var merge={},tmp=[],test=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(m[3]=="even"&&"2n"||m[3]=="odd"&&"2n+1"||!/\D/.test(m[3])&&"0n+"+m[3]||m[3]),first=(test[1]+(test[2]||1))-0,last=test[3]-0;for(var i=0,rl=r.length;i=0)add=true;if(add^not)tmp.push(node);}r=tmp;}else{var fn=jQuery.expr[m[1]];if(typeof fn=="object")fn=fn[m[2]];if(typeof fn=="string")fn=eval("false||function(a,i){return "+fn+";}");r=jQuery.grep(r,function(elem,i){return fn(elem,i,m,r);},not);}}return{r:r,t:t};},dir:function(elem,dir){var matched=[];var cur=elem[dir];while(cur&&cur!=document){if(cur.nodeType==1)matched.push(cur);cur=cur[dir];}return matched;},nth:function(cur,result,dir,elem){result=result||1;var num=0;for(;cur;cur=cur[dir])if(cur.nodeType==1&&++num==result)break;return cur;},sibling:function(n,elem){var r=[];for(;n;n=n.nextSibling){if(n.nodeType==1&&(!elem||n!=elem))r.push(n);}return r;}});jQuery.event={add:function(elem,types,handler,data){if(elem.nodeType==3||elem.nodeType==8)return;if(jQuery.browser.msie&&elem.setInterval!=undefined)elem=window;if(!handler.guid)handler.guid=this.guid++;if(data!=undefined){var fn=handler;handler=function(){return fn.apply(this,arguments);};handler.data=data;handler.guid=fn.guid;}var events=jQuery.data(elem,"events")||jQuery.data(elem,"events",{}),handle=jQuery.data(elem,"handle")||jQuery.data(elem,"handle",function(){var val;if(typeof jQuery=="undefined"||jQuery.event.triggered)return val;val=jQuery.event.handle.apply(arguments.callee.elem,arguments);return val;});handle.elem=elem;jQuery.each(types.split(/\s+/),function(index,type){var parts=type.split(".");type=parts[0];handler.type=parts[1];var handlers=events[type];if(!handlers){handlers=events[type]={};if(!jQuery.event.special[type]||jQuery.event.special[type].setup.call(elem)===false){if(elem.addEventListener)elem.addEventListener(type,handle,false);else if(elem.attachEvent)elem.attachEvent("on"+type,handle);}}handlers[handler.guid]=handler;jQuery.event.global[type]=true;});elem=null;},guid:1,global:{},remove:function(elem,types,handler){if(elem.nodeType==3||elem.nodeType==8)return;var events=jQuery.data(elem,"events"),ret,index;if(events){if(types==undefined||(typeof types=="string"&&types.charAt(0)=="."))for(var type in events)this.remove(elem,type+(types||""));else{if(types.type){handler=types.handler;types=types.type;}jQuery.each(types.split(/\s+/),function(index,type){var parts=type.split(".");type=parts[0];if(events[type]){if(handler)delete events[type][handler.guid];else +for(handler in events[type])if(!parts[1]||events[type][handler].type==parts[1])delete events[type][handler];for(ret in events[type])break;if(!ret){if(!jQuery.event.special[type]||jQuery.event.special[type].teardown.call(elem)===false){if(elem.removeEventListener)elem.removeEventListener(type,jQuery.data(elem,"handle"),false);else if(elem.detachEvent)elem.detachEvent("on"+type,jQuery.data(elem,"handle"));}ret=null;delete events[type];}}});}for(ret in events)break;if(!ret){var handle=jQuery.data(elem,"handle");if(handle)handle.elem=null;jQuery.removeData(elem,"events");jQuery.removeData(elem,"handle");}}},trigger:function(type,data,elem,donative,extra){data=jQuery.makeArray(data||[]);if(type.indexOf("!")>=0){type=type.slice(0,-1);var exclusive=true;}if(!elem){if(this.global[type])jQuery("*").add([window,document]).trigger(type,data);}else{if(elem.nodeType==3||elem.nodeType==8)return undefined;var val,ret,fn=jQuery.isFunction(elem[type]||null),event=!data[0]||!data[0].preventDefault;if(event)data.unshift(this.fix({type:type,target:elem}));data[0].type=type;if(exclusive)data[0].exclusive=true;if(jQuery.isFunction(jQuery.data(elem,"handle")))val=jQuery.data(elem,"handle").apply(elem,data);if(!fn&&elem["on"+type]&&elem["on"+type].apply(elem,data)===false)val=false;if(event)data.shift();if(extra&&jQuery.isFunction(extra)){ret=extra.apply(elem,val==null?data:data.concat(val));if(ret!==undefined)val=ret;}if(fn&&donative!==false&&val!==false&&!(jQuery.nodeName(elem,'a')&&type=="click")){this.triggered=true;try{elem[type]();}catch(e){}}this.triggered=false;}return val;},handle:function(event){var val;event=jQuery.event.fix(event||window.event||{});var parts=event.type.split(".");event.type=parts[0];var handlers=jQuery.data(this,"events")&&jQuery.data(this,"events")[event.type],args=Array.prototype.slice.call(arguments,1);args.unshift(event);for(var j in handlers){var handler=handlers[j];args[0].handler=handler;args[0].data=handler.data;if(!parts[1]&&!event.exclusive||handler.type==parts[1]){var ret=handler.apply(this,args);if(val!==false)val=ret;if(ret===false){event.preventDefault();event.stopPropagation();}}}if(jQuery.browser.msie)event.target=event.preventDefault=event.stopPropagation=event.handler=event.data=null;return val;},fix:function(event){var originalEvent=event;event=jQuery.extend({},originalEvent);event.preventDefault=function(){if(originalEvent.preventDefault)originalEvent.preventDefault();originalEvent.returnValue=false;};event.stopPropagation=function(){if(originalEvent.stopPropagation)originalEvent.stopPropagation();originalEvent.cancelBubble=true;};if(!event.target)event.target=event.srcElement||document;if(event.target.nodeType==3)event.target=originalEvent.target.parentNode;if(!event.relatedTarget&&event.fromElement)event.relatedTarget=event.fromElement==event.target?event.toElement:event.fromElement;if(event.pageX==null&&event.clientX!=null){var doc=document.documentElement,body=document.body;event.pageX=event.clientX+(doc&&doc.scrollLeft||body&&body.scrollLeft||0)-(doc.clientLeft||0);event.pageY=event.clientY+(doc&&doc.scrollTop||body&&body.scrollTop||0)-(doc.clientTop||0);}if(!event.which&&((event.charCode||event.charCode===0)?event.charCode:event.keyCode))event.which=event.charCode||event.keyCode;if(!event.metaKey&&event.ctrlKey)event.metaKey=event.ctrlKey;if(!event.which&&event.button)event.which=(event.button&1?1:(event.button&2?3:(event.button&4?2:0)));return event;},special:{ready:{setup:function(){bindReady();return;},teardown:function(){return;}},mouseenter:{setup:function(){if(jQuery.browser.msie)return false;jQuery(this).bind("mouseover",jQuery.event.special.mouseenter.handler);return true;},teardown:function(){if(jQuery.browser.msie)return false;jQuery(this).unbind("mouseover",jQuery.event.special.mouseenter.handler);return true;},handler:function(event){if(withinElement(event,this))return true;arguments[0].type="mouseenter";return jQuery.event.handle.apply(this,arguments);}},mouseleave:{setup:function(){if(jQuery.browser.msie)return false;jQuery(this).bind("mouseout",jQuery.event.special.mouseleave.handler);return true;},teardown:function(){if(jQuery.browser.msie)return false;jQuery(this).unbind("mouseout",jQuery.event.special.mouseleave.handler);return true;},handler:function(event){if(withinElement(event,this))return true;arguments[0].type="mouseleave";return jQuery.event.handle.apply(this,arguments);}}}};jQuery.fn.extend({bind:function(type,data,fn){return type=="unload"?this.one(type,data,fn):this.each(function(){jQuery.event.add(this,type,fn||data,fn&&data);});},one:function(type,data,fn){return this.each(function(){jQuery.event.add(this,type,function(event){jQuery(this).unbind(event);return(fn||data).apply(this,arguments);},fn&&data);});},unbind:function(type,fn){return this.each(function(){jQuery.event.remove(this,type,fn);});},trigger:function(type,data,fn){return this.each(function(){jQuery.event.trigger(type,data,this,true,fn);});},triggerHandler:function(type,data,fn){if(this[0])return jQuery.event.trigger(type,data,this[0],false,fn);return undefined;},toggle:function(){var args=arguments;return this.click(function(event){this.lastToggle=0==this.lastToggle?1:0;event.preventDefault();return args[this.lastToggle].apply(this,arguments)||false;});},hover:function(fnOver,fnOut){return this.bind('mouseenter',fnOver).bind('mouseleave',fnOut);},ready:function(fn){bindReady();if(jQuery.isReady)fn.call(document,jQuery);else +jQuery.readyList.push(function(){return fn.call(this,jQuery);});return this;}});jQuery.extend({isReady:false,readyList:[],ready:function(){if(!jQuery.isReady){jQuery.isReady=true;if(jQuery.readyList){jQuery.each(jQuery.readyList,function(){this.apply(document);});jQuery.readyList=null;}jQuery(document).triggerHandler("ready");}}});var readyBound=false;function bindReady(){if(readyBound)return;readyBound=true;if(document.addEventListener&&!jQuery.browser.opera)document.addEventListener("DOMContentLoaded",jQuery.ready,false);if(jQuery.browser.msie&&window==top)(function(){if(jQuery.isReady)return;try{document.documentElement.doScroll("left");}catch(error){setTimeout(arguments.callee,0);return;}jQuery.ready();})();if(jQuery.browser.opera)document.addEventListener("DOMContentLoaded",function(){if(jQuery.isReady)return;for(var i=0;i=0){var selector=url.slice(off,url.length);url=url.slice(0,off);}callback=callback||function(){};var type="GET";if(params)if(jQuery.isFunction(params)){callback=params;params=null;}else{params=jQuery.param(params);type="POST";}var self=this;jQuery.ajax({url:url,type:type,dataType:"html",data:params,complete:function(res,status){if(status=="success"||status=="notmodified")self.html(selector?jQuery("
    ").append(res.responseText.replace(//g,"")).find(selector):res.responseText);self.each(callback,[res.responseText,status,res]);}});return this;},serialize:function(){return jQuery.param(this.serializeArray());},serializeArray:function(){return this.map(function(){return jQuery.nodeName(this,"form")?jQuery.makeArray(this.elements):this;}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password/i.test(this.type));}).map(function(i,elem){var val=jQuery(this).val();return val==null?null:val.constructor==Array?jQuery.map(val,function(val,i){return{name:elem.name,value:val};}):{name:elem.name,value:val};}).get();}});jQuery.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(i,o){jQuery.fn[o]=function(f){return this.bind(o,f);};});var jsc=(new Date).getTime();jQuery.extend({get:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data=null;}return jQuery.ajax({type:"GET",url:url,data:data,success:callback,dataType:type});},getScript:function(url,callback){return jQuery.get(url,null,callback,"script");},getJSON:function(url,data,callback){return jQuery.get(url,data,callback,"json");},post:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data={};}return jQuery.ajax({type:"POST",url:url,data:data,success:callback,dataType:type});},ajaxSetup:function(settings){jQuery.extend(jQuery.ajaxSettings,settings);},ajaxSettings:{global:true,type:"GET",timeout:0,contentType:"application/x-www-form-urlencoded",processData:true,async:true,data:null,username:null,password:null,accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(s){var jsonp,jsre=/=\?(&|$)/g,status,data;s=jQuery.extend(true,s,jQuery.extend(true,{},jQuery.ajaxSettings,s));if(s.data&&s.processData&&typeof s.data!="string")s.data=jQuery.param(s.data);if(s.dataType=="jsonp"){if(s.type.toLowerCase()=="get"){if(!s.url.match(jsre))s.url+=(s.url.match(/\?/)?"&":"?")+(s.jsonp||"callback")+"=?";}else if(!s.data||!s.data.match(jsre))s.data=(s.data?s.data+"&":"")+(s.jsonp||"callback")+"=?";s.dataType="json";}if(s.dataType=="json"&&(s.data&&s.data.match(jsre)||s.url.match(jsre))){jsonp="jsonp"+jsc++;if(s.data)s.data=(s.data+"").replace(jsre,"="+jsonp+"$1");s.url=s.url.replace(jsre,"="+jsonp+"$1");s.dataType="script";window[jsonp]=function(tmp){data=tmp;success();complete();window[jsonp]=undefined;try{delete window[jsonp];}catch(e){}if(head)head.removeChild(script);};}if(s.dataType=="script"&&s.cache==null)s.cache=false;if(s.cache===false&&s.type.toLowerCase()=="get"){var ts=(new Date()).getTime();var ret=s.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+ts+"$2");s.url=ret+((ret==s.url)?(s.url.match(/\?/)?"&":"?")+"_="+ts:"");}if(s.data&&s.type.toLowerCase()=="get"){s.url+=(s.url.match(/\?/)?"&":"?")+s.data;s.data=null;}if(s.global&&!jQuery.active++)jQuery.event.trigger("ajaxStart");if((!s.url.indexOf("http")||!s.url.indexOf("//"))&&s.dataType=="script"&&s.type.toLowerCase()=="get"){var head=document.getElementsByTagName("head")[0];var script=document.createElement("script");script.src=s.url;if(s.scriptCharset)script.charset=s.scriptCharset;if(!jsonp){var done=false;script.onload=script.onreadystatechange=function(){if(!done&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){done=true;success();complete();head.removeChild(script);}};}head.appendChild(script);return undefined;}var requestDone=false;var xml=window.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest();xml.open(s.type,s.url,s.async,s.username,s.password);try{if(s.data)xml.setRequestHeader("Content-Type",s.contentType);if(s.ifModified)xml.setRequestHeader("If-Modified-Since",jQuery.lastModified[s.url]||"Thu, 01 Jan 1970 00:00:00 GMT");xml.setRequestHeader("X-Requested-With","XMLHttpRequest");xml.setRequestHeader("Accept",s.dataType&&s.accepts[s.dataType]?s.accepts[s.dataType]+", */*":s.accepts._default);}catch(e){}if(s.beforeSend)s.beforeSend(xml);if(s.global)jQuery.event.trigger("ajaxSend",[xml,s]);var onreadystatechange=function(isTimeout){if(!requestDone&&xml&&(xml.readyState==4||isTimeout=="timeout")){requestDone=true;if(ival){clearInterval(ival);ival=null;}status=isTimeout=="timeout"&&"timeout"||!jQuery.httpSuccess(xml)&&"error"||s.ifModified&&jQuery.httpNotModified(xml,s.url)&&"notmodified"||"success";if(status=="success"){try{data=jQuery.httpData(xml,s.dataType);}catch(e){status="parsererror";}}if(status=="success"){var modRes;try{modRes=xml.getResponseHeader("Last-Modified");}catch(e){}if(s.ifModified&&modRes)jQuery.lastModified[s.url]=modRes;if(!jsonp)success();}else +jQuery.handleError(s,xml,status);complete();if(s.async)xml=null;}};if(s.async){var ival=setInterval(onreadystatechange,13);if(s.timeout>0)setTimeout(function(){if(xml){xml.abort();if(!requestDone)onreadystatechange("timeout");}},s.timeout);}try{xml.send(s.data);}catch(e){jQuery.handleError(s,xml,null,e);}if(!s.async)onreadystatechange();function success(){if(s.success)s.success(data,status);if(s.global)jQuery.event.trigger("ajaxSuccess",[xml,s]);}function complete(){if(s.complete)s.complete(xml,status);if(s.global)jQuery.event.trigger("ajaxComplete",[xml,s]);if(s.global&&!--jQuery.active)jQuery.event.trigger("ajaxStop");}return xml;},handleError:function(s,xml,status,e){if(s.error)s.error(xml,status,e);if(s.global)jQuery.event.trigger("ajaxError",[xml,s,e]);},active:0,httpSuccess:function(r){try{return!r.status&&location.protocol=="file:"||(r.status>=200&&r.status<300)||r.status==304||r.status==1223||jQuery.browser.safari&&r.status==undefined;}catch(e){}return false;},httpNotModified:function(xml,url){try{var xmlRes=xml.getResponseHeader("Last-Modified");return xml.status==304||xmlRes==jQuery.lastModified[url]||jQuery.browser.safari&&xml.status==undefined;}catch(e){}return false;},httpData:function(r,type){var ct=r.getResponseHeader("content-type");var xml=type=="xml"||!type&&ct&&ct.indexOf("xml")>=0;var data=xml?r.responseXML:r.responseText;if(xml&&data.documentElement.tagName=="parsererror")throw"parsererror";if(type=="script")jQuery.globalEval(data);if(type=="json")data=eval("("+data+")");return data;},param:function(a){var s=[];if(a.constructor==Array||a.jquery)jQuery.each(a,function(){s.push(encodeURIComponent(this.name)+"="+encodeURIComponent(this.value));});else +for(var j in a)if(a[j]&&a[j].constructor==Array)jQuery.each(a[j],function(){s.push(encodeURIComponent(j)+"="+encodeURIComponent(this));});else +s.push(encodeURIComponent(j)+"="+encodeURIComponent(a[j]));return s.join("&").replace(/%20/g,"+");}});jQuery.fn.extend({show:function(speed,callback){return speed?this.animate({height:"show",width:"show",opacity:"show"},speed,callback):this.filter(":hidden").each(function(){this.style.display=this.oldblock||"";if(jQuery.css(this,"display")=="none"){var elem=jQuery("<"+this.tagName+" />").appendTo("body");this.style.display=elem.css("display");if(this.style.display=="none")this.style.display="block";elem.remove();}}).end();},hide:function(speed,callback){return speed?this.animate({height:"hide",width:"hide",opacity:"hide"},speed,callback):this.filter(":visible").each(function(){this.oldblock=this.oldblock||jQuery.css(this,"display");this.style.display="none";}).end();},_toggle:jQuery.fn.toggle,toggle:function(fn,fn2){return jQuery.isFunction(fn)&&jQuery.isFunction(fn2)?this._toggle(fn,fn2):fn?this.animate({height:"toggle",width:"toggle",opacity:"toggle"},fn,fn2):this.each(function(){jQuery(this)[jQuery(this).is(":hidden")?"show":"hide"]();});},slideDown:function(speed,callback){return this.animate({height:"show"},speed,callback);},slideUp:function(speed,callback){return this.animate({height:"hide"},speed,callback);},slideToggle:function(speed,callback){return this.animate({height:"toggle"},speed,callback);},fadeIn:function(speed,callback){return this.animate({opacity:"show"},speed,callback);},fadeOut:function(speed,callback){return this.animate({opacity:"hide"},speed,callback);},fadeTo:function(speed,to,callback){return this.animate({opacity:to},speed,callback);},animate:function(prop,speed,easing,callback){var optall=jQuery.speed(speed,easing,callback);return this[optall.queue===false?"each":"queue"](function(){if(this.nodeType!=1)return false;var opt=jQuery.extend({},optall);var hidden=jQuery(this).is(":hidden"),self=this;for(var p in prop){if(prop[p]=="hide"&&hidden||prop[p]=="show"&&!hidden)return jQuery.isFunction(opt.complete)&&opt.complete.apply(this);if(p=="height"||p=="width"){opt.display=jQuery.css(this,"display");opt.overflow=this.style.overflow;}}if(opt.overflow!=null)this.style.overflow="hidden";opt.curAnim=jQuery.extend({},prop);jQuery.each(prop,function(name,val){var e=new jQuery.fx(self,opt,name);if(/toggle|show|hide/.test(val))e[val=="toggle"?hidden?"show":"hide":val](prop);else{var parts=val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),start=e.cur(true)||0;if(parts){var end=parseFloat(parts[2]),unit=parts[3]||"px";if(unit!="px"){self.style[name]=(end||1)+unit;start=((end||1)/e.cur(true))*start;self.style[name]=start+unit;}if(parts[1])end=((parts[1]=="-="?-1:1)*end)+start;e.custom(start,end,unit);}else +e.custom(start,val,"");}});return true;});},queue:function(type,fn){if(jQuery.isFunction(type)||(type&&type.constructor==Array)){fn=type;type="fx";}if(!type||(typeof type=="string"&&!fn))return queue(this[0],type);return this.each(function(){if(fn.constructor==Array)queue(this,type,fn);else{queue(this,type).push(fn);if(queue(this,type).length==1)fn.apply(this);}});},stop:function(clearQueue,gotoEnd){var timers=jQuery.timers;if(clearQueue)this.queue([]);this.each(function(){for(var i=timers.length-1;i>=0;i--)if(timers[i].elem==this){if(gotoEnd)timers[i](true);timers.splice(i,1);}});if(!gotoEnd)this.dequeue();return this;}});var queue=function(elem,type,array){if(!elem)return undefined;type=type||"fx";var q=jQuery.data(elem,type+"queue");if(!q||array)q=jQuery.data(elem,type+"queue",array?jQuery.makeArray(array):[]);return q;};jQuery.fn.dequeue=function(type){type=type||"fx";return this.each(function(){var q=queue(this,type);q.shift();if(q.length)q[0].apply(this);});};jQuery.extend({speed:function(speed,easing,fn){var opt=speed&&speed.constructor==Object?speed:{complete:fn||!fn&&easing||jQuery.isFunction(speed)&&speed,duration:speed,easing:fn&&easing||easing&&easing.constructor!=Function&&easing};opt.duration=(opt.duration&&opt.duration.constructor==Number?opt.duration:{slow:600,fast:200}[opt.duration])||400;opt.old=opt.complete;opt.complete=function(){if(opt.queue!==false)jQuery(this).dequeue();if(jQuery.isFunction(opt.old))opt.old.apply(this);};return opt;},easing:{linear:function(p,n,firstNum,diff){return firstNum+diff*p;},swing:function(p,n,firstNum,diff){return((-Math.cos(p*Math.PI)/2)+0.5)*diff+firstNum;}},timers:[],timerId:null,fx:function(elem,options,prop){this.options=options;this.elem=elem;this.prop=prop;if(!options.orig)options.orig={};}});jQuery.fx.prototype={update:function(){if(this.options.step)this.options.step.apply(this.elem,[this.now,this]);(jQuery.fx.step[this.prop]||jQuery.fx.step._default)(this);if(this.prop=="height"||this.prop=="width")this.elem.style.display="block";},cur:function(force){if(this.elem[this.prop]!=null&&this.elem.style[this.prop]==null)return this.elem[this.prop];var r=parseFloat(jQuery.css(this.elem,this.prop,force));return r&&r>-10000?r:parseFloat(jQuery.curCSS(this.elem,this.prop))||0;},custom:function(from,to,unit){this.startTime=(new Date()).getTime();this.start=from;this.end=to;this.unit=unit||this.unit||"px";this.now=this.start;this.pos=this.state=0;this.update();var self=this;function t(gotoEnd){return self.step(gotoEnd);}t.elem=this.elem;jQuery.timers.push(t);if(jQuery.timerId==null){jQuery.timerId=setInterval(function(){var timers=jQuery.timers;for(var i=0;ithis.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var done=true;for(var i in this.options.curAnim)if(this.options.curAnim[i]!==true)done=false;if(done){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(jQuery.css(this.elem,"display")=="none")this.elem.style.display="block";}if(this.options.hide)this.elem.style.display="none";if(this.options.hide||this.options.show)for(var p in this.options.curAnim)jQuery.attr(this.elem.style,p,this.options.orig[p]);}if(done&&jQuery.isFunction(this.options.complete))this.options.complete.apply(this.elem);return false;}else{var n=t-this.startTime;this.state=n/this.options.duration;this.pos=jQuery.easing[this.options.easing||(jQuery.easing.swing?"swing":"linear")](this.state,n,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update();}return true;}};jQuery.fx.step={scrollLeft:function(fx){fx.elem.scrollLeft=fx.now;},scrollTop:function(fx){fx.elem.scrollTop=fx.now;},opacity:function(fx){jQuery.attr(fx.elem.style,"opacity",fx.now);},_default:function(fx){fx.elem.style[fx.prop]=fx.now+fx.unit;}};jQuery.fn.offset=function(){var left=0,top=0,elem=this[0],results;if(elem)with(jQuery.browser){var parent=elem.parentNode,offsetChild=elem,offsetParent=elem.offsetParent,doc=elem.ownerDocument,safari2=safari&&parseInt(version)<522&&!/adobeair/i.test(userAgent),fixed=jQuery.css(elem,"position")=="fixed";if(elem.getBoundingClientRect){var box=elem.getBoundingClientRect();add(box.left+Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),box.top+Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));add(-doc.documentElement.clientLeft,-doc.documentElement.clientTop);}else{add(elem.offsetLeft,elem.offsetTop);while(offsetParent){add(offsetParent.offsetLeft,offsetParent.offsetTop);if(mozilla&&!/^t(able|d|h)$/i.test(offsetParent.tagName)||safari&&!safari2)border(offsetParent);if(!fixed&&jQuery.css(offsetParent,"position")=="fixed")fixed=true;offsetChild=/^body$/i.test(offsetParent.tagName)?offsetChild:offsetParent;offsetParent=offsetParent.offsetParent;}while(parent&&parent.tagName&&!/^body|html$/i.test(parent.tagName)){if(!/^inline|table.*$/i.test(jQuery.css(parent,"display")))add(-parent.scrollLeft,-parent.scrollTop);if(mozilla&&jQuery.css(parent,"overflow")!="visible")border(parent);parent=parent.parentNode;}if((safari2&&(fixed||jQuery.css(offsetChild,"position")=="absolute"))||(mozilla&&jQuery.css(offsetChild,"position")!="absolute"))add(-doc.body.offsetLeft,-doc.body.offsetTop);if(fixed)add(Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));}results={top:top,left:left};}function border(elem){add(jQuery.curCSS(elem,"borderLeftWidth",true),jQuery.curCSS(elem,"borderTopWidth",true));}function add(l,t){left+=parseInt(l)||0;top+=parseInt(t)||0;}return results;};})(); \ No newline at end of file diff --git a/js/jquery/jquery-simplemodal.js b/js/jquery/jquery-simplemodal.js new file mode 100644 index 0000000..84f4dd0 --- /dev/null +++ b/js/jquery/jquery-simplemodal.js @@ -0,0 +1,16 @@ +/* + * SimpleModal 1.1.1 - jQuery Plugin + * http://www.ericmmartin.com/projects/simplemodal/ + * http://plugins.jquery.com/project/SimpleModal + * http://code.google.com/p/simplemodal/ + * + * Copyright (c) 2007 Eric Martin - http://ericmmartin.com + * + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * Revision: $Id: jquery.simplemodal.js 93 2008-01-15 16:14:20Z emartin24 $ + * + */ +(function($){$.modal=function(data,options){return $.modal.impl.init(data,options);};$.modal.close=function(){$.modal.impl.close(true);};$.fn.modal=function(options){return $.modal.impl.init(this,options);};$.modal.defaults={overlay:50,overlayId:'modalOverlay',overlayCss:{},containerId:'modalContainer',containerCss:{},close:true,closeTitle:'Close',closeClass:'modalClose',persist:false,onOpen:null,onShow:null,onClose:null};$.modal.impl={opts:null,dialog:{},init:function(data,options){if(this.dialog.data){return false;}this.opts=$.extend({},$.modal.defaults,options);if(typeof data=='object'){data=data instanceof jQuery?data:$(data);if(data.parent().parent().size()>0){this.dialog.parentNode=data.parent();if(!this.opts.persist){this.dialog.original=data.clone(true);}}}else if(typeof data=='string'||typeof data=='number'){data=$('
    ').html(data);}else{if(console){console.log('SimpleModal Error: Unsupported data type: '+typeof data);}return false;}this.dialog.data=data.addClass('modalData');data=null;this.create();this.open();if($.isFunction(this.opts.onShow)){this.opts.onShow.apply(this,[this.dialog]);}return this;},create:function(){this.dialog.overlay=$('
    ').attr('id',this.opts.overlayId).addClass('modalOverlay').css($.extend(this.opts.overlayCss,{opacity:this.opts.overlay/100,height:'100%',width:'100%',position:'fixed',left:0,top:0,zIndex:3000})).hide().appendTo('body');this.dialog.container=$('
    ').attr('id',this.opts.containerId).addClass('modalContainer').css($.extend(this.opts.containerCss,{position:'fixed',zIndex:3100})).append(this.opts.close?'':'').hide().appendTo('body');if($.browser.msie&&($.browser.version<7)){this.fixIE();}this.dialog.container.append(this.dialog.data.hide());},bindEvents:function(){var modal=this;$('.'+this.opts.closeClass).click(function(e){e.preventDefault();modal.close();});},unbindEvents:function(){$('.'+this.opts.closeClass).unbind('click');},fixIE:function(){var wHeight=$(document.body).height()+'px';var wWidth=$(document.body).width()+'px';this.dialog.overlay.css({position:'absolute',height:wHeight,width:wWidth});this.dialog.container.css({position:'absolute'});this.dialog.iframe=$('
    + + + '; +} + + + + +/** + * A ReCaptchaResponse is returned from recaptcha_check_answer() + */ +class ReCaptchaResponse { + var $is_valid; + var $error; +} + + +/** + * Calls an HTTP POST function to verify if the user's guess was correct + * @param string $privkey + * @param string $remoteip + * @param string $challenge + * @param string $response + * @return ReCaptchaResponse + */ +function recaptcha_check_answer ($privkey, $remoteip, $challenge, $response) +{ + if ($privkey == null || $privkey == '') { + die ("To use reCAPTCHA you must get an API key from http://recaptcha.net/api/getkey"); + } + + if ($remoteip == null || $remoteip == '') { + die ("For security reasons, you must pass the remote ip to reCAPTCHA"); + } + + + + //discard spam submissions + if ($challenge == null || strlen($challenge) == 0 || $response == null || strlen($response) == 0) { + $recaptcha_response = new ReCaptchaResponse(); + $recaptcha_response->is_valid = false; + $recaptcha_response->error = 'incorrect-captcha-sol'; + return $recaptcha_response; + } + + $response = _recaptcha_http_post (RECAPTCHA_VERIFY_SERVER, "/verify", + array ( + 'privatekey' => $privkey, + 'remoteip' => $remoteip, + 'challenge' => $challenge, + 'response' => $response + ) + ); + + if($response === false){ + return false; + } + + $answers = explode ("\n", $response [1]); + $recaptcha_response = new ReCaptchaResponse(); + + if (trim ($answers [0]) == 'true') { + $recaptcha_response->is_valid = true; + } + else { + $recaptcha_response->is_valid = false; + $recaptcha_response->error = $answers [1]; + } + return $recaptcha_response; + +} + +/** + * gets a URL where the user can sign up for reCAPTCHA. If your application + * has a configuration page where you enter a key, you should provide a link + * using this function. + * @param string $domain The domain where the page is hosted + * @param string $appname The name of your application + */ +function recaptcha_get_signup_url ($domain = null, $appname = null) { + return "http://recaptcha.net/api/getkey?" . _recaptcha_qsencode (array ('domain' => $domain, 'app' => $appname)); +} + +function _recaptcha_aes_pad($val) { + $block_size = 16; + $numpad = $block_size - (strlen ($val) % $block_size); + return str_pad($val, strlen ($val) + $numpad, chr($numpad)); +} + +/* Mailhide related code */ + +function _recaptcha_aes_encrypt($val,$ky) { + if (! function_exists ("mcrypt_encrypt")) { + die ("To use reCAPTCHA Mailhide, you need to have the mcrypt php module installed."); + } + $mode=MCRYPT_MODE_CBC; + $enc=MCRYPT_RIJNDAEL_128; + $val=_recaptcha_aes_pad($val); + return mcrypt_encrypt($enc, $ky, $val, $mode, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"); +} + + +function _recaptcha_mailhide_urlbase64 ($x) { + return strtr(base64_encode ($x), '+/', '-_'); +} + +/* gets the reCAPTCHA Mailhide url for a given email, public key and private key */ +function recaptcha_mailhide_url($pubkey, $privkey, $email) { + if ($pubkey == '' || $pubkey == null || $privkey == "" || $privkey == null) { + die ("To use reCAPTCHA Mailhide, you have to sign up for a public and private key, " . + "you can do so at http://mailhide.recaptcha.net/apikey"); + } + + + $ky = pack('H*', $privkey); + $cryptmail = _recaptcha_aes_encrypt ($email, $ky); + + return "http://mailhide.recaptcha.net/d?k=" . $pubkey . "&c=" . _recaptcha_mailhide_urlbase64 ($cryptmail); +} + +/** + * gets the parts of the email to expose to the user. + * eg, given johndoe@example,com return ["john", "example.com"]. + * the email is then displayed as john...@example.com + */ +function _recaptcha_mailhide_email_parts ($email) { + $arr = preg_split("/@/", $email ); + + if (strlen ($arr[0]) <= 4) { + $arr[0] = substr ($arr[0], 0, 1); + } else if (strlen ($arr[0]) <= 6) { + $arr[0] = substr ($arr[0], 0, 3); + } else { + $arr[0] = substr ($arr[0], 0, 4); + } + return $arr; +} + +/** + * Gets html to display an email address given a public an private key. + * to get a key, go to: + * + * http://mailhide.recaptcha.net/apikey + */ +function recaptcha_mailhide_html($pubkey, $privkey, $email) { + $emailparts = _recaptcha_mailhide_email_parts ($email); + $url = recaptcha_mailhide_url ($pubkey, $privkey, $email); + + return htmlentities($emailparts[0]) . "...@" . htmlentities ($emailparts [1]); + +} + + +?> diff --git a/license.txt b/license.txt new file mode 100644 index 0000000..d212ee2 --- /dev/null +++ b/license.txt @@ -0,0 +1 @@ +APPNITRO SOFTWARE LICENSE TERMS AND CONDITIONS This End User License Agreement (the "Agreement") is a binding legal agreement between you and Appnitro Software (the "Author"). By installing or using MachForm (the "Software"), you agree to be bound by the terms of this Agreement. If you do not agree to the Agreement, do not download, install, or use the Software. Installation or use of the Software signifies that you have read, understood, and agreed to be bound by the Agreement. The Author reserves the right to alter this agreement at any time, for any reason, without notice. Usage This Agreement grants a non-exclusive, non-transferable license to install and use the Software on a single Website. Additional Software licenses must be purchased in order to install and use the Software on additional Websites. The Author reserves the right to determine whether use of the Software qualifies under this Agreement. The Author owns all rights, title and interest to the Software (including all intellectual property rights) and reserves all rights to the Software that are not expressly granted in this Agreement. Backups You may make copies of the Software in any machine readable form solely for back-up purposes, provided that you reproduce the Software in its original form and with all proprietary notices on the back-up copy. All rights to the Software not expressly granted herein are reserved by the Author. Restrictions You understand and agree that you shall only use the Software in a manner that complies with any and all applicable laws in the jurisdictions in which you use the Software. Your use shall be in accordance with applicable restrictions concerning privacy and intellectual property rights. You may not: * Use the Software to provide services to others; such as the basis of a hosted form-building service, or any other services which is a direct competition against The Author; * Distribute derivative works based on the Software; * Reproduce the Software except as described in this Agreement; * Sell, assign, license, disclose, distribute, or otherwise transfer or make available the Software or its Source Code, in whole or in part, in any form to any third parties; * Remove or alter any copyright notices on the Software; * Use the Software in any site which endorse unlawful manner or for any unlawful purpose (such as Pornography & Adult Content site, Gambling Transactions or Sports Gambling Prognostication, etc). Support If you purchased a support contract, The Author will respond to your requests for technical support during the term of your support contract. To reach customer support services, please contact Appnitro Software by e-mail at customer.service@appnitro.com. A valid Customer ID is required for support. We generally respond to e-mails within one business day. Support contracts run from year to year. You may purchase a support contract only for a full one-year term.We reserve the right to increase the price of our support contracts from year to year. You acknowledge that the Software is inherently complex, that not all errors will be identifiable or be corrected and that the time it might take to correct errors may not be commercially reasonable. The Author provides support on a "best efforts" basis only and does not represent or warrant that it will be able to resolve every technical support request. THE SOFTWARE IS OFFERED ON AN "AS-IS" BASIS AND NO WARRANTY, EITHER EXPRESSED OR IMPLIED, IS GIVEN. THE AUTHOR EXPRESSLY DISCLAIMS ALL WARRANTIES OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. YOU ASSUME ALL RISK ASSOCIATED WITH THE QUALITY, PERFORMANCE, INSTALLATION AND USE OF THE SOFTWARE INCLUDING, BUT NOT LIMITED TO, THE RISKS OF PROGRAM ERRORS, DAMAGE TO EQUIPMENT, LOSS OF DATA OR SOFTWARE PROGRAMS, OR UNAVAILABILITY OR INTERRUPTION OF OPERATIONS. YOU ARE SOLELY RESPONSIBLE FOR DETERMINING THE APPROPRIATENESS OF USE THE SOFTWARE AND ASSUME ALL RISKS ASSOCIATED WITH ITS USE. Term, Termination, and Modification. You may use the Software under this Agreement until either party terminates this Agreement as set forth in this paragraph. Either party may terminate the Agreement at any time, upon written notice to the other party. Upon termination, all licenses granted to you will terminate, and you will immediately uninstall and cease all use of the Software. The Sections entitled "No Warranty," "Indemnification," and "Limitation of Liability" will survive any termination of this Agreement. The Author may modify the Software with notice to you either in email or by publishing content on the Software website, including but not limited to changing the functionality or appearance of the Software, and such modification will become binding on you unless you terminate this Agreement. The Software source code may be altered (at your own risk). However, modifying your source code may void the technical support portion of your support contract Indemnification. By accepting the Agreement, you agree to indemnify and otherwise hold harmless the Author, its officers, employers, agents, subsidiaries, affiliates and other partners from any direct, indirect, incidental, special, consequential or exemplary damages arising out of, relating to, or resulting from your use of the Software or any other matter relating to the Software. Limitation of Liability. YOU EXPRESSLY UNDERSTAND AND AGREE THAT THE AUTHOR SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL OR EXEMPLARY DAMAGES, INCLUDING BUT NOT LIMITED TO, DAMAGES FOR LOSS OF PROFITS, GOODWILL, USE, DATA OR OTHER INTANGIBLE LOSSES (EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES). SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF THE LIMITATION OR EXCLUSION OF LIABILITY FOR INCIDENTAL OR CONSEQUENTIAL DAMAGES. ACCORDINGLY, SOME OF THE ABOVE LIMITATIONS MAY NOT APPLY TO YOU. IN NO EVENT WILL THE AUTHORS'S TOTAL CUMULATIVE DAMAGES EXCEED THE FEES YOU PAID TO THE AUTHOR UNDER THIS AGREEMENT IN THE MOST RECENT TWELVE-MONTH PERIOD. Definitions Definition of Website A "Website" is defined as a single domain including sub-domains that operate as a single entity. What constitutes a single entity shall be at the sole discretion of the Author. Definition of Source Code The "Source Code" is defined as the contents of all HTML, CSS, JavaScript, and PHP files provided with the Software and includes all related image files and database schemas. FURTHER INFORMATION For further Information about Appnitro Software's licensing policies or products, contact Appnitro Software at: E-mail: customer.service@appnitro.com Web: http://www.appnitro.com \ No newline at end of file diff --git a/logout.php b/logout.php new file mode 100644 index 0000000..dfacaea --- /dev/null +++ b/logout.php @@ -0,0 +1,25 @@ + \ No newline at end of file diff --git a/machform.php b/machform.php new file mode 100644 index 0000000..9850115 --- /dev/null +++ b/machform.php @@ -0,0 +1,242 @@ +top.location = '{$_SERVER['REQUEST_URI']}?done=1'"; + }else{ + header("Location: {$_SERVER['REQUEST_URI']}?done=1"); + } + exit; + }else{ + if($use_javascript_redirect){ + echo ""; + }else{ + header("Location: {$_SERVER['REQUEST_URI']}&done=1"); + } + exit; + } + }else{ + + if($use_javascript_redirect){ + echo ""; + }else{ + header("Location: {$submit_result['form_redirect']}"); + } + exit; + } + }else{ + $old_values = $submit_result['old_values']; + $custom_error = $submit_result['custom_error']; + $error_elements = $submit_result['error_elements']; + + $markup = display_integrated_form($input_array['form_id'],$old_values,$error_elements,$custom_error,0,$machform_path); + } + }else{ //if password form submitted + if($submit_result['status'] === true){ //on success, display the form + $markup = display_integrated_form($input_array['form_id'],null,null,'',0,$machform_path); + }else{ + $custom_error = $submit_result['custom_error']; //error, display the pasword form again + $markup = display_integrated_form($input_array['form_id'],null,null,$custom_error,0,$machform_path); + } + } + }elseif(!empty($_POST['submit_continue'])){ //if form with continue (review) button submitted + unset($_POST['submit_continue']); + + $input_array = ap_sanitize_input($_POST); + + $input_array['machform_data_path'] = $machform_data_path; + $submit_result = process_form($input_array); + + + if($submit_result['status'] === true){ + + if(empty($submit_result['review_id'])){ + if(empty($submit_result['form_redirect'])){ + + if(strpos($_SERVER['REQUEST_URI'],'?') === false){ + if($use_javascript_redirect){ + echo ""; + }else{ + header("Location: {$_SERVER['REQUEST_URI']}?done=1"); + } + exit; + }else{ + if($use_javascript_redirect){ + echo ""; + }else{ + header("Location: {$_SERVER['REQUEST_URI']}&done=1"); + } + exit; + } + + }else{ + + if($use_javascript_redirect){ + echo ""; + }else{ + header("Location: {$submit_result['form_redirect']}"); + } + exit; + } + }else{ //redirect to review page + + $_SESSION['review_id'] = $submit_result['review_id']; + + if(strpos($_SERVER['REQUEST_URI'],'?') === false){ + if($use_javascript_redirect){ + echo ""; + }else{ + header("Location: {$_SERVER['REQUEST_URI']}?show_review=1"); + } + }else{ + if($use_javascript_redirect){ + echo ""; + }else{ + header("Location: {$_SERVER['REQUEST_URI']}&show_review=1"); + } + } + + exit; + } + + }else{ + $old_values = $submit_result['old_values']; + $custom_error = $submit_result['custom_error']; + $error_elements = $submit_result['error_elements']; + + $markup = display_integrated_form($input_array['form_id'],$old_values,$error_elements,$custom_error,0,$machform_path); + } + + }elseif(!empty($_POST['review_submit'])){ //if review page submitted + //commit data from review table to actual table + $record_id = $_SESSION['review_id']; + $param['machform_data_path'] = $machform_data_path; + $param['machform_base_path'] = $machform_path; + + $commit_result = commit_form_review($form_id,$record_id,$param); + + unset($_SESSION['review_id']); + + if(empty($commit_result['form_redirect'])){ + $url = str_replace(array("&show_review=1","?show_review=1"),"",$_SERVER['REQUEST_URI']); + if(strpos($url,'?') === false){ + if($use_javascript_redirect){ + echo ""; + }else{ + header("Location: {$url}?done=1"); + } + }else{ + if($use_javascript_redirect){ + echo ""; + }else{ + header("Location: {$url}&done=1"); + } + } + exit; + }else{ + if($use_javascript_redirect){ + echo ""; + }else{ + header("Location: {$commit_result['form_redirect']}"); + } + exit; + } + }elseif (!empty($_GET['show_review'])){ //show review page + if(empty($_SESSION['review_id'])){ + die("Your session has been expired. Please start again."); + }else{ + $record_id = $_SESSION['review_id']; + } + $markup = display_integrated_form_review($form_id,$record_id,$machform_path); + }elseif (!empty($_POST['review_back'])){ //go back to form + $url = str_replace(array("&show_review=1","?show_review=1"),"",$_SERVER['REQUEST_URI']); + + if($use_javascript_redirect){ + echo ""; + }else{ + header("Location: {$url}"); + } + + exit; + }else{ + + if(empty($form_id)){ + die('ID required.'); + } + + //check for delete file option + //this is available for form with review enabled + if(!empty($_GET['delete_file']) && !empty($_SESSION['review_id'])){ + $element_id = (int) trim($_GET['delete_file']); + $param['machform_data_path'] = $machform_data_path; + delete_review_file_entry($form_id,$_SESSION['review_id'],$element_id,$param); + } + + if(!empty($_GET['done'])){ + $markup = display_integrated_success($form_id,$machform_path); + }else{ + $markup = display_integrated_form($form_id,null,null,'',0,$machform_path); + } + } + + echo $markup; + + } + +?> \ No newline at end of file diff --git a/manage_entries.php b/manage_entries.php new file mode 100644 index 0000000..6564634 --- /dev/null +++ b/manage_entries.php @@ -0,0 +1,628 @@ + $lastpage){ + $pageno = $lastpage; + } + + //construct the LIMIT clause for the sql SELECT statement + if(!empty($numrows)){ + $limit = 'LIMIT ' .($pageno - 1) * $rows_per_page .',' .$rows_per_page; + } + /*****End Pagination code *******/ + + + //get form name + $query = "select form_name from `ap_forms` where form_id='$form_id'"; + $result = do_query($query); + $row = do_fetch_result($result); + $form_name = $row['form_name']; + + + $max_data_length = 80; //maximum length of column header and content + + //get form element options + $query = "select element_id,option_id,`option` from ap_element_options where form_id='$form_id' and live=1 order by element_id,option_id asc"; + $result = do_query($query); + while($row = do_fetch_result($result)){ + $element_id = $row['element_id']; + $option_id = $row['option_id']; + + //limit the data length + if(strlen($row['option']) > $max_data_length){ + $element_option_lookup[$element_id][$option_id] = htmlspecialchars(substr($row['option'],0,$max_data_length).'...',ENT_QUOTES); + }else{ + $element_option_lookup[$element_id][$option_id] = htmlspecialchars($row['option'],ENT_QUOTES); + } + } + + /******************************************************************************************/ + //prepare column header names lookup + $query = "select element_id,element_title,element_type,element_constraint from `ap_form_elements` where form_id='$form_id' order by element_position asc"; + $result = do_query($query); + + while($row = do_fetch_result($result)){ + $element_type = $row['element_type']; + $element_constraint = $row['element_constraint']; + + //limit the title length + if(strlen($row['element_title']) > $max_data_length){ + $row['element_title'] = substr($row['element_title'],0,$max_data_length).'...'; + } + + $row['element_title'] = htmlspecialchars($row['element_title']); + + if('address' == $element_type){ //address has 6 fields + $column_name_lookup['element_'.$row['element_id'].'_1'] = $row['element_title'].' - Street Address'; + $column_name_lookup['element_'.$row['element_id'].'_2'] = 'Address Line 2'; + $column_name_lookup['element_'.$row['element_id'].'_3'] = 'City'; + $column_name_lookup['element_'.$row['element_id'].'_4'] = 'State/Province/Region'; + $column_name_lookup['element_'.$row['element_id'].'_5'] = 'Zip/Postal Code'; + $column_name_lookup['element_'.$row['element_id'].'_6'] = 'Country'; + + $column_type_lookup['element_'.$row['element_id'].'_1'] = $row['element_type']; + $column_type_lookup['element_'.$row['element_id'].'_2'] = $row['element_type']; + $column_type_lookup['element_'.$row['element_id'].'_3'] = $row['element_type']; + $column_type_lookup['element_'.$row['element_id'].'_4'] = $row['element_type']; + $column_type_lookup['element_'.$row['element_id'].'_5'] = $row['element_type']; + $column_type_lookup['element_'.$row['element_id'].'_6'] = $row['element_type']; + + }elseif ('simple_name' == $element_type){ //simple name has 2 fields + $column_name_lookup['element_'.$row['element_id'].'_1'] = $row['element_title'].' - First'; + $column_name_lookup['element_'.$row['element_id'].'_2'] = $row['element_title'].' - Last'; + + $column_type_lookup['element_'.$row['element_id'].'_1'] = $row['element_type']; + $column_type_lookup['element_'.$row['element_id'].'_2'] = $row['element_type']; + + }elseif ('name' == $element_type){ //name has 4 fields + $column_name_lookup['element_'.$row['element_id'].'_1'] = $row['element_title'].' - Title'; + $column_name_lookup['element_'.$row['element_id'].'_2'] = $row['element_title'].' - First'; + $column_name_lookup['element_'.$row['element_id'].'_3'] = $row['element_title'].' - Last'; + $column_name_lookup['element_'.$row['element_id'].'_4'] = $row['element_title'].' - Suffix'; + + $column_type_lookup['element_'.$row['element_id'].'_1'] = $row['element_type']; + $column_type_lookup['element_'.$row['element_id'].'_2'] = $row['element_type']; + $column_type_lookup['element_'.$row['element_id'].'_3'] = $row['element_type']; + $column_type_lookup['element_'.$row['element_id'].'_4'] = $row['element_type']; + + }elseif('money' == $element_type){//money format + $column_name_lookup['element_'.$row['element_id']] = $row['element_title']; + if(!empty($element_constraint)){ + $column_type_lookup['element_'.$row['element_id']] = $element_constraint; //euro, pound, yen + }else{ + $column_type_lookup['element_'.$row['element_id']] = 'dollar'; //default is dollar + } + }elseif('checkbox' == $element_type){ //checkboxes, get childs elements + + $this_checkbox_options = $element_option_lookup[$row['element_id']]; + foreach ($this_checkbox_options as $option_id=>$option){ + $column_name_lookup['element_'.$row['element_id'].'_'.$option_id] = $option; + $column_type_lookup['element_'.$row['element_id'].'_'.$option_id] = $row['element_type']; + } + }elseif ('time' == $element_type){ + if($element_constraint == 'show_seconds'){ + $column_type_lookup['element_'.$row['element_id']] = $row['element_type']; + }else{ + $column_type_lookup['element_'.$row['element_id']] = 'time_noseconds'; + } + + $column_name_lookup['element_'.$row['element_id']] = $row['element_title']; + }else{ //for other elements with only 1 field + $column_name_lookup['element_'.$row['element_id']] = $row['element_title']; + $column_type_lookup['element_'.$row['element_id']] = $row['element_type']; + } + } + /******************************************************************************************/ + + + //set column properties for basic fields + $column_name_lookup['id'] = ''; + $column_name_lookup['row_num'] = '#'; + $column_name_lookup['date_created'] = 'Date Created'; + $column_name_lookup['date_updated'] = 'Date Updated'; + $column_name_lookup['ip_address'] = 'IP Address'; + + $column_type_lookup['id'] = 'number'; + $column_type_lookup['row_num'] = 'number'; + $column_type_lookup['date_created'] = 'text'; + $column_type_lookup['date_updated'] = 'text'; + $column_type_lookup['ip_address'] = 'text'; + + /******************************************************************************************/ + //get columns preference + $query = "select element_name from ap_column_preferences where form_id='{$form_id}' order by position asc"; + $result = do_query($query); + while($row = do_fetch_result($result)){ + $column_prefs[] = $row['element_name']; + } + + //if empty display 6 first columns + if(empty($column_prefs)){ + $query = "select * from `ap_form_{$form_id}` limit 1"; + $result = do_query($query); + + $i = 0; + $j = 0; + $fields_num = mysql_num_fields($result); + while(($i < $fields_num) && ($j <= 5)){ + $meta = mysql_fetch_field($result, $i); + + if(!in_array($i,array(0,2,3))){ //don't display id (0), date_updated (2) and ip_address (3) as default + $column_prefs[$j] = $meta->name; + $j++; + } + + $i++; + } + } + + $field_list = implode(',',$column_prefs); + $query = "select id,id as row_num,{$field_list} from `ap_form_{$form_id}` order by id desc $limit"; + $result = do_query($query); + + //get actual field name from selected table + $i = 0; + $fields_num = mysql_num_fields($result); + while($i < $fields_num){ + $meta = mysql_fetch_field($result, $i); + $columns[$i] = $meta->name; + $i++; + } + + $i=0; + $c=0; + $column_label = array(); + $first_row_number = ($pageno -1) * $rows_per_page + 1; + $last_row_number = $first_row_number; + + + while($row = do_fetch_result($result)){ + + for($j=0;$j<$fields_num;$j++){ + + + $column_name = $columns[$j]; + + + $form_data[$i][$j] = ''; + + //limit the data length, unless for file element + if($column_type_lookup[$column_name] != 'file'){ + if(strlen($row[$column_name]) > $max_data_length){ + $row[$column_name] = substr($row[$column_name],0,$max_data_length).'...'; + } + } + + if($column_type_lookup[$column_name] == 'time'){ + if(!empty($row[$column_name])){ + $form_data[$i][$j] = date("h:i:s A",strtotime($row[$column_name])); + }else { + $form_data[$i][$j] = ''; + } + }elseif($column_type_lookup[$column_name] == 'time_noseconds'){ + if(!empty($row[$column_name])){ + $form_data[$i][$j] = date("h:i A",strtotime($row[$column_name])); + }else { + $form_data[$i][$j] = ''; + } + }elseif(in_array($column_type_lookup[$column_name],array('dollar','euro','pound','yen'))){ //set column formatting for money fields + $column_type = $column_type_lookup[$column_name]; + + switch ($column_type){ + case 'dollar' : $currency = '$';break; + case 'pound' : $currency = '£';break; + case 'euro' : $currency = '€';break; + case 'yen' : $currency = '¥';break; + } + + if(!empty($row[$column_name])){ + $form_data[$i][$j] = '
    '.$currency.$row[$column_name].'
    '; + }else{ + $form_data[$i][$j] = ''; + } + }elseif($column_type_lookup[$column_name] == 'date'){ //date with format MM/DD/YYYY + if(!empty($row[$column_name]) && ($row[$column_name] != '0000-00-00')){ + $exploded_value = array(); + $exploded_value = explode("-",$row[$column_name]); + $form_data[$i][$j] = "{$exploded_value[0]}/{$exploded_value[1]}/{$exploded_value[2]}"; + } + }elseif($column_type_lookup[$column_name] == 'europe_date'){ //date with format DD/MM/YYYY + if(!empty($row[$column_name]) && ($row[$column_name] != '0000-00-00')){ + $exploded_value = array(); + $exploded_value = explode("-",$row[$column_name]); + $form_data[$i][$j] = "{$exploded_value[0]}/{$exploded_value[1]}/{$exploded_value[2]}"; + } + }elseif($column_type_lookup[$column_name] == 'number'){ + $form_data[$i][$j] = $row[$column_name]; + }elseif (in_array($column_type_lookup[$column_name],array('radio','select'))){ //multiple choice or dropdown + $exploded = array(); + $exploded = explode('_',$column_name); + $this_element_id = $exploded[1]; + $this_option_id = $row[$column_name]; + + $form_data[$i][$j] = $element_option_lookup[$this_element_id][$this_option_id]; + }elseif($column_type_lookup[$column_name] == 'checkbox'){ + + if(!empty($row[$column_name])){ + $form_data[$i][$j] = '
    '; + }else{ + $form_data[$i][$j] = ''; + } + + }elseif(in_array($column_type_lookup[$column_name],array('phone','simple_phone'))){ + $form_data[$i][$j] = $row[$column_name]; + }elseif($column_type_lookup[$column_name] == 'file'){ + if(!empty($row[$column_name])){ + //encode the long query string for more readibility + $q_string = base64_encode("form_id={$form_id}&id={$row['id']}&el={$column_name}"); + $form_data[$i][$j] = "  Download file"; + } + }else{ + $form_data[$i][$j] = htmlspecialchars(str_replace("\r","",str_replace("\n"," ",$row[$column_name])),ENT_QUOTES); + + if($column_name == 'date_created' || $column_name == 'date_updated'){ + $form_data[$i][$j] = short_relative_date($form_data[$i][$j]); + } + } + + if(count($column_label) < $fields_num){ + $column_label[$c]['name'] = $column_name; + $column_label[$c]['label'] = str_replace("\r","",str_replace("\n"," ",$column_name_lookup[$column_name])); + $c++; + } + } + + $last_row_number++; + $i++; + } + + $last_row_number--; + /******************************************************************************************/ + + + $header_data =<< + + + +EOT; + + +?> + + + + +
    + +
    + +
    Export all entries: Excel File CSV File
    + +

    Entries

    +

    Edit and manage your form entries

    +
    + + +
    +
    +
    +
      + or + +
    + +
    + + + + + +'.$table_header['label'].''; + }elseif ($table_header['name'] == 'row_num'){ + echo ''; + }else{ + echo ''; + } + + + } +?> + + + + +"; + + foreach ($row_data as $key=>$column_data){ + if($key == 0){ + echo ''; + }elseif ($key == 1){ + echo ''; + }else{ + echo ''; + } + } + + echo ''; + } +?> + +
    '.$table_header['label'].'
    '.$table_header['label'].'
    '.$column_data.'
    '.$column_data.'
    + + +
    +
    + +

    This form doesn't have any entry yet.

    "; + } +?> + + + +
    + 19){ + echo " <<First "; + } + $prevpage = $pageno-1; + + + } + + //middle navigation + if($pageno == 1){ + $i=1; + while(($i<=19) && ($i<=$lastpage)){ + if($i != 1){ + $active_style = ''; + }else{ + $active_style = 'class="active_page"'; + } + echo " $i "; + $i++; + } + if($lastpage > $i){ + echo ' ... '; + } + }elseif ($pageno == $lastpage){ + + if(($lastpage - 19) > 1){ + echo ' ... '; + $i=1; + $j=$lastpage - 18; + while($i<=19){ + if($j != $lastpage){ + $active_style = ''; + }else{ + $active_style = 'class="active_page"'; + } + echo " $j "; + $i++; + $j++; + } + }else{ + $i=1; + while(($i<=19) && ($i<=$lastpage)){ + if($i != $lastpage){ + $active_style = ''; + }else{ + $active_style = 'class="active_page"'; + } + echo " $i "; + $i++; + } + } + + }else{ + $next_pages = false; + $prev_pages = false; + + if(($lastpage - ($pageno + 9)) >= 1){ + $next_pages = true; + } + if(($pageno - 9) > 1){ + $prev_pages = true; + } + + if($prev_pages){ //if there are previous pages + echo ' ... '; + if($next_pages){ //if there are next pages + $i=1; + $j=$pageno - 9; + while($i<=19){ + if($j != $pageno){ + $active_style = ''; + }else{ + $active_style = 'class="active_page"'; + } + echo " $j "; + $i++; + $j++; + } + echo ' ... '; + }else{ + + $i=1; + $j=$pageno - 9; + while(($i<=19) && ($j <= $lastpage)){ + if($j != $pageno){ + $active_style = ''; + }else{ + $active_style = 'class="active_page"'; + } + echo " $j "; + $i++; + $j++; + } + } + }else{ //if there aren't previous pages + + $i=1; + while(($i<=19) && ($i <= $lastpage)){ + if($i != $pageno){ + $active_style = ''; + }else{ + $active_style = 'class="active_page"'; + } + echo " $i "; + $i++; + + } + if($next_pages){ + echo ' ... '; + } + + } + + + } + + if ($pageno != $lastpage) + { + $nextpage = $pageno+1; + if($lastpage > 19){ + echo " Last>> "; + } + } + + + //next we inform the user of his current position in the sequence of available pages + ?> + + +
    + + + + +
    + \ No newline at end of file diff --git a/manage_form.php b/manage_form.php new file mode 100644 index 0000000..4c5136d --- /dev/null +++ b/manage_form.php @@ -0,0 +1,682 @@ +$value){ + $index_key = array_search($form_id,$value,true); + if($index_key !== false){ + $active_tab_auto = $index_key; + $pageno_auto = $key + 1; + } + } + } + + + //check for form delete parameter + if(!empty($_GET['delete'])){ + $deleted_form_id = (int) trim($_GET['delete']); + delete_form($deleted_form_id); + } + + //check for form duplicate parameter + if(!empty($_GET['duplicate'])){ + $target_form_id = (int) trim($_GET['duplicate']); + $result_form_id = duplicate_form($target_form_id); + + if(!empty($result_form_id)){ + $_SESSION['AP_SUCCESS']['title'] = 'Success'; + $_SESSION['AP_SUCCESS']['desc'] = 'Form duplicated.'; + + header("Location: manage_form.php?id={$result_form_id}"); + exit; + } + } + + + /****Pagination *************/ + //get page number for pagination + if(!empty($pageno_auto)){ + $pageno = $pageno_auto; + }elseif(!empty($_GET['pageno'])) { + $pageno = $_GET['pageno']; + }else{ + $pageno = 1; + } + + //identify how many database rows are available + $query = "select count(*) total_row from `ap_forms`"; + $result = do_query($query); + $row = do_fetch_result($result); + + $numrows = $row['total_row']; + + $lastpage = ceil($numrows/$rows_per_page); + + + //ensure that $pageno is within range + //this code checks that the value of $pageno is an integer between 1 and $lastpage + $pageno = (int)$pageno; + + if ($pageno < 1) { + $pageno = 1; + } + elseif ($pageno > $lastpage){ + $pageno = $lastpage; + } + + //construct the LIMIT clause for the sql SELECT statement + if(!empty($numrows)){ + $limit = 'LIMIT ' .($pageno - 1) * $rows_per_page .',' .$rows_per_page; + } + /*****End Pagination code *******/ + + + + //get form list + $query = "select form_id,form_name,form_active,form_email from `ap_forms` order by form_id asc $limit"; + $result = do_query($query); + $i=0; + $form_id_array = array(); + while($row = do_fetch_result($result)){ + $form_list[$i]['form_id'] = $row['form_id']; + $form_list[$i]['form_name'] = $row['form_name']; + $form_list[$i]['form_active'] = $row['form_active']; + if(!empty($row['form_email'])){ + $form_list[$i]['form_email'] = $row['form_email']; + }else{ + $form_list[$i]['form_email'] = 'nobody'; + } + $form_id_array[] = $row['form_id']; + $i++; + } + + //get total entries for each form + foreach ($form_id_array as $form_id){ + //get all time entries + $query = "select count(*) total_entry from `ap_form_{$form_id}`"; + $result = do_query($query); + $row = do_fetch_result($result); + $entries[$form_id]['total'] = $row['total_entry']; + + //get todays entries + $query = "select count(*) today_entry from `ap_form_{$form_id}` where date_created >= date_format(curdate(),'%Y-%m-%d 00:00:00') "; + $result = do_query($query); + $row = do_fetch_result($result); + $entries[$form_id]['today'] = $row['today_entry']; + + //get latest entry timing + $query = "select date_created from `ap_form_{$form_id}` order by id desc limit 1"; + $result = do_query($query); + $row = do_fetch_result($result); + $entries[$form_id]['latest_entry'] = relative_date($row['date_created']); + } + + $header_data =<< + + + + + + +EOT; + + //delete a form, definition, entries and uploaded files + function delete_form($form_id){ + //remove from ap_forms + $query = "delete from `ap_forms` where form_id='$form_id'"; + do_query($query); + + //remove from ap_form_elements + $query = "delete from `ap_form_elements` where form_id='$form_id'"; + do_query($query); + + //remove from ap_element_options + $query = "delete from `ap_element_options` where form_id='$form_id'"; + do_query($query); + + //remove from ap_column_preferences + $query = "delete from `ap_column_preferences` where form_id='$form_id'"; + do_query($query); + + //remove review table + $query = "drop table if exists `ap_form_{$form_id}_review`"; + do_query($query); + + //remove the actual table + $query = "drop table if exists `ap_form_{$form_id}`"; + do_query($query); + + //remove form folder + @full_rmdir(UPLOAD_DIR."/form_{$form_id}"); + if(DATA_DIR != UPLOAD_DIR){ + @full_rmdir(DATA_DIR."/form_{$form_id}"); + } + return true; + } + + //duplicate a form + function duplicate_form($form_id){ + + //set the new name + $query = "select form_name,form_review from `ap_forms` where form_id='$form_id'"; + $result = do_query($query); + $row = do_fetch_result($result); + $form_review = $row['form_review']; + $form_name = trim($row['form_name']); + $form_name .= " Copy"; + + //get new form_id + $query = "select max(form_id)+1 new_form_id from `ap_forms`"; + $result = do_query($query); + $row = do_fetch_result($result); + $new_form_id = trim($row['new_form_id']); + + //insert into ap_forms table + $query = "select * from `ap_forms` where form_id='{$form_id}'"; + $result = do_query($query); + + $i = 0; + $columns = array(); + $fields_num = mysql_num_fields($result); + while($i < $fields_num){ + $meta = mysql_fetch_field($result, $i); + + if(($meta->name != 'form_id') && ($meta->name != 'form_name')){ + $columns[] = $meta->name; + } + + $i++; + } + + + //build the query string + $columns_joined = implode(",",$columns); + $form_name = mysql_real_escape_string($form_name); + + //insert to ap_forms + $query = "insert into + `ap_forms`(form_id,form_name,{$columns_joined}) + select + {$new_form_id},'{$form_name}',{$columns_joined} + from + `ap_forms` + where + form_id='$form_id'"; + do_query($query); + + //create the new table + do_query("create table `ap_form_{$new_form_id}` like `ap_form_{$form_id}`"); + + + //copy ap_form_elements table + $query = "select * from `ap_form_elements` limit 1"; + $result = do_query($query); + + $i = 0; + $columns = array(); + $fields_num = mysql_num_fields($result); + while($i < $fields_num){ + $meta = mysql_fetch_field($result, $i); + + if($meta->name != 'form_id'){ + $columns[] = $meta->name; + } + + $i++; + } + $columns_joined = implode("`,`",$columns); + $query = "insert into + `ap_form_elements`(form_id,`{$columns_joined}`) + select + {$new_form_id},`{$columns_joined}` + from + `ap_form_elements` + where + form_id='$form_id'"; + do_query($query); + + //copy ap_element_options table + $query = "select * from `ap_element_options` limit 1"; + $result = do_query($query); + + $i = 0; + $columns = array(); + $fields_num = mysql_num_fields($result); + while($i < $fields_num){ + $meta = mysql_fetch_field($result, $i); + + if(($meta->name != 'form_id') && ($meta->name != 'aeo_id')){ + $columns[] = $meta->name; + } + + $i++; + } + $columns_joined = implode("`,`",$columns); + $query = "insert into + `ap_element_options`(form_id,`{$columns_joined}`) + select + {$new_form_id},`{$columns_joined}` + from + `ap_element_options` + where + form_id='$form_id'"; + do_query($query); + + + //copy ap_column_preferences table + $query = "select * from `ap_column_preferences` limit 1"; + $result = do_query($query); + + $i = 0; + $columns = array(); + $fields_num = mysql_num_fields($result); + while($i < $fields_num){ + $meta = mysql_fetch_field($result, $i); + + if(($meta->name != 'form_id') && ($meta->name != 'acp_id')){ + $columns[] = $meta->name; + } + + $i++; + } + $columns_joined = implode("`,`",$columns); + $query = "insert into + `ap_column_preferences`(form_id,`{$columns_joined}`) + select + {$new_form_id},`{$columns_joined}` + from + `ap_column_preferences` + where + form_id='$form_id'"; + do_query($query); + + //copy ap_form_xx_review table if exists + if(!empty($form_review)){ + do_query("CREATE TABLE `ap_form_{$new_form_id}_review` like `ap_form_{$form_id}_review`"); + } + + //create form folder + $old_mask = umask(0); + mkdir(DATA_DIR."/form_{$new_form_id}",0777); + mkdir(DATA_DIR."/form_{$new_form_id}/css",0777); + if(DATA_DIR != UPLOAD_DIR){ + mkdir(UPLOAD_DIR."/form_{$new_form_id}",0777); + } + mkdir(UPLOAD_DIR."/form_{$new_form_id}/files",0777); + umask($old_mask); + + //copy css file + copy(DATA_DIR."/form_{$form_id}/css/view.css",DATA_DIR."/form_{$new_form_id}/css/view.css"); + + return $new_form_id; + } + +?> + + +
    + +
    + +
    + +
    +

    Form Manager

    +

    Create, edit and manage your forms

    +
    + + + + +'; + + foreach ($form_list as $data){ + + if(!empty($data['form_active'])){ + $form_status = 'Accepting Entries'; + $image_status = 'checkbox.gif'; + $activation_text = 'Disable this form'; + $activation_link = 'disable_form'; + }else{ + $form_status = 'Inactive'; + $image_status = 'disabled.gif'; + $activation_text = 'Enable this form'; + $activation_link = 'enable_form'; + }; + + +?> +
    +
    +

    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    ">">">">">  ">
    ">Entries">Edit Form">Edit CSS">Emails">Embed Code View Form ">DuplicateDelete
    +
    + Today's Entries:
    + Total Entries:

    + Latest Entry:
    + +
    + Notifications will be sent to: +
    + + + Form Status: +       +    + + +
    +
    +
    +'; + echo ''; + + }else{ + echo "

    You have no form yet. Go create one!

    "; + } +?> + + + + + + +
    +
    + 19){ + echo " <<First "; + } + $prevpage = $pageno-1; + + + } + + //middle navigation + if($pageno == 1){ + $i=1; + while(($i<=19) && ($i<=$lastpage)){ + if($i != 1){ + $active_style = ''; + }else{ + $active_style = 'class="active_page"'; + } + echo " $i "; + $i++; + } + if($lastpage > $i){ + echo ' ... '; + } + }elseif ($pageno == $lastpage){ + + if(($lastpage - 19) > 1){ + echo ' ... '; + $i=1; + $j=$lastpage - 18; + while($i<=19){ + if($j != $lastpage){ + $active_style = ''; + }else{ + $active_style = 'class="active_page"'; + } + echo " $j "; + $i++; + $j++; + } + }else{ + $i=1; + while(($i<=19) && ($i<=$lastpage)){ + if($i != $lastpage){ + $active_style = ''; + }else{ + $active_style = 'class="active_page"'; + } + echo " $i "; + $i++; + } + } + + }else{ + $next_pages = false; + $prev_pages = false; + + if(($lastpage - ($pageno + 9)) >= 1){ + $next_pages = true; + } + if(($pageno - 9) > 1){ + $prev_pages = true; + } + + if($prev_pages){ //if there are previous pages + echo ' ... '; + if($next_pages){ //if there are next pages + $i=1; + $j=$pageno - 9; + while($i<=19){ + if($j != $pageno){ + $active_style = ''; + }else{ + $active_style = 'class="active_page"'; + } + echo " $j "; + $i++; + $j++; + } + echo ' ... '; + }else{ + + $i=1; + $j=$pageno - 9; + while(($i<=19) && ($j <= $lastpage)){ + if($j != $pageno){ + $active_style = ''; + }else{ + $active_style = 'class="active_page"'; + } + echo " $j "; + $i++; + $j++; + } + } + }else{ //if there aren't previous pages + + $i=1; + while(($i<=19) && ($i <= $lastpage)){ + if($i != $pageno){ + $active_style = ''; + }else{ + $active_style = 'class="active_page"'; + } + echo " $i "; + $i++; + + } + if($next_pages){ + echo ' ... '; + } + + } + + + } + + if ($pageno != $lastpage) + { + $nextpage = $pageno+1; + if($lastpage > 19){ + echo " Last>> "; + } + } + + + //next we inform the user of his current position in the sequence of available pages + ?> + + +
    + + + + +
    + \ No newline at end of file diff --git a/save.php b/save.php new file mode 100644 index 0000000..33fbbb3 --- /dev/null +++ b/save.php @@ -0,0 +1,474 @@ +decode($input_array['form']); + $elements_object = $json->decode($input_array['elements']); + + $form_id = $form_object->id; + + /******** Start Form Section ********************************************************************/ + //check for form_id, if exist this is an update operation + //if not this is an insert operation + $query = "select count(form_id) form_exist from ap_forms where form_id='$form_id'"; + $result = do_query($query); + $row = do_fetch_result($result); + + if(empty($row['form_exist'])){ + $is_new_form = true; + }else{ + $is_new_form = false; + } + + $form_input['form_id'] = $form_id; + $form_input['form_name'] = $form_object->name; + $form_input['form_description'] = $form_object->description; + $form_input['form_redirect'] = $form_object->redirect; + $form_input['form_success_message'] = $form_object->success_message; + $form_input['form_password'] = $form_object->password; + $form_input['form_unique_ip'] = $form_object->unique_ip; + $form_input['form_captcha'] = $form_object->captcha; + $form_input['form_review'] = $form_object->review; + $form_input['form_frame_height'] = $form_object->frame_height; + + if($is_new_form){ //this is a new form, insert new form data + $result = ap_forms_insert($form_input); + check_result($result); + + $form_id = mysql_insert_id(); + + //create new table for this form + $query = "CREATE TABLE `ap_form_{$form_id}` ( + `id` int(11) NOT NULL auto_increment, + `date_created` datetime NOT NULL default '0000-00-00 00:00:00', + `date_updated` datetime default NULL, + `ip_address` varchar(15) default NULL, + PRIMARY KEY (`id`) + ) DEFAULT CHARACTER SET utf8;"; + do_query($query); + + //create data folder for this form + if(is_writable(DATA_DIR)){ + + $old_mask = umask(0); + mkdir(DATA_DIR."/form_{$form_id}",0777); + mkdir(DATA_DIR."/form_{$form_id}/css",0777); + if(DATA_DIR != UPLOAD_DIR){ + mkdir(UPLOAD_DIR."/form_{$form_id}",0777); + } + mkdir(UPLOAD_DIR."/form_{$form_id}/files",0777); + + umask($old_mask); + + //copy default view.css to css folder + if(copy("./view.css",DATA_DIR."/form_{$form_id}/css/view.css")){ + //on success update 'form_has_css' field on ap_forms table + $form_update_input['form_has_css'] = 1; + ap_forms_update($form_id,$form_update_input); + } + } + }else{ //this is just an update, update form info + $result = ap_forms_update($form_id,$form_input); + check_result($result); + } + /******** End Form Section ********************************************************************/ + + + /******** Start Elements Section ********************************************************************/ + $elements_array = $elements_object->elements; + + //separate optionable elements (checkbox/radio button/dropdown) from other elements + $optionable_elements = array(); + + foreach ($elements_array as $key=>$value){ + if(($value->type == 'radio') || ($value->type == 'checkbox') || ($value->type == 'select')){ + $optionable_elements[] = $value; + }else{ + $value->options = null; //remove options for elements other than checkbox/radio/dropdown + $non_optionable_elements[] = $value; + } + } + + //1. Process non optionable elements + if(!empty($non_optionable_elements)){ + foreach ($non_optionable_elements as $element){ + if(empty($element->is_db_live)){ + $new_non_optionable_elements[] = $element; + }else{ + $old_non_optionable_elements[] = $element; + } + } + } + //1.1 Process new non-optionable element. Insert to table + + //get new element_id + $query = "select ifnull(max(element_id),0)+1 next_element_id from ap_form_elements where form_id='{$form_id}'"; + $result = do_query($query); + $row = do_fetch_result($result); + + $next_element_id = $row['next_element_id']; + + $element_input = array(); + $element_input['form_id'] = $form_id; + + if(!empty($new_non_optionable_elements)){ + foreach ($new_non_optionable_elements as $element){ + $element_input['element_id'] = $next_element_id; + $element_input['element_title'] = $element->title; + $element_input['element_guidelines'] = $element->guidelines; + $element_input['element_size'] = $element->size; + $element_input['element_is_required'] = $element->is_required; + $element_input['element_is_unique'] = $element->is_unique; + $element_input['element_is_private'] = $element->is_private; + $element_input['element_type'] = $element->type; + $element_input['element_position'] = $element->position; + $element_input['element_default_value'] = $element->default_value; + $element_input['element_constraint'] = $element->constraint; + + if(empty($element_child_lookup[$element->type])){ + $element_input['element_total_child'] = 0; + }else{ + $element_input['element_total_child'] = $element_child_lookup[$element->type]; + } + + ap_form_elements_insert($element_input); //insert field information + table_add_field($form_id,$next_element_id,$element->type); //actually create the field + + $next_element_id++; + } + } + + //1.2 Process old non-optionable element. Update table + + + $element_input = array(); + $updatable_element_type = array('phone','simple_phone','date','europe_date'); + + if(!empty($old_non_optionable_elements)){ + foreach ($old_non_optionable_elements as $element){ + $element_input['element_title'] = $element->title; + $element_input['element_guidelines'] = $element->guidelines; + $element_input['element_size'] = $element->size; + $element_input['element_is_required'] = $element->is_required; + $element_input['element_is_unique'] = $element->is_unique; + $element_input['element_is_private'] = $element->is_private; + $element_input['element_position'] = $element->position; + $element_input['element_default_value'] = $element->default_value; + $element_input['element_constraint'] = $element->constraint; + + if(empty($element_child_lookup[$element->type])){ + $element_input['element_total_child'] = 0; + }else{ + $element_input['element_total_child'] = $element_child_lookup[$element->type]; + } + + //special for phone,simple_phone,date,europe_date .. type can be changed + if(in_array($element->type,$updatable_element_type)){ + $element_input['element_type'] = $element->type; + }else{ + unset($element_input['element_type']); + } + + ap_form_elements_update($form_id,$element->id,$element_input); + + } + } + + + + //2. Process optionable elements (checkbox/radio button/dropdown) + foreach ($optionable_elements as $element){ + if(empty($element->is_db_live)){ + $new_optionable_elements[] = $element; + }else{ + $old_optionable_elements[] = $element; + } + } + + //2.1 Process new optionable element. Insert to table + $element_input = array(); + $element_input['form_id'] = $form_id; + + if(!empty($new_optionable_elements)){ + foreach ($new_optionable_elements as $element){ + $element_input['element_id'] = $next_element_id; + $element_input['element_title'] = $element->title; + $element_input['element_guidelines'] = $element->guidelines; + $element_input['element_size'] = $element->size; + $element_input['element_is_required'] = $element->is_required; + $element_input['element_is_unique'] = $element->is_unique; + $element_input['element_is_private'] = $element->is_private; + $element_input['element_type'] = $element->type; + $element_input['element_position'] = $element->position; + $element_input['element_default_value'] = $element->default_value; + $element_input['element_constraint'] = $element->constraint; + + if(empty($element_child_lookup[$element->type])){ + $element_input['element_total_child'] = 0; + }else{ + $element_input['element_total_child'] = $element_child_lookup[$element->type]; + } + ap_form_elements_insert($element_input); + + if(($element->type == 'radio') || ($element->type == 'select')){ //radio button and select only need one field total,,while checkboxes need one field per option + table_add_field($form_id,$next_element_id,$element->type); //actually create the field + } + + //insert options into ap_element_options table + //get new option_id + $query = "select ifnull(max(option_id),0)+1 next_option_id from ap_element_options where form_id='{$form_id}' and element_id='{$next_element_id}'"; + $result = do_query($query); + $row = do_fetch_result($result); + + $next_option_id = $row['next_option_id']; + + $option_input = array(); + $option_input['form_id'] = $form_id; + $option_input['element_id'] = $next_element_id; + $position = 1; + foreach ($element->options as $option){ + $option->option = trim($option->option); + if(empty($option->option) && ($option->option != '0')){ + continue; + } + $option_input['option_id'] = $next_option_id; + $option_input['option'] = $option->option; + $option_input['option_is_default'] = $option->is_default; + $option_input['position'] = $position; + ap_element_options_insert($option_input); + + if($element->type == 'checkbox'){ + table_add_field($form_id,$next_element_id,$element->type,$next_option_id); //actually create the field for checkbox + } + + $next_option_id++; + $position++; + } + + //update 'element_total_child' on ap_form_elements + $position -= 2; + do_query("update ap_form_elements set element_total_child='$position' where form_id='$form_id' and element_id='$next_element_id'"); + + $next_element_id++; + } + } + + + + //2.2 Process old optionable element. Update table + $element_input = array(); + + if(!empty($old_optionable_elements)){ + foreach ($old_optionable_elements as $element){ + //update ap_forms_element table + $element_input['element_title'] = $element->title; + $element_input['element_guidelines'] = $element->guidelines; + $element_input['element_size'] = $element->size; + $element_input['element_is_required'] = $element->is_required; + $element_input['element_is_unique'] = $element->is_unique; + $element_input['element_is_private'] = $element->is_private; + $element_input['element_position'] = $element->position; + $element_input['element_default_value'] = $element->default_value; + $element_input['element_constraint'] = $element->constraint; + + if(empty($element_child_lookup[$element->type])){ + $element_input['element_total_child'] = 0; + }else{ + $element_input['element_total_child'] = $element_child_lookup[$element->type]; + } + + ap_form_elements_update($form_id,$element->id,$element_input); + + //update ap_element_options table (checkbox/radio button/dropdown) + //'erase' all old data + $query = "update `ap_element_options` set `live`=0 where form_id='{$form_id}' and element_id='{$element->id}'"; + do_query($query); + + + //get new option_id for current element_id, just in case we need it to insert new option + $query = "select ifnull(max(option_id),0)+1 next_option_id from ap_element_options where form_id='{$form_id}' and element_id='{$element->id}'"; + $result = do_query($query); + $row = do_fetch_result($result); + + $next_option_id = $row['next_option_id']; + + $option_input = array(); + $option_input['form_id'] = $form_id; + $option_input['element_id'] = $element->id; + + //loop through elements + $position = 1; + foreach ($element->options as $option){ + $option->option = trim($option->option); + if(empty($option->option) && ($option->option != '0')){ + continue; + } + + $option_input['option'] = $option->option; + $option_input['option_is_default'] = $option->is_default; + $option_input['live'] = 1; + $option_input['position'] = $position; + + if(empty($option->id)){ //if id=0 insert new row + $option_input['option_id'] = $next_option_id; + + ap_element_options_insert($option_input); + + if($element->type == 'checkbox'){ + table_add_field($form_id,$element->id,$element->type,$next_option_id); //actually create the field for checkbox + } + + $next_option_id++; + }else{//if id !=0 update + unset($option_input['option_id']); + ap_element_options_update($form_id,$element->id,$option->id,$option_input); + } + $position++; + } + + //update 'element_total_child' on ap_form_elements + $position -= 2; + do_query("update ap_form_elements set element_total_child='$position' where form_id='$form_id' and element_id='{$element->id}'"); + } + } + + /******** End Elements Section **********************************************************************/ + + /******** Start processing review table **********************************************************/ + //delete review table if exists + do_query("DROP TABLE IF EXISTS `ap_form_{$form_id}_review`"); + + //if review is enabled, create the table + if(!empty($form_input['form_review'])){ + do_query("CREATE TABLE `ap_form_{$form_id}_review` like `ap_form_{$form_id}`"); + + do_query("ALTER TABLE `ap_form_{$form_id}_review` ADD COLUMN `session_id` varchar(100) NULL"); + } + + /******** End processing review table **********************************************************/ + + + $_SESSION['AP_SUCCESS']['title'] = 'Success'; + $_SESSION['AP_SUCCESS']['desc'] = 'Your form has been saved.'; + + echo '{ "status" : "ok", "message" : "'.$form_id.'" }'; + + /** Functions *************************/ + + function check_result($result){ + if($result !== true){ + if(!is_array($result)){ //if one line error message + $error = '{ "status" : "error","message" : "'.$result.'"}'; + echo $error; + } + } + } + + + + + //add fields to the specified form table + function table_add_field($form_id,$element_id,$type,$option_id=0){ + global $comment_desc; + + $comment = @$comment_desc[$type]; + + if(('text' == $type) || ('phone' == $type) || ('simple_phone' == $type) || ('url' == $type) || ('email' == $type) || ('file' == $type)){ + $query = "ALTER TABLE `ap_form_{$form_id}` ADD COLUMN `element_{$element_id}` text NULL COMMENT '{$comment}';"; + do_query($query); + }elseif ('textarea' == $type){ + $query = "ALTER TABLE `ap_form_{$form_id}` ADD COLUMN `element_{$element_id}` mediumtext NULL COMMENT '{$comment}';"; + do_query($query); + }elseif (('radio' == $type) || ('select' == $type)){ + $query = "ALTER TABLE `ap_form_{$form_id}` ADD COLUMN `element_{$element_id}` int(6) unsigned NOT NULL DEFAULT '0' COMMENT '{$comment}';"; + do_query($query); + }elseif ('time' == $type){ + $query = "ALTER TABLE `ap_form_{$form_id}` ADD COLUMN `element_{$element_id}` time NULL COMMENT '{$comment}';"; + do_query($query); + }elseif (('date' == $type) || ('europe_date' == $type)){ + $query = "ALTER TABLE `ap_form_{$form_id}` ADD COLUMN `element_{$element_id}` date NULL COMMENT '{$comment}';"; + do_query($query); + }elseif ('money' == $type){ + $query = "ALTER TABLE `ap_form_{$form_id}` ADD COLUMN `element_{$element_id}` decimal(62,2) NULL COMMENT '{$comment}';"; + do_query($query); + }elseif ('number' == $type){ + $query = "ALTER TABLE `ap_form_{$form_id}` ADD COLUMN `element_{$element_id}` double NULL COMMENT '{$comment}';"; + do_query($query); + }elseif ('simple_name' == $type){ + //add two field, first and last name + $query = "ALTER TABLE `ap_form_{$form_id}` ADD COLUMN `element_{$element_id}_1` varchar(255) NULL COMMENT '{$comment} - First', ADD COLUMN `element_{$element_id}_2` varchar(255) NULL COMMENT '{$comment} - Last';"; + do_query($query); + }elseif ('name' == $type){ + //add four field, title, first, last, suffix + $query = "ALTER TABLE `ap_form_{$form_id}` ADD COLUMN `element_{$element_id}_1` varchar(255) NULL COMMENT '{$comment} - Title', ADD COLUMN `element_{$element_id}_2` varchar(255) NULL COMMENT '{$comment} - First', ADD COLUMN `element_{$element_id}_3` varchar(255) NULL COMMENT '{$comment} - Last', ADD COLUMN `element_{$element_id}_4` varchar(255) NULL COMMENT '{$comment} - Suffix';"; + do_query($query); + }elseif ('address' == $type){ + //add six field + $query = "ALTER TABLE `ap_form_{$form_id}` ADD COLUMN `element_{$element_id}_1` varchar(255) NULL COMMENT '{$comment} - Street', ADD COLUMN `element_{$element_id}_2` varchar(255) NULL COMMENT '{$comment} - Line 2', ADD COLUMN `element_{$element_id}_3` varchar(255) NULL COMMENT '{$comment} - City', ADD COLUMN `element_{$element_id}_4` varchar(255) NULL COMMENT '{$comment} - State/Province/Region', ADD COLUMN `element_{$element_id}_5` varchar(255) NULL COMMENT '{$comment} - Zip/Postal Code', ADD COLUMN `element_{$element_id}_6` varchar(255) NULL COMMENT '{$comment} - Country';"; + do_query($query); + }elseif ('checkbox' == $type){ + $query = "ALTER TABLE `ap_form_{$form_id}` ADD COLUMN `element_{$element_id}_{$option_id}` int(6) unsigned NOT NULL DEFAULT '0' COMMENT '{$comment} - {$option_id}';"; + do_query($query); + } + + } +?> \ No newline at end of file diff --git a/template_variables.php b/template_variables.php new file mode 100644 index 0000000..ce62643 --- /dev/null +++ b/template_variables.php @@ -0,0 +1,149 @@ + MAX_TITLE_LENGTH){ + $row['element_title'] = substr($row['element_title'],0,MAX_TITLE_LENGTH); + } + + $row['element_title'] = htmlspecialchars($row['element_title']); + $column_list[$i]['field_name'] = $row['element_title']; + $column_list[$i]['template_variable'] = '{element_'.$row['element_id'].'}'; + $i++; + } + /******************************************************************************************/ + $column_list[$i]['field_name'] = ' '; + $column_list[$i]['template_variable'] = ' '; + $i++; + $column_list[$i]['field_name'] = 'Entry No.'; + $column_list[$i]['template_variable'] = '{entry_no}'; + $i++; + $column_list[$i]['field_name'] = 'Date Created'; + $column_list[$i]['template_variable'] = '{date_created}'; + $i++; + $column_list[$i]['field_name'] = 'IP Address'; + $column_list[$i]['template_variable'] = '{ip_address}'; + $i++; + $column_list[$i]['field_name'] = 'Form ID'; + $column_list[$i]['template_variable'] = '{form_id}'; + $i++; + $column_list[$i]['field_name'] = 'Form Name'; + $column_list[$i]['template_variable'] = '{form_name}'; + $i++; + $column_list[$i]['field_name'] = 'Complete Entry'; + $column_list[$i]['template_variable'] = '{entry_data}'; + + $header_data =<< + + + +EOT; + +?> + + + + +
    + +
    +

    Emails Template Variables

    +

    A list of available template variables for your email content

    +
    + + +
    +
    + + + + + + + + + + + + + +EOT; + echo $table_row; + $i++; + } +?> + + +
    FieldTemplate Variable
    {$data['field_name']}
    {$data['template_variable']}

    + +
    +
    + What is a Template Variable? +

    A Template Variable is a special identifier that is automatically replaced with data typed in by a user.


    + How are they used? +

    Copy the variable name on the left (including curly braces) to your email template.


    + Where can Template Variables be used? +

    Template Variables can be used in From Name, Subject and Content fields.

    +
    + +
    + \ No newline at end of file diff --git a/upgrade.php b/upgrade.php new file mode 100644 index 0000000..2d9c6b4 --- /dev/null +++ b/upgrade.php @@ -0,0 +1,416 @@ +Congratulations!
    You have completed the upgrade process. MachForm version 2 is now installed."; + }else{ + $install_message = "An error has occured during upgrade."; + } + + $state = 'install_report'; + }else{ + + //do a pre installation check + $state = 'show_preinstall_check'; + + //check for PHP version + if(version_compare(PHP_VERSION,"4.3.0",">=")){ + $is_php_version_passed = true; + }else{ + $is_php_version_passed = false; + $pre_install_has_error = true; + } + + //check for MySQL version + if(version_compare(mysql_get_server_info(),"4.1.0",">=")){ + $is_mysql_version_passed = true; + }else{ + $is_mysql_version_passed = false; + $pre_install_has_error = true; + } + + //check for MySQL user,password and database existance + if(empty($mysql_connect_error)){ + $is_mysql_connect_passed = true; + }else{ + $is_mysql_connect_passed = false; + $pre_install_has_error = true; + } + + if(empty($mysql_select_db_error)){ + $is_mysql_select_db_passed = true; + }else{ + $is_mysql_select_db_passed = false; + $pre_install_has_error = true; + } + + //check for data folder permission + if(is_writable(DATA_DIR)){ + $is_data_dir_writable = true; + }else { + $is_data_dir_writable = false; + $pre_install_has_error = true; + $data_dir_writable_error = "MachForm require read and write access to this folder. Please set the correct permission."; + } + + //check for current tables, make sure that version 2 is not installed already + $query = "select form_review from ap_forms limit 1"; + mysql_query($query); + $error_msg = mysql_error(); + if(empty($error_msg)){ + $is_version2_already_installed = true; + $pre_install_has_error = true; + $version2_already_installed_error = "Your installation already has the most recent version (Version 2)."; + }else{ + $is_version2_already_installed = false; + } + + if($pre_install_has_error){ + $pre_install_message = "Your system does not match the minimum requirements necessary. Please take the appropriate actions to correct the errors."; + }else{ + $pre_install_message = "Your system passed the minimum requirements necessary. You can now start the upgrade process."; + } + } + } + + } + + $hide_nav = true; +?> + + + +
    + + +
    +

    MachForm Installer Error

    +

    Please fix the following error before you can continue the installation process:

    +
    + +
    +
    +
      +
    • + +
      +

      + There doesn't seem to be a config.php file. We need this before we can get started. +

      +

      +

      In the base directory of your installation you'll find a file called config-empty.php. Open this file and fill in the required database information.



      +

      After the details are filled in you must rename the file config.php before continuing.


      +
      +
    • +
    • + +
    • +
    +
    +

    + + + +
    +

    MachForm 2.0 Pre-Upgrade Check

    +

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

    + + + +
    +

    No Previous Version of MachForm Found

    +

    Please follow the step below to be able to continue:

    +
    + +
    +
    +
      +
    • + +
      +

      + In order to upgrade to version 2.0, you need to have version 1.2 installed. +

      +
      +

      Make sure to double check your config.php file for any error or typo.


      +

      If this is the first time you use MachForm, then go to the installer page instead.


      +
      +
    • +
    +
    +

    + + + + +
    +

    MachForm Upgrade Report

    +

    +
    + +
    +
    +
      + +
    • + +
    • +
    • + +
    • +
    • + +
    • +
    • + +
    • +
    • + +
    • +
    • + +
    • +
    • + Important: Please delete this installer file (upgrade.php) now.

      After deleting this file, you can login to MachForm admin panel +
    • + +
    • + +
    • + + +
    • + +
    • + + + + +
    • + + +
    • + + +
    +
    +

    + + + +
    + \ No newline at end of file diff --git a/view.css b/view.css new file mode 100644 index 0000000..a04fa20 --- /dev/null +++ b/view.css @@ -0,0 +1,936 @@ +#main_body +{ + background:#fffff; + font-family:"Lucida Grande", Tahoma, Arial, Verdana, sans-serif; + font-size:small; + margin:8px 0 16px; + text-align:center; +} + +#form_container +{ + background:#fff; + border:1px solid #ccc; + margin:0 auto; + text-align:left; + width:640px; +} + +#top +{ + display:block; + height:10px; + margin:10px auto 0; + width:650px; +} + +#footer +{ + width:640px; + clear:both; + color:#999999; + text-align:center; + width:640px; + padding-bottom: 15px; + font-size: 85%; +} + +#footer a{ + color:#999999; + text-decoration: none; + border-bottom: 1px dotted #999999; +} + +#bottom +{ + display:block; + height:10px; + margin:0 auto; + width:650px; +} + +form.appnitro +{ + margin:20px 20px 0; + padding:0 0 20px; +} + +/**** Logo Section *****/ +#main_body h1 +{ + background-color:#dedede; + margin:0; + min-height:0; + padding:0; + text-decoration:none; + text-indent:-8000px; + background-image: url('../../../images/machform.gif'); + background-repeat: no-repeat; +} + +#main_body h1 a +{ + + display:block; + height:100%; + min-height:40px; + overflow:hidden; +} + + +#main_body img +{ + behavior:url(css/iepngfix.htc); + border:none; +} + + +/**** Form Section ****/ +.appnitro +{ + font-family:Lucida Grande, Tahoma, Arial, Verdana, sans-serif; + font-size:small; +} + +.appnitro li +{ + width:61%; +} + +#main_body form ul +{ + font-size:100%; + list-style-type:none; + margin:0; + padding:0; + width:100%; +} + +#main_body form li +{ + display:block; + margin:0; + padding:4px 5px 2px 9px; + position:relative; +} + +#main_body form li:after +{ + clear:both; + content:"."; + display:block; + height:0; + visibility:hidden; +} + +#main_body .buttons:after +{ + clear:both; + content:"."; + display:block; + height:0; + visibility:hidden; +} + +#main_body .buttons +{ + clear:both; + display:block; + margin-top:10px; +} + +#main_body html form li div +{ + display:inline-block; +} + +#main_body form li div +{ + color:#444; + margin:0 4px 0 0; + padding:0 0 8px; +} + +#main_body form li span +{ + color:#444; + float:left; + margin:0 4px 0 0; + padding:0 0 8px; +} + +#main_body form li div.left +{ + display:inline; + float:left; + width:48%; +} + +#main_body form li div.right +{ + display:inline; + float:right; + width:48%; +} + +#main_body form li div.left .medium +{ + width:100%; +} + +#main_body form li div.right .medium +{ + width:98%; +} + +#main_body .clear +{ + clear:both; +} + +#main_body form li div label +{ + clear:both; + color:#444; + display:block; + font-size:9px; + line-height:9px; + margin:0; + padding-top:3px; +} + +#main_body form li span label +{ + clear:both; + color:#444; + display:block; + font-size:9px; + line-height:9px; + margin:0; + padding-top:3px; +} + +#main_body form li .datepicker +{ + cursor:pointer !important; + float:left; + height:16px; + margin:.1em 5px 0 0; + padding:0; + width:16px; +} + +#main_body .form_description +{ + border-bottom:1px dotted #ccc; + clear:both; + display:inline-block; + margin:0 0 1em; +} + +#main_body .form_description[class] +{ + display:block; +} + +#main_body .form_description h2 +{ + clear:left; + font-size:160%; + font-weight:400; + margin:0 0 3px; +} + +#main_body .form_description p +{ + font-size:95%; + line-height:130%; + margin:0 0 12px; +} + +#main_body form hr +{ + display:none; +} + +#main_body form li.section_break +{ + border-top:1px dotted #ccc; + margin-top:9px; + padding-bottom:0; + padding-left:9px; + padding-top:13px; + width:97% !important; +} + +#main_body form ul li.first +{ + border-top:none !important; + margin-top:0 !important; + padding-top:0 !important; +} + +#main_body form .section_break h3 +{ + font-size:110%; + font-weight:400; + line-height:130%; + margin:0 0 2px; +} + +#main_body form .section_break p +{ + font-size:85%; + + margin:0 0 10px; +} + +/**** Buttons ****/ +#main_body input.button_text +{ + overflow:visible; + padding:0 7px; + width:auto; +} + +#main_body .buttons input +{ + font-size:120%; + margin-right:5px; +} + +/**** Inputs and Labels ****/ +#main_body label.description +{ + border:none; + color:#222; + display:block; + font-size:95%; + font-weight:700; + line-height:150%; + padding:0 0 1px; +} + +#main_body span.symbol +{ + font-size:115%; + line-height:130%; +} + +#main_body input.text +{ + background:#fff url(../../../images/shadow.gif) repeat-x top; + border-bottom:1px solid #ddd; + border-left:1px solid #c3c3c3; + border-right:1px solid #c3c3c3; + border-top:1px solid #7c7c7c; + color:#333; + font-size:100%; + margin:0; + padding:2px 0; +} + +#main_body input.file +{ + color:#333; + font-size:100%; + margin:0; + padding:2px 0; +} + +#main_body textarea.textarea +{ + background:#fff url(../../../images/shadow.gif) repeat-x top; + border-bottom:1px solid #ddd; + border-left:1px solid #c3c3c3; + border-right:1px solid #c3c3c3; + border-top:1px solid #7c7c7c; + color:#333; + font-family:"Lucida Grande", Tahoma, Arial, Verdana, sans-serif; + font-size:100%; + margin:0; + width:99%; +} + +#main_body select.select +{ + color:#333; + font-size:100%; + margin:1px 0; + padding:1px 0 0; + background:#fff url(../../../images/shadow.gif) repeat-x top; + border-bottom:1px solid #ddd; + border-left:1px solid #c3c3c3; + border-right:1px solid #c3c3c3; + border-top:1px solid #7c7c7c; +} + + +#main_body input.currency +{ + text-align:right; + padding-right:3px; +} + +#main_body input.checkbox +{ + display:block; + height:13px; + line-height:1.4em; + margin:6px 0 0 3px; + width:13px; +} + +#main_body input.radio +{ + display:block; + height:13px; + line-height:1.4em; + margin:6px 0 0 3px; + width:13px; +} + +#main_body label.choice +{ + color:#444; + display:block; + font-size:100%; + line-height:1.4em; + margin:-1.55em 0 0 25px; + padding:4px 0 5px; + width:90%; +} + +#main_body select.select[class] +{ + margin:0; + padding:1px 0; +} + +*:first-child+html select.select[class] +{ + margin:1px 0; +} + +#main_body .safari select.select +{ + font-size:120% !important; + margin-bottom:1px; +} + +#main_body input.small +{ + width:25%; +} + +#main_body select.small +{ + width:25%; +} + +#main_body input.medium +{ + width:50%; +} + +#main_body select.medium +{ + width:50%; +} + +#main_body input.large +{ + width:99%; +} + +#main_body select.large +{ + width:100%; +} + +#main_body textarea.small +{ + height:5.5em; +} + +#main_body textarea.medium +{ + height:10em; +} + +#main_body textarea.large +{ + height:20em; +} + +/**** Errors ****/ +#error_message +{ + background:#fff; + border:1px dotted red; + margin-bottom:1em; + padding-left:0; + padding-right:0; + padding-top:4px; + text-align:center; + width:97%; +} + +#error_message_title +{ + color:#DF0000; + font-size:125%; + margin:7px 0 5px !important; + padding:0 !important; +} + +#error_message_desc +{ + color:#000; + font-size:100%; + margin:0 0 .8em !important; +} + +#error_message_desc strong +{ + background-color:#FFDFDF; + color:red; + padding:2px 3px; +} + +#main_body form li.error +{ + background-color:#FFDFDF !important; + border-bottom:1px solid #EACBCC; + border-right:1px solid #EACBCC; + margin:3px 0; +} + +#main_body form li.error label +{ + color:#DF0000 !important; +} + +#main_body form p.error +{ + clear:both; + color:red; + font-size:10px; + font-weight:700; + margin:0 0 5px !important; +} + +#main_body form .required +{ + color:red !important; + float:none !important; + font-weight:700; +} + +/**** Guidelines and Error Highlight ****/ +#main_body form li.highlighted +{ + background-color:#fff7c0; +} + +#main_body form .guidelines +{ + background:#f5f5f5; + border:1px solid #e6e6e6; + color:#444; + font-size:80%; + left:100%; + line-height:130%; + margin:0 0 0 8px !important; + padding:8px 10px 9px; + position:absolute; + top:0; + visibility:hidden; + width:42%; + z-index:1000; +} + +#main_body form .guidelines small +{ + font-size:105%; +} + +#main_body form li.highlighted .guidelines +{ + visibility:visible; +} + +#main_body form li:hover .guidelines +{ + visibility:visible; +} + +.no_guidelines .guidelines +{ + display:none !important; +} + +.no_guidelines form li +{ + width:97%; +} + +.no_guidelines li.section +{ + padding-left:9px; +} + +/*** Success Message ****/ +.form_success +{ + clear: both; + margin: 0; + padding: 90px 0pt 100px; + text-align: center +} + +.form_success h2 { + clear:left; + font-size:160%; + font-weight:normal; + margin:0pt 0pt 3px; +} + +/*** Password ****/ +#main_body ul.password{ + margin-top:60px; + margin-bottom: 60px; + text-align: center; +} +.password h2{ + color:#DF0000; + font-weight:bold; + margin:0pt auto 10px; +} + +.password input.text { + font-size:170% !important; + width:380px; + text-align: center; +} +.password label{ + display:block; + font-size:120% !important; + padding-top:10px; + font-weight:bold; +} + +#li_captcha{ + padding-left: 5px; +} + + +#li_captcha span{ + float:none; + padding: 0px !important; +} + +#li_captcha div{ + padding: 0px !important; +} +#captcha_image{ + padding-top: 5px; + padding-bottom: 10px; +} +#captcha_response_field{ + margin-bottom: 10px; +} +#dummy_captcha_internal{ + height: 8px; +} +/** Embedded Form **/ + +.embed #top, .embed #bottom, .embed h1{ + display: none; +} + +.embed #form_container{ + border: none; + width: 100%; + background: none; +} + +.embed #footer{ + text-align: left; + padding-left: 10px; + width: 99%; +} + +.embed #footer.success{ + text-align: center; +} + +.embed form.appnitro +{ + margin:0px 0px 0; + +} + +/** Integrated Form **/ +.integrated *{ + font-family:"Lucida Grande", Tahoma, Arial, Verdana, sans-serif; + color: #000; +} + +.integrated #top, .integrated #bottom, .integrated h1{ + display: none; +} + +.integrated #form_container{ + border: none; + width: 99%; + background: none; +} + +.integrated #footer{ + text-align: left; + padding-left: 10px; + width: 99%; +} + +.integrated #footer.success{ + text-align: center; +} + +.integrated form.appnitro +{ + margin:0px 0px 0; + +} + +.integrated form .section_break h3 +{ + border: none !important; +} + +.integrated #error_message h3 +{ + border: none !important; + +} + + + +/*** Calendar **********************/ +div.calendar { position: relative; } + + +.calendar table { +cursor:pointer; +border:1px solid #ccc; +font-size: 11px; +color: #000; +background: #fff; +font-family:"Lucida Grande", Tahoma, Arial, Verdana, sans-serif; +} + +.calendar table .title,.calendar table .button{ +font-size: 11px; +} + +.calendar * { +font-size: 11px; +font-family:"Lucida Grande", Tahoma, Arial, Verdana, sans-serif; +} + +.calendar .button { +text-align: center; +padding: 2px; +} + +.calendar .nav { +background:#f5f5f5; +} + +.calendar thead .title { +font-weight: bold; +text-align: center; +background: #dedede; +color: #000; +padding: 2px 0 3px 0; +} + +.calendar thead .headrow { +background: #f5f5f5; +color: #444; +font-weight:bold; +} + +.calendar thead .daynames { +background: #fff; +color:#333; +font-weight:bold; +} + +.calendar thead .name { +border-bottom: 1px dotted #ccc; +padding: 2px; +text-align: center; +color: #000; +} + +.calendar thead .weekend { +color: #666; +} + +.calendar thead .hilite { +background-color: #444; +color: #fff; +padding: 1px; +} + +.calendar thead .active { +background-color: #d12f19; +color:#fff; +padding: 2px 0px 0px 2px; +} + + +.calendar tbody .day { +width:1.8em; +color: #222; +text-align: right; +padding: 2px 2px 2px 2px; +} +.calendar tbody .day.othermonth { +font-size: 80%; +color: #bbb; +} +.calendar tbody .day.othermonth.oweekend { +color: #fbb; +} + +.calendar table .wn { +padding: 2px 2px 2px 2px; +border-right: 1px solid #000; +background: #666; +} + +.calendar tbody .rowhilite td { +background: #FFF1AF; +} + +.calendar tbody .rowhilite td.wn { +background: #FFF1AF; +} + +.calendar tbody td.hilite { +padding: 1px 1px 1px 1px; +background:#444 !important; +color:#fff !important; +} + +.calendar tbody td.active { +color:#fff; +background: #529214 !important; +padding: 2px 2px 0px 2px; +} + +.calendar tbody td.selected { +font-weight: bold; +border: 1px solid #888; +padding: 1px 1px 1px 1px; +background: #f5f5f5 !important; +color: #222 !important; +} + +.calendar tbody td.weekend { +color: #666; +} + +.calendar tbody td.today { +font-weight: bold; +color: #529214; +background:#D9EFC2; +} + +.calendar tbody .disabled { color: #999; } + +.calendar tbody .emptycell { +visibility: hidden; +} + +.calendar tbody .emptyrow { +display: none; +} + +.calendar tfoot .footrow { +text-align: center; +background: #556; +color: #fff; +} + +.calendar tfoot .ttip { +background: #222; +color: #fff; +font-size:10px; +border-top: 1px solid #dedede; +padding: 3px; +} + +.calendar tfoot .hilite { +background: #aaf; +border: 1px solid #04f; +color: #000; +padding: 1px; +} + +.calendar tfoot .active { +background: #77c; +padding: 2px 0px 0px 2px; +} + +.calendar .combo { +position: absolute; +display: none; +top: 0px; +left: 0px; +width: 4em; +border: 1px solid #ccc; +background: #f5f5f5; +color: #222; +font-size: 90%; +z-index: 100; +} + +.calendar .combo .label, +.calendar .combo .label-IEfix { +text-align: center; +padding: 1px; +} + +.calendar .combo .label-IEfix { +width: 4em; +} + +.calendar .combo .hilite { +background: #444; +color:#fff; +} + +.calendar .combo .active { +border-top: 1px solid #999; +border-bottom: 1px solid #999; +background: #dedede; +font-weight: bold; +} + +/** Form Review **/ +#machform_review_table tbody tr:hover +{ + background-color: #FFF7C0; +} +.alt{ + background: #efefef; +} +#machform_review_table td +{ + text-align: left; + border-bottom:1px solid #DEDEDE; + padding:5px 10px; +} \ No newline at end of file diff --git a/view.php b/view.php new file mode 100644 index 0000000..8994f3c --- /dev/null +++ b/view.php @@ -0,0 +1,92 @@ +top.location.replace('{$submit_result['form_redirect']}')"; + exit; + } + }else{ //redirect to review page + $ssl_suffix = get_ssl_suffix(); + + $_SESSION['review_id'] = $submit_result['review_id']; + header("Location: http{$ssl_suffix}://".$_SERVER['HTTP_HOST'].get_dirname($_SERVER['PHP_SELF'])."/confirm.php?id={$input_array['form_id']}"); + exit; + } + }else{ + $old_values = $submit_result['old_values']; + $custom_error = @$submit_result['custom_error']; + $error_elements = $submit_result['error_elements']; + + $markup = display_form($input_array['form_id'],$old_values,$error_elements,$custom_error); + } + }else{ //if password form submitted + if($submit_result['status'] === true){ //on success, display the form + $markup = display_form($input_array['form_id']); + }else{ + $custom_error = $submit_result['custom_error']; //error, display the pasword form again + $markup = display_form($input_array['form_id'],null,null,$custom_error); + } + } + }else{ + $form_id = (int) trim($_GET['id']); + if(empty($form_id)){ + die('ID required.'); + } + + //check for delete file option + //this is available for form with review enabled + if(!empty($_GET['delete_file']) && !empty($_SESSION['review_id'])){ + $element_id = (int) trim($_GET['delete_file']); + delete_review_file_entry($form_id,$_SESSION['review_id'],$element_id); + } + + if(!empty($_GET['done'])){ + $markup = display_success($form_id); + }else{ + $markup = display_form($form_id); + } + } + + header("Content-Type: text/html; charset=UTF-8"); + echo $markup; + +?> diff --git a/view_entry.php b/view_entry.php new file mode 100644 index 0000000..0d6af34 --- /dev/null +++ b/view_entry.php @@ -0,0 +1,221 @@ + $entry_id order by id asc limit 1"); + $row = do_fetch_result($result); + $newer_entry_id = $row['id']; + + //newest entry id + $result = do_query("select id from ap_form_{$form_id} order by id desc limit 1"); + $row = do_fetch_result($result); + $newest_entry_id = $row['id']; + + if(($entry_id == $newest_entry_id) && ($entry_id == $oldest_entry_id)){ + $nav_position = 'disabled'; + }elseif($entry_id == $newest_entry_id){ + $nav_position = 'newest'; + }elseif ($entry_id == $oldest_entry_id){ + $nav_position = 'oldest'; + }else{ + $nav_position = 'middle'; + } + + + $header_data =<< + + + + + + + + + +EOT; + + +?> + + + + +
    + +
    +

    Entries #

    +

    Viewing entry #

    +
    + + +
    +
    + + + + + > + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + +
    Entry Info 
    Date Created
    Date Updated
    IP Address
    +
    + +
    +
    + + " alt="Newest">  + " alt="Newer">  + + + +   +   + + + +" alt="Older">  + " alt="Oldest"> + + +   + + +
    +
    Entry Options
    +
    + +
    +
    + + +
    + \ No newline at end of file