I'm currently working on a Codeigniter 3 project that has real time search values using datatables, the project was on MySQL and all worked fine and it has to be migrated to PostgreSQL and now the search doesn't work because is needed to add explicit type casts in the ID column, this is the error: ERROR: operator does not exist: integer ~~ text.
I figured how to do it by adding ::varchar after de column name and I tested it typing the Query directly on PHPpgadmin and it works, but I can't find how i exactly i can do this in the CI code
This is the code
$datatable->db_search(array(
"consultas.nombre",
"usuarios.username",
"u2.username",
"consultas.guest_email",
"consultas.last_reply_string",
"consultas.ID",
)
);
db_search function
public function db_search($columns)
{
if(!empty($this->search)) {
if($this->search_type == 0) {
// Search all columns for likeness
$words = explode(" ", $this->search);
$this->CI->db->group_start();
foreach($words as $word) {
foreach($columns as $field) {
$this->CI->db->or_like($field, $word);
}
}
$this->CI->db->group_end();
} elseif($this->search_type == 1) {
// Search all colums for likeness for whole string
$this->CI->db->group_start();
foreach($columns as $field) {
$this->CI->db->or_like($field, $this->search);
}
$this->CI->db->group_end();
} else {
// Search for each individual column.
// First 2 indexes are reserved for above
if(isset($columns[$this->search_type-2])) {
$this->CI->db->group_start();
$this->CI->db->or_like($columns[$this->search_type-2], $this->search);
$this->CI->db->group_end();
}
}
}
}
Already tried:
"consultas.ID::varchar",
"'consultas.ID', '1011%'"
You need to avoid the escaping in those columns you are casting.
Normally the last parameter for QueryBuilder methods is for escaping, which can be true or false (default: true, DO escape)
$this->CI->db->or_like($field, $word, false); // <-- false, do not escape
See my answer here to a similar question:
type "e" does not exist , Redshift through Postgresql connector in php codeigniter
Try to cast this way
CAST(consultas.ID as TEXT);
Make 3rd parameter of or_like FALSE for consultas.ID.
if($field == 'consultas.ID')
{
$this->CI->db->or_like($field, $word, FALSE);
}
else{
$this->CI->db->or_like($field, $word);
}
Related
In the official documentation, the following columns are mentioned :
parent_id
lft
rgt
depth
I haven't found any explanation of their types in the documentation. Could someone help me and tell me what they are ?
I also want to know if they are all mandatory if I only want to reorder a list of items (I don't need any nesting).
Edit: As this question is quite popular, I've updated the documentation with the correct info.
The reordering id columns should be integer or INT(10) if you're not using a migration.
Unfortunately they're all mandatory, yes. But if you're on a very strict DB schema, you could eliminate all of them except the "lft" column by adding this method to your EntityCrudController (basically overwriting the one in Backpack\CRUD\app\Http\Controllers\CrudFeatures\Reorder):
public function saveReorder()
{
$this->crud->hasAccessOrFail('reorder');
$all_entries = \Request::input('tree');
if (count($all_entries)) {
$count = 0;
foreach ($all_entries as $key => $entry) {
if ($entry['item_id'] != '' && $entry['item_id'] != null) {
$item = $this->crud->model->find($entry['item_id']);
$item->lft = empty($entry['left']) ? null : $entry['left'];
$item->save();
$count++;
}
}
} else {
return false;
}
return 'success for '.$count.' items';
}
I've tried to implement a new module that catches the keys written in the default search form and displays other results than the default search result page. With these other results I will make an external query, which is put in a special block.
Any idea on how to do this?
I've tried to use a custom module making a "hook_alter_form " with no success.
In other words :
I have a function like this:
function my_function_name_form_alter(&$form,&$form_state,$form_id){
switch($form_id){
case 'search-block-form':
//Here i want to catch the text that i wrote in the search box
break;
}
}
Thank u!
You can alter the search query in order to show other results:
function mymodule_query_alter(QueryAlterableInterface $query){
$is_search = FALSE;
foreach ($query->getTables() as $table) {
if ($table['table'] == 'search_index') {
$is_search = TRUE;
}
}
if ($is_search) {
global $language;
$db_or = db_or();
$db_or->condition('n.type', 'event', '=');
$db_or->condition('n.type', 'real_sitio', '=');
$query->condition($db_or);
$query->condition('n.language' , $language->language, '=');
}
}
This is a bit performance killer so there's a patch for drupal at http://drupal.org/node/1435834 that adds a hook for making the alter directly in the search query:
So finally it would look like:
function mymodule_search_query_search_node_alter(&$query) {
$query->condition('n.type', 'article', '=');
}
I am working with Zend and I needed to check whether a row in the DB already exists (A simple solution to get rid of the duplicate key error I was getting). I tried several things but nothing seemed to work... (for example the Zend_Validate_Db_NoRecordExists method)
So I wrote the following the code and I was wondering if this is a valid way to do it, or if I should do things differently:
In the model:
$where = $condition = array(
'user_id = ' . $user_id,
'page_id = ' . $page_id
);
$check = $this->fetchRow($where);
if(count($check) > 0) {
return null;
}else{
// Here I create a new row, fill it with data, save and return it.
}
And then in my view:
if($this->result != null) { /* do stuff */ }else{ /* do other stuff */ }
It does work but it does seem to take more time (duh, because of the extra query) and I am a bit unsure whether I should stick with this..
Any recommendation is welcome :)
Assuming you have coded your function in your controller
$row = $this->fetchRow($where); //If no row is found then $row is null .
if(!$row)
{
$row = $dbTb->createNew($insert); //$insert an associative array where it keys map cols of table
$row->save();
$this->view->row_not_found = true;
}
return $row;
In your view you can do this
if($this->row_not_found)
{
}else {
}
I'm writing a tinyMce plugin which contains a section of code, replacing one element for another. I'm using the editor's dom instance to create the node I want to insert, and I'm using the same instance to do the replacement.
My code is as follows:
var nodeData =
{
"data-widgetId": data.widget.widgetKey(),
"data-instanceKey": "instance1",
src: "/content/images/icon48/cog.png",
class: "widgetPlaceholder",
title: data.widget.getInfo().name
};
var nodeToInsert = ed.dom.create("img", nodeData);
// Insert this content into the editor window
if (data.mode == 'add') {
tinymce.DOM.add(ed.getBody(), nodeToInsert);
}
else if (data.mode == 'edit' && data.selected != null) {
var instanceKey = $(data.selected).attr("data-instancekey");
var elementToReplace = tinymce.DOM.select("[data-instancekey=" + instanceKey + "]");
if (elementToReplace.length === 1) {
ed.dom.replace(elementToReplace[0], nodeToInsert);
}
else {
throw new "No element to replace with that instance key";
}
}
TinyMCE breaks during the replace, here:
replace : function(n, o, k) {
var t = this;
if (is(o, 'array'))
n = n.cloneNode(true);
return t.run(o, function(o) {
if (k) {
each(tinymce.grep(o.childNodes), function(c) {
n.appendChild(c);
});
}
return o.parentNode.replaceChild(n, o);
});
},
..with the error Cannot call method 'replaceChild' of null.
I've verified that the two argument's being passed into replace() are not null and that their parentNode fields are instantiated. I've also taken care to make sure that the elements are being created and replace using the same document instance (I understand I.E has an issue with this).
I've done all this development in Google Chrome, but I receive the same errors in Firefox 4 and IE8 also. Has anyone else come across this?
Thanks in advance
As it turns out, I was simply passing in the arguments in the wrong order. I should have been passing the node I wanted to insert first, and the node I wanted to replace second.
So how does one obtain the previous value of a custom field in a Jira IssueEventListener? I am writing a custom handler for the issueUpdated(IssueEvent) event and I would like to alter the handler's behavior if a certain custom field has changed. To detect the type of change I would like to compare the previous and current values.
(I'm am not asking about how to obtain its current value - I know how to get that from the related Issue)
I am developing against Jira 4.0.2 on Windows.
Is the best way to scan the change history for the last known value?
List changes = changeHistoryManager.getChangeHistoriesForUser(issue, user);
I'm assuming the original poster is writing a JIRA plugin with Java. I cannot be certain of how to accomplish this task in JIRA v4.0.2, but here is how I managed to do so with JIRA v5.0.2 (the solutions may very well be the same):
public void workflowEvent( IssueEvent event )
{
Long eventTypeId = event.getEventTypeId();
if( eventTypeId.equals( EventType.ISSUE_UPDATED_ID ) )
{
List<GenericValue> changeItemList = null;
try
{
changeItemList = event.getChangeLog().getRelated( "ChildChangeItem" );
}
catch( GenericEntityException e )
{
// Error or do what you need to do here.
e.printStackTrace();
}
if( changeItemList == null )
{
// Same deal here.
return;
}
Iterator<GenericValue> changeItemListIterator = changeItemList.iterator();
while( changeItemListIterator.hasNext() )
{
GenericValue changeItem = ( GenericValue )changeItemListIterator.next();
String fieldName = changeItem.get( "field" ).toString();
if( fieldName.equals( customFieldName ) ) // Name of custom field.
{
Object oldValue = changeItem.get( "oldvalue" );
Object newValue = changeItem.get( "newvalue" );
}
}
}
}
Some possible key values for changeItem are:
newvalue
oldstring
field
id
fieldtype
newstring
oldvalue
group
For many of the custom field types Object oldValue is probably just a String. But I don't think that's true for every case.
Try this example :
String codeProjetOldValue= "";
List<GenericValue> changeItemList = issueEvent.getChangeLog().getRelated("ChildChangeItem");
for (GenericValue genericValue : changeItemList) {
if(champCodeProjet.equals(genericValue.get("field"))){
codeProjetOldValue=genericValue.getString("oldstring");
break;
}
}
Note that : champCodeProjet is the name of customfield.