Undefined index: 0 when using hook_node_insert() Drupal 7 - drupal-7

I'm writing a custom module to insert data into database using hook_node_insert() when creating a new node. But if I left any field in the node empty without adding anything (non required field) and save the field I get the following error even though i have used isset function to check for empty fields.
Notice: Undefined index: 0 in add_customer_node_insert() in line no:5
Line no -5
$node_id = isset($node->field_id['und'])? $node->field_id['und']['0']['value']:NULL;

You only check if $node->field_id['und'] is set but not if the next part of the multi dimensinal array $node->field_id['und'][0] is set which you use for your assignment to $node_id. Change your statement to
isset($node->field_id['und']['0']['value'])

In your following code
$node_id = isset($node->field_id['und'])? $node->field_id['und']['0']['value'] : NULL;
$node->field_id['und'] is an array. You should check this by using empty() function for example like this
$node_id = !empty($node->field_id['und']) ? $node->field_id['und']['0']['value'] : NULL;
OR if you want to use isset() function
$node_id = isset($node->field_id['und']['0']['value']) ? $node->field_id['und']['0']['value'] : NULL;

Related

How to update internal table without using MODIFY?

I have created internal tables where I want to update age of employee in one internal table by calculating it from another table, I have done arithmetic calculations to get age but now how can I update it by any alternate way instead of MODIFY?
WRITE : / 'FirstName','LastName', ' Age'.
LOOP AT gt_items1 INTO gwa_items1.
READ TABLE gt_header INTO gwa_header WITH KEY empid = gwa_items1-empid.
gwa_items1-age = gv_date+0(4) - gwa_header-bdate+0(4).
MODIFY gt_items1 from gwa_items1 TRANSPORTING age WHERE empid = gwa_items1-empid.
WRITE : / gwa_items1-fname , gwa_items1-lname , gwa_items1-age .
ENDLOOP.
Use field symbols (instead of work areas) by LOOPing over internal tables:
WRITE : / 'FirstName','LastName', ' Age'.
LOOP AT gt_items1
ASSIGNING FIELD-SYMBOL(<ls_item1>).
READ TABLE gt_header
ASSIGNING FIELD-SYMBOL(<ls_header>)
WITH KEY empid = <ls_item1>-empid.
IF sy-subrc EQ 0.
<ls_item1>-age = gv_date+0(4) - <ls_header>-bdate+0(4).
WRITE : / <ls_item1>-fname , <ls_item1>-lname , <ls_item1>-age .
ENDIF.
ENDLOOP.
Field symbols have two advantages:
They modify the internal table directly, no separate MODIFY is
necessary.
They are somewhat faster, than work areas.
Besides József Szikszai's answer you could also use references:
write : / 'FirstName','LastName', ' Age'.
sort gt_header by empid. " <------------- Sort for binary search
loop at gt_items1 reference into data(r_item1).
read table gt_header reference into data(r_header)
with key empid = r_item1->empid binary search. " <------------- Faster read
check sy-subrc eq 0.
r_item1->age = gv_date+0(4) - r_header->bdate+0(4).
write : / r_item1->fname , r_item1->lname , r_item1->age .
endloop.
I added some enhacements to your code also.
For more info check this link.

Filter SQL datatable according to different parameters, without a WHERE clause

I'm building an application that needs to allow the user to filter a data table according to different filters. So, the user will have three different filter posibilites but he might use only one, or two or the three of them at the same tame.
So, let's say I have the following columns on the table:
ID (int) PK
Sede (int)
Programa (int)
Estado (int)
All of those columns will store numbers, integers. The "ID" column is the primary key, "Sede" stores 1 or 2, "Programa" is any number between 1 and 15, and "Estado" will store numbers between 1 and 13.
The user may filter the data stored in the table using any of those filters (Sede, Programa or Estado). But the might, as well, use two filters, or the three of them at the same time.
The idea is that this application works like the data filters on Excel. I created a simulated table on excel to show what I want to achieve:
This first image shows the whole table, without applying any filter.
Here, the user selected a filter for "Sede" and "Programa" but leaved the "Estado" filter empty. So the query returns the values that are equal to the filter, but leaves the "Estado" filter open, and brings all the records, filering only by "Sede" (1) and "Programa" (6).
In this image, the user only selected the "Estado" filter (5), so it brings all the records that match this criteria, it doesn't matter if "Sede" or "Programa" are empty.
If I use a SELECT clasuse with a WHERE on it, it will work, but only if the three filters have a value:
DECLARE #sede int
DECLARE #programa int
DECLARE #estado int
SET #sede = '1'
SET #programa = '5'
SET #estado = '12'
SELECT * FROM [dbo].[Inscripciones]
WHERE
([dbo].[Inscripciones].[Sede] = #sede)
AND
([dbo].[Inscripciones].[Programa] = #programa)
AND
([dbo].[Inscripciones].[Estado] = #estado)
I also tryed changing the "AND" for a "OR", but I can't get the desired result.
Any help will be highly appreciated!! Thanks!
common problem: try using coalesce on the variable and for the 2nd value use the field name you're comparing to. Be careful though; Ensure it's NULL and not empty string being passed!
What this does is take the first non-null value of the variable passed in or the value you're comparing to.. Thus if the value passed in is null the comparison will always return true.
WHERE
[dbo].[Inscripciones].[Sede] = coalesce(#sede, [dbo].[Inscripciones].[Sede])
AND
[dbo].[Inscripciones].[Programa] = coalesce(#programa, [dbo].[Inscripciones].[Programa])
AND
[dbo].[Inscripciones].[Estado] = coalesce(#estado, [dbo].[Inscripciones].[Estado])
If sede is null and programa and estado are populated the compare would look like...
?=? (or 1=1)
?=programa variable passed in
?=Estado variable passed in
Boa Sorte!
Thank you all for your anwers. After reading the article posted in the comments by #SeanLange I was finally able to achieve what was needed. Using a CASE clause in the WHERE statement solves the deal. Here's the code:
SELECT
*
FROM [dbo].[Inscripciones]
WHERE
([dbo].[Inscripciones].[Sede] = (CASE WHEN #sede = '' THEN [dbo].[Inscripciones].[Sede] ELSE #sede END))
AND
([dbo].[Inscripciones].[Programa] = (CASE WHEN #programa = '' THEN [dbo].[Inscripciones].[Programa] ELSE #programa END))
AND
([dbo].[Inscripciones].[Estado] = (CASE WHEN #estado = '' THEN [dbo].[Inscripciones].[Estado] ELSE #estado END))
AND
([dbo].[Inscripciones].[TipoIngreso] = (CASE WHEN #tipoingreso = '' THEN [dbo].[Inscripciones].[TipoIngreso] ELSE #tipoingreso END))
Thanks again!!

Nested loop conditional

Supposed I have this table:
TDID TDLINE
F04 04-AA
F04 04-BB <-- call a function
F05 05-AA
F05 05-BB <-- call a function
F06 06-AA <-- call a function
I would like to call a function while the TDID field is not the same as the previous one. I have the code below, it works but somehow it's not perfectly works (it missed the last row):
LOOP AT lines ASSIGNING <fs1>.
IF <fs2> IS INITIAL.
<fs2> = <fs1>.
ELSE.
li_line-tdline = <fs2>-tdline.
APPEND li_line.
IF <fs1>-tdid NE <fs2>-tdid.
li_thead-tdid = <fs2>-tdid.
CALL FUNCTION 'SAVE_TEXT'
EXPORTING
header = li_thead
savemode_direct = 'X'
TABLES
lines = li_line
CLEAR: li_thead,
li_line.
FREE: li_thead,
li_line.
ENDIF.
ENDIF.
ENDLOOP.
ANSWER
Thank you to vwegert for the answer:
LOOP AT lines ASSIGNING <fs1>.
AT NEW tdid.
REFRESH li_thead.
REFRESH li_line.
li_thead-tdid = <fs1>-tdid.
APPEND li_thead.
ENDAT.
li_line-tdline = <fs1>-tdline.
APPEND li_line.
AT END OF tdid.
CALL FUNCTION 'SAVE_TEXT'
EXPORTING
header = li_thead
savemode_direct = 'X'
TABLES
lines = li_line
ENDAT.
ENDLOOP.
Assuming that the table is sorted by TDID and no field left of TDID changes more frequently than TDID:
LOOP AT lines ASSIGNING <fs1>.
AT NEW tdid.
REFRESH some_other_tab.
ENDAT.
APPEND <fs1> TO some_other_tab.
AT END OF tdid.
CALL FUNCTION ...
ENDAT.
ENDLOOP.
The unpredictability as mentioned by vwegert comes because the characters fields next to the field on which Control statement is applied are converted to asterisks(*). If you want to use these values in the control statement make sure you copy the values in a temporary table and loop on it instead of the original internal table and use the values using READ on the original internal table. Also keep in mind that control statement considers all columns to the left of the column being used in the statement for it's condition.

bad use of variables in db.query

I'm trying to develop a blog using webpy.
def getThread(self,num):
myvar = dict(numero=num)
print myvar
que = self.datab.select('contenidos',vars=myvar,what='contentTitle,content,update',where="category LIKE %%s%" %numero)
return que
I've used some of the tips you answer in this web but I only get a
<type 'exceptions.NameError'> at /
global name 'numero' is not defined
Python C:\xampp\htdocs\webpy\functions.py in getThread, line 42
Web GET http://:8080/
...
I'm trying to make a selection of some categorized posts. There is a table with category name and id. There is a column in the content table which takes a string which will be formatted '1,2,3,5'.
Then the way I think I can select the correct entries with the LIKE statement and some %something% magic. But I have this problem.
I call the code from the .py file which builds the web, the import statement works properly
getThread is defined inside this class:
class categoria(object):
def __init__(self,datab,nombre):
self.nombre = nombre
self.datab = datab
self.n = str(self.getCat()) #making the integer to be a string
self.thread = self.getThread(self.n)
return self.thread
def getCat(self):
'''
returns the id of the categorie (integer)
'''
return self.datab.select('categorias',what='catId', where='catName = %r' %(self.nombre), limit=1)
Please check the correct syntax for db.select (http://webpy.org/cookbook/select), you should not format query with "%" because it makes code vulnerable to sql injections. Instead, put vars in dict and refer to them with $ in your query.
myvars = dict(category=1)
db.select('contenidos', what='contentTitle,content,`update`', where="category LIKE '%'+$category+'%'", vars=myvars)
Will produce this query:
SELECT contentTitle,content,`update` FROM contenidos WHERE category LIKE '%'+1+'%'
Note that I backquoted update because it is reserved word in SQL.

With cakePHP, can I increment the value of a column without reading it's value first?

I'd like to increment the value of a column in cakePHP.
Is there a way to have cakePHP write this?
UPDATE `gigs` SET `visits` = visits+1 WHERE `gigs`.`id` = 1
I tried this:
function addVisit($id){
$this->id = $id;
$this->saveField('visits', 'visits+1');
}
but cakePHP adds quotes around visits+1.
UPDATE `gigs` SET `visits` = 'visits+1' WHERE `gigs`.`id` = 1
I tried double quotes, results the same.
$this->updateAll(array(), array('Model.field + 1'))
or
$this->updateAll(null, array('Model.field + 1'))
one of them should work, saveField does not allow sql fragments, updateAll does

Resources