2013-08-07 5 views
4

나는 Symfony 2.3을 사용하여 SonataAdmin에서 ImageAdmin 클래스와 관련된 실제 객체를 가져와 조작하려고합니다. ImageAdmin 클래스가 사용되는 유일한 경우이 잘 작동합니다. 그러나 ImageAdmin이 다른 관리자에 포함되어 있으면 잘못 처리됩니다.Sonata Admin의 임베디드 Admin 클래스에서 하위 객체를 가져 오는 방법은 무엇입니까?

class ImageAdmin extends Admin { 
    protected $baseRoutePattern = 'image'; 

    protected function configureFormFields(FormMapper $formMapper) { 
     $subject = $this->getSubject(); 
    } 
} 

하지만 ParentAdmin에 ImageAdmin을 포함 할 때 사용 : 당신이 부모 항목을 편집 할 때 다음

class PageAdmin extends Admin { 
    protected function configureFormFields(FormMapper $formMapper) { 
     $formMapper->add('image1', 'sonata_type_admin'); 
    } 
} 

다음은 내장 된 관리자가 없을 때 작동하는 무슨이다 id 10을 호출하고 ImageAdmin에서 getSubject()를 호출하면 이미지 및 id 10!

다시 말해 getSubject()는 URL에서 ID를 추출한 다음 $this->getModelManager()->find($this->getClass(), $id);을 호출합니다.이 값은 부모 ID와 이미지 ID를 상호 참조합니다. 죄송합니다.


그래서 ... 내가 뭘 원하는가 직접 또는 포함 된 양식을 사용하여 편집되고 있는지 여부, 현재 ImageAdmin 인스턴스에서 편집 렌더링되는 실제 객체 /의 보류를 얻을 수 있으며, 그때 그것으로 일을 할 수 있어야합니다.

아마도 getSubject()는 잘못된 트리로 짖을 수도 있지만, ImageAdmin :: configureFormFields()에서 호출하면 $this->getCurrentChild()은 sonata_type_admin 필드 유형을 사용하여 ImageAdmin이 포함 된 경우에도 false를 반환합니다. 나는 아주 혼란 ​​스럽다. ...

어쨌든 간과 한 일부 명백한 방법으로 물건을 잡아서 누군가가 나를 계몽하는 데 도움이되기를 바란다.

답변

11

몇 가지 아이디어에 대한 Tautrimas 덕분에,하지만이에 대한 답을 알아 내기 위해 관리는 :

protected function configureFormFields(FormMapper $formMapper) 
{ 
    if($this->hasParentFieldDescription()) { // this Admin is embedded 
     $getter = 'get' . $this->getParentFieldDescription()->getFieldName(); 
     $parent = $this->getParentFieldDescription()->getAdmin()->getSubject(); 
     if ($parent) { 
      $image = $parent->$getter(); 
     } else { 
      $image = null; 
     } 
    } else { // this Admin is not embedded 
     $image = $this->getSubject(); 
    } 

    // You can then do things with the $image, like show a thumbnail in the help: 
    $fileFieldOptions = array('required' => false); 
    if ($image && ($webPath = $image->getWebPath())) { 
     $fileFieldOptions['help'] = '<img src="'.$webPath.'" class="admin-preview" />'; 
    } 

    $formMapper 
     ->add('file', 'file', $fileFieldOptions) 
    ; 
} 

곧 다가오는 SonataAdmin 요리 책이 게재됩니다 : ImageAdmin에서

이 설정!

https://github.com/sonata-project/SonataAdminBundle/issues/1546

+1

caponica의 솔루션은 oneToOne 관계에서만 작동합니다. ? 내 oneToMany 경우, this : $ parent -> $ getter()는 콜렉션을 리턴하고 현재 주제를 식별하는 방법을 모른다. 나는이 버그 보고서를 발견했다 : https : // github.co.kr/sonata-project/SonataAdminBundle/issues/1568에 수정 사항이 포함되어 있지만 아직 열려 있으므로 곧 병합하기를 바랍니다. – hombee

0

ImageAdmin에서 $this->getForm()->getViewData();을 사용해 볼 수 있습니까? 이렇게하면 올바른 하위 항목을 가져와야합니다.

+0

이> getForm()는 -> getViewData은()''안에''ImageAdmin :: configureFormFields은()'', 무한 루프를 일으킬 것 같은 메모리 부족과 죽음의 흰색 화면에서 ... 예. – caponica

+1

그럼'$ formMapper-> getFormBuilder() -> getForm() -> getViewData()'가 도움이 될까요? – TautrimasPajarskas

+0

글쎄, 폭발을 막을 지 모르지만 편집중인 페이지에 관련 이미지가 있어도 getViewData()는 NULL을 반환합니다. – caponica

2

caponica의 솔루션은 내가 맞다 만 oneToOne 관계에 노력하고 있습니다? 내 oneToMany 경우, this : $ parent -> $ getter()는 콜렉션을 리턴하고 현재 주제를 식별하는 방법을 모른다. 나는이 버그 보고서를 발견했습니다 https://github.com/sonata-project/SonataAdminBundle/issues/1568, 이것에 대한 수정 프로그램이 포함 된,하지만 여전히 열려있는, 그래서 나는 그들이 곧 병합 :(

편집

일부 연구가 희망 이 임시 수정 : 한마디로 Fixed getting wrong subject in sonata_type_collection

:

클래스를 생성하고이 파일의 내용 CopyPaste에 : AdminType 는 다음 서비스에 이것을 추가합니다.형태는 한 부모 docment에서 cascade_validation 활성화 및 임베디드 때

도 작동하지 않습니다 수정 : 그것은 여전히 ​​비록 버그가

services: 
sonata.admin.form.type.admin: 
    class: ACME\AdminBundle\Form\Type\AdminType 
    tags: 
     - { name: form.type, alias: sonata_type_admin } 

: YML, 당신에게 새로운 클래스 네임 스페이스를 클래스 네임 스페이스를 변경 오류

0

나는이 모든 솔루션을 시도했지만 아무 것도 작동하지 못함을 입증했습니다.
그래서 해결책을 찾기 위해 노력했습니다. 내 솔루션은 caponica의 솔루션을 기반으로하지만 oneToMany 케이스에서 작업합니다. 그쪽으로 찾은 해결책은 해결 방법이지만 효과가 좋습니다.
세션을 사용 중입니다.

public function getCurrentObjectFromCollection($adminChild) 
    { 
    $getter = 'get' . $adminChild->getParentFieldDescription() 
           ->getFieldName(); 
    $parent = $adminChild->getParentFieldDescription() 
        ->getAdmin() 
        ->getSubject(); 
    $collection = $parent->$getter(); 

    $session = $adminChild->getRequest()->getSession(); 
    $number = 0; 
    if ($session->get('adminCollection')) { 
     $number = $session->get('adminCollection'); 
     $session->remove('adminCollection'); 
    } 
    else { 
     $session->set('adminCollection', 1 - $number); 
    } 

    return $collection[$number]; 
} 

그리고 당신에 의해 관리자에 올바른 개체를 얻을 : 부모가 자식 관리자의 목록을 표시해야하는 경우

$object = $this->getCurrentObjectFromCollection($this) 

따라서, 각 하위 관리자가이 기능을 실행하고 의지합니다 세션 매개 변수를 업데이트하십시오. 모든 요소를 ​​가져 오면 세션 매개 변수가 삭제됩니다.
이 코드는 요소가 2 개만있는 목록 용이지만 요소 수에 관계없이 업데이트 할 수 있습니다.

희망이 내가 같은 문제가 있었다 사람 :