問題
こんにちは、私は Symfony CMF 1.2、liip/imagine-bundle 1.3、symfony-cmf/media-bundle 1.2 を使用しています。ImagineBlock を拡張するブロックに 2 つの追加の画像フィールドを追加したいのは、アップロードするすべての画像に対して、単純なサイズ変更、アスペクト比などではない画像のモバイル バージョンとタブレット バージョンが存在するためです。画像の品質に影響を与えずにトリミング/サイズ変更することはできません。
試み
私のブロック
namespace xx\BlockBundle\Document;
use Doctrine\ODM\PHPCR\Mapping\Annotations as PHPCR;
use Symfony\Cmf\Bundle\BlockBundle\Doctrine\Phpcr\ImagineBlock;
use Symfony\Cmf\Bundle\MediaBundle\Doctrine\Phpcr\Image;
use Symfony\Cmf\Bundle\MediaBundle\ImageInterface;
use Symfony\Component\HttpFoundation\File\UploadedFile;
/**
* Class ClickableBlock
* @package xx\BlockBundle\Document
* @PHPCR\Document(referenceable=true)
*/
class ClickableBlock extends ImagineBlock
{
/**
* @PHPCR\Child(nodeName="image-mobile", cascade={"persist"})
* @var Image
*/
protected $imageMobile;
/**
* @PHPCR\Child(nodeName="image-tablet", cascade={"persist"})
* @var Image
*/
protected $imageTablet;
public function setIsPublishable($publishable)
{
$this->setPublishable($publishable);
}
/**
* @return Image
*/
public function getImageMobile()
{
return $this->imageMobile;
}
/**
* @return Image
*/
public function getImageTablet()
{
return $this->imageTablet;
}
/**
* Set the imageMobile for this block.
*
* @param ImageInterface|UploadedFile|null $image optional the imageMobile to update
* @return $this
* @throws \InvalidArgumentException If the $image parameter can not be handled.
*/
public function setImageMobile($image = null)
{
return $this->processImage($image, 'image-mobile', $this->imageMobile);
}
/**
* Set the imageTablet for this block.
*
* @param ImageInterface|UploadedFile|null $image optional the imageTablet to update
* @return $this
* @throws \InvalidArgumentException If the $image parameter can not be handled.
*/
public function setImageTablet($image = null)
{
return $this->processImage($image, 'image-tablet', $this->imageTablet);
}
/**
* @param ImageInterface|UploadedFile|null $image
* @param string $imageName
* @param Image $imageRef
* @return $this
*/
protected function processImage($image, $imageName, $imageRef)
{
if (!$image) {
return $this;
}
if (!$image instanceof ImageInterface && !$image instanceof UploadedFile) {
$type = is_object($image) ? get_class($image) : gettype($image);
throw new \InvalidArgumentException(sprintf(
'Image is not a valid type, "%s" given.',
$type
));
}
if ($imageRef) {
// existing imageTablet, only update content
$imageRef->copyContentFromFile($image);
} elseif ($image instanceof ImageInterface) {
$image->setName($imageName); // ensure document has right name
$imageRef = $image;
} else {
$imageRef = new Image();
$imageRef->copyContentFromFile($image);
}
return $this;
}
}
管理者:
namespace xx\BlockBundle\Admin;
use xx\BlockBundle\Document\ClickableBlock;
use xx\MainBundle\Form\Common\FormMapper as CommonFormMapper;
use Cocur\Slugify\Slugify;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Symfony\Cmf\Bundle\BlockBundle\Admin\Imagine\ImagineBlockAdmin;
class ClickableBlockAdmin extends ImagineBlockAdmin
{
/**
* {@inheritdoc}
*/
public function toString($object)
{
return $object instanceof ClickableBlock && $object->getLabel()
? $object->getLabel()
: parent::toString($object);
}
/**
* {@inheritdoc}
*/
public function prePersist($document)
{
parent::prePersist($document);
$this->InitialiseDocument($document);
}
/**
* @param $document
*/
private function InitialiseDocument(&$document)
{
$documentManager = $this->getModelManager();
$parentDocument = $documentManager->find(null, '/cms/xx/block');
$document->setParentDocument($parentDocument);
$slugifier = new Slugify();
$document->setName($slugifier->slugify($document->getLabel()));
}
/**
* {@inheritdoc}
*/
public function preUpdate($document)
{
parent::preUpdate($document);
$this->InitialiseDocument($document);
}
/**
* {@inheritdoc}
*/
protected function configureFormFields(FormMapper $formMapper)
{
parent::configureFormFields($formMapper);
if (null === $this->getParentFieldDescription()) {
$imageRequired = ($this->getSubject() && $this->getSubject()->getParentDocument()) ? false : true;
$formMapper
->with('form.group_general')
->remove('parentDocument')
->remove('filter')
->add('parentDocument', 'hidden', ['required' => false, 'data' => 'filler'])
->add('name', 'hidden', ['required' => false, 'data' => 'filler'])
->add('imageMobile', 'cmf_media_image', array('required' => $imageRequired))
->add('imageTablet', 'cmf_media_image', array('required' => $imageRequired))
->end();
// Append common fields to FormMapper
$commonFormMapper = new CommonFormMapper($formMapper);
$formMapper = $commonFormMapper->getPublishingFields();
}
}
}
このクラスに (コンストラクター/メソッドを介して) サービス コンテナーを挿入できないことに注意してください。そのため、今のところサービスを使用する代わりに、ハードコードされたノード パスとインスタンス化された Slugify クラスを使用しています。私はこれに対する解決策にも耳を傾けています。参照 -
xx.main.admin.pageadmin.container:
class: xx\MainBundle\Admin\PageAdmin
calls:
- [setContainer,[ @service_container ]]
# arguments: ["@service_container"]
画像フィールドの注釈は、 で見つけた次の構成に基づいています
\vendor\symfony-cmf\block-bundle\Resources\config\doctrine-phpcr\ImagineBlock.phpcr.xml
。
<doctrine-mapping
xmlns="http://doctrine-project.org/schemas/phpcr-odm/phpcr-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/phpcr-odm/phpcr-mapping
https://github.com/doctrine/phpcr-odm/raw/master/doctrine-phpcr-odm-mapping.xsd"
>
<document
name="Symfony\Cmf\Bundle\BlockBundle\Doctrine\Phpcr\ImagineBlock"
referenceable="true"
translator="attribute"
>
<node name="node"/>
<locale name="locale"/>
<field name="label" type="string" translated="true" nullable="true"/>
<field name="linkUrl" type="string" translated="true" nullable="true"/>
<field name="filter" type="string" nullable="true"/>
<child name="image" node-name="image">
<cascade>
<cascade-persist/>
</cascade>
</child>
</document>
</doctrine-mapping>
結果
デフォルトの「画像」フィールドは正常に保持されますが、他の 2 つの追加された画像フィールドは考慮されません。なぜなら、prePersist でデバッグすると、画像フィールドにはアップロードされたファイルが含まれているのに、両方のフィールドが null であることがわかるからです。
ページに保存して通常どおり表示する通常のテキストフィールドを追加してみました。
私は自分のプロジェクトで YAML を使用しているため、指定された XML が正確にどのように変換されるかはわかりません。
助けてください。:)