Drupal 7 db_query - database

The perfect little module for what I am looking to do was made for drupal 6 but to my dismay it doesn't work on drupal 7. I've have learned that drupal 7 has a new api for the database. I have tried to get it to work but I am admittedly out of my league here. I am hoping some one could give me a little guidance. Specifically with the db_query.
function webform_image_validation_webform_validation_validate($validator_name, $items,
$components, $rule) {
$errors = array();
if ($items) {
switch ($validator_name) {
case 'max_image_size':
$dimensions = explode('x', $rule['data']);
foreach ($items as $key => $val) {
if (is_numeric($val['_fid'])) {
$result = db_query("select * from {files} where fid = %d", $val['_fid']);
while ($data = db_fetch_object($result)) {
$thefile = $data;
}
$image_info = image_get_info($thefile->filepath);
if (webform_image_validation_validate_image($image_info, $dimensions[0], $dimensions[1], FALSE) === FALSE) {
$errors[$key] = t('Your image did not match the required width and/or height. (') . $dimensions[0] . t(' x ') . $dimensions[1] . t(')');
}
}
}
This is the error I receive.
Argument 2 passed to db_query() must be an array, string given, called in
/home/designco/public_html/dev/sites/all/modules/webform_image_validation/
webform_image_validation.module on line 69 and defined in
/home/designco/public_html/dev/includes/database/database.inc on line 2310
It appears I need to add an array but I get lost there. Any help would be appreciated. I'm just trying to find out if I'm the right track.

db_query works differently in Drupal7.
$result = db_query("select * from {files} where fid = %d", $val['_fid']);
while ($data = db_fetch_object($result)) {
$thefile = $data;
}
becomes
$results = db_query("select * from {files} where fid = :fid", array(':fid' => $val['_fid']));
foreach($results as $result) {
// Do your thing for each result.
}

Try changing
$result = db_query("select * from {files} where fid = %d", $val['_fid']);
while ($data = db_fetch_object($result)) {
$thefile = $data;
}
to
$query = db_select('files', 'f')
->fields('f')
->condition('fid', $val['_fid']);
$thefile = $query->execute()->fetchObject();
The Drupal 7 database API docs http://drupal.org/node/310069

thanks JurgenR for the answer.
Just to add one more thing: In drupal 6, we use '%s' for strings. In drupal 7, it is same for all.
For example:
$results = db_query("select * from {files}
where filename = :fname", array(':fname' => $filename));
If you want to search for records starting with a pattern then query will be:
$results = db_query("select * from {files}
where filename = :fname", array(':fname' => $filename.'%'));
Hope this is useful.

Related

How can i get top 15 occurrences in an array and use each value to fetch data from mysql database?

I am currently working on a project (A music website) with PHP Codeigniter. I want to fetch top 15 songs by number of downloads. To my knowledge, I got all unique ID's out ranging from highest to least. But now, I want to use each of these unique ID's to fetch data from another table in the database.
I have tried using for loop; but it seems to only return one of the rows which happens to be the first and highest number of occurrence in the array. The code below echo's the ID's but how can I use each of those ID's to fetch data.
function top15(){
$this->db->select('musiccode');
$result=$this->db->get('downloads');
$query = $result->result_array();
$downloads = array();
if(!empty($query)) {
foreach($query as $row)
{
$musiccode[] = $row['musiccode'];
}
$mode = array_count_values($musiccode);
arsort($mode);
$i = 0;
foreach ($mode as $field => $number) {
$i++;
echo $field." occured ". $number." times <br>";
if ($i == 15) {
break;
}
}
}
}
for ($b=0; $b < count($field); $b++) {
$this->db->where(array('track_musiccode'=> $field));
$field = $this->db->get('tracks');
return $field->result_array();
}
The code above only produce one row for me. I expect to have more than one and according to the number of ID's in the array. Thanks in advance.
For a single column condition, you could use where_in() instead and drop the for loop :
$this->db->where_in('track_musiccode', $field);
$field = $this->db->get('tracks');
return $field->result_array();
Yes Finally i did it. Incase if anyone needs it. this works just fine
function top15(){
$this->db->where('d_month', date('m'));
$this->db->select('musiccode');
$result=$this->db->get('downloads');
$query = $result->result_array();
$downloads = array();
if(!empty($query)) {
foreach($query as $row){
$musiccode[] = $row['musiccode'];
}
$res='';
$count=array_count_values($musiccode);
arsort($count);
$keys=array_keys($count);
for ($i=0; $i < count($keys); $i++) {
$res[] .= "$keys[$i]";
}
$this->db->where_in('track_musiccode', $res);
return $this->db->get('tracks')->result_array();
}
}
And I got this too. If I wasn't going to count occurrences but just iterate the number of downloads which is far more better than counting in other not to over populate the database and make your website work slowly.
function top15(){
$tracks = '';
$this->db->group_by('counter');
$result=$this->db->get('downloads');
$query = $result->result_array();
$counter = '';
$fields = '';
if(!empty($query)) {
foreach($query as $row) {
$counter[] = $row['counter'];
}
rsort($counter);
for ($i=0; $i<=15; $i++) {
$this->db->where('downloads.counter', $counter[$i]);
$this->db->join('tracks', 'tracks.musicid = downloads.musicid');
$fields[] = $this->db->get('downloads')->row_array();
}
return $fields;
}
}
Enjoy...

Merging and adding values of 2 JSON feeds in PHP

I'm trying to write a shopping list app for a website which already has ingredients listed in JSON.
The full code is at the bottom, but just to explain; What I'm aiming to do is to be able to merge the 2 arrays, adding the values from the 'quantity' when the 'name' (and preferably also the 'measure') matches.
e.g. 'Sunflower oil' is listed in both JSON feeds.
I want it to output as:
{"name":"Sunflower oil","quantity":110,"measure":"ml"}
but it currently overwrites the JSON and the output is:
{"name":"Sunflower oil","quantity":10,"measure":"ml"},
Any assistance in what I'm doing wrong would be greatly appreciated as JSON and objects/arrays aren't my strong point!
Thanks in advance - here's my code:
<?php
$a = '{"ingredients":[{"name": "Sunflower oil","quantity": 100,"measure": "ml"}]}';
$b = '{"ingredients":[{"name": "Sunflower oil","quantity": 10,"measure": "ml"},{"name": "Fennel seeds","quantity": 1,"measure": "teaspoon"},{"name": "Garlic","quantity": 1,"measure": "clove"}]}';
print_r( json_encode(array_merge(json_decode($a, true),json_decode($b, true))) );
?>
You can use the following code to get the expected result:
<?php
$a = '{"ingredients":[{"name": "Sunflower oil","quantity": 100,"measure": "ml"},{"name": "Olive oil","quantity": 50,"measure": "ml"}]}';
$b = '{"ingredients":[{"name": "Sunflower oil","quantity": 10,"measure": "ml"},{"name": "Fennel seeds","quantity": 1,"measure": "teaspoon"},{"name": "Garlic","quantity": 1,"measure": "clove"}]}';
$aArr = json_decode($a, true);
$bArr = json_decode($b, true);
$sumArr = array("ingredients" => array());
foreach ($aArr['ingredients'] as $valA) {
foreach ($bArr['ingredients'] as $keyB => $valB) {
if ($valA['name'] == $valB['name'] &&
$valA['measure'] == $valB['measure']) {
$valA['quantity'] += $valB['quantity'];
$sumArr['ingredients'][] = $valA;
unset($bArr['ingredients'][$keyB]);
continue 2;
}
}
$sumArr['ingredients'][] = $valA;
}
$sumArr['ingredients'] = array_merge($sumArr['ingredients'], $bArr['ingredients']);
print_r( json_encode( $sumArr ));
?>

How do you filter Joomla 3 articles by article id

I'm trying to create a Joomla module that displays articles based on categories and tags.
I've taken code for selecting tagged articles from https://github.com/lasinducharith/joomla-tags-selected) and introduced it into a copy of mod_articles_news:
public static function getList(&$params)
{
$app = JFactory::getApplication();
$db = JFactory::getDbo();
// Code base on https://github.com/lasinducharith/joomla-tags-selected to fetch ids of tagged articles
$tagsHelper = new JHelperTags;
$tagIds = $params->get('tagid', array());
$tagIds = implode(',', $tagIds);
echo '<pre>search for tags[' . $tagIds . ']';
$query=$tagsHelper->getTagItemsQuery($tagIds, $typesr = null, $includeChildren = false, $orderByOption = 'c.core_title', $orderDir = 'ASC',$anyOrAll = true, $languageFilter = 'all', $stateFilter = '0,1');
$db->setQuery($query, 0, $maximum);
$results = $db->loadObjectList();
$article_ids=array();
foreach ($results as $result){
$article_ids[]=$result->content_item_id;
}
echo ' yields articles[' . implode(',', $article_ids ) . ']</pre>';
// Get an instance of the generic articles model
$model = JModelLegacy::getInstance('Articles', 'ContentModel', array('ignore_request' => true));
// Set application parameters in model
$appParams = JFactory::getApplication()->getParams();
$model->setState('params', $appParams);
// Set the filters based on the module params
$model->setState('list.start', 0);
$model->setState('list.limit', (int) $params->get('count', 15));
$model->setState('filter.published', 1);
$model->setState('list.select', 'a.fulltext, a.id, a.title, a.alias, a.introtext, a.state, a.catid, a.created, a.created_by, a.created_by_alias,' .
' a.modified, a.modified_by, a.publish_up, a.publish_down, a.images, a.urls, a.attribs, a.metadata, a.metakey, a.metadesc, a.access,' .
' a.hits, a.featured' );
// Access filter
$access = !JComponentHelper::getParams('com_content')->get('show_noauth');
$authorised = JAccess::getAuthorisedViewLevels(JFactory::getUser()->get('id'));
$model->setState('filter.access', $access);
// Category filter
$model->setState('filter.category_id', $params->get('catid', array()));
// Article filter
$model->setState('filter.id', $article_ids);
// Filter by language
$model->setState('filter.language', $app->getLanguageFilter());
// Set ordering
$ordering = $params->get('ordering', 'a.publish_up');
$model->setState('list.ordering', $ordering);
if (trim($ordering) == 'rand()')
{
$model->setState('list.direction', '');
}
else
{
$direction = $params->get('direction', 1) ? 'DESC' : 'ASC';
$model->setState('list.direction', $direction);
}
// Retrieve Content
$items = $model->getItems();
$newitems=array();
foreach ($items as &$item)
{
echo '<pre>fetched article[' . $item->id .'] which is ';
if ( !in_array($item->id, $article_ids )){
echo 'not tagged';
} else{
echo 'tagged';
}
echo '</pre>';
...
}
return $newitems;
}
The debug statements give me:
search for tags[2] yields articles[40,44,45]
fetched article[45] which is tagged
fetched article[44] which is tagged
fetched article[43] which is not tagged
fetched article[42] which is not tagged
fetched article[41] which is not tagged
fetched article[40] which is tagged
fetched article[39] which is not tagged
fetched article[38] which is not tagged
So the articles have not been filtered by id. I'd be very grateful for any advice.
Thanks
Found the problem, the filter should be article_id:
// Article filter
$model->setState('filter.article_id', $article_ids);
Now it selects articles based on tags and categories

Find all in CakePHP is dumping a semicolon in my view

I don't know what exactly is happening with my CakePHP app. It worked last week and I have literally changed nothing with that particular file.
When I use find 'all' in my controller it dumps a semi-colon in my view even if there is nothing in the view file.
Here is my code
$evts = $this->Event->find('all');
There is nothing in my view file. I don't know if it makes a difference but I'm using a json view.
As requested here is the complete code for the action
public function search(){
$this->Event->recursive = 2;
$conditions = array();
if(!empty($this->request->query['name'])){
$conditions = array('Event.name LIKE ' => "%" . str_replace(" ","%", $this->request->query['name']) . "%");
}
if(!empty($this->request->query['home'])){
$conditions = array('Event.home_team_id' => $this->request->query['home']);
}
if(!empty($this->request->query['away'])){
$conditions = array('Event.away_team_id' => $this->request->query['away']);
}
$limit = 25;
if(!empty($this->request->query['limit'])){
$limit = $this->request->query['limit'];
}
//$evts = $this->Event->find('all',array('conditions'=>array($conditions),'order' => array('Event.start_time'),'limit'=>$limit));
$evts = $this->Event->find('all');
$this->set('events',$evts);
}
Everything in the view has been commented out ... but here is the code anyway
$results = array();
$i = 0;
foreach ($events as $event) {
$results[$i]['id'] = $event['Event']['id'];
$results[$i]['label'] = $event['Event']['name'] . "(" . date_format(date_create($event['Event']['start_time']), 'D, jS M Y') . ")";
$results[$i]['value'] = $event['Event']['name'];
$results[$i]['home_team_name'] = $event['HomeTeam']['name'];
$results[$i]['away_team_name'] = $event['AwayTeam']['name'];
$results[$i]['sport_name'] = $event['Sport']['name'];
$results[$i]['tournament_name'] = $event['Tournament']['name'];
$results[$i]['start_time'] = $event['Event']['start_time'];
$results[$i]['img'] = $event['Event']['img_path'];
$results[$i]['listener_count'] = 0; //TODO Get the follower count
$i++;
}
echo json_encode($results);
Display
If you changed nothing with that particular file then perhaps you have installed callbacks (either in the controller or in the model) that echo that ";". Look for 'afterFind' calls...
Search your model and your controller folders for "echo statement". In fact you should search your entire app folder except for the Views folder.

How do I use fixed fields in CakeDC's csvUpload behavior in Util plugin

I am using the csvUpload behavior of the Utils plugin by CakeDC, on a CakePHP 2.2.1 install.
I have it working great it's processing a rather large csv successfully. However there are two fields in my table / Model that would be considered fixed, as they are based on ID's from from associated models that are not consistent. So I need to get these fixed values via variables which is easy enough.
So my question is, how do I use the fixed fields aspect of csvUpload? I have tried that following and many little variation, which obviously didn't work.
public function upload_csv($Id = null) {
$unique_add = 69;
if ( $this->request->is('POST') ) {
$records_count = $this->Model->find( 'count' );
try {
$fixed = array('Model' => array('random_id' => $Id, 'unique_add' => $unique_add));
$this->Model->importCSV($this->request->data['Model']['CsvFile']['tmp_name'], $fixed);
} catch (Exception $e) {
$import_errors = $this->Model->getImportErrors();
$this->set( 'import_errors', $import_errors );
$this->Session->setFlash( __('Error Importing') . ' ' . $this->request->data['Model']['CsvFile']['name'] . ', ' . __('column name mismatch.') );
$this->redirect( array('action'=>'import') );
}
$new_records_count = $this->Model->find( 'count' ) - $records_count;
$this->Session->setFlash(__('Successfully imported') . ' ' . $new_records_count . ' records from ' . $this->request->data['Model']['CsvFile']['name'] );
$this->redirect(array('plugin'=>'usermgmt', 'controller'=>'users', 'action'=>'dashboard'));
}
}
Any help would be greatly appreciated as I have only found 1 post concerning this behavior when I searching...
I made my custom method to achieve the same task. Define the following method in app\Plugin\Utils\Model\Behavior
public function getCSVData(Model &$Model, $file, $fixed = array())
{
$settings = array(
'delimiter' => ',',
'enclosure' => '"',
'hasHeader' => true
);
$this->setup($Model, $settings);
$handle = new SplFileObject($file, 'rb');
$header = $this->_getHeader($Model, $handle);
$db = $Model->getDataSource();
$db->begin($Model);
$saved = array();
$data = array();
$i = 0;
while (($row = $this->_getCSVLine($Model, $handle)) !== false)
{
foreach ($header as $k => $col)
{
// get the data field from Model.field
$col = str_replace('.', '-', trim($col));
if (strpos($col, '.') !== false)
{
list($model,$field) = explode('.', $col);
$data[$i][$model][$field] = (isset($row[$k])) ? $row[$k] : '';
}
else
{
$col = str_replace(' ','_', $col);
$data[$i][$Model->alias][$col] = (isset($row[$k])) ? $row[$k] : '';
}
}
$is_valid_row = false;
foreach($data[$i][$Model->alias] as $col => $value )
{
if(!empty($data[$i][$Model->alias][$col]))
{
$is_valid_row = true;
}
}
if($is_valid_row == true)
{
$i++;
$data = Set::merge($data, $fixed);
}
else
{
unset($data[$i]);
}
}
return $data;
}
And you can use it using:
$csv_data = $this->Model->getCSVData($this->request->data['Model']['CsvFile']['tmp_name'], $fixed);
Here $csv_data will contain an array of all of those records from the csv file which are not empty and with the fixed field in each record index.
So as I was telling Arun, I answered my own question and figured it out. I was looking to broad instead of really examining what was in front of me. I started running some debugging and figured it out.
First of all, $unique_add = 69 is seen as an int, duh. In order for it to be added to the csv it need to viewed as a string. So it simply becomes, $unique_add = '69'.
I couldn't enter the value of $Id directly into the fixed array. So I just had to perform a simple find to get the value I needed.
$needed_id = $this->Model->find('first', array(
'condition'=>array('Model.id'=>$Id)
)
);
$random_id = $needed_id['Model']['id'];
Hopefully this won't be needed to help anyone because hopefully no one else will make this silly mistake. But one plus... Now there's actually more than one post on the internet documenting the use of fixed fields in the CakeDC Utils plugin.

Resources