MM-Relation in Repository realisieren [Gelöst]

  • nexuss nexuss
    R2-D2
    0 x
    80 Beiträge
    0 Hilfreiche Beiträge
    30. 05. 2011, 10:06

    Hallo Typo3 Fans,
    ich bin gerade dabei eine Extension auf Basis von Extbase zu bauen. Es kommt eine MM-Relation vor. Doch genau hier ist das Problem.

    Zur Erläuterung:
    Produkte können einer oder mehreren Kategorien zugeordnet werden.

    Folgende Tabellen habe ich (Auszug):

    1. CREATE TABLE tx_myextensionkey_domain_model_category (
    2. ...
    3.  
    4. products INT(11) DEFAULT '0' NOT NULL,
    5.  
    6. ...
    7. );
    8.  
    9. CREATE TABLE tx_myextensionkey_domain_model_product (
    10. ...
    11.  
    12. categories INT(11) DEFAULT '0' NOT NULL,
    13.  
    14. ...
    15. );
    16.  
    17. CREATE TABLE tx_myextensionkey_category_products_mm (
    18. ...
    19.  
    20. uid_local INT(11) UNSIGNED DEFAULT '0' NOT NULL,
    21. uid_foreign INT(11) UNSIGNED DEFAULT '0' NOT NULL,
    22. sorting INT(11) UNSIGNED DEFAULT '0' NOT NULL,
    23. sorting_foreign INT(11) UNSIGNED DEFAULT '0' NOT NULL,
    24.  
    25. ...
    26. );

    Im TCA steht (Auszug):

    1. $TCA['tx_myextensionkey_domain_model_category'] = array(
    2. ...
    3. 'columns' => array(
    4. ...
    5. 'products' => array(
    6. 'exclude' => 0,
    7. 'label' => 'LLL:EXT:myextensionkey/Resources/Private/Language/locallang_db.xml:tx_myextensionkey_domain_model_category.products',
    8. 'config' => array(
    9. 'type' => 'select',
    10. 'size' => 10,
    11. 'minitems' => 0,
    12. 'maxitems' => 9999,
    13. 'autoSizeMax' => 10,
    14. 'multiple' => 0,
    15. 'foreign_table' => 'tx_myextensionkey_domain_model_product',
    16. 'MM' => 'tx_myextensionkey_category_products_mm',
    17. 'MM_opposite_field' => 'categories',
    18. )
    19. ),
    20. ...
    21. ),
    22. );
    23.  
    24. $TCA['tx_myextensionkey_domain_model_product'] = array(
    25. ...
    26. 'columns' => array(
    27. ...
    28. 'categories' => array(
    29. 'exclude' => 0,
    30. 'label' => 'LLL:EXT:myextensionkey/Resources/Private/Language/locallang_db.xml:tx_myextensionkey_domain_model_product.categories',
    31. 'config' => array(
    32. 'type' => 'select',
    33. 'size' => 10,
    34. 'minitems' => 0,
    35. 'maxitems' => 9999,
    36. 'autoSizeMax' => 10,
    37. 'multiple' => 0,
    38. 'foreign_table' => 'tx_myextensionkey_domain_model_category',
    39. 'MM' => 'tx_myextensionkey_category_products_mm',
    40. )
    41. ),
    42. ...
    43. ),
    44. );

    Jetzt möchte ich im Repository die korrekte Abfrage erstellen, damit in der jeweiligen Kategorie die verknüpften Produkte gelistet werden. Aber wie?

    Ich habe es schon mit folgendem Join versucht:

    1. public function findProductsByCategory() {
    2.  
    3. $query = $this->createQuery();
    4. $qomFactory = Tx_Extbase_Dispatcher::getPersistenceManager()->getBackend()->getQomFactory();
    5.  
    6. $categoriesSelector = $query->getSource();
    7. $mmSelector = $qomFactory->selector(null, 'tx_myextensionkey_category_products_mm');
    8. $productsSelector = $qomFactory->selector(null, 'tx_myextensionkey_domain_model_product');
    9. $AMMJoinCondition = $qomFactory->equiJoinCondition(
    10. $mmSelector->getSelectorName(), 'uid_local',
    11. $productsSelector->getSelectorName(), 'uid'
    12. );
    13. $MMBJoinCondition = $qomFactory->equiJoinCondition(
    14. $mmSelector->getSelectorName(), 'uid_foreign',
    15. $categoriesSelector->getSelectorName(), 'uid'
    16. );
    17. $query->setSource(
    18. $qomFactory->join(
    19. $productsSelector,
    20. $qomFactory->join(
    21. $mmSelector,
    22. $categoriesSelector,
    23. Tx_Extbase_Persistence_QueryInterface::JCR_JOIN_TYPE_INNER,
    24. $MMBJoinCondition
    25. ),
    26. Tx_Extbase_Persistence_QueryInterface::JCR_JOIN_TYPE_INNER,
    27. $AMMJoinCondition
    28. )
    29. );
    30. $query->setOrderings(array('title' => Tx_Extbase_Persistence_QueryInterface::ORDER_ASCENDING));
    31. return $query->execute();
    32. }

    Der funktioniert aber nicht. Da ist laut Bugtracker noch der Wurm drinne (Bug #10212, http://forge.typo3.org/issues/10212).

    Hat jemand einen guten Tip auf Lager? Wäre toll.

    Viele Grüße
    Thomas


  • 1
  • nexuss nexuss
    R2-D2
    0 x
    80 Beiträge
    0 Hilfreiche Beiträge
    14. 06. 2011, 21:52

    Ok, ich habs soweit.

    Es ist zwar im Join ein Bug enthalten, aber MM-Ralationen kann man sehr praktisch wie folgt ohne Join durchführen:

    Zuerst habe ich im Model folgendes eingetragen:

    1. <?php
    2.  
    3. ...
    4.  
    5. /**
    6.  * Categories
    7.  */
    8. class Tx_myextensionkey_Domain_Model_Category extends Tx_Extbase_DomainObject_AbstractEntity {
    9.  
    10. ...
    11.  
    12. /**
    13.   * The products of the Cateogy
    14.   *
    15.   * @var Tx_Extbase_Persistence_ObjectStorage<Tx_myextensionkey_Domain_Model_Product>
    16.   * @lazy
    17.   * @cascade remove
    18.   */
    19. protected $products;
    20.  
    21. ...
    22. ?>

    und im Repository dann:

    1. <?php
    2.  
    3. ...
    4.  
    5. /**
    6.  * Repository for Tx_myextensionkey_Domain_Model_Product
    7.  */
    8. class Tx_myextensionkey_Domain_Repository_ProductRepository extends Tx_Extbase_Persistence_Repository {
    9.  
    10. ...
    11.  
    12. /**
    13.   * Finds products by the specified category
    14.   *
    15.   * @param string $product
    16.   * @param Tx_myextensionkey_Domain_Model_Category $category The category the product must refer to
    17.   * @return Tx_Extbase_Persistence_QueryResultInterface The products
    18.   */
    19. public function findProductsByCategory(Tx_myextensionkey_Domain_Model_Category $category) {
    20. $query = $this->createQuery();
    21. $query->matching($query->contains('categories', $category->getUid()));
    22. $query->setOrderings(array('title' => Tx_Extbase_Persistence_QueryInterface::ORDER_ASCENDING));
    23. return $query->execute();
    24. }
    25. }
    26.  
    27. ...
    28.  
    29. ?>

    Und siehe da, alles wird so angezeigt wie es soll.

    Gruß
    Tom

  • 1