Skip to content

Instantly share code, notes, and snippets.

@Tocacar
Created December 19, 2012 16:06
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Tocacar/4337861 to your computer and use it in GitHub Desktop.
Save Tocacar/4337861 to your computer and use it in GitHub Desktop.
I need to create a custom DataSourceIterator so that I can pass a related collection's properties to the sonata admin bundle's exportAction (I think this is the only way to achieve the export of one-to-many values, I may be wrong). I have traced backwards how my admin class is currently generating a DataSourceIterator (I think) - see below. Pres…
// vendor/sonata-project/admin-bundle/Sonata/AdminBundle/Admin/Admin.php
/**
* @return
*/
public function getDataSourceIterator()
{
$datagrid = $this->getDatagrid();
$datagrid->buildPager();
return $this->getModelManager()->getDataSourceIterator($datagrid, $this->getExportFields());
}
// $this->getModelManager() is as follows:
/**
* {@inheritdoc}
*/
public function getModelManager()
{
return $this->modelManager;
}
// and $this->modelManager is set using this method:
/**
* @param \Sonata\AdminBundle\Model\ModelManagerInterface $modelManager
*/
public function setModelManager(ModelManagerInterface $modelManager)
{
$this->modelManager = $modelManager;
}
// so, the getDataSourceIterator method that is called once the modelManager property is retrieved is defined in the ModelManagerInterface class and looks like this:
// vendor/sonata-project/admin-bundle/Sonata/AdminBundle/Model/ModelManagerInterface.php
/**
* @param DatagridInterface $datagrid
* @param array $fields
* @param null $firstResult
* @param null $maxResult
*
* @return \Exporter\Source\SourceIteratorInterface
*/
function getDataSourceIterator(DatagridInterface $datagrid, array $fields, $firstResult = null, $maxResult = null);
// and is implemented, from what I can tell, in the ModelManager class like this:
// vendor/sonata-project/doctrine-orm-admin-bundle/Sonata/DoctrineORMAdminBundle/Model/ModelManager.php
/**
* {@inheritdoc}
*/
public function getDataSourceIterator(DatagridInterface $datagrid, array $fields, $firstResult = null, $maxResult = null)
{
$datagrid->buildPager();
$query = $datagrid->getQuery();
$query->select('DISTINCT ' . $query->getRootAlias());
$query->setFirstResult($firstResult);
$query->setMaxResults($maxResult);
return new DoctrineORMQuerySourceIterator($query instanceof ProxyQuery ? $query->getQuery() : $query, $fields);
}
@Thabo02
Copy link

Thabo02 commented Jun 23, 2014

Hi Tocacar,

I know this is old. Did you ever find a solution?

@ZaneA
Copy link

ZaneA commented May 28, 2015

For anyone else who lands here in the future, here is one way to do it :)

In the Admin class (this currently doesn't paginate properly, instead returning all results, hopefully will update here shortly when I figure that out):

    public function getDataSourceIterator()
    {
        $datagrid = $this->getDatagrid();

        $datagrid->buildPager();
        $query = $datagrid->getQuery();

        $query->select('DISTINCT ' . $query->getRootAlias());
        //$query->setFirstResult($firstResult);
        //$query->setMaxResults($maxResult);

        return new CustomQuerySourceIterator($query->getQuery(), $this->getExportFields());
    }

The CustomQuerySourceIterator:

use Exporter\Source\DoctrineORMQuerySourceIterator;

class CustomQuerySourceIterator extends DoctrineORMQuerySourceIterator
{
    protected function getValue($value)
    {
        //if value is array or collection, creates string
        if (is_array($value) or $value instanceof \Traversable) {
            $result = array();
            foreach ($value as $item) {
                $result[] = $this->getValue($item);
            }
            $value = implode(', ', $result);
            //formated datetime output
        } elseif ($value instanceof \DateTime) {
            $value = $value->format('r');
        } elseif (is_object($value)) {
            $value = (string) $value;
        }

        return $value;
    }
}

@shades3002
Copy link

shades3002 commented Nov 15, 2017

Greetings. how could I do a search of this type in this method getDataSourceIterator.

$query-> select () -> where ('state.name') -> notEqual ('approved');

You can guide me

public function getDataSourceIterator()
{
        $datagrid = $this->getDatagrid();
        $datagrid->buildPager();
        $query = $datagrid->getQuery();
        $query->select()->where('state.name')->notEqual('approved');
 
        if ($query instanceof ProxyQueryInterface) {
            $query->addOrderBy($query->getSortBy(), $query->getSortOrder());
            $query = $query->getQuery();
        }

        return $this->getModelManager()->getDataSourceIterator($this->getDatagrid(), $this->getExportFields());
}

@shades3002
Copy link

Solvent that way by doing the query before instantiating the buildPager () and it worked correctly.

public function getDataSourceIterator()
{
    $datagrid = $this->getDatagrid();
    $datagrid->getQuery()->field('state')->equals(APPROVED);
    $datagrid->buildPager();
    $datasource = $this->getModelManager()->getDataSourceIterator($datagrid, $this->getExportFields());
    return $datasource;
}

@souflam
Copy link

souflam commented Feb 14, 2018

how i can save the results of this DoctrineORMQuerySourceIterator in my server or send as a attachement in a email ?

@Saif-hub24
Copy link

I just want to override the query in the getDataSourceIterator function or export query. I want to change entire query with multiple joins so that I can get my required field exported. Is it possible? Any help is much appreciated.

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