<?php
/*
* This file is part of Contao.
*
* (c) Leo Feyer
*
* @license LGPL-3.0-or-later
*/
namespace Contao\Model;
use Contao\Database;
use Contao\DcaExtractor;
/**
* The class reads the relation meta data from the DCA and creates the necessary
* JOIN queries to retrieve an object from the database.
*
* @author Leo Feyer <https://github.com/leofeyer>
*/
class QueryBuilder
{
/**
* Build a query based on the given options
*
* @param array $arrOptions The options array
*
* @return string The query string
*/
public static function find(array $arrOptions)
{
$objBase = DcaExtractor::getInstance($arrOptions['table']);
if (!$objBase->hasRelations())
{
$strQuery = "SELECT * FROM " . $arrOptions['table'];
}
else
{
$arrJoins = array();
$arrFields = array($arrOptions['table'] . ".*");
$intCount = 0;
foreach ($objBase->getRelations() as $strKey=>$arrConfig)
{
// Automatically join the single-relation records
if ($arrConfig['load'] == 'eager' || $arrOptions['eager'])
{
if ($arrConfig['type'] == 'hasOne' || $arrConfig['type'] == 'belongsTo')
{
++$intCount;
$objRelated = DcaExtractor::getInstance($arrConfig['table']);
foreach (array_keys($objRelated->getFields()) as $strField)
{
$arrFields[] = 'j' . $intCount . '.' . Database::quoteIdentifier($strField) . ' AS ' . $strKey . '__' . $strField;
}
$arrJoins[] = " LEFT JOIN " . $arrConfig['table'] . " j$intCount ON " . $arrOptions['table'] . "." . Database::quoteIdentifier($strKey) . "=j$intCount." . $arrConfig['field'];
}
}
}
// Generate the query
$strQuery = "SELECT " . implode(', ', $arrFields) . " FROM " . $arrOptions['table'] . implode("", $arrJoins);
}
// Where condition
if (isset($arrOptions['column']))
{
$strQuery .= " WHERE " . (\is_array($arrOptions['column']) ? implode(" AND ", $arrOptions['column']) : $arrOptions['table'] . '.' . Database::quoteIdentifier($arrOptions['column']) . "=?");
}
// Group by
if (isset($arrOptions['group']))
{
@trigger_error('Using the "group" option has been deprecated and will no longer work in Contao 5.0. See https://github.com/contao/contao/issues/1680', E_USER_DEPRECATED);
$strQuery .= " GROUP BY " . $arrOptions['group'];
}
// Having (see #6446)
if (isset($arrOptions['having']))
{
$strQuery .= " HAVING " . $arrOptions['having'];
}
// Order by
if (isset($arrOptions['order']))
{
$strQuery .= " ORDER BY " . $arrOptions['order'];
}
return $strQuery;
}
/**
* Build a query based on the given options to count the number of records
*
* @param array $arrOptions The options array
*
* @return string The query string
*/
public static function count(array $arrOptions)
{
$strQuery = "SELECT COUNT(*) AS count FROM " . $arrOptions['table'];
if ($arrOptions['column'] !== null)
{
$strQuery .= " WHERE " . (\is_array($arrOptions['column']) ? implode(" AND ", $arrOptions['column']) : $arrOptions['table'] . '.' . Database::quoteIdentifier($arrOptions['column']) . "=?");
}
return $strQuery;
}
}
class_alias(QueryBuilder::class, 'Model\QueryBuilder');