Skip to content

Instantly share code, notes, and snippets.

@mindplay-dk
Created January 16, 2014 19:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mindplay-dk/8462105 to your computer and use it in GitHub Desktop.
Save mindplay-dk/8462105 to your computer and use it in GitHub Desktop.
Invasive createCommand() method you can add to your own Yii ActiveRecord extension.
<?php
class ActiveRecord extends CActiveRecord
{
/**
* Create and configure a CDbCommand instance based on current criteria.
*
* Think twice before using this method - use only in cases where being able to stream
* through the raw SQL record-sets is crucial, usually for performance reasons, when
* dealing with very large record sets.
*
* This often will not do what you expect, at least not in the first attempt - Yii AR
* writes queries that are optimized for Yii, and not always fit for human consumption.
*
* if you're going to grab the raw SQL command with this method:
*
* - DON'T use CActiveRecord::together() - you won't get what you were expecting!
* - DO add custom CDbCriteria::$select clauses, since Yii garbles column names by
* default; you probably want to be selective about which columns you select anyway.
*
* @param mixed $condition query condition or criteria.
* @param array $params parameters to be bound to an SQL statement.
*
* @return CDbCommand DANGER DANGER, ENTER THE GRAVE YARD CHAMBER
* @see http://www.youtube.com/watch?v=auqur-Nz-X8
*/
public function createCommand($condition = '', $params = array())
{
// create criteria and apply active scope:
$criteria = $this->getCommandBuilder()->createCriteria($condition, $params);
$this->applyScopes($criteria);
// get an ActiveFinder instance for the model:
$finder = $this->getActiveFinder($criteria->with ?: array());
// hack into CActiveFinder to obtain the join-tree:
static $accessor;
if (!$accessor) {
$accessor = new ReflectionProperty('CActiveFinder', '_joinTree');
$accessor->setAccessible(true);
}
/** @var CJoinElement $joinTree */
$joinTree = $accessor->getValue($finder);
// construct your own join-query instance using the stolen join-tree:
$query = new CJoinQuery($joinTree, $criteria);
// build the query:
$joinTree->buildQuery($query);
// create the command for the query:
return $query->createCommand($this->getCommandBuilder());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment