-1

I have the following objects that I would like make them cooperate between themselves. The user could create each object separated from the others and at different time. The final usage is that the user links all the objects together to compose the final one.

Invoice.php

<?php
class Invoice
{
  private $header;
  private $xml;

  public function __construct()
  {
    // code that initializes $this XML tree (root)
  }

  public function setInvoiceHeader($invoiceHeader)
  {
       /* code that should merge $this->xml with the one from the $invoiceHeader param
       but I can't access it here because of private visibility and I would like to avoid
       the public visibility */
  }

  public function writeXMLDocument()
  {
    // code that returns the XML document
  }

}
?>

InvoiceHeader.php

<?php
class InvoiceHeader
{
  private $xml;

  public function __construct()
  {
    // code that initializes $this XML tree
  }

  public function setTransmissionData($transmissionData)
  {
    /* code that should merge $this->xml with the one from the $transmissionData param
       but I can't access it here because of private visibility and I would like to avoid
       the public visibility */
  }

}
?>

TransmissionData.php

<?php
class TransmissionData
{
  private $xml;
  private $transmissionIdNode;

  public function __construct()
  {
    // code that initializes $this XML tree
  }

  public function setTransmissionId($idCountry, $idCode)
  {
    // code that creates the XML node with the params
  }

}
?>

I can't find a way to pass the private $xml between the objects.

I would like to avoid using the public visibility because I don't want that the user can access the low-level implementation.

I would like to avoid using the inheritance and protected visibility because I think that these objects are not so much related (InvoiceHeader is not an Invoice and TransmissionData is not an InvoiceHeader); furthermore the only thing that they would have inherit is a field.. it is like a waste to my ears.

I would like to treat them more like some components, assuming it is possible.

yivi
  • 42,438
  • 18
  • 116
  • 138
Etraz
  • 25
  • 6
  • 1
    what about implementing a simple getter `getXml()`? – Jeff Oct 25 '18 at 09:11
  • Either you change the property visibility, or you create an accessor method as Jeff mentioned. – yivi Oct 25 '18 at 09:32
  • or what about having a property `$invoice` and an `$invoiceHeader` in `TransmissionData`. You can then use their methods in TransmissionData – Jeff Oct 25 '18 at 10:04
  • @Jeff If I use a 'public' getter, then what is the point of the encapsulation and hiding the implementation? The user could simple use 'getXML()' on each object and then handle the entire XML tree document within its own program, without the need of parent components which safeguard the implementation. However, I don't think there are other ways but using the inheritance in order to avoid the 'public' visibility at this point. – Etraz Oct 29 '18 at 08:44
  • @Jeff The problem is that the user could create a TransmissionData object before it creates the parent objects (Invoice and InvoiceHeader), so those properties will not be linked together. I would like that the user will be obliged to create the parent objects and THEN fill them with child objects. – Etraz Oct 29 '18 at 08:48

1 Answers1

-1

You could have InvoiceHeader hold a TransmissionData object (set by your current set method), and have TransmissionData object expose a method to get the generated XML so that you don't need to expose the raw properties, only the resultant XML block?

Similarly the Invoice could hold an Invoice header object property, and InvoiceHeader exposes another method to get the required XML, again keeping property editing within the core class and only exposing the data in the consumable format?

If multiple sections of XML are required at any point to put into various places in the final result, you could expose a number of methods for each required block.

I'll not try to type out php code here - I'm rusty!

SazooCat
  • 150
  • 1
  • 6
  • Yeah, the idea behind my implementation is that each object should provide a 'service' to its parent object. In this way, each object handles only its own tree and it delegates to its parent the merging operation. However, I would like that this 'service' will not be public to the end-user but only shared between objects. I think there is no way but using the objects inheritance. – Etraz Oct 29 '18 at 09:00
  • Based on my C++/C# experience, I went looking for the equivalent in PHP, have you looked at "Friend" classes? https://wiki.php.net/rfc/friend-classes https://stackoverflow.com/questions/317835/php-equivalent-of-friend-or-internal – SazooCat Oct 30 '18 at 09:12