Help with query and sorting

8 posts by 2 authors in: Forums > CMS Builder
Last Post: January 11, 2013   (RSS)

By weblm - January 8, 2013

I have 2 tables......a reviews table and a property_listings table.

For the reviews section, the customer can create multiple new reviews.  It's a multi-record section.  They can select which property the review is for based on a list field that pulls the Property name and num from the property_listings table.

On the reviews page itself, I want to add a dropdown that lists all the properties that currently have a review....so the user can narrow the page down by just a single property.  Here's the code I have that is working for that:

<?php
$reviewedPropertyNum = mysql_query_fetch_all_assoc("SELECT DISTINCT property FROM {$TABLE_PREFIX}reviews");

echo '<form><select name="property" onchange="window.location.href= this.form.property.options[this.form.property.selectedIndex].value">'."\n";
echo '<option value="'.htmlentities($_SERVER['PHP_SELF']).'">All Properties</option>'."\n";

foreach ($reviewedPropertyNum as $reviewedPropertyNumrecord) {

$reviewedProperties = mysql_query_fetch_all_assoc("SELECT num, property_name FROM {$TABLE_PREFIX}property_listings WHERE num='$reviewedPropertyNumrecord[property]'");
if ($reviewedProperties) {

foreach ($reviewedProperties as $reviewedProperty) {

if ($_GET['property'] == $reviewedProperty[num]) { echo '<option selected value="'.htmlentities($_SERVER['PHP_SELF']).'?property='.$reviewedProperty['num'].'">'.$reviewedProperty['property_name'].'</option>'."\n"; }
else { echo '<option value="'.htmlentities($_SERVER['PHP_SELF']).'?property='.$reviewedProperty['num'].'">'.$reviewedProperty['property_name'].'</option>'."\n"; }

}

}
}

echo '</select></form>'."\n";
?>

1) Is this the best way to do this? 

2) I really want the final property list in the dopdown sorted by property_name....but I'm not sure how to do that....since it's getting each one in a foreach loop.  

Any ideas?

-Kevin

LM

By gregThomas - January 9, 2013

Hi Kevin, 

There is a way you can do this with one getRecords function using the :label meta field for your drop down title. I would do something like this:

// load viewer library
$libraryPath = 'cmsAdmin/lib/viewer_functions.php';
$dirsToCheck = array('C:/wamp/www/','','../','../../','../../../');
foreach ($dirsToCheck as $dir) { if (@include_once("$dir$libraryPath")) { break; }}
if (!function_exists('getRecords')) { die("Couldn't load viewer library, check filepath in sourcecode."); }

// load records from 'reviews'
list($reviewRecords, $reviewMetaData) = getRecords(array(
'tableName' => 'reviews',
'loadUploads' => true,
'allowSearch' => false,
));

//Create an array that only contains the review items.
$reviewItems = array();
foreach($reviewRecords as $record){
//check if propery already is already in the review Items array, if not, add it to it.
if(!in_array($record['property:label'], $reviewItems) && $record['property'] > 0){
//Set the num value to the key, and set what is being stored in the label as the record value
$reviewItems[$record['property']] = $record['property:label'];
}
}
//Sort the items in the array alphabetically
sort($reviewItems);


echo ''."\n";
echo 'All Properties'."\n";

foreach ($reviewItems as $numValue => $reviewTitle) {
echo ''.$reviewTitle.''."\n";
}

echo ''."\n";

You might have to change some of the variables ( for example, section or field names) to get this working.

Thanks!

Greg

Greg Thomas







PHP Programmer - interactivetools.com

By weblm - January 9, 2013

Greg....you rock.

Two things:

1) Is there a way in that to obtain the property num?  That's the value I need in my select list as the value to re-sort the page.  Since the reviews table stores the property num, not the name.
2) Is there anyway to check to see if the property is Active and if not, don't include it in the list.

Now with your awesome left join code....I was able to change my reviews page to only show reviews for properties that are Active.  In doing that I changed my original code from this:

$reviewedProperties = mysql_query_fetch_all_assoc("SELECT num, property_name FROM {$TABLE_PREFIX}property_listings WHERE num='$reviewedPropertyNumrecord[property]'");

To this:

$reviewedProperties = mysql_query_fetch_all_assoc("SELECT num, property_name FROM {$TABLE_PREFIX}property_listings WHERE num='$reviewedPropertyNumrecord[property]' AND status='Active' ORDER BY property_name"); 

Thanks for all your help.

-Kevin

LM

By gregThomas - January 9, 2013

Hi Kevin,

1) If you've set up the property field in the reviews section so that the property num value is the value, and the property name/title is the label of each drop down entry (which I think you have looking at your code above). Then the field 'property field for each record should contain the property num value. I've highlighted in red values that I think should contain the num value in blue below.

2)This can be done with the trusty left join feature. I've added a left join statement to the getRecords function, and then used a where statement to filter out entires that arn't active. 

// load records from 'category'
list($reviewRecords, $reviewMetaData) = getRecords(array(
'tableName' => 'reviews',
'loadUploads' => true,
'where' => "property_listings.status = 'Active'",
'allowSearch' => false,
'leftJoin' => array(
'property_listings ' => 'property', // foreign table => local field (that matches num in foreign table)
)
));

//Create an array that only contains the review items.
$reviewItems = array();
foreach($reviewRecords as $record){
if(!in_array($record['property:label'], $reviewItems) && $record['property'] > 0){
$reviewItems[$record['property']] = $record['property:label'];
}
}
sort($reviewItems);


echo ''."\n";
echo 'All Properties'."\n";

foreach ($reviewItems as $numValue => $reviewTitle) {

echo '<option value="'.htmlentities($_SERVER['PHP_SELF']).'?property='.$numValue.'">'.$reviewTitle.'</option>'."\n";

}

echo ''."\n";

You will probably need to modify the code to use the correct variables like before. 

Cheers

Greg

Greg Thomas







PHP Programmer - interactivetools.com

By weblm - January 10, 2013

Hi Greg,

Yes, in the reviews section.....the property field is just the number of the property  (from the num field in the property_listings table).

What I'm getting with the value $numValue is array numbers from the NEW array....not the original values.  So for example, the $reviewItems array that is created below looks like this with a showme($reviewItems);

Array(
[0] => Alpine Creek #3
[1] => Alpine Creek #4
[2] => Aspenglow
[3] => Chez Louisa
[4] => Creekside
[5] => Great Western
)

Make sense?

Let me know your thoughts.

-Kevin

LM

By gregThomas - January 11, 2013

Hi Kevin,

Sorry about that, apparently the sort function destroys the current key values and uses it's own. Instead you need to use the asort function:

// load records from 'category'
list($reviewRecords, $reviewMetaData) = getRecords(array(
'tableName' => 'reviews',
'loadUploads' => true,
'where' => "property_listings.status = 'Active'",
'allowSearch' => false,
'leftJoin' => array(
'property_listings ' => 'property', // foreign table => local field (that matches num in foreign table)
)
));

//Create an array that only contains the review items.
$reviewItems = array();
foreach($reviewRecords as $record){
if(!in_array($record['property:label'], $reviewItems) && $record['property'] > 0){
$reviewItems[$record['property']] = $record['property:label'];
}
}
asort($reviewItems);


echo ''."\n";
echo 'All Properties'."\n";

foreach ($reviewItems as $numValue => $reviewTitle) {

echo '<option value="'.htmlentities($_SERVER['PHP_SELF']).'?property='.$numValue.'">'.$reviewTitle.'</option>'."\n";

}

Thanks!

Greg

Greg Thomas







PHP Programmer - interactivetools.com

By weblm - January 11, 2013

Greg......thank you SO much.  You have no idea how helpful you've been to me.  Do you work for Interactive Tools?  It's hard to tell in the new forum without the avatars like the old forum had.

This worked perfectly for me.

The only thing I added, just for anyone else's reference is.....we have some homes that start with A, or The.  In the MySQL queries, I'm able to orderby, by ignoring the 'The'.   But because we have to get this list and have PHP sort it.....I came across this bit of code that works:

# move a,an,the to the end of string
$reviewItems = preg_replace('/^(a|an|the) (.*)/i', "$2\x00$1", $reviewItems);

#asort keeps the original key values
asort($reviewItems);

# move a,an,the back to the beginning
$reviewItems = preg_replace('/^(.*?)\x00(.*)/', "$2 $1", $reviewItems);

Thanks again...you've been a HUGE help to me on this project.  

-Kevin

LM