Radicore Forum
Fast Uncompromising Discussions. FUDforum will get your users talking.

Home » RADICORE development » Transaction Patterns » Output 3 - _cm_output_multi()
Output 3 - _cm_output_multi() [message #7618] Tue, 03 August 2021 16:14 Go to next message
htManager is currently offline  htManager
Messages: 342
Registered: May 2014
Senior Member
Hi Tony,

after installing the new version 2.19.0 I have some problems with two output3 patterns and the _cm_output_multi() function.

As you described in "dialog-types.html#output3" and in "functions-and-variables.html#notes._cm_output_multi" the _cm_output_multi($name, $inarray, $iteration) function holds in the $inarray ($fieldarray) the data of the parent record. I have the correct parent values in the _cm_changeConfig() and the _cm_initialise() method. But in the _cm_output_multi() method I have the value of the first record of the child table.

Do I have to change the values somewhere else?
Re: Output 3 - _cm_output_multi() [message #7619 is a reply to message #7618] Wed, 04 August 2021 05:21 Go to previous messageGo to next message
htManager is currently offline  htManager
Messages: 342
Registered: May 2014
Senior Member
_cm_changeConfig() is called twice. The first time the $fieldarray() shows the correct values. The second time the $fieldarray() is empty.

In std.table.class.inc...->initialise() the $where string is empty, only the $where2 string has the correct values. Is this correct behaviour or do I have an error in my code?
Re: Output 3 - _cm_output_multi() [message #7620 is a reply to message #7618] Wed, 04 August 2021 05:22 Go to previous messageGo to next message
AJM is currently offline  AJM
Messages: 2274
Registered: April 2006
Location: Surrey, UK
Senior Member
I have just tested all the OUTPUT3 tasks that I have, and they are all working as expected. Logon to the demo system at https://www.radicore.org/demo/menu/logon.php then navigate to PROTO->Example System->List Person, select a person then press the "Invoice(PDF)" button and you will see that the selected PERSON record appears in $fieldarray. I don't know what you mean when you say that you are getting the first row of the child table as there is no child table defined for that pattern. It is only AFTER the _cm_output_multi() method is called that any child table is identified and accessed.

Re: Output 3 - _cm_output_multi() [message #7621 is a reply to message #7620] Wed, 04 August 2021 06:19 Go to previous messageGo to next message
htManager is currently offline  htManager
Messages: 342
Registered: May 2014
Senior Member
Thank you for the information. Then it is obviously because of my "construction". I call the output3 pattern from a list2 screen because I want to have the data of the parent record in the report title and the child occurrences in different multi sections. In V 2.18.0 this construction worked fine but in V 2.19.0 not anymore. So I will search for the error in my code.
Re: Output 3 - _cm_output_multi() [message #7622 is a reply to message #7621] Thu, 05 August 2021 04:57 Go to previous messageGo to next message
AJM is currently offline  AJM
Messages: 2274
Registered: April 2006
Location: Surrey, UK
Senior Member
If you are calling an OUTPUT3 pattern from a LIST2 screen then in the _cm_initialise() method of the OUTPUT3 task the $where argument should contain the primary key of the outer entity of the LIST2 screen while the $selection argument should contain the primary keys of any selected rows from the inner entity. Check that you are using the correct primary key.

Re: Output 3 - _cm_output_multi() [message #7623 is a reply to message #7622] Thu, 05 August 2021 05:03 Go to previous messageGo to next message
AJM is currently offline  AJM
Messages: 2274
Registered: April 2006
Location: Surrey, UK
Senior Member
If it is your intention to have a separate page for each selected row from the inner entity then the _cm_output_multi() method will be called for each row. If you want some data from the parent record shown in the report title then your SELECT query should contain a JOIN to that table so that the data is available in each inner row.

Re: Output 3 - _cm_output_multi() [message #7624 is a reply to message #7622] Thu, 05 August 2021 11:50 Go to previous messageGo to next message
htManager is currently offline  htManager
Messages: 342
Registered: May 2014
Senior Member
At the moment the $where argument in the _cm_initialise() method contains the right values but with the primary key fieldnames of the inner entity not the outer entity. The &$selection argument contains the same values.
In the _cm_changeConfig() method the same. $where and $fieldarray contain the same values of the inner entity as in the _cm_initialise().

Where is my mistake? I checked the relationship and exported the *.dict.inc files once again.

I do not want a separate page for each selected row. I want to store qualified records in the different multi sections. My SELECT query contains the joins. This works fine.
Re: Output 3 - _cm_output_multi() [message #7625 is a reply to message #7624] Thu, 05 August 2021 13:46 Go to previous messageGo to next message
AJM is currently offline  AJM
Messages: 2274
Registered: April 2006
Location: Surrey, UK
Senior Member
If you do not want a separate page for each selected row then you must ignore the contents of $selection in the _cm_initialise() method. The $where string should contain the primary key of the outer entity in the LIST2 screen. This string should also have been used as the foreign key for the inner entity of the LIST2 screen. The $selection string should only be populated if you marked any of the inner rows in the LIST2 screen as selected.

The two strings should NOT be the same. If they are you need to debug the childform() function inside file include.session.inc where it calls $dbobject->getWhere().



Re: Output 3 - _cm_output_multi() [message #7626 is a reply to message #7625] Fri, 06 August 2021 05:06 Go to previous messageGo to next message
htManager is currently offline  htManager
Messages: 342
Registered: May 2014
Senior Member
It is exactly as you described. $selection is empty if I do not mark records in the child table. In the file include.session.inc the call $dbobject->getWhere() shows the right outer and inner table name and the correct $where string.

FYI: The _cm_output_multi() method works fine until the last multi-zone. But the report shows a page for EVERY row of the outer entity and not only the page of the selected row!

Where can I search next?
Re: Output 3 - _cm_output_multi() [message #7627 is a reply to message #7626] Sat, 07 August 2021 05:16 Go to previous messageGo to next message
AJM is currently offline  AJM
Messages: 2274
Registered: April 2006
Location: Surrey, UK
Senior Member
The $where argument in the _cm_initialise() method should contain the primary key of a single row in the outer entity of the parent LIST2 screen. The child OUTPUT3 task should then read that single row, then call the _cm_output_multi() method so that it can add additional rows to the output. The $fieldarray argument in the _cm_output_multi() method should contain the data for the single selected row. It should be called multiple times with different zone names in the $name argument. Once all the zones have been processed for the current row it should then look for the next row, but there should be no next rows.

What the the names of the two tables? What are their primary keys? If everything works fine until the last multi zone then what code do you have for that zone? What record is shown in the $fieldarray argument?


Re: Output 3 - _cm_output_multi() [message #7628 is a reply to message #7627] Sat, 07 August 2021 05:45 Go to previous messageGo to next message
htManager is currently offline  htManager
Messages: 342
Registered: May 2014
Senior Member
The report works fine again when I replace the primary key fields in the $where string in the _cm_initialise() method with the primary key fields of the outer entity.

The $where argument in the _cm_initialise() method contains the primary key fields (with the correct values) of the inner entity. The report is displayed correctly but has 86 pages. Exactly the number of records in the outer entity.
Re: Output 3 - _cm_output_multi() [message #7629 is a reply to message #7628] Sun, 08 August 2021 06:00 Go to previous messageGo to next message
AJM is currently offline  AJM
Messages: 2274
Registered: April 2006
Location: Surrey, UK
Senior Member
I have just run a test on my development system where I go to a LIST2 screen and press a navigation button to activate a child task, then in the child task I look to see what values are passed in $where and $selection. As expected the $where string contains a single primary key for the outer entity in the LIST2 screen while $selection contains a list of zero or more primary keys for whatever rows were marked as selected in the inner entity of the LIST2 screen.

If you are saying that the $where string identifies multiple rows instead of a single row then there must be something in your code which is overriding the framework's default behaviour.

What is the primary key of your outer entity? What value is being extracted by the call to the getWhere() function inside the childForm() function within script include.session.inc? This happens within the parent screen before the child screen is called, so this would be where the wrong value is being obtained.


Re: Output 3 - _cm_output_multi() [message #7630 is a reply to message #7629] Sun, 08 August 2021 07:31 Go to previous messageGo to next message
htManager is currently offline  htManager
Messages: 342
Registered: May 2014
Senior Member
The list2 pattern shows the correct primary key values in the getWhere() function inside childForm() in include.session.inc.

Only if I call the output3 pattern (from this list2 pattern) the primary key values are not correct. The getWhere() function in childForm() shows the primary key values of the child entity not these of the outer entity as in the list2 pattern. In the _cm_changeConfig() and _cm_initialise() method I can't see that I do override the $where string.

I have two more of such constructions and there is the same behaviour. If I really do override the code I unfortunately don't know where.
Re: Output 3 - _cm_output_multi() [message #7631 is a reply to message #7630] Mon, 09 August 2021 04:07 Go to previous messageGo to next message
htManager is currently offline  htManager
Messages: 342
Registered: May 2014
Senior Member
Can it be that I use the output3 pattern in an unimagined way for the framework? Because I call the output3 pattern from the list2 form and I want to have a certain number of records in the respective multi zones?
Normally the output3 pattern should show the details of the child entity if I understand right. But I need a report where several records can be shown in a multi zone. And in the report title I need the information of the parent table. If I use the output3 pattern in a not wanted way then I have now found a way to get it work with replacing the $where string in _cm_initialise() and I am happy that it works. I was just wondering why this worked in V 2.18.0 before and not anymore in V 2.19.0.
Re: Output 3 - _cm_output_multi() [message #7632 is a reply to message #7631] Tue, 10 August 2021 04:33 Go to previous messageGo to next message
AJM is currently offline  AJM
Messages: 2274
Registered: April 2006
Location: Surrey, UK
Senior Member
You are confusing me. You start with a LIST2 screen which has two tables, OUTER and INNER. It contains one occurrence of the OUTER table and multiple occurrences of the INNER table. When you press the navigation button which activates the OUTPUT3 task it passes down two variables - $where and $selection. $where will contain the primary key (or its foreign key equivalent) of OUTER while selection will contain the primary keys of any of the INNER rows which were marked as selected. In your OUTPUT3 task what is the starting table? What additional tables are you accessing in the _cm_output_multi() method?

Re: Output 3 - _cm_output_multi() [message #7633 is a reply to message #7632] Tue, 10 August 2021 06:34 Go to previous messageGo to next message
htManager is currently offline  htManager
Messages: 342
Registered: May 2014
Senior Member
Sorry for confusing you. Probably this is because of my knowledge and the language. Sorry.

I try to explain it better:

The LIST2 screen has the outer entity orga_spiele which holds all the games/matches. The inner entity is orga_spiele_anwesenheit which holds the team members. In the team members table are fields where I can choose if the member participates in this match or not. Additionally there is a field where I can choose the position of the player in the game.

The OUTPUT3 task has the name orga_spiele_anwesenheit_einzel_position and is defined as subclass of orga_spiele and extends orga_spiele (as defined in the orga_spiele_anwesenheit_einzel_position.class.inc).

In the orga_spiele_anwesenheit_einzel_position(output3).php my $table_id is 'orga_spiele_anwesenheit_einzel_position' and $sql_from is 'orga_spiele' with two LEFT JOINS on related tables for getting information for the title.

If I now press the OUTPUT3 task in the LIST2 screen $where in _cm_initialise() in orga_spiele_anwesenheit_einzel_position.class.inc passes down the primary key fields and the primary key values of the inner table not of the outer table. The $selection string passes (correctly) down all selected occurences of the inner table (orga_spiele_anwesenheit).

I have a primary key consisting of 6 fields and the fields are normally different in each table as you advised in one of your articles to make it easier to identify the table fields. I use the following code to change the $where string in _cm_initialise() of orga_spiele_anwesenheit_einzel_position.class.inc:

$where = str_replace('spiele_anwesenheit_verbaende_art_id=', 'verbaende_art_id=', $where);
$where = ..... (for all 6 fields)

This works fine.

In the _cm_output_multi() method I am accessing the inner table (orga_spiele_anwesenheit) again to get the available players for the different positions. For better understanding I attached the output3 pdf file. Maybe you can better see what is wrong in my logic. As you can see each multi zone contains the available team members for this position.
  • Attachment: Output3.pdf
    (Size: 330.83KB, Downloaded 25 times)
Re: Output 3 - _cm_output_multi() [message #7634 is a reply to message #7633] Wed, 11 August 2021 05:04 Go to previous messageGo to next message
AJM is currently offline  AJM
Messages: 2274
Registered: April 2006
Location: Surrey, UK
Senior Member
You say that when the OUTPUT3 task is activated and the _cm_initialise() method is called that both the $where and $selection arguments contain the primary key fields and values from the inner entity of the LIST2 screen, which is orga_spiele_anwesenheit. This is not correct. The $where argument should contain the $where string that went into the inner entity before it performed its own $inner->getData($where) and the $selection argument will contain the primary keys of those inner rows which were selected after the screen was displayed.

If the field names of the outer table's primary key are different from the field names of the inner entity's foreign key then it would have been necessary to convert them before they could be used in $inner->getData(). It is these foreign key values which would have been extracted from the LIST2 screen and passed as the $where argument to the child OUTPUT3 task.


Re: Output 3 - _cm_output_multi() [message #7635 is a reply to message #7634] Wed, 11 August 2021 16:09 Go to previous messageGo to next message
htManager is currently offline  htManager
Messages: 342
Registered: May 2014
Senior Member
If I understand you right then replacing the primary key values as I did is the right way to get the result/report I want.

Only if the primary key field names of both the outer and the inner entity are the same then there would be no problem. Is this correct?

All I have to do in the future is to take care of these constructions and to replace the primary key field names in _cm_initialise(). No problem. Thank you.
Re: Output 3 - _cm_output_multi() [message #7637 is a reply to message #7635] Thu, 12 August 2021 05:04 Go to previous messageGo to next message
AJM is currently offline  AJM
Messages: 2274
Registered: April 2006
Location: Surrey, UK
Senior Member
When a navigation button is pressed the $where and $selection strings which are passed to the next task are obtained from the inner table of the current task. The $where string is what was used as the $where argument in the _cm_pre_getData() method while the $selection string is constructed from all those rows from the inner table which were marked as selected.

Note that if the names of the primary key fields in the outer table of the LIST2 screen are different from the corresponding foreign key names of the inner table then these will have to be adjusted if you wish to reconstruct the primary key of the outer table. This adjustment can be done in either the _cm_initialise() method of the next task or at the start of the _cm_pre_getData() method.

My usual practice is the use the same field names in both the primary and foreign keys, with the only exception being when there is more than one relationship between the two tables, or when a table is related to itself.


Re: Output 3 - _cm_output_multi() [message #7638 is a reply to message #7637] Sat, 14 August 2021 04:26 Go to previous messageGo to next message
htManager is currently offline  htManager
Messages: 342
Registered: May 2014
Senior Member
Thank you for the information. Now I know that I misunderstood what you wrote in one of your articles about primary keys. I will change my 'naming' in the future.

Important for me is that I still have the opportunity to change this in _cm_initialise() or _cm_pre_getData() method.
Re: Output 3 - _cm_output_multi() [message #7639 is a reply to message #7638] Sat, 14 August 2021 04:56 Go to previous messageGo to next message
AJM is currently offline  AJM
Messages: 2274
Registered: April 2006
Location: Surrey, UK
Senior Member
You should also be aware that in patterns such as LIST2 and LIST3 where there are multiple tables in a parent-child relationship that the script will use the getForeignKeyValues($parent, $child) function to extract the primary key from the parent table so that it can be passed down to the child. If the relationship in the Data Dictionary identifies that the field names in the foreign key of the child are different from the field names of the primary key in the parent then this function will return the foreign key names instead of the primary key names, which means that you should not have to make any manual adjustments in the child class.

Re: Output 3 - _cm_output_multi() [message #7646 is a reply to message #7639] Tue, 17 August 2021 06:54 Go to previous messageGo to next message
htManager is currently offline  htManager
Messages: 342
Registered: May 2014
Senior Member
Thank you for the info. I will try to keep this in mind for the future.
Re: Output 3 - _cm_output_multi() [message #7647 is a reply to message #7639] Mon, 30 August 2021 09:52 Go to previous messageGo to next message
htManager is currently offline  htManager
Messages: 342
Registered: May 2014
Senior Member
FYI: I had some more problems with LIST2 and ADD5 patterns with V 2.19.0. As soon as I changed the names of the primary key fields of the child table in the names of the primary key fields of the parent table everything worked fine again. I think I will do this one after the other with all my child tables to avoid these problems in the future.
Re: Output 3 - _cm_output_multi() [message #7648 is a reply to message #7647] Tue, 31 August 2021 04:52 Go to previous messageGo to next message
AJM is currently offline  AJM
Messages: 2274
Registered: April 2006
Location: Surrey, UK
Senior Member
It should not be necessary to change the names of the primary key fields in the child table, only the foreign key fields, unless the two are the same.

If you have described the relationship between the parent and child tables in the Data Dictionary then this should have identified the names of the foreign key fields which are related to the primary key fields in the parent table. In this case the LIST2/3/4 patterns, which use the getForeignKeyValues() function, should automatically convert the field names for you.


Re: Output 3 - _cm_output_multi() [message #7650 is a reply to message #7648] Thu, 02 September 2021 11:34 Go to previous messageGo to next message
htManager is currently offline  htManager
Messages: 342
Registered: May 2014
Senior Member
You are right. I read your 'RADICRE programming guidelines' once again and there you wrote in No 7 that 'Wherever possible fields with the same content should have the same name'. That was one of my mistakes. I gave the primary key fields in the child table a different name as them in the parent table because I misunderstood/had a wrong idea of your recommendation. The same with the foreign keys. After reading your 'php-mysql/database-design.html#foreign.keys' article I now think that I understand it right or at least better.

The framework works fine. What I was obviously looking for some times was a possibility (probably) outside the framework. In my ObjectPAL programming environment I had no transaction patterns and that's why I could write code just as I wanted; with huge effort every time!

How would you deal with the following situation:

Parent table: PKey: A1_id, A2_id, A3_id
Child table: PKey: A1_id, A2_id, A3_id, U_id

U_id is the foreign key of the user table. I have a list2 pattern and now want to open an output3 report for the user U_id selected in the child table and write some more information with the _cm_output_multi() method. Is this possible? Or do I have to go to the user screen and call it from there?

I already tried several things like changing the table in the controller script and exploding the $where string to get the U_id but with no success. Calling from this place would be convenient.
Re: Output 3 - _cm_output_multi() [message #7651 is a reply to message #7650] Fri, 03 September 2021 04:48 Go to previous messageGo to next message
AJM is currently offline  AJM
Messages: 2274
Registered: April 2006
Location: Surrey, UK
Senior Member
If the parent table has a compound primary key then any child table must have a compound foreign key where every column within the foreign key is matched to the corresponding column in the primary key.

In your above example the columns A1_id, A2_id, A3_id in the child table would be the foreign key with U_id being part of the primary key. In this case you should not have to take any action as the components of the foreign key have exactly the same names as the components of the primary key, so no swapping of column names is necessary.


Re: Output 3 - _cm_output_multi() [message #7665 is a reply to message #7651] Sun, 24 October 2021 05:40 Go to previous messageGo to next message
htManager is currently offline  htManager
Messages: 342
Registered: May 2014
Senior Member
I changed my column names and everything works fine now.

Now I want to have values of the parent table and of the child table in the report title. But I don't know how to do this best.

In the _cm_initialise() method $selection contains all the key values. In the _cm_pre_getData() method $where contains only the key values of the child table.

Do I have to store the values of the parent talbe in $GLOBALS in _cm_initialise() or can I do this in a better way?
Re: Output 3 - _cm_output_multi() [message #7666 is a reply to message #7665] Mon, 25 October 2021 04:47 Go to previous messageGo to next message
AJM is currently offline  AJM
Messages: 2274
Registered: April 2006
Location: Surrey, UK
Senior Member
You could always do what I do - when you generate the SELECT query for the child table you include a JOIN to the parent table and add the columns that you want from the parent to the SELECT list. These columns will then be available in the $fieldarray for the child table.

Re: Output 3 - _cm_output_multi() [message #7667 is a reply to message #7666] Mon, 25 October 2021 06:36 Go to previous messageGo to next message
htManager is currently offline  htManager
Messages: 342
Registered: May 2014
Senior Member
Thank you for the answer. I tried this but I failed probably because my query wasn't correct. I think I will try to get the query right...

At the moment I store the needed values in the _cm_initialise() method in $GLOBALS. So I can use them in the report too. But I think your way is better. Thank you.
Re: Output 3 - _cm_output_multi() [message #7668 is a reply to message #7667] Tue, 26 October 2021 04:37 Go to previous messageGo to next message
AJM is currently offline  AJM
Messages: 2274
Registered: April 2006
Location: Surrey, UK
Senior Member
You might also want to take a look at Using Parent Relations to construct sql JOINs which will allow the framework to construct the JOIN for you.

Re: Output 3 - _cm_output_multi() [message #7669 is a reply to message #7668] Tue, 26 October 2021 06:29 Go to previous message
htManager is currently offline  htManager
Messages: 342
Registered: May 2014
Senior Member
If I read how you constructed the JOIN's, everything seems to be easy, but if I try to construct my own JOIN's, everything is very hard work for me because I haven't the knowledge and the experience as you have. Every time I have such a challenge I search for solutions in your articles. And mostly I improve a little bit but in very small steps... Wink

This time I succeeded by storing the needed values in $GLOBALS in the _cm_initialise() method for the report title and querying the body occurences in the _cm_output_multi() method with some of these stored values too. The construction of the JOIN's of all tables was too complex for me at the moment. Maybe with the next challenge... Wink

[Updated on: Tue, 26 October 2021 06:29]

Report message to a moderator

Previous Topic: POPUP3 not working
Next Topic: Introduction to Transaction Patterns within Radicore
Goto Forum:
  


Current Time: Tue Oct 26 21:02:36 EDT 2021

Total time taken to generate the page: 0.01052 seconds