Assigning custom variables to a document template
From Achievo/ATK Wiki
|
ATK Howto: Assigning custom variables to a document template
|
As previously discussed the standard implementation of atkDocumentAttribute works well at assigning the variables within the node that the document attribute has been created in, however it cannot reference related data in another node which is linked to the current node by a m2o or o2m relation.
The standard behaviour of document assignment performs three tasks:
- Load the selected record within the current node from the database.
- Assign the record variables to the document using the docuement writer functions.
- Assign generic variables to the document using the docuement writer functions.
In order to populate the document with data from a related node we need to perform steps 1 and 2 for the related node. Fortunately the code within the action_document function of the document handler allows for an overide to the above function within the node class file (it is one of the Hooks).
I have included an example of a node override to this function below:
public function assignDocumentVars($handler, $documentWriter, $selector) { // Load the selected record from the database $record = $this->select($selector)->getFirstRow(); $documentWriter->assignDocumentSingleRecord($this, $record); // Assign the referenced reportdetail - ManyToOne attribute $report = atkGetNode("developmentprograms.dpreports"); $reportrecord = $report->select("ccm_dpreports.dp_report_id='".$record["dp_report_id"]["dp_report_id"]."'")->getFirstRow(); $documentWriter->assignDocumentSingleRecord($report, $reportrecord, "report_"); // Assign the referenced childdetail - ManyToOne attribute $child = atkGetNode("nursery.children"); $childrecord = $child->select("ccm_children.child_id='".$record["child_id"]["child_id"]."'")->getFirstRow(); $documentWriter->assignDocumentSingleRecord($child, $childrecord, "child_"); // Assign the referenced keyworker detail - ManyToOne attribute $kw = atkGetNode("system.users"); $kwrecord = $kw->select("ccm_authuser.userid='".$record["assigned_to"]["userid"]."'")->getFirstRow(); $documentWriter->assignDocumentSingleRecord($kw, $kwrecord, "kw_"); // Assign the referenced Sum Rep text detail - OneToMany attribute $sumrep = atkGetNode("developmentprograms.children2dpsum"); $sumreprecords = $sumrep->select("ccm_childrentodpsum.children_dp_report_id='".$record["children_dp_report_id"]."'")->getAllRows(); foreach ($sumreprecords as $sumreprecord) { $file_tag = $sumreprecord["dp_area_id"]["file_tag"]."_"; $documentWriter->assignDocumentSingleRecord($sumrep, $sumreprecord, $file_tag); } // Also assign the generic (date) vars tot the documentWriter $documentWriter->assignDocumentGenericVars(); }
I will repeat the above in blocks and relevant comments on each section below:
public function assignDocumentVars($handler, $documentWriter, $selector) {
Notice the function now has three parameters the first paramater is $node which references the node in which the function is being called.
// Load the selected record from the database $record = $this->select($selector)->getFirstRow(); $documentWriter->assignDocumentSingleRecord($this, $record);
This is the same as the original function and assigns the variables for the current node as described in atkDocumentAttribute
// Assign the referenced reportdetail - ManyToOne attribute $report = &atkGetNode("developmentprograms.dpreports"); $reportrecord = $report->select("ccm_dpreports.dp_report_id='".$record["dp_report_id"]["dp_report_id"]."'")->getFirstRow(); $documentWriter->assignDocumentSingleRecord($report, $reportrecord, "report_");
The above section of code is for a m2o relation attribute and uses the relation id held in $record to pull the related nodes data. It then uses assigns the document vars, notice the optional third paramater in assignDocumentSingleRecord this is a prefix for the template variables. Therefore in the above example you would write [report_attribute_name] in the template document where you wish to place the related attribute.
// Assign the referenced childdetail - ManyToOne attribute $child = atkGetNode("nursery.children"); $childrecord = $child->select("ccm_children.child_id='".$record["child_id"]["child_id"]."'")->getFirstRow(); $documentWriter->assignDocumentSingleRecord($child, $childrecord, "child_"); // Assign the referenced keyworker detail - ManyToOne attribute $kw = &atkGetNode("system.users"); $kwrecord = $kw->select("ccm_authuser.userid='".$record["assigned_to"]["userid"]."'")->getFirstRow(); $documentWriter->assignDocumentSingleRecord($kw, $kwrecord, "kw_");
The above two code sections are a repeat of the functionality for two other m2o relations.
// Assign the referenced Sum Rep text detail - OneToMany attribute $sumrep = atkGetNode("developmentprograms.children2dpsum"); $sumreprecords = $sumrep->select("ccm_childrentodpsum.children_dp_report_id='".$record["children_dp_report_id"]."'")->getAllRows(); foreach ($sumreprecords as $sumreprecord) { $file_tag = $sumreprecord["dp_area_id"]["file_tag"]."_"; $documentWriter->assignDocumentSingleRecord($sumrep, $sumreprecord, $file_tag); }
This is a more lenghty piece of code used for a o2m relationship. Because the select method will pull back more than one record we have to iterate through the records to insert the variables. Also for this example within the related node their is a field I wish to use as the prefix (i.e file_tag). This is usefull to direct the exact placement of each of the "many" records. If "m" is defined/limited in your relation you may prefer to iterate through with a numeric prefix.
// Also assign the generic (date) vars tot the documentWriter $documentWriter->assignDocumentGenericVars(); }
This is the same generic assignment in the original function.
Acknowledgement
All of the above was a result of discussions and help in the following thread ManyToOne Relations and OneToMany Relations with atkDocument in the atk Forums.
I would like to specifically thank Yury whose assistance through pm's helped me clinch the final part of this solution.