Backend -Artikelliste Erweiterung durch eigenes Model?

Hallo zusammen,

ich habe ein Problem mit der Erweiterung der Artikelliste im Backend. Mit Artikel-Attributen bekomme ich das relativ einfach hin. Nun möchte ich aber eine Spalte mit dem Inhalt eines eigenen Models integrieren und auch filterbar machen.

Ich habe ein Model custom/plugins/FpDemandPlanning/Models/Supplier.php -> hier habe ich das Feld $name, welches ich auslesen will.

Ich habe mich nun an diese beiden Events gehängt:

'SwagMultiEdit_Product_DqlHelper_getColumnsForProductListing_filterColumns' => 'filterBackendArticleColumns',
'SwagMultiEdit_Product_DqlHelper_getJoinColumns_filterColumns' => 'joinBackendArticleColumns',


public function filterBackendArticleColumns(\Enlight_Event_EventArgs $args) {
    $result = $args->getReturn();

    $shownColumns = $args->get('defaultColumns');
    $columnPositions = array_flip($shownColumns);

    $alias = 'FpDemandPlanning_Supplier';
    $result['FpDemandPlanningSupplier'] = array(
        'entity' => 'Supplier',
        'field' => 'name',
        'editable' => false,
        'type' => 'string',
        'nullable' => true,
        'allowInGrid' => true,
        'columnName' => 'name',
        'alias' => $alias,
        'table' => 'fp_demand_planning_supplier',
        'show' => in_array($alias, $shownColumns),
        'position' => array_key_exists($alias, $columnPositions) ? $columnPositions[$alias] : -1,
    );

    return $result;
}

public function joinBackendArticleColumns(\Enlight_Event_EventArgs $args) {
    $join = $args->getReturn();
    
        $join['FpDemandPlanning\Models\Supplier'] = 'FpDemandPlanning\Models\Supplier';

    return $join;
}

Den  /Shopware/Components/MultiEdit/Resource/Product/DqlHelper.php habe ich wie folgt erweitert, um die Spalte mit Daten zu füllen.

public function getDefaultColumns()
{
    $columns = parent::getDefaultColumns();
    $columns[] = 'FpDemandPlanning_Supplier';

    return $columns;
}

public function getProductForListing($detailId) {
    $article = parent::getProductForListing($detailId);

    $articleObj = $this->getModelManager()->find(Article::class, $detailId);

    $service = $this->container->get('fp_dashboard.dashboard_service');
    $supplier = $service->getArticleFpSupplier($articleObj);
    $article['FpDemandPlanning_Supplier'] = $supplier['name'];

    return $article;
}

 Beim Aufruf der Artikelliste erhalte ich nun folgende Fehlermeldung in SW:

Ups! Ein Fehler ist aufgetreten! Die nachfolgenden Hinweise sollten Ihnen weiterhelfen. [Semantical Error] line 0, col 147 near ‘WHERE detail.kind’: Error: Class ‘WHERE’ is not defined. in vendor/doctrine/orm/lib/Doctrine/ORM/Query/QueryException.php on line 63 Stack trace: #0 

Ich habe danach nachgesehen, woher das detail.kind überhaupt kommt, und sehe hier im DqlHelper.php die Funktion  getDqlFromTokens , dort werden die Tokens durchgegangen und bei ISMAIN steht:

case 'ISMAIN':
    $newTokens[] = ' detail.kind = 1 ';
    continue 2;

Ich glaube, ich muss nun in der  SwagMultiEdit_Product_DqlHelper_getJoinColumns_filterColumns die tokens ermitteln und auf Basis der Tokens überhaupt den Join durchführen, aber was sind die Tokens überhaupt? Muss ich ggf einen eigenen Token definieren, der nichts weiter mit meiner SQL macht? Wie kann ich das hier lösen, das er bei einem Token gar nichts macht, außer das er mir mein Ergebnis liefert und dieses filterbar ist?

Das ist ein etwas komplexeres Thema und ich hoffe jemand liest sich das Ganze durch kann mir helfen :wink:

Danke!

Hallo,

 

Du bist das ganze meiner Meinung nach falsch angegangen. Du musst ein ExtJS Backend Modul erweitern. Dir fehlt noch komplett der ExtJS Teil, also Deine zusätzliche Spalte in JavaScript bzw. ExtJS. Du musst hierfür das Standard-Model überschreiben und um deine Spalte erweitern. Mehr dazu findest Du aber auch in der Doku: Backend extensions

Und auch der Beitrag mit den ExtJS Listing dürfte für Dich interessant sein: Backend Components - Listing

ExtJS und das Shopware Backend im Allgemeinen ist nicht leicht zu verstehen, besonders weil es lange unkommentierte Methoden und Klassen gibt. Wenn Du weitere Fragen zur Implementierung hast, dann stelle sie hier einfach. Es ist noch kein Meister vom Himmel gefallen und gerade bei Backend Extensions tun sich die meisten Leute schwer. War bei mir am Anfang auch so…

 

 

MFG

 

derwunner

Moin derwunner,

danke für deine Antwort. Ich glaube nicht, dass ich hier ExtJs erweitern muss. Die Hooks, die ich anspreche sind in den Original-Dateien kommentiert, dass sich diese zur Erweiterung der Spalten, Tokens nutzen lassen. Ich weiß nur nicht zu 100% wie - da ich z.B. noch wegen der Tokens einen Fehler erhalte. Aber Showpare hat hier an den Stellen Filter, in die man sich für die Erweiterung hängen kann - ohne ExtJs.

Das mag schon so sein. Du hast bisher nur dafür gesorgt, dass die Daten aus der Datenank gelesen werden. Jetzt musst Du sie noch zur Anzeige bringen in der Liste im Backend. Und das geht soviel ich weiß nur mit ExtJS.

@derwunner‍

Ich komme leider erst jetzt zum Antworten. Mit meinen Änderungen von oben wird die Information bereits in einer neuen Spalte angezeigt: http://d.pr/i/ApFcts

Ohne ExtJs Erweiterung… das passt also. Ich habe hier noch zwei Probleme:

  1. Wenn ich nun in dem Grid eine Änderung z.B: am Lagerbestand vornehme und speichere, erhalte ich eine Fehlermeldung:

    [2017-07-25 12:02:15] core.ERROR: exception ‘Doctrine\Common\Persistence\Mapping\MappingException’ with message ‘Class ‘’ does not exist’ in /var/www/html/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/MappingException.php:96 Stack trace: #0 /var/www/html/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/RuntimeReflectionService.php(41): Doctrine\Common\Persistence\Mapping\MappingException::nonExistingClass(’’) #1 /var/www/html/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php(281): Doctrine\Common\Persistence\Mapping\RuntimeReflectionService->getParentClasses(’’) #2 /var/www/html/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php(311): Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory->getParentClasses(’’) #3 /var/www/html/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php(78): Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory->loadMetadata(’’) #4 /var/www/html/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php(216): Doctrine\ORM\Mapping\ClassMetadataFactory->loadMetadata(’’) #5 /var/www/html/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php(379): Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory->getMetadataFor(’’) #6 /var/www/html/engine/Shopware/Components/MultiEdit/Resource/Product.php(192): Doctrine\ORM\EntityManager->find(NULL, NULL) #7 /var/www/html/engine/Shopware/Controllers/Backend/ArticleList.php(109): Shopware\Components\MultiEdit\Resource\Product->save(Array) #8 /var/www/html/engine/Library/Enlight/Controller/Action.php(159): Shopware_Controllers_Backend_ArticleList->saveSingleEntityAction() #9 /var/www/html/engine/Library/Enlight/Controller/Dispatcher/Default.php(523): Enlight_Controller_Action->dispatch(‘saveSingleEntit…’) #10 /var/www/html/engine/Library/Enlight/Controller/Front.php(223): Enlight_Controller_Dispatcher_Default->dispatch(Object(Enlight_Controller_Request_RequestHttp), Object(Enlight_Controller_Response_ResponseHttp)) #11 /var/www/html/engine/Shopware/Kernel.php(180): Enlight_Controller_Front->dispatch() #12 /var/www/html/vendor/symfony/http-kernel/HttpCache/HttpCache.php(487): Shopware\Kernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #13 /var/www/html/engine/Shopware/Components/HttpCache/AppCache.php(255): Symfony\Component\HttpKernel\HttpCache\HttpCache->forward(Object(Symfony\Component\HttpFoundation\Request), true, NULL) #14 /var/www/html/vendor/symfony/http-kernel/HttpCache/HttpCache.php(258): Shopware\Components\HttpCache\AppCache->forward(Object(Symfony\Component\HttpFoundation\Request), true) #15 /var/www/html/engine/Shopware/Components/HttpCache/AppCache.php(103): Symfony\Component\HttpKernel\HttpCache\HttpCache->pass(Object(Symfony\Component\HttpFoundation\Request), true) #16 /var/www/html/shopware.php(117): Shopware\Components\HttpCache\AppCache->handle(Object(Symfony\Component\HttpFoundation\Request)) #17 {main} {“uid”:“2fb835b”}

  2. Sollte es ebenfalls möglich sein nach dem Inhalt der neuen Spalte zu suchen/filtern. Ich muss der Suche also beibringen auch diese Spalte zu durchsuchen.

Hast Du hier eine Idee, wie ich das beides lösen kann?