Search through related model in Yii - search

I have a problem with searching in Yii. I have two models: Teams and Workers. On website there is a page called 'Team Workers' where I want to display CGridView widget with searching that displays Workers from the team (team id is passed as a _GET parameter).
I did this in TeamsController:
public function actionWorkers($id)
{
$model = Teams::model()->findByPk($id);
$workers = Workers::model();
$workers->unsetAttributes();
if(isset($_GET['Workers']))
{
$_GET['Workers']['idTeam'] = $id;
$workers->attributes = $_GET['Workers'];
}
else {
$workers->attributes = array('idTeam' => $id);
}
$teamWorkers = $workers;
$this->render('workers', array(
'model' => $model,
'teamWorkers' => $teamWorkers
));
}
And in the view file:
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'team-workers-grid',
'dataProvider'=>$teamWorkers->search(),
'filter' => $teamWorkers,
'columns'=>array(
'name',
'surname',
array(
'id' => 'idWorker',
'class' => 'CCheckBoxColumn',
'checked' => '$data->confirmer',
'selectableRows' => '2',
// 'headerTemplate' => '{item}'
)
),
)); ?>
I got the error:
CDbCommand nie zdołał wykonać instrukcji SQL: SQLSTATE[23000]: Integrity constraint
violation: 1052 Column 'idTeam' in where clause is ambiguous. The SQL statement
executed was: SELECT COUNT(DISTINCT `t`.`idWorker`) FROM `workers` `t` LEFT OUTER JOIN
`teams` `Team` ON (`t`.`idTeam`=`Team`.`idTeam`) WHERE ((idTeam=:ycp0) AND (Team.name
LIKE :ycp1))
When I dont set idTeam attribute - it works fine. It's pretty weird - at the regular CRUD admin page - idTeam attribute is passed and that works fine.
Hot to deal with it?

In Workers::search() you have something like
$criteria->compare('idTeam',$this->idTeam);
Change it to
$criteria->compare('t.idTeam',$this->idTeam);
i.e prefix sql attribute with t. if it is from current model or with relation name if from other table/model
Also instead of:
$workers->attributes = array('idTeam' => $id);
yould could keep it simpler with:
$workers->idTeam = $id;

You have defined the column idTeam in Team and Workers. By joining those tables you would have a duplicate ("ambiguous") column in the result. That's what the error message tells you.
To solve this you have to use an alias for one of the columns.

Related

How to use select query for creating form in drupal 8?

I have a table in my database. I want to use the data of that table and create form of that data. I created a module and made a form.php page. Wrote select query in function but how to make form from that data?
I believe you want to create listing page of the table data. Here is how you can create a tabular listing with pagination and column sorting.
Suppose you have a table named "students" with the below fields.
id, name, email
1. Create a controller in your module in the below path.
modules/your_module/Src/Controller/StudentsController.php
<?php
namespace Drupal\your_module\Controller;
use Drupal\Core\Controller\ControllerBase;
class StudentsController extends ControllerBase {
public function __construct() {
}
public function list() {
$header = array(
array('data' => t('ID'), 'field' => 'st.id'),
array('data' => t('Name'), 'field' => 'st.name'),
array('data' => t('Email'), 'field' => 'st.email'),
);
$query = db_select('students', 'st')
->fields('st', array('id', 'name', 'email'))
->extend('Drupal\Core\Database\Query\TableSortExtender')
->extend('Drupal\Core\Database\Query\PagerSelectExtender')
->orderByHeader($header);
$data = $query->execute();
$rows = array();
foreach ($data as $row) {
$rows[] = array('data' => (array) $row);
}
$build['table_pager'][] = array(
'#type' => 'table',
'#header' => $header,
'#rows' => $rows,
);
$build['table_pager'][] = array(
'#type' => 'pager',
);
return $build;
}
}
So your controller action is ready, now you have to add routing in order to create path to this listing page.
2. Create routing.yml file inside your module folder as the file name mentioned below, and the code below.
modules/your_module/your_module.routing.yml
students.list:
path: 'admin/config/students/list'
defaults:
_controller: 'Drupal\your_module\Controller\StudentsController::list'
_title: 'Students List'
requirements:
_permission: 'access students list'
3. To create permissions, you can create the followin ing file in your module.
modules/your_module/your_module.permissions.yml
access students list:
title: 'Access students list page'
Clear CMS cache
Go to People => Permissions, Enable the permission for relevant user roles.
Then, browse your page "admin/config/students/list"

How to stop Silverstripe SearchContext from throwing Version Table_Live error

Consider the following Silverstripe page class
<?php
class Page extends SiteTree{
static $has_many = array('OtherDataObjects' => 'DataObjectClass');
public function getSearchContext() {
$fields = new FieldSet(
new TextField('Title', 'Tour'),
new DropdownField('OtherDataObjects', 'Other Data Object', array('data', 'value')
);
$filters = array(
'Title' => new PartialMatchFilter('Title'),
'OtherDataObjects' => new PartialMatchFilter('OtherDataObjects.Title')
);
return new SearchContext(
'Page',
$fields,
$filters
);
}
}
Adding this search form to a front-end form and posting a search form always results in a [User Error] with a SQL error containing something like this at the end.
AND ("DataObjectClass_Live"."DataObjectClass_Live" LIKE 'title') ORDER BY "Sort" LIMIT 25 OFFSET 0 Table 'database DataObjectClass_Live' doesn't exist
My searchcontext search throws up an error each time I try to run a search on a has_many relationship. The versioned extension seems to be the culprit because it adds _live to all tables regardless whether the baseclass has the versioned extension or not I get the same error in SilverStripe versions 2.4.x and the latest 3.0.x versions.
Any help or pointers will be appreciated.
maybe try using an sqlQuery. something like
function SearchResults() {
$select = array('*');
$from = array('OtherDataObjects');
$where = array('OtherDataObjects:PartialMatch' => '%' . $data['Title'] . '%');
$sqlQuery = new SQLQuery($select, $from, $where);
$results = $sqlQuery->execute();
return $results;
}
$data['Title'] is to be the value from the search textbox
partial match reference: http://doc.silverstripe.org/framework/en/topics/datamodel
sql query reference: http://doc.silverstripe.org/framework/en/reference/sqlquery

Drupal 7 programmatic field definition

I need to programmatically set up a node reference field.
My module successfully creates a and associates a pair of 'CCK' fields to my nodes. One of these fields is a node_reference field. My code is a follows:
$field_ref_name = 'field_custom_reference';
$field = field_info_field($field_ref_name);
if (empty($field)) {
$field = array(
"field_name"=>$field_ref_name,
"label"=>"Custom Reference",
"type"=>"node_reference",
"cardinality"=>"1",
'locked' => TRUE,
);
field_create_field($field);
}
$instance = array(
"field_name"=>$field_ref_name,
"label"=>"Sequence Reference",
"type"=>"node_reference",
"widget"=>array(
"type"=>"node_reference_autocomplete"
),
"description" => "text describing purpose of this field",
);
$instance["entity_type"] = "node";
$instance["bundle"] = $type;
if( !in_array($type, $field['bundles']['node']) )
field_create_instance($instance);
Now, the code works but when I edit a node inputting a valid value into the node reference field and attempt to save, I get the following error:
...: this post can't be referenced.
I realized the reason for the error is because the node reference field settings does not have any selected nodes as "Content types that can be referenced".
How can I adjust my code to set referenceable content types?
The reference-able types is a field setting. So it should be put under a "settings" array in the field definition. Something like -
$field = array(
"field_name"=>$field_ref_name,
"label"=>"Custom Reference",
"type"=>"node_reference",
"cardinality"=>"1",
'locked' => TRUE,
'settings' => array(
'referenceable_types' => array('article'),
),
);

Empty Grid in jqgrid

I am trying to integrate a grid to my PHP project, JQgrid looked so easy!!
When i Integrated I was only able to see the grid, not the data in the grid!
I have just change the db settings of the sample code to work with my DB.
Debug results:
When I debugged with firebug I am able to see the db rows in the consolde mode of firebug.
Here with also pasting the logs of jqGrid.log
It also throws a warning msg "Warning: date() [function.date]: It is not safe to rely on the system's timezone settings. You are required to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'America/New_York' for '-5.0/no DST' instead in C:\Users\Karthik\Desktop\apache\htdocs\php\jqGrid.php(1) : eval()'d code on line 1"
Both files resides in root directory. Some clues to troubleshoot
PHP Code"myfristgrid.php"
require_once 'jq-config.php';
// include the jqGrid Class
require_once "php/jqGrid.php";
require_once "php/jqGridPdo.php";
$conn = new PDO(DB_DSN,DB_USER,DB_PASSWORD);
$conn->query("SET NAMES utf8");
$grid = new jqGridRender($conn);
$grid->debug = true;
$grid->SelectCommand = 'SELECT * FROM question';
$grid->datatype = 'json';
$grid->setColModel();
$grid->setUrl('myfirstgrid.php');
$grid->setGridOptions(array(
"caption"=>"This is custom Caption",
"rowNum"=>10,
"sortname"=>"id",
"hoverrows"=>true,
"rowList"=>array(10,20,50),
));
$grid->setColProperty("id", array("label"=>"ID", "width"=>60));
// Enjoy
$grid->renderGrid('#grid','#pager',true, null, null, true,true);
$conn = null;
jqGrid.log
Executed 2 query(s) - 2011-01-26 22:50:28
Array
(
[0] => Array
(
[time] => 2011-01-26 22:50:28
[query] => SELECT COUNT(*) AS COUNT FROM question
[data] =>
[types] =>
[fields] =>
[primary] =>
[input] =>
)
[1] => Array
(
[time] => 2011-01-26 22:50:28
[query] => SELECT * FROM question ORDER BY id asc LIMIT 0, 10
[data] =>
[types] =>
[fields] =>
[primary] =>
[input] =>
)
)
You can't properly use setColProperty in the jqGrid.

how to index cck field of type text area in solr: drupal6

I've created a cck filed of type textarea with name filed_desc, how do i get this field to index in solr.
i found this article http://acquia.com/blog/understanding-apachesolr-cck-api, i have tried this but it is not indexing the filed, can somebody help.
<?php
// $Id$
/**
* Implementation of hook_apachesolr_cck_fields_alter
*/
function example_apachesolr_cck_fields_alter(&$mappings) {
// either for all CCK of a given field_type and widget option
// 'filefield' is here the CCK field_type. Correlates to $field['field_type']
$mappings['text'] = array(
'text_textarea' => array('callback' => 'example_callback', 'index_type' => 'string'),
);
}
/**
* A function that gets called during indexing.
* #node The current node being indexed
* #fieldname The current field being indexed
*
* #return an array of arrays. Each inner array is a value, and must be
* keyed 'value' => $value
*/
function example_callback($node, $fieldname) {
$fields = array();
foreach ($node->$fieldname as $field) {
// In this case we are indexing the filemime type. While this technically
// makes it possible that we could search for nodes based on the mime type
// of their file fields, the real purpose is to have facet blocks during
// searching.
$fields[] = array('value' => $field['field_desc']);
}
return $fields;
}
?>
I am currently working on adding this in a nice, pretty, generic way. If you really need this working now, take a look at this issue on Drupal.org. My code is currently living at GitHub, though hopefully I can get this included upstream and make a release of it.
Hope that helps!
Per field mapping is easier to control.
alter function:
$mappings['per-field']['field_specialities'] = array(
'index_type' => 'string',
'callback' => 'ge_search_apachesolr_field_specialities_callback'
);
callback:
function ge_search_apachesolr_field_specialities_callback($node, $fieldname)
{
$fields = array();
foreach($node->$fieldname as $field) {
$fields[] = array('value' => $field['value']);
}
return $fields;
}

Resources