/**
  * Update any requests to limit the results to the current site
  */
 public function augmentSQL(SQLSelect $query, DataQuery $dataQuery = NULL)
 {
     if (Subsite::$disable_subsite_filter) {
         return;
     }
     // If you're querying by ID, ignore the sub-site - this is a bit ugly...
     if ($query->filtersOnID()) {
         return;
     }
     $regexp = '/^(.*\\.)?("|`)?SubsiteID("|`)?\\s?=/';
     foreach ($query->getWhereParameterised($parameters) as $predicate) {
         if (preg_match($regexp, $predicate)) {
             return;
         }
     }
     try {
         $subsiteID = (int) Subsite::currentSubsiteID();
         $froms = $query->getFrom();
         $froms = array_keys($froms);
         $tableName = array_shift($froms);
         if ($tableName != 'SiteConfig') {
             return;
         }
         $query->addWhere("\"{$tableName}\".\"SubsiteID\" IN ({$subsiteID})");
     } catch (UnexpectedValueException $e) {
         // No subsites exist yet
     }
 }
 /**
  * Update any requests to limit the results to the current site
  */
 public function augmentSQL(SQLSelect $query, DataQuery $dataQuery = NULL)
 {
     if (Subsite::$disable_subsite_filter) {
         return;
     }
     if ($dataQuery->getQueryParam('Subsite.filter') === false) {
         return;
     }
     // If you're querying by ID, ignore the sub-site - this is a bit ugly...
     // if(!$query->where || (strpos($query->where[0], ".\"ID\" = ") === false && strpos($query->where[0], ".`ID` = ") === false && strpos($query->where[0], ".ID = ") === false && strpos($query->where[0], "ID = ") !== 0)) {
     if ($query->filtersOnID()) {
         return;
     }
     if (Subsite::$force_subsite) {
         $subsiteID = Subsite::$force_subsite;
     } else {
         /*if($context = DataObject::context_obj()) $subsiteID = (int)$context->SubsiteID;
           else */
         $subsiteID = (int) Subsite::currentSubsiteID();
     }
     // The foreach is an ugly way of getting the first key :-)
     foreach ($query->getFrom() as $tableName => $info) {
         // The tableName should be SiteTree or SiteTree_Live...
         if (strpos($tableName, 'SiteTree') === false) {
             break;
         }
         $query->addWhere("\"{$tableName}\".\"SubsiteID\" IN ({$subsiteID})");
         break;
     }
 }
 /**
  * Update any requests to limit the results to the current site
  */
 public function augmentSQL(SQLSelect $query)
 {
     if (Subsite::$disable_subsite_filter) {
         return;
     }
     // If you're querying by ID, ignore the sub-site - this is a bit ugly...
     if ($query->filtersOnID()) {
         return;
     }
     $regexp = '/^(.*\\.)?("|`)?SubsiteID("|`)?\\s?=/';
     foreach ($query->getWhereParameterised($parameters) as $predicate) {
         if (preg_match($regexp, $predicate)) {
             return;
         }
     }
     /*if($context = DataObject::context_obj()) $subsiteID = (int)$context->SubsiteID;
     		else */
     $subsiteID = (int) Subsite::currentSubsiteID();
     $froms = $query->getFrom();
     $froms = array_keys($froms);
     $tableName = array_shift($froms);
     if ($tableName != 'SiteConfig') {
         return;
     }
     $query->addWhere("\"{$tableName}\".\"SubsiteID\" IN ({$subsiteID})");
 }
 /**
  * Return the LIMIT clause ready for inserting into a query.
  *
  * @param SQLSelect $query The expression object to build from
  * @param array $parameters Out parameter for the resulting query parameters
  * @return string The finalised limit SQL fragment
  */
 public function buildLimitFragment(SQLSelect $query, array &$parameters)
 {
     $nl = $this->getSeparator();
     // Ensure limit is given
     $limit = $query->getLimit();
     if (empty($limit)) {
         return '';
     }
     // For literal values return this as the limit SQL
     if (!is_array($limit)) {
         return "{$nl}LIMIT {$limit}";
     }
     // Assert that the array version provides the 'limit' key
     if (!array_key_exists('limit', $limit) || $limit['limit'] !== null && !is_numeric($limit['limit'])) {
         throw new InvalidArgumentException('SQLite3QueryBuilder::buildLimitSQL(): Wrong format for $limit: ' . var_export($limit, true));
     }
     $clause = "{$nl}";
     if ($limit['limit'] !== null) {
         $clause .= "LIMIT {$limit['limit']} ";
     } else {
         $clause .= "LIMIT -1 ";
     }
     if (isset($limit['start']) && is_numeric($limit['start']) && $limit['start'] !== 0) {
         $clause .= "OFFSET {$limit['start']}";
     }
     return $clause;
 }
Example #5
0
  function LoadFromDB() {
    global $POSTS_PER_PAGE;

    $s = new SQLSelect();
    $s->AddTable("bbs_topics");
    $s->AddWhere("bbs_topics.id=".$this->id);
    $this->topic = SQLLib::SelectRow($s->GetQuery());
    if(!$this->topic) return false;

    $s = new SQLSelect();
    $s->AddField("count(*) as c");
    $s->AddTable("bbs_posts");
    $s->AddWhere("bbs_posts.topic=".$this->id);
    $this->postcount = SQLLib::SelectRow($s->GetQuery())->c;

    $s = new BM_Query();
    $s->AddTable("bbs_posts");
    $s->AddField("bbs_posts.id as id");
    $s->AddField("bbs_posts.post as post");
    $s->AddField("bbs_posts.added as added");
    $s->attach(array("bbs_posts"=>"author"),array("users as user"=>"id"));
    $s->AddWhere("bbs_posts.topic=".$this->id);
    //$s->SetLimit( $POSTS_PER_PAGE, (int)(($this->page - 1)*$POSTS_PER_PAGE) );

    $this->paginator = new PouetPaginator();
    $this->paginator->SetData( "topic.php?which=".$this->id, $this->postcount, $POSTS_PER_PAGE, $_GET["page"] );
    $this->paginator->SetLimitOnQuery( $s );

    $this->posts = $s->perform();

    $this->title = _html($this->topic->topic);
  }
 public function getMap()
 {
     $this->getDimensions();
     if (empty($this->map)) {
         $sel = new SQLSelect($this->table);
         $res = $sel->execute();
         $this->map = parallelToAssoc($res[strtoupper($this->idfields[0])], $res[strtoupper($this->idfields[1])]);
     }
     return $this->map;
 }
 public function getPossLanguages()
 {
     if (empty($this->posslanguages)) {
         $getl = new SQLSelect("translation_language");
         $getl->fetchas = "row";
         $res = $getl->execute();
         $this->posslanguages = $res;
     }
     return $this->posslanguages;
 }
 public function processFields()
 {
     if (!isset($this->fields["language_keycode"]["options"])) {
         $opsel = new SQLSelect("translation_language");
         $opsel->selectfields = array("id" => "keycode", "label" => "name_def");
         $opsel->fetchas = "row";
         $res = $opsel->execute();
         $options = $res;
         $this->fields["language_keycode"]["options"] = $options;
     }
 }
 /**
  * Extracts the limit and offset from the limit clause
  * 
  * @param SQLSelect $query
  * @return array Two item array with $limit and $offset as values
  * @throws InvalidArgumentException
  */
 protected function parseLimit(SQLSelect $query)
 {
     $limit = '';
     $offset = '0';
     if (is_array($query->getLimit())) {
         $limitArr = $query->getLimit();
         if (isset($limitArr['limit'])) {
             $limit = $limitArr['limit'];
         }
         if (isset($limitArr['start'])) {
             $offset = $limitArr['start'];
         }
     } else {
         if (preg_match('/^([0-9]+) offset ([0-9]+)$/i', trim($query->getLimit()), $matches)) {
             $limit = $matches[1];
             $offset = $matches[2];
         } else {
             //could be a comma delimited string
             $bits = explode(',', $query->getLimit());
             if (sizeof($bits) > 1) {
                 list($offset, $limit) = $bits;
             } else {
                 $limit = $bits[0];
             }
         }
     }
     return array($limit, $offset);
 }
 /**
  * Attempt to find an old/renamed page from some given the URL as an array
  *
  * @param array $params The array of URL, e.g. /foo/bar as array('foo', 'bar')
  * @param SiteTree $parent The current parent in the recursive flow
  * @param boolean $redirect Whether we've found an old page worthy of a redirect
  *
  * @return string|boolean False, or the new URL
  */
 public static function find_old_page($params, $parent = null, $redirect = false)
 {
     $parent = is_numeric($parent) ? SiteTree::get()->byId($parent) : $parent;
     $params = (array) $params;
     $URL = rawurlencode(array_shift($params));
     if (empty($URL)) {
         return false;
     }
     if ($parent) {
         $page = SiteTree::get()->filter(array('ParentID' => $parent->ID, 'URLSegment' => $URL))->First();
     } else {
         $page = SiteTree::get()->filter(array('URLSegment' => $URL))->First();
     }
     if (!$page) {
         // If we haven't found a candidate, lets resort to finding an old page with this URL segment
         $oldFilter = array('"SiteTree_versions"."URLSegment"' => $URL, '"SiteTree_versions"."WasPublished"' => true);
         if ($parent) {
             $oldFilter[] = array('"SiteTree_versions"."ParentID"' => $parent->ID);
         }
         $query = new SQLSelect('"RecordID"', '"SiteTree_versions"', $oldFilter, '"LastEdited" DESC', null, null, 1);
         $record = $query->execute()->first();
         if ($record) {
             $page = SiteTree::get()->byID($record['RecordID']);
             $redirect = true;
         }
     }
     if ($page && $page->canView()) {
         if (count($params)) {
             // We have to go deeper!
             $ret = self::find_old_page($params, $page, $redirect);
             if ($ret) {
                 // A valid child page was found! We can return it
                 return $ret;
             } else {
                 // No valid page found.
                 if ($redirect) {
                     // If we had some redirect to be done, lets do it. imagine /foo/action -> /bar/action, we still want this redirect to happen if action isn't a page
                     return $page->Link() . implode('/', $params);
                 }
             }
         } else {
             // We've found the final, end all, page.
             return $page->Link();
         }
     }
     return false;
 }
 /**
  * Update any requests to limit the results to the current site
  */
 public function augmentSQL(SQLSelect $query)
 {
     if (Subsite::$disable_subsite_filter) {
         return;
     }
     // If you're querying by ID, ignore the sub-site - this is a bit ugly... (but it was WAYYYYYYYYY worse)
     //@TODO I don't think excluding if SiteTree_ImageTracking is a good idea however because of the SS 3.0 api and ManyManyList::removeAll() changing the from table after this function is called there isn't much of a choice
     $from = $query->getFrom();
     if (isset($from['SiteTree_ImageTracking']) || $query->filtersOnID()) {
         return;
     }
     $subsiteID = (int) Subsite::currentSubsiteID();
     // The foreach is an ugly way of getting the first key :-)
     foreach ($query->getFrom() as $tableName => $info) {
         $where = "\"{$tableName}\".\"SubsiteID\" IN (0, {$subsiteID})";
         $query->addWhere($where);
         break;
     }
     $sect = array_values($query->getSelect());
     $isCounting = strpos($sect[0], 'COUNT') !== false;
     // Ordering when deleting or counting doesn't apply
     if (!$isCounting) {
         $query->addOrderBy("\"SubsiteID\"");
     }
 }
 public function build_query()
 {
     $setstring = "";
     // If insertIfAbsent is set, check for the row
     if ($this->insertIfAbsent) {
         $sel = new SQLSelect($this->table, $this->schema);
         $sel->selectfields[] = "1";
         $sel->wherearray = $this->selectors;
         $val = $sel->execute();
         if ($val == NULL || empty($val) || $val[1] == array()) {
             $ins = new SQLInsert($this->table, $this->values);
             $q = $ins->build_query();
             $this->query = $q;
             return $this->query;
         }
     }
     // Perform the UPDATE
     foreach ($this->values as $key => $value) {
         // Skip selectors
         if (isset($this->selectors[$key])) {
             continue;
         }
         // Build 'SET' string
         if ($setstring != "") {
             $setstring .= ",";
         }
         $setstring .= $key . "=" . dbize($value, $this->get_column_datatype($key));
     }
     if ($setstring != "") {
         $setstring = " SET " . $setstring;
     }
     // Add selectors to WHERE clause
     foreach ($this->selectors as $key => $value) {
         $this->wherefields[] = "{$key} = " . dbize($value, $this->get_column_datatype($key));
     }
     $wherestring = $this->wherefields_to_string();
     if ($setstring != "" && $wherestring != "") {
         $query = "UPDATE " . $this->table_with_schema() . $setstring . $wherestring;
         $this->query = $query;
     }
     return $this->query;
 }
Example #13
0
  function LoadFromDB() {
    $s = new SQLSelect();

    $this->group = PouetGroup::Spawn($this->id);
    $this->addeduser = PouetUser::Spawn($this->group->addedUser);

    // not to boast or anything, but this is f*****g beautiful.

    $sub = new SQLSelect();
    $sub->AddField("max(comments.addedDate) as maxDate");
    $sub->AddField("comments.which");
    $sub->AddTable("comments");
    $sub->AddJoin("left","prods","prods.id = comments.which");
    //$sub->AddOrder("comments.addedDate desc");
    $sub->AddGroup("comments.which");
    $sub->AddWhere(sprintf_esc("(prods.group1 = %d) or (prods.group2 = %d) or (prods.group3 = %d)",$this->id,$this->id,$this->id));

    $s = new BM_Query("prods");
    $s->AddField("cmts.addedDate as lastcomment");
    $s->AddField("cmts.rating as lastcommentrating");
    $s->AddJoin("left","(select comments.addedDate,comments.who,comments.which,comments.rating from (".$sub->GetQuery().") as dummy left join comments on dummy.maxDate = comments.addedDate and dummy.which = comments.which) as cmts","cmts.which=prods.id");
    $s->attach(array("cmts"=>"who"),array("users as user"=>"id"));
    $s->AddWhere(sprintf_esc("(prods.group1 = %d) or (prods.group2 = %d) or (prods.group3 = %d)",$this->id,$this->id,$this->id));

    $r = !!$_GET["reverse"];
    switch($_GET["order"])
    {
      case "type": $s->AddOrder("prods.type ".($r?"DESC":"ASC")); break;
      case "party": $s->AddOrder("prods_party.name ".($r?"DESC":"ASC")); $s->AddOrder("prods.party_year ".($r?"DESC":"ASC")); $s->AddOrder("prods.party_place ".($r?"DESC":"ASC")); break;
      case "release": $s->AddOrder("prods.releaseDate ".($r?"ASC":"DESC")); break;
      case "thumbup": $s->AddOrder("prods.voteup ".($r?"ASC":"DESC")); break;
      case "thumbpig": $s->AddOrder("prods.votepig ".($r?"ASC":"DESC")); break;
      case "thumbdown": $s->AddOrder("prods.votedown ".($r?"ASC":"DESC")); break;
      case "avg": $s->AddOrder("prods.voteavg ".($r?"ASC":"DESC")); break;
      case "views": $s->AddOrder("prods.views ".($r?"ASC":"DESC")); break;
      case "latestcomment": $s->AddOrder("lastcomment ".($r?"ASC":"DESC")); break;
      default: $s->AddOrder("prods.name ".($r?"DESC":"ASC")); break;
    }
    $this->prods = $s->perform();
    PouetCollectPlatforms($this->prods);
    PouetCollectAwards($this->prods);

    $s = new BM_Query("affiliatedboards");
    $s->attach(array("affiliatedboards"=>"board"),array("boards as board"=>"id"));
    $s->AddWhere(sprintf_esc("affiliatedboards.group=%d",$this->id));
    $this->affil = $s->perform();
  }
  function Load( $cached = false ) {
    $s = new SQLSelect();
    $s->AddTable("buttons");
    $s->AddOrder("rand()");
    $s->AddWhere("dead = 0");
    $s->SetLimit("1");
    $this->data = SQLLib::SelectRow($s->GetQuery());

    $this->title = $this->data->type;
  }
 /**
  * For each author, add an AuthorHelper
  */
 private function migrateAuthors()
 {
     /** @var SQLSelect $query */
     $query = SQLSelect::create();
     $query->setSelect('Author')->setFrom('News')->setDistinct(true);
     $authors = $query->execute();
     foreach ($authors as $author) {
         /** Create a new author if it doesn't exist */
         if (!($authorHelper = AuthorHelper::get()->filter(array('OriginalName' => trim($author['Author'])))->first())) {
             /** @var AuthorHelper $authorHelper */
             $authorHelper = AuthorHelper::create();
             $authorHelper->OriginalName = $author['Author'];
             $authorHelper->write();
         }
         $sql = "UPDATE `News` SET `AuthorHelperID` = '" . $authorHelper->ID . "' WHERE Author = '" . $author['Author'] . "'";
         DB::query($sql);
     }
 }
 /**
  * Update any requests to limit the results to the current site
  */
 public function augmentSQL(SQLSelect $query, DataQuery $dataQuery = null)
 {
     if (Subsite::$disable_subsite_filter) {
         return;
     }
     if (Cookie::get('noSubsiteFilter') == 'true') {
         return;
     }
     // If you're querying by ID, ignore the sub-site - this is a bit ugly...
     if (!$query->filtersOnID()) {
         /*if($context = DataObject::context_obj()) $subsiteID = (int)$context->SubsiteID;
         		else */
         $subsiteID = (int) Subsite::currentSubsiteID();
         // Don't filter by Group_Subsites if we've already done that
         $hasGroupSubsites = false;
         foreach ($query->getFrom() as $item) {
             if (is_array($item) && strpos($item['table'], 'Group_Subsites') !== false || !is_array($item) && strpos($item, 'Group_Subsites') !== false) {
                 $hasGroupSubsites = true;
                 break;
             }
         }
         if (!$hasGroupSubsites) {
             if ($subsiteID) {
                 $query->addLeftJoin("Group_Subsites", "\"Group_Subsites\".\"GroupID\" \n\t\t\t\t\t\t= \"Group\".\"ID\" AND \"Group_Subsites\".\"SubsiteID\" = {$subsiteID}");
                 $query->addWhere("(\"Group_Subsites\".\"SubsiteID\" IS NOT NULL OR\n\t\t\t\t\t\t\"Group\".\"AccessAllSubsites\" = 1)");
             } else {
                 $query->addWhere("\"Group\".\"AccessAllSubsites\" = 1");
             }
         }
         // WORKAROUND for databases that complain about an ORDER BY when the column wasn't selected (e.g. SQL Server)
         $select = $query->getSelect();
         if (isset($select[0]) && !$select[0] == 'COUNT(*)') {
             $query->orderby = "\"AccessAllSubsites\" DESC" . ($query->orderby ? ', ' : '') . $query->orderby;
         }
     }
 }
Example #17
0
<?
require_once("bootstrap.inc.php");

header("Content-type: application/json; charset=utf-8");

$sql = new SQLSelect();
$sql->AddField("id");
$sql->AddField("nickname as name");
$sql->AddField("avatar");
$sql->AddField("glops");
$sql->AddTable("users");

$r = array();
if ($_POST["search"])
{
  $sql->AddWhere(sprintf_esc("nickname like '%%%s%%'",_like($_POST["search"])));
  $sql->AddOrder(sprintf_esc("if(nickname='%s',1,2), nickname, lastLogin DESC",$_POST["search"]));
  $sql->SetLimit(10);
  $r = SQLLib::selectRows( $sql->GetQuery() );
}
else if ($_POST["id"])
{
  $sql->AddWhere(sprintf_esc("id = %d",$_POST["id"]));
  $sql->SetLimit(1);
  $r = SQLLib::selectRows( $sql->GetQuery() );
}
echo json_encode($r);
?>
 public function toDelete()
 {
     if (!$this->isDelete) {
         user_error('SQLQuery::toDelete called when $isDelete is false. Use ' . 'toAppropriateExpression() instead', E_USER_WARNING);
     }
     parent::toDelete();
 }
 public function html()
 {
     global $db;
     $html = "";
     // Pull value from another table, if needed
     if (isset($this->value_sqltable) && $this->value_sqltable != "") {
         if (isset($this->value_sqlselectfield) && $this->value_sqlselectfield != "") {
             $selectfield = $this->value_sqlselectfield;
         } else {
             $selectfield = $this->name;
         }
         $sel = new SQLSelect($this->value_sqltable);
         $sel->selectfields[] = $selectfield;
         if (!empty($this->value_sqlwherefields)) {
             $sel->wherefields = $this->value_sqlwherefields;
         }
         $res = $sel->execute();
         if (isset($res[strtoupper($selectfield)][0])) {
             $this->value = $res[strtoupper($selectfield)][0];
         }
     }
     // Unencode value
     if (isset($this->value) && $this->value != "") {
         $this->value = htmlspecialchars_decode($this->value);
     }
     if ($this->type == "header") {
         if ($this->is_html_table) {
             $html .= "<tr><td";
             if ($this->colspan > 0) {
                 $html .= " colspan='" . $this->colspan . "'";
             } else {
                 if ($this->maximum_fields_per_row) {
                     $html .= " colspan='" . $this->maximum_fields_per_row . "'";
                 }
             }
             $html .= ">";
         }
         $html .= "<h3>" . $this->label . "</h3>";
         if ($this->helptext != "") {
             $html .= "<span id='" . $this->id . "_helpblock' class='help-block " . $this->helptextclasses . "'>" . $this->helptext . "</span>";
         }
         if ($this->is_html_table) {
             $html .= "</td></tr>";
         }
         return $html;
     }
     // Line separator, if applicable
     if ($this->inline == true && $this->newline == true && $this->is_html_table == false) {
         $html .= "<p>";
     }
     // New TR, for table form
     if ($this->is_html_table && $this->type != "hidden") {
         if ($this->newline) {
             $html .= "<tr>";
         }
         $html .= "<td";
         if ($this->colspan > 0) {
             $html .= " colspan='" . $this->colspan . "'";
         } else {
             if ($this->maximum_fields_per_row) {
                 $html .= " colspan='" . $this->maximum_fields_per_row . "'";
             }
         }
         $html .= ">";
     }
     // Open container div
     if ($this->type != "hidden") {
         $html .= "<div class='form-group";
         if (isset($this->containerclasses)) {
             $html .= " " . $this->containerclasses;
         }
         $html .= "'>";
     }
     // Label
     $labelhtml = "";
     if ($this->type != "hidden" && $this->type != "html" && $this->label != "") {
         $labelhtml .= "<label";
         if ($this->id != "") {
             $labelhtml .= " for='" . $this->id . "'";
         }
         // Label classes
         $labelhtml .= " class='form-control-label control-label";
         if ($this->required == true) {
             $labelhtml .= "requiredLabel";
         }
         if ($this->horizontal == true) {
             $labelhtml .= " col-sm-2";
         }
         if (isset($this->labelclasses) && $this->labelclasses != "") {
             $labelhtml .= " " . $this->labelclasses;
         }
         $labelhtml .= "'";
         if (isset($this->labelattrs) && $this->labelattrs != "") {
             $labelhtml .= " " . $this->labelattrs;
         }
         $labelhtml .= ">";
         $labelhtml .= $this->label;
         $labelhtml .= "</label>";
     }
     // Initialize input tag string
     $inputhtml = "";
     // Surrounding grid for horizontal
     if ($this->horizontal == true && $this->type != "hidden") {
         $inputhtml .= "<div class='col-sm-10'>";
     }
     // Prefix, if any
     if (isset($this->prefix) && $this->prefix != "") {
         $inputhtml .= "<div class='prefixandinput'><div class='prefix'>" . $this->prefix . "</div>";
     }
     // Open input tag
     if ($this->type != "html") {
         if ($this->type == 'textarea') {
             $inputhtml .= "<textarea";
         } else {
             if ($this->type == 'select') {
                 $inputhtml .= "<select";
             } else {
                 $inputhtml .= "<input type='" . $this->type . "'";
             }
         }
         // Id and name
         if ($this->id != "") {
             $inputhtml .= " id='" . $this->id . "'";
         }
         if ($this->name != "") {
             $inputhtml .= " name='" . $this->name . "'";
         }
         // Required
         if ($this->type != "hidden" && $this->required == true) {
             $inputhtml .= " required='" . $this->required . "'";
         }
         // Size & step
         if ($this->type == 'number') {
             $size = 3;
             if ($this->size > 0) {
                 $size = $this->size;
                 $this->inputattrs .= "style='width:" . ($size * 2 + 1) . "em'";
             }
             $inputhtml .= " size='{$size}'";
             $inputhtml .= " step='" . $this->step . "'";
         }
         // Minimum & maximum
         if ($this->minimum !== "") {
             $inputhtml .= " min='" . $this->minimum . "'";
         }
         if ($this->maximum !== "") {
             $inputhtml .= " min='" . $this->maximum . "'";
         }
         // Classes
         if ($this->type != 'hidden') {
             $inputhtml .= " class='form-control";
             if ($this->required == true) {
                 $inputhtml .= " required";
             }
             if ($this->alignright && $this->type != "textarea" && $this->type != "checkbox") {
                 $this->inputclasses = "alignright";
             }
             // Decide if align right
             if ($this->type == 'textarea') {
                 if ($this->inputclasses != "") {
                     $this->inputclasses .= " ";
                 }
                 $this->inputclasses .= "block width100";
                 // Special for align right text area (to NOT align right and show the full one)
             }
             if (isset($this->inputclasses)) {
                 $inputhtml .= " " . $this->inputclasses;
             }
             $inputhtml .= "'";
         }
         // I'm putting the default value as a dummy attribute, which can be used for javascript resets, etc.
         if (isset($this->defaultvalue) && $this->defaultvalue != "" && $this->value != "") {
             $inputhtml .= ' data-defaultvalue="' . str_replace('"', '&#34;', htmlentities($this->defaultvalue)) . '"';
         }
         // Calculation attributes
         if (isset($this->calculate_addfields) && !empty($this->calculate_addfields)) {
             $inputhtml .= ' data-calculate_addfields="' . implode(",", $this->calculate_addfields) . '"';
         }
         if (isset($this->calculate_subtractfields) && !empty($this->calculate_subtractfields)) {
             $inputhtml .= ' data-calculate_subtractfields="' . implode(",", $this->calculate_subtractfields) . '"';
         }
         // Helptext association
         if ($this->helptext != "") {
             $inputhtml .= ' aria-described-by="' . $this->id . '_helpblock"';
         }
         // Value
         if ($this->type == "checkbox") {
             $inputhtml .= ' value="1"';
             if ($this->value == 1) {
                 $inputhtml .= ' checked';
             }
         } else {
             if ($this->type != 'textarea' && $this->type != 'select') {
                 if ($this->value != "") {
                     $inputhtml .= ' value="' . $db->undbize($this->value) . '"';
                 } else {
                     if ($this->defaultvalue !== "") {
                         $inputhtml .= ' value="' . $db->undbize($this->defaultvalue) . '"';
                     }
                 }
             }
         }
         // Readonly
         if ($this->readonly) {
             $inputhtml .= ' readonly';
         }
         // Input attributes
         if ($this->inputattrs != "") {
             $inputhtml .= " " . $this->inputattrs;
         }
         // End of opening tag
         $inputhtml .= ">";
         // Textarea value
         if ($this->type == 'textarea' && $this->value != "") {
             $inputhtml .= $db->undbize($this->value);
         }
         // Select options
         if ($this->type == 'select' && !empty($this->options)) {
             $idx = 0;
             $optionvalues = array_values($this->options);
             if (isset($this->nulloptiontext)) {
                 $inputhtml .= "<option value=''>" . $this->nulloptiontext . "</option>";
             }
             foreach ($this->options as $key => $option) {
                 if (isset($optionvalues[$idx - 1])) {
                     $lastoption = $optionvalues[$idx - 1];
                 }
                 if (isset($optionvalues[$idx + 1])) {
                     $nextoption = $optionvalues[$idx + 1];
                 }
                 $idx++;
                 if (is_array($option)) {
                     $option = array_change_key_case($option);
                     if (isset($lastoption)) {
                         $lastoption = array_change_key_case($lastoption);
                     }
                     if (isset($nextoption)) {
                         $nextoption = array_change_key_case($nextoption);
                     }
                     if (isset($this->optionidkey)) {
                         $optionidkey = strtolower($this->optionidkey);
                     } else {
                         if (isset($option["key"])) {
                             $optionidkey = "key";
                         } else {
                             if (isset($option["value"])) {
                                 $optionidkey = "value";
                             } else {
                                 $optionidkey = "id";
                             }
                         }
                     }
                     if (isset($this->optiontextkey)) {
                         $optiontextkey = strtolower($this->optiontextkey);
                     } else {
                         if (isset($option["label"])) {
                             $optiontextkey = "label";
                         } else {
                             if (isset($option["name"])) {
                                 $optiontextkey = "name";
                             } else {
                                 $optiontextkey = "text";
                             }
                         }
                     }
                     if (isset($this->optiongroupkey)) {
                         $optiongroupkey = strtolower($this->optiongroupkey);
                     }
                     $value = $option[$optionidkey];
                     $text = $option[$optiontextkey];
                 } else {
                     $value = $key;
                     $text = $option;
                 }
                 if (isset($optiongroupkey) && isset($option[$optiongroupkey]) && (!isset($lastoption) || $option[$optiongroupkey] != $lastoption[$optiongroupkey])) {
                     $inputhtml .= "<optgroup label='" . $option[$optiongroupkey] . "'>";
                 }
                 $inputhtml .= "<option value='{$value}'";
                 if ($this->value == $value) {
                     $inputhtml .= " selected";
                 }
                 $inputhtml .= ">{$text}</option>";
                 if (isset($optiongroupkey) && isset($option[$optiongroupkey]) && (!isset($nextoption) || $option[$optiongroupkey] != $nextoption[$optiongroupkey])) {
                     $inputhtml .= "</optgroup>";
                 }
             }
         }
         // Close tag
         if ($this->type == 'textarea') {
             $inputhtml .= "</textarea>";
         } else {
             if ($this->type == 'select') {
                 $inputhtml .= "</select>";
             } else {
                 $inputhtml .= "</input>";
             }
         }
         if ($this->postfix != "") {
             $inputhtml .= " " . $this->postfix;
         }
         // Surrounding grid for horizontal
         if ($this->horizontal == true && $this->type != "hidden") {
             $inputhtml .= "</div>";
         }
     }
     // End prefixandinput div
     if (isset($this->prefix) && $this->prefix != "") {
         $inputhtml .= "</div>";
     }
     // Put label & input in order
     if ($this->type == "checkbox" && $this->horizontal == false) {
         $html .= $inputhtml . " " . $labelhtml;
     } else {
         $html .= $labelhtml . " " . $inputhtml;
     }
     // HTML element content
     if ($this->type == "html" && $this->content != "") {
         $html .= $this->content;
     }
     // Tooltip
     if ($this->tooltip != "") {
         $html .= "<span class='badge' style='margin-left:0.5em;' data-toggle='tooltip' data-placement='auto right' title='" . $this->tooltip . "'>\r\n\t\t\t  ?\r\n\t\t\t</span>";
     }
     // Helptext
     if ($this->helptext != "") {
         $html .= " <span id='" . $this->id . "_helpblock' class='help-block " . $this->helptextclasses . "'>" . $this->helptext . "</span>";
     }
     // End div
     if ($this->type != "hidden") {
         $html .= "</div>";
     }
     // New TR, for table form
     if ($this->is_html_table && $this->type != "hidden") {
         $html .= "</td>";
         if ($this->newline_next) {
             $html .= "</tr>";
         }
     }
     $this->html = $html;
     return $html;
 }
 /**
  * Test passing in a LIMIT with OFFSET clause string.
  */
 public function testLimitSetFromClauseString()
 {
     $query = new SQLSelect();
     $query->setSelect('*');
     $query->setFrom('"SQLQueryTest_DO"');
     $query->setLimit('20 OFFSET 10');
     $limit = $query->getLimit();
     $this->assertEquals(20, $limit['limit']);
     $this->assertEquals(10, $limit['start']);
 }
Example #21
0
<?
require_once("bootstrap.inc.php");

header("Content-type: application/json; charset=utf-8");

$sql = new SQLSelect();
$sql->AddField("prods.id");
$sql->AddField("prods.name");
$sql->AddField("groups.name as groupName");
$sql->AddJoin("left","groups","groups.id = prods.group1");
$sql->AddTable("prods");

$r = array();
if ($_POST["search"])
{
  $sql->AddWhere(sprintf_esc("prods.name like '%%%s%%'",_like($_POST["search"])));
  $sql->AddOrder(sprintf_esc("if(prods.name='%s',1,2), prods.views desc, prods.name",$_POST["search"]));
  $sql->SetLimit(10);
  $r = SQLLib::selectRows( $sql->GetQuery() );
}
else if ($_POST["id"])
{
  $sql->AddWhere(sprintf_esc("prods.id = %d",$_POST["id"]));
  $sql->SetLimit(1);
  $r = SQLLib::selectRows( $sql->GetQuery() );
}
echo json_encode($r);
?>
 /**
  * Add an item to this many_many relationship
  * Does so by adding an entry to the joinTable.
  *
  * @param mixed $item
  * @param array $extraFields A map of additional columns to insert into the joinTable.
  * Column names should be ANSI quoted.
  */
 public function add($item, $extraFields = array())
 {
     // Ensure nulls or empty strings are correctly treated as empty arrays
     if (empty($extraFields)) {
         $extraFields = array();
     }
     // Determine ID of new record
     if (is_numeric($item)) {
         $itemID = $item;
     } elseif ($item instanceof $this->dataClass) {
         $itemID = $item->ID;
     } else {
         throw new InvalidArgumentException("ManyManyList::add() expecting a {$this->dataClass} object, or ID value", E_USER_ERROR);
     }
     // Validate foreignID
     $foreignIDs = $this->getForeignID();
     if (empty($foreignIDs)) {
         throw new Exception("ManyManyList::add() can't be called until a foreign ID is set", E_USER_WARNING);
     }
     // Apply this item to each given foreign ID record
     if (!is_array($foreignIDs)) {
         $foreignIDs = array($foreignIDs);
     }
     foreach ($foreignIDs as $foreignID) {
         // Check for existing records for this item
         if ($foreignFilter = $this->foreignIDWriteFilter($foreignID)) {
             // With the current query, simply add the foreign and local conditions
             // The query can be a bit odd, especially if custom relation classes
             // don't join expected tables (@see Member_GroupSet for example).
             $query = new SQLSelect("*", "\"{$this->joinTable}\"");
             $query->addWhere($foreignFilter);
             $query->addWhere(array("\"{$this->joinTable}\".\"{$this->localKey}\"" => $itemID));
             $hasExisting = $query->count() > 0;
         } else {
             $hasExisting = false;
         }
         // Blank manipulation
         $manipulation = array($this->joinTable => array('command' => $hasExisting ? 'update' : 'insert', 'fields' => array()));
         if ($hasExisting) {
             $manipulation[$this->joinTable]['where'] = array("\"{$this->joinTable}\".\"{$this->foreignKey}\"" => $foreignID, "\"{$this->joinTable}\".\"{$this->localKey}\"" => $itemID);
         }
         if ($extraFields && $this->extraFields) {
             // Write extra field to manipluation in the same way
             // that DataObject::prepareManipulationTable writes fields
             foreach ($this->extraFields as $fieldName => $fieldSpec) {
                 // Skip fields without an assignment
                 if (array_key_exists($fieldName, $extraFields)) {
                     $fieldObject = Object::create_from_string($fieldSpec, $fieldName);
                     $fieldObject->setValue($extraFields[$fieldName]);
                     $fieldObject->writeToManipulation($manipulation[$this->joinTable]);
                 }
             }
         }
         $manipulation[$this->joinTable]['fields'][$this->localKey] = $itemID;
         $manipulation[$this->joinTable]['fields'][$this->foreignKey] = $foreignID;
         DB::manipulate($manipulation);
     }
 }
 /**
  * Return the number of rows in this query if the limit were removed.  Useful in paged data sets.
  *
  * @param string $column
  * @return int
  */
 public function unlimitedRowCount($column = null)
 {
     // we can't clear the select if we're relying on its output by a HAVING clause
     if (count($this->having)) {
         $records = $this->execute();
         return $records->numRecords();
     }
     $clone = clone $this;
     $clone->limit = null;
     $clone->orderby = null;
     // Choose a default column
     if ($column == null) {
         if ($this->groupby) {
             // @todo Test case required here
             $countQuery = new SQLSelect();
             $countQuery->setSelect("count(*)");
             $countQuery->setFrom(array('(' . $clone->sql($innerParameters) . ') all_distinct'));
             $sql = $countQuery->sql($parameters);
             // $parameters should be empty
             $result = DB::prepared_query($sql, $innerParameters);
             return $result->value();
         } else {
             $clone->setSelect(array("count(*)"));
         }
     } else {
         $clone->setSelect(array("count({$column})"));
     }
     $clone->setGroupBy(array());
     return $clone->execute()->value();
 }
 /**
  * Find the extra field data for a single row of the relationship join
  * table, given the known child ID.
  *
  * @param string $componentName The name of the component
  * @param int $itemID The ID of the child for the relationship
  *
  * @return array Map of fieldName => fieldValue
  */
 public function getExtraData($componentName, $itemID)
 {
     $result = array();
     // Skip if no extrafields or unsaved record
     if (empty($this->extraFields) || empty($itemID)) {
         return $result;
     }
     if (!is_numeric($itemID)) {
         user_error('ComponentSet::getExtraData() passed a non-numeric child ID', E_USER_ERROR);
     }
     $cleanExtraFields = array();
     foreach ($this->extraFields as $fieldName => $dbFieldSpec) {
         $cleanExtraFields[] = "\"{$fieldName}\"";
     }
     $query = new SQLSelect($cleanExtraFields, "\"{$this->joinTable}\"");
     $filter = $this->foreignIDWriteFilter($this->getForeignID());
     if ($filter) {
         $query->setWhere($filter);
     } else {
         user_error("Can't call ManyManyList::getExtraData() until a foreign ID is set", E_USER_WARNING);
     }
     $query->addWhere(array("\"{$this->localKey}\"" => $itemID));
     $queryResult = $query->execute()->current();
     if ($queryResult) {
         foreach ($queryResult as $fieldName => $value) {
             $result[$fieldName] = $value;
         }
     }
     return $result;
 }
 /**
  * Select the given field expressions.
  *
  * @param $fieldExpression String The field to select (escaped SQL statement)
  * @param $alias String The alias of that field (escaped SQL statement)
  */
 protected function selectField($fieldExpression, $alias = null)
 {
     $this->query->selectField($fieldExpression, $alias);
 }
 /**
  * Link this group set to a specific member.
  *
  * Recursively selects all groups applied to this member, as well as any
  * parent groups of any applied groups
  *
  * @param array|integer $id (optional) An ID or an array of IDs - if not provided, will use the current
  * ids as per getForeignID
  * @return array Condition In array(SQL => parameters format)
  */
 public function foreignIDFilter($id = null)
 {
     if ($id === null) {
         $id = $this->getForeignID();
     }
     // Find directly applied groups
     $manyManyFilter = parent::foreignIDFilter($id);
     $query = new SQLSelect('"Group_Members"."GroupID"', '"Group_Members"', $manyManyFilter);
     $groupIDs = $query->execute()->column();
     // Get all ancestors, iteratively merging these into the master set
     $allGroupIDs = array();
     while ($groupIDs) {
         $allGroupIDs = array_merge($allGroupIDs, $groupIDs);
         $groupIDs = DataObject::get("Group")->byIDs($groupIDs)->column("ParentID");
         $groupIDs = array_filter($groupIDs);
     }
     // Add a filter to this DataList
     if (!empty($allGroupIDs)) {
         $allGroupIDsPlaceholders = DB::placeholders($allGroupIDs);
         return array("\"Group\".\"ID\" IN ({$allGroupIDsPlaceholders})" => $allGroupIDs);
     } else {
         return array('"Group"."ID"' => 0);
     }
 }
 /**
  * Returns true if the member is allowed to do the given action.
  * See {@link extendedCan()} for a more versatile tri-state permission control.
  *
  * @param string $perm The permission to be checked, such as 'View'.
  * @param Member $member The member whose permissions need checking.  Defaults to the currently logged
  * in user.
  *
  * @return boolean True if the the member is allowed to do the given action
  */
 public function can($perm, $member = null)
 {
     if (!isset($member)) {
         $member = Member::currentUser();
     }
     if (Permission::checkMember($member, "ADMIN")) {
         return true;
     }
     if ($this->many_many('Can' . $perm)) {
         if ($this->ParentID && $this->SecurityType == 'Inherit') {
             if (!($p = $this->Parent)) {
                 return false;
             }
             return $this->Parent->can($perm, $member);
         } else {
             $permissionCache = $this->uninherited('permissionCache');
             $memberID = $member ? $member->ID : 'none';
             if (!isset($permissionCache[$memberID][$perm])) {
                 if ($member->ID) {
                     $groups = $member->Groups();
                 }
                 $groupList = implode(', ', $groups->column("ID"));
                 // TODO Fix relation table hardcoding
                 $query = new SQLSelect("\"Page_Can{$perm}\".PageID", array("\"Page_Can{$perm}\""), "GroupID IN ({$groupList})");
                 $permissionCache[$memberID][$perm] = $query->execute()->column();
                 if ($perm == "View") {
                     // TODO Fix relation table hardcoding
                     $query = new SQLSelect("\"SiteTree\".\"ID\"", array("\"SiteTree\"", "LEFT JOIN \"Page_CanView\" ON \"Page_CanView\".\"PageID\" = \"SiteTree\".\"ID\""), "\"Page_CanView\".\"PageID\" IS NULL");
                     $unsecuredPages = $query->execute()->column();
                     if ($permissionCache[$memberID][$perm]) {
                         $permissionCache[$memberID][$perm] = array_merge($permissionCache[$memberID][$perm], $unsecuredPages);
                     } else {
                         $permissionCache[$memberID][$perm] = $unsecuredPages;
                     }
                 }
                 Config::inst()->update($this->class, 'permissionCache', $permissionCache);
             }
             if ($permissionCache[$memberID][$perm]) {
                 return in_array($this->ID, $permissionCache[$memberID][$perm]);
             }
         }
     } else {
         return parent::can($perm, $member);
     }
 }
 public function testDbDatetimeDifference()
 {
     $offset = $this->checkPreconditions();
     $clause = $this->adapter->datetimeDifferenceClause('1974-10-14 10:30:00', '1973-10-14 10:30:00');
     $result = DB::query('SELECT ' . $clause)->value();
     $this->matchesRoughly($result / 86400, 365, '1974 - 1973 = 365 * 86400 sec', $offset);
     $clause = $this->adapter->datetimeDifferenceClause(date('Y-m-d H:i:s', strtotime('-15 seconds')), 'now');
     $result = DB::query('SELECT ' . $clause)->value();
     $this->matchesRoughly($result, -15, '15 seconds ago - now', $offset);
     $clause = $this->adapter->datetimeDifferenceClause('now', $this->adapter->datetimeIntervalClause('now', '+45 Minutes'));
     $result = DB::query('SELECT ' . $clause)->value();
     $this->matchesRoughly($result, -45 * 60, 'now - 45 minutes ahead', $offset);
     $query = new SQLSelect();
     $query->setSelect(array());
     $query->selectField($this->adapter->datetimeDifferenceClause('"LastEdited"', '"Created"'), 'test')->setFrom('"DbDateTimeTest_Team"')->setLimit(1);
     $result = $query->execute()->value();
     $lastedited = Dataobject::get_one('DbDateTimeTest_Team')->LastEdited;
     $created = Dataobject::get_one('DbDateTimeTest_Team')->Created;
     $this->matchesRoughly($result, strtotime($lastedited) - strtotime($created), 'age of HomePage record in seconds since unix epoc', $offset);
 }
    public function testParameterisedLeftJoins()
    {
        $query = new SQLSelect();
        $query->setSelect(array('"SQLSelectTest_DO"."Name"', '"SubSelect"."Count"'));
        $query->setFrom('"SQLSelectTest_DO"');
        $query->addLeftJoin('(SELECT "Title", COUNT(*) AS "Count" FROM "SQLSelectTestBase" GROUP BY "Title" HAVING "Title" NOT LIKE ?)', '"SQLSelectTest_DO"."Name" = "SubSelect"."Title"', 'SubSelect', 20, array('%MyName%'));
        $query->addWhere(array('"SQLSelectTest_DO"."Date" > ?' => '2012-08-08 12:00'));
        $this->assertSQLEquals('SELECT "SQLSelectTest_DO"."Name", "SubSelect"."Count"
			FROM "SQLSelectTest_DO" LEFT JOIN (SELECT "Title", COUNT(*) AS "Count" FROM "SQLSelectTestBase"
		   GROUP BY "Title" HAVING "Title" NOT LIKE ?) AS "SubSelect" ON "SQLSelectTest_DO"."Name" =
		   "SubSelect"."Title"
			WHERE ("SQLSelectTest_DO"."Date" > ?)', $query->sql($parameters));
        $this->assertEquals(array('%MyName%', '2012-08-08 12:00'), $parameters);
        $query->execute();
    }
 /**
  * Augment the the SQLSelect that is created by the DataQuery
  * @todo Should this all go into VersionedDataQuery?
  */
 public function augmentSQL(SQLSelect $query, DataQuery $dataQuery = null)
 {
     if (!$dataQuery || !$dataQuery->getQueryParam('Versioned.mode')) {
         return;
     }
     $baseTable = ClassInfo::baseDataClass($dataQuery->dataClass());
     switch ($dataQuery->getQueryParam('Versioned.mode')) {
         // Reading a specific data from the archive
         case 'archive':
             $date = $dataQuery->getQueryParam('Versioned.date');
             foreach ($query->getFrom() as $table => $dummy) {
                 if (!DB::get_schema()->hasTable($table . '_versions')) {
                     continue;
                 }
                 $query->renameTable($table, $table . '_versions');
                 $query->replaceText("\"{$table}_versions\".\"ID\"", "\"{$table}_versions\".\"RecordID\"");
                 $query->replaceText("`{$table}_versions`.`ID`", "`{$table}_versions`.`RecordID`");
                 // Add all <basetable>_versions columns
                 foreach (Config::inst()->get('Versioned', 'db_for_versions_table') as $name => $type) {
                     $query->selectField(sprintf('"%s_versions"."%s"', $baseTable, $name), $name);
                 }
                 $query->selectField(sprintf('"%s_versions"."%s"', $baseTable, 'RecordID'), "ID");
                 if ($table != $baseTable) {
                     $query->addWhere("\"{$table}_versions\".\"Version\" = \"{$baseTable}_versions\".\"Version\"");
                 }
             }
             // Link to the version archived on that date
             $query->addWhere(array("\"{$baseTable}_versions\".\"Version\" IN\n\t\t\t\t(SELECT LatestVersion FROM\n\t\t\t\t\t(SELECT\n\t\t\t\t\t\t\"{$baseTable}_versions\".\"RecordID\",\n\t\t\t\t\t\tMAX(\"{$baseTable}_versions\".\"Version\") AS LatestVersion\n\t\t\t\t\t\tFROM \"{$baseTable}_versions\"\n\t\t\t\t\t\tWHERE \"{$baseTable}_versions\".\"LastEdited\" <= ?\n\t\t\t\t\t\tGROUP BY \"{$baseTable}_versions\".\"RecordID\"\n\t\t\t\t\t) AS \"{$baseTable}_versions_latest\"\n\t\t\t\t\tWHERE \"{$baseTable}_versions_latest\".\"RecordID\" = \"{$baseTable}_versions\".\"RecordID\"\n\t\t\t\t)" => $date));
             break;
             // Reading a specific stage (Stage or Live)
         // Reading a specific stage (Stage or Live)
         case 'stage':
             $stage = $dataQuery->getQueryParam('Versioned.stage');
             if ($stage && $stage != $this->defaultStage) {
                 foreach ($query->getFrom() as $table => $dummy) {
                     // Only rewrite table names that are actually part of the subclass tree
                     // This helps prevent rewriting of other tables that get joined in, in
                     // particular, many_many tables
                     if (class_exists($table) && ($table == $this->owner->class || is_subclass_of($table, $this->owner->class) || is_subclass_of($this->owner->class, $table))) {
                         $query->renameTable($table, $table . '_' . $stage);
                     }
                 }
             }
             break;
             // Reading a specific stage, but only return items that aren't in any other stage
         // Reading a specific stage, but only return items that aren't in any other stage
         case 'stage_unique':
             $stage = $dataQuery->getQueryParam('Versioned.stage');
             // Recurse to do the default stage behavior (must be first, we rely on stage renaming happening before
             // below)
             $dataQuery->setQueryParam('Versioned.mode', 'stage');
             $this->augmentSQL($query, $dataQuery);
             $dataQuery->setQueryParam('Versioned.mode', 'stage_unique');
             // Now exclude any ID from any other stage. Note that we double rename to avoid the regular stage rename
             // renaming all subquery references to be Versioned.stage
             foreach ($this->stages as $excluding) {
                 if ($excluding == $stage) {
                     continue;
                 }
                 $tempName = 'ExclusionarySource_' . $excluding;
                 $excludingTable = $baseTable . ($excluding && $excluding != $this->defaultStage ? "_{$excluding}" : '');
                 $query->addWhere('"' . $baseTable . '"."ID" NOT IN (SELECT "ID" FROM "' . $tempName . '")');
                 $query->renameTable($tempName, $excludingTable);
             }
             break;
             // Return all version instances
         // Return all version instances
         case 'all_versions':
         case 'latest_versions':
             foreach ($query->getFrom() as $alias => $join) {
                 if ($alias != $baseTable) {
                     $query->setJoinFilter($alias, "\"{$alias}\".\"RecordID\" = \"{$baseTable}_versions\".\"RecordID\"" . " AND \"{$alias}\".\"Version\" = \"{$baseTable}_versions\".\"Version\"");
                 }
                 $query->renameTable($alias, $alias . '_versions');
             }
             // Add all <basetable>_versions columns
             foreach (Config::inst()->get('Versioned', 'db_for_versions_table') as $name => $type) {
                 $query->selectField(sprintf('"%s_versions"."%s"', $baseTable, $name), $name);
             }
             // Alias the record ID as the row ID
             $query->selectField(sprintf('"%s_versions"."%s"', $baseTable, 'RecordID'), "ID");
             // Ensure that any sort order referring to this ID is correctly aliased
             $orders = $query->getOrderBy();
             foreach ($orders as $order => $dir) {
                 if ($order === "\"{$baseTable}\".\"ID\"") {
                     unset($orders[$order]);
                     $orders["\"{$baseTable}_versions\".\"RecordID\""] = $dir;
                 }
             }
             $query->setOrderBy($orders);
             // latest_version has one more step
             // Return latest version instances, regardless of whether they are on a particular stage
             // This provides "show all, including deleted" functonality
             if ($dataQuery->getQueryParam('Versioned.mode') == 'latest_versions') {
                 $query->addWhere("\"{$alias}_versions\".\"Version\" IN\n\t\t\t\t\t(SELECT LatestVersion FROM\n\t\t\t\t\t\t(SELECT\n\t\t\t\t\t\t\t\"{$alias}_versions\".\"RecordID\",\n\t\t\t\t\t\t\tMAX(\"{$alias}_versions\".\"Version\") AS LatestVersion\n\t\t\t\t\t\t\tFROM \"{$alias}_versions\"\n\t\t\t\t\t\t\tGROUP BY \"{$alias}_versions\".\"RecordID\"\n\t\t\t\t\t\t) AS \"{$alias}_versions_latest\"\n\t\t\t\t\t\tWHERE \"{$alias}_versions_latest\".\"RecordID\" = \"{$alias}_versions\".\"RecordID\"\n\t\t\t\t\t)");
             } else {
                 // If all versions are requested, ensure that records are sorted by this field
                 $query->addOrderBy(sprintf('"%s_versions"."%s"', $baseTable, 'Version'));
             }
             break;
         default:
             throw new InvalidArgumentException("Bad value for query parameter Versioned.mode: " . $dataQuery->getQueryParam('Versioned.mode'));
     }
 }