Registry/Singleton in Extbase Extensions

  • fragile74 fragile74
    Jedi-Ritter
    0 x
    125 Beiträge
    0 Hilfreiche Beiträge
    14. 02. 2010, 18:19

    Hallo,

    ich code gerade eine extbase/fluid-basierte Extension, die die PHPExcel-Klassen verwendet. Diese sind ja für TYPO3 in der PHPExcel-Extension gekapselt. Diese ist vom Typ "Service".

    Wie binde ich diese Extension jetzt richtig in mein MVC-Modell ein ? Habe leider in entsprechenden Referenzen/Tutorials nichts derartiges gefunden bzw. fehlt mir momentan etwas das Verständnis ...

    Thx 4 tipps...


  • 1
  • fragile74 fragile74
    Jedi-Ritter
    0 x
    125 Beiträge
    0 Hilfreiche Beiträge
    14. 02. 2010, 20:59

    Nochmal zur Erläuterung:

    Ich habe ein Model Tx_MyExtension_Domain_Model_Sheet und einen Controller Tx_MyExtension_Controller_Start.
    Mein Model sieht so aus:

    1. class Tx_MyExtension_Domain_Model_Sheet extends Tx_Extbase_DomainObject_AbstractEntity {
    2.  
    3.  
    4.  
    5. /**
    6. * Some title.
    7. *
    8. * @var string
    9. * @identity
    10. */
    11. protected $title, $ExcelSheet = null;
    12.  
    13. /**
    14. * Sheet constructor
    15. *
    16. */
    17. public function __construct() {
    18. set_include_path(get_include_path() . PATH_SEPARATOR . t3lib_extMgm::extPath('phpexcel_library').'phpexcel/Classes/');
    19. require_once 'PHPExcel.php';
    20. require_once 'PHPExcel/Writer/Excel2007.php';
    21.  
    22. }
    23.  
    24.  
    25. /**
    26. * Inits the sheet
    27. *
    28. * @param string $title
    29. * return void
    30. */
    31. public function initSheet($title) {
    32.  
    33. $ExcelSheet = t3lib_div::makeInstance('PHPExcel');
    34. $ExcelSheet->getProperties()->setCreator("Myself");
    35. $ExcelSheet->getProperties()->setLastModifiedBy("MySelf");
    36. $ExcelSheet->getProperties()->setTitle($title);
    37. $ExcelSheet->getProperties()->setSubject($title);
    38.  
    39. $ExcelSheet->setActiveSheetIndex(0);
    40. $ExcelSheet->getActiveSheet()->SetCellValue('A1', 'Hello');
    41. $ExcelSheet->getActiveSheet()->SetCellValue('B2', 'world!');
    42. $ExcelSheet->getActiveSheet()->SetCellValue('C1', 'Hello');
    43. $ExcelSheet->getActiveSheet()->SetCellValue('D2', 'world!');
    44. echo ('Sheet initiated');
    45.  
    46. return $ExcelSheet;
    47.  
    48. }
    49.  
    50. /**
    51. * Save Excel sheet
    52. *
    53. *@param string $Name
    54. */
    55. public function saveSheet($Name, $ExcelObj) {
    56.  
    57. $objWriter = new PHPExcel_Writer_Excel2007($ExcelObj);
    58. $objWriter->save('../../'.$Name.'.xlsx');
    59.  
    60. echo ('Saved');
    61. }
    62.  
    63. }

    Mein Controller so:

    1. class Tx_MyExtension_Controller_StartController extends Tx_Extbase_MVC_Controller_ActionController {
    2.  
    3.  
    4. public $TestObj;
    5.  
    6. /**
    7. * Initializes the current action
    8. *
    9. * @return void
    10. */
    11. public function initializeAction() {
    12.  
    13. }
    14.  
    15. /**
    16. * Index action for this controller.
    17. *
    18. * @return string The rendered view
    19. */
    20. public function indexAction() {
    21.  
    22. $this->view->assign($message,'Process initiated.');
    23.  
    24. }
    25.  
    26. public function saveAction() {
    27.  
    28. $start = t3lib_div::makeInstance('Tx_Efempty_Domain_Model_Start');
    29. $TestObj = $start->initSheet('MeinSheet');
    30. $start->saveSheet('Testing', $TestObj);
    31. $this->view->assign($message,'ExcelSheet saved.');
    32.  
    33. }
    34.  
    35.  
    36. }

    Ich möchte aber EINMAL in meiner Extension ein Objekt vom Typ PHPExcel anlegen und dies dann im GESAMTEN Klassenraum (zumindest im Controller) in diversen Funktionen nutzen können -> ist ja der Sinn einer Extension, die mit PHPExcel arbeitet ... kann mich mal ein MVC/Extbase - Experte über die richtige "Anordnung" der Objektinstanzen innerhalb dieser Extbase-Extension aufklären ?

    Danke - auch ein "das verstehe ich nicht, erklärs mir mal anders" etc. würde mir schon weiterhelfen ...

  • fragile74 fragile74
    Jedi-Ritter
    0 x
    125 Beiträge
    0 Hilfreiche Beiträge
    15. 02. 2010, 16:04

    Niemand ? Ist das Thema zu neu oder zu unklar formuliert ?

    Soweit ich es verstanden habe, wäre das ein klassischer "Singleton" UseCase.
    Frage: Wo in der Klassenhierarchie von Extbase/Fluid instanziere ich dann die PHPExcel-Klasse am besten ? Bisher gehe ich davon aus, dass die Model-Klasse die richtige ist. Oder muss ich nochmal eine Helper-Klasse als 2. Model-Objekt(Klasse) implementieren ? Ich checke im Moment einfach nicht, wie ich eine Instanz über die gesamte Laufzeit der Extension am Leben erhalte

  • Ranger Ranger
    T3PO
    0 x
    16 Beiträge
    0 Hilfreiche Beiträge
    25. 03. 2010, 09:50

    Das würde mich auch brennend ineressieren, da ich meine Daten per SOAP von einem anderen System hole. Die SOAP-Instanz möchte ich auch von überall ansprechen können. Im Idealfall auch irgendwie die daten in meine Models übertragen, aber steh ich auch wie der Ochs vorm Berg....alles noch ziemliches Neuland für mich.

  • fragile74 fragile74
    Jedi-Ritter
    0 x
    125 Beiträge
    0 Hilfreiche Beiträge
    25. 03. 2010, 11:57

    Hi,

    das Thema ist eigentlich OO-typisch und kann entweder mit einer Singleton-Klasse oder z.b. über Injections gelöst werden.

    In meinem Fall habe ich einfach im Konstruktor der Model-Klasse ein "t3lib_div::makeInstance('<deineKlasse>');" eingefügt. Dadurch steht mir diese Klasse in meiner Model-Klasse zur Verfügung.

    Ich warte auch gespannt auf das O'Reilly Buch der beiden Extbase/Fluid-Macher, in dem hoffentlich solche Konstruktionen erklärt/aufgeklärt werden ...

    PS: Natürlich musst du vorher deine Klasse z.b. über require_once für die Modelklasse verfügbar machen...

  • Ranger Ranger
    T3PO
    0 x
    16 Beiträge
    0 Hilfreiche Beiträge
    25. 03. 2010, 13:11

    So ähnlich habe ich es auch gemacht, nur dass ich die Klassen-Instanz nicht im model mache sondern in der Repository-Klasse, da ich in dieser eh die Funktionen um die SOAP-Metoden erweitern musste. Aber im endefekt ist es ja gehüpft wie gesprungen....jo, das Buch erwarte ich auch voller Spannung...dauert nur noch n guten Monat, glaub ich.
    Dank Dir aber für das Feedback!

  • zeradun zeradun
    T3PO
    0 x
    11 Beiträge
    0 Hilfreiche Beiträge
    13. 07. 2010, 15:31

    Bin in einer ähnlichen Situation auch auf das Problem gekommen.

    In eigenen Systemen könnte man die Definitionen entsprechend coden:

    1. class xyz {
    2. private static $instance;
    3.  
    4. private function __construct() {
    5. // Construct
    6. }
    7.  
    8. public static function getInstance() {
    9. if(empty(xyz::$instance)) {
    10. xyz::$instance = new xyz();
    11. }
    12. return xyz:$intstance;
    13. }
    14.  
    15. public function do_something() {
    16. // do some action
    17. }
    18. }
    19.  
    20. // Objekt instanzieren
    21. $obj = xyz::getInstance();
    22. $obj->do_something();

    Das objekt ist überall das gleiche egal woher man es holt.
    Man kann es nur nicht neu konstruieren da der konstruktor privat ist.

    Mit

    1. t3lib_div::makeInstance('xyz');
    geht das System aber NICHT!

    Da hat TYPO3 das Interface 'Singleton'

    TYPO3 supports singleton pattern for classes. Singletons are instantiated only once per HTTP request regardless of the number of calls to the t3lib_div::makeInstance(). To use singleton pattern class must implement t3lib_Singleton interface:

    1. require_once(PATH_t3lib . 'interfaces/interface.t3lib_singleton.php');
    2.  
    3. class tx_myext_mySingletonClass implements t3lib_Singleton {
    4.  
    5.  
    6. }

    Entsprechend kann man alle Klassen vom Typ singleton mit t3lib_div::makeInstance('xyz'); aufrufen.

    Quelle: Typo3.org Core Documentation

  • 1