diff --git a/common/code/extract.php b/common/code/extract.php index 8592f90b..c7e6d728 100644 --- a/common/code/extract.php +++ b/common/code/extract.php @@ -1,57 +1,73 @@ ')); - $text = substr($text,0,strpos($text,'')); - for ($i = 0; $i < 8; $i++) { - $text = preg_replace( - '@(.*)@Ssm', - '${2}', - $text ); - } - $text = str_replace('
','',$text); - $text = str_replace('','
',$text); - - #print htmlentities($text); - print $text; - } + $path_parts = array(); + preg_match($pattern, $vpath, $path_parts); + + $key = $path_parts[2]; + $file = ARCHIVE_FILE_PREFIX . $path_parts[1] . '/' . $path_parts[2]; + $archive = str_replace('\\','/', ARCHIVE_PREFIX . $path_parts[1] . '.zip'); + + return array($key,$file,$archive); +} + +function archive_file_extract($path_parts) +{ + $key = $path_parts[0]; + $file = $path_parts[1]; + $archive = $path_parts[2]; + + $type = null; + if (preg_match('/^doc\/html\/.*html$/',$key)) { $type = 'boost.book.html'; } + else if (preg_match('/^.*png$/',$key)) { $type = 'raw'; } + else { return null; } + + $unzip = UNZIP . ' -p "' . $archive . '" "' . $file . '"'; + $f_handle = popen($unzip,'rb'); + if ($type === 'raw') { + fpassthru($f_handle); + } + else { + $text = ''; + while ($f_handle && !feof($f_handle)) { + $text .= fread($f_handle,8*1024); + } + } + pclose($f_handle); + + if ($type === 'boost.book.html') { + $text = substr($text,strpos($text,'
')); + $text = substr($text,0,strpos($text,'')); + for ($i = 0; $i < 8; $i++) { + $text = preg_replace( + '@(.*)@Ssm', + '${2}', + $text ); + } + $text = str_replace('
','',$text); + $text = str_replace('
','
',$text); + + #print htmlentities($text); + print $text; + } } ?> diff --git a/common/code/webnotes.php b/common/code/webnotes.php new file mode 100644 index 00000000..035cccd5 --- /dev/null +++ b/common/code/webnotes.php @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/common/code/webnotes/about_page.php b/common/code/webnotes/about_page.php new file mode 100644 index 00000000..631d817a --- /dev/null +++ b/common/code/webnotes/about_page.php @@ -0,0 +1,28 @@ +Fore more information about phpWebnotes visit our website at http://webnotes.futureware.biz.

'; + + print_footer( __FILE__ ); + print_bottom_page( $g_bottom_page_inc ); + print_body_bottom(); + print_html_bottom(); +?> \ No newline at end of file diff --git a/common/code/webnotes/action.php b/common/code/webnotes/action.php new file mode 100644 index 00000000..0e19aed8 --- /dev/null +++ b/common/code/webnotes/action.php @@ -0,0 +1,89 @@ +'; + exit; + } + + # @@@@ add handling for confirm? + + # The access level check is done in the APIs + if ( isset( $f_note_id )) { + $t_note_info = note_get_info( note_where_id_equals( $f_note_id ) ); + if ( false === $t_note_info ) { + echo "note not found"; + exit; + } + + $t_page_info = page_get_info( page_where_id_equals( $t_note_info['page_id'] ) ); + if ( false === $t_page_info ) { + echo "page not found"; + exit; + } + $t_url = $t_page_info['url']; + + if ( 'accept' === $f_action ) { + note_accept( $f_note_id ); + } else if ( 'decline' === $f_action ) { + note_decline( $f_note_id ); + } else if ( 'archive' === $f_action ) { + note_archive( $f_note_id ); + } else if ( 'delete' === $f_action ) { + note_delete( $f_note_id ); + } else if ( 'pack' === $f_action ) { + # in this case id = 0 + note_pack_deleted(); + } else if ( 'queue' === $f_action ) { + note_pending( $f_note_id ); + } else if ( 'edit' === $f_action ) { + util_header_redirect( "$g_note_add_page?f_note_id=$f_note_id" ); + } + } + + # The access level check is done in the APIs + if ( isset( $f_page_id ) ) { + $c_page_id = stripslashes( urldecode( $f_page_id ) ); + if ( 'unindex' === $f_action ) { + page_delete( $c_page_id ); + } + if ( 'index' === $f_action ) { + page_add( $c_page_id ); + } + + $t_url = $HTTP_REFERER; + } + + if ( isset( $f_wait ) ) { + print_html_top(); + print_head_top(); + print_title( $g_window_title ); + print_css( $g_css_inc_file ); + print_head_bottom(); + print_body_top(); + print_header( $g_page_title ); + print_top_page( $g_top_page_inc ); + + print_admin_menu(); + + echo "
Operation Successful
[ Click here to proceed ]

"; + + print_footer( __FILE__ ); + print_bottom_page( $g_bottom_page_inc ); + print_body_bottom(); + print_html_bottom(); + } else { + util_header_redirect( $t_url ); + } +?> \ No newline at end of file diff --git a/common/code/webnotes/admin_change_password.php b/common/code/webnotes/admin_change_password.php new file mode 100644 index 00000000..67fa2ff1 --- /dev/null +++ b/common/code/webnotes/admin_change_password.php @@ -0,0 +1,94 @@ + +

Password changed successfully

+ +EOT; + } + } + + print_html_top(); + print_head_top(); + print_title( $g_window_title ); + print_css( $g_css_inc_file ); + print_head_bottom(); + print_body_top(); + print_header( $g_page_title ); + print_top_page( $g_top_page_inc ); + + print_admin_menu(); + + if ( isset( $pass_change ) && ( $pass_change == 1 ) ) { + echo '
Password changed.
'; + } else { + echo << +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ $s_change_password_title +
$s_username:$v_username
Current Password:
$s_password:
$s_verify_password:
+ + +EOT; + } + + print_bottom_page( $g_bottom_page_inc ); + print_footer( __FILE__ ); + print_body_bottom(); + print_html_bottom(); +?> \ No newline at end of file diff --git a/common/code/webnotes/admin_index_files.php b/common/code/webnotes/admin_index_files.php new file mode 100644 index 00000000..e7a19685 --- /dev/null +++ b/common/code/webnotes/admin_index_files.php @@ -0,0 +1,86 @@ + +
+ + + + + + + + + + + + + + + + + +
+ +
+ +
+ +
+ +
+ + +
+
+ + \ No newline at end of file diff --git a/common/code/webnotes/admin_manage_notes.php b/common/code/webnotes/admin_manage_notes.php new file mode 100644 index 00000000..368f60df --- /dev/null +++ b/common/code/webnotes/admin_manage_notes.php @@ -0,0 +1,86 @@ +Following are the pages that have notes pending approval:

+ + \n +EOT; + $count = 0; + while ( $row = db_fetch_array( $result ) ) { + $color = util_alternate_colors( $count++ ); + extract( $row, EXTR_PREFIX_ALL, 'v' ); + echo "\n"; + } + + $t_now = date( config_get( 'date_format' ) ); + echo << +

There are $count page(s) to be moderated.

\n +
+
+

Following are all the pages that use phpWebNotes:

+

Time now is $t_now

+
PageURLPending Notes
$v_page$v_url$v_notes_count
+ \n +EOT; + + $count = 0; + $t_total_visits = 0; + $t_total_notes = 0; + $pages = page_get_array ( page_where_url_exists(), 'last_updated DESC' ); + foreach( $pages as $page ) { + extract( $page, EXTR_PREFIX_ALL, 'v' ); + $t_number = page_notes_count( $v_id ); + $t_total_notes += $t_number; + $t_visits = page_visits_count( $v_id ); + $t_total_visits += $t_visits; + $t_last_updated = date( config_get( 'date_format' ), $v_last_updated ); + + $color = util_alternate_colors( $count++ ); + echo "\n"; + } + + echo << +

There are $count page(s) that are indexed, with $t_total_notes note(s) and $t_total_visits visit(s).

\n +EOT; + + print_footer( __FILE__ ); + print_bottom_page( $g_bottom_page_inc ); + print_body_bottom(); + print_html_bottom(); +?> diff --git a/common/code/webnotes/admin_manage_users.php b/common/code/webnotes/admin_manage_users.php new file mode 100644 index 00000000..2d5efcdb --- /dev/null +++ b/common/code/webnotes/admin_manage_users.php @@ -0,0 +1,51 @@ +'; + echo '
'; + $i = 0; + foreach ( $t_users_array as $user ) { + extract( $user, EXTR_PREFIX_ALL, 'v' ); + $v_enabled = $v_enabled ? 'x' : ' '; + $v_protected = $v_protected ? 'x' : ' '; + $t_class = util_alternate_class( $i++ ); + $t_access_level = enum_get_element( 'access_levels', $v_access_level ); + echo ""; + } + echo '
Page# of Notes# of hitsLast UpdatedURL
$v_page$t_number$t_visits$t_last_updated$v_url
UsernameEmailAccess LevelEnabledProtected
$v_username$v_email$t_access_level$v_enabled$v_protected
'; + echo '
'; + echo link_create( $g_admin_manage_users_add_page, 'Add User' ); + + # @@@ LOCALIZE + + print_footer( __FILE__ ); + print_bottom_page( $g_bottom_page_inc ); + print_body_bottom(); + print_html_bottom(); +?> \ No newline at end of file diff --git a/common/code/webnotes/admin_manage_users_add.php b/common/code/webnotes/admin_manage_users_add.php new file mode 100644 index 00000000..226e239c --- /dev/null +++ b/common/code/webnotes/admin_manage_users_add.php @@ -0,0 +1,42 @@ + \ No newline at end of file diff --git a/common/code/webnotes/admin_manage_users_add_page.php b/common/code/webnotes/admin_manage_users_add_page.php new file mode 100644 index 00000000..d847fd82 --- /dev/null +++ b/common/code/webnotes/admin_manage_users_add_page.php @@ -0,0 +1,111 @@ + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Add User +
+ Username + + +
+ Email + + +
+ Password + + +
+ Password Confirm + + +
+ Access Level + + +
+ Enabled + + +
+ Protected + + +
+ +
+
+
+
+ \ No newline at end of file diff --git a/common/code/webnotes/admin_manage_users_delete.php b/common/code/webnotes/admin_manage_users_delete.php new file mode 100644 index 00000000..2e866cc2 --- /dev/null +++ b/common/code/webnotes/admin_manage_users_delete.php @@ -0,0 +1,21 @@ + \ No newline at end of file diff --git a/common/code/webnotes/admin_manage_users_delete_page.php b/common/code/webnotes/admin_manage_users_delete_page.php new file mode 100644 index 00000000..66400e4c --- /dev/null +++ b/common/code/webnotes/admin_manage_users_delete_page.php @@ -0,0 +1,45 @@ + +
+Are you sure you want to delete user ''?
+
+
+ + +
+
+ \ No newline at end of file diff --git a/common/code/webnotes/admin_manage_users_edit.php b/common/code/webnotes/admin_manage_users_edit.php new file mode 100644 index 00000000..e279e9f3 --- /dev/null +++ b/common/code/webnotes/admin_manage_users_edit.php @@ -0,0 +1,122 @@ + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Update User +
+ Username + + +
+ Email + + +
+ Password + + +
+ Password Confirm + + +
+ Access Level + + +
+ Enabled + + /> +
+ Protected + + /> +
+ + +
+
+
+
+ + +
+ +
+ \ No newline at end of file diff --git a/common/code/webnotes/admin_manage_users_update.php b/common/code/webnotes/admin_manage_users_update.php new file mode 100644 index 00000000..ed3b90e6 --- /dev/null +++ b/common/code/webnotes/admin_manage_users_update.php @@ -0,0 +1,42 @@ + \ No newline at end of file diff --git a/common/code/webnotes/admin_view_queue.php b/common/code/webnotes/admin_view_queue.php new file mode 100644 index 00000000..891ef087 --- /dev/null +++ b/common/code/webnotes/admin_view_queue.php @@ -0,0 +1,135 @@ + +
+ + + + + + + + 0 ) { ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ [] +
+ + + +
+ + + +
+ + + +
+ + + +
+ +
+ +
+ + + + + + + + + + + +
+ +
+ +
+
+
+ + \ No newline at end of file diff --git a/common/code/webnotes/core/access_api.php b/common/code/webnotes/core/access_api.php new file mode 100644 index 00000000..1e75f640 --- /dev/null +++ b/common/code/webnotes/core/access_api.php @@ -0,0 +1,221 @@ +'; + echo '
Access Denied

'; + print_bracket_link( $p_url, lang_get( 'proceed' ) ); + print '
'; + print_bottom_page( config_get( 'bottom_page_inc' ) ); + print_footer( __FILE__ ); + print_body_bottom(); + print_html_bottom(); + exit; + } + # -------------------- + # Check to see that the unique identifier is really unique + function check_cookie_string_duplicate( $p_cookie_string ) { + global $g_phpWN_user_table; + + $c_cookie_string = addslashes($p_cookie_string); + + $query = "SELECT COUNT(*) + FROM $g_phpWN_user_table + WHERE cookie_string='$c_cookie_string'"; + $result = db_query( $query ); + $t_count = db_result( $result, 0, 0 ); + return ( $t_count > 0 ); + } + # -------------------- + # This string is used to use as the login identified for the web cookie + # It is not guarranteed to be unique and should be checked + # The string returned should be 64 characters in length + function generate_cookie_string() { + $t_val = mt_rand( 0, mt_getrandmax() ) + mt_rand( 0, mt_getrandmax() ); + $t_val = md5( $t_val ) . md5( time() ); + return substr( $t_val, 0, 64 ); + } + # -------------------- + # The string returned should be 64 characters in length + function create_cookie_string() { + $t_cookie_string = generate_cookie_string(); + while ( check_cookie_string_duplicate( $t_cookie_string ) ) { + $t_cookie_string = generate_cookie_string(); + } + return $t_cookie_string; + } + ### -------------------- + function access_encrypt_password( $p_password ) { + switch( config_get( 'auth_type' ) ) { + case AUTH_PLAIN: + $t_password = $p_password; + break; + + case AUTH_CRYPT: + $salt = substr( $p_password, 0, 2 ); + $t_password = crypt( $p_password, $salt ); + break; + + case AUTH_MD5: + $t_password = md5( $p_password ); + break; + + default: + # @@@@ Replace with proper error + echo "Invalid authentication type"; + exit; + } // switchconfig_get()) { + + return substr( $t_password, 0, 32 ); + } + ### -------------------- + function password_match( $p_test_password, $p_password ) { + return ( access_encrypt_password( $p_test_password ) === $p_password ); + } + ### -------------------- + function access_verify_login( $p_username, $p_password ) { + global $g_phpWN_user_table; + + $c_username = db_prepare_string( $p_username ); + + ### get user info + $query = "SELECT * + FROM $g_phpWN_user_table + WHERE username='$c_username' AND enabled=1"; + $result = db_query( $query ); + $row = db_fetch_array( $result ); + + if ( $row ) { + extract( $row, EXTR_PREFIX_ALL, 'v' ); + } else { + ### invalid login, retry + return (false); + } + + return ( password_match( $p_password, $v_password ) ); + } + ### -------------------- + function create_random_password( $p_email ) { + mt_srand( time() ); + $t_val = mt_rand( 0, mt_getrandmax() ) + mt_rand( 0, mt_getrandmax() ); + return substr( crypt( md5( $p_email.$t_val ) ), 0, 12 ); + } + ### -------------------- + function is_moderator() { + global $g_string_cookie_val, $g_phpWN_user_table; + + $query = "SELECT COUNT(*) + FROM $g_phpWN_user_table + WHERE cookie_string='$g_string_cookie_val'"; + $result = db_query( $query ); + $count = db_result( $result, 0, 0 ); + + return $count; + } + ### -------------------- + function access_is_logged_in() { + global $g_string_cookie_val; + + ### if logged in + if ( isset( $g_string_cookie_val ) ) { + return ( !empty( $g_string_cookie_val ) ); + } + + ### not logged in + return false; + } + ### -------------------- + ### checks to see that a user is logged in + ### if the user is and the account is enabled then let them pass + ### otherwise redirect them to the login page + function login_cookie_check( $p_redirect_url = '' ) { + global $g_string_cookie_val, $g_login_page, $g_logout; + + ### if logged in + if ( isset( $g_string_cookie_val ) ) { + if ( empty( $g_string_cookie_val ) ) { + util_header_redirect( $g_login_page ); + } + + ### go to redirect + if ( !empty( $p_redirect_url ) ) { + util_header_redirect( $p_redirect_url ); + } + ### continue with current page + else { + return; + } + } + ### not logged in + else { + util_header_redirect( $g_login_page ); + } + } + ### -------------------- + # Make sure that the specified action can be done by the logged-in user + # true: allowed + # false: not allowed + # if for this action a threshold is defined, it will be used. + # if the threshold is set to NOBODY, the specified set of user types will be used. + # if action is unknown, then it will return false + function access_check_action( $p_action ) { + global $g_string_cookie_val, $g_access_levels, $g_access_sets; + + if ( !isset( $g_access_levels[$p_action] ) ) { + return false; + } + + if ( empty( $g_string_cookie_val ) ) { + $t_access_level = ANONYMOUS; + } else { + $t_user = user_get_info( user_where_current() ); + if ( false === $t_user ) { + return false; + } + + $t_access_level = $t_user['access_level']; + } + + if ( NOBODY !== $g_access_levels[$p_action] ) { + return ( $t_access_level >= $g_access_levels[$p_action] ); + } + + if ( !isset( $g_access_sets[$p_action] ) ) { + return false; + } + + return ( in_array( $t_access_level, $g_access_sets[$p_action] ) ); + } + ### -------------------- + function access_ensure_check_action( $p_action, $p_url = null ) { + if ( access_check_action( $p_action ) ) { + return; + } + + access_denied( $p_url ); + } +?> \ No newline at end of file diff --git a/common/code/webnotes/core/api.php b/common/code/webnotes/core/api.php new file mode 100644 index 00000000..85ed906d --- /dev/null +++ b/common/code/webnotes/core/api.php @@ -0,0 +1,90 @@ + \ No newline at end of file diff --git a/common/code/webnotes/core/class.phpmailer.php b/common/code/webnotes/core/class.phpmailer.php new file mode 100644 index 00000000..b262ba93 --- /dev/null +++ b/common/code/webnotes/core/class.phpmailer.php @@ -0,0 +1,1636 @@ + +// +// License: LGPL, see LICENSE +//////////////////////////////////////////////////// + +/** + * phpmailer - PHP email transport class + * @author Brent R. Matzelle + */ +class phpmailer +{ + ///////////////////////////////////////////////// + // PUBLIC VARIABLES + ///////////////////////////////////////////////// + + /** + * Email priority (1 = High, 3 = Normal, 5 = low). + * @access public + * @var int + */ + var $Priority = 3; + + /** + * Sets the CharSet of the message. + * @access public + * @var string + */ + var $CharSet = "iso-8859-1"; + + /** + * Sets the Content-type of the message. + * @access public + * @var string + */ + var $ContentType = "text/plain"; + + /** + * Sets the Encoding of the message. Options for this are "8bit", + * "7bit", "binary", "base64", and "quoted-printable". + * @access public + * @var string + */ + var $Encoding = "8bit"; + + /** + * Holds the most recent mailer error message. + * @access public + * @var string + */ + var $ErrorInfo = ""; + + /** + * Sets the From email address for the message. + * @access public + * @var string + */ + var $From = "root@localhost"; + + /** + * Sets the From name of the message. + * @access public + * @var string + */ + var $FromName = "Root User"; + + /** + * Sets the Sender email of the message. If not empty, will be sent via -f to sendmail + * or as 'MAIL FROM' in smtp mode. + * @access public + * @var string + */ + var $Sender = ""; + + /** + * Sets the Subject of the message. + * @access public + * @var string + */ + var $Subject = ""; + + /** + * Sets the Body of the message. This can be either an HTML or text body. + * If HTML then run IsHTML(true). + * @access public + * @var string + */ + var $Body = ""; + + /** + * Sets the text-only body of the message. This automatically sets the + * email to multipart/alternative. This body can be read by mail + * clients that do not have HTML email capability such as mutt. Clients + * that can read HTML will view the normal Body. + * @access public + * @var string + */ + var $AltBody = ""; + + /** + * Sets word wrapping on the body of the message to a given number of + * characters. + * @access public + * @var int + */ + var $WordWrap = 0; + + /** + * Method to send mail: ("mail", "sendmail", or "smtp"). + * @access public + * @var string + */ + var $Mailer = "mail"; + + /** + * Sets the path of the sendmail program. + * @access public + * @var string + */ + var $Sendmail = "/usr/sbin/sendmail"; + + /** + * Turns Microsoft mail client headers on and off. Useful mostly + * for older clients. + * @access public + * @var bool + */ + var $UseMSMailHeaders = false; + + /** + * Path to phpmailer plugins. This is now only useful if the SMTP class + * is in a different directory than the PHP include path. + * @access public + * @var string + */ + var $PluginDir = ""; + + /** + * Holds phpmailer version. + * @access public + * @var string + */ + var $Version = "1.62"; + + /** + * Sets the email address that a reading confirmation will be sent. + * @access public + * @var string + */ + var $ConfirmReadingTo = ""; + + /** + * Sets the line endings of the message. + * @access public + * @var string + */ + var $LE = "\n"; + + + ///////////////////////////////////////////////// + // SMTP VARIABLES + ///////////////////////////////////////////////// + + /** + * Sets the SMTP hosts. All hosts must be separated by a + * semicolon. You can also specify a different port + * for each host by using this format: [hostname:port] + * (e.g. "smtp1.domain.com:25;smtp2.domain.com"). + * Hosts will be tried in order. + * @access public + * @var string + */ + var $Host = "localhost"; + + /** + * Sets the default SMTP server port. + * @access public + * @var int + */ + var $Port = 25; + + /** + * Sets the SMTP HELO of the message. + * @access public + * @var string + */ + var $Helo = "localhost.localdomain"; + + /** + * Sets SMTP authentication. Utilizes the Username and Password variables. + * @access public + * @var bool + */ + var $SMTPAuth = false; + + /** + * Sets SMTP username. + * @access public + * @var string + */ + var $Username = ""; + + /** + * Sets SMTP password. + * @access public + * @var string + */ + var $Password = ""; + + /** + * Sets the SMTP server timeout in seconds. This function will not + * work with the win32 version. + * @access public + * @var int + */ + var $Timeout = 10; + + /** + * Sets SMTP class debugging on or off. + * @access public + * @var bool + */ + var $SMTPDebug = false; + + + ///////////////////////////////////////////////// + // PRIVATE VARIABLES + ///////////////////////////////////////////////// + + /** + * Holds all "To" addresses. + * @access private + * @var array + */ + var $to = array(); + + /** + * Holds all "CC" addresses. + * @access private + * @var array + */ + var $cc = array(); + + /** + * Holds all "BCC" addresses. + * @access private + * @var array + */ + var $bcc = array(); + + /** + * Holds all "Reply-To" addresses. + * @var array + */ + var $ReplyTo = array(); + + /** + * Holds all string and binary attachments. + * @access private + * @var array + */ + var $attachment = array(); + + /** + * Holds all custom headers. + * @var array + */ + var $CustomHeader = array(); + + /** + * Holds the type of the message. + * @var string + */ + var $message_type = ""; + + /** + * Holds the message boundaries. + * @access private + * @var string array + */ + var $boundary = array(); + + ///////////////////////////////////////////////// + // VARIABLE METHODS + ///////////////////////////////////////////////// + + /** + * Sets message type to HTML. Returns void. + * @access public + * @return void + */ + function IsHTML($bool) { + if($bool == true) + $this->ContentType = "text/html"; + else + $this->ContentType = "text/plain"; + } + + /** + * Sets Mailer to send message using SMTP. + * Returns void. + * @access public + * @return void + */ + function IsSMTP() { + $this->Mailer = "smtp"; + } + + /** + * Sets Mailer to send message using PHP mail() function. + * Returns void. + * @access public + * @return void + */ + function IsMail() { + $this->Mailer = "mail"; + } + + /** + * Sets Mailer to send message using the $Sendmail program. + * Returns void. + * @access public + * @return void + */ + function IsSendmail() { + $this->Mailer = "sendmail"; + } + + /** + * Sets Mailer to send message using the qmail MTA. Returns void. + * @access public + * @return void + */ + function IsQmail() { + //$this->Sendmail = "/var/qmail/bin/qmail-inject"; + $this->Sendmail = "/var/qmail/bin/sendmail"; + $this->Mailer = "sendmail"; + } + + + ///////////////////////////////////////////////// + // RECIPIENT METHODS + ///////////////////////////////////////////////// + + /** + * Adds a "To" address. Returns void. + * @access public + * @return void + */ + function AddAddress($address, $name = "") { + $cur = count($this->to); + $this->to[$cur][0] = trim($address); + $this->to[$cur][1] = $name; + } + + /** + * Adds a "Cc" address. Note: this function works + * with the SMTP mailer on win32, not with the "mail" + * mailer. This is a PHP bug that has been submitted + * on http://bugs.php.net. The *NIX version of PHP + * functions correctly. Returns void. + * @access public + * @return void + */ + function AddCC($address, $name = "") { + $cur = count($this->cc); + $this->cc[$cur][0] = trim($address); + $this->cc[$cur][1] = $name; + } + + /** + * Adds a "Bcc" address. Note: this function works + * with the SMTP mailer on win32, not with the "mail" + * mailer. This is a PHP bug that has been submitted + * on http://bugs.php.net. The *NIX version of PHP + * functions correctly. + * Returns void. + * @access public + * @return void + */ + function AddBCC($address, $name = "") { + $cur = count($this->bcc); + $this->bcc[$cur][0] = trim($address); + $this->bcc[$cur][1] = $name; + } + + /** + * Adds a "Reply-to" address. Returns void. + * @access public + * @return void + */ + function AddReplyTo($address, $name = "") { + $cur = count($this->ReplyTo); + $this->ReplyTo[$cur][0] = trim($address); + $this->ReplyTo[$cur][1] = $name; + } + + + ///////////////////////////////////////////////// + // MAIL SENDING METHODS + ///////////////////////////////////////////////// + + /** + * Creates message and assigns Mailer. If the message is + * not sent successfully then it returns false. Use the ErrorInfo + * variable to view description of the error. Returns bool. + * @access public + * @return bool + */ + function Send() { + $header = ""; + $body = ""; + + if((count($this->to) + count($this->cc) + count($this->bcc)) < 1) + { + $this->error_handler("You must provide at least one recipient email address"); + return false; + } + + // Set whether the message is multipart/alternative + if(!empty($this->AltBody)) + $this->ContentType = "multipart/alternative"; + + // Attach sender information & date + $header = $this->received(); + $header .= sprintf("Date: %s%s", $this->rfc_date(), $this->LE); + $header .= $this->create_header(); + + if(!$body = $this->create_body()) + return false; + + //echo "
".$header . $body . "
"; // debugging + + // Choose the mailer + if($this->Mailer == "sendmail") + { + if(!$this->sendmail_send($header, $body)) + return false; + } + elseif($this->Mailer == "mail") + { + if(!$this->mail_send($header, $body)) + return false; + } + elseif($this->Mailer == "smtp") + { + if(!$this->smtp_send($header, $body)) + return false; + } + else + { + $this->error_handler(sprintf("%s mailer is not supported", $this->Mailer)); + return false; + } + + return true; + } + + /** + * Sends mail message to an assigned queue directory. Has an optional + * sendTime argument. This is used when the user wants the + * message to be sent from the queue at a predetermined time. + * The data must be a valid timestamp like that returned from + * the time() or strtotime() functions. Returns false on failure + * or the message file name if success. + * @access public + * @return string + */ + function SendToQueue($queue_path, $send_time = 0) { + $message = array(); + $header = ""; + $body = ""; + + // If invalid or empty just set to the current time + if($send_time == 0) + $send_time = time(); + + if(!is_dir($queue_path)) + { + $this->error_handler("The supplied queue directory does not exist"); + return false; + } + + if((count($this->to) + count($this->cc) + count($this->bcc)) < 1) + { + $this->error_handler("You must provide at least one recipient email address"); + return false; + } + + // Set whether the message is multipart/alternative + if(!empty($this->AltBody)) + $this->ContentType = "multipart/alternative"; + + $header = $this->create_header(); + if(!$body = $this->create_body()) + return false; + + // Seed randomizer + mt_srand(time()); + $msg_id = md5(uniqid(mt_rand())); + + $fp = @fopen($queue_path . $msg_id . ".pqm", "wb"); + if(!$fp) + { + $this->error_handler(sprintf("Could not write to %s directory", $queue_path)); + return false; + } + + $message[] = sprintf("----START PQM HEADER----%s", $this->LE); + $message[] = sprintf("SendTime: %s%s", $send_time, $this->LE); + $message[] = sprintf("Mailer: %s%s", $this->Mailer, $this->LE); + + // Choose the mailer + if($this->Mailer == "sendmail") + { + $message[] = sprintf("Sendmail: %s%s", $this->Sendmail, $this->LE); + $message[] = sprintf("Sender: %s%s", $this->Sender, $this->LE); + } + elseif($this->Mailer == "mail") + { + $message[] = sprintf("Sender: %s%s", $this->Sender, $this->LE); + $message[] = sprintf("Subject: %s%s", $this->Subject, $this->LE); + $message[] = sprintf("to: %s%s", $this->addr_list($this->to), $this->LE); + } + elseif($this->Mailer == "smtp") + { + $message[] = sprintf("Host: %s%s", $this->Host, $this->LE); + $message[] = sprintf("Port: %d%s", $this->Port, $this->LE); + $message[] = sprintf("Helo: %s%s", $this->Helo, $this->LE); + $message[] = sprintf("Timeout: %d%s", $this->Timeout, $this->LE); + + if($this->SMTPAuth) + $auth_no = 1; + else + $auth_no = 0; + $message[] = sprintf("SMTPAuth: %d%s", $auth_no, $this->LE); + $message[] = sprintf("Username: %s%s", $this->Username, $this->LE); + $message[] = sprintf("Password: %s%s", $this->Password, $this->LE); + $message[] = sprintf("From: %s%s", $this->From, $this->LE); + + $message[] = sprintf("to: %s%s", $this->addr_list($this->to), $this->LE); + $message[] = sprintf("cc: %s%s", $this->addr_list($this->cc), $this->LE); + $message[] = sprintf("bcc: %s%s", $this->addr_list($this->bcc), $this->LE); + } + else + { + $this->error_handler(sprintf("%s mailer is not supported", $this->Mailer)); + return false; + } + + $message[] = sprintf("----END PQM HEADER----%s", $this->LE); // end of pqm header + $message[] = $header; + $message[] = $body; + + if(fwrite($fp, join("", $message)) == -1) + { + $this->error_handler("Write to file failed"); + return false; + } + fclose($fp); + + return ($msg_id . ".pqm"); + } + + /** + * Sends mail using the $Sendmail program. Returns bool. + * @access private + * @return bool + */ + function sendmail_send($header, $body) { + if ($this->Sender != "") + $sendmail = sprintf("%s -oi -f %s -t", $this->Sendmail, $this->Sender); + else + $sendmail = sprintf("%s -oi -t", $this->Sendmail); + + if(!@$mail = popen($sendmail, "w")) + { + $this->error_handler(sprintf("Could not execute %s", $this->Sendmail)); + return false; + } + + fputs($mail, $header); + fputs($mail, $body); + + $result = pclose($mail) >> 8 & 0xFF; + if($result != 0) + { + $this->error_handler(sprintf("Could not execute %s", $this->Sendmail)); + return false; + } + + return true; + } + + /** + * Sends mail using the PHP mail() function. Returns bool. + * @access private + * @return bool + */ + function mail_send($header, $body) { + //$to = substr($this->addr_append("To", $this->to), 4, -2); + + // Cannot add Bcc's to the $to + $to = $this->to[0][0]; // no extra comma + for($i = 1; $i < count($this->to); $i++) + $to .= sprintf(",%s", $this->to[$i][0]); + + if ($this->Sender != "" && PHP_VERSION >= "4.0") + { + $old_from = ini_get("sendmail_from"); + ini_set("sendmail_from", $this->Sender); + } + + if ($this->Sender != "" && PHP_VERSION >= "4.0.5") + { + // The fifth parameter to mail is only available in PHP >= 4.0.5 + $params = sprintf("-oi -f %s", $this->Sender); + $rt = @mail($to, $this->Subject, $body, $header, $params); + } + else + { + $rt = @mail($to, $this->Subject, $body, $header); + } + + if (isset($old_from)) + ini_set("sendmail_from", $old_from); + + if(!$rt) + { + $this->error_handler("Could not instantiate mail()"); + return false; + } + + return true; + } + + /** + * Sends mail via SMTP using PhpSMTP (Author: + * Chris Ryan). Returns bool. Returns false if there is a + * bad MAIL FROM, RCPT, or DATA input. + * @access private + * @return bool + */ + function smtp_send($header, $body) { + // Include SMTP class code, but not twice + include_once($this->PluginDir . "class.smtp.php"); + + $smtp = new SMTP; + + $smtp->do_debug = $this->SMTPDebug; + + // Try to connect to all SMTP servers + $hosts = explode(";", $this->Host); + $index = 0; + $connection = false; + $smtp_from = ""; + $bad_rcpt = array(); + $e = ""; + + // Retry while there is no connection + while($index < count($hosts) && $connection == false) + { + if(strstr($hosts[$index], ":")) + list($host, $port) = explode(":", $hosts[$index]); + else + { + $host = $hosts[$index]; + $port = $this->Port; + } + + if($smtp->Connect($host, $port, $this->Timeout)) + $connection = true; + //printf("%s host could not connect
", $hosts[$index]); //debug only + $index++; + } + if(!$connection) + { + $this->error_handler("SMTP Error: could not connect to SMTP host server(s)"); + return false; + } + + // Must perform HELO before authentication + $smtp->Hello($this->Helo); + + // If user requests SMTP authentication + if($this->SMTPAuth) + { + if(!$smtp->Authenticate($this->Username, $this->Password)) + { + $this->error_handler("SMTP Error: Could not authenticate"); + return false; + } + } + + if ($this->Sender == "") + $smtp_from = $this->From; + else + $smtp_from = $this->Sender; + + if(!$smtp->Mail(sprintf("<%s>", $smtp_from))) + { + $e = sprintf("SMTP Error: From address [%s] failed", $smtp_from); + $this->error_handler($e); + return false; + } + + // Attempt to send attach all recipients + for($i = 0; $i < count($this->to); $i++) + { + if(!$smtp->Recipient(sprintf("<%s>", $this->to[$i][0]))) + $bad_rcpt[] = $this->to[$i][0]; + } + for($i = 0; $i < count($this->cc); $i++) + { + if(!$smtp->Recipient(sprintf("<%s>", $this->cc[$i][0]))) + $bad_rcpt[] = $this->cc[$i][0]; + } + for($i = 0; $i < count($this->bcc); $i++) + { + if(!$smtp->Recipient(sprintf("<%s>", $this->bcc[$i][0]))) + $bad_rcpt[] = $this->bcc[$i][0]; + } + + // Create error message + if(count($bad_rcpt) > 0) + { + for($i = 0; $i < count($bad_rcpt); $i++) + { + if($i != 0) + $e .= ", "; + $e .= $bad_rcpt[$i]; + } + $e = sprintf("SMTP Error: The following recipients failed [%s]", $e); + $this->error_handler($e); + + return false; + } + + + if(!$smtp->Data(sprintf("%s%s", $header, $body))) + { + $this->error_handler("SMTP Error: Data not accepted"); + return false; + } + $smtp->Quit(); + + return true; + } + + + ///////////////////////////////////////////////// + // MESSAGE CREATION METHODS + ///////////////////////////////////////////////// + + /** + * Creates recipient headers. Returns string. + * @access private + * @return string + */ + function addr_append($type, $addr) { + $addr_str = $type . ": "; + $addr_str .= $this->addr_format($addr[0]); + if(count($addr) > 1) + { + for($i = 1; $i < count($addr); $i++) + { + $addr_str .= sprintf(", %s", $this->addr_format($addr[$i])); + } + $addr_str .= $this->LE; + } + else + $addr_str .= $this->LE; + + return($addr_str); + } + + /** + * Creates a semicolon delimited list for use in pqm files. + * @access private + * @return string + */ + function addr_list($list_array) { + $addr_list = ""; + for($i = 0; $i < count($list_array); $i++) + { + if($i > 0) + $addr_list .= ";"; + $addr_list .= $list_array[$i][0]; + } + + return $addr_list; + } + + /** + * Formats an address correctly. + * @access private + * @return string + */ + function addr_format($addr) { + if(empty($addr[1])) + $formatted = $addr[0]; + else + $formatted = sprintf('"%s" <%s>', addslashes($addr[1]), $addr[0]); + + return $formatted; + } + + /** + * Wraps message for use with mailers that do not + * automatically perform wrapping and for quoted-printable. + * Original written by philippe. Returns string. + * @access private + * @return string + */ + function word_wrap($message, $length, $qp_mode = false) { + if ($qp_mode) + $soft_break = sprintf(" =%s", $this->LE); + else + $soft_break = $this->LE; + + $message = $this->fix_eol($message); + if (substr($message, -1) == $this->LE) + $message = substr($message, 0, -1); + + $line = explode($this->LE, $message); + $message = ""; + for ($i=0 ;$i < count($line); $i++) + { + $line_part = explode(" ", $line[$i]); + $buf = ""; + for ($e = 0; $e $length)) + { + $space_left = $length - strlen($buf) - 1; + if ($e != 0) + { + if ($space_left > 20) + { + $len = $space_left; + if (substr($word, $len - 1, 1) == "=") + $len--; + elseif (substr($word, $len - 2, 1) == "=") + $len -= 2; + $part = substr($word, 0, $len); + $word = substr($word, $len); + $buf .= " " . $part; + $message .= $buf . sprintf("=%s", $this->LE); + } + else + { + $message .= $buf . $soft_break; + } + $buf = ""; + } + while (strlen($word) > 0) + { + $len = $length; + if (substr($word, $len - 1, 1) == "=") + $len--; + elseif (substr($word, $len - 2, 1) == "=") + $len -= 2; + $part = substr($word, 0, $len); + $word = substr($word, $len); + + if (strlen($word) > 0) + $message .= $part . sprintf("=%s", $this->LE); + else + $buf = $part; + } + } + else + { + $buf_o = $buf; + if ($e == 0) + $buf .= $word; + else + $buf .= " " . $word; + if (strlen($buf) > $length and $buf_o != "") + { + $message .= $buf_o . $soft_break; + $buf = $word; + } + } + } + $message .= $buf . $this->LE; + } + + return ($message); + } + + /** + * Set the body wrapping. + * @access private + * @return void + */ + function SetWordWrap() { + if($this->WordWrap < 1) + return; + + switch($this->message_type) + { + case "alt": + case "alt_attachment": + $this->AltBody = $this->word_wrap($this->AltBody, $this->WordWrap); + break; + default: + $this->Body = $this->word_wrap($this->Body, $this->WordWrap); + break; + } + } + + /** + * Assembles message header. Returns a string if successful + * or false if unsuccessful. + * @access private + * @return string + */ + function create_header() { + $header = array(); + + // Set the boundaries + $uniq_id = md5(uniqid(time())); + $this->boundary[1] = "b1_" . $uniq_id; + $this->boundary[2] = "b2_" . $uniq_id; + + // To be created automatically by mail() + if(($this->Mailer != "mail") && (count($this->to) > 0)) + $header[] = $this->addr_append("To", $this->to); + + $header[] = sprintf("From: \"%s\" <%s>%s", addslashes($this->FromName), + trim($this->From), $this->LE); + if(count($this->cc) > 0) + $header[] = $this->addr_append("Cc", $this->cc); + + // sendmail and mail() extract Bcc from the header before sending + if((($this->Mailer == "sendmail") || ($this->Mailer == "mail")) && (count($this->bcc) > 0)) + $header[] = $this->addr_append("Bcc", $this->bcc); + + if(count($this->ReplyTo) > 0) + $header[] = $this->addr_append("Reply-to", $this->ReplyTo); + + // mail() sets the subject itself + if($this->Mailer != "mail") + $header[] = sprintf("Subject: %s%s", trim($this->Subject), $this->LE); + + $header[] = sprintf("X-Priority: %d%s", $this->Priority, $this->LE); + $header[] = sprintf("X-Mailer: phpmailer [version %s]%s", $this->Version, $this->LE); + $header[] = sprintf("Return-Path: %s%s", trim($this->From), $this->LE); + + if($this->ConfirmReadingTo != "") + $header[] = sprintf("Disposition-Notification-To: <%s>%s", + trim($this->ConfirmReadingTo), $this->LE); + + // Add custom headers + for($index = 0; $index < count($this->CustomHeader); $index++) + $header[] = sprintf("%s%s", $this->CustomHeader[$index], $this->LE); + + if($this->UseMSMailHeaders) + $header[] = $this->AddMSMailHeaders(); + + $header[] = sprintf("MIME-Version: 1.0%s", $this->LE); + + // Determine what type of message this is + if(count($this->attachment) < 1 && strlen($this->AltBody) < 1) + $this->message_type = "plain"; + else + { + if(count($this->attachment) > 0) + $this->message_type = "attachments"; + if(strlen($this->AltBody) > 0 && count($this->attachment) < 1) + $this->message_type = "alt"; + if(strlen($this->AltBody) > 0 && count($this->attachment) > 0) + $this->message_type = "alt_attachments"; + } + + switch($this->message_type) + { + case "plain": + $header[] = sprintf("Content-Transfer-Encoding: %s%s", + $this->Encoding, $this->LE); + $header[] = sprintf("Content-Type: %s; charset = \"%s\"", + $this->ContentType, $this->CharSet); + break; + case "attachments": + case "alt_attachments": + if($this->EmbeddedImageCount() > 0) + { + $header[] = sprintf("Content-Type: %s;%s\ttype=\"text/html\";%s\tboundary=\"%s\"%s", + "multipart/related", $this->LE, $this->LE, + $this->boundary[1], $this->LE); + } + else + { + $header[] = sprintf("Content-Type: %s;%s", + "multipart/mixed", $this->LE); + $header[] = sprintf("\tboundary=\"%s\"%s", $this->boundary[1], $this->LE); + } + break; + case "alt": + $header[] = sprintf("Content-Type: %s;%s", + "multipart/alternative", $this->LE); + $header[] = sprintf("\tboundary=\"%s\"%s", $this->boundary[1], $this->LE); + break; + } + + // No additional lines when using mail() function + if($this->Mailer != "mail") + $header[] = $this->LE.$this->LE; + + return(join("", $header)); + } + + /** + * Assembles the message body. Returns a string if successful + * or false if unsuccessful. + * @access private + * @return string + */ + function create_body() { + $body = array(); + + $this->SetWordWrap(); + + switch($this->message_type) + { + case "alt": + // Return text of body + $bndry = new Boundary($this->boundary[1]); + $bndry->CharSet = $this->CharSet; + $bndry->Encoding = $this->Encoding; + $body[] = $bndry->GetSource(); + + $body[] = sprintf("%s%s", $this->AltBody, $this->LE.$this->LE); + + $bndry = new Boundary($this->boundary[1]); + $bndry->CharSet = $this->CharSet; + $bndry->ContentType = "text/html"; + $bndry->Encoding = $this->Encoding; + $body[] = $bndry->GetSource(); + + $body[] = sprintf("%s%s", $this->Body, $this->LE.$this->LE); + + // End the boundary + $body[] = sprintf("%s--%s--%s", $this->LE, + $this->boundary[1], $this->LE.$this->LE); + break; + case "plain": + $body[] = $this->Body; + break; + case "attachments": + $bndry = new Boundary($this->boundary[1]); + $bndry->CharSet = $this->CharSet; + $bndry->ContentType = $this->ContentType; + $bndry->Encoding = $this->Encoding; + $body[] = sprintf("%s%s%s%s", $bndry->GetSource(false), $this->LE, + $this->Body, $this->LE); + + if(!$body[] = $this->attach_all()) + return false; + break; + case "alt_attachments": + $body[] = sprintf("--%s%s", $this->boundary[1], $this->LE); + $body[] = sprintf("Content-Type: %s;%s" . + "\tboundary=\"%s\"%s", + "multipart/alternative", $this->LE, + $this->boundary[2], $this->LE.$this->LE); + + // Create text body + $bndry = new Boundary($this->boundary[2]); + $bndry->CharSet = $this->CharSet; + $bndry->ContentType = "text/plain"; + $bndry->Encoding = $this->Encoding; + $body[] = $bndry->GetSource() . $this->LE; + + $body[] = sprintf("%s%s", $this->AltBody, $this->LE.$this->LE); + + // Create the HTML body + $bndry = new Boundary($this->boundary[2]); + $bndry->CharSet = $this->CharSet; + $bndry->ContentType = "text/html"; + $bndry->Encoding = $this->Encoding; + $body[] = $bndry->GetSource() . $this->LE; + + $body[] = sprintf("%s%s", $this->Body, $this->LE.$this->LE); + + $body[] = sprintf("%s--%s--%s", $this->LE, + $this->boundary[2], $this->LE.$this->LE); + + if(!$body[] = $this->attach_all()) + return false; + break; + } + // Add the encode string code here + $sBody = join("", $body); + $sBody = $this->encode_string($sBody, $this->Encoding); + + return $sBody; + } + + + ///////////////////////////////////////////////// + // ATTACHMENT METHODS + ///////////////////////////////////////////////// + + /** + * Adds an attachment from a path on the filesystem. + * Checks if attachment is valid and then adds + * the attachment to the list. + * Returns false if the file could not be found + * or accessed. + * @access public + * @return bool + */ + function AddAttachment($path, $name = "", $encoding = "base64", $type = "application/octet-stream") { + if(!@is_file($path)) + { + $this->error_handler(sprintf("Could not access [%s] file", $path)); + return false; + } + + $filename = basename($path); + if($name == "") + $name = $filename; + + // Append to $attachment array + $cur = count($this->attachment); + $this->attachment[$cur][0] = $path; + $this->attachment[$cur][1] = $filename; + $this->attachment[$cur][2] = $name; + $this->attachment[$cur][3] = $encoding; + $this->attachment[$cur][4] = $type; + $this->attachment[$cur][5] = false; // isStringAttachment + $this->attachment[$cur][6] = "attachment"; + $this->attachment[$cur][7] = 0; + + return true; + } + + /** + * Attaches all fs, string, and binary attachments to the message. + * Returns a string if successful or false if unsuccessful. + * @access private + * @return string + */ + function attach_all() { + // Return text of body + $mime = array(); + + // Add all attachments + for($i = 0; $i < count($this->attachment); $i++) + { + // Check for string attachment + $bString = $this->attachment[$i][5]; + if ($bString) + { + $string = $this->attachment[$i][0]; + } + else + { + $path = $this->attachment[$i][0]; + } + $filename = $this->attachment[$i][1]; + $name = $this->attachment[$i][2]; + $encoding = $this->attachment[$i][3]; + $type = $this->attachment[$i][4]; + $disposition = $this->attachment[$i][6]; + $cid = $this->attachment[$i][7]; + + $mime[] = sprintf("--%s%s", $this->boundary[1], $this->LE); + $mime[] = sprintf("Content-Type: %s; name=\"%s\"%s", $type, $name, $this->LE); + $mime[] = sprintf("Content-Transfer-Encoding: %s%s", $encoding, $this->LE); + + if($disposition == "inline") + $mime[] = sprintf("Content-ID: <%s>%s", $cid, $this->LE); + else + $mime[] = sprintf("Content-ID: <%s>%s", $name, $this->LE); + + $mime[] = sprintf("Content-Disposition: %s; filename=\"%s\"%s", + $disposition, $name, $this->LE.$this->LE); + + // Encode as string attachment + if($bString) + { + if(!$mime[] = $this->encode_string($string, $encoding)) + return false; + $mime[] = $this->LE.$this->LE; + } + else + { + if(!$mime[] = $this->encode_file($path, $encoding)) + return false; + $mime[] = $this->LE.$this->LE; + } + } + + $mime[] = sprintf("--%s--%s", $this->boundary[1], $this->LE); + + return(join("", $mime)); + } + + /** + * Encodes attachment in requested format. Returns a + * string if successful or false if unsuccessful. + * @access private + * @return string + */ + function encode_file ($path, $encoding = "base64") { + if(!@$fd = fopen($path, "rb")) + { + $this->error_handler(sprintf("File Error: Could not open file %s", $path)); + return false; + } + $file_buffer = fread($fd, filesize($path)); + $file_buffer = $this->encode_string($file_buffer, $encoding); + fclose($fd); + + return $file_buffer; + } + + /** + * Encodes string to requested format. Returns a + * string if successful or false if unsuccessful. + * @access private + * @return string + */ + function encode_string ($str, $encoding = "base64") { + switch(strtolower($encoding)) { + case "base64": + // chunk_split is found in PHP >= 3.0.6 + $encoded = chunk_split(base64_encode($str)); + break; + + case "7bit": + case "8bit": + $encoded = $this->fix_eol($str); + if (substr($encoded, -2) != $this->LE) + $encoded .= $this->LE; + break; + + case "binary": + $encoded = $str; + break; + + case "quoted-printable": + $encoded = $this->encode_qp($str); + break; + + default: + $this->error_handler(sprintf("Unknown encoding: %s", $encoding)); + return false; + } + return($encoded); + } + + /** + * Encode string to quoted-printable. Returns a string. + * @access private + * @return string + */ + function encode_qp ($str) { + $encoded = $this->fix_eol($str); + if (substr($encoded, -2) != $this->LE) + $encoded .= $this->LE; + + // Replace every high ascii, control and = characters + $encoded = preg_replace("/([\001-\010\013\014\016-\037\075\177-\377])/e", + "'='.sprintf('%02X', ord('\\1'))", $encoded); + // Replace every spaces and tabs when it's the last character on a line + $encoded = preg_replace("/([\011\040])".$this->LE."/e", + "'='.sprintf('%02X', ord('\\1')).'".$this->LE."'", $encoded); + + // Maximum line length of 76 characters before CRLF (74 + space + '=') + $encoded = $this->word_wrap($encoded, 74, true); + + return $encoded; + } + + /** + * Adds a string or binary attachment (non-filesystem) to the list. + * This method can be used to attach ascii or binary data, + * such as a BLOB record from a database. + * @access public + * @return void + */ + function AddStringAttachment($string, $filename, $encoding = "base64", $type = "application/octet-stream") { + // Append to $attachment array + $cur = count($this->attachment); + $this->attachment[$cur][0] = $string; + $this->attachment[$cur][1] = $filename; + $this->attachment[$cur][2] = $filename; + $this->attachment[$cur][3] = $encoding; + $this->attachment[$cur][4] = $type; + $this->attachment[$cur][5] = true; // isString + $this->attachment[$cur][6] = "attachment"; + $this->attachment[$cur][7] = 0; + } + + /** + * Adds an embedded attachment. This can include images, sounds, and + * just about any other document. + * @param cid this is the Content Id of the attachment. Use this to identify + * the Id for accessing the image in an HTML form. + * @access public + * @return bool + */ + function AddEmbeddedImage($path, $cid, $name = "", $encoding = "base64", $type = "application/octet-stream") { + + if(!@is_file($path)) + { + $this->error_handler(sprintf("Could not access [%s] file", $path)); + return false; + } + + $filename = basename($path); + if($name == "") + $name = $filename; + + // Append to $attachment array + $cur = count($this->attachment); + $this->attachment[$cur][0] = $path; + $this->attachment[$cur][1] = $filename; + $this->attachment[$cur][2] = $name; + $this->attachment[$cur][3] = $encoding; + $this->attachment[$cur][4] = $type; + $this->attachment[$cur][5] = false; // isStringAttachment + $this->attachment[$cur][6] = "inline"; + $this->attachment[$cur][7] = $cid; + + return true; + } + + /** + * Returns the number of embedded images in an email. + * @access private + * @return int + */ + function EmbeddedImageCount() { + $ret = 0; + for($i = 0; $i < count($this->attachment); $i++) + { + if($this->attachment[$i][6] == "inline") + $ret++; + } + + return $ret; + } + + ///////////////////////////////////////////////// + // MESSAGE RESET METHODS + ///////////////////////////////////////////////// + + /** + * Clears all recipients assigned in the TO array. Returns void. + * @access public + * @return void + */ + function ClearAddresses() { + $this->to = array(); + } + + /** + * Clears all recipients assigned in the CC array. Returns void. + * @access public + * @return void + */ + function ClearCCs() { + $this->cc = array(); + } + + /** + * Clears all recipients assigned in the BCC array. Returns void. + * @access public + * @return void + */ + function ClearBCCs() { + $this->bcc = array(); + } + + /** + * Clears all recipients assigned in the ReplyTo array. Returns void. + * @access public + * @return void + */ + function ClearReplyTos() { + $this->ReplyTo = array(); + } + + /** + * Clears all recipients assigned in the TO, CC and BCC + * array. Returns void. + * @access public + * @return void + */ + function ClearAllRecipients() { + $this->to = array(); + $this->cc = array(); + $this->bcc = array(); + } + + /** + * Clears all previously set filesystem, string, and binary + * attachments. Returns void. + * @access public + * @return void + */ + function ClearAttachments() { + $this->attachment = array(); + } + + /** + * Clears all custom headers. Returns void. + * @access public + * @return void + */ + function ClearCustomHeaders() { + $this->CustomHeader = array(); + } + + + ///////////////////////////////////////////////// + // MISCELLANEOUS METHODS + ///////////////////////////////////////////////// + + /** + * Adds the error message to the error container. + * Returns void. + * @access private + * @return void + */ + function error_handler($msg) { + $this->ErrorInfo = $msg; + } + + /** + * Returns the proper RFC 822 formatted date. Returns string. + * @access private + * @return string + */ + function rfc_date() { + $tz = date("Z"); + $tzs = ($tz < 0) ? "-" : "+"; + $tz = abs($tz); + $tz = ($tz/3600)*100 + ($tz%3600)/60; + $date = sprintf("%s %s%04d", date("D, j M Y H:i:s"), $tzs, $tz); + return $date; + } + + /** + * Returns received header for message tracing. Returns string. + * @access private + * @return string + */ + function received() { + // Check for vars because they might not exist. Possibly + // write a small retrieval function (that mailer can use too!) + + $str = sprintf("Received: from phpmailer ([%s]) by %s " . + "with HTTP;%s\t %s%s", + $this->get_server_var("REMOTE_ADDR"), + $this->get_server_var("SERVER_NAME"), + $this->LE, + $this->rfc_date(), + $this->LE); + + return $str; + } + + /** + * Returns the appropriate server variable. Should work with both + * PHP 4.1.0+ as well as older versions. Returns an empty string + * if nothing is found. + * @access private + * @return mixed + */ + function get_server_var($varName) { + global $HTTP_SERVER_VARS; + global $HTTP_ENV_VARS; + + if(!isset($_SERVER)) + { + $_SERVER = $HTTP_SERVER_VARS; + if(!isset($_SERVER["REMOTE_ADDR"])) + $_SERVER = $HTTP_ENV_VARS; // must be Apache + } + + if(isset($_SERVER[$varName])) + return $_SERVER[$varName]; + else + return ""; + } + + /** + * Changes every end of line from CR or LF to CRLF. Returns string. + * @access private + * @return string + */ + function fix_eol($str) { + $str = str_replace("\r\n", "\n", $str); + $str = str_replace("\r", "\n", $str); + $str = str_replace("\n", $this->LE, $str); + return $str; + } + + /** + * Adds a custom header. Returns void. + * @access public + * @return void + */ + function AddCustomHeader($custom_header) { + $this->CustomHeader[] = $custom_header; + } + + /** + * Adds all the Microsoft message headers. Returns string. + * @access private + * @return string + */ + function AddMSMailHeaders() { + $MSHeader = ""; + if($this->Priority == 1) + $MSPriority = "High"; + elseif($this->Priority == 5) + $MSPriority = "Low"; + else + $MSPriority = "Medium"; + + $MSHeader .= sprintf("X-MSMail-Priority: %s%s", $MSPriority, $this->LE); + $MSHeader .= sprintf("Importance: %s%s", $MSPriority, $this->LE); + + return($MSHeader); + } + +} + + +/** + * Boundary - MIME message boundary class + * @author Brent R. Matzelle + */ +class Boundary +{ + /** + * Sets the boundary ID. + * @access private + * @var string + */ + var $ID = 0; + + /** + * Sets the boundary Content Type. + * @access public + * @var string + */ + var $ContentType = "text/plain"; + + /** + * Sets the Encoding. + * @access public + * @var string + */ + var $Encoding = ""; + + /** + * Sets an attachment disposition. + * @access public + * @var string + */ + var $Disposition = ""; + + /** + * Sets an attachment file name. + * @access public + * @var string + */ + var $FileName = ""; + + /** + * Sets the Char set. + * @access public + * @var string + */ + var $CharSet = ""; + + /** + * Sets the line endings of the message. Default is "\n"; + * @access public + * @var string + */ + var $LE = "\n"; + + /** + * Main constructor. + */ + function Boundary($boundary_id) { + $this->ID = $boundary_id; + } + + /** + * Returns the source of the boundary. + * @access public + * @return string + */ + function GetSource($bLineEnding = true) { + $ret = array(); + $mime[] = sprintf("--%s%s", $this->ID, $this->LE); + $mime[] = sprintf("Content-Type: %s; charset = \"%s\"%s", + $this->ContentType, $this->CharSet, $this->LE); + //$mime[] = sprintf("Content-Transfer-Encoding: %s%s", $this->Encoding, + // $this->LE); + + if(strlen($this->Disposition) > 0) + { + $mime[] = sprintf("Content-Disposition: %s;"); + if(strlen($this->FileName) > 0) + $mime[] = sprinf("filename=\"%s\"", $this->$this->FileName); + } + + if($bLineEnding) + $mime[] = $this->LE; + + return join("", $mime); + } +} + +?> diff --git a/common/code/webnotes/core/class.smtp.php b/common/code/webnotes/core/class.smtp.php new file mode 100644 index 00000000..da9d0153 --- /dev/null +++ b/common/code/webnotes/core/class.smtp.php @@ -0,0 +1,1008 @@ + + * Created: 03/26/2001 + * + * TODO: + * - Move all the duplicate code to a utility function + * Most of the functions have the first lines of + * code do the same processing. If this can be moved + * into a utility function then it would reduce the + * overall size of the code significantly. + */ + + /* + * STMP is rfc 821 compliant and implements all the rfc 821 SMTP + * commands except TURN which will always return a not implemented + * error. SMTP also provides some utility methods for sending mail + * to an SMTP server. + */ + class SMTP { + var $SMTP_PORT = 25; # the default SMTP PORT + var $CRLF = "\r\n"; # CRLF pair + + var $smtp_conn; # the socket to the server + var $error; # error if any on the last call + var $helo_rply; # the reply the server sent to us for HELO + + var $do_debug; # the level of debug to perform + + /* + * SMTP() + * + * Initialize the class so that the data is in a known state. + */ + function SMTP() { + $this->smtp_conn = 0; + $this->error = null; + $this->helo_rply = null; + + $this->do_debug = 0; + } + + /************************************************************ + * CONNECTION FUNCTIONS * + ***********************************************************/ + + /* + * Connect($host, $port=0, $tval=30) + * + * Connect to the server specified on the port specified. + * If the port is not specified use the default SMTP_PORT. + * If tval is specified then a connection will try and be + * established with the server for that number of seconds. + * If tval is not specified the default is 30 seconds to + * try on the connection. + * + * SMTP CODE SUCCESS: 220 + * SMTP CODE FAILURE: 421 + */ + function Connect($host,$port=0,$tval=30) { + # set the error val to null so there is no confusion + $this->error = null; + + # make sure we are __not__ connected + if($this->connected()) { + # ok we are connected! what should we do? + # for now we will just give an error saying we + # are already connected + $this->error = + array("error" => "Already connected to a server"); + return false; + } + + if(empty($port)) { + $port = $this->SMTP_PORT; + } + + #connect to the smtp server + $this->smtp_conn = fsockopen($host, # the host of the server + $port, # the port to use + $errno, # error number if any + $errstr, # error message if any + $tval); # give up after ? secs + # verify we connected properly + if(empty($this->smtp_conn)) { + $this->error = array("error" => "Failed to connect to server", + "errno" => $errno, + "errstr" => $errstr); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . + ": $errstr ($errno)" . $this->CRLF; + } + return false; + } + + # sometimes the SMTP server takes a little longer to respond + # so we will give it a longer timeout for the first read + // Windows still does not have support for this timeout function + if(substr(PHP_OS, 0, 3) != "WIN") + socket_set_timeout($this->smtp_conn, 1, 0); + + # get any announcement stuff + $announce = $this->get_lines(); + + # set the timeout of any socket functions at 1/10 of a second + //if(function_exists("socket_set_timeout")) + // socket_set_timeout($this->smtp_conn, 0, 100000); + + if($this->do_debug >= 2) { + echo "SMTP -> FROM SERVER:" . $this->CRLF . $announce; + } + + return true; + } + + /* + * Authenticate() + * + * Performs SMTP authentication. Must be run after running the + * Hello() method. Returns true if successfully authenticated. + */ + function Authenticate($username, $password) { + // Start authentication + fputs($this->smtp_conn,"AUTH LOGIN" . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($code != 334) { + $this->error = + array("error" => "AUTH not accepted from server", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . + ": " . $rply . $this->CRLF; + } + return false; + } + + // Send encoded username + fputs($this->smtp_conn, base64_encode($username) . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($code != 334) { + $this->error = + array("error" => "Username not accepted from server", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . + ": " . $rply . $this->CRLF; + } + return false; + } + + // Send encoded password + fputs($this->smtp_conn, base64_encode($password) . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($code != 235) { + $this->error = + array("error" => "Password not accepted from server", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . + ": " . $rply . $this->CRLF; + } + return false; + } + + return true; + } + + /* + * Connected() + * + * Returns true if connected to a server otherwise false + */ + function Connected() { + if(!empty($this->smtp_conn)) { + $sock_status = socket_get_status($this->smtp_conn); + if($sock_status["eof"]) { + # hmm this is an odd situation... the socket is + # valid but we aren't connected anymore + if($this->do_debug >= 1) { + echo "SMTP -> NOTICE:" . $this->CRLF . + "EOF caught while checking if connected"; + } + $this->Close(); + return false; + } + return true; # everything looks good + } + return false; + } + + /* + * Close() + * + * Closes the socket and cleans up the state of the class. + * It is not considered good to use this function without + * first trying to use QUIT. + */ + function Close() { + $this->error = null; # so there is no confusion + $this->helo_rply = null; + if(!empty($this->smtp_conn)) { + # close the connection and cleanup + fclose($this->smtp_conn); + $this->smtp_conn = 0; + } + } + + + /************************************************************** + * SMTP COMMANDS * + *************************************************************/ + + /* + * Data($msg_data) + * + * Issues a data command and sends the msg_data to the server + * finializing the mail transaction. $msg_data is the message + * that is to be send with the headers. Each header needs to be + * on a single line followed by a with the message headers + * and the message body being seperated by and additional . + * + * Implements rfc 821: DATA + * + * SMTP CODE INTERMEDIATE: 354 + * [data] + * . + * SMTP CODE SUCCESS: 250 + * SMTP CODE FAILURE: 552,554,451,452 + * SMTP CODE FAILURE: 451,554 + * SMTP CODE ERROR : 500,501,503,421 + */ + function Data($msg_data) { + $this->error = null; # so no confusion is caused + + if(!$this->connected()) { + $this->error = array( + "error" => "Called Data() without being connected"); + return false; + } + + fputs($this->smtp_conn,"DATA" . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($this->do_debug >= 2) { + echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; + } + + if($code != 354) { + $this->error = + array("error" => "DATA command not accepted from server", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . + ": " . $rply . $this->CRLF; + } + return false; + } + + # the server is ready to accept data! + # according to rfc 821 we should not send more than 1000 + # including the CRLF + # characters on a single line so we will break the data up + # into lines by \r and/or \n then if needed we will break + # each of those into smaller lines to fit within the limit. + # in addition we will be looking for lines that start with + # a period '.' and append and additional period '.' to that + # line. NOTE: this does not count towards are limit. + + # normalize the line breaks so we know the explode works + $msg_data = str_replace("\r\n","\n",$msg_data); + $msg_data = str_replace("\r","\n",$msg_data); + $lines = explode("\n",$msg_data); + + # we need to find a good way to determine is headers are + # in the msg_data or if it is a straight msg body + # currently I'm assuming rfc 822 definitions of msg headers + # and if the first field of the first line (':' sperated) + # does not contain a space then it _should_ be a header + # and we can process all lines before a blank "" line as + # headers. + $field = substr($lines[0],0,strpos($lines[0],":")); + $in_headers = false; + if(!empty($field) && !strstr($field," ")) { + $in_headers = true; + } + + $max_line_length = 998; # used below; set here for ease in change + + while(list(,$line) = @each($lines)) { + $lines_out = null; + if($line == "" && $in_headers) { + $in_headers = false; + } + # ok we need to break this line up into several + # smaller lines + while(strlen($line) > $max_line_length) { + $pos = strrpos(substr($line,0,$max_line_length)," "); + $lines_out[] = substr($line,0,$pos); + $line = substr($line,$pos + 1); + # if we are processing headers we need to + # add a LWSP-char to the front of the new line + # rfc 822 on long msg headers + if($in_headers) { + $line = "\t" . $line; + } + } + $lines_out[] = $line; + + # now send the lines to the server + while(list(,$line_out) = @each($lines_out)) { + if(strlen($line_out) > 0) + { + if(substr($line_out, 0, 1) == ".") { + $line_out = "." . $line_out; + } + } + fputs($this->smtp_conn,$line_out . $this->CRLF); + } + } + + # ok all the message data has been sent so lets get this + # over with aleady + fputs($this->smtp_conn, $this->CRLF . "." . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($this->do_debug >= 2) { + echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; + } + + if($code != 250) { + $this->error = + array("error" => "DATA not accepted from server", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . + ": " . $rply . $this->CRLF; + } + return false; + } + return true; + } + + /* + * Expand($name) + * + * Expand takes the name and asks the server to list all the + * people who are members of the _list_. Expand will return + * back and array of the result or false if an error occurs. + * Each value in the array returned has the format of: + * [ ] + * The definition of is defined in rfc 821 + * + * Implements rfc 821: EXPN + * + * SMTP CODE SUCCESS: 250 + * SMTP CODE FAILURE: 550 + * SMTP CODE ERROR : 500,501,502,504,421 + */ + function Expand($name) { + $this->error = null; # so no confusion is caused + + if(!$this->connected()) { + $this->error = array( + "error" => "Called Expand() without being connected"); + return false; + } + + fputs($this->smtp_conn,"EXPN " . $name . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($this->do_debug >= 2) { + echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; + } + + if($code != 250) { + $this->error = + array("error" => "EXPN not accepted from server", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . + ": " . $rply . $this->CRLF; + } + return false; + } + + # parse the reply and place in our array to return to user + $entries = explode($this->CRLF,$rply); + while(list(,$l) = @each($entries)) { + $list[] = substr($l,4); + } + + return $rval; + } + + /* + * Hello($host="") + * + * Sends the HELO command to the smtp server. + * This makes sure that we and the server are in + * the same known state. + * + * Implements from rfc 821: HELO + * + * SMTP CODE SUCCESS: 250 + * SMTP CODE ERROR : 500, 501, 504, 421 + */ + function Hello($host="") { + $this->error = null; # so no confusion is caused + + if(!$this->connected()) { + $this->error = array( + "error" => "Called Hello() without being connected"); + return false; + } + + # if a hostname for the HELO wasn't specified determine + # a suitable one to send + if(empty($host)) { + # we need to determine some sort of appopiate default + # to send to the server + $host = "localhost"; + } + + fputs($this->smtp_conn,"HELO " . $host . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($this->do_debug >= 2) { + echo "SMTP -> FROM SERVER: " . $this->CRLF . $rply; + } + + if($code != 250) { + $this->error = + array("error" => "HELO not accepted from server", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . + ": " . $rply . $this->CRLF; + } + return false; + } + + $this->helo_rply = $rply; + + return true; + } + + /* + * Help($keyword="") + * + * Gets help information on the keyword specified. If the keyword + * is not specified then returns generic help, ussually contianing + * A list of keywords that help is available on. This function + * returns the results back to the user. It is up to the user to + * handle the returned data. If an error occurs then false is + * returned with $this->error set appropiately. + * + * Implements rfc 821: HELP [ ] + * + * SMTP CODE SUCCESS: 211,214 + * SMTP CODE ERROR : 500,501,502,504,421 + * + */ + function Help($keyword="") { + $this->error = null; # to avoid confusion + + if(!$this->connected()) { + $this->error = array( + "error" => "Called Help() without being connected"); + return false; + } + + $extra = ""; + if(!empty($keyword)) { + $extra = " " . $keyword; + } + + fputs($this->smtp_conn,"HELP" . $extra . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($this->do_debug >= 2) { + echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; + } + + if($code != 211 && $code != 214) { + $this->error = + array("error" => "HELP not accepted from server", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . + ": " . $rply . $this->CRLF; + } + return false; + } + + return $rply; + } + + /* + * Mail($from) + * + * Starts a mail transaction from the email address specified in + * $from. Returns true if successful or false otherwise. If True + * the mail transaction is started and then one or more Recipient + * commands may be called followed by a Data command. + * + * Implements rfc 821: MAIL FROM: + * + * SMTP CODE SUCCESS: 250 + * SMTP CODE SUCCESS: 552,451,452 + * SMTP CODE SUCCESS: 500,501,421 + */ + function Mail($from) { + $this->error = null; # so no confusion is caused + + if(!$this->connected()) { + $this->error = array( + "error" => "Called Mail() without being connected"); + return false; + } + + fputs($this->smtp_conn,"MAIL FROM:" . $from . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($this->do_debug >= 2) { + echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; + } + + if($code != 250) { + $this->error = + array("error" => "MAIL not accepted from server", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . + ": " . $rply . $this->CRLF; + } + return false; + } + return true; + } + + /* + * Noop() + * + * Sends the command NOOP to the SMTP server. + * + * Implements from rfc 821: NOOP + * + * SMTP CODE SUCCESS: 250 + * SMTP CODE ERROR : 500, 421 + */ + function Noop() { + $this->error = null; # so no confusion is caused + + if(!$this->connected()) { + $this->error = array( + "error" => "Called Noop() without being connected"); + return false; + } + + fputs($this->smtp_conn,"NOOP" . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($this->do_debug >= 2) { + echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; + } + + if($code != 250) { + $this->error = + array("error" => "NOOP not accepted from server", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . + ": " . $rply . $this->CRLF; + } + return false; + } + return true; + } + + /* + * Quit($close_on_error=true) + * + * Sends the quit command to the server and then closes the socket + * if there is no error or the $close_on_error argument is true. + * + * Implements from rfc 821: QUIT + * + * SMTP CODE SUCCESS: 221 + * SMTP CODE ERROR : 500 + */ + function Quit($close_on_error=true) { + $this->error = null; # so there is no confusion + + if(!$this->connected()) { + $this->error = array( + "error" => "Called Quit() without being connected"); + return false; + } + + # send the quit command to the server + fputs($this->smtp_conn,"quit" . $this->CRLF); + + # get any good-bye messages + $byemsg = $this->get_lines(); + + if($this->do_debug >= 2) { + echo "SMTP -> FROM SERVER:" . $this->CRLF . $byemsg; + } + + $rval = true; + $e = null; + + $code = substr($byemsg,0,3); + if($code != 221) { + # use e as a tmp var cause Close will overwrite $this->error + $e = array("error" => "SMTP server rejected quit command", + "smtp_code" => $code, + "smtp_rply" => substr($byemsg,4)); + $rval = false; + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $e["error"] . ": " . + $byemsg . $this->CRLF; + } + } + + if(empty($e) || $close_on_error) { + $this->Close(); + } + + return $rval; + } + + /* + * Recipient($to) + * + * Sends the command RCPT to the SMTP server with the TO: argument of $to. + * Returns true if the recipient was accepted false if it was rejected. + * + * Implements from rfc 821: RCPT TO: + * + * SMTP CODE SUCCESS: 250,251 + * SMTP CODE FAILURE: 550,551,552,553,450,451,452 + * SMTP CODE ERROR : 500,501,503,421 + */ + function Recipient($to) { + $this->error = null; # so no confusion is caused + + if(!$this->connected()) { + $this->error = array( + "error" => "Called Recipient() without being connected"); + return false; + } + + fputs($this->smtp_conn,"RCPT TO:" . $to . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($this->do_debug >= 2) { + echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; + } + + if($code != 250 && $code != 251) { + $this->error = + array("error" => "RCPT not accepted from server", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . + ": " . $rply . $this->CRLF; + } + return false; + } + return true; + } + + /* + * Reset() + * + * Sends the RSET command to abort and transaction that is + * currently in progress. Returns true if successful false + * otherwise. + * + * Implements rfc 821: RSET + * + * SMTP CODE SUCCESS: 250 + * SMTP CODE ERROR : 500,501,504,421 + */ + function Reset() { + $this->error = null; # so no confusion is caused + + if(!$this->connected()) { + $this->error = array( + "error" => "Called Reset() without being connected"); + return false; + } + + fputs($this->smtp_conn,"RSET" . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($this->do_debug >= 2) { + echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; + } + + if($code != 250) { + $this->error = + array("error" => "RSET failed", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . + ": " . $rply . $this->CRLF; + } + return false; + } + + return true; + } + + /* + * Send($from) + * + * Starts a mail transaction from the email address specified in + * $from. Returns true if successful or false otherwise. If True + * the mail transaction is started and then one or more Recipient + * commands may be called followed by a Data command. This command + * will send the message to the users terminal if they are logged + * in. + * + * Implements rfc 821: SEND FROM: + * + * SMTP CODE SUCCESS: 250 + * SMTP CODE SUCCESS: 552,451,452 + * SMTP CODE SUCCESS: 500,501,502,421 + */ + function Send($from) { + $this->error = null; # so no confusion is caused + + if(!$this->connected()) { + $this->error = array( + "error" => "Called Send() without being connected"); + return false; + } + + fputs($this->smtp_conn,"SEND FROM:" . $from . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($this->do_debug >= 2) { + echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; + } + + if($code != 250) { + $this->error = + array("error" => "SEND not accepted from server", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . + ": " . $rply . $this->CRLF; + } + return false; + } + return true; + } + + /* + * SendAndMail($from) + * + * Starts a mail transaction from the email address specified in + * $from. Returns true if successful or false otherwise. If True + * the mail transaction is started and then one or more Recipient + * commands may be called followed by a Data command. This command + * will send the message to the users terminal if they are logged + * in and send them an email. + * + * Implements rfc 821: SAML FROM: + * + * SMTP CODE SUCCESS: 250 + * SMTP CODE SUCCESS: 552,451,452 + * SMTP CODE SUCCESS: 500,501,502,421 + */ + function SendAndMail($from) { + $this->error = null; # so no confusion is caused + + if(!$this->connected()) { + $this->error = array( + "error" => "Called SendAndMail() without being connected"); + return false; + } + + fputs($this->smtp_conn,"SAML FROM:" . $from . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($this->do_debug >= 2) { + echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; + } + + if($code != 250) { + $this->error = + array("error" => "SAML not accepted from server", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . + ": " . $rply . $this->CRLF; + } + return false; + } + return true; + } + + /* + * SendOrMail($from) + * + * Starts a mail transaction from the email address specified in + * $from. Returns true if successful or false otherwise. If True + * the mail transaction is started and then one or more Recipient + * commands may be called followed by a Data command. This command + * will send the message to the users terminal if they are logged + * in or mail it to them if they are not. + * + * Implements rfc 821: SOML FROM: + * + * SMTP CODE SUCCESS: 250 + * SMTP CODE SUCCESS: 552,451,452 + * SMTP CODE SUCCESS: 500,501,502,421 + */ + function SendOrMail($from) { + $this->error = null; # so no confusion is caused + + if(!$this->connected()) { + $this->error = array( + "error" => "Called SendOrMail() without being connected"); + return false; + } + + fputs($this->smtp_conn,"SOML FROM:" . $from . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($this->do_debug >= 2) { + echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; + } + + if($code != 250) { + $this->error = + array("error" => "SOML not accepted from server", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . + ": " . $rply . $this->CRLF; + } + return false; + } + return true; + } + + /* + * Turn() + * + * This is an optional command for SMTP that this class does not + * support. This method is here to make the RFC821 Definition + * complete for this class and __may__ be implimented in the future + * + * Implements from rfc 821: TURN + * + * SMTP CODE SUCCESS: 250 + * SMTP CODE FAILURE: 502 + * SMTP CODE ERROR : 500, 503 + */ + function Turn() { + $this->error = array("error" => "This method, TURN, of the SMTP ". + "is not implemented"); + if($this->do_debug >= 1) { + echo "SMTP -> NOTICE: " . $this->error["error"] . $this->CRLF; + } + return false; + } + + /* + * Verify($name) + * + * Verifies that the name is recognized by the server. + * Returns false if the name could not be verified otherwise + * the response from the server is returned. + * + * Implements rfc 821: VRFY + * + * SMTP CODE SUCCESS: 250,251 + * SMTP CODE FAILURE: 550,551,553 + * SMTP CODE ERROR : 500,501,502,421 + */ + function Verify($name) { + $this->error = null; # so no confusion is caused + + if(!$this->connected()) { + $this->error = array( + "error" => "Called Verify() without being connected"); + return false; + } + + fputs($this->smtp_conn,"VRFY " . $name . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($this->do_debug >= 2) { + echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; + } + + if($code != 250 && $code != 251) { + $this->error = + array("error" => "VRFY failed on name '$name'", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . + ": " . $rply . $this->CRLF; + } + return false; + } + return $rply; + } + + /****************************************************************** + * INTERNAL FUNCTIONS * + ******************************************************************/ + + /* + * get_lines() + * + * __internal_use_only__: read in as many lines as possible + * either before eof or socket timeout occurs on the operation. + * With SMTP we can tell if we have more lines to read if the + * 4th character is '-' symbol. If it is a space then we don't + * need to read anything else. + */ + function get_lines() { + $data = ""; + while($str = fgets($this->smtp_conn,515)) { + if($this->do_debug >= 4) { + echo "SMTP -> get_lines(): \$data was \"$data\"" . + $this->CRLF; + echo "SMTP -> get_lines(): \$str is \"$str\"" . + $this->CRLF; + } + $data .= $str; + if($this->do_debug >= 4) { + echo "SMTP -> get_lines(): \$data is \"$data\"" . $this->CRLF; + } + # if the 4th character is a space then we are done reading + # so just break the loop + if(substr($str,3,1) == " ") { break; } + } + return $data; + } + + } + + + ?> diff --git a/common/code/webnotes/core/config_api.php b/common/code/webnotes/core/config_api.php new file mode 100644 index 00000000..cd442c03 --- /dev/null +++ b/common/code/webnotes/core/config_api.php @@ -0,0 +1,83 @@ + diff --git a/common/code/webnotes/core/config_defaults_inc.php b/common/code/webnotes/core/config_defaults_inc.php new file mode 100644 index 00000000..9d058a9c --- /dev/null +++ b/common/code/webnotes/core/config_defaults_inc.php @@ -0,0 +1,224 @@ + MODERATOR, + ACTION_NOTES_VIEW_ACCEPTED => EVERYBODY, + ACTION_NOTES_VIEW_DECLINED => MODERATOR, + ACTION_NOTES_VIEW_ARCHIVED => MODERATOR, + ACTION_NOTES_VIEW_DELETED => ADMINISTRATOR, + ACTION_NOTES_SUBMIT => EVERYBODY, + ACTION_NOTES_ADD => MODERATOR, + ACTION_NOTES_EDIT => MODERATOR, + ACTION_NOTES_EDIT_OWN => REGISTERED, + ACTION_NOTES_DELETE_OWN => REGISTERED, + ACTION_NOTES_MODERATE => MODERATOR, + ACTION_NOTES_MODERATE_ACCEPT => MODERATOR, + ACTION_NOTES_MODERATE_DECLINE => MODERATOR, + ACTION_NOTES_MODERATE_ARCHIVE => MODERATOR, + ACTION_NOTES_MODERATE_DELETE => MODERATOR, + ACTION_NOTES_MODERATE_QUEUE => MODERATOR, + ACTION_NOTES_PACK_DELETED => NOBODY, + ACTION_NOTES_PACK_DECLINED => MODERATOR, + ACTION_USERS_MANAGE => ADMINISTRATOR, + ACTION_USERS_ADD => ADMINISTRATOR, + ACTION_USERS_EDIT => ADMINISTRATOR, + ACTION_USERS_EDIT_OWN => REGISTERED, + ACTION_USERS_EDIT_OWN_PROTECTED => ADMINISTRATOR, + ACTION_USERS_DELETE => ADMINISTRATOR, + ACTION_PAGES_MANAGE => ADMINISTRATOR, + ACTION_PAGES_ADD => ADMINISTRATOR, + ACTION_PAGES_DELETE => ADMINISTRATOR ); + + # This array specified for each action, the user types that can perform it. + # This is more flexible than specifying a threshold. This is only used when + # the threshold is set to NOBODY for the specified action. + # Added one example below (although this could have been done by setting + # the threshold to ADMINISTRATOR. + $g_access_sets = array( ACTION_NOTES_PACK_DELETED => array( ADMINISTRATOR ) ); + + ################### + # EMAIL SETTINGS + ################### + + # This option allows you to use a remote SMTP host. Must use the phpMailer script + # Name of smtp host, needed for phpMailer, taken from php.ini + $g_smtp_host = 'localhost'; + + $g_webmaster_email = 'webmaster@nowhere'; + $g_administrator_email = 'admin@nowhere'; + + # the "From: " field in emails + $g_from_email = 'noreply@nowhere'; + + # the return address for bounced mail + $g_return_path_email = 'admin@nowhere'; + + # if ON users will be sent their password when reset. + # if OFF the password will be set to blank. + $g_send_reset_password = ON; + + # allow email notification + $g_enable_email_notification = ON; + + # Set to OFF to remove X-Priority header + $g_use_x_priority = ON; + + # some Mail transfer agents (MTAs) don't like bare linefeeds... + # or they take good input and create barelinefeeds + # If problems occur when sending mail through your server try turning this OFF + # more here: http://pobox.com/~djb/docs/smtplf.html + $g_mail_send_crlf = OFF; + + ########################## + # ENUMERATIONS SETTINGS + ########################## + + # --- enum strings ---------------- + # status from $g_status_index-1 to 79 are used for the onboard customization (if enabled) + # directly use Mantis to edit them. + $g_access_levels_enum_string = '10:anonymous,40:registered,70:moderator,90:administrator'; +?> diff --git a/common/code/webnotes/core/constants_inc.php b/common/code/webnotes/core/constants_inc.php new file mode 100644 index 00000000..6ef0150d --- /dev/null +++ b/common/code/webnotes/core/constants_inc.php @@ -0,0 +1,69 @@ + \ No newline at end of file diff --git a/common/code/webnotes/core/css_inc.php b/common/code/webnotes/core/css_inc.php new file mode 100644 index 00000000..fc902f98 --- /dev/null +++ b/common/code/webnotes/core/css_inc.php @@ -0,0 +1,84 @@ + + \ No newline at end of file diff --git a/common/code/webnotes/core/custom_config_inc.php b/common/code/webnotes/core/custom_config_inc.php new file mode 100644 index 00000000..ca84a9cc --- /dev/null +++ b/common/code/webnotes/core/custom_config_inc.php @@ -0,0 +1,22 @@ + \ No newline at end of file diff --git a/common/code/webnotes/core/cvs_env b/common/code/webnotes/core/cvs_env new file mode 100755 index 00000000..d7f36fab --- /dev/null +++ b/common/code/webnotes/core/cvs_env @@ -0,0 +1,2 @@ +CVSROOT=${LOGNAME}@cvs.webnotes.sourceforge.net:/cvsroot/webnotes; export CVSROOT; +CVS_RSH=ssh; export CVS_RSH; diff --git a/common/code/webnotes/core/database_api.php b/common/code/webnotes/core/database_api.php new file mode 100644 index 00000000..0b7e3f71 --- /dev/null +++ b/common/code/webnotes/core/database_api.php @@ -0,0 +1,152 @@ + 0 ) ) { + return mysql_result( $p_result, $p_index1, $p_index2 ); + } + else { + return false; + } + } + # -------------------- + # return the last inserted id + function db_insert_id() { + if ( mysql_affected_rows() > 0 ) { + return mysql_insert_id(); + } else { + return false; + } + } + ### -------------------- + function db_close() { + $t_result = mysql_close(); + } + ### -------------------- + # -------------------- + # prepare a string before DB insertion + function db_prepare_string( $p_string ) { + return mysql_escape_string( $p_string ); + } + # -------------------- + # prepare an integer before DB insertion + function db_prepare_int( $p_int ) { + return (integer)$p_int; + } + # -------------------- + # prepare a boolean before DB insertion + function db_prepare_bool( $p_bool ) { + return (int)(bool)$p_bool; + } + # -------------------- + # generic unprepare if type is unknown + function db_unprepare( $p_string ) { + return stripslashes( $p_string ); + } + # -------------------- + # unprepare a string after taking it out of the DB + function db_unprepare_string( $p_string ) { + return db_unprepare( $p_string ); + } + # -------------------- + # unprepare an integer after taking it out of the DB + function db_unprepare_int( $p_int ) { + return (integer)db_unprepare( $p_int ); + } + # -------------------- + # unprepare a boolean after taking it out of the DB + function db_unprepare_bool( $p_bool ) { + return (bool)db_unprepare( $p_bool ); + } + # -------------------- + # calls db_unprepare() on every item in a row + function db_unprepare_row( $p_row ) { + if ( false == $p_row ) { + return false; + } + + $t_new_row = array(); + + while ( list( $t_key, $t_val ) = each( $p_row ) ) { + $t_new_row[$t_key] = db_unprepare( $t_val ); + } + + return $t_new_row; + } + + ########################################################################### + ### CODE TO EXECUTE ### + ########################################################################### + + db_connect( $g_hostname, $g_db_username, $g_db_password, $g_database_name ); +?> \ No newline at end of file diff --git a/common/code/webnotes/core/email_api.php b/common/code/webnotes/core/email_api.php new file mode 100644 index 00000000..3f3850cd --- /dev/null +++ b/common/code/webnotes/core/email_api.php @@ -0,0 +1,166 @@ +\r\n"; + $t_headers .= "X-Mailer: phpWebNotes $g_phpWebNotes_version\r\n"; + if ( ON == $g_use_x_priority ) { + $t_headers .= "X-Priority: 0\r\n"; # Urgent = 1, Not Urgent = 5, Disable = 0 + } + $t_headers .= "Return-Path: <$g_return_path_email>\r\n"; # return email if error + + # If you want to send foreign charsets + # $t_headers .= "Content-Type: text/html; charset=iso-8859-1\r\n"; + + $t_headers .= $p_header . "\r\n"; + + $t_recipient = email_make_lf_crlf( $t_recipient ); + $t_subject = email_make_lf_crlf( $t_subject ); + $t_message = email_make_lf_crlf( $t_message ); + $t_headers = email_make_lf_crlf( $t_headers ); + $result = mail( $t_recipient, $t_subject, $t_message, $t_headers ); + if ( false === $result ) { + echo "PROBLEMS SENDING MAIL TO: $t_recipient
"; + echo htmlspecialchars($t_recipient).'
'; + echo htmlspecialchars($t_subject).'
'; + echo nl2br(htmlspecialchars($t_headers)).'
'; + #echo nl2br(htmlspecialchars($t_message)).'
'; + exit; + } + } + # -------------------- + # clean up LF to CRLF + function email_make_lf_crlf( $p_string ) { + if ( OFF == config_get( 'mail_send_crlf' ) ) { + return $p_string; + } + + $p_string = str_replace( "\n", "\r\n", $p_string ); + return str_replace( "\r\r\n", "\r\n", $p_string ); + } + # -------------------- + # email build note message + function email_build_note_message( $p_note_id, &$subject, &$content ) { + $note = note_get_info( note_where_id_equals( $p_note_id ) ); + if ( $note === false ) { + return false; + } + extract( $note, EXTR_PREFIX_ALL, 'note' ); + + $page = page_get_info( page_where_id_equals( $note_page_id ) ); + if ( $page === false ) { + return false; + } + extract( $page, EXTR_PREFIX_ALL, 'page' ); + + $subject = "[$page_page] $note_email"; + + $content = ''; + $content .= str_pad( '', 70, '=' ) . "\n"; + $content .= 'http://' . $_SERVER['SERVER_NAME'] . $page_url . "\n"; + $content .= str_pad( '', 70, '-' ) . "\n"; + $content .= "Note Id: $note_id\n"; + $content .= "Email: $note_email\n"; + $content .= "IP: $note_ip\n"; + $content .= "Date Submitted: " . date( 'd-M-Y H:i:s', $note_date_submitted ) . "\n"; + $content .= "Visible: " . ( $note_visible ? "Yes" : "No" ) . "\n"; + $content .= str_pad( '', 70, '-' ) . "\n"; + $content .= $note_note . "\n"; + $content .= str_pad( '', 70, '=' ) . "\n"; + + return true; + } + + # -------------------- + # build an array of recipients + function email_recipients( $p_note_id ) + { + global $g_phpWN_user_table; + + $query = "SELECT email FROM $g_phpWN_user_table + WHERE access_level >= " . MODERATOR . + " AND email <> ''"; + $result = db_query( $query ); + + $emails_array = array(); + while( $row = db_fetch_array( $result ) ) { + $emails_array[] = $row['email']; + } + + $emails_array = array_unique( $emails_array ); + $emails = implode( ',', $emails_array ); + + return $emails; + } + + # -------------------- + # email note to administrator + # @@@ Query the database to send to moderators / administrators, rather than + # just the administrator in the configs. + function email_note_added( $p_note_id ) { + $subject = ''; + $content = ''; + email_build_note_message( $p_note_id, $subject, $content ); + + $t_recipients = email_recipients( $p_note_id ); + + global $g_administrator_email; + email_send( $t_recipients, $subject, $content ); + } + + # -------------------- + # email note to administrator + # @@@ Query the database to send to moderators / administrators, rather than + # just the administrator in the configs. + function email_note_updated( $p_note_id ) { + email_note_added( $p_note_id ); + } +?> diff --git a/common/code/webnotes/core/enum_api.php b/common/code/webnotes/core/enum_api.php new file mode 100644 index 00000000..cf27daa7 --- /dev/null +++ b/common/code/webnotes/core/enum_api.php @@ -0,0 +1,68 @@ + \ No newline at end of file diff --git a/common/code/webnotes/core/gpc_api.php b/common/code/webnotes/core/gpc_api.php new file mode 100644 index 00000000..06b80e7a --- /dev/null +++ b/common/code/webnotes/core/gpc_api.php @@ -0,0 +1,234 @@ + 1 ) { #check for a default passed in (allowing null) + $t_result = $p_default; + } else { + #trigger_error(ERROR_GPC_VAR_NOT_FOUND, ERROR); + echo "Variable '$p_var_name' not found"; + $t_result = null; + } + + return $t_result; + } + # ----------------- + # Retrieve a string GPC variable. Uses gpc_get(). + # If you pass in *no* default, an error will be triggered if + # the variable does not exist + function gpc_get_string( $p_var_name, $p_default = null ) { + # Don't pass along a default unless one was given to us + # otherwise we prevent an error being triggered + if ( func_num_args() > 1 ) { + $t_result = gpc_get( $p_var_name, $p_default ); + } else { + $t_result = gpc_get( $p_var_name ); + } + + if ( is_array( $t_result ) ) { + #trigger_error( ERROR_GPC_ARRAY_UNEXPECTED, ERROR );e + echo "Unexpected array '$p_var_name'."; + } + + return $t_result; + } + # ------------------ + # Retrieve an integer GPC variable. Uses gpc_get(). + # If you pass in *no* default, an error will be triggered if + # the variable does not exist + function gpc_get_int( $p_var_name, $p_default = null ) { + # Don't pass along a default unless one was given to us + # otherwise we prevent an error being triggered + if ( func_num_args() > 1 ) { + $t_result = gpc_get( $p_var_name, $p_default ); + } else { + $t_result = gpc_get( $p_var_name ); + } + + if ( is_array( $t_result ) ) { + #trigger_error( ERROR_GPC_ARRAY_UNEXPECTED, ERROR ); + echo "Unexpected array '$p_var_name'."; + } + + return (integer)$t_result; + } + # ------------------ + # Retrieve a boolean GPC variable. Uses gpc_get(). + # If you pass in *no* default, false will be used + function gpc_get_bool( $p_var_name, $p_default = false ) { + $t_result = gpc_get( $p_var_name, $p_default ); + + if ( $t_result === $p_default ) { + return $p_default; + } else { + if ( is_array( $t_result ) ) { + #trigger_error( ERROR_GPC_ARRAY_UNEXPECTED, ERROR ); + echo "Unexpected array '$p_var_name'."; + } + + return gpc_string_to_bool( $t_result ); + } + } + + #=================================== + # Array Functions + #=================================== + + # ------------------ + # Retrieve a atring array GPC variable. Uses gpc_get(). + # If you pass in *no* default, an error will be triggered if + # the variable does not exist + function gpc_get_string_array( $p_var_name, $p_default = null ) { + # Don't pass along a default unless one was given to us + # otherwise we prevent an error being triggered + if ( func_num_args() > 1 ) { + $t_result = gpc_get( $p_var_name, $p_default ); + } else { + $t_result = gpc_get( $p_var_name ); + } + + if ( ! is_array( $t_result ) ) { + #trigger_error( ERROR_GPC_ARRAY_EXPECTED, ERROR); + echo "Unexpected array '$p_var_name'."; + } + + return $t_result; + } + # ------------------ + # Retrieve an integer array GPC variable. Uses gpc_get(). + # If you pass in *no* default, an error will be triggered if + # the variable does not exist + function gpc_get_int_array( $p_var_name, $p_default = null ) { + # Don't pass along a default unless one was given to us + # otherwise we prevent an error being triggered + if ( func_num_args() > 1 ) { + $t_result = gpc_get( $p_var_name, $p_default ); + } else { + $t_result = gpc_get( $p_var_name ); + } + + if ( ! is_array( $t_result ) ) { + #trigger_error( ERROR_GPC_ARRAY_EXPECTED, ERROR); + echo "Unexpected array '$p_var_name'."; + } + + for ( $i=0 ; $i < sizeof( $t_result ) ; $i++ ) { + $t_result[$i] = (integer)$t_result[$i]; + } + + return $t_result; + } + # ------------------ + # Retrieve a boolean array GPC variable. Uses gpc_get(). + # If you pass in *no* default, an error will be triggered if + # the variable does not exist + function gpc_get_bool_array( $p_var_name, $p_default = null ) { + # Don't pass along a default unless one was given to us + # otherwise we prevent an error being triggered + if ( func_num_args() > 1 ) { + $t_result = gpc_get( $p_var_name, $p_default ); + } else { + $t_result = gpc_get( $p_var_name ); + } + + if ( ! is_array( $t_result ) ) { + #trigger_error( ERROR_GPC_ARRAY_EXPECTED, ERROR); + echo "Unexpected array '$p_var_name'."; + } + + for ( $i=0 ; $i < sizeof( $t_result ) ; $i++ ) { + $t_result[$i] = gpc_string_to_bool( $t_result[$i] ); + } + + return $t_result; + } + + #=================================== + # Cookie Functions + #=================================== + + # ------------------ + # Retrieve a cookie variable + # You may pass in any variable as a default (including null) but if + # you pass in *no* default then an error will be triggered if the cookie + # cannot be found + function gpc_get_cookie( $p_var_name, $p_default = null ) { + # simulate auto-globals from PHP v4.1.0 (see also code in php_api.php) + if ( ! php_version_at_least( '4.1.0' ) ) { + global $_COOKIE; + } + + if ( isset( $_COOKIE[$p_var_name] ) ) { + $t_result = gpc_strip_slashes( $_COOKIE[$p_var_name] ); + } else if ( func_num_args() > 1 ) { #check for a default passed in (allowing null) + $t_result = $p_default; + } else { + #trigger_error(ERROR_GPC_VAR_NOT_FOUND, ERROR); + echo "Variable '$p_var_name' not found"; + $t_result = null; + } + + return $t_result; + } + + #=================================== + # Helper Functions + #=================================== + + # ------------------ + # Convert a string to a bool + function gpc_string_to_bool( $p_string ) { + if ( 0 == strcasecmp( 'off', $p_string ) || + 0 == strcasecmp( 'no', $p_string ) || + 0 == strcasecmp( 'false', $p_string ) || + 0 == strcasecmp( '0', $p_string ) ) { + return false; + } else { + return true; + } + } + + # ------------------ + # Strip slashes if necessary (supports arrays) + function gpc_strip_slashes( $p_var ) { + if (get_magic_quotes_gpc() == 0) { + return $p_var; + } else if ( ! is_array( $p_var ) ){ + return stripslashes( $p_var ); + } else { + for ( $i=0 ; $i < sizeof( $p_var ) ; $i++ ) { + $p_var[$i] = stripslashes( $p_var[$i] ); + + return $p_var; + } + } + } +?> diff --git a/common/code/webnotes/core/html_api.php b/common/code/webnotes/core/html_api.php new file mode 100644 index 00000000..7266a82b --- /dev/null +++ b/common/code/webnotes/core/html_api.php @@ -0,0 +1,173 @@ +' . + "\n"; + } + ### -------------------- + function print_head_top() { + echo ''; + } + ### -------------------- + function print_title( $p_title ) { + echo "$p_title"; + } + ### -------------------- + function print_css( $p_css = '' ) { + if ( !empty( $p_css ) && file_exists( $p_css ) ) { + include_once( $p_css ); + } + } + ### -------------------- + function print_css_link( $p_css ) { + echo ""; + } + ### -------------------- + function print_meta_inc( $p_meta_inc = '' ) { + if ( !empty( $p_meta_inc ) && file_exists( $p_meta_inc ) ) { + include_once( $p_meta_inc ); + } + } + ### -------------------- + function print_meta_redirect( $p_url, $p_time ) { + echo ""; + } + ### -------------------- + function print_head_bottom() { + echo ''; + } + ### -------------------- + function print_body_top() { + echo '
'; + } + ### -------------------- + function print_header( $p_title = '' ) { + echo << + $p_title +
+EOT; + } + ### -------------------- + function print_top_page( $p_page ) { + if ( !empty( $p_page ) && file_exists( $p_page ) ) { + echo '
'; + include_once( $p_page ); + echo '
'; + } + } + ### -------------------- + function print_bottom_page( $p_page ) { + if ( !empty( $p_page ) && file_exists( $p_page ) ) { + echo '
'; + include_once( $p_page ); + echo '
'; + } + } + ### -------------------- + function print_footer( $p_file ) { + global $g_webmaster_email; + + echo ''; + } + ### -------------------- + function print_body_bottom() { + echo ''; + } + ### -------------------- + function print_html_bottom() { + echo ''; + } + ### -------------------- + ########################################################################### + # HTML Appearance Helper API + ########################################################################### + ### -------------------- + ### checks to see whether we need to be displaying the version number + function print_phpWebNotes_version() { + if ( ON == config_get( 'show_version' ) ) { + echo 'phpWebNotes - ' . config_get( 'phpWebNotes_version' ) . '
'; + } + } + ### -------------------- + function print_spacer() { + echo '
'; + } + ### -------------------- + function print_admin_menu( $p_add_space = true ) { + global $g_logout, $g_admin_index_files, $g_admin_change_password, + $g_admin_manage_notes, $g_admin_manage_users, + $s_logout_link, $s_index_files, $s_change_password, + $s_manage_notes, $s_manage_users, $g_user_home_page; + + $queue_count = note_queue_count(); + + echo ' +EOT; + } + # -------------------- + # print the bracketed links used near the top + # if the $p_link is blank then the text is printed but no link is created + function print_bracket_link( $p_link, $p_url_text ) { + if ( empty( $p_link ) ) { + echo "[ $p_url_text ]"; + } else { + echo "[ $p_url_text ]"; + } + } + ### -------------------- + function html_option_list_access_level( $p_access_level = '' ) { + $ids = enum_get_ids_array( 'access_levels' ); + + foreach ( $ids as $id ) { + if ( ( NOBODY == $id ) || ( EVERYBODY == $id ) ) { + continue; + } + + echo ''; + } + } + ### -------------------- +?> diff --git a/common/code/webnotes/core/lang_api.php b/common/code/webnotes/core/lang_api.php new file mode 100644 index 00000000..45bfd117 --- /dev/null +++ b/common/code/webnotes/core/lang_api.php @@ -0,0 +1,30 @@ + \ No newline at end of file diff --git a/common/code/webnotes/core/link_api.php b/common/code/webnotes/core/link_api.php new file mode 100644 index 00000000..9893c42c --- /dev/null +++ b/common/code/webnotes/core/link_api.php @@ -0,0 +1,63 @@ +$p_caption$p_suffix"; + } else { + return "$p_prefix$p_caption$p_suffix"; + } + } + ### -------------------- + function link_note_action( $p_note_id, $p_action, $p_url, $p_link_active = true, $p_caption = null ) { + if ( null === $p_caption ) { + $t_caption = lang_get( 'action_' . $p_action ); + $t_before = '[ '; + $t_after = ' ]'; + } else { + $t_caption = $p_caption; + $t_before = $t_after = ''; + } + + $c_note_id = db_prepare_int( $p_note_id ); + $c_action = urlencode( $p_action ); + # $c_url = urlencode( $p_url ); + $t_action = config_get( 'web_directory') . 'action.php'; + $t_link = "$t_action?f_action=$c_action&f_note_id=$c_note_id"; # &f_url=$c_url"; + + return( link_create( $t_link, $t_caption, $p_link_active, $t_before, $t_after ) ); + } + ### -------------------- + # $p_page = $p_page_id if action is unindex + # $p_page = $p_page_name if action is index + function link_page_action( $p_page, $p_action, $p_url, $p_link_active = true, $p_caption = null ) { + if ( null === $p_caption ) { + $t_caption = lang_get( 'action_' . $p_action ); + $t_before = '[ '; + $t_after = ' ]'; + } else { + $t_caption = $p_caption; + $t_before = $t_after = ''; + } + + $c_page_id = urlencode( $p_page ); + $c_action = urlencode( $p_action ); + $c_url = urlencode( $p_url ); + $t_action = config_get( 'web_directory' ) . 'action.php'; + $t_link = "$t_action?f_action=$c_action&f_page_id=$c_page_id&f_url=$c_url"; + + return( link_create( $t_link, $t_caption, $p_link_active, $t_before, $t_after ) ); + } +?> \ No newline at end of file diff --git a/common/code/webnotes/core/meta_inc.php b/common/code/webnotes/core/meta_inc.php new file mode 100644 index 00000000..cc95ff56 --- /dev/null +++ b/common/code/webnotes/core/meta_inc.php @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/common/code/webnotes/core/note_api.php b/common/code/webnotes/core/note_api.php new file mode 100644 index 00000000..024fcb95 --- /dev/null +++ b/common/code/webnotes/core/note_api.php @@ -0,0 +1,261 @@ + 0 ) { + $t_info = db_fetch_array( $result ); + + if ( null === $p_field ) { + return $t_info; + } else { + #echo "$p_field\n"; var_dump($t_info); exit; + return $t_info["$p_field"]; + } + } + + return false; + } + ### -------------------- + # allow an array of visibilities as a parameter + function note_queue_count() { + # the reason of including the page is to avoid counting orphan + # notes. + $query = "SELECT COUNT(*) + FROM " . config_get( 'phpWN_note_table' ) . " n, + " . config_get( 'phpWN_page_table' ) . " p + WHERE n.page_id = p.id AND + visible=" . NOTE_VISIBLE_PENDING; + $result = db_query( $query ); + return db_result( $result, 0, 0 ); + } + ### -------------------- + function note_add( $p_page_id, $p_email, $p_remote_addr, $p_note ) { + note_ensure_mandatory_fields( $p_email, $p_note ); + + if ( ON == config_get('auto_accept_notes') ) { + $t_visible = NOTE_VISIBLE_ACCEPTED; + } else { + $t_visible = NOTE_VISIBLE_PENDING; + } + + $c_page_id = db_prepare_int( $p_page_id ); + $c_email = db_prepare_string( $p_email ); + $c_note = db_prepare_string( $p_note ); + $c_remote_address = db_prepare_string( $p_remote_addr ); + + # @@@@ Also set last-updated field + + $query = "INSERT INTO " . config_get( 'phpWN_note_table' ) . " + ( id, page_id, email, ip, date_submitted, note, visible ) + VALUES + ( null, $c_page_id, '$c_email', '$c_remote_address', NOW(), '$c_note', $t_visible )"; + $result = db_query( $query ); + $result = db_insert_id(); + + page_touch( $p_page_id ); + + return ( $result ); + } + ### -------------------- + function note_get_visibility_str( $p_visible ) { + switch ( $p_visible ) { + case NOTE_VISIBLE_PENDING: + return "Pending"; + case NOTE_VISIBLE_ACCEPTED: + return "Accepted"; + case NOTE_VISIBLE_DECLINED: + return "Declined"; + case NOTE_VISIBLE_ARCHIVED: + return "Archived"; + case NOTE_VISIBLE_DELETED: + return "Deleted"; + default: + return "Unknown"; + } + } + ### -------------------- + function note_update_visibility( $p_id, $p_visibility ) { + $c_id = db_prepare_int( $p_id ); + $c_visibility = db_prepare_int( $p_visibility ); + + $query = "UPDATE " . config_get( 'phpWN_note_table' ) . " + SET visible=$c_visibility + WHERE id=$c_id LIMIT 1"; + $result = db_query( $query ); + + note_touch( $p_id ); + } + ### -------------------- + # Put back as pending if approved by default. + function note_pending( $p_id ) { + note_update_visibility( $p_id, NOTE_VISIBLE_PENDING ); + } + ### -------------------- + function note_accept( $p_id ) { + note_update_visibility( $p_id, NOTE_VISIBLE_ACCEPTED ); + } + ### -------------------- + function note_decline( $p_id ) { + note_update_visibility( $p_id, NOTE_VISIBLE_DECLINED ); + } + ### -------------------- + function note_archive( $p_id ) { + note_update_visibility( $p_id, NOTE_VISIBLE_ARCHIVED ); + } + ### -------------------- + function note_delete( $p_id ) { + note_update_visibility( $p_id, NOTE_VISIBLE_DELETED ); + } + ### -------------------- + function note_pack_deleted() { + $query = "DELETE FROM " . config_get( 'phpWN_note_table' ) . " + WHERE visible=" . NOTE_VISIBLE_DELETED; + $result = db_query( $query ); + } + ### -------------------- + function note_ensure_mandatory_fields( $p_email, $p_note ) { + if ( trim( $p_email ) == '' ) + { + echo sprintf( 'Mandatory field "%s" missing.', 'email'); + exit; + } + + if ( trim( $p_note ) == '' ) + { + echo sprintf( 'Mandatory field "%s" missing.', 'note'); + exit; + } + + } + ### -------------------- + function note_update( $p_id, $p_email, $p_note ) { + note_ensure_mandatory_fields( $p_email, $p_note ); + + $c_id = db_prepare_int( $p_id ); + $c_email = db_prepare_string( $p_email ); + $c_note = db_prepare_string( $p_note ); + + $query = "UPDATE " . config_get( 'phpWN_note_table' ) . " + SET email='$c_email', note='$c_note' + WHERE id=$c_id LIMIT 1"; + $result = db_query( $query ); + + note_touch( $p_id ); + + return ( $result ); + } + ### -------------------- + function note_get_page_id( $p_note_id ) { + $t_note_info = note_get_info( note_where_id_equals ( $p_note_id ) ); + if ( false === $t_note_info ) { + return false; + } + + return $t_note_info['page_id']; + } + ### -------------------- + function note_touch( $p_note_id, $p_page_id = null ) { + if ( null === $p_page_id ) { + $p_page_id = note_get_page_id( $p_note_id ); + } + + page_touch( $p_page_id ); + } + ### -------------------- + function note_get_all_visible( $p_page_id ) { + $notes = array(); + + $t_page_info = page_get_info( page_where_id_equals( $p_page_id ) ); + if ( false === $t_page_info ) { + return false; + } + + $c_page_id = db_prepare_int( $p_page_id ); + + $query = "SELECT *, UNIX_TIMESTAMP(date_submitted) as date_submitted + FROM " . config_get( 'phpWN_note_table' ) . " + WHERE page_id=$c_page_id + ORDER BY date_submitted " . config_get( 'note_order' ); + + $result = db_query( $query ); + while ( $row = db_fetch_array( $result ) ) { + extract( $row, EXTR_PREFIX_ALL, 'v' ); + + if ( ( NOTE_VISIBLE_PENDING == $v_visible ) && ( access_check_action( ACTION_NOTES_VIEW_PENDING ) === false ) ) { + continue; + } + + if ( ( NOTE_VISIBLE_ACCEPTED == $v_visible ) && ( access_check_action( ACTION_NOTES_VIEW_ACCEPTED ) === false ) ) { + continue; + } + + if ( ( NOTE_VISIBLE_DECLINED == $v_visible ) && ( access_check_action( ACTION_NOTES_VIEW_DECLINED ) === false ) ) { + continue; + } + + if ( ( NOTE_VISIBLE_ARCHIVED == $v_visible ) && ( access_check_action( ACTION_NOTES_VIEW_ARCHIVED ) === false ) ) { + continue; + } + + if ( ( NOTE_VISIBLE_DELETED == $v_visible ) && ( access_check_action( ACTION_NOTES_VIEW_DELETED ) === false ) ) { + continue; + } + + $info['visible'] = $v_visible; + $info['id'] = $v_id; + $info['email'] = string_prepare_note_for_viewing ( $v_email, $t_page_info['url'] ); + $info['note'] = string_prepare_note_for_viewing ( $v_note, $t_page_info['url'] ); + + $info['date'] = $v_date_submitted; + + $notes[] = $info; + } + + return( $notes ); + } + ### -------------------- + # @@@@ Should be obsolete soon! + function note_queue( $p_only_one = true ) { + $query = "SELECT n.id as note_id, n.*, p.page + FROM " . config_get( 'phpWN_note_table' ) . " n, + " . config_get( 'phpWN_page_table' ) . " p + WHERE n.visible=" . NOTE_VISIBLE_PENDING . " + AND n.page_id=p.id"; + + if ( $p_only_one ) { + $query .= ' LIMIT 1'; + } else { + $query .= ' ORDER BY p.page, n.date_submitted'; + } + + return db_query( $query ); + } + ### -------------------- +?> diff --git a/common/code/webnotes/core/page_api.php b/common/code/webnotes/core/page_api.php new file mode 100644 index 00000000..e1576ab2 --- /dev/null +++ b/common/code/webnotes/core/page_api.php @@ -0,0 +1,389 @@ + '')"); + } + ### -------------------- + function page_where_id_equals( $p_page_id ) { + $c_page_id = db_prepare_int( $p_page_id ); + return ("(id=$c_page_id)"); + } + ### -------------------- + function page_where_all() { + return ("(1=1)"); + } + ### -------------------- + function page_where_page_equals( $p_page ) { + $c_page = db_prepare_string( $p_page ); + return ("(page='$c_page')"); + } + ### -------------------- + # $p_where is constructed by page_where* and hence does not need to be cleaned. + function page_get_info ( $p_where, $p_field = null ) { + $query = "SELECT *, UNIX_TIMESTAMP(last_updated) as last_updated + FROM " . config_get( 'phpWN_page_table' ) . " + WHERE $p_where + LIMIT 1"; + + $result = db_query( $query ); + if ( db_num_rows( $result) > 0 ) { + $t_info = db_fetch_array( $result ); + + if ( null === $p_field ) { + return $t_info; + } else { + #echo "$p_field\n"; var_dump($t_info); exit; + return $t_info["$p_field"]; + } + } + + return false; + } + ### -------------------- + # $p_where is constructed by page_where* and hence does not need to be cleaned. + function page_get_array ( $p_where, $p_order = null ) { + if ( null !== $p_order ) { + $c_order = 'ORDER BY ' . db_prepare_string( $p_order ); + } else { + $c_order = ''; + } + + $query = "SELECT *, UNIX_TIMESTAMP(last_updated) as last_updated + FROM " . config_get( 'phpWN_page_table' ) . " + WHERE $p_where + $c_order"; + + $t_array = array(); + $result = db_query( $query ); + while ( $row = db_fetch_array( $result ) ) { + $t_array[] = $row; + } + + return $t_array; + } + ### -------------------- + function page_get_id( $p_page ) { + return ( page_get_info( page_where_page_equals( $p_page ), 'id' ) ); + } + ### -------------------- + function page_valid_id( $p_page_id ) { + return ( false !== $p_page_id ); + } + ### -------------------- + function page_is_indexed( $p_page ) { + return ( page_valid_id( page_get_id( $p_page ) ) ); + } + ### -------------------- + function page_visible_notes_count( $p_page_id ) { + $c_page_id = db_prepare_int( $p_page_id ); + + $query = "SELECT COUNT(*) + FROM " . config_get( 'phpWN_note_table' ) . " + WHERE page_id=$c_page_id AND visible=" . NOTE_VISIBLE_ACCEPTED; + $result = db_query( $query ); + return db_result( $result, 0, 0 ); + } + ### -------------------- + function page_notes_count( $p_page_id ) { + $c_page_id = db_prepare_int( $p_page_id ); + + $query = "SELECT COUNT(*) + FROM " . config_get( 'phpWN_note_table' ) . " + WHERE page_id=$c_page_id"; + $result = db_query( $query ); + return db_result( $result, 0, 0 ); + } + ### -------------------- + function page_get_name( $p_page_id ) { + $c_page_id = db_prepare_int( $p_page_id ); + + $query = "SELECT page + FROM " . config_get( 'phpWN_page_table' ) . " + WHERE id=$c_page_id + LIMIT 1"; + + $result = db_query( $query ); + if ( db_num_rows( $result) > 0 ) { + return db_result( $result, 0, 0 ); + } + + return false; + } + ### -------------------- + function page_update_url( $p_page_id, $p_url ) { + $t_url = page_get_info( page_where_id_equals( $p_page_id ), 'url' ); + if ( $t_url === $p_url ) { + return; + } + + # @@@@ If the information is the same, then don't update/touch. + + $c_page_id = db_prepare_int( $p_page_id ); + $c_url = db_prepare_string( $p_url ); + + $query = "UPDATE " . config_get( 'phpWN_page_table' ) . " + SET url='$c_url' + WHERE id=$c_page_id LIMIT 1"; + $result = db_query( $query ); + page_touch( $p_page_id ); + } + ### -------------------- + function page_update_neighbours( $p_page_id, $p_prev, $p_next, $p_parent ) { + if ( ( null === $p_prev ) && ( null === $p_next ) && ( null === $p_parent ) ) { + return; + } + + $t_page_info = page_get_info( page_where_id_equals( $p_page_id ) ); + if ( false === $t_page_info ) { + return; + } + + if ( null === $p_parent ) { + $t_parent_id = $t_page_info['parent_id']; + } else { + $t_parent_id = page_get_id( $p_parent ); + if ( false === page_valid_id( $t_parent_id ) ) { + $t_parent_id = 0; + } + } + + if ( null === $p_prev ) { + $t_prev_id = $t_page_info['prev_id']; + } else { + $t_prev_id = page_get_id( $p_prev ); + if ( false === page_valid_id( $t_prev_id ) ) { + $t_prev_id = 0; + } + } + + if ( null === $p_next ) { + $t_next_id = $t_page_info['next_id']; + } else { + $t_next_id = page_get_id( $p_next ); + if ( false === page_valid_id( $t_next_id ) ) { + $t_next_id = 0; + } + } + + # If the information is the same, then don't update/touch. + if ( ( $t_parent_id == $t_page_info['parent_id'] ) && + ( $t_prev_id == $t_page_info['prev_id'] ) && + ( $t_next_id == $t_page_info['next_id'] ) ) { + return; + } + + $c_page_id = db_prepare_int( $p_page_id ); + + $query = "UPDATE " . config_get( 'phpWN_page_table' ) . " + SET parent_id=$t_parent_id, prev_id=$t_prev_id, next_id=$t_next_id + WHERE id=$c_page_id LIMIT 1"; + $result = db_query( $query ); + page_touch( $p_page_id ); + } + ### -------------------- + # Update the last modified time stamp for the page. + function page_touch( $p_page_id ) { + $c_page_id = db_prepare_int( $p_page_id ); + + $query ='UPDATE ' . config_get( 'phpWN_page_table') . ' ' . + "SET last_updated=NOW() " . + "WHERE id=$c_page_id " . + "LIMIT 1"; + + return ( false !== db_query( $query ) ); + } + ### -------------------- + ### Allows for path navigation to choose base dir + function print_dirs( $p_path, $p_php_self ) { + global $g_admin_index_files; + + echo ''; + + $handle = opendir( $p_path ); + while ( $file = readdir( $handle ) ) { + if ( is_dir( $p_path . $file ) && ( $file != '.' ) ) { + if ( $file == '..' ) { + $t_dir = dirname( $p_path ); + } else { + $t_dir = $p_path . $file; + } + $t_dir = urlencode( $t_dir ); + echo ""; + } + } + closedir( $handle ); + + $handle = opendir( $p_path ); + while ( $file = readdir( $handle ) ) { + if ( !is_dir( $p_path . $file ) ) { + $t_filename = $p_path . $file; + $t_id = page_get_id( $t_filename ); + #echo "$file
"; + $t_add = !page_valid_id( $t_id ); + if ( !$t_add ) { + $t_count = '(' . page_visible_notes_count( $t_id ) . ')'; + } else { + $t_count = ''; + } + + echo ""; + } + } + closedir( $handle ); + + echo '
[$file]
" . link_page_action( $t_filename, 'index', $p_php_self, $t_add ) . ' ' . link_page_action( $t_id, 'unindex', $p_php_self, !$t_add ). "$file$t_count
'; + } + ### -------------------- + function page_add( $p_page_name ) { + # if page already exists, return to avoid duplicates + if ( page_get_id( $p_page_name ) !== false ) { + return 0; + } + + $c_page_name = db_prepare_string( $p_page_name ); + + $query = "INSERT INTO " . config_get( 'phpWN_page_table' ) . " + ( id, date_indexed, last_updated, page ) + VALUES + ( null, NOW(), NOW(), '$c_page_name' )"; + $result = db_query( $query ); + + return $result; + } + ### -------------------- + function page_add_dir( $p_path='', $p_recursive=true ) { + $dirs = array(); + $files = array(); + + $handle = opendir( $p_path ); + while ( $file = readdir( $handle ) ) { + if ( ( $file == '.' ) || ( $file == '..' ) ) { + continue; + } + + if ( is_dir( $p_path . $file ) ) { + $dirs[] = $file; + } else { + $files[] = $file; + } + } + closedir( $handle ); + sort( $dirs ); + sort( $files ); + + foreach ( $files as $file ) { + $t_filename = $p_path . $file; + page_add( $t_filename ); + } + + # if not recursive return before processing sub-directories + if ( !$p_recursive ) { + return; + } + + foreach ( $dirs as $dir ) { + page_add_dir( $p_path . $dir . DIRECTORY_SEPARATOR ); + } + } + ### -------------------- + function page_delete_notes( $p_page_id ) { + $c_page_id = db_prepare_int( $p_page_id ); + + $query = "DELETE FROM " . config_get( 'phpWN_note_table' ) . " + WHERE page_id=$c_page_id"; + + $result = db_query( $query ); + + return true; + } + ### -------------------- + function page_delete( $p_page_id ) { + if ( !page_delete_notes( $p_page_id ) ) { + return false; + } + + $c_page_id = db_prepare_int( $p_page_id ); + + $query = "DELETE FROM " . config_get( 'phpWN_page_table' ) . " + WHERE id=$c_page_id + LIMIT 1"; + + $result = db_query( $query ); + + return true; + } + ### -------------------- + function page_prepare_theme_data( $p_page_id ) { + $t_page_data = array(); + + $t_page_info = page_get_info( page_where_id_equals( $p_page_id ) ); + if ( false === $t_page_info ) { + return (false); + } + + $t_page_data['id'] = $t_page_info['id']; + $t_page_data['page'] = $t_page_info['page']; + $t_page_data['url'] = $t_page_info['url']; + $t_page_data['last_updated'] = $t_page_info['last_updated']; + $t_page_data['preview'] = false; + + $t_prev_page = page_get_info( page_where_id_equals( $t_page_info['prev_id'] ) ); + $t_next_page = page_get_info( page_where_id_equals( $t_page_info['next_id'] ) ); + + if ( false === $t_prev_page ) { + $t_page_data['prev_page'] = ''; + $t_page_data['prev_url'] = ''; + } else { + $t_page_data['prev_page'] = $t_prev_page['page']; + $t_page_data['prev_url'] = $t_prev_page['url']; + } + + if ( false === $t_next_page ) { + $t_page_data['next_page'] = ''; + $t_page_data['next_url'] = ''; + } else { + $t_page_data['next_page'] = $t_next_page['page']; + $t_page_data['next_url'] = $t_next_page['url']; + } + + $t_page_data['notes'] = note_get_all_visible( $p_page_id ); + + return( $t_page_data ); + } + ### -------------------- + function page_visit( $p_page_id ) { + $c_page_id = db_prepare_int( $p_page_id ); + $query ='UPDATE ' . config_get( 'phpWN_page_table') . ' ' . + "SET visits=visits+1 " . + "WHERE id=$c_page_id " . + "LIMIT 1"; + return ( false !== db_query( $query ) ); + } + ### -------------------- + function page_visits_count( $p_page_id ) { + $c_page_id = db_prepare_int( $p_page_id ); + + $query = "SELECT visits + FROM " . config_get( 'phpWN_page_table' ) . " + WHERE id=$c_page_id + LIMIT 1"; + + $result = db_query( $query ); + if ( db_num_rows( $result) > 0 ) { + return db_result( $result, 0, 0 ); + } + + return false; + } + ### -------------------- + +?> diff --git a/common/code/webnotes/core/php_api.php b/common/code/webnotes/core/php_api.php new file mode 100644 index 00000000..f4b86b01 --- /dev/null +++ b/common/code/webnotes/core/php_api.php @@ -0,0 +1,80 @@ + (int)$t_minver[$i] ) { + return true; + } + } + + # if we get here, the versions must match exactly so: + return true; + } + # -------------------- + + # Enforce our minimum requirements + if ( ! php_version_at_least( PHP_MIN_VERSION ) ) { + ob_end_clean(); + echo 'Your version of PHP is too old. Webnotes requires PHP version ' . PHP_MIN_VERSION . ' or newer
'; + phpinfo(); + die(); + } + + ini_set('magic_quotes_runtime', 0); + + # Experimental support for $_* auto-global variables in PHP < 4.1.0 + if ( ! php_version_at_least( '4.1.0' ) ) { + global $_REQUEST, $_GET, $_POST, $_COOKIE, $_SERVER; + + $_GET = $HTTP_GET_VARS; + $_POST = $HTTP_POST_VARS; + $_COOKIE = $HTTP_COOKIE_VARS; + $_SERVER = $HTTP_SERVER_VARS; + + $_REQUEST = $HTTP_COOKIE_VARS; + foreach ($HTTP_POST_VARS as $key => $value) { + $_REQUEST[$key] = $value; + } + foreach ($HTTP_GET_VARS as $key => $value) { + $_REQUEST[$key] = $value; + } + } + + # @@@ Experimental + # deal with register_globals being Off + # @@@ NOTE we want to get rid of this once we start getting all + # our GPC variables with functions. In fact we may want to + # turn off register_global_variables if we can + if ( false == ini_get( 'register_globals' ) ) { + extract( $_REQUEST ); + extract( $_SERVER ); + } +?> diff --git a/common/code/webnotes/core/pwn_api.php b/common/code/webnotes/core/pwn_api.php new file mode 100644 index 00000000..cf58beb4 --- /dev/null +++ b/common/code/webnotes/core/pwn_api.php @@ -0,0 +1,105 @@ +\"$p_page_top\"$p_page_top
\n"; + } + + if ( ( $p_page_parent != null ) && ( $p_page_parent != $p_page_top ) ) { + echo "
\n"; + $link = pwn_page_get_link( $p_page_parent ); + echo "\"$p_page_parent\"$p_page_parent
"; + } + + $siblings = pwn_page_get_siblings_array( $p_page ); + if ( count( $siblings ) > 0 ) { + echo ""; + + foreach( $siblings as $sibling ) { + if ( $sibling == $p_page ) { + $bullet = $image_current; + } else { + $bullet = $image_sibling; + } + $link = pwn_page_get_link( $sibling ); + echo "\"$sibling\"$sibling
"; + } + + echo "
"; + } + } +?> \ No newline at end of file diff --git a/common/code/webnotes/core/string_api.php b/common/code/webnotes/core/string_api.php new file mode 100644 index 00000000..7aa9d280 --- /dev/null +++ b/common/code/webnotes/core/string_api.php @@ -0,0 +1,123 @@ +", htmlspecialchars(stripslashes( $p_string ))); + } + ### -------------------- + function string_edit( $p_string ) { + return str_replace( "
", "", stripslashes( $p_string ) ); + } + ### -------------------- + # return just the URL portion of the file path + function string_get_url( $p_page ) { + global $DOCUMENT_ROOT; + return substr( $p_page, strlen($DOCUMENT_ROOT), strlen($p_page)); + } + ### -------------------- + function string_preserve_spaces( $p_string ) { + $p_string = str_replace( "\t", "        ", $p_string ); + return str_replace( " ", " ", $p_string ); + } + ### -------------------- + # Preserve spaces at beginning of lines. + function string_preserve_spaces_at_bol( $p_string ) { + $lines = explode("\n", $p_string); + for ( $i = 0; $i < count( $lines ); $i++ ) { + $count = 0; + $prefix = ''; + while ( substr($lines[$i], $count, 1) == ' ' ) { + $count++; + } + for ($j = 0; $j < $count; $j++) { + $prefix .= ' '; + } + $lines[$i] = $prefix . substr( $lines[$i], $count ); + + } + $result = implode( "\n", $lines ); + return $result; + } + ### -------------------- + function string_to_form( $p_string ) { + return htmlspecialchars( addslashes( $p_string ) ); + } + ### -------------------- + function string_add_note_links( $p_page_url, $p_note ) { + return ( preg_replace( '/#([0-9]+)/', "#\\1", $p_note ) ); + } + ### -------------------- + function string_emotions( $p_note ) { + if ( OFF == config_get( 'enable_smileys' ) ) { + return $p_note; + } + + $images_dir = config_get( 'web_directory' ) . 'images/'; + + $smile = ':)'; + $sad = ':('; + $wink = ';)'; + $big_smile = ':D'; + $cool = '8-D'; + $mad = '>-('; + $shocked = ':-*'; + + $p_note = str_replace( ':)', $smile, $p_note ); + $p_note = str_replace( ':-)', $smile, $p_note ); + $p_note = str_replace( ':(', $sad, $p_note ); + $p_note = str_replace( ':-(', $sad, $p_note ); + $p_note = str_replace( ';)', $wink, $p_note ); + $p_note = str_replace( ';-)', $wink, $p_note ); + $p_note = str_replace( ':D', $big_smile, $p_note ); + $p_note = str_replace( ':-D', $big_smile, $p_note ); + $p_note = str_replace( '8-)', $cool, $p_note ); + $p_note = str_replace( '>-(', $mad, $p_note ); + $p_note = str_replace( ':-*', $shocked, $p_note ); + + return ( $p_note ); + } + ### -------------------- + function string_hyperlink( $p_note_string ) { + $p_note_string = preg_replace("/(http:\/\/[0-9a-zA-Z\-\._\/\?=]+)/", "\\1", $p_note_string); + $p_note_string = preg_replace("/(mailto:[0-9a-zA-Z\-\._@]+)/", "\\1", $p_note_string); + return ($p_note_string); + } + ### -------------------- + function string_icq_status( $p_note_string ) { + return (preg_replace("/icq:\/\/([0-9]+)/", "\\0", $p_note_string )); + } + ### -------------------- + function string_prepare_note_for_viewing( $p_note_string, $p_url = null ) { + $p_note_string = htmlspecialchars( $p_note_string ); + $p_note_string = string_preserve_spaces_at_bol( $p_note_string ); + $p_note_string = string_hyperlink( $p_note_string ); + $p_note_string = string_icq_status( $p_note_string ); + if ( null !== $p_url ) { + $p_note_string = string_add_note_links( $p_url, $p_note_string ); + } + + $p_note_string = string_emotions( $p_note_string ); + return ($p_note_string); + } + ### -------------------- +?> \ No newline at end of file diff --git a/common/code/webnotes/core/user_api.php b/common/code/webnotes/core/user_api.php new file mode 100644 index 00000000..f6def56f --- /dev/null +++ b/common/code/webnotes/core/user_api.php @@ -0,0 +1,225 @@ +Duplicate user.

"; + return false; + } + + if ( false !== user_get_info( user_where_email_equals( $p_email ) ) ) { + echo "

Duplicate email.

"; + return false; + } + + if ( null === $p_access_level ) { + $p_access_level = REGISTERED; # @@@@ Move to config. + } + + $c_username = db_prepare_string( $p_username ); + $c_email = db_prepare_string( $p_email ); + $c_encrypted_password = db_prepare_string( access_encrypt_password( $p_password ) ); + $c_enabled = db_prepare_int( $p_enabled ); + $c_protected = db_prepare_int( $p_protected ); + + $t_seed = $p_email . $p_username; + $t_cookie_string = create_cookie_string( $t_seed ); + $c_cookie_string = db_prepare_string( $t_cookie_string ); + + $query = "INSERT INTO phpWN_user_table (username, password, email, cookie_string, access_level, enabled, protected) + VALUES ('$c_username', '$c_encrypted_password', '$c_email', '$c_cookie_string', $p_access_level, $c_enabled, $c_protected)"; + $result = mysql_query($query); + + return( false !== $result ); + } + ### -------------------- + function user_signup( $p_username, $p_email ) { + # Check to see if signup is allowed + if ( OFF == config_get( 'allow_signup' ) ) { + return false; + } + + if ( empty( $p_username ) || empty( $p_email ) ) { + return false; + } + + $t_password = create_random_password( $p_email ); + + if ( false === user_create( $p_username, $t_password, $p_email ) ) { + return false; + } + + email_signup($p_username, $t_password, $p_email); + + return true; + } + ### -------------------- + function user_where_current( ) { + global $g_string_cookie_val; + return ( user_where_cookie_equals( $g_string_cookie_val ) ); + } + ### -------------------- + function user_where_id_equals( $p_id ) { + $c_id = db_prepare_int( $p_id ); + return ("(id='$c_id')"); + } + ### -------------------- + function user_where_username_equals( $p_username ) { + $c_username = db_prepare_string( $p_username ); + return ("(username='$c_username')"); + } + ### -------------------- + function user_where_username_equals_and_enabled( $p_username ) { + $c_username = db_prepare_string( $p_username ); + return ("((username='$c_username') AND (enabled=1))"); + } + ### -------------------- + function user_where_email_equals( $p_email ) { + $c_email = db_prepare_string( $p_email ); + return ("(email='$c_email')"); + } + ### -------------------- + function user_where_cookie_equals( $p_cookie ) { + $c_cookie = db_prepare_string( $p_cookie ); + return ("(cookie_string='$c_cookie')"); + } + ### -------------------- + # The parameter passed to this function is constructed via user_where_*(). + # $p_where is not cleaned, since it is assume that all the necessary escaping is + # done in the function that constructed the where statement. + function user_get_info( $p_where ) { + $query = "SELECT * + FROM " . config_get( 'phpWN_user_table' ) . " + WHERE $p_where + LIMIT 1"; + + $result = db_query( $query ); + if ( false === $result ) { + return false; + } + + $row = db_fetch_array( $result ); + if ( false === $row ) { + return false; + } + + return $row; + } + ### -------------------- + function user_get_all() { + global $g_phpWN_user_table; + + $t_users_array = array(); + + $query = "SELECT * + FROM $g_phpWN_user_table"; + $result = db_query( $query ); + if ( !$result ) { + return false; + } + + while ( $row = db_fetch_array( $result ) ) { + $t_users_array[] = $row; + } + + return $t_users_array; + } + ### -------------------- + function user_get_row( $p_user_id ) { + global $g_phpWN_user_table; + + $t_users_array = array(); + + $query = "SELECT * + FROM $g_phpWN_user_table + WHERE id='$p_user_id'"; + $result = db_query( $query ); + if ( !$result ) { + return false; + } + + return db_fetch_array( $result ); + } + ### -------------------- + # $p_where is constructed using user_where_*(). + function user_change_password( $p_where, $p_old_password, $p_new_password, $p_verify_password = null ) { + $t_user = user_get_info( $p_where ); + if ( false === $t_user ) { + return false; ## error message printed by user_get_info(). + } + + if ( !access_verify_login( $t_user['username'], $p_old_password ) ) { + echo 'Original password is incorrect.
'; + return false; + } + + if ( ( $p_verify_password !== null ) && ( $p_verify_password != $p_new_password ) ) { + echo 'New and verify passwords do not match.
'; + return false; + } + + $t_password = access_encrypt_password( $p_new_password ); + $c_password = db_prepare_string( $t_password ); + + $query = "UPDATE " . config_get( 'phpWN_user_table' ) . " + SET password='$c_password' + WHERE $p_where"; + $result = db_query( $query ); + if ( false === $result ) { + return false; + } + + return true; + } + ### -------------------- + # we assume that the password has been checked for accuracy + # we assume that the enabled value is 0 or 1 + function user_update( $p_user_id, $p_email, $p_password, $p_access_level, $p_enabled, $p_protected ) { + global $g_phpWN_user_table; + + if ( empty( $p_password ) ) { + $t_user_row = user_get_row( $p_user_id ); + $c_password = $t_user_row['password']; + } else { + $c_password = db_prepare_string( access_encrypt_password( $p_password ) ); + } + + $c_user_id = db_prepare_int( $p_user_id ); + $c_email = db_prepare_string( $p_email ); + $c_access_level = db_prepare_string( $p_access_level ); + $c_enabled = db_prepare_string( $p_enabled ); + $c_protected = db_prepare_string( $p_protected ); + + $query = "UPDATE $g_phpWN_user_table + SET email='$c_email', + password='$c_password', + access_level=$c_access_level, + enabled=$c_enabled, + protected=$c_protected + WHERE id=$c_user_id"; + return db_query( $query ); + } + ### -------------------- + function user_delete( $p_user_id ) { + global $g_phpWN_user_table; + + $c_user_id = db_prepare_int( $p_user_id ); + + $query = "DELETE FROM $g_phpWN_user_table + WHERE id=$c_user_id"; + return db_query( $query ); + } + ### -------------------- +?> \ No newline at end of file diff --git a/common/code/webnotes/core/util_api.php b/common/code/webnotes/core/util_api.php new file mode 100644 index 00000000..54afa039 --- /dev/null +++ b/common/code/webnotes/core/util_api.php @@ -0,0 +1,84 @@ + \ No newline at end of file diff --git a/common/code/webnotes/doc/CREDITS b/common/code/webnotes/doc/CREDITS new file mode 100644 index 00000000..7167fd3a --- /dev/null +++ b/common/code/webnotes/doc/CREDITS @@ -0,0 +1,27 @@ +# phpWebNotes - a php based note addition system +# Copyright (C) 2000-2002 Webnotes Team - webnotes-devel@sourceforge.net +# This program is distributed under the terms and conditions of the GPL +# See the files README and LICENSE for details + +*** Please contact Webnotes administrators if you should be on this list! + +CREDITS + +Administrators +-------------- + +Kenzaburo Ito (prescience) +Victor Boctor (vboctor) + +Developers +---------- + +Remon Metira (rmetira) +Mantis Team (mantisbt.sf.net - some code was re-used from Mantis Bugtracker) +Roland Verlander (roly) + +Translations +------------ + +Dat-Son Nguyen (French) +Luca Pecatore (Italian) diff --git a/common/code/webnotes/doc/ChangeLog b/common/code/webnotes/doc/ChangeLog new file mode 100644 index 00000000..1c7b5d99 --- /dev/null +++ b/common/code/webnotes/doc/ChangeLog @@ -0,0 +1,65 @@ +# phpWebNotes - a php based note addition system +# Copyright (C) 2000-2002 Webnotes Team - webnotes-devel@sourceforge.net +# This program is distributed under the terms and conditions of the GPL +# See the files README and LICENSE for details + +phpWebNotes + +??.??-2003 - 2.0.0 + * Database Change: Added protected field in the users table. + * Database Change: Added visits field in the pages table. + * Added support for protected users. These users are useful for demo account to disallow users from changing password / email / ..etc. + * Fixed a problem where the ?var=value portions of http addresses were not hyperlinked. + * Added current time, last updated time for each page, number of notes of notes for each page to the manage notes page. + * Added support for tracking the number of hits on each page. + * Display the number of hits on each page in the manage notes page. + * Send email notifications to moderators/administrators on addition/update of notes. + * Fix #100: column "cookie_string" must be 64 not 32. + * Added Danish localization. + +06.10-2002 - 2.0.0pr1 (2.0.0 pre-release 1) + * Fixed bug causing weird "headers already sent in whatever" errors on some servers + * convertToPHP3 script removed + * Added directory core/ to include source files that are not accessed directly through the web. + * Added directory sql/ to include SQL files to be used to create/upgrade the database. + * Added directory themes/ to include different themes to be used to view the webnotes. + * Added directory lang/ to contain the localisation files. + * Added directory doc/ to contain documentation files. + * Added directory sample/ to contain sample files that can be used to test phpWebNotes. + * Cleanup of all files for better readability and complying with coding standards. + * Change the extension of the language files to .php rather than .txt. + * Moved to XHTML + * Integrated the Italian/French strings into cvs. + * Added support for themes (#2). + * Added admin_pending.php to allow moderating notes in any order (#10). + * Added $g_auto_accept_notes to allow auto-accepting of notes (useful for demos and Intranet installations) + * Added $g_auto_index_pages to allow auto-indexing for pages which call phpWebNotes but are not indexed. Default is ON. + * Added the preview note support + * Added support for MD5 and plain password authentication (with MD5 as the default). + * Changed the encrypted password field size from 16 to 32 characters (for MD5 support). + * Added warning to login page, if default account is not disabled. + * Added warning to login page, if plain passwords are used. + * Fixed a problem in db_generate.sql where the administrator account had access level 0 and was not enabled. + * Added db_upgrade.sql to upgrade the db and include the password field change. + * Added support for cross referencing between notes on the same document (#). + * Added user sign up support ($g_allow_signup) + * Added core/enum_api.php to support enumeration strings. + * Built infrastructure for multiple access levels. + * Implemented inline moderation where the moderators can moderate notes on the actual pages. + * Viewing notes based on access level rather than displaying all accepted notes for everybody. + * Added support for prev / next documents. + * Added pwn_api.php to act the the main interface to phpWebNotes. + * Added support for Last Updated timestamp for pages. + * Added support for emotions icons. + * Added support for icq online status when detecting the format: "icq://9999999". + * Added support for the enabled field in the user table. + * Added $g_auto_set_email to allow defaulting e-mail for logged in users. + * Added support for parent page + APIs to allow easy support for PHP-like Manuals. + +03.12.2001 - 1.0.0 + + * Rewrite and release + +01.01.2001 - 0.9.0 + + * Initial release diff --git a/common/code/webnotes/doc/INSTALL b/common/code/webnotes/doc/INSTALL new file mode 100644 index 00000000..7013ab4e --- /dev/null +++ b/common/code/webnotes/doc/INSTALL @@ -0,0 +1,139 @@ +# phpWebNotes - a php based note addition system +# Copyright (C) 2000-2002 Webnotes Team - webnotes-devel@sourceforge.net +# This program is distributed under the terms and conditions of the GPL +# See the files README and LICENSE for details + +------------------------------------------------------------------------------- +### Installation steps ### +------------------------------------------------------------------------------- + +*** REQUIREMENTS: MySql database, php 4.0.6 and higer (4.1.2+ recommended), a webserver (tested on Apache and IIS,should work anything else PHP will run with). + +1. First, transfer the file to your webserver. You will need to telnet/ssh into +the server for the next steps. + +2. Next, untar/gunzip it to the directory that you want. (On Linux type tar zxf filename.tar.gz to decompress) + +3. After that you will need to cd into the sql/ folder under the webnotes +directory and locate the db_generate.sql file. Run the following command: + +mysql -u -p < db_generate.sql + +Then you will need to upgrade the db to the latest (that's only needed if you have +downloaded a CVS version). + +mysql -u -p < db_upgrade.sql + +If you installed MySQL from source code you may have to add /usr/local/mysql/bin/ infront of those commands + +You could also cut and paste the sql statements from db_generate.sql into a +package like phpMyAdmin. You will need to have created the database ahead of +time. + +4. Create core/custom_config_inc.php which overrides the default values in +config_defaults_inc.php. You can edit directly the config_defaults_inc.php but +this will make it harder to upgrade to future releases of phpWebNotes. In particular you +will want to set the database variables: hostname, username, password, and +database name. These must be set to match the configuration of your webserver and mysql +database. Also, don't forget to input the correct directory paths. + +5. For every page that you want notes to be available you will need to convert +their extension to one that is interpreted by PHP (Such as .php). Then: + +Insert the following inside the <head> </head> tag): + +<? + require_once('/mypath/core/api.php'); # replace with actual path + pwn_head(); +?> + +Insert the following into the bottom of the document (before the </body> tag): + +<? + pwn_body( 'my-page-logical-name', $PHP_SELF, $page_prev, $page_next, $page_parent ); +?> + +You can replace the 'my-page-logical-name' with __FILE__ or basename( __FILE__ ) +if you don't want to assign ids to the pages. + +The require_once argument should be the absolute path to your installation of +phpWebNotes. It should not be relative to what your browser would see. +This way if you have lots of files in different directories you will always +be able to add the web note functionality to each page. + +6. If you want the pages to auto-index (register themselves) in the database +(default) then skip the next step. + +7. You will need to index the files in your website. Open up the phpWebNotes +directory in your web browser and login. The default username and password is +administrator / root. You should change this later on! Open up the "File +Index" page. Select the root directory and then choose the Index button. It +indexes all files in the directory it is located in and all subdirectories. + +8. If you need the notes to be moderated before they appear on the webpage then +leave $g_auto_accept_notes = OFF, otherwise set it to ON and go to step 11. + +9. Notes will be added as pending. They need to be approved by the moderator/ +administrator before they will become visible. This can be done by loggin in and +then visiting the page. All notes will have the actions next to them, to approve +a note, the [ Accept ] action should be clicked. + +10. You can edit or delete notes later on by going to the page. This option will +only be available if you have logged in as a moderator/administrator. + +11. The next step is to get the sample working. This depends on the auto-index feature. +For each page we need to index it, and add links to parent, previous, and next. All +these links can only be established if the page we are linking to is already linked. +Hence, we need to visit each page to index it, and we also need to visit it again when +all its neighbours are indexed and already visited (i.e. they know they own urls). + +Webopedia + |_ Markup + | |_ xml + | |_ xhtml + | + |_ Web Services + +a. Visit http://.../webnotes/sample/webopedia.php [ this will index webopedia page ] +b. Visit http://.../webnotes/sample/markup.php [ this will index markup, and add Webopedia as parent / prev ] +c. Visit http://.../webnotes/sample/xml.php [ this will index xml, add markup as parent, prev ] +d. Visit http://.../webnotes/sample/xhtml.php [ this will index xhtml, add markup as parent, xml as prev ] +e. Visit http://.../webnotes/sample/webservices.php [ this will index web services, add webopedia as parent, xhtml as prev ] +f. Visit http://.../webnotes/sample/xhtml.php [ this will add web services as next ] +g. Visit http://.../webnotes/sample/xml.php [ this will add xhtml as next ] +h. Visit http://.../webnotes/sample/markup.php [ this will add xml as next ] +i. Visit http://.../webnotes/sample/webopedia.php [ this will add markup as next ] + +------------------------------------------------------------------------------- +### Troubleshooting ### +------------------------------------------------------------------------------- + +* PROBLEM: Warning messages prevent you from viewing or adding notes. + +SOLUTION: Your error_level is too high. Open up your php.ini (or php3.ini) +and lower it. There should be enough comments around the variable to help you +out. + +* PROBLEM: After upgrading from phpWebNotes 1.0.0, I can not login. + +SOLUTION: Users were created in version 1.0.0 with enabled equal to 0. This was not +a problem in v1.0.0 because the enabled field was ignored. However, in v2.0.0 enabled +is checked. In order to solve this problem, login to the database and set the enabled +flag to 1 for the accounts that you need enabled. + +* PROBLEM: Adding notes does nothing + +SOLUTION: You may have track_vars set to Off (or 0). Set this to On in your +php.ini file. As of version 4.0.3 and newer it is set to On by default. + +* PROBLEM: phpWebNotes does not work under PHP 4.2 and 4.3 + +SOLUTION: phpWebNotes requires register_globals to be on which used to be enabled +by default in 4.1.2 and older. 4.2.0 and newer have it set to Off as default so +you will have to set register_globals to On in php.ini + +------------------------------------------------------------------------------- +### Useful links ### +------------------------------------------------------------------------------- + +See http://webnotes.sf.net/links.php for useful links. diff --git a/common/code/webnotes/doc/LICENSE b/common/code/webnotes/doc/LICENSE new file mode 100644 index 00000000..5b6e7c66 --- /dev/null +++ b/common/code/webnotes/doc/LICENSE @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/common/code/webnotes/doc/README b/common/code/webnotes/doc/README new file mode 100644 index 00000000..29b3d4ba --- /dev/null +++ b/common/code/webnotes/doc/README @@ -0,0 +1,31 @@ +# phpWebNotes - a php based note addition system +# Copyright (C) 2000-2002 Webnotes Team - webnotes-devel@sourceforge.net +# This program is distributed under the terms and conditions of the GPL +# See the files README and LICENSE for details + +phpWebNotes is a PHP based solution to letting users add their own comments to +a document. It is heavily modelled after the example set by php.net. + +This project was originally conceived to help people who maintain technical +help docs and how-tos. It is more direct than searching through a forum and +less involving for the users than signing up for a mailing list. Of course, +it adapts to other uses easily. + +Updating documents is tedious and documents often lack the real world +examples and experience to make them truly useful. The best help sites we have +ever found had not only detailed documentation but lots and lots of examples +and problems and quirks that appear in real life. Unfortunately this rules +out many man pages (unix help docs). Allowing user comments lets the doc +maintainer do less work. Whenever the maintainer needs to update the doc they +can just roll in the user feedback instead of recreating the information. +This sort of automation cuts down on email and mailing list traffic as well. + +You will need to have PHP, MySql, and a web server. You don't need +to know too much about any of them other than how to set them up and some basic +administration commands. + +The team would appreciate an email letting us know if you find this program +useful. This information will not be published without permission, it will just +provide the team with the feedback that this have proven to be useful for some +people and hence will motivate the team to put more effort into it. Also this +feedback is what we need to keep improving phpWebNotes. diff --git a/common/code/webnotes/doc/ROADMAP b/common/code/webnotes/doc/ROADMAP new file mode 100644 index 00000000..b9235457 --- /dev/null +++ b/common/code/webnotes/doc/ROADMAP @@ -0,0 +1,44 @@ +# phpWebNotes - a php based note addition system +# Copyright (C) 2000-2002 Webnotes Team - webnotes-devel@sourceforge.net +# This program is distributed under the terms and conditions of the GPL +# See the files README and LICENSE for details + +phpWebNotes + +2.0.0 + * General cleanup of the code / rewrite. + * XHTML compliance + * Support for themes + * Implement php.net theme + * Email notifications to moderators/administrators on the submission of new notes. + * Support MD5 password encryption (as the default) + * Database schema modifications + * A new administrator interface to manage pages, notes, and users. + * A new moderator interface to manage notes. + * A new user interface to manage own posting / own information. + * Multiple access levels: Anonymous, Registered, Moderator, Administrator. + * Allowing users to signup (configurable). + * Support auto-accept mode to be used for Intranet / Demo installations. + +2.0.1 + * Bug fixes. + * Language Localisation (English, French, Italian, German). + +2.0.2 + * Factor out the use of hard-coded formatting / colours and replace with styles. + * Caching / speed optimisations. + * Manual + +2.1.0 + * Multiple authentication modes + * Add IP/IP range blocking. + * PAM Support + * FAQ + * Support direct links to specific notes + * Allow certain HTML tags or bbcodes [url], [b], ...etc. + * Ability to assign a set of pages for each moderator to manage. + * Consider replacing cookies with sessions. + +3.0.0 + * Database abstraction + * Logo diff --git a/common/code/webnotes/doc/SCRATCHPAD b/common/code/webnotes/doc/SCRATCHPAD new file mode 100644 index 00000000..35a3cd31 --- /dev/null +++ b/common/code/webnotes/doc/SCRATCHPAD @@ -0,0 +1,18 @@ +# phpWebNotes - a php based note addition system +# Copyright (C) 2000-2002 Webnotes Team - webnotes-devel@sourceforge.net +# This program is distributed under the terms and conditions of the GPL +# See the files README and LICENSE for details + +----------------------------------------- +SCRATCH PAD +----------------------------------------- + +To-Do list: + + * Be able to reverse the display order (vb: they may already be supported) + * Add access_api.php - note_accept() / decline() / update() / delete() should check the access level. + * Consider supporting html only pages. This can be done by a php loader page + some other tricks (output buffering?) + * Indexing page + * Add a link next to each file to open it for viewing. + * API mode for plugability into existing systems. + * Add note on how to parse HTML files through the PHP interpreter. diff --git a/common/code/webnotes/images/bigsmile.gif b/common/code/webnotes/images/bigsmile.gif new file mode 100644 index 00000000..b54cd0f9 Binary files /dev/null and b/common/code/webnotes/images/bigsmile.gif differ diff --git a/common/code/webnotes/images/cool.gif b/common/code/webnotes/images/cool.gif new file mode 100644 index 00000000..2520bcf6 Binary files /dev/null and b/common/code/webnotes/images/cool.gif differ diff --git a/common/code/webnotes/images/mad.gif b/common/code/webnotes/images/mad.gif new file mode 100644 index 00000000..63d39a80 Binary files /dev/null and b/common/code/webnotes/images/mad.gif differ diff --git a/common/code/webnotes/images/sad.gif b/common/code/webnotes/images/sad.gif new file mode 100644 index 00000000..0d8abc8a Binary files /dev/null and b/common/code/webnotes/images/sad.gif differ diff --git a/common/code/webnotes/images/shocked.gif b/common/code/webnotes/images/shocked.gif new file mode 100644 index 00000000..961fd474 Binary files /dev/null and b/common/code/webnotes/images/shocked.gif differ diff --git a/common/code/webnotes/images/smile.gif b/common/code/webnotes/images/smile.gif new file mode 100644 index 00000000..3fb63ae4 Binary files /dev/null and b/common/code/webnotes/images/smile.gif differ diff --git a/common/code/webnotes/images/wink.gif b/common/code/webnotes/images/wink.gif new file mode 100644 index 00000000..62914d80 Binary files /dev/null and b/common/code/webnotes/images/wink.gif differ diff --git a/common/code/webnotes/index.php b/common/code/webnotes/index.php new file mode 100644 index 00000000..3d06ea77 --- /dev/null +++ b/common/code/webnotes/index.php @@ -0,0 +1,13 @@ + \ No newline at end of file diff --git a/common/code/webnotes/lang/strings_danish.php b/common/code/webnotes/lang/strings_danish.php new file mode 100644 index 00000000..24fc6c89 --- /dev/null +++ b/common/code/webnotes/lang/strings_danish.php @@ -0,0 +1,113 @@ + \ No newline at end of file diff --git a/common/code/webnotes/lang/strings_english.php b/common/code/webnotes/lang/strings_english.php new file mode 100644 index 00000000..a8c16362 --- /dev/null +++ b/common/code/webnotes/lang/strings_english.php @@ -0,0 +1,112 @@ + \ No newline at end of file diff --git a/common/code/webnotes/lang/strings_french.php b/common/code/webnotes/lang/strings_french.php new file mode 100644 index 00000000..7269d8d9 --- /dev/null +++ b/common/code/webnotes/lang/strings_french.php @@ -0,0 +1,72 @@ + diff --git a/common/code/webnotes/lang/strings_italian.php b/common/code/webnotes/lang/strings_italian.php new file mode 100644 index 00000000..825e88ca --- /dev/null +++ b/common/code/webnotes/lang/strings_italian.php @@ -0,0 +1,74 @@ + \ No newline at end of file diff --git a/common/code/webnotes/login.php b/common/code/webnotes/login.php new file mode 100644 index 00000000..07c1586a --- /dev/null +++ b/common/code/webnotes/login.php @@ -0,0 +1,50 @@ + \ No newline at end of file diff --git a/common/code/webnotes/login_page.php b/common/code/webnotes/login_page.php new file mode 100644 index 00000000..21d049ca --- /dev/null +++ b/common/code/webnotes/login_page.php @@ -0,0 +1,95 @@ + + ERROR: Unauthorised access for supplied user name and password. + +EOT; + } + + # Warning, if plain passwords are selected + if ( config_get( 'auth_type' ) == AUTH_PLAIN ) { + echo << + WARNING: Plain password authentication is used, this will expose your passwords to administrators. + +EOT; + } + + # Generate a warning if administrator/root is valid. + if ( access_verify_login( 'administrator', 'root' ) ) { + echo << + WARNING: You should disable the "administrator" account or change its password. + +EOT; + } + + echo << +
+
+ + + + + + + + + + + + + + + + + + + + +
$s_login_title[ Sign Up ]
$s_username:
$s_password:
$s_save_login:
+
+
+ + + + +EOT; + + print_bottom_page( $g_bottom_page_inc ); + print_footer(__FILE__); + print_body_bottom(); + print_html_bottom(); +?> diff --git a/common/code/webnotes/logout.php b/common/code/webnotes/logout.php new file mode 100644 index 00000000..e976da7e --- /dev/null +++ b/common/code/webnotes/logout.php @@ -0,0 +1,16 @@ + \ No newline at end of file diff --git a/common/code/webnotes/note_add.php b/common/code/webnotes/note_add.php new file mode 100644 index 00000000..f9803771 --- /dev/null +++ b/common/code/webnotes/note_add.php @@ -0,0 +1,70 @@ +'; + if ( $result ) { + if ( 0 == $f_note_id ) { + echo "

$s_created_note_msg

"; + } else { + echo "

Note modified successfully

"; + } + } + else { + echo "$s_sql_error_msg $s_administrator
"; + } + + echo "

$s_click_to_proceed_msg

"; + echo ''; + + print_footer( __FILE__ ); + print_body_bottom(); + print_html_bottom(); +?> \ No newline at end of file diff --git a/common/code/webnotes/note_add_msg_inc.php b/common/code/webnotes/note_add_msg_inc.php new file mode 100644 index 00000000..119eebc6 --- /dev/null +++ b/common/code/webnotes/note_add_msg_inc.php @@ -0,0 +1,21 @@ + +
+
+
+

NOTE

+

You can contribute your insights to this document via your web browser!

+

Just add your comment and (optional) email address in the form below. If you do specify your real email, anti-spam measures are encouraged (eg. yourname@NOSPAMyourdomain.com).

+

No HTML tags are allowed. Line breaks are preserved.

+

After you add your note it will be queued for approval by a moderator. Your note may be edited for spelling, grammar, and content.

+
+
+
diff --git a/common/code/webnotes/note_add_page.php b/common/code/webnotes/note_add_page.php new file mode 100644 index 00000000..cee504b7 --- /dev/null +++ b/common/code/webnotes/note_add_page.php @@ -0,0 +1,112 @@ + "; + # @@@@ replace with one parameterised localisation string + echo "$s_not_indexed_part1 $s_administrator $s_not_indexed_part2"; + echo ""; + } + else { +?> + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
$s_add_note
$s_page$t_base_page_name
$s_date$t_date
$s_email
$s_note
+
+ +EOT; + } ### end else + print_footer( __FILE__ ); + print_bottom_page( $g_bottom_page_inc ); + print_body_bottom(); + print_html_bottom(); +?> \ No newline at end of file diff --git a/common/code/webnotes/note_preview_page.php b/common/code/webnotes/note_preview_page.php new file mode 100644 index 00000000..cbf34e95 --- /dev/null +++ b/common/code/webnotes/note_preview_page.php @@ -0,0 +1,72 @@ + +
+ + + + + +
+EOT; + + print_footer( __FILE__ ); + print_body_bottom(); + print_html_bottom(); +?> \ No newline at end of file diff --git a/common/code/webnotes/sample/markup.php b/common/code/webnotes/sample/markup.php new file mode 100644 index 00000000..ef01b87f --- /dev/null +++ b/common/code/webnotes/sample/markup.php @@ -0,0 +1,25 @@ + +

Markup Languages

+ +

This section explains different markup languages including: XHTML and XML.

+ + diff --git a/common/code/webnotes/sample/sample.css b/common/code/webnotes/sample/sample.css new file mode 100644 index 00000000..32997ec2 --- /dev/null +++ b/common/code/webnotes/sample/sample.css @@ -0,0 +1,22 @@ +/* + # phpWebNotes - a php based note addition system + # Copyright (C) 2000-2002 Webnotes Team - webnotes-devel@sourceforge.net + # This program is distributed under the terms and conditions of the GPL + # See the files README and LICENSE for details + + # -------------------------------------------------------- + # $Id$ + # -------------------------------------------------------- +*/ + + +table.layout { border: 0px; width: 100%; } +td.title, .dark { background-color: #d0d0d0; } +td.search, .light { background-color: #e0e0e0; } +td.side, .lighter { background-color: #f0f0f0; } +td.title, td.search, td.side { font-family:Verdana, Arial; font-size: 10pt; } +td.title { padding: 10px; } +td.search { text-align: right; } +td.side { border-right: 1px dotted #a0a0a0; vertical-align: top; padding: 10px; } +td.body { padding: 5px; } +img.bullet { border: 0px; height: 7px; width: 11px; } \ No newline at end of file diff --git a/common/code/webnotes/sample/sample_footer.php b/common/code/webnotes/sample/sample_footer.php new file mode 100644 index 00000000..8a99de06 --- /dev/null +++ b/common/code/webnotes/sample/sample_footer.php @@ -0,0 +1,8 @@ + + +xxx +xxxxxx + +

phpWebNotes @ SourceForge

+ + diff --git a/common/code/webnotes/sample/sample_header.php b/common/code/webnotes/sample/sample_header.php new file mode 100644 index 00000000..3a2eb251 --- /dev/null +++ b/common/code/webnotes/sample/sample_header.php @@ -0,0 +1,26 @@ + + + <?php echo $page_title ?> + '; + print_css( dirname( __FILE__ ) . DIRECTORY_SEPARATOR . 'sample.css' ); + echo ''; + ?> + + + + + + + + + + + +

Webopedia Manual

+ + \ No newline at end of file diff --git a/common/code/webnotes/sample/webopedia.php b/common/code/webnotes/sample/webopedia.php new file mode 100644 index 00000000..185a86e6 --- /dev/null +++ b/common/code/webnotes/sample/webopedia.php @@ -0,0 +1,30 @@ + +

Webopedia

+ +

This is a sample document that contains multiple pages. Each page can have its + own notes. Pages are linked together through previous/next nagivation, as well as + the top, parent, and siblings on the left side.

+ +

The contents of the pages lists in this document is copied from Webopedia to serve as a sample.

+ + diff --git a/common/code/webnotes/sample/webservices.php b/common/code/webnotes/sample/webservices.php new file mode 100644 index 00000000..d3fe4862 --- /dev/null +++ b/common/code/webnotes/sample/webservices.php @@ -0,0 +1,33 @@ + +

Web services

+ +

The term Web services describes a standardized way of integrating Web-based applications using the XML, SOAP, WSDL and UDDI open standards over an Internet protocol backbone. XML is used to tag the data, SOAP is used to transfer the data, WSDL is used for describing the services available and UDDI is used for listing what services are available. Used primarily as a means for businesses to communicate with each other and with clients, Web services allow organizations to communicate data without intimate knowledge of each other's IT systems behind the firewall.

+

Unlike traditional client/server models, such as a Web server/Web page system, Web services do not provide the user with a GUI. Web services instead share business logic, data and processes through a programmatic interface across a network. The applications interface, not the users. Developers can then add the Web service to a GUI (such as a Web page or an executable program) to offer specific functionality to users.

+ +

Web services allow different applications from different sources to communicate with each other without time-consuming custom coding, and because all communication is in XML, Web services are not tied to any one operating system or programming language. For example, Java can talk with Perl, Windows applications can talk with UNIX applications.

+ +

Web services do not require the use of browsers or HTML.

+ +

Web services are sometimes called application services.

+ +

The above definition was copied from Webopedia.

+ diff --git a/common/code/webnotes/sample/xhtml.php b/common/code/webnotes/sample/xhtml.php new file mode 100644 index 00000000..6aca92aa --- /dev/null +++ b/common/code/webnotes/sample/xhtml.php @@ -0,0 +1,29 @@ + +

XHTML

+

Short for Extensible Hypertext Markup Language, a hybrid between HTML and XML specifically designed for Net device displays.

+

XHTML is a markup language written in XML; therefore, it is an XML application.

+

XHTML uses three XML namespaces (used to qualify element and attributes names by associating them with namespaces identified by URI references. Namespaces prevent identically custom-named tags that may be used in different XML documents from being read the same way), which correspond to three HTML 4.0 DTDs: Strict, Transitional, and Frameset.

+

XHTML markup must conform to the markup standards defined in a HTML DTD.

+

When applied to Net devices, XHTML must go through a modularization process. This enables XHTML pages to be read by many different platforms.

+

A device designer, using standard building blocks, will specify which elements are supported. Content creators will then target these building blocks--or modules.

+

Because these modules conform to certain standards, XHTML's extensibility ensures that layout and presentation stay true-to-form over any platform.

+ diff --git a/common/code/webnotes/sample/xml.php b/common/code/webnotes/sample/xml.php new file mode 100644 index 00000000..d3fab040 --- /dev/null +++ b/common/code/webnotes/sample/xml.php @@ -0,0 +1,27 @@ + +

XML

+ +

Short for Extensible Markup Language, a specification developed by the W3C. XML is a pared-down version of SGML, designed especially for Web documents. It allows designers to create their own customized tags, enabling the definition, transmission, validation, and interpretation of data between applications and between organizations.

+ +

The above definition was copied from Webopedia.

+ + diff --git a/common/code/webnotes/signup_page.php b/common/code/webnotes/signup_page.php new file mode 100644 index 00000000..f69fa29b --- /dev/null +++ b/common/code/webnotes/signup_page.php @@ -0,0 +1,85 @@ + +

An e-mail is sent to $t_email with the login details. It is recommended to change your password on first login.

+ [ Login ] + +EOT; + } else { + # @@@@ proper error + echo "Unable to signup user.
"; + } + + print_bottom_page( $g_bottom_page_inc ); + print_footer( __FILE__ ); + print_body_bottom(); + print_html_bottom(); + exit; + } + + echo << +
+
+
+ + + + + + + + + + + + + + + +
Sign Up
$s_username:
E-mail:
+
+
+
+ + + +EOT; + + print_bottom_page( $g_bottom_page_inc ); + print_footer( __FILE__ ); + print_body_bottom(); + print_html_bottom(); +?> \ No newline at end of file diff --git a/common/code/webnotes/sql/db_generate.sql b/common/code/webnotes/sql/db_generate.sql new file mode 100644 index 00000000..1bc890c5 --- /dev/null +++ b/common/code/webnotes/sql/db_generate.sql @@ -0,0 +1,68 @@ +# phpMyAdmin MySQL-Dump +# version 2.3.0 +# http://phpwizard.net/phpMyAdmin/ +# http://www.phpmyadmin.net/ (download page) +# +# Host: localhost +# Generation Time: Oct 07, 2002 at 12:58 AM +# Server version: 3.23.49 +# PHP Version: 4.0.6 +# Database : `phpWebNotes` +# -------------------------------------------------------- + +# +# Table structure for table `phpWN_note_table` +# + +CREATE TABLE phpWN_note_table ( + id int(10) unsigned zerofill NOT NULL auto_increment, + page_id int(10) unsigned zerofill NOT NULL default '0000000000', + email varchar(128) NOT NULL default '', + ip varchar(15) NOT NULL default '', + date_submitted datetime default NULL, + visible int(1) NOT NULL default '0', + note text NOT NULL, + PRIMARY KEY (id), + KEY visible (visible) +) TYPE=MyISAM; +# -------------------------------------------------------- + +# +# Table structure for table `phpWN_page_table` +# + +CREATE TABLE phpWN_page_table ( + id int(10) unsigned zerofill NOT NULL auto_increment, + date_indexed datetime default NULL, + last_updated datetime NOT NULL default '0000-00-00 00:00:00', + page varchar(255) NOT NULL default '', + url varchar(255) NOT NULL default '', + parent_id int(10) unsigned zerofill NOT NULL default '0000000000', + prev_id int(10) unsigned zerofill NOT NULL default '0000000000', + next_id int(10) unsigned zerofill NOT NULL default '0000000000', + PRIMARY KEY (id), + UNIQUE KEY page (page), + KEY parent_id (parent_id) +) TYPE=MyISAM; +# -------------------------------------------------------- + +# +# Table structure for table `phpWN_user_table` +# + +CREATE TABLE phpWN_user_table ( + id int(10) unsigned zerofill NOT NULL auto_increment, + username varchar(32) NOT NULL default '', + password varchar(32) NOT NULL default '', + email varchar(64) NOT NULL default '', + access_level int(2) NOT NULL default '40', + enabled int(1) NOT NULL default '0', + cookie_string varchar(32) NOT NULL default '', + PRIMARY KEY (id) +) TYPE=MyISAM; + +# +# Dumping data for table 'phpWN_user_table' +# + +INSERT INTO phpWN_user_table VALUES ( '0000000001', 'administrator', '63a9f0ea7bb98050796b649e85481845', '', '90', '1', '9eCxeTLdGjDpI149f9aca9f0ba076ce2'); diff --git a/common/code/webnotes/sql/db_upgrade.sql b/common/code/webnotes/sql/db_upgrade.sql new file mode 100644 index 00000000..59edaff2 --- /dev/null +++ b/common/code/webnotes/sql/db_upgrade.sql @@ -0,0 +1,20 @@ +# +# Upgrade phpWebNotes 1.0.0 to phpWebNotes 2.0.0pr1 +# +ALTER TABLE `phpWN_user_table` CHANGE `password` `password` VARCHAR( 32 ) NOT NULL; +ALTER TABLE `phpWN_user_table` CHANGE `access_level` `access_level` INT( 2 ) DEFAULT '40' NOT NULL; +ALTER TABLE `phpWN_page_table` ADD `url` VARCHAR( 255 ) NOT NULL ; +ALTER TABLE `phpWN_page_table` ADD `prev_id` INT( 10 ) UNSIGNED ZEROFILL NOT NULL ; +ALTER TABLE `phpWN_page_table` ADD `next_id` INT( 10 ) UNSIGNED ZEROFILL NOT NULL ; +ALTER TABLE `phpWN_page_table` ADD `last_updated` DATETIME NOT NULL AFTER `date_indexed` ; +ALTER TABLE `phpWN_page_table` ADD `parent_id` INT( 10 ) UNSIGNED ZEROFILL NOT NULL AFTER `url` ; +ALTER TABLE `phpWN_page_table` ADD INDEX ( `parent_id` ) ; +ALTER TABLE `phpWN_page_table` DROP INDEX `id` ; +ALTER TABLE `phpWN_note_table` DROP INDEX `id` ; + +# +# Upgrade 2.0.0pr1 to latest +# +ALTER TABLE `phpwn_user_table` ADD `protected` INT( 1 ) DEFAULT '0' NOT NULL AFTER `enabled` ; +ALTER TABLE `phpWN_page_table` ADD `visits` INT(10) NOT NULL; +ALTER TABLE `phpwn_user_table` CHANGE `cookie_string` `cookie_string` VARCHAR( 64 ) NOT NULL ; \ No newline at end of file diff --git a/common/code/webnotes/themes/classic/theme_api.php b/common/code/webnotes/themes/classic/theme_api.php new file mode 100644 index 00000000..0f2f1c32 --- /dev/null +++ b/common/code/webnotes/themes/classic/theme_api.php @@ -0,0 +1,126 @@ + + + + + + + + +EOT; + } + + # This function is called for every note. The note information + # are all included in the associative array that is passed to the + # function. The theme should check that a field is defined in + # the array before using it. + function theme_notes_echo( $p_page, $p_url, $p_note_info_array ) { + global $g_primary_dark_color, $g_primary_light_color, $g_white_color; + + if ( isset( $p_note_info_array['email'] ) ) { + $t_email = $p_note_info_array['email']; + } else { + $t_email = ''; + } + + if ( isset( $p_note_info_array['date'] ) ) { + $t_date = $p_note_info_array['date']; + } else { + $t_date = ''; + } + + if ( isset( $p_note_info_array['note'] ) ) { + $t_note = '
' . $p_note_info_array['note'] . '
'; + } else { + $t_note = ' '; + } + + echo << + + + + + + + + + +EOT; + } + + # This function is called after all notes are echo'ed. + function theme_notes_end( $p_page, $p_url ) { + global $g_primary_dark_color, $g_note_add_page, $g_admin_manage_notes, $g_admin_page, + $s_add_note_link, $s_manage, $s_admin; + + $c_url = urlencode( $p_page ); + $t_page_id = page_get_id( $p_page ); + + echo << + +
+ $s_user_notes +
 $t_email - $t_date
$t_note
+ $s_add_note_link +EOT; + + if ( is_moderator() ) { + echo <<$s_manage + | $s_admin +EOT; + } + + echo << +
+ +EOT; + } + + # This function is called if the current page has no notes associated + # with it. In this case theme_notes_start() and theme_notes_end() + # APIs are not called. + function theme_notes_none( $p_page, $p_url ) { + theme_notes_start( $p_page, $p_url ); + theme_notes_end( $p_page, $p_url ); + } + + # This function is called if the current page was not indexed + function theme_not_indexed( $p_page ) { + global $g_administrator_email, $s_not_indexed_part1, $s_administrator, $s_not_indexed_part2; + + echo << + $s_not_indexed_part1 $s_administrator $s_not_indexed_part2 + +EOT; + } +?> diff --git a/common/code/webnotes/themes/clean/images/bullet_current.gif b/common/code/webnotes/themes/clean/images/bullet_current.gif new file mode 100644 index 00000000..e679f85a Binary files /dev/null and b/common/code/webnotes/themes/clean/images/bullet_current.gif differ diff --git a/common/code/webnotes/themes/clean/images/bullet_sibling.gif b/common/code/webnotes/themes/clean/images/bullet_sibling.gif new file mode 100644 index 00000000..65d30d7d Binary files /dev/null and b/common/code/webnotes/themes/clean/images/bullet_sibling.gif differ diff --git a/common/code/webnotes/themes/clean/images/caret_left.gif b/common/code/webnotes/themes/clean/images/caret_left.gif new file mode 100644 index 00000000..80db02d0 Binary files /dev/null and b/common/code/webnotes/themes/clean/images/caret_left.gif differ diff --git a/common/code/webnotes/themes/clean/images/caret_right.gif b/common/code/webnotes/themes/clean/images/caret_right.gif new file mode 100644 index 00000000..f06f0ab5 Binary files /dev/null and b/common/code/webnotes/themes/clean/images/caret_right.gif differ diff --git a/common/code/webnotes/themes/clean/images/caret_top.gif b/common/code/webnotes/themes/clean/images/caret_top.gif new file mode 100644 index 00000000..d4cf004b Binary files /dev/null and b/common/code/webnotes/themes/clean/images/caret_top.gif differ diff --git a/common/code/webnotes/themes/clean/images/caret_up.gif b/common/code/webnotes/themes/clean/images/caret_up.gif new file mode 100644 index 00000000..79e6130b Binary files /dev/null and b/common/code/webnotes/themes/clean/images/caret_up.gif differ diff --git a/common/code/webnotes/themes/clean/images/notes_about.gif b/common/code/webnotes/themes/clean/images/notes_about.gif new file mode 100644 index 00000000..5787da0f Binary files /dev/null and b/common/code/webnotes/themes/clean/images/notes_about.gif differ diff --git a/common/code/webnotes/themes/clean/images/notes_add.gif b/common/code/webnotes/themes/clean/images/notes_add.gif new file mode 100644 index 00000000..54a4d0ee Binary files /dev/null and b/common/code/webnotes/themes/clean/images/notes_add.gif differ diff --git a/common/code/webnotes/themes/clean/images/spacer.gif b/common/code/webnotes/themes/clean/images/spacer.gif new file mode 100644 index 00000000..e66849ac Binary files /dev/null and b/common/code/webnotes/themes/clean/images/spacer.gif differ diff --git a/common/code/webnotes/themes/clean/theme.css b/common/code/webnotes/themes/clean/theme.css new file mode 100644 index 00000000..16d9d314 --- /dev/null +++ b/common/code/webnotes/themes/clean/theme.css @@ -0,0 +1,55 @@ +/* + Copyright 2005 Redshift Software, Inc. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) +*/ +.webnotes-headline { + border-bottom: 1px solid #000000; +} +.webnotes-page { + text-align: right; + font-weight: bold; +} +.webnotes-page * { + font-weight: inherit; +} +.webnotes-edit { + display: block; + float: right; + font-size: 80%; + text-align: right; + margin: 1.5em 1.5em 0.5em 0.5em; + padding: 0.25em; + background: #EEEEEE; + border: #CCCCCC 1px solid; +} +.webnotes-edit .webnotes-dash { + display: none; +} +.webnotes-edit a, .webnotes-edit a:hover, .webnotes-edit a:visited { + border: none !important; +} +.webnotes-text { + margin: 1em !important; + border: 1px solid #CCCCCC !important; + text-align: left !important; + padding: 0.5em !important; +} +.webnotes-updated { + font-size: 80%; + text-align: center; + border-top: 1px solid #000000; +} +.webnotes-admin { + font-size: 80%; + text-align: center; + padding: 0.25em; + background: #EEEEEE; + border: #CCCCCC 1px solid; +} +.webnotes-admin a, .webnotes-admin a:hover, .webnotes-admin a:visited { + border: none !important; +} +.webnotes-id { + display: none; +} diff --git a/common/code/webnotes/themes/clean/theme_api.php b/common/code/webnotes/themes/clean/theme_api.php new file mode 100644 index 00000000..b6549ddb --- /dev/null +++ b/common/code/webnotes/themes/clean/theme_api.php @@ -0,0 +1,259 @@ +"; + $t_link_end = ''; + } + else + { + $t_link_start = $t_link_end = ''; + } + + # + # HEADER + # + + $t_about_page = config_get( 'about_page' ); + + echo << +

Notes

+

$t_page + ${t_link_start}Add${t_link_end} +

+HTML; + + # + # NOTES + # + + if ( 0 === count( $t_notes ) ) + { + echo <<There are no user contributed notes for this page.

+HTML; + } + else + { + for ( $i = 0; $i < count( $t_notes ); $i++ ) + { + $t_moderation = ''; + $t_note_info = $t_notes[$i]; + + if ( false === $p_page_data['preview'] ) + { + if ( access_check_action( ACTION_NOTES_MODERATE ) ) + { + $t_url = $p_page_data['url']; + $t_moderation = ''; + + if ( $t_note_info['visible'] != NOTE_VISIBLE_ACCEPTED ) + { + $t_moderation .= link_note_action( $t_note_info['id'], 'accept', $t_url, + access_check_action( ACTION_NOTES_MODERATE_ACCEPT ) ) . ' '; + } + if ( $t_note_info['visible'] != NOTE_VISIBLE_PENDING ) + { + $t_moderation .= link_note_action( $t_note_info['id'], 'queue', $t_url, + access_check_action( ACTION_NOTES_MODERATE_QUEUE ) ) . ' '; + } + if ( $t_note_info['visible'] != NOTE_VISIBLE_DECLINED ) + { + $t_moderation .= link_note_action( $t_note_info['id'], 'decline', $t_url, + access_check_action( ACTION_NOTES_MODERATE_DECLINE ) ) . ' '; + } + if ( $t_note_info['visible'] != NOTE_VISIBLE_ARCHIVED ) + { + $t_moderation .= link_note_action( $t_note_info['id'], 'archive', $t_url, + access_check_action( ACTION_NOTES_MODERATE_ARCHIVE ) ) . ' '; + } + + $t_moderation .= link_note_action( $t_note_info['id'], 'edit', $t_url, + access_check_action( ACTION_NOTES_EDIT ) ); + + if ( $t_note_info['visible'] != NOTE_VISIBLE_DELETED ) + { + $t_moderation .= link_note_action( $t_note_info['id'], 'delete', $t_url, + access_check_action( ACTION_NOTES_MODERATE_DELETE ) ); + } + } + } + + if ( isset( $t_note_info['id'] ) && ( $t_note_info['id'] != 0 ) ) + { + $t_id = (integer)$t_note_info['id']; + $t_visibility = ''; + if ( NOTE_VISIBLE_ACCEPTED != $t_note_info['visible'] ) + { + $t_visibility = '(' . note_get_visibility_str( $t_note_info['visible'] ) . ') - '; + } + if ( access_check_action( ACTION_NOTES_MODERATE ) ) + { + $t_id_view = " $t_visibility $t_moderation"; + } + $t_id_bookmark = "$t_id"; + } + else + { + $t_id_view = ' '; + $t_id_bookmark = ''; + } + + if ( isset( $t_note_info['email'] ) ) + { + if ( access_check_action( ACTION_NOTES_MODERATE ) ) + { + $t_email = ''.$t_note_info['email'].''; + } + else + { + $t_email = str_replace('@',"-at-",substr($t_note_info['email'],0,15)) . '...'; + } + } + else + { + $t_email = ''; + } + + if ( isset( $t_note_info['date'] ) ) + { + $t_date = date('Y-m-d G:i', $t_note_info['date']); + } + else + { + $t_date = ''; + } + + if ( isset( $t_note_info['note'] ) ) + { + $t_note = nl2br($t_note_info['note']); + } + else + { + $t_note = ' '; + } + + echo << +

+ ${t_id_bookmark} + $t_email on $t_date + $t_id_view +

+
${t_note}
+ +HTML; + } + } + + # + # FOOTER + # + + if ( empty( $p_page_data['prev_page'] ) ) + { + $t_prev_text = ''; + } + else + { + $t_prev_text = "\""" . + link_create( $p_page_data['prev_url'], $p_page_data['prev_page'], true, '', '' ); + } + + if ( empty( $p_page_data['next_page' ] ) ) + { + $t_next_text = ''; + } + else + { + $t_next_text = link_create( $p_page_data['next_url'], $p_page_data['next_page'], true, '', '' ) . + "\"""; + } + + if ( empty( $t_prev_text ) && empty( $t_next_text ) ) + { + $t_navigation_row = ''; + } + else + { + $t_navigation_row = "

$t_prev_text — $t_next_text

"; + } + + if ( false === $p_page_data['preview'] ) + { + $t_link_start = ""; + $t_link_end = ''; + } + else + { + $t_link_start = $t_link_end = ''; + } + + if ( 0 !== count( $t_notes ) ) + { + echo <<$t_page + ${t_link_start}Add${t_link_end} +

+HTML; + } + + if ( false === $p_page_data['preview'] ) + { + $t_last_updated = date('Y-m-d G:i:s', $p_page_data['last_updated']); + echo <<Last updated: $t_last_updated

+HTML; + } + + echo << +HTML; + + if ( ( false === $p_page_data['preview'] ) && ( access_is_logged_in() ) ) + { + echo '
'; + print_admin_menu(); + echo '
'; + } +} +?> diff --git a/common/code/webnotes/themes/phpnet/images/bullet_current.gif b/common/code/webnotes/themes/phpnet/images/bullet_current.gif new file mode 100644 index 00000000..e679f85a Binary files /dev/null and b/common/code/webnotes/themes/phpnet/images/bullet_current.gif differ diff --git a/common/code/webnotes/themes/phpnet/images/bullet_sibling.gif b/common/code/webnotes/themes/phpnet/images/bullet_sibling.gif new file mode 100644 index 00000000..65d30d7d Binary files /dev/null and b/common/code/webnotes/themes/phpnet/images/bullet_sibling.gif differ diff --git a/common/code/webnotes/themes/phpnet/images/caret_left.gif b/common/code/webnotes/themes/phpnet/images/caret_left.gif new file mode 100644 index 00000000..80db02d0 Binary files /dev/null and b/common/code/webnotes/themes/phpnet/images/caret_left.gif differ diff --git a/common/code/webnotes/themes/phpnet/images/caret_right.gif b/common/code/webnotes/themes/phpnet/images/caret_right.gif new file mode 100644 index 00000000..f06f0ab5 Binary files /dev/null and b/common/code/webnotes/themes/phpnet/images/caret_right.gif differ diff --git a/common/code/webnotes/themes/phpnet/images/caret_top.gif b/common/code/webnotes/themes/phpnet/images/caret_top.gif new file mode 100644 index 00000000..d4cf004b Binary files /dev/null and b/common/code/webnotes/themes/phpnet/images/caret_top.gif differ diff --git a/common/code/webnotes/themes/phpnet/images/caret_up.gif b/common/code/webnotes/themes/phpnet/images/caret_up.gif new file mode 100644 index 00000000..79e6130b Binary files /dev/null and b/common/code/webnotes/themes/phpnet/images/caret_up.gif differ diff --git a/common/code/webnotes/themes/phpnet/images/notes_about.gif b/common/code/webnotes/themes/phpnet/images/notes_about.gif new file mode 100644 index 00000000..5787da0f Binary files /dev/null and b/common/code/webnotes/themes/phpnet/images/notes_about.gif differ diff --git a/common/code/webnotes/themes/phpnet/images/notes_add.gif b/common/code/webnotes/themes/phpnet/images/notes_add.gif new file mode 100644 index 00000000..54a4d0ee Binary files /dev/null and b/common/code/webnotes/themes/phpnet/images/notes_add.gif differ diff --git a/common/code/webnotes/themes/phpnet/images/spacer.gif b/common/code/webnotes/themes/phpnet/images/spacer.gif new file mode 100644 index 00000000..e66849ac Binary files /dev/null and b/common/code/webnotes/themes/phpnet/images/spacer.gif differ diff --git a/common/code/webnotes/themes/phpnet/theme.css b/common/code/webnotes/themes/phpnet/theme.css new file mode 100644 index 00000000..ee2a1d57 --- /dev/null +++ b/common/code/webnotes/themes/phpnet/theme.css @@ -0,0 +1,19 @@ +/* + # phpWebNotes - a php based note addition system + # Copyright (C) 2000-2002 Webnotes Team - webnotes-devel@sourceforge.net + # This program is distributed under the terms and conditions of the GPL + # See the files README and LICENSE for details + + # -------------------------------------------------------- + # $Id$ + # -------------------------------------------------------- +*/ + +div.phpnet { } +div.phpnet td { font-family:Verdana, Arial; font-size: 10pt; padding: 4px; } +div.phpnet .dark { background-color: #d0d0d0; } +div.phpnet .light { background-color: #e0e0e0; } +div.phpnet .lighter { background-color: #f0f0f0; } +div.phpnet tr { vertical-align: top; } +div.phpnet img { border: 0px; } +div.phpnet table { border: 0px; width: 100%; } diff --git a/common/code/webnotes/themes/phpnet/theme_api.php b/common/code/webnotes/themes/phpnet/theme_api.php new file mode 100644 index 00000000..73e0f7b5 --- /dev/null +++ b/common/code/webnotes/themes/phpnet/theme_api.php @@ -0,0 +1,243 @@ +"; + $t_link_end = ''; + } else { + $t_link_start = $t_link_end = ''; + } + + # + # HEADER + # + + $t_about_page = config_get( 'about_page' ); + + echo << + + + + + +EOT; + + # + # NOTES + # + + if ( 0 === count( $t_notes ) ) { + echo << + + +EOT; + } else { + for ( $i = 0; $i < count( $t_notes ); $i++ ) { + $t_moderation = ''; + $t_note_info = $t_notes[$i]; + + if ( false === $p_page_data['preview'] ) { + if ( access_check_action( ACTION_NOTES_MODERATE ) ) { + $t_url = $p_page_data['url']; + $t_moderation = ''; + + if ( $t_note_info['visible'] != NOTE_VISIBLE_ACCEPTED ) { + $t_moderation .= link_note_action( $t_note_info['id'], 'accept', $t_url, + access_check_action( ACTION_NOTES_MODERATE_ACCEPT ) ) . ' '; + } + + if ( $t_note_info['visible'] != NOTE_VISIBLE_PENDING ) { + $t_moderation .= link_note_action( $t_note_info['id'], 'queue', $t_url, + access_check_action( ACTION_NOTES_MODERATE_QUEUE ) ) . ' '; + } + + if ( $t_note_info['visible'] != NOTE_VISIBLE_DECLINED ) { + $t_moderation .= link_note_action( $t_note_info['id'], 'decline', $t_url, + access_check_action( ACTION_NOTES_MODERATE_DECLINE ) ) . ' '; + } + + if ( $t_note_info['visible'] != NOTE_VISIBLE_ARCHIVED ) { + $t_moderation .= link_note_action( $t_note_info['id'], 'archive', $t_url, + access_check_action( ACTION_NOTES_MODERATE_ARCHIVE ) ) . ' '; + } + + $t_moderation .= link_note_action( $t_note_info['id'], 'edit', $t_url, + access_check_action( ACTION_NOTES_EDIT ) ); + + if ( $t_note_info['visible'] != NOTE_VISIBLE_DELETED ) { + $t_moderation .= link_note_action( $t_note_info['id'], 'delete', $t_url, + access_check_action( ACTION_NOTES_MODERATE_DELETE ) ); + } + } + } + + if ( isset( $t_note_info['id'] ) && ( $t_note_info['id'] != 0 ) ) { + $t_id = (integer)$t_note_info['id']; + $t_visibility = ''; + if ( NOTE_VISIBLE_ACCEPTED != $t_note_info['visible'] ) { + $t_visibility = '(' . note_get_visibility_str( $t_note_info['visible'] ) . ') - '; + } + $t_id_view = "$t_visibility#$t_id
$t_moderation
"; + $t_id_bookmark = ""; + } else { + $t_id_view = ' '; + $t_id_bookmark = ''; + } + + if ( isset( $t_note_info['email'] ) ) { + $t_email = $t_note_info['email']; + } else { + $t_email = ''; + } + + if ( isset( $t_note_info['date'] ) ) { + # 06-Feb-2002 02:28 + $t_date = date('d-M-Y G:i', $t_note_info['date']); + } else { + $t_date = ''; + } + + if ( isset( $t_note_info['note'] ) ) { + $t_note = nl2br('' . $t_note_info['note'] . ''); + } else { + $t_note = ' '; + } + + echo << + + +EOT; + } + } + + # + # FOOTER + # + + if ( empty( $p_page_data['prev_page'] ) ) { + $t_prev_text = ''; + } else { + $t_prev_text = "\""" . + link_create( $p_page_data['prev_url'], $p_page_data['prev_page'], true, '', '' ); + } + + if ( empty( $p_page_data['next_page' ] ) ) { + $t_next_text = ''; + } else { + $t_next_text = link_create( $p_page_data['next_url'], $p_page_data['next_page'], true, '', '' ) . + "\"""; + } + + if ( empty( $t_prev_text ) && empty( $t_next_text ) ) { + $t_navigation_row = ''; + } else { + $t_navigation_row = ""; + } + + if ( false === $p_page_data['preview'] ) { + $t_link_start = ""; + $t_link_end = ''; + } else { + $t_link_start = $t_link_end = ''; + } + + if ( 0 !== count( $t_notes ) ) { + echo << + + +EOT; + } + + if ( false === $p_page_data['preview'] ) { + # Tue, 17 Sep 2002 + $t_last_updated = date('D, d M Y - G:i:s', $p_page_data['last_updated']); + echo << +EOT; + } + + echo '
User Contributed Notes
$t_page
+ $t_link_startAdd Notes$t_link_end + About Notes +
There are no user contributed notes for this page.
+ $t_id_bookmark + + + + + + + + + +
$t_email
$t_date
$t_id_view
$t_note
+
$t_prev_text$t_next_text
+ $t_link_startAdd Notes$t_link_end + About Notes +
+ + $t_navigation_row + +
Last updated: $t_last_updated
+
'; + + if ( ( false === $p_page_data['preview'] ) && ( access_is_logged_in() ) ) { + echo '
'; + print_admin_menu(); + echo '
'; + } + } + ### -------------------- +?> diff --git a/common/code/webnotes/user_home_page.php b/common/code/webnotes/user_home_page.php new file mode 100644 index 00000000..b4dbbf12 --- /dev/null +++ b/common/code/webnotes/user_home_page.php @@ -0,0 +1,37 @@ +Logged in as $v_username ($t_access_level)

"; + + print_bottom_page( $g_bottom_page_inc ); + print_footer( __FILE__ ); + print_body_bottom(); + print_html_bottom(); +?> \ No newline at end of file diff --git a/doc/display.php b/doc/display.php index 7c556f10..7e54e3f5 100644 --- a/doc/display.php +++ b/doc/display.php @@ -1,11 +1,15 @@ @@ -17,6 +21,7 @@ else { + @@ -27,10 +32,17 @@ else {
-
+
- + +
+
+
+
+
+
+
diff --git a/style/css_0/section-doc.css b/style/css_0/section-doc.css index a1d90af8..8ead22d5 100644 --- a/style/css_0/section-doc.css +++ b/style/css_0/section-doc.css @@ -20,18 +20,16 @@ li#doc-section-tab a { } #content .spirit-nav img { border: none; + margin: 0.25em 0.25em 0em 0.25em; } #content .spirit-nav a { border: none; - margin: 0em 0em 0em 0.25em; } #content .spirit-nav a:hover { border: none; - margin: 0em 0em 0em 0.25em; } #content .spirit-nav a:visited { border: none; - margin: 0em 0em 0em 0.25em; } #content div.toc { margin: 1em;