Joomla using DISTINCT in mySQL call - php

I'm trying to use DISTINCT to get a list of cities from a column in my DB.
function cityData() {
$db =& JFactory::getDBO();
$query = "SELECT DISTINCT MSTCITY FROM " . $db->nameQuote('#__mls') . " ORDER BY MSTCITY;";
$db->setQuery($query);
$tbl = $db->loadObjectList();
return $tbl;
}
Is there something akin to loadObjectList() that I can use ?

There are several options available to get data using database object.
You can check this link- http://docs.joomla.org/Accessing_the_database_using_JDatabase/1.5
In your case you can use loadResultArray() in place of loadObjectList.It'll return list of cities as values of an array.

Here's the revised joomla resource page for version 2.5 and 3.x
Selecting data using JDatabase. Also since you're already using the loadObjectList() function this question may be better asked as
How to use DISTINCT and JDatabase together
This post has a good solution by Janga_Jack but for your example here's a Joomla 3.x way to accomplish what you need, that allows you to use the convenience methods quote() or q(), quoteName() or qn(), and especially escape() or e().
function cityData() {
$db =& JFactory::getDBO();
$query = $db->getQuery(true);
$fieldlist = $db->qn(array('mls.MSTCITY')); // add the field names to an array
$fieldlist[0] = 'distinct ' . $fieldlist[0]; //prepend the distinct keyword to the first field name
$query->select($fieldlist);
->from($db->qn('#__mls', 'mls'))
->order($db->qn('mls.MSTCITY'));
$db->setQuery($query);
$tbl = $db->loadObjectList();
return $tbl;
}

Related

Transfotm PHP SQL to Joomla SQL query

I am moving a PHP page to my Joomla website and I was advised that I "should use Joomla's coding standards and methods for everything, this includes database queries"
My question is:
How should I transform my old PHP code regarding Joomla standards:
$query = "SELECT * FROM `TABLE 2` WHERE Power=".$input->get('Power', '', 'RAW')." AND Poles=".$input->get('Poles', '', 'RAW')."";
$results = mysql_query($query)
or die(mysql_error());
while ($row = mysql_fetch_array($results))
{
extract($row);
}
?>
This is the TABLE 2 contents. I use the values of each row as a variables on my page.
Most importantly make sure to filter the input to disallow sql injections. Seems both your inputs are numbers (Power is a float and Poles possibly an int?). Also use the #__ - in table names, it will be replaced by the table prefex when you use it in joomla functions. Simplest way to transform your code would be something like:
$app = JFactory::getApplication();
$power = $app->input->getFloat('Power'); // use the correct function
$poles = $app->input->getInt('Poles'); // for the datatype you want
see here for JInput docs
$db = $app->getDbo();
//short variant
$sql = "SELECT * from `#__table 2` WHERE power = "
. $db->quote($power) . " AND poles = " . $db->quote($poles);
$db->setQuery($sql);
$result = $db->loadRowList();
foreach($result as $array){
print_r($array);
}
It should be noted that there are more useful methods for retrieving the data, loadAssoc/loadAssocList for associative arrays, loadObject/loadObjectList for objects. Check the docs for JDatabaseDriver
Alternatively you could transform the query to a "Joomla query" like:
$q = $db->getQuery();
$q->select("*")->from($q->quoteName("#__Table 2"));
$q->where("Power = " . $db->quote($power));
$q->where("Poles = " . $db->quote($poles));
$db->setQuery($q);
...
Docs to JDatabaseQuery

Trying to Find the Best way to pull DB item in Joomla 2.5 Component

I have a database which has 2 columns id and title. What is the best way for me to filter through these table values to display the matching title results when a user submits the id value in a form for a Joomla 2.5 component (admin view)?
When I look at the documentation here:
http://docs.joomla.org/Selecting_data_using_JDatabase
I see that by using Joomla’s API I can use a shorthand to create this connection. I have tried:
$userSubmittedIDValue = $_GET["userSubmittedIDValue"];
// Get a db connection.
$db = JFactory::getDbo();
// Create a new query object.
$query = $db->getQuery(true);
$query
->select($db->quoteName(array('title')))
->from($db->quoteName('#__mycomponent_table'))
->where($db->quoteName('id') . ' = '. $db->quote('$userSubmittedIDValue'))
$results = $db->loadObjectList();
Unfortunately, this gives the following error:
Parse error: syntax error, unexpected T_VARIABLE
Then the error points to $results = $db->loadObjectList();
I just need to pull that value and apply it to a php variable so that I can use it as required. Any ideas?
Okay thanks to the first answer I have realized that I was missing a semi-colon. The trouble I am having now is still in pulling the value from the array using foreach. I have tried adding the following:
foreach (array($results) as $userSubmittedIDValue) {
echo $results;
}
But this just prints the word Array. I am getting close, but something is still off.
You're getting that error due to the fact you have a missing semi colon after your query.
So, change this:
->where($db->quoteName('id') . ' = '. $db->quote('$userSubmittedIDValue'))
to this:
->where($db->quoteName('id') . ' = '. $db->quote('$userSubmittedIDValue'));
Simply note the ; on the end
Once done, you can use a foreach loops to display your results.
So your final code to use would be this:
$db = JFactory::getDBO();
$query = $db->getQuery(true);
$query->select('*')
->from('#__mycomponent_table')
->where($db->quoteName('id') . ' = '. $db->quote($userSubmittedIDValue));
$db->setQuery($query);
$rows = $db->loadObjectList();
foreach ($rows as $row) {
echo $row->title;
}
I completely forgot to mention before that you also have to remove the single quote wrapped around $userSubmittedIDValue in the query as shown in my code above.
Hope this helps

Close session after executing database query

I have very little experience with joomla and sql and I would really appreciate your help!
I am using joomla 2.5 and I am querying data from the database and storing it in memory with the following code:
function getList()
{
$mainframe = JFactory::getApplication('site');
$db = JFactory::getDBO();
$query = " SELECT
*
FROM
#__ListUser
WHERE
$db->setQuery( $query );"
$rows = $db->loadObjectList();
return $rows;
}
I have 3 questions,
When I query the database, a new DB session is opened, Do I need to close it after or is automatic?
Do you know of a more efficient way to achieve this method (a user session memory size is about 11MB!)
Is there any security issue with accessing the database using this method?
Thank you very much! any help would be very appreciated!
The code should look like this (I don't see how it can work now):
function getList()
{
// $mainframe = JFactory::getApplication('site'); // you don't need this line!
$db = JFactory::getDBO();
$query = " SELECT
*
FROM
#__ListUser
WHERE
1=1"; // just some condition to extract selected rows
$db->setQuery( $query ); // this sets the query and it's joomla, not sql.
$rows = $db->loadObjectList();
return $rows;
}
Please note the WHERE .... needs a condition (else if you want all the rows, remove WHERE and what follows)
You don't need to close it
11Mb is not necessarily due to that query, try adding LIMIT 0,1 (to return just one row) you'll see your memory doesn't change much. Turn on debug in the global configuration, and reload the component. At the very bottom of the page you'll see which extensions are eating up your memory. 11Mb is acceptable though on most installations.
Should you create your WHERE condition using input params, just make sure you $db->quote() any values to prevent SQL-injection.
Try
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->select($db->quote('*')
->from($db->quoteName('#__Listuser') // Do you really have upper case there?
->where('your condition with proper quoting');
$db->setQuery($query);
$rows = $db->loadObjectList();
1.
UNCOOL:
If you want to close or disconnect the database-session, you may use:
$db->disconnect(); // See: http://api.joomla.org/cms-3/classes/JDatabaseDriver.html#method_disconnect
But i guess, that the database-connection for every other module, plugin or template that want to use JFactory::getDBO(); is also closed then and needs to be reopened.
BETTER:
You should use FREE RESULT instead after a query is transfered to a PHP-Variable: http://api.joomla.org/cms-3/classes/JDatabaseDriverMysql.html#method_freeResult
$db->freeResult();

PHP loop to echo all Joomla article id's

With my very basic PHP knowledge I'm trying to make a module for Joomla V1.5. I am not quite into all the Joomla classes and methods but perhaps you can help me out.
What I'm trying to do is create a php loop which echo's all the article id's (and some html) from a certain category.
Normally I would do this by calling on the content table from the Joomla db but to make the code a bit more tidy I want to use the Joomla classes for this.
Can anyone point me the right direction which classes and methods to use for this?
There are no classes for handling the selection of the articles.
So it comes down to using a query and looping through the result set:
$catId = 59; // the category ID
$query = "SELECT * FROM #__content WHERE catid ='" . $catId . "'"; // prepare query
$db = &JFactory::getDBO(); // get database object
$db->setQuery($query); // apply query
$articles = $db->loadObjectList(); // execute query, return result list
foreach($articles as $article){ // loop through articles
echo 'ID:' . $article->id . ' Title: ' . $article->title;
}

Select ignores where clause using Zend_Db_Select

$table = new Zend_Db_Table(array('name'=>'rules'));
$select = $table->select();
$select->setTable($table);
$select->setIntegrityCheck(false);
$select = $select
->from(array('ru'=>'rules'),array('ru.*'))
->join(array('ro'=>'roles'),'ro.id=ru.role_id',array('role_id'=>'ro.id'))
->join(array('g'=>'groups'),'ro.group_id=g.id',array('group_id'=>'g.id'))
->join(array('ug'=>'user_groups'),"ug.group_id=g.id",array('user_group_id'=>'ug.id'))
->where("ug.user_id={$userId}")
->where("ru.resource='{$resource}'")
->where("ru.privilege='{$privilege}'");
echo "select: ".$select->__toString();
$row = $table->fetchAll();
I have the preceding code,but when I try fetchAll() it returns all rows in the table, ignoring the where clause, when I use fetchRow() it returns the first row it finds, ignoring the where clause, I printed the SQL statement and run it separately and it executes correctly
any clue ?
This is how you would create a db select object correctly
$db = Zend_Db::factory( ...options... );
$select = new Zend_Db_Select($db);
Or you use the database adapter's select() method
$db = Zend_Db::factory( ...options... );
$select = $db->select();
And you can add clauses
// Build this query:
// SELECT *
// FROM "table1"
// JOIN "table2"
// ON "table1".column1 = "table2".column1
// WHERE column2 = 'foo'
$select = $db->select()
->from('table1')
->joinUsing('table2', 'column1')
->where('column2 = ?', 'foo');
Have a look at the Zend_Db Reference Guide for more information
#ArtWorkAD is right in a certain way. But in your case you're not just using a Zend_Db_Select. You tried to extend a Zend_Db_Select obtained from a Zend_Db_Table (well, you should try to handle a Singleton pattern with Zend_Db_Table but this is another problem). Your current problem (if we except the fact you are certainly reading documentation too fast) is that this line was correct:
$select->setIntegrityCheck(false);
It make your 'select-from-a-zend-db-table' not anymore restricted to the Active Record Mode, and available for extra joins.
But just after that you make a:
$select = new Zend_Db_Select($table);
This is the complete creation of a new object, that you put into your variable. Nothing is kept from previous variable value. You could add a $select=null; just before it would be the same. So this is just canceling the 3 previous lines.
In quite the same confusion mode this line:
$select->setTable($table);
Is not necessary as you're already taking the select from a Zend_Db_Table so the table is already there.
EDIT
And your last and bigger error is:
$table->fetchAll()
You do not use your built $select but your $table, so effectively everything done in your $select is ignored :-) . Fecthing from the $select shoudl give you better results
This should work. Just tested it.
$table = new Zend_Db_Table('rules');
$select = $table->getAdapter()->select();
$select->from(array('ru' => 'rules'), array('ru.*'))
->join(array('ro'=>'roles'), 'ro.id = ru.role_id', array('role_id'=>'ro.id'))
->join(array('g'=>'groups'), 'ro.group_id = g.id', array('group_id'=>'g.id'))
->join(array('ug'=>'user_groups'),"ug.group_id=g.id",array('user_group_id'=>'ug.id'))
->where('ug.user_id = ?', $userId)
->where('ru.resource = ?', $resource)
->where("ru.privilege = ?", $privilege);
echo (string)$select;

Categories