littlewing1977 Posted December 31, 2013 Share Posted December 31, 2013 I am using an open source address book on my web site that is coded using PHP and connected to a MySQL database. I believe it was written for an older version. I am currently using PHP 5.4.23 and MySQL 5.5.32. I have no experience with PHP or MySQL, but I was able to figure out how to fix several errors. I still have one problem that I cannot figure out. I am hoping someone can help me. Thanks in advance.I think it may be a syntax problem from using a newer version of PHP. I'm not exactly sure what the line is doing, but I commented it out and it works. It just doesn't get the option that tells it to open it in a popup window. I'm hoping that is an easy fix. It starts by creating a new object. // RETRIEVE OPTIONS THAT PERTAIN TO THIS PAGE $options = new Options(); I figured out that this line is doing a SQL query to a specific table. It will retrieve either a 1 or a 0. Or it will return an error. Also, that row in the database is configured as an "int(1)" and does not accept null values. $options = mysql_fetch_array(mysql_query("SELECT displayAsPopup FROM " . TABLE_OPTIONS . " LIMIT 1", $db_link)) or die(reportScriptError("Unable to retrieve options.")); So at this point $options should equal 1 with my current configuration. Then, I don't really understand what the next line is trying to do, but this is the line that fails. $options->displayAsPopup = $options['displayAsPopup']; This is the error I get. Warning: Attempt to assign property of non-object in /public_html/members/search.php on line 37Warning: Cannot modify header information - headers already sent by (output started at /public_html/members/search.php:37) in /public_html/members/search.php on line 114 I'm not sure if I'm using the correct terminology for this language, but $options seems like a UDT which appears to be defined by the following code. Maybe that is where the problem is. I really have no idea what is going on in there though. <?php /************************************************************* * THE ADDRESS BOOK : version 1.04 * * lib/class-options.php * Object: retrieve and set global or user options * *************************************************************/ class Options { // DECLARE OPTION VARIABLES var $bdayInterval; var $bdayDisplay; var $displayAsPopup; var $useMailScript; var $picAlwaysDisplay; var $picWidth; var $picHeight; var $picDupeMode; var $picAllowUpload; var $modifyTime; // not currently in use; reserved for future use var $msgLogin; var $msgWelcome; var $countryDefault; var $allowUserReg; var $eMailAdmin; var $requireLogin; var $language; var $defaultLetter; // test var $limitEntries; // test // DECLARE OTHER VARIABLES var $global_options; var $user_options; var $message; // CONSTRUCTOR FUNCTION function Options() { $this->get(); } function get() { // This function retrieves global options first. Then, it retrieves user options // if a user name is available, which will overwrite certain global options. $this->set_global(); if ((isset($_SESSION['username'])) && ($_SESSION['username'] != '@auth_off')) { $this->set_user(); } } function set_global() { // This function restores all options to the administrator-specified global settings. // Call this function when you need to ignore the user-specified settings. // Note: If you do not call this function, you can still obtain global settings // directly using the $this->global_options variable. global $db_link; $this->global_options = mysql_fetch_array(mysql_query("SELECT * FROM " . TABLE_OPTIONS . " LIMIT 1", $db_link)) or die(reportScriptError("Unable to retrieve global options.")); $this->bdayInterval = $this->global_options['bdayInterval']; $this->bdayDisplay = $this->global_options['bdayDisplay']; $this->displayAsPopup = $this->global_options['displayAsPopup']; $this->useMailScript = $this->global_options['useMailScript']; $this->picAlwaysDisplay = $this->global_options['picAlwaysDisplay']; $this->picWidth = $this->global_options['picWidth']; $this->picHeight = $this->global_options['picHeight']; $this->picDupeMode = $this->global_options['picDupeMode']; $this->picAllowUpload = $this->global_options['picAllowUpload']; $this->modifyTime = $this->global_options['modifyTime']; $this->msgLogin = stripslashes( $this->global_options['msgLogin'] ); $this->msgWelcome = stripslashes( $this->global_options['msgWelcome'] ); $this->countryDefault = $this->global_options['countryDefault']; $this->allowUserReg = $this->global_options['allowUserReg']; $this->eMailAdmin = $this->global_options['eMailAdmin']; $this->requireLogin = $this->global_options['requireLogin']; $this->language = $this->load_lang($this->global_options['language']); $this->defaultLetter = $this->global_options['defaultLetter']; $this->limitEntries = $this->global_options['limitEntries']; } function set_user() { // This function overrides admin-specified options with user options. // Call this function if you need to restore the user settings after resetting // to global settings. // Note: If you do not call this function, you can still obtain the user settings // directly using the $this->user_options variable. global $db_link; $this->user_options = mysql_fetch_array(mysql_query("SELECT * FROM " . TABLE_USERS . " WHERE username='" . $_SESSION['username'] . "' LIMIT 1", $db_link)) or die(reportScriptError("Unable to retrieve user options.")); if (!is_null($this->user_options['bdayInterval'])) $this->bdayInterval = $this->user_options['bdayInterval']; if (!is_null($this->user_options['bdayDisplay'])) $this->bdayDisplay = $this->user_options['bdayDisplay']; if (!is_null($this->user_options['displayAsPopup'])) $this->displayAsPopup = $this->user_options['displayAsPopup']; if (!is_null($this->user_options['useMailScript'])) $this->useMailScript = $this->user_options['useMailScript']; if (!is_null($this->user_options['language'])) $this->language = $this->load_lang($this->user_options['language']); if (!is_null($this->user_options['defaultLetter'])) $this->defaultLetter = $this->user_options['defaultLetter']; if (!is_null($this->user_options['limitEntries'])) $this->limitEntries = $this->user_options['limitEntries']; } function save_global() { // This function saves global settings to the database, in the options table. // It assumes that the options have already been placed in the $_POST superglobal. global $db_link; global $lang; // CHECK NUMERICAL INPUT // This is DIFFERENT from the previous implemenation (TAB 1.03 and earlier) // where empty or faulty information resulted in resetting the value to a // hard-coded default value. Here, it will check if the $_POST value is valid, // and if so, it will overwrite the existing setting. Otherwise the original // value (whatever it is) is retained. if (($_POST['bdayInterval'] > 0) && is_numeric($_POST['bdayInterval'])) $this->bdayInterval = $_POST['bdayInterval']; if (($_POST['picWidth'] > 0) && is_numeric($_POST['picWidth'])) $this->picWidth = $_POST['picWidth']; if (($_POST['picHeight'] > 0) && is_numeric($_POST['picHeight'])) $this->picHeight = $_POST['picHeight']; if (($_POST['picDupeMode'] == 1) || ($_POST['picDupeMode'] == 2) || ($_POST['picDupeMode'] == 3)) $this->picDupeMode = $_POST['picDupeMode']; if (($_POST['countryDefault'])) $this->countryDefault = $_POST['countryDefault']; if (($_POST['limitEntries'] >= 0) && is_numeric($_POST['limitEntries'])) $this->limitEntries = $_POST['limitEntries']; if ($_POST['language']) $this->language = $_POST['language']; // not numerical, but the same principle applies $this->defaultLetter = (empty($_POST['defaultLetter'])) ? "" : $_POST['defaultLetter']; // if no value is sent, then turn defaultLetter off (note: off must be empty string, NOT 0 value) // CLEAN UP STRING INPUT // These are allowed to be blank. We will take these "as is" -- no checking is done. $this->msgLogin = addslashes(strip_tags(trim($_POST['msgLogin']),'<a><b><i><u><p><br>')); $this->msgWelcome = addslashes(strip_tags(trim($_POST['msgWelcome']),'<a><b><i><u><p><br>')); // CHECKBOXES // If the variable does not exist in $_POST, that means the checkbox is turned off! // Give it a value of 0 so we know what to enter into the database. // Everything else results in 1 (which should be the contents of the $_POST variable anyway, but let's be sure $this->bdayDisplay = (empty($_POST['bdayDisplay'])) ? 0 : 1; $this->displayAsPopup = (empty($_POST['displayAsPopup'])) ? 0 : 1; $this->useMailScript = (empty($_POST['useMailScript'])) ? 0 : 1; $this->picAlwaysDisplay = (empty($_POST['picAlwaysDisplay'])) ? 0 : 1; $this->picAllowUpload = (empty($_POST['picAllowUpload'])) ? 0 : 1; $this->allowUserReg = (empty($_POST['allowUserReg'])) ? 0 : 1; $this->eMailAdmin = (empty($_POST['eMailAdmin'])) ? 0 : 1; $this->requireLogin = (empty($_POST['requireLogin'])) ? 0 : 1; // CREATES THE QUERY AND UPDATES THE OPTIONS TABLE $sql = "UPDATE " . TABLE_OPTIONS . " SET bdayInterval = $this->bdayInterval, bdayDisplay = $this->bdayDisplay, displayAsPopup = $this->displayAsPopup, useMailScript = $this->useMailScript, picAlwaysDisplay = $this->picAlwaysDisplay, picWidth = $this->picWidth, picHeight = $this->picHeight, picDupeMode = $this->picDupeMode, picAllowUpload = $this->picAllowUpload, modifyTime = $this->modifyTime, msgLogin = '$this->msgLogin', msgWelcome = '$this->msgWelcome', countryDefault = '$this->countryDefault', allowUserReg = $this->allowUserReg, requireLogin = $this->requireLogin, eMailAdmin = $this->eMailAdmin, language = '$this->language', defaultLetter = '$this->defaultLetter', limitEntries = $this->limitEntries"; mysql_query($sql, $db_link) or die(reportSQLError($lang['ERR_OPTIONS_NO_SAVE'])); $this->get(); $this->message = $lang['OPT_SAVED']; return true; } function save_user() { // This function saves user settings to the database, in the users table. // This is largely similar in function to save_global() except that there are much fewer // options to deal with. It may be better to condense the two functions into // one function so as to avoid repetition of code but we can worry about that later. global $db_link; global $lang; // CHECK INPUT // Condensed version of events from save_global(). if (($_POST['bdayInterval'] > 0) && is_numeric($_POST['bdayInterval'])) $this->bdayInterval = $_POST['bdayInterval']; if (($_POST['limitEntries'] >= 0) && is_numeric($_POST['limitEntries'])) $this->limitEntries = $_POST['limitEntries']; if ($_POST['language']) $this->language = $_POST['language']; $this->defaultLetter = (empty($_POST['defaultLetter'])) ? "" : $_POST['defaultLetter']; $this->bdayDisplay = (empty($_POST['bdayDisplay'])) ? 0 : 1; $this->displayAsPopup = (empty($_POST['displayAsPopup'])) ? 0 : 1; $this->useMailScript = (empty($_POST['useMailScript'])) ? 0 : 1; // CREATES THE QUERY AND UPDATES THE OPTIONS TABLE $sql = "UPDATE " . TABLE_USERS . " SET bdayInterval = $this->bdayInterval, bdayDisplay = $this->bdayDisplay, displayAsPopup = $this->displayAsPopup, useMailScript = $this->useMailScript, language = '$this->language', defaultLetter = '$this->defaultLetter', limitEntries = $this->limitEntries WHERE username='" . $_SESSION['username'] . "'"; mysql_query($sql, $db_link) or die(reportSQLError($lang['ERR_OPTIONS_NO_SAVE'])); $this->get(); $this->message = $lang['OPT_SAVED_USER']; return true; } function reset_user() { // This function is designed to clear the user's settings and have all option variables // set to NULL in the database. NULL means neither yes or no, and will force the // script to look to the global options table for information. global $db_link; global $lang; // QUERY $sql = "UPDATE " . TABLE_USERS . " SET bdayInterval = NULL, bdayDisplay = NULL, displayAsPopup = NULL, useMailScript = NULL, language = NULL, defaultLetter = NULL, limitEntries = NULL WHERE username='" . $_SESSION['username'] . "'"; mysql_query($sql, $db_link) or die(reportSQLError($lang['ERR_OPTIONS_NO_SAVE'])); // RESET MEMBER VARIABLES $this->set_global(); $this->message = $lang['OPT_RESET_USER']; return true; } function load_lang($file) { global $php_ext; // The following variables are loaded from country files. Make these global scope global $lang; global $country; $fullpath = dirname($_SERVER['SCRIPT_FILENAME']) . '/' . PATH_LANGUAGES . $file . '.' . $php_ext; // This function takes the value returned by the 'language' column in global or user options table, // and checks to make sure that the file exists in the /language directory. If it exists, it loads // the language into memory. If it does not exist, it attempts to loads 'english' (the default language). if (file_exists($fullpath)) { require_once($fullpath); return $file; } else { require_once(dirname($_SERVER['SCRIPT_FILENAME']) . '/' . PATH_LANGUAGES . 'english.' . $php_ext); $this->message = $lang['OPT_LANGUAGE_MISSING']; return 'english'; } } // END Options } ?> Quote Link to comment Share on other sites More sharing options...
requinix Posted December 31, 2013 Share Posted December 31, 2013 The problem is you're trying to use the "$options" variable for two different things at the same time: one for an object and one for a row from a database query. Pick one to call "options" and change the name of the other one. Quote Link to comment Share on other sites More sharing options...
littlewing1977 Posted December 31, 2013 Author Share Posted December 31, 2013 Are you talking about in the single line that is failing or in the other PHP file? I see in the other file there is a class and a function that are both called options. Is this what I want to change? If so, I am assuming that I would want to change the function. The class is probably called from several locations. Does that sound accurate? I really don't know anything about PHP. Quote Link to comment Share on other sites More sharing options...
mac_gyver Posted December 31, 2013 Share Posted December 31, 2013 or in the other PHP file? if the posted lines of code are from multiple separate places in the program, they could be the intended usage. it may also be that the code has always been foo-bar and with warning messages turned off 'functioned' as the author intended. post at least 5-10 lines of code leading up to and including the line where the error is occurring. also, posting a link to the original site where you got this script would help. Quote Link to comment Share on other sites More sharing options...
littlewing1977 Posted December 31, 2013 Author Share Posted December 31, 2013 You can find the script here. It is no longer in development and the author's web site doesn't exist anymore. I believe this functioned correctly on previous versions of PHP, but I'm not positive. I did fix several other errors that were from changes in syntax. http://sourceforge.net/projects/theaddressbook/ Here is the entire page called search.php. It fails on line 37, which I currently have commented out. The page works with the line commented but it opens the search results on the same page instead of in a popup window, even when the displayaspopup option is enabled. <?php /************************************************************* * THE ADDRESS BOOK : version 1.04d * * CHANGE LOG since 1.04 release on 30 May 05 where + sign indicates if this particular file was modified * 1.04a - Corrected <? to <?php for all instances due to some servers having short_open_tags set to off. * 1.04b - Corrected 3 more cases of <? which were missed earlier. Only affects index.php * 1.04c - Corrected mailsend.php syntax error (extraneous open bracket [). * 1.04d - Corrected Javascript error in mailto.php * Corrected improper default country select in edit.php * Removed use of file_get_contents() from options.php and users.php due to pre php4.3 incompatibility * + Changed call to charset iso-8859-1 from hard code in header to variable to accomodate greek and other non- 8859-1 languages **************************************************************** * search.php * Searches address book entries. * *************************************************************/ // ** GET CONFIGURATION DATA ** require_once('constants.inc'); require_once(FILE_FUNCTIONS); require_once(FILE_CLASS_OPTIONS); // ** OPEN CONNECTION TO THE DATABASE ** $db_link = openDatabase($db_hostname, $db_username, $db_password, $db_name); // ** CHECK FOR LOGIN ** checkForLogin(); // RETRIEVE OPTIONS THAT PERTAIN TO THIS PAGE $options = new Options(); $options = mysql_fetch_array(mysql_query("SELECT displayAsPopup FROM " . TABLE_OPTIONS . " LIMIT 1", $db_link)) or die(reportScriptError("Unable to retrieve options.")); //$options->displayAsPopup = $options['displayAsPopup']; // PHP code is placed BEFORE sending any HTML information because we want the script to // stop processing and send another file instead if a single entry is found. // Because we don't rely on the browser to redirect, this allows pressing 'back' on the // browser to take us back to the list, and not keep forwarding. // See if search terms have been passed to this page. $goTo = $_POST['goTo']; if (!$goTo AND !$search) { echo("<P>".$lang['SEARCH_TERMS']); exit(); } // goTo functionality // Search does not work so we'll make it do the same thing as goTo for now. if ($search) { $goTo = $search; } if ($goTo) { $gotosql = "SELECT id, CONCAT(lastname,', ',firstname) AS fullname, lastname, firstname FROM " . TABLE_CONTACT . " WHERE CONCAT(firstname,' ', lastname) LIKE '%$goTo%' OR CONCAT(firstname,' ', middlename,' ', lastname) LIKE '%$goTo%' OR nickname LIKE '%$goTo%' ORDER BY fullname"; $r_goto = mysql_query($gotosql, $db_link); $numGoTo = mysql_num_rows($r_goto); } // print results if ($numGoTo == 1) { $t_goto = mysql_fetch_array($r_goto); $contact_id = $t_goto['id']; if ($options->displayAsPopup == 1) { $theAddress = FILE_ADDRESS."?id=".$contact_id; ?> <HTML> <HEAD> <TITLE> <?php echo "$lang[TITLE_TAB] - $lang[SEARCH_LBL]" ?></TITLE> <meta http-equiv="Content-Type" content="text/html; charset=<?php echo $lang['CHARSET']?>"> <LINK REL="stylesheet" HREF="styles.css" TYPE="text/css"> <SCRIPT LANGUAGE="JavaScript"> <!-- window.open('<?php echo($theAddress); ?>',null,'width=600,height=450,scrollbars,resizable,menubar,status'); history.back(); // --> </SCRIPT> </HEAD> <BODY> <CENTER> <TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0 WIDTH=570> <TR> <TD CLASS="headTitle"><?php echo $lang['SEARCH_RESULTS']?></TD> </TR> <TR> <TD CLASS="infoBox"> <TABLE BORDER=0 CELLPADDING=10 CELLSPACING=0 WIDTH=500><TR VALIGN="top"><TD CLASS="data"> One entry found. It will appear in a new window. If no window appears, <A HREF="#" onClick="window.open('<?php echo($theAddress); ?>',addressWindow,'width=600,height=450,scrollbars,resizable,menubar,status'); return false;">click here</A>. </TD></TR></TABLE> </TD> </TR> </TABLE> </CENTER> </BODY> </HTML> <?php } else { header("Location: " . FILE_ADDRESS . "?id=$contact_id"); } exit; } ?> <HTML> <HEAD> <TITLE> <?php echo "$lang[TITLE_TAB] - $lang[SEARCH_LBL]" ?></TITLE> <LINK REL="stylesheet" HREF="styles.css" TYPE="text/css"> <meta http-equiv="Content-Type" content="text/html; charset=<?php echo $lang['CHARSET']?>"> </HEAD> <BODY> <CENTER> <TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0 WIDTH=570> <TR> <TD CLASS="headTitle"><?php echo $lang['SEARCH_LBL'] ?></TD> </TR> <TR> <TD CLASS="infoBox"> <TABLE BORDER=0 CELLPADDING=10 CELLSPACING=0 WIDTH=500><TR VALIGN="top"><TD CLASS="data"> <?php // print search info echo("<B>".$lang['SEARCH_MATCH']. " $goTo ".$lang['SEARCH_IN_NAME']."</B>"); // print results in case $numGoTo did not equal 1 if ($numGoTo == 0) { echo("<P>".$lang['SEARCH_NONE']); echo("<P><B><A HREF=\"" . FILE_LIST . "\">".$lang['BTN_RETURN']."</A></B>"); } else { echo("<P>".$lang['SEARCH_MULTIPLE']."<P>"); while ($t_goto = mysql_fetch_array($r_goto) ) { $contact_id = $t_goto['id']; $contact_name = $t_goto['fullname']; $contact_firstname = $t_goto['firstname']; $contact_lastname = $t_goto['lastname']; if (!$contact_firstname) { $contact_name = $contact_lastname; } if ($options->displayAsPopup == 1) { $popupLink = " onClick=\"window.open('" . FILE_ADDRESS . "?id=$contact_id','addressWindow','width=600,height=450,scrollbars,resizable,menubar,status'); return false;\""; } echo("<BR><A HREF=\"" . FILE_ADDRESS . "?id=$contact_id\"$popupLink>$contact_name</A>\n"); } echo("<P><B><A HREF=\"" . FILE_LIST. "\">".$lang['BTN_RETURN']."</A></B>"); } ?> </TD></TR></TABLE> </TD> </TR> </TABLE> </CENTER> </BODY> </HTML> Quote Link to comment Share on other sites More sharing options...
Solution mac_gyver Posted December 31, 2013 Solution Share Posted December 31, 2013 ASSUMING (<--- making a big assumption) that the options class functions correctly, i.e. getting the global settings, then modifying them with any user settings, then the offending mysql logic in the search.php page should not be needed. try it with the following lines commented out - //$options = mysql_fetch_array(mysql_query("SELECT displayAsPopup FROM " . TABLE_OPTIONS . " LIMIT 1", $db_link)) // or die(reportScriptError("Unable to retrieve options.")); // $options->displayAsPopup = $options['displayAsPopup']; Quote Link to comment Share on other sites More sharing options...
littlewing1977 Posted December 31, 2013 Author Share Posted December 31, 2013 I already know that it works with line 37 commented out. It just doesn't use the popup window. That query is looking at the global options. The user options are stored in a different table. Quote Link to comment Share on other sites More sharing options...
mac_gyver Posted December 31, 2013 Share Posted December 31, 2013 i suggested commenting out the three lines that are setting $options variable from the inline mysql query code. the rest of the code on that page expects $options to be an instance of the options class. therefore, any code that is directly setting $options to anything else, doesn't belong. Quote Link to comment Share on other sites More sharing options...
littlewing1977 Posted December 31, 2013 Author Share Posted December 31, 2013 That seems to work. I'm wondering if that will cause the Global option to override the User option though. If so, I don't think that will be much of an issue. I think this will work for me, unless you have any other suggestions after finding out the results of that test. Quote Link to comment Share on other sites More sharing options...
mac_gyver Posted January 1, 2014 Share Posted January 1, 2014 I'm wondering if that will cause the Global option to override the User option though. you could always test this since you have a working system installed. Quote Link to comment Share on other sites More sharing options...
littlewing1977 Posted January 1, 2014 Author Share Posted January 1, 2014 Actually, it appears to be working correctly. Thanks for your help. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.