Skip to content

Instantly share code, notes, and snippets.

@romansklenar
Created August 15, 2010 03:36
Show Gist options
  • Save romansklenar/525030 to your computer and use it in GitHub Desktop.
Save romansklenar/525030 to your computer and use it in GitHub Desktop.
Doctrine 2, BLOB datatype implementation
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\DBAL\Types;
use Doctrine\DBAL\Platforms\AbstractPlatform;
/**
* Type that maps a PHP binary data to a blob SQL type.
*
* @since 2.0
* @author Roman Sklenar <[email protected]>
*/
class Blob extends Type
{
const BLOB = 'blog';
public function getName()
{
return self::BLOB;
}
public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
{
return $platform->getDoctrineTypeMapping('BLOB');
}
public function convertToDatabaseValue($value, AbstractPlatform $platform)
{
return ($value === null) ? null : base64_encode($value);
}
public function convertToPHPValue($value, AbstractPlatform $platform)
{
return ($value === null) ? null : base64_decode($value);
}
}
<?php
// ...
$em = Doctrine\ORM\EntityManager::create($conn, $config, $evm);
// types registration
Doctrine\DBAL\Types\Type::addType('blob', 'Doctrine\DBAL\Types\Blob');
$em->getConnection()->getDatabasePlatform()->registerDoctrineTypeMapping('BLOB', 'blob');
<?php
namespace Entities;
/**
* @Entity
* @Table(name="Photos")
*/
class Photo extends Base
{
/** @Column(type="integer") @Id @GeneratedValue */
protected $id;
// ...
/** @Column(type="blob") */
protected $data;
/**
* Converts instance to Nette\Image.
*
* @return Image
*/
public function toImage() {
return Nette\Image::fromString($this->data);
}
}
@Monomachus
Copy link

According to daSn0wie (http://stackoverflow.com/users/433927/dasn0wie) you don't need to add anything in bootstrap.php,
just to your Bundle initialization (/src/YOURDOMAIN/YOURBUNDLE/YOURDOMAINYOUBUNDLE.php)

class YourBundle extends Bundle
{
    public function boot()
    {
        $em = $this->container->get('doctrine.orm.entity_manager');
        Type::addType('blob', 'YOURDOMAIN\YOURBUNDLE\YOURTYPEDIRECTORY\BlobType');
        $em->getConnection()->getDatabasePlatform()->registerDoctrineTypeMapping('blob','blob');        
    }
}

@VishwaKumar
Copy link

In above Blob.php, there is this line const BLOB = 'blog'; This is wrong right? The constant value must be 'blob' rather than 'blog' right?

@Monomachus
Copy link

@VishwaKumar
Yes you got it right it should be blob

@VishwaKumar
Copy link

@Monomachus
Ok thanks!
I am trying to register the Blobtype using the function boot() but i am getting this error:

Fatal error: Class 'MYDOMAIN\MYBundle\Type' not found in C:\xampp\htdocs\project\src\MYDOMAIN\MyBundle\MYDOMAINMyBundle.php on line 12

Am i missing something here?
Thank You.

@VishwaKumar
Copy link

ok got it! i had not included this in MYDOMAINMyBundle.php

use Doctrine\DBAL\Types\Type;

@VishwaKumar
Copy link

Now i am getting this exception:

[Doctrine\DBAL\DBALException]
Type blob already exists.

What is the issue?

@Monomachus
Copy link

@VishwaKumar
You actually need function boot() in your bundle file instead of bootstrap.php, so please verify that you have only one or another

@VishwaKumar
Copy link

Actually i have two bundles in my src folder: one for admin and the other for site. I have put the function boot() in both the bundles php file. Is this causing the issue. If i put it in only one bundle will the BlobType be available in other bundle also?

@Monomachus
Copy link

@VishwaKumar
hmmm hadn't this exact situation. But yeah I think you are right.
I think you now have to do it like this in both your bundles. Like that you verify that it is not already registered.

class YourBundle extends Bundle
{
     public function boot()
    {
        $em = $this->container->get('doctrine.orm.entity_manager');
        if (!Type::hasType('blob') 
        {
            Type::addType('blob', 'YOURDOMAIN\YOURBUNDLE\YOURTYPEDIRECTORY\BlobType');
            $em->getConnection()->getDatabasePlatform()->registerDoctrineTypeMapping('blob','blob');
        }        
    }
}    

@VishwaKumar
Copy link

@Monomachus
It worked like magic! :)
Thank You for your time.
Appreciate it.

@alexandresalome
Copy link

Avoid instanciating the entity manager and check type:

    $conn = $this->container->get('doctrine')->getConnection();
    // If you have multiple connections, iterate over get('...')->getConnections();
    if (!Type::hasType('blob')) {
        Type::addType('blob', 'YOURDOMAIN\YOURBUNDLE\Doctrine\DBAL\Type\BlobType');
        $conn->getDatabasePlatform()->registerDoctrineTypeMapping('blob','blob');        
    }

@zebba
Copy link

zebba commented Dec 13, 2012

We have had problems using this implementation when we tried to duplicate entries in the database by copying/cloning. The operation always resulted in a 0-sized entry in the blob field.

Once you add an is_file()-check and decide from there it was working however.

@egor-xyz
Copy link

How I can get value from parameters.yml in Class *** extended Type? I need to take public key for RSA encrypt.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment