Skip to content

Instantly share code, notes, and snippets.

@bystrano
Created February 21, 2015 14:52
Show Gist options
  • Save bystrano/398ebb0b7be591796898 to your computer and use it in GitHub Desktop.
Save bystrano/398ebb0b7be591796898 to your computer and use it in GitHub Desktop.
<?php
/**
* Une boîte à outils de fonctions pour construire des requêtes SQL
*
* @plugin Base Magique
* @copyright 2014
* @author Michel @ Vertige ASBL
* @licence GNU/GPL
*/
if (!defined('_ECRIRE_INC_VERSION')) return;
/**
* Transforme un tableau de contraintes imbriquées en une chaîne de
* caractère utilisable dans un WHERE
*
* Les tableaux where sont des listes dont le premier élément et un
* opérateur, comme AND ou OR. Le reste des éléments sera "implodé"
* avec l'opérateur. La fonction est appliquée récursivement sur les
* sous-tableaux.
*
* @exemple
* applatir_where(array(
* 'AND',
* 'grand',
* 'beau',
* array(
* 'OR',
* 'blond',
* 'roux',
* ),
* ));
*
* => "( 'grand' AND 'beau' AND ( 'blond' OR 'roux' ))"
*
* @param array $tableau_where : Le tableau de contraintes
*
* @return String : Un morceau de requête SQL à utiliser dans un WHERE
*/
function aplatir_where ($tableau_where) {
$operateur = array_shift($tableau_where);
$tableau_where = array_map(function ($el) {
if (is_array($el)) {
return "(" . construire_where($el) . ")";
} else {
return "( $el )";
}
}, $tableau_where);
return implode(" $operateur ", $tableau_where);
}
/**
* Calcule une jointure à utiliser dans un FROM
*
* Pour les objets éditoriaux SPIP, les liaisons sont toujours faites
* avec une table de liens, il faut donc toujours faire de deux
* jointures pour récupérer des valeurs dans une table jointe. Cette
* fonction permet de générer facilement une telle paire de jointures.
*
* @param Strin $depart : Le nom de l'objet de départ
* @param Strin $arrivee : Le nom de l'objet d'arrivee, celui qui à
* une table de liens à son nom.
*
* @return String : Un morceau de requête SQL à utiliser dans un FROM
*/
function calculer_jointure_liens ($depart, $arrivee) {
include_spip('base/objets');
$table_depart = table_objet_sql($depart);
$table_arrivee = table_objet_sql($arrivee);
$alias_depart = table_objet($table_depart);
$alias_arrivee = table_objet($table_arrivee);
$id_table_depart = id_table_objet($table_depart);
$id_table_arrivee = id_table_objet($table_arrivee);
return " INNER JOIN "
. $table_arrivee."_liens as " . $alias_arrivee."_liens"
. " ON (( " . $alias_arrivee . "_liens.objet='" . objet_type($table_depart) . "' )"
. " AND ( " . $alias_arrivee . "_liens.id_objet="
. $alias_depart . "." . $id_table_depart." ))".
"INNER JOIN " . $table_arrivee . " AS " . $alias_arrivee .
" ON ( " . $alias_arrivee."_liens." . $id_table_arrivee
. "=" . $alias_arrivee . "." . $id_table_arrivee . " )";
}
/**
* Force un string à être sur une seule ligne, et vire d'éventuelles
* indentations
*
* @param String $string : La chaîne de caractère possiblement avec
* des retours de ligne.
*
* @return String : La chaîne de caractère sans retours de ligne.
*/
function monoligne($string) {
$tab = explode("\n", $string);
return trim(
array_reduce($tab,
function ($carry, $item) {
return $carry . trim($item) . ' ';
}, ''));
}
/**
* Faire un UNION avec plusieurs SELECTs
*
* @exemple
* $requete = sql_multiselect(array(
* "SELECT ('article'), id_article as id_objet, titre
* FROM spip_articles
* WHERE id_rubrique=1",
* "SELECT ('rubrique'), id_rubrique as id_objet, titre
* FROM spip_rubriques
* WHERE id_parent=1",
* ), 'titre, article DESC');
*
* =>
* SELECT ('article'), id_article as id_objet, titre
* FROM spip_articles
* WHERE id_rubrique=1
* UNION ALL
* SELECT ('rubrique'), id_rubrique as id_objet, titre
* FROM spip_rubriques
* WHERE id_parent=1
* ORDER BY titre, article DESC
*
* @param array $selects : Une liste de requêtes SELECT
* @param String $orderby : La partie ORDER BY de la requête
* @param String $limit : Une éventuelle limite pour le nombre de
* résultats de la requête
*
* @return String : La requête SQL qui fait un UNION avec les SELECTs
* qu'on a passés en paramètre.
*/
function sql_multiselect($selects, $orderby, $limit=null) {
$requete = implode("\nUNION ALL\n", $selects);
$requete .= "\n" .
"ORDER BY " . $orderby . "\n" .
($limit ? "LIMIT " . $limit : '');
return $requete;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment